]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
Fix a typo.
[tcpdump] / print-ip.c
index af17385325c1295d4a4109e1558350059095c1cb..b05088d31da638dd4bfaab8068380c42492f83a0 100644 (file)
@@ -21,7 +21,7 @@
 
 #ifndef lint
 static const char rcsid[] _U_ =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.138 2004-04-28 22:02:23 guy Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.147 2005-01-21 08:02:06 hannes Exp $ (LBL)";
 #endif
 
 #ifdef HAVE_CONFIG_H
@@ -41,11 +41,23 @@ static const char rcsid[] _U_ =
 #include "ip.h"
 #include "ipproto.h"
 
+struct tok ip_option_values[] = {
+    { IPOPT_EOL, "EOL" },
+    { IPOPT_NOP, "NOP" },
+    { IPOPT_TS, "timestamp" },
+    { IPOPT_SECURITY, "security" },
+    { IPOPT_RR, "RR" },
+    { IPOPT_SSRR, "SSRR" },
+    { IPOPT_LSRR, "LSRR" },
+    { IPOPT_RA, "RA" },
+    { 0, NULL }
+};
+
 /*
  * print the recorded route in an IP RR, LSRR or SSRR option.
  */
 static void
-ip_printroute(const char *type, register const u_char *cp, u_int length)
+ip_printroute(register const u_char *cp, u_int length)
 {
        register u_int ptr;
        register u_int len;
@@ -54,25 +66,21 @@ ip_printroute(const char *type, register const u_char *cp, u_int length)
                printf(" [bad length %u]", length);
                return;
        }
-       printf(" %s{", type);
        if ((length + 1) & 3)
                printf(" [bad length %u]", length);
        ptr = cp[2] - 1;
        if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
                printf(" [bad ptr %u]", cp[2]);
 
-       type = "";
        for (len = 3; len < length; len += 4) {
-               if (ptr == len)
-                       type = "#";
-               printf("%s%s", type, ipaddr_string(&cp[len]));
-               type = " ";
+               printf("%s", ipaddr_string(&cp[len]));
+                if (ptr > len)
+                    printf (", ");
        }
-       printf("%s}", ptr == len? "#" : "");
 }
 
 /*
- * If source-routing is present, return the final destination.
+ * If source-routing is present and valid, return the final destination.
  * Otherwise, return IP destination.
  *
  * This is used for UDP and TCP pseudo-header in the checksum
@@ -94,14 +102,15 @@ ip_finddst(const struct ip *ip)
 
                TCHECK(*cp);
                tt = *cp;
-               if (tt == IPOPT_NOP || tt == IPOPT_EOL)
+               if (tt == IPOPT_EOL)
+                       break;
+               else if (tt == IPOPT_NOP)
                        len = 1;
                else {
                        TCHECK(cp[1]);
                        len = cp[1];
-               }
-               if (len < 2) {
-                       return 0;
+                       if (len < 2)
+                               break;
                }
                TCHECK2(*cp, len);
                switch (tt) {
@@ -109,15 +118,14 @@ ip_finddst(const struct ip *ip)
                case IPOPT_SSRR:
                case IPOPT_LSRR:
                        if (len < 7)
-                               return 0;
+                               break;
                        memcpy(&retval, cp + len - 4, 4);
                        return retval;
                }
        }
-       return ip->ip_dst.s_addr;
-
 trunc:
-       return 0;
+       memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+       return retval;
 }
 
 static void
@@ -188,75 +196,56 @@ done:
 static void
 ip_optprint(register const u_char *cp, u_int length)
 {
-       register u_int len;
+       register u_int option_len;
 
-       for (; length > 0; cp += len, length -= len) {
-               int tt;
+       for (; length > 0; cp += option_len, length -= option_len) {
+               u_int option_code;
 
                TCHECK(*cp);
-               tt = *cp;
-               if (tt == IPOPT_NOP || tt == IPOPT_EOL)
-                       len = 1;
+               option_code = *cp;
+
+               if (option_code == IPOPT_NOP ||
+                    option_code == IPOPT_EOL)
+                       option_len = 1;
+
                else {
                        TCHECK(cp[1]);
-                       len = cp[1];
-                       if (len < 2) {
-                               printf("[|ip op len %d]", len);
-                               return;
-                       }
-                       TCHECK2(*cp, len);
+                       option_len = cp[1];                     
                }
-               switch (tt) {
 
-               case IPOPT_EOL:
-                       printf(" EOL");
-                       if (length > 1)
-                               printf("-%d", length - 1);
-                       return;
+                printf("%s (%u) len %u",
+                       tok2str(ip_option_values,"unknown",option_code),
+                       option_code,
+                       option_len);
 
-               case IPOPT_NOP:
-                       printf(" NOP");
-                       break;
+                if (option_len < 2)
+                        return;
 
-               case IPOPT_TS:
-                       ip_printts(cp, len);
-                       break;
+                TCHECK2(*cp, option_len);
 
-#ifndef IPOPT_SECURITY
-#define IPOPT_SECURITY 130
-#endif /* IPOPT_SECURITY */
-               case IPOPT_SECURITY:
-                       printf(" SECURITY{%d}", len);
-                       break;
+               switch (option_code) {
+               case IPOPT_EOL:
+                       return;
 
-               case IPOPT_RR:
-                       ip_printroute("RR", cp, len);
+               case IPOPT_TS:
+                       ip_printts(cp, option_len);
                        break;
 
+               case IPOPT_RR:       /* fall through */
                case IPOPT_SSRR:
-                       ip_printroute("SSRR", cp, len);
-                       break;
-
                case IPOPT_LSRR:
-                       ip_printroute("LSRR", cp, len);
+                       ip_printroute( cp, option_len);
                        break;
 
-#ifndef IPOPT_RA
-#define IPOPT_RA 148           /* router alert */
-#endif
                case IPOPT_RA:
-                       printf(" RA");
-                       if (len != 4)
-                               printf("{%d}", len);
-                       else {
-                               TCHECK(cp[3]);
-                               if (cp[2] || cp[3])
-                                       printf("%d.%d", cp[2], cp[3]);
-                       }
+                        TCHECK(cp[3]);
+                        if (EXTRACT_16BITS(&cp[2]) != 0)
+                            printf("value %u", EXTRACT_16BITS(&cp[2]));
                        break;
 
+               case IPOPT_NOP:       /* nothing to print - fall through */
+               case IPOPT_SECURITY:
                default:
-                       printf(" IPOPT-%d{%d}", cp[0], len);
                        break;
                }
        }
