tcpdump mailing list archives
UDP-lite (rfc 3828)
From: Darren Reed <darrenr () reed wattle id au>
Date: Wed, 14 Jul 2004 17:48:25 +1000 (EST)
A new RFC (3828) documents a slightly modified UDP protocol, #136, called "UDP-Lite". For the true geeks, 136 is 10001000 and UDP (17) is 00010001 :) The main difference is the length field bcomes a checksum length field with valid values 0,[8,65535]. This indicates the amount of data in the 'UDP' portion of the packet to checksum. A value of 0 indicates "all", 8 is just the UDP header, and so on. Values for this field in the interval [1,7] are not valid. I expect that the same port assignments for UDP will exist for UDP-lite and given this, it might be appropriate to also use uporttable[] (addrtoname.c) for udplite as well as udp ? I've roughed up some patches below to account for IPPROTO_UDPLITE, but the real problem is no real packets to test it on :-o The patches overload print-udp.c, which seems like a better idea than creating print-udplite.c given the extreme similariies but if someone wants to disagree, I won't stop you. Darren Index: interface.h =================================================================== diff -c -u -r1.1.1.1 interface.h --- interface.h 8 Jul 2004 11:07:12 -0000 1.1.1.1 +++ interface.h 14 Jul 2004 06:16:50 -0000 @@ -252,7 +252,7 @@ extern void tcp_print(const u_char *, u_int, const u_char *, int); extern void tftp_print(const u_char *, u_int); extern void timed_print(const u_char *); -extern void udp_print(const u_char *, u_int, const u_char *, int); +extern void udp_print(const u_char *, u_int, const u_char *, int, int); extern void wb_print(const void *, u_int); extern int ah_print(register const u_char *); extern void isakmp_print(const u_char *, u_int, const u_char *); Index: ipproto.h =================================================================== diff -c -u -r1.1.1.1 ipproto.h --- ipproto.h 8 Jul 2004 11:07:12 -0000 1.1.1.1 +++ ipproto.h 14 Jul 2004 06:13:34 -0000 @@ -136,3 +136,6 @@ #ifndef IPPROTO_MOBILITY #define IPPROTO_MOBILITY 135 #endif +#ifndef IPPROTO_UDPLITE +#define IPPROTO_UDPLITE 136 /* Lightweight User Datagram Protocol (RFC 3828) */ +#endif Index: netdissect.h =================================================================== diff -c -u -r1.1.1.1 netdissect.h --- netdissect.h 8 Jul 2004 11:07:12 -0000 1.1.1.1 +++ netdissect.h 14 Jul 2004 06:16:55 -0000 @@ -363,7 +363,7 @@ extern void tftp_print(netdissect_options *,const u_char *, u_int); extern void timed_print(netdissect_options *,const u_char *, u_int); extern void udp_print(netdissect_options *,const u_char *, u_int, - const u_char *, int); + const u_char *, int, int); extern void wb_print(netdissect_options *,const void *, u_int); extern int ah_print(netdissect_options *,register const u_char *, register const u_char *); Index: print-ip.c =================================================================== diff -c -u -r1.1.1.1 print-ip.c --- print-ip.c 8 Jul 2004 11:07:12 -0000 1.1.1.1 +++ print-ip.c 14 Jul 2004 06:06:53 -0000 @@ -536,7 +536,8 @@ break; case IPPROTO_UDP: - udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); + case IPPROTO_UDPLITE: + udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000), nh); break; case IPPROTO_ICMP: Index: print-udp.c =================================================================== diff -c -u -r1.2 print-udp.c --- print-udp.c 8 Jul 2004 11:10:37 -0000 1.2 +++ print-udp.c 14 Jul 2004 07:46:43 -0000 @@ -107,20 +107,22 @@ #define RTCP_PT_APP 204 static void -vat_print(const void *hdr, register const struct udphdr *up) +vat_print(const void *hdr, register const struct udphdr *up, int protocol) { /* vat/vt audio */ u_int ts = *(u_int16_t *)hdr; if ((ts & 0xf060) != 0) { /* probably vt */ - (void)printf("udp/vt %u %d / %d", + (void)printf("udp%s/vt %u %d / %d", + (protocol == IPPROTO_UDPLITE) ? "lite" : "", (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)), ts & 0x3ff, ts >> 10); } else { /* probably vat */ u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]); u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]); - printf("udp/vat %u c%d %u%s", + printf("udp%s/vat %u c%d %u%s", + (protocol == IPPROTO_UDPLITE) ? "lite" : "", (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8), i0 & 0xffff, i1, i0 & 0x800000? "*" : ""); @@ -133,7 +135,7 @@ } static void -rtp_print(const void *hdr, u_int len, register const struct udphdr *up) +rtp_print(const void *hdr, u_int len, register const struct udphdr *up, const int protocol) { /* rtp v1 or v2 */ u_int *ip = (u_int *)hdr; @@ -164,7 +166,8 @@ ip += 1; len -= 1; } - printf("udp/%s %d c%d %s%s %d %u", + printf("udp%s/%s %d c%d %s%s %d %u", + (protocol == IPPROTO_UDPLITE) ? "lite" : "", ptype, dlen, contype, @@ -285,7 +288,8 @@ static int udp_cksum(register const struct ip *ip, register const struct udphdr *up, - register u_int len) + register u_int len, + register u_in protocol) { union phu { struct phdr { @@ -302,7 +306,7 @@ /* pseudo-header.. */ phu.ph.len = htons((u_int16_t)len); phu.ph.mbz = 0; - phu.ph.proto = IPPROTO_UDP; + phu.ph.proto = protocol; memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t)); if (IP_HL(ip) == 5) memcpy(&phu.ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t)); @@ -417,7 +421,8 @@ void udp_print(register const u_char *bp, u_int length, - register const u_char *bp2, int fragmented) + register const u_char *bp2, int fragmented, + int protocol) { register const struct udphdr *up; register const struct ip *ip; @@ -475,7 +480,7 @@ case PT_VAT: udpipaddr_print(ip, sport, dport); - vat_print((void *)(up + 1), up); + vat_print((void *)(up + 1), up, protocol); break; case PT_WB: @@ -496,7 +501,7 @@ case PT_RTP: udpipaddr_print(ip, sport, dport); - rtp_print((void *)(up + 1), length, up); + rtp_print((void *)(up + 1), length, up, protocol); break; case PT_RTCP: @@ -570,26 +575,62 @@ if (IP_V(ip) == 4 && (vflag > 1) && !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 + sizeof(struct udphdr)); - if (sum != 0) - (void)printf("[bad udp cksum %x!] ", sum); - else - (void)printf("[udp sum ok] "); + + if (protocol == IPPROTO_UDP) { + if (sum == 0) { + (void)printf("[no cksum] "); + } else if (TTEST2(cp[0], length)) { + sum = udp_cksum(ip, up, length + sizeof(struct udphdr), nh); + if (sum != 0) + (void)printf("[bad udp cksum %x!] ", sum); + else + (void)printf("[udp sum ok] "); + } + } + if (protocol == IPPROTO_UDPLITE) { + int uhlen = up->uh_ulen, sum = 0; + + if (uhlen == 0) + uhlen = length; + + if (uhlen > 0 && uhlen < 8) { + (void)printf("[bad udplite checksum length %d] ", uhlen); + } else if (TTEST2(cp[0], uhlen)) { + sum = udp_cksum(ip, up, uhlen + sizeof(struct udphdr), nh); + if (sum != 0) + (void)printf("[bad udplite cksum %x!] ", sum); + else + (void)printf("[udplite 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 + sizeof(struct udphdr)); - if (sum != 0) - (void)printf("[bad udp cksum %x!] ", sum); - else - (void)printf("[udp sum ok] "); + if (protocol == IPPROTO_UDP) { + if (TTEST2(cp[0], length)) { + sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr)); + if (sum != 0) + (void)printf("[bad udp cksum %x!] ", sum); + else + (void)printf("[udp sum ok] "); + } + } else if (protocol == IPPROTO_UDPLITE) { + int uhlen = up->uh_ulen; + + if (uhlen == 0) + uhlen = length; + + if (uhlen > 0 && uhlen < 8) { + (void)printf("[bad udplite checksum length %d] ", uhlen); + } else if (TTEST2(cp[0], uhlen)) { + sum = udp6_cksum(ip6, up, uhlen + (struct udphdr)); + if (sum != 0) + (void)printf("[bad udplite cksum %x!] ", sum); + else + (void)printf("[udplite sum ok] "); + } } } #endif @@ -642,7 +683,7 @@ nbt_udp138_print((const u_char *)(up + 1), length); #endif else if (dport == 3456) - vat_print((const void *)(up + 1), up); + vat_print((const void *)(up + 1), up, protocol); else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT)) zephyr_print((const void *)(up + 1), length); /* - This is the tcpdump-workers list. Visit https://lists.sandelman.ca/ to unsubscribe.
Current thread:
- UDP-lite (rfc 3828) Darren Reed (Jul 14)