]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-udp.c
Add changes in 4.2.1.
[tcpdump] / print-udp.c
index 640ac0d3cd9b5a48dd9c7653ba700387e8338c82..885d42e4da0c201e1bafa0bdba38d99147cf6de5 100644 (file)
@@ -286,57 +286,16 @@ static int udp_cksum(register const struct ip *ip,
                     register const struct udphdr *up,
                     register u_int len)
 {
-       struct phdr {
-               u_int32_t src;
-               u_int32_t dst;
-               u_char mbz;
-               u_char proto;
-               u_int16_t len;
-       } ph;
-       struct cksum_vec vec[2];
-
-       /* pseudo-header.. */
-       ph.len = htons((u_int16_t)len);
-       ph.mbz = 0;
-       ph.proto = IPPROTO_UDP;
-       memcpy(&ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
-       if (IP_HL(ip) == 5)
-               memcpy(&ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
-       else
-               ph.dst = ip_finddst(ip);
-
-       vec[0].ptr = (const u_int8_t *)(void *)&ph;
-       vec[0].len = sizeof(ph);
-       vec[1].ptr = (const u_int8_t *)(void *)up;
-       vec[1].len = len;
-       return (in_cksum(vec, 2));
+       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)
 {
-       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;
-       struct cksum_vec vec[2];
-
-       /* pseudo-header */
-       memset(&ph, 0, sizeof(ph));
-       ph.ph_src = ip6->ip6_src;
-       ph.ph_dst = ip6->ip6_dst;
-       ph.ph_len = htonl(len);
-       ph.ph_nxt = IPPROTO_UDP;
-
-       vec[0].ptr = (const u_int8_t *)(void *)&ph;
-       vec[0].len = sizeof(ph);
-       vec[1].ptr = (const u_int8_t *)(void *)up;
-       vec[1].len = len;
-       return (in_cksum(vec, 2));
+       return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len,
+           IPPROTO_UDP));
 }
 #endif
 
@@ -549,31 +508,46 @@ udp_print(register const u_char *bp, u_int length,
        }
        udpipaddr_print(ip, sport, dport);
 
-       if (IP_V(ip) == 4 && (vflag > 1) && !Kflag && !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 && !Kflag && !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))
@@ -635,7 +609,7 @@ udp_print(register const u_char *bp, u_int length,
                        ripng_print((const u_char *)(up + 1), length);
                else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT))
                        dhcp6_print((const u_char *)(up + 1), length);
-               else if (ISPORT(BABEL_PORT))
+               else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD))
                        babel_print((const u_char *)(up + 1), length);
 #endif /*INET6*/
                /*