Merge remote-tracking branch 'goog/tcpdump'

* goog/tcpdump: (3066 commits)
  Remove old version. Getting ready for new tcpdump 4.5
  Support -Q for setting the capture direction.
  Clean up the TLV processing loop.
  With -A and -AA, don't send CRs to the standard output.
  Use the new libpcap <pcap/nflog.h> for NFLOG definitions and declarations.
  Do our own isascii(), isprint(), isgraph(), and toascii().
  Fix a compiler warning.
  Don't use the __attribute__((packed)) on most platforms.
  The interval in an AODV HELLO extension is not aligned on a 4-byte boundary.
  As with memcpy, so with memcmp.
  More UNALIGNED_MEM{CPY,CMP} on IP addresses.
  Another case where UNALIGNED_MEMCPY() is probably necessary.
  No need for casting back and forth.
  Only do the unaligned_mem{cpy,cmp} hack if necessary.
  No need to declare unaligned_mem{cpy,cmp} in netdissect.h *and* interface.h.
  More possibly-unaligned memcpy()s and assignments - use unaligned_memcpy().
  Check for compiling for IPv6; don't check whether we can create an IPv6 socket.
  Use unaligned_memcmp() to compare with IPv{4,6} addresses in a packet.
  Use EXTRACT_nBITS even when just testing against zero.
  Fix some more unaligned accesses.
  ...

Change-Id: I9e98707d30c989b9e32dcd5af798bd0746ab4434
diff --git a/print-udp.c b/print-udp.c
index d2983b6..8148023 100644
--- a/print-udp.c
+++ b/print-udp.c
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.138.2.1 2007/03/28 07:45:46 hannes Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.142 2007-08-08 17:20:58 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -33,8 +33,6 @@
 #ifdef SEGSIZE
 #undef SEGSIZE
 #endif
-//#include <arpa/tftp.h>
-#include "tftp.h"
 
 #include <stdio.h>
 #include <string.h>
@@ -288,75 +286,16 @@
 		     register const struct udphdr *up,
 		     register u_int len)
 {
-	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;
-
-	/* pseudo-header.. */
-	phu.ph.len = htons((u_int16_t)len);
-	phu.ph.mbz = 0;
-	phu.ph.proto = IPPROTO_UDP;
-	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));
-	else
-		phu.ph.dst = ip_finddst(ip);
-
-	sp = &phu.pa[0];
-	return in_cksum((u_short *)up, len,
-			sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
+	return (nextproto4_cksum(ip, (const u_int8_t *)(void *)up, len,
+	    IPPROTO_UDP));
 }
 
 #ifdef INET6
 static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
 	u_int len)
 {
-	size_t i;
-	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;
-
-	/* 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(len);
-	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 < (len & ~1); i += 2)
-		sum += *sp++;
-
-	if (len & 1)
-		sum += htons((*(const u_int8_t *)sp) << 8);
-
-	while (sum > 0xffff)
-		sum = (sum & 0xffff) + (sum >> 16);
-	sum = ~sum & 0xffff;
-
-	return (sum);
+	return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len,
+	    IPPROTO_UDP));
 }
 #endif
 
@@ -530,6 +469,26 @@
 			    0);
 #endif
 			break;
+
+		case PT_RADIUS:
+			udpipaddr_print(ip, sport, dport);
+			radius_print(cp, length);
+			break;
+
+		case PT_VXLAN:
+			udpipaddr_print(ip, sport, dport);
+			vxlan_print((const u_char *)(up + 1), length);
+			break;
+
+		case PT_PGM:
+		case PT_PGM_ZMTP1:
+			udpipaddr_print(ip, sport, dport);
+			pgm_print(cp, length, bp2);
+			break;
+		case PT_LMP:
+			udpipaddr_print(ip, sport, dport);
+			lmp_print(cp, length);
+			break;
 		}
 		return;
 	}
@@ -569,31 +528,46 @@
 	}
 	udpipaddr_print(ip, sport, dport);
 
-	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 (vflag && !Kflag && !fragmented) {
+                /* Check the checksum, if possible. */
+                u_int16_t sum, udp_sum;
+
+		/*
+		 * XXX - do this even if vflag == 1?
+		 * TCP does, and we do so for UDP-over-IPv6.
+		 */
+	        if (IP_V(ip) == 4 && (vflag > 1)) {
+			udp_sum = EXTRACT_16BITS(&up->uh_sum);
+			if (udp_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 0x%04x -> 0x%04x!] ",
+					    udp_sum,
+					    in_cksum_shouldbe(udp_sum, 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 + sizeof(struct udphdr));
-			if (sum != 0)
-				(void)printf("[bad udp cksum %x!] ", sum);
-			else
-				(void)printf("[udp sum ok] ");
+		else if (IP_V(ip) == 6 && ip6->ip6_plen) {
+			/* for IPv6, UDP checksum is mandatory */
+			if (TTEST2(cp[0], length)) {
+				sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr));
+				udp_sum = EXTRACT_16BITS(&up->uh_sum);
+
+	                        if (sum != 0) {
+        	                        (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ",
+					    udp_sum,
+					    in_cksum_shouldbe(udp_sum, sum));
+				} else
+					(void)printf("[udp sum ok] ");
+			}
 		}
