X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/c0c93f3a653f3aa56631c3bf6ee60772ec417e5e..cbd4cbb99cf9e68c67af16b5b20a050ef8819af6:/print-udp.c diff --git a/print-udp.c b/print-udp.c index 7b4e535e..c9bb189b 100644 --- a/print-udp.c +++ b/print-udp.c @@ -21,7 +21,7 @@ #ifndef lint static const char rcsid[] = - "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.69 1999-11-23 08:27:41 fenner Exp $ (LBL)"; + "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.93 2001-03-17 04:41:51 itojun Exp $ (LBL)"; #endif #ifdef HAVE_CONFIG_H @@ -30,22 +30,9 @@ static const char rcsid[] = #include #include -#include #include -#include -#include -#include -#include -#include -#ifdef NOERROR -#undef NOERROR /* Solaris sucks */ -#endif -#ifdef T_UNSPEC -#undef T_UNSPEC /* SINIX does too */ -#endif -#include #ifdef SEGSIZE #undef SEGSIZE #endif @@ -54,27 +41,38 @@ static const char rcsid[] = #include #include - -#ifdef INET6 -#include -#endif +#include #include "interface.h" #include "addrtoname.h" #include "appletalk.h" +#include "udp.h" + +#include "ip.h" +#ifdef INET6 +#include "ip6.h" +#endif + +#ifdef NOERROR +#undef NOERROR /* Solaris sucks */ +#endif +#ifdef T_UNSPEC +#undef T_UNSPEC /* SINIX does too */ +#endif +#include "nameser.h" #include "nfs.h" #include "bootp.h" struct rtcphdr { - u_short rh_flags; /* T:2 P:1 CNT:5 PT:8 */ - u_short rh_len; /* length of message (in words) */ - u_int rh_ssrc; /* synchronization src id */ + u_int16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */ + u_int16_t rh_len; /* length of message (in words) */ + u_int32_t rh_ssrc; /* synchronization src id */ }; typedef struct { - u_int upper; /* more significant 32 bits */ - u_int lower; /* less significant 32 bits */ + u_int32_t upper; /* more significant 32 bits */ + u_int32_t lower; /* less significant 32 bits */ } ntp64; /* @@ -82,9 +80,9 @@ typedef struct { */ struct rtcp_sr { ntp64 sr_ntp; /* 64-bit ntp timestamp */ - u_int sr_ts; /* reference media timestamp */ - u_int sr_np; /* no. packets sent */ - u_int sr_nb; /* no. bytes sent */ + u_int32_t sr_ts; /* reference media timestamp */ + u_int32_t sr_np; /* no. packets sent */ + u_int32_t sr_nb; /* no. bytes sent */ }; /* @@ -92,12 +90,12 @@ struct rtcp_sr { * Time stamps are middle 32-bits of ntp timestamp. */ struct rtcp_rr { - u_int rr_srcid; /* sender being reported */ - u_int rr_nl; /* no. packets lost */ - u_int rr_ls; /* extended last seq number received */ - u_int rr_dv; /* jitter (delay variance) */ - u_int rr_lsr; /* orig. ts from last rr from this src */ - u_int rr_dlsr; /* time from recpt of last rr to xmit time */ + 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*/ @@ -119,7 +117,7 @@ static void vat_print(const void *hdr, u_int len, register const struct udphdr *up) { /* vat/vt audio */ - u_int ts = *(u_short *)hdr; + u_int ts = *(u_int16_t *)hdr; if ((ts & 0xf060) != 0) { /* probably vt */ (void)printf(" udp/vt %u %d / %d", @@ -127,8 +125,8 @@ vat_print(const void *hdr, u_int len, register const struct udphdr *up) ts & 0x3ff, ts >> 10); } else { /* probably vat */ - u_int i0 = ntohl(((u_int *)hdr)[0]); - u_int i1 = ntohl(((u_int *)hdr)[1]); + u_int32_t i0 = (u_int32_t)ntohl(((u_int *)hdr)[0]); + u_int32_t i1 = (u_int32_t)ntohl(((u_int *)hdr)[1]); printf(" udp/vat %u c%d %u%s", (u_int32_t)(ntohs(up->uh_ulen) - sizeof(*up) - 8), i0 & 0xffff, @@ -147,8 +145,8 @@ rtp_print(const void *hdr, u_int len, register const struct udphdr *up) /* rtp v1 or v2 */ u_int *ip = (u_int *)hdr; u_int hasopt, hasext, contype, hasmarker; - u_int i0 = ntohl(((u_int *)hdr)[0]); - u_int i1 = ntohl(((u_int *)hdr)[1]); + u_int32_t i0 = (u_int32_t)ntohl(((u_int *)hdr)[0]); + u_int32_t i1 = (u_int32_t)ntohl(((u_int *)hdr)[1]); u_int dlen = ntohs(up->uh_ulen) - sizeof(*up) - 8; const char * ptype; @@ -182,7 +180,7 @@ rtp_print(const void *hdr, u_int len, register const struct udphdr *up) i0 & 0xffff, i1); if (vflag) { - printf(" %u", i1); + printf(" %u", (u_int32_t)ntohl(((u_int *)hdr)[2])); if (hasopt) { u_int i2, optlen; do { @@ -219,7 +217,7 @@ rtcp_print(const u_char *hdr, const u_char *ep) struct rtcp_sr *sr; struct rtcphdr *rh = (struct rtcphdr *)hdr; u_int len; - u_short flags; + u_int16_t flags; int cnt; double ts, dts; if ((u_char *)(rh + 1) > ep) { @@ -236,7 +234,7 @@ rtcp_print(const u_char *hdr, const u_char *ep) if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh)) printf(" [%d]", len); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); if ((u_char *)(sr + 1) > ep) { printf(" [|rtcp]"); return (ep); @@ -254,18 +252,18 @@ rtcp_print(const u_char *hdr, const u_char *ep) printf(" [%d]", len); rr = (struct rtcp_rr *)(rh + 1); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); break; case RTCP_PT_SDES: printf(" sdes %d", len); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); cnt = 0; break; case RTCP_PT_BYE: printf(" bye %d", len); if (vflag) - printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); + printf(" %u", (u_int32_t)ntohl(rh->rh_ssrc)); cnt = 0; break; default: @@ -292,6 +290,100 @@ rtcp_print(const u_char *hdr, const u_char *ep) return (hdr + len); } +static int udp_cksum(register const struct ip *ip, + register const struct udphdr *up, + register 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; + register 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 INET6 +static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up, + int len) +{ + int i, tlen; + register 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); + phu.ph.ph_nxt = IPPROTO_UDP; + + sum = 0; + for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) + sum += phu.pa[i]; + + 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); +} +#endif + + /* XXX probably should use getservbyname() and cache answers */ #define TFTP_PORT 69 /*XXX*/ #define KERBEROS_PORT 88 /*XXX*/ @@ -300,16 +392,22 @@ rtcp_print(const u_char *hdr, const u_char *ep) #define NTP_PORT 123 /*XXX*/ #define SNMPTRAP_PORT 162 /*XXX*/ #define ISAKMP_PORT 500 /*XXX*/ +#define TIMED_PORT 525 /*XXX*/ #define RIP_PORT 520 /*XXX*/ #define KERBEROS_SEC_PORT 750 /*XXX*/ #define L2TP_PORT 1701 /*XXX*/ -#define ISAKMP_PORT_USER1 7500 /*??? - nonstandard*/ -#define ISAKMP_PORT_USER2 8500 /*??? - nonstandard*/ +#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/ +#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/ #define RX_PORT_LOW 7000 /*XXX*/ #define RX_PORT_HIGH 7009 /*XXX*/ #define NETBIOS_NS_PORT 137 #define NETBIOS_DGRAM_PORT 138 #define CISCO_AUTORP_PORT 496 /*XXX*/ +#define RADIUS_PORT 1645 +#define RADIUS_NEW_PORT 1812 +#define RADIUS_ACCOUNTING_PORT 1646 +#define RADIUS_NEW_ACCOUNTING_PORT 1813 +#define LWRES_PORT 921 #ifdef INET6 #define RIPNG_PORT 521 /*XXX*/ @@ -318,13 +416,14 @@ rtcp_print(const u_char *hdr, const u_char *ep) #endif void -udp_print(register const u_char *bp, u_int length, register const u_char *bp2) +udp_print(register const u_char *bp, u_int length, + register const u_char *bp2, int fragmented) { register const struct udphdr *up; register const struct ip *ip; register const u_char *cp; register const u_char *ep = bp + length; - u_short sport, dport, ulen; + u_int16_t sport, dport, ulen; #ifdef INET6 register const struct ip6_hdr *ip6; #endif @@ -334,7 +433,7 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) up = (struct udphdr *)bp; ip = (struct ip *)bp2; #ifdef INET6 - if (ip->ip_v == 6) + if (IP_V(ip) == 6) ip6 = (struct ip6_hdr *)bp2; else ip6 = NULL; @@ -356,6 +455,13 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) sport = ntohs(up->uh_sport); dport = ntohs(up->uh_dport); ulen = ntohs(up->uh_ulen); + if (ulen < 8) { + (void)printf("%s > %s: truncated-udplength %d", + ipaddr_string(&ip->ip_src), + ipaddr_string(&ip->ip_dst), + ulen); + return; + } if (packettype) { register struct rpc_msg *rp; enum msg_type direction; @@ -418,6 +524,15 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) udpport_string(dport)); snmp_print((const u_char *)(up + 1), length); break; + + case PT_CNFP: + (void)printf("%s.%s > %s.%s:", + ipaddr_string(&ip->ip_src), + udpport_string(sport), + ipaddr_string(&ip->ip_dst), + udpport_string(dport)); + cnfp_print(cp, length, (const u_char *)ip); + break; } return; } @@ -451,7 +566,7 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) (atalk_port(sport) || atalk_port(dport))) { if (vflag) fputs("kip ", stdout); - atalk_print(cp, length); + llap_print(cp, length); return; } } @@ -488,10 +603,38 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) } #endif + if (IP_V(ip) == 4 && vflag && !fragmented) { + int sum = up->uh_sum; + if (sum == 0) { + (void)printf("[no cksum] "); + } else if (TTEST2(cp[0], length)) { + sum = udp_cksum(ip, up, length); + if (sum != 0) + (void)printf("[bad udp cksum %x!] ", sum); + else + (void)printf("[udp sum ok] "); + } + } +#ifdef INET6 + if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !fragmented) { + int sum = up->uh_sum; + /* for IPv6, UDP checksum is mandatory */ + if (TTEST2(cp[0], length)) { + sum = udp6_cksum(ip6, up, length); + if (sum != 0) + (void)printf("[bad udp cksum %x!] ", sum); + else + (void)printf("[udp sum ok] "); + } + } +#endif + if (!qflag) { #define ISPORT(p) (dport == (p) || sport == (p)) if (ISPORT(NAMESERVER_PORT)) ns_print((const u_char *)(up + 1), length); + else if (ISPORT(TIMED_PORT)) + timed_print((const u_char *)(up + 1), length); else if (ISPORT(TFTP_PORT)) tftp_print((const u_char *)(up + 1), length); else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS)) @@ -514,10 +657,10 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) else if (ISPORT(L2TP_PORT)) l2tp_print((const u_char *)(up + 1), length); else if (ISPORT(NETBIOS_NS_PORT)) { - nbt_udp137_print((const u_char *)(up + 1), length); + nbt_udp137_print((const u_char *)(up + 1), length); } else if (ISPORT(NETBIOS_DGRAM_PORT)) { - nbt_udp138_print((const u_char *)(up + 1), length); + nbt_udp138_print((const u_char *)(up + 1), length); } else if (dport == 3456) vat_print((const void *)(up + 1), length, up); @@ -544,6 +687,13 @@ udp_print(register const u_char *bp, u_int length, register const u_char *bp2) wb_print((const void *)(up + 1), length); else if (ISPORT(CISCO_AUTORP_PORT)) cisco_autorp_print((const void *)(up + 1), length); + else if (ISPORT(RADIUS_PORT) || + ISPORT(RADIUS_NEW_PORT) || + ISPORT(RADIUS_ACCOUNTING_PORT) || + ISPORT(RADIUS_NEW_ACCOUNTING_PORT) ) + radius_print((const u_char *)(up+1), length); + else if (ISPORT(LWRES_PORT)) + lwres_print((const u_char *)(up + 1), length); else (void)printf(" udp %u", (u_int32_t)(ulen - sizeof(*up)));