@@ -374,7 +363,7 @@ void
 ip_print(register const u_char *bp, register u_int length)
 {
        register const struct ip *ip;
-       register u_int hlen, len, len0, off;
+       register u_int hlen, len, off;
        const u_char *ipend;
        register const u_char *cp;
        u_char nh;
@@ -388,7 +377,7 @@ ip_print(register const u_char *bp, register u_int length)
            if (IP_V(ip) == 6)
                printf(", wrong link-layer encapsulation");
        }
-        else
+        else if (!eflag)
            printf("IP ");
 
        if ((u_char *)(ip + 1) > snapend) {
@@ -396,7 +385,7 @@ ip_print(register const u_char *bp, register u_int length)
                return;
        }
        if (length < sizeof (struct ip)) {
-               (void)printf("truncated-ip %d", length);
+               (void)printf("truncated-ip %u", length);
                return;
        }
        hlen = IP_HL(ip) * 4;
@@ -410,8 +399,19 @@ ip_print(register const u_char *bp, register u_int length)
                (void)printf("truncated-ip - %u bytes missing! ",
                        len - length);
        if (len < hlen) {
-               (void)printf("bad-len %u", len);
-               return;
+#ifdef GUESS_TSO
+            if (len) {
+                (void)printf("bad-len %u", len);
+                return;
+            }
+            else {
+                /* we guess that it is a TSO send */
+                len = length;
+            }
+#else
+            (void)printf("bad-len %u", len);
+            return;
+#endif /* GUESS_TSO */
        }
 
        /*
@@ -422,7 +422,6 @@ ip_print(register const u_char *bp, register u_int length)
                snapend = ipend;
 
        len -= hlen;
-       len0 = len;
 
        off = EXTRACT_16BITS(&ip->ip_off);
 
@@ -461,7 +460,7 @@ ip_print(register const u_char *bp, register u_int length)
             (void)printf(", length: %u", EXTRACT_16BITS(&ip->ip_len));
 
             if ((hlen - sizeof(struct ip)) > 0) {
-                (void)printf(", optlength: %u (", hlen - (u_int)sizeof(struct ip));
+                printf(", options ( ");
                 ip_optprint((u_char *)(ip + 1), hlen - sizeof(struct ip));
                 printf(" )");
             }
@@ -506,7 +505,7 @@ again:
                case IPPROTO_ESP:
                    {
                        int enh, padlen;
-                       advance = esp_print(gndo, cp, (const u_char *)ip, &enh, &padlen);
+                       advance = esp_print(gndo, cp, len, (const u_char *)ip, &enh, &padlen);
                        if (advance <= 0)
                                break;
                        cp += advance;
@@ -545,7 +544,6 @@ again:
                        break;
 
                case IPPROTO_PIGP:
-               case IPPROTO_EIGRP:
                        /*
                         * XXX - the current IANA protocol number assignments
                         * page lists 9 as "any private interior gateway
@@ -558,23 +556,20 @@ again:
                         * IP_PROTO_EIGRP as 88; those names better
                         * match was the current protocol number
                         * assignments say.
-                        *
-                        * XXX - at least according to the Ethereal
-                        * dissectors, Cisco IGRP and Cisco EIGRP are
-                        * *not* the same, so it's not clear that both
-                        * IPPROTO_PIGP and IPPROTO_EIGRP should be
-                        * handed to the same print routine; "igrp_print()"
-                        * appears to be for IGRP, not EIGRP.
                         */
                        igrp_print(cp, len, (const u_char *)ip);
                        break;
 
+               case IPPROTO_EIGRP:
+                       eigrp_print(cp, len);
+                       break;
+
                case IPPROTO_ND:
                        (void)printf(" nd %d", len);
                        break;
 
                case IPPROTO_EGP:
-                       egp_print(cp);
+                       egp_print(cp, len);
                        break;
 
                case IPPROTO_OSPF: