]> The Tcpdump Group git mirrors - tcpdump/commitdiff
verify/warn icmpv6 checksum. from jinmei@kame
authoritojun <itojun>
Fri, 2 May 2003 08:13:54 +0000 (08:13 +0000)
committeritojun <itojun>
Fri, 2 May 2003 08:13:54 +0000 (08:13 +0000)
interface.h
print-icmp6.c
print-ip6.c

index 07378f7217ef2c93d80b7d8be6bd3ea9b29977f1..29b6f9b227d348b95fb8f3db02d16180615432db 100644 (file)
@@ -18,7 +18,7 @@
  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.208 2003-05-01 18:02:12 guy Exp $ (LBL)
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.209 2003-05-02 08:13:54 itojun Exp $ (LBL)
  */
 
 #ifndef tcpdump_interface_h
@@ -312,7 +312,7 @@ extern int hbhopt_print(const u_char *);
 extern int dstopt_print(const u_char *);
 extern int frag6_print(const u_char *, const u_char *);
 extern int mobility_print(const u_char *, const u_char *);
-extern void icmp6_print(const u_char *, const u_char *);
+extern void icmp6_print(const u_char *, const u_char *, int);
 extern void ripng_print(const u_char *, unsigned int);
 extern int rt6_print(const u_char *, const u_char *);
 extern void ospf6_print(const u_char *, u_int);
index ce7474f9fe27a2a297cb203e1a8e6cf5e8caed07..5b8b44f57944774a1c67fad909e57fd5cc3787b3 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.69 2003-03-13 07:36:56 guy Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.70 2003-05-02 08:13:55 itojun Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -100,8 +100,51 @@ print_lladdr(const u_int8_t *p, size_t l)
        }
 }
 
+static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp,
+       int len)
+{
+       int i;
+       register const u_int16_t *sp;
+       u_int32_t sum;
+       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_ICMPV6;
+
+       sum = 0;
+       for (i = 0; i < sizeof(phu.pa) / sizeof(phu.pa[0]); i++)
+               sum += phu.pa[i];
+
+       sp = (const u_int16_t *)icp;
+
+       for (i = 0; i < (len & ~1); i += 2)
+               sum += *sp++;
+
+       if (len & 1)
+               sum += htons((*(const u_int8_t *)sp) << 8);
+
+       while (sum > 0xffff)
+               sum = (sum & 0xffff) + (sum >> 16);
+       sum = ~sum & 0xffff;
+
+       return (sum);
+}
+
 void
-icmp6_print(const u_char *bp, const u_char *bp2)
+icmp6_print(const u_char *bp, const u_char *bp2, int fragmented)
 {
        const struct icmp6_hdr *dp;
        const struct ip6_hdr *ip;
@@ -125,7 +168,20 @@ icmp6_print(const u_char *bp, const u_char *bp2)
        else                    /* XXX: jumbo payload case... */
                icmp6len = snapend - bp;
 
-       TCHECK(dp->icmp6_code);
+       TCHECK(dp->icmp6_cksum);
+
+       if (vflag && !fragmented) {
+               int sum = dp->icmp6_cksum;
+
+               if (TTEST2(bp[0], icmp6len)) {
+                       sum = icmp6_cksum(ip, dp, icmp6len);
+                       if (sum != 0)
+                               (void)printf("[bad icmp6 cksum %x!] ", sum);
+                       else
+                               (void)printf("[icmp6 sum ok] ");
+               }
+       }
+
        switch (dp->icmp6_type) {
        case ICMP6_DST_UNREACH:
                TCHECK(oip->ip6_dst);
index 846071dada10b42759d041f1673137f82d12c1a1..9f5777a3001853d474ade7121f69617facdaa334 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.28 2002-12-11 07:14:02 guy Exp $";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.29 2003-05-02 08:13:55 itojun Exp $";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -121,7 +121,7 @@ ip6_print(register const u_char *bp, register u_int length)
                                (const u_char *)ip6, fragmented);
                        goto end;
                case IPPROTO_ICMPV6:
-                       icmp6_print(cp, (const u_char *)ip6);
+                       icmp6_print(cp, (const u_char *)ip6, fragmented);
                        goto end;
                case IPPROTO_AH:
                        advance = ah_print(cp);