📄 _udp.c
字号:
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
* the University nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior
* written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <string.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <net/if.h>
#include <arpa/nameser.h>
#include <arpa/tftp.h>
#include <rpc/rpc.h>
#include "interfac.h"
#include "a2name.h"
#include "appletal.h"
#include "nfs.h"
#include "smb.h"
#include "bootp.h"
#include "afsops.h"
#include "rxkops.h"
#include "ip.h"
#include "ip6.h"
#include "udp.h"
struct rtcphdr {
u_short rh_flags; /* T:2 P:1 CNT:5 PT:8 */
u_short rh_len; /* length of message (in bytes) */
u_int rh_ssrc; /* synchronization src id */
};
typedef struct {
u_long upper; /* more significant 32 bits */
u_long lower; /* less significant 32 bits */
} ntp64;
/*
* Sender report.
*/
struct rtcp_sr {
ntp64 sr_ntp; /* 64-bit ntp timestamp */
u_int32_t sr_ts; /* reference media timestamp */
u_int32_t sr_np; /* no. packets sent */
u_int32_t sr_nb; /* no. bytes sent */
};
/*
* Receiver report.
* Time stamps are middle 32-bits of ntp timestamp.
*/
struct rtcp_rr {
u_int32_t rr_srcid; /* sender being reported */
u_int32_t rr_nl; /* no. packets lost */
u_int32_t rr_ls; /* extended last seq number received */
u_int32_t rr_dv; /* jitter (delay variance) */
u_int32_t rr_lsr; /* orig. ts from last rr from this src */
u_int32_t rr_dlsr; /* time from recpt of last rr to xmit time */
};
/* XXX */
#define RTCP_PT_SR 200
#define RTCP_PT_RR 201
#define RTCP_PT_SDES 202
#define RTCP_SDES_CNAME 1
#define RTCP_SDES_NAME 2
#define RTCP_SDES_EMAIL 3
#define RTCP_SDES_PHONE 4
#define RTCP_SDES_LOC 5
#define RTCP_SDES_TOOL 6
#define RTCP_SDES_TXT 7
#define RTCP_PT_BYE 203
#define RTCP_PT_APP 204
/*
* Announce-listen control packets are sent to the odd port,
* Reply/repair/data packets are sent to the even port.
*/
static void wc_print (const u_char *wp, u_int len, const struct udphdr *up)
{
u_short dport = ntohs (up->uh_dport);
if (!(dport % 2))
{
srm2_print (wp, len);
return;
}
#if 0
{
char str[100];
u_int slen = min (snapend - (u_char*)wp+1, sizeof(str));
snprintf (str, slen, " %s", wp);
PRINTF ("%s", str);
}
#endif
}
static void vat_print (const void *hdr, u_int len, const struct udphdr *up)
{
/* vat/vt audio */
u_int ts = *(u_short*)hdr;
if ((ts & 0xf060) != 0)
{
/* probably vt */
PRINTF (" udp/vt %u %d / %d",
(u_int) (ntohs (up->uh_ulen) - sizeof(*up)),
ts & 0x3ff, ts >> 10);
}
else
{
/* probably vat */
u_int i0 = ntohl (((u_int*)hdr)[0]);
u_int i1 = ntohl (((u_int*)hdr)[1]);
PRINTF (" udp/vat %u c%d %u%s",
(u_int) (ntohs (up->uh_ulen) - sizeof(*up) - 8),
i0 & 0xffff,
i1, i0 & 0x800000 ? "*" : "");
/* audio format */
if (i0 & 0x1f0000)
PRINTF (" f%d", (i0 >> 16) & 0x1f);
if (i0 & 0x3f000000)
PRINTF (" s%d", (i0 >> 24) & 0x3f);
}
}
static void rtp_print (const void *hdr, u_int len, const struct udphdr *up)
{
/* rtp v1 or v2 */
u_int hasopt, hasext, contype, hasmarker;
u_int *ip = (u_int*)hdr;
u_int i0 = ntohl (((u_int*)hdr)[0]);
u_int i1 = ntohl (((u_int*)hdr)[1]);
u_int dlen = ntohs (up->uh_ulen) - sizeof(*up) - 8;
const char *ptype;
ip += 2;
len >>= 2;
len -= 2;
hasopt = 0;
hasext = 0;
if ((i0 >> 30) == 1)
{
/* rtp v1 */
hasopt = i0 & 0x800000;
contype = (i0 >> 16) & 0x3f;
hasmarker = i0 & 0x400000;
ptype = "rtpv1";
}
else
{ /*XXX */
/* rtp v2 */
hasext = i0 & 0x10000000;
contype = (i0 >> 16) & 0x7f;
hasmarker = i0 & 0x800000;
dlen -= 4;
ptype = "rtp";
ip += 1;
len -= 1;
}
PRINTF (" udp/%s %d c%d %s%s %d",
ptype, dlen, contype,
(hasopt || hasext) ? "+" : "",
hasmarker ? "*" : "",
i0 & 0xffff);
if (vflag)
{
PRINTF (" %u", i1);
if (hasopt)
{
u_int i2, optlen;
do
{
i2 = ip[0];
optlen = (i2 >> 16) & 0xff;
if (optlen == 0 || optlen > len)
{
PUTS (" !opt");
return;
}
ip += optlen;
len -= optlen;
}
while ((int) i2 >= 0);
}
if (hasext)
{
u_int i2, extlen;
i2 = ip[0];
extlen = (i2 & 0xffff) + 1;
if (extlen > len)
{
PUTS (" !ext");
return;
}
ip += extlen;
}
if (contype == 0x1f) /* H.261 */
PRINTF (" 0x%04x", ip[0] >> 16);
}
}
static const u_char *rtcp_print (const u_char * hdr, u_char *ep)
{
/* rtp v2 control (rtcp) */
struct rtcp_rr *rr = 0;
struct rtcp_sr *sr;
struct rtcphdr *rh = (struct rtcphdr*)hdr;
int cnt, len;
u_short flags;
double ts, dts;
if ((u_char*)(rh+1) > ep)
{
PUTS (" [|rtcp]");
return (ep);
}
len = (ntohs (rh->rh_len)+1) * 4;
flags = ntohs (rh->rh_flags);
cnt = (flags >> 8) & 0x1f;
switch (flags & 0xff)
{
case RTCP_PT_SR:
sr = (struct rtcp_sr*)(rh+1);
PUTS (" sr");
if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
PRINTF (" [%d]", len);
if (vflag)
PRINTF (" %lu", ntohl (rh->rh_ssrc));
if ((u_char*)(sr+1) > ep)
{
PUTS (" [|rtcp]");
return (ep);
}
ts = (double) ((u_int32_t) ntohl (sr->sr_ntp.upper)) +
((double) ((u_int32_t) ntohl (sr->sr_ntp.lower)) / 4294967296.0);
PRINTF (" @%.2f %lu %lup %lub", ts,
ntohl (sr->sr_ts), ntohl(sr->sr_np), ntohl(sr->sr_nb));
rr = (struct rtcp_rr*)(sr+1);
break;
case RTCP_PT_RR:
PUTS (" rr");
if (len != cnt * sizeof(*rr) + sizeof(*rh))
PRINTF (" [%d]", len);
rr = (struct rtcp_rr*)(rh+1);
if (vflag)
PRINTF (" %lu", ntohl(rh->rh_ssrc));
break;
case RTCP_PT_SDES:
PRINTF (" sdes %d", len);
if (vflag)
PRINTF (" %lu", ntohl (rh->rh_ssrc));
cnt = 0;
break;
case RTCP_PT_BYE:
PRINTF (" bye %d", len);
if (vflag)
PRINTF (" %lu", ntohl (rh->rh_ssrc));
cnt = 0;
break;
default:
PRINTF (" type-0x%x %d", flags & 0xff, len);
cnt = 0;
break;
}
if (cnt > 1)
PRINTF (" c%d", cnt);
while (--cnt >= 0)
{
if ((u_char*)(rr+1) > ep)
{
PUTS (" [|rtcp]");
return (ep);
}
if (vflag)
PRINTF (" %lu", ntohl(rr->rr_srcid));
ts = (double) ((u_int32_t) ntohl (rr->rr_lsr)) / 65536.;
dts = (double) ((u_int32_t) ntohl (rr->rr_dlsr)) / 65536.;
PRINTF (" %lul %lus %luj @%.2f+%.2f",
ntohl (rr->rr_nl) & 0x00ffffff,
ntohl (rr->rr_ls),
ntohl (rr->rr_dv), ts, dts);
}
return (hdr + len);
}
static int udp_cksum (const struct ip *ip, const struct udphdr *up, int len)
{
int i, tlen;
union phu {
struct phdr {
u_int32_t src;
u_int32_t dst;
u_char mbz;
u_char proto;
u_int16_t len;
} ph;
u_int16_t pa[6];
} phu;
const u_int16_t *sp;
u_int32_t sum;
tlen = ntohs (ip->ip_len) - ((const char *) up - (const char *) ip);
/* pseudo-header.. */
phu.ph.len = htons (tlen);
phu.ph.mbz = 0;
phu.ph.proto = IPPROTO_UDP;
memcpy (&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
memcpy (&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
sp = &phu.pa[0];
sum = sp[0] + sp[1] + sp[2] + sp[3] + sp[4] + sp[5];
sp = (const u_int16_t*) up;
for (i = 0; i < (tlen & ~1); i += 2)
sum += *sp++;
if (tlen & 1)
sum += htons ((*(const u_int8_t*)sp) << 8);
while (sum > 0xffff)
sum = (sum & 0xffff) + (sum >> 16);
sum = ~sum & 0xffff;
return (sum);
}
#ifdef USE_INET6
static int udp6_cksum (const struct ip6_hdr *ip6, const struct udphdr *up, int len)
{
int i, tlen;
const u_int16_t *sp;
u_int32_t sum;
union {
struct {
struct in6_addr ph_src;
struct in6_addr ph_dst;
u_int32_t ph_len;
u_int8_t ph_zero[3];
u_int8_t ph_nxt;
} ph;
u_int16_t pa[20];
} phu;
tlen = ntohs (ip6->ip6_plen) + sizeof(struct ip6_hdr) -
((const char *) up - (const char *) ip6);
/* pseudo-header */
memset (&phu, 0, sizeof(phu));
phu.ph.ph_src = ip6->ip6_src;
phu.ph.ph_dst = ip6->ip6_dst;
phu.ph.ph_len = htonl (tlen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -