]> The Tcpdump Group git mirrors - tcpdump/commitdiff
modularize ip6 nextlayer checksum generation and
authorHannes Gredler <[email protected]>
Mon, 12 Oct 2009 08:16:58 +0000 (10:16 +0200)
committerHannes Gredler <[email protected]>
Mon, 12 Oct 2009 08:16:58 +0000 (10:16 +0200)
change tcp6 and pim6 to use it.

interface.h
ip6.h
netdissect.h
print-ip.c
print-ip6.c
print-pim.c
print-tcp.c

index afeaee968430c18a1caddfdb14daae139f33315b..7685a308c8f58ebaf7e4ca7f4a0f33d0d672b25f 100644 (file)
@@ -1,4 +1,4 @@
-/*
+im/*
  * Copyright (c) 1988-2002
  *     The Regents of the University of California.  All rights reserved.
  *
@@ -241,7 +241,7 @@ extern void lwapp_control_print(const u_char *, u_int, int);
 extern void lwapp_data_print(const u_char *, u_int);
 extern void eigrp_print(const u_char *, u_int);
 extern void mobile_print(const u_char *, u_int);
-extern void pim_print(const u_char *, u_int);
+extern void pim_print(const u_char *, u_int, u_int);
 extern u_int pppoe_print(const u_char *, u_int);
 extern u_int ppp_print(register const u_char *, u_int);
 extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *);
@@ -327,6 +327,7 @@ extern u_int usb_linux_print(const struct pcap_pkthdr *, const u_char *);
 #ifdef INET6
 extern void ip6_print(const u_char *, u_int);
 extern void ip6_opt_print(const u_char *, int);
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_short *, u_int, u_int);
 extern int hbhopt_print(const u_char *);
 extern int dstopt_print(const u_char *);
 extern int frag6_print(const u_char *, const u_char *);
diff --git a/ip6.h b/ip6.h
index e4f9fe1c9e5ef00278090e9fcfbb422b1d647d1c..a6df97aae10b2251feef2547ad18e281a2dd4cb6 100644 (file)
--- a/ip6.h
+++ b/ip6.h
@@ -88,6 +88,20 @@ struct ip6_hdr {
        struct in6_addr ip6_dst;        /* destination address */
 };
 
+/*
+ * Pseudo header, used for higher layer checksumming.
+ */
+union ip6_pseudo_hdr {
+    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;
+    u_int16_t pa[20];
+};
+
 #define ip6_vfc                ip6_ctlun.ip6_un2_vfc
 #define ip6_flow       ip6_ctlun.ip6_un1.ip6_un1_flow
 #define ip6_plen       ip6_ctlun.ip6_un1.ip6_un1_plen
index 9b64f3a5cb066953d55cfca3f6fbd84499806bb1..42ef245601203bd647c46c9e858fa7eae7923c93 100644 (file)
@@ -362,7 +362,7 @@ extern void ospf_print(netdissect_options *,const u_char *,
                       u_int, const u_char *);
 extern void pimv1_print(netdissect_options *,const u_char *, u_int);
 extern void mobile_print(netdissect_options *,const u_char *, u_int);
-extern void pim_print(netdissect_options *,const u_char *, u_int);
+extern void pim_print(netdissect_options *,const u_char *, u_int, u_int);
 extern void pppoe_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
 extern void pppoe_print(netdissect_options *,const u_char *, u_int);
 extern void ppp_print(netdissect_options *,
@@ -437,6 +437,7 @@ extern void pptp_print(netdissect_options *,const u_char *, u_int);
 #ifdef INET6
 extern void ip6_print(netdissect_options *,const u_char *, u_int);
 extern void ip6_opt_print(netdissect_options *,const u_char *, int);
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_short *, u_int, u_int);
 extern int hbhopt_print(netdissect_options *,const u_char *);
 extern int dstopt_print(netdissect_options *,const u_char *);
 extern int frag6_print(netdissect_options *,const u_char *,
index 3dd1edb9b0c5b0d2cf1cec7c04022430f4c970ae..acf3bd8be9fe0de2a466231ed54087ac960c7e92 100644 (file)
@@ -508,7 +508,8 @@ again:
                break;
 
        case IPPROTO_PIM:
-               pim_print(ipds->cp,  ipds->len);
+               pim_print(ipds->cp,  ipds->len,
+                         in_cksum((const u_short*)ipds->cp, ipds->len, 0));
                break;
 
        case IPPROTO_VRRP:
index 0758bb952ed021790886dc4889fc4a22b01956dd..7aa97a542dab930535ae854f2c930810c1fe9ce5 100644 (file)
@@ -43,6 +43,31 @@ static const char rcsid[] _U_ =
 #include "ip6.h"
 #include "ipproto.h"
 
+/*
+ * Compute a V6-style checksum by building a pseudoheader.
+ */
+int
+nextproto6_cksum(const struct ip6_hdr *ip6, const u_short *data,
+                u_int len, u_int next_proto)
+{
+        size_t i;
+        u_int32_t sum = 0;
+       union ip6_pseudo_hdr phu;
+
+        /* pseudo-header */
+        memset(&phu, 0, sizeof(phu));
+        phu.ph.ph_src = ip6->ip6_src;
+        phu.ph.ph_dst = ip6->ip6_dst;
+        phu.ph.ph_len = htonl(len);
+        phu.ph.ph_nxt = next_proto;
+
+        for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++) {
+                sum += phu.pa[i];
+       }
+
+        return in_cksum(data, len, sum);
+}
+
 /*
  * print an IP6 datagram.
  */
@@ -193,7 +218,8 @@ ip6_print(register const u_char *bp, register u_int length)
                    }
 
                case IPPROTO_PIM:
-                       pim_print(cp, len);
+                       pim_print(cp, len, nextproto6_cksum(ip6, (u_short *)cp, len,
+                                                           IPPROTO_PIM));
                        return;
 
                case IPPROTO_OSPF:
index 774096e2f934d10354210165fb92724ca54c764b..f9fd0c69f553b9a272742a9c3e932018f6ef060c 100644 (file)
@@ -118,7 +118,7 @@ struct pim {
 
 #include "ip.h"
 
-static void pimv2_print(register const u_char *bp, register u_int len);
+static void pimv2_print(register const u_char *bp, register u_int len, u_int cksum);
 
 static void
 pimv1_join_prune_print(register const u_char *bp, register u_int len)
@@ -413,7 +413,7 @@ trunc:
 }
 
 void
-pim_print(register const u_char *bp, register u_int len)
+pim_print(register const u_char *bp, register u_int len, u_int cksum)
 {
        register const u_char *ep;
        register struct pim *pim = (struct pim *)bp;
@@ -438,7 +438,7 @@ pim_print(register const u_char *bp, register u_int len)
                        PIM_VER(pim->pim_typever),
                        len,
                        tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)));
-                pimv2_print(bp, len);
+                pimv2_print(bp, len, cksum);
             }
             break;
        default:
@@ -618,7 +618,7 @@ trunc:
 }
 
 static void
-pimv2_print(register const u_char *bp, register u_int len)
+pimv2_print(register const u_char *bp, register u_int len, u_int cksum)
 {
        register const u_char *ep;
        register struct pim *pim = (struct pim *)bp;
@@ -638,9 +638,7 @@ pimv2_print(register const u_char *bp, register u_int len)
         if (EXTRACT_16BITS(&pim->pim_cksum) == 0) {
                 printf("(unverified)");
         } else {
-                printf("(%scorrect)",
-                       TTEST2(bp[0], len) &&
-                       in_cksum((const u_short*)bp, len, 0) ? "in" : "" );
+                printf("(%scorrect)", TTEST2(bp[0], len) && cksum ? "in" : "" );
         }
 
        switch (PIM_TYPE(pim->pim_typever)) {
index 7893f61da1ab978443d9c35f07b53617a82c5af9..ea57132221a76e754e23ed0f82a06063c82546d0 100644 (file)
@@ -156,37 +156,6 @@ static int tcp_cksum(register const struct ip *ip,
                         sp[0]+sp[1]+sp[2]+sp[3]+sp[4]+sp[5]);
 }
 
-#ifdef INET6
-static int tcp6_cksum(const struct ip6_hdr *ip6, const struct tcphdr *tp,
-                      u_int len)
-{
-        size_t i;
-        u_int32_t sum = 0;
-        union {
-                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;
-                u_int16_t pa[20];
-        } phu;
-
-        /* pseudo-header */
-        memset(&phu, 0, sizeof(phu));
-        phu.ph.ph_src = ip6->ip6_src;
-        phu.ph.ph_dst = ip6->ip6_dst;
-        phu.ph.ph_len = htonl(len);
-        phu.ph.ph_nxt = IPPROTO_TCP;
-
-        for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
-                sum += phu.pa[i];
-
-        return in_cksum((u_short *)tp, len, sum);
-}
-#endif
-
 void
 tcp_print(register const u_char *bp, register u_int length,
          register const u_char *bp2, int fragmented)
@@ -441,7 +410,7 @@ tcp_print(register const u_char *bp, register u_int length,
         if (IP_V(ip) == 6 && ip6->ip6_plen && vflag && !Kflag && !fragmented) {
                 u_int16_t sum,tcp_sum;
                 if (TTEST2(tp->th_sport, length)) {
-                        sum = tcp6_cksum(ip6, tp, length);
+                        sum = nextproto6_cksum(ip6, (u_short *)tp, length, IPPROTO_TCP);
                         (void)printf(", cksum 0x%04x",EXTRACT_16BITS(&tp->th_sum));
                         if (sum != 0) {
                                 tcp_sum = EXTRACT_16BITS(&tp->th_sum);