diff options
author | Guy Harris <guy@alum.mit.edu> | 2011-06-17 01:09:16 -0700 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2011-06-17 01:09:16 -0700 |
commit | 57bfcb4ebe253111f5d0c12e2269846678306c2a (patch) | |
tree | d51bf19ad10f43b4f3404f9ffe18fae3050ade23 | |
parent | d18bb2331dbcb9585d6ca2de96ad02a2ddb7ad03 (diff) | |
download | tcpdump-57bfcb4ebe253111f5d0c12e2269846678306c2a.tar.gz |
Add a routine to do the "checksum with pseudo-header" stuff for IPv4.
Clean up some other stuff while we're at it.
-rw-r--r-- | ip.h | 2 | ||||
-rw-r--r-- | netdissect.h | 1 | ||||
-rw-r--r-- | print-dccp.c | 29 | ||||
-rw-r--r-- | print-ip.c | 35 | ||||
-rw-r--r-- | print-tcp.c | 26 | ||||
-rw-r--r-- | print-udp.c | 26 |
6 files changed, 43 insertions, 76 deletions
@@ -161,4 +161,4 @@ struct ip_timestamp { #define IP_MSS 576 /* default maximum segment size */ /* in print-ip.c */ -extern u_int32_t ip_finddst(const struct ip *); +extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int); diff --git a/netdissect.h b/netdissect.h index 5363988f..700c71a4 100644 --- a/netdissect.h +++ b/netdissect.h @@ -352,6 +352,7 @@ extern void igmp_print(netdissect_options *, register const u_char *, u_int); extern void igrp_print(netdissect_options *,const u_char *, u_int, const u_char *); +extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int); extern void ipN_print(netdissect_options *,const u_char *, u_int); extern void ipx_print(netdissect_options *,const u_char *, u_int); extern void isoclns_print(netdissect_options *,const u_char *, diff --git a/print-dccp.c b/print-dccp.c index 96aa7ab2..79ea5f72 100644 --- a/print-dccp.c +++ b/print-dccp.c @@ -60,7 +60,7 @@ static const char *dccp_feature_nums[] = { "check data checksum", }; -static inline int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) +static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) { u_int cov; @@ -73,31 +73,8 @@ static inline int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len) static int dccp_cksum(const struct ip *ip, const struct dccp_hdr *dh, u_int len) { - int cov = dccp_csum_coverage(dh, 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.mbz = 0; - ph.len = htons(len); - ph.proto = IPPROTO_DCCP; - 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 *)dh; - vec[1].len = cov; - return in_cksum(vec, 2); + return nextproto4_cksum(ip, (const u_int8_t *)(void *)dh, + dccp_csum_coverage(dh, len), IPPROTO_DCCP); } #ifdef INET6 @@ -87,7 +87,7 @@ ip_printroute(register const u_char *cp, u_int length) * This is used for UDP and TCP pseudo-header in the checksum * calculation. */ -u_int32_t +static u_int32_t ip_finddst(const struct ip *ip) { int length; @@ -129,6 +129,39 @@ trunc: return retval; } +/* + * Compute a V4-style checksum by building a pseudoheader. + */ +int +nextproto4_cksum(const struct ip *ip, const u_int8_t *data, + u_int len, u_int next_proto) +{ + 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 = next_proto; + 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 = data; + vec[1].len = len; + return (in_cksum(vec, 2)); +} + static void ip_printts(register const u_char *cp, u_int length) { diff --git a/print-tcp.c b/print-tcp.c index 82840419..88b46157 100644 --- a/print-tcp.c +++ b/print-tcp.c @@ -129,30 +129,8 @@ static int tcp_cksum(register const struct ip *ip, register const struct tcphdr *tp, 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_TCP; - 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 *)tp; - vec[1].len = len; - return in_cksum(vec, 2); + return (nextproto4_cksum(ip, (const u_int8_t *)tp, len, + IPPROTO_TCP)); } void diff --git a/print-udp.c b/print-udp.c index 02a1e6ec..da6cfd38 100644 --- a/print-udp.c +++ b/print-udp.c @@ -286,30 +286,8 @@ 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 |