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: