]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
Use "len", not "payload_len", as we step through the packet; use
[tcpdump] / print-ip.c
index 19edb1a35339cba60fd3359d3863fc8dea8be0a9..f426722296629fe1d64ab1c5422571358a93624e 100644 (file)
@@ -20,8 +20,8 @@
  */
 
 #ifndef lint
-static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.122 2003-05-08 14:26:54 hannes Exp $ (LBL)";
+static const char rcsid[] _U_ =
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.132 2003-11-19 00:36:07 guy Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -39,11 +39,7 @@ static const char rcsid[] =
 #include "extract.h"                   /* must come after interface.h */
 
 #include "ip.h"
-
-/* Compatibility */
-#ifndef        IPPROTO_ND
-#define        IPPROTO_ND      77
-#endif
+#include "ipproto.h"
 
 /*
  * print the recorded route in an IP RR, LSRR or SSRR option.
@@ -362,16 +358,22 @@ ip_print(register const u_char *bp, register u_int length)
 {
        register const struct ip *ip;
        register u_int hlen, len, len0, off;
+       const u_char *ipend;
        register const u_char *cp;
        u_char nh;
        int advance;
        struct protoent *proto;
        u_int16_t sum, ip_sum;
-       const char *sep = "";
-
-       printf("IP%s ", (((*bp >> 4) & 0xf) == 4) ? "" : "4"); /* print version if != 4 */
 
        ip = (const struct ip *)bp;
+       if (IP_V(ip) != 4) { /* print version if != 4 */
+           printf("IP%u ", IP_V(ip));
+           if (IP_V(ip) == 6)
+               printf(", wrong link-layer encapsulation");
+       }
+        else
+           printf("IP ");
+
        if ((u_char *)(ip + 1) > snapend) {
                printf("[|ip]");
                return;
@@ -382,14 +384,26 @@ ip_print(register const u_char *bp, register u_int length)
        }
        hlen = IP_HL(ip) * 4;
        if (hlen < sizeof (struct ip)) {
-               (void)printf("bad-hlen %d", hlen);
+               (void)printf("bad-hlen %u", hlen);
                return;
        }
 
        len = EXTRACT_16BITS(&ip->ip_len);
        if (length < len)
-               (void)printf("truncated-ip - %d bytes missing! ",
+               (void)printf("truncated-ip - %u bytes missing! ",
                        len - length);
+       if (len < hlen) {
+               (void)printf("bad-len %u", len);
+               return;
+       }
+
+       /*
+        * Cut off the snapshot length to the end of the IP payload.
+        */
+       ipend = bp + len;
+       if (ipend < snapend)
+               snapend = ipend;
+
        len -= hlen;
        len0 = len;
 
@@ -412,7 +426,7 @@ ip_print(register const u_char *bp, register u_int length)
             }
 
             if (ip->ip_ttl >= 1)
