]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Calculate UDP/TCP pseudo-checksum properly in the presence of
authorfenner <fenner>
Sun, 28 Jul 2002 04:14:21 +0000 (04:14 +0000)
committerfenner <fenner>
Sun, 28 Jul 2002 04:14:21 +0000 (04:14 +0000)
 source-route options.

ip.h
print-ip.c
print-tcp.c
print-udp.c

diff --git a/ip.h b/ip.h
index 5b7e449ce44e03583fce6b7e92fc287ec326bd0e..dd8bad60b5526faa5649cd21d677c30ff6a16a07 100644 (file)
--- a/ip.h
+++ b/ip.h
@@ -1,4 +1,4 @@
-/* @(#) $Header: /tcpdump/master/tcpdump/ip.h,v 1.7 2000-10-03 09:17:40 guy Exp $ (LBL) */
+/* @(#) $Header: /tcpdump/master/tcpdump/ip.h,v 1.8 2002-07-28 04:14:21 fenner Exp $ (LBL) */
 /*
  * Copyright (c) 1982, 1986, 1993
  *     The Regents of the University of California.  All rights reserved.
@@ -157,3 +157,6 @@ struct      ip_timestamp {
 #define        IPTTLDEC        1               /* subtracted when forwarding */
 
 #define        IP_MSS          576             /* default maximum segment size */
+
+/* in print-ip.c */
+extern u_int32_t ip_finddst(const struct ip *);
index d8eda70a23e85fe7b490ac8a920dcd7d2b0c3a4b..0ab20d3b15b1cfc09ea97878169d913bb3b92794 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.109 2002-07-21 20:48:26 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.110 2002-07-28 04:14:21 fenner Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -76,6 +76,52 @@ ip_printroute(const char *type, register const u_char *cp, u_int length)
        printf("%s}", ptr == len? "#" : "");
 }
 
+/*
+ * If source-routing is present, return the final destination.
+ * Otherwise, return IP destination.
+ *
+ * This is used for UDP and TCP pseudo-header in the checksum
+ * calculation.
+ */
+u_int32_t
+ip_finddst(const struct ip *ip)
+{
+       int length;
+       int len;
+       const u_char *cp;
+       uint32_t retval;
+
+       cp = (const u_char *)(ip + 1);
+       length = (IP_HL(ip) << 2) - sizeof(struct ip);
+
+       for (; length > 0; cp += len, length -= len) {
+               int tt = *cp;
+
+               if (tt == IPOPT_NOP || tt == IPOPT_EOL)
+                       len = 1;
+               else {
+                       if (&cp[1] >= snapend) {
+                               return 0;
+                       }
+                       len = cp[1];
+               }
+               if (len <= 0) {
+                       return 0;
+               }
+               if (&cp[1] >= snapend || cp + len > snapend) {
+                       return 0;
+               }
+               switch (tt) {
+
+               case IPOPT_SSRR:
+               case IPOPT_LSRR:
+                       memcpy(&retval, cp + len - 4, 4);
+                       return retval;
+               }
+       }
+       return ip->ip_dst.s_addr;
+}
+
 static void
 ip_printts(register const u_char *cp, u_int length)
 {
index 1f57dfcf46e7388d53b083d0241d4c0f50d39f00..0d924dea87c1a15e6dc6ef5a73ae4d6a721ea2de 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.96 2002-07-21 20:56:24 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.97 2002-07-28 04:14:22 fenner Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -122,7 +122,10 @@ static int tcp_cksum(register const struct ip *ip,
        phu.ph.mbz = 0;
        phu.ph.proto = IPPROTO_TCP;
        memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
-       memcpy(&phu.ph.dst, &ip->ip_dst.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 *)tp, len,
index c27989f6870615ff7463bb6d461862c202ae82b6..f8b6a070f54610d9264057fb35370acc20eb695c 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.104 2002-06-11 17:08:58 itojun Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.105 2002-07-28 04:14:22 fenner Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -305,7 +305,10 @@ static int udp_cksum(register const struct ip *ip,
        phu.ph.mbz = 0;
        phu.ph.proto = IPPROTO_UDP;
        memcpy(&phu.ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
-       memcpy(&phu.ph.dst, &ip->ip_dst.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,