X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/d186680e9e798defc7f7fa36c56d00dfb6c4cd5b..8fb0656b71083c70f6c749a5cb9ad7152abb2a9d:/print-ip.c diff --git a/print-ip.c b/print-ip.c index 3be53992..505cf847 100644 --- a/print-ip.c +++ b/print-ip.c @@ -21,7 +21,11 @@ #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 @@ -29,16 +33,7 @@ static const char rcsid[] = #include #include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_MALLOC_H -#include -#endif + #include #include #include @@ -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; + } +}