-                (void)printf(", ttl %u", ip->ip_ttl);    
+                (void)printf(", ttl %3u", ip->ip_ttl);    
 
            /*
             * for the firewall guys, print id, offset.
@@ -437,10 +451,8 @@ ip_print(register const u_char *bp, register u_int length)
                sum = in_cksum((const u_short *)ip, hlen, 0);
                if (sum != 0) {
                    ip_sum = EXTRACT_16BITS(&ip->ip_sum);
-                   (void)printf("%sbad cksum %x (->%x)!", sep,
-                            ip_sum,
+                   (void)printf(", bad cksum %x (->%x)!", ip_sum,
                             in_cksum_shouldbe(ip_sum, sum));
-                   sep = ", ";
                }
            }
 
@@ -455,9 +467,6 @@ ip_print(register const u_char *bp, register u_int length)
                cp = (const u_char *)ip + hlen;
                nh = ip->ip_p;
 
-#ifndef IPPROTO_SCTP
-#define IPPROTO_SCTP 132
-#endif
                if (nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
                    nh != IPPROTO_SCTP) {
                        (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src),
@@ -466,42 +475,35 @@ ip_print(register const u_char *bp, register u_int length)
 again:
                switch (nh) {
 
-#ifndef IPPROTO_AH
-#define IPPROTO_AH     51
-#endif
                case IPPROTO_AH:
                        nh = *cp;
                        advance = ah_print(cp);
+                       if (advance <= 0)
+                               break;
                        cp += advance;
                        len -= advance;
                        goto again;
 
-#ifndef IPPROTO_ESP
-#define IPPROTO_ESP    50
-#endif
                case IPPROTO_ESP:
                    {
                        int enh, padlen;
                        advance = esp_print(cp, (const u_char *)ip, &enh, &padlen);
+                       if (advance <= 0)
+                               break;
                        cp += advance;
                        len -= advance + padlen;
-                       if (enh < 0)
-                               break;
                        nh = enh & 0xff;
                        goto again;
                    }
 
-#ifndef IPPROTO_IPCOMP
-#define IPPROTO_IPCOMP 108
-#endif
                case IPPROTO_IPCOMP:
                    {
                        int enh;
                        advance = ipcomp_print(cp, &enh);
+                       if (advance <= 0)
+                               break;
                        cp += advance;
                        len -= advance;
-                       if (enh < 0)
-                               break;
                        nh = enh & 0xff;
                        goto again;
                    }
@@ -519,12 +521,10 @@ again:
                        break;
 
                case IPPROTO_ICMP:
-                       icmp_print(cp, len, (const u_char *)ip);
+                       /* pass on the MF bit plus the offset to detect fragments */
+                       icmp_print(cp, len, (const u_char *)ip, (off & 0x3fff));
                        break;
 
-#ifndef IPPROTO_IGRP
-#define IPPROTO_IGRP 9
-#endif
                case IPPROTO_IGRP:
                        igrp_print(cp, len, (const u_char *)ip);
                        break;
@@ -537,21 +537,15 @@ again:
                        egp_print(cp);
                        break;
 
-#ifndef IPPROTO_OSPF
-#define IPPROTO_OSPF 89
-#endif
                case IPPROTO_OSPF:
                        ospf_print(cp, len, (const u_char *)ip);
                        break;
 
-#ifndef IPPROTO_IGMP
-#define IPPROTO_IGMP 2
-#endif
                case IPPROTO_IGMP:
                        igmp_print(cp, len);
                        break;
 
-               case 4:
+               case IPPROTO_IPV4:
                        /* DVMRP multicast tunnel (ip-in-ip encapsulation) */
                        ip_print(cp, len);
                        if (! vflag) {
@@ -561,47 +555,29 @@ again:
                        break;
 
 #ifdef INET6
-#ifndef IP6PROTO_ENCAP
-#define IP6PROTO_ENCAP 41
-#endif
-               case IP6PROTO_ENCAP:
+               case IPPROTO_IPV6:
                        /* ip6-in-ip encapsulation */
                        ip6_print(cp, len);
                        break;
 #endif /*INET6*/
 
-#ifndef IPPROTO_RSVP
-#define IPPROTO_RSVP 46
-#endif
                case IPPROTO_RSVP:
                        rsvp_print(cp, len);
                        break;
 
-#ifndef IPPROTO_GRE
-#define IPPROTO_GRE 47
-#endif
                case IPPROTO_GRE:
                        /* do it */
                        gre_print(cp, len);
                        break;
 
-#ifndef IPPROTO_MOBILE
-#define IPPROTO_MOBILE 55
-#endif
                case IPPROTO_MOBILE:
                        mobile_print(cp, len);
                        break;
 
-#ifndef IPPROTO_PIM
-#define IPPROTO_PIM    103
-#endif
                case IPPROTO_PIM:
                        pim_print(cp, len);
                        break;
 
-#ifndef IPPROTO_VRRP
-#define IPPROTO_VRRP   112
-#endif
                case IPPROTO_VRRP:
                        vrrp_print(cp, len, ip->ip_ttl);
                        break;