]> The Tcpdump Group git mirrors - tcpdump/blobdiff - print-ip.c
Patch sent to Debian by Roderick Schertler <[email protected]> to print
[tcpdump] / print-ip.c
index 3be539921368065fe59bfa44137764606f11afac..505cf847b665b9f5b9c6969aa44357ef7cf93dc2 100644 (file)
 
 #ifndef lint
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.73 1999-11-21 03:47:35 assar Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.89 2000-10-03 02:54:58 itojun Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
 #endif
 
 #include <sys/param.h>
@@ -29,16 +33,7 @@ static const char rcsid[] =
 #include <sys/socket.h>
 
 #include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/ip_var.h>
-#include <netinet/udp.h>
-#include <netinet/udp_var.h>
-#include <netinet/tcp.h>
-
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -48,6 +43,8 @@ static const char rcsid[] =
 #include "interface.h"
 #include "extract.h"                   /* must come after interface.h */
 
+#include "ip.h"
+
 /* Compatibility */
 #ifndef        IPPROTO_ND
 #define        IPPROTO_ND      77
@@ -66,21 +63,11 @@ struct tr_query {
        u_int  tr_src;                  /* traceroute source */
        u_int  tr_dst;                  /* traceroute destination */
        u_int  tr_raddr;                /* traceroute response address */
-#if defined(WORDS_BIGENDIAN) || (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))
-       struct {
-               u_int   ttl : 8;        /* traceroute response ttl */
-               u_int   qid : 24;       /* traceroute query id */
-       } q;
-#else
-       struct {
-               u_int   qid : 24;       /* traceroute query id */
-               u_int   ttl : 8;        /* traceroute response ttl */
-       } q;
-#endif
+       u_int  tr_rttlqid;              /* response ttl and qid */
 };
 
-#define tr_rttl q.ttl
-#define tr_qid  q.qid
+#define TR_GETTTL(x)           (int)(((x) >> 24) & 0xff)
+#define TR_GETQID(x)           ((x) & 0x00ffffff)
 
 /*
  * Traceroute response format.  A traceroute response has a tr_query at the
@@ -125,22 +112,24 @@ static void print_mtrace(register const u_char *bp, register u_int len)
 {
        register struct tr_query *tr = (struct tr_query *)(bp + 8);
 
-       printf("mtrace %d: %s to %s reply-to %s", tr->tr_qid,
+       printf("mtrace %lu: %s to %s reply-to %s",
+               (u_long)TR_GETQID(ntohl(tr->tr_rttlqid)),
                ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
                ipaddr_string(&tr->tr_raddr));
        if (IN_CLASSD(ntohl(tr->tr_raddr)))
-               printf(" with-ttl %d", tr->tr_rttl);
+               printf(" with-ttl %d", TR_GETTTL(ntohl(tr->tr_rttlqid)));
 }
 
 static void print_mresp(register const u_char *bp, register u_int len)
 {
        register struct tr_query *tr = (struct tr_query *)(bp + 8);
 
-       printf("mresp %d: %s to %s reply-to %s", tr->tr_qid,
+       printf("mresp %lu: %s to %s reply-to %s",
+               (u_long)TR_GETQID(ntohl(tr->tr_rttlqid)),
                ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
                ipaddr_string(&tr->tr_raddr));
        if (IN_CLASSD(ntohl(tr->tr_raddr)))
-               printf(" with-ttl %d", tr->tr_rttl);
+               printf(" with-ttl %d", TR_GETTTL(ntohl(tr->tr_rttlqid)));
 }
 
 static void
@@ -154,22 +143,27 @@ igmp_print(register const u_char *bp, register u_int len,
                ipaddr_string(&ip->ip_src),
                ipaddr_string(&ip->ip_dst));
 
+       if (qflag) {
+               (void)printf("igmp");
+               return;
+       }
+
        TCHECK2(bp[0], 8);
        switch (bp[0]) {
        case 0x11:
                (void)printf("igmp query");
-               if (*(int *)&bp[4])
+               if (EXTRACT_32BITS(&bp[4]))
                        (void)printf(" [gaddr %s]", ipaddr_string(&bp[4]));
                if (len != 8)
                        (void)printf(" [len %d]", len);
                break;
        case 0x12:
-               (void)printf("igmp report %s", ipaddr_string(&bp[4]));
+               (void)printf("igmp v1 report %s", ipaddr_string(&bp[4]));
                if (len != 8)
                        (void)printf(" [len %d]", len);
                break;
        case 0x16:
-               (void)printf("igmp nreport %s", ipaddr_string(&bp[4]));
+               (void)printf("igmp v2 report %s", ipaddr_string(&bp[4]));
                break;
        case 0x17:
                (void)printf("igmp leave %s", ipaddr_string(&bp[4]));
@@ -182,8 +176,8 @@ igmp_print(register const u_char *bp, register u_int len,
                        dvmrp_print(bp, len);
                break;
        case 0x14:
-               (void)printf("igmp pim");
-               igmp_pim_print(bp, len);
+               (void)printf("igmp pimv1");
+               pimv1_print(bp, len);
                break;
        case 0x1e:
                print_mresp(bp, len);
@@ -192,14 +186,11 @@ igmp_print(register const u_char *bp, register u_int len,
                print_mtrace(bp, len);
                break;
        default:
-               (void)printf("igmp-%d", bp[0] & 0xf);
+               (void)printf("igmp-%d", bp[0]);
                break;
        }
-       if ((bp[0] >> 4) != 1)
-               (void)printf(" [v%d]", bp[0] >> 4);
 
-       TCHECK2(bp[0], len);
-       if (vflag) {
+       if (vflag && TTEST2(bp[0], len)) {
                /* Check the IGMP checksum */
                if (in_cksum((const u_short*)bp, len, 0))
                        printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2]));
@@ -238,7 +229,7 @@ static void
 ip_printts(register const u_char *cp, u_int length)
 {
        register u_int ptr = cp[2] - 1;
-       register u_int len;
+       register u_int len = 0;
        int hoplen;
        char *type;
 
@@ -255,10 +246,16 @@ ip_printts(register const u_char *cp, u_int length)
        case IPOPT_TS_TSANDADDR:
                printf("TS+ADDR");
                break;
+       /*
+        * prespecified should really be 3, but some ones might send 2
+        * instead, and the IPOPT_TS_PRESPEC constant can apparently
+        * have both values, so we have to hard-code it here.
+        */
+
        case 2:
                printf("PRESPEC2.0");
                break;
-       case IPOPT_TS_PRESPEC:
+       case 3:                 /* IPOPT_TS_PRESPEC */
                printf("PRESPEC");
                break;
        default:        
@@ -270,7 +267,7 @@ ip_printts(register const u_char *cp, u_int length)
        for (len = 4; len < length; len += hoplen) {
                if (ptr == len)
                        type = " ^ ";
-               printf("%s%d@%s", type, ntohl(*(u_int32_t *)&cp[len+hoplen-4]),
+               printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
                       hoplen!=8 ? "" : ipaddr_string(&cp[len]));
                type = " ";
        }
@@ -295,7 +292,15 @@ ip_optprint(register const u_char *cp, u_int length)
        for (; length > 0; cp += len, length -= len) {
                int tt = *cp;
 
-               len = (tt == IPOPT_NOP || tt == IPOPT_EOL) ? 1 : cp[1];
+               if (tt == IPOPT_NOP || tt == IPOPT_EOL)
+                       len = 1;
+               else {
+                       if (&cp[1] >= snapend) {
+                               printf("[|ip]");
+                               return;
+                       }
+                       len = cp[1];
+               }
                if (len <= 0) {
                        printf("[|ip op len %d]", len);
                        return;
@@ -438,7 +443,11 @@ ip_print(register const u_char *bp, register u_int length)
                (void)printf("truncated-ip %d", length);
                return;
        }
-       hlen = ip->ip_hl * 4;
+       hlen = IP_HL(ip) * 4;
+       if (hlen < sizeof (struct ip)) {
+               (void)printf("bad-hlen %d", hlen);
+               return;
+       }
 
        len = ntohs(ip->ip_len);
        if (length < len)
@@ -622,6 +631,13 @@ again:
                        pim_print(cp, len);
                        break;
 
+#ifndef IPPROTO_VRRP
+#define IPPROTO_VRRP   112
+#endif
+               case IPPROTO_VRRP:
+                       vrrp_print(cp, len, ip->ip_ttl);
+                       break;
+
                default:
 #if 0
                        (void)printf("%s > %s:", ipaddr_string(&ip->ip_src),
@@ -632,6 +648,11 @@ again:
                }
        }
 
+       /* Ultra quiet now means that all this stuff should be suppressed */
+       /* res 3-Nov-98 */
+       if (qflag > 1) return;
+
+
        /*
         * for fragmented datagrams, print id:size@offset.  On all
         * but the last stick a "+".  For unfragmented datagrams, note
@@ -686,6 +707,8 @@ again:
                        (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id));
                        sep = ", ";
                }
+               (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len));
+               sep = ", ";
                if ((u_char *)ip + hlen <= snapend) {
                        sum = in_cksum((const u_short *)ip, hlen, 0);
                        if (sum != 0) {
@@ -701,3 +724,29 @@ again:
                printf(")");
        }
 }
+
+void
+ipN_print(register const u_char *bp, register u_int length)
+{
+       struct ip *ip, hdr;
+
+       ip = (struct ip *)bp;
+       if (length < 4) {
+               (void)printf("truncated-ip %d", length);
+               return;
+       }
+       memcpy (&hdr, (char *)ip, 4);
+       switch (IP_V(&hdr)) {
+       case 4:
+           ip_print (bp, length);
+           return;
+#ifdef INET6
+       case 6:
+           ip6_print (bp, length);
+           return;
+#endif
+       default:
+           (void)printf("unknown ip %d", IP_V(&hdr));
+           return;
+       }
+}