summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2011-06-17 01:09:16 -0700
committerGuy Harris <guy@alum.mit.edu>2011-06-17 01:09:16 -0700
commit57bfcb4ebe253111f5d0c12e2269846678306c2a (patch)
treed51bf19ad10f43b4f3404f9ffe18fae3050ade23
parentd18bb2331dbcb9585d6ca2de96ad02a2ddb7ad03 (diff)
downloadtcpdump-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.h2
-rw-r--r--netdissect.h1
-rw-r--r--print-dccp.c29
-rw-r--r--print-ip.c35
-rw-r--r--print-tcp.c26
-rw-r--r--print-udp.c26
6 files changed, 43 insertions, 76 deletions
diff --git a/ip.h b/ip.h
index fd53503e..8a97632e 100644
--- a/ip.h
+++ b/ip.h
@@ -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
diff --git a/print-ip.c b/print-ip.c
index 21f83c10..d2df0a89 100644
--- a/print-ip.c
+++ b/print-ip.c
@@ -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