-	}
 #endif
+	}
 
 	if (!qflag) {
 #define ISPORT(p) (dport == (p) || sport == (p))
@@ -638,7 +612,7 @@
 		else if (ISPORT(NETBIOS_DGRAM_PORT))
 			nbt_udp138_print((const u_char *)(up + 1), length);
 #endif
-		else if (dport == 3456)
+		else if (dport == VAT_PORT)
 			vat_print((const void *)(up + 1), up);
 		else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT))
 			zephyr_print((const void *)(up + 1), length);
@@ -653,14 +627,15 @@
 #ifdef INET6
 		else if (ISPORT(RIPNG_PORT))
 			ripng_print((const u_char *)(up + 1), length);
-		else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) {
+		else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT))
 			dhcp6_print((const u_char *)(up + 1), length);
-		}
+		else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD))
+			babel_print((const u_char *)(up + 1), length);
 #endif /*INET6*/
 		/*
 		 * Kludge in test for whiteboard packets.
 		 */
-		else if (dport == 4567)
+		else if (dport == WB_PORT)
 			wb_print((const void *)(up + 1), length);
 		else if (ISPORT(CISCO_AUTORP_PORT))
 			cisco_autorp_print((const void *)(up + 1), length);
@@ -673,21 +648,40 @@
 			hsrp_print((const u_char *)(up + 1), length);
 		else if (ISPORT(LWRES_PORT))
 			lwres_print((const u_char *)(up + 1), length);
-                else if (ISPORT(LDP_PORT))
+		else if (ISPORT(LDP_PORT))
 			ldp_print((const u_char *)(up + 1), length);
-                else if (ISPORT(OLSR_PORT))
-			olsr_print((const u_char *)(up + 1), length);
-                else if (ISPORT(MPLS_LSP_PING_PORT))
+		else if (ISPORT(OLSR_PORT))
+			olsr_print((const u_char *)(up + 1), length,
+#if INET6
+					(IP_V(ip) == 6) ? 1 : 0);
+#else
+					0);
+#endif
+		else if (ISPORT(MPLS_LSP_PING_PORT))
 			lspping_print((const u_char *)(up + 1), length);
 		else if (dport == BFD_CONTROL_PORT ||
 			 dport == BFD_ECHO_PORT )
 			bfd_print((const u_char *)(up+1), length, dport);
                 else if (ISPORT(LMP_PORT))
 			lmp_print((const u_char *)(up + 1), length);
+		else if (ISPORT(VQP_PORT))
+			vqp_print((const u_char *)(up + 1), length);
+                else if (ISPORT(SFLOW_PORT))
+                        sflow_print((const u_char *)(up + 1), length);
+	        else if (dport == LWAPP_CONTROL_PORT)
+			lwapp_control_print((const u_char *)(up + 1), length, 1);
+                else if (sport == LWAPP_CONTROL_PORT)
+                        lwapp_control_print((const u_char *)(up + 1), length, 0);
+                else if (ISPORT(LWAPP_DATA_PORT))
+                        lwapp_data_print((const u_char *)(up + 1), length);
                 else if (ISPORT(SIP_PORT))
 			sip_print((const u_char *)(up + 1), length);
                 else if (ISPORT(SYSLOG_PORT))
 			syslog_print((const u_char *)(up + 1), length);
+                else if (ISPORT(OTV_PORT))
+			otv_print((const u_char *)(up + 1), length);
+                else if (ISPORT(VXLAN_PORT))
+			vxlan_print((const u_char *)(up + 1), length);
 		else
 			(void)printf("UDP, length %u",
 			    (u_int32_t)(ulen - sizeof(*up)));
@@ -703,3 +697,4 @@
  * c-basic-offset: 8
  * End:
  */
+