X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/94a4b4608009a96bf791ff24b2d019f40a120085..a90e99737eceb0041b83d95895b6d46eea41124f:/print-udp.c diff --git a/print-udp.c b/print-udp.c index 640ac0d3..885d42e4 100644 --- a/print-udp.c +++ b/print-udp.c @@ -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*/ /*