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)
