X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/d186680e9e798defc7f7fa36c56d00dfb6c4cd5b..2cfe2bf4a5bdba199215e4c92129a36271b10a64:/print-ip.c diff --git a/print-ip.c b/print-ip.c index 3be53992..3cc07768 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.98 2001-06-15 22:17:33 fenner 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,167 +43,13 @@ 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 #endif -#ifndef IN_CLASSD -#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000) -#endif - -/* (following from ipmulti/mrouted/prune.h) */ - -/* - * The packet format for a traceroute request. - */ -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 -}; - -#define tr_rttl q.ttl -#define tr_qid q.qid - -/* - * Traceroute response format. A traceroute response has a tr_query at the - * beginning, followed by one tr_resp for each hop taken. - */ -struct tr_resp { - u_int tr_qarr; /* query arrival time */ - u_int tr_inaddr; /* incoming interface address */ - u_int tr_outaddr; /* outgoing interface address */ - u_int tr_rmtaddr; /* parent address in source tree */ - u_int tr_vifin; /* input packet count on interface */ - u_int tr_vifout; /* output packet count on interface */ - u_int tr_pktcnt; /* total incoming packets for src-grp */ - u_char tr_rproto; /* routing proto deployed on router */ - u_char tr_fttl; /* ttl required to forward on outvif */ - u_char tr_smask; /* subnet mask for src addr */ - u_char tr_rflags; /* forwarding error codes */ -}; - -/* defs within mtrace */ -#define TR_QUERY 1 -#define TR_RESP 2 - -/* fields for tr_rflags (forwarding error codes) */ -#define TR_NO_ERR 0 -#define TR_WRONG_IF 1 -#define TR_PRUNED 2 -#define TR_OPRUNED 3 -#define TR_SCOPED 4 -#define TR_NO_RTE 5 -#define TR_NO_FWD 7 -#define TR_NO_SPACE 0x81 -#define TR_OLD_ROUTER 0x82 - -/* fields for tr_rproto (routing protocol) */ -#define TR_PROTO_DVMRP 1 -#define TR_PROTO_MOSPF 2 -#define TR_PROTO_PIM 3 -#define TR_PROTO_CBT 4 - -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, - 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); -} - -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, - 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); -} - -static void -igmp_print(register const u_char *bp, register u_int len, - register const u_char *bp2) -{ - register const struct ip *ip; - - ip = (const struct ip *)bp2; - (void)printf("%s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); - - TCHECK2(bp[0], 8); - switch (bp[0]) { - case 0x11: - (void)printf("igmp query"); - if (*(int *)&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])); - if (len != 8) - (void)printf(" [len %d]", len); - break; - case 0x16: - (void)printf("igmp nreport %s", ipaddr_string(&bp[4])); - break; - case 0x17: - (void)printf("igmp leave %s", ipaddr_string(&bp[4])); - break; - case 0x13: - (void)printf("igmp dvmrp"); - if (len < 8) - (void)printf(" [len %d]", len); - else - dvmrp_print(bp, len); - break; - case 0x14: - (void)printf("igmp pim"); - igmp_pim_print(bp, len); - break; - case 0x1e: - print_mresp(bp, len); - break; - case 0x1f: - print_mtrace(bp, len); - break; - default: - (void)printf("igmp-%d", bp[0] & 0xf); - break; - } - if ((bp[0] >> 4) != 1) - (void)printf(" [v%d]", bp[0] >> 4); - - TCHECK2(bp[0], len); - if (vflag) { - /* Check the IGMP checksum */ - if (in_cksum((const u_short*)bp, len, 0)) - printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2])); - } - return; -trunc: - fputs("[|igmp]", stdout); -} - /* * print the recorded route in an IP RR, LSRR or SSRR option. */ @@ -238,7 +79,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 +96,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 +117,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 +142,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; @@ -348,7 +203,7 @@ ip_optprint(register const u_char *cp, u_int length) printf("{%d}", len); else if (cp[2] || cp[3]) printf("%d.%d", cp[2], cp[3]); - break; + break; default: printf(" IPOPT-%d{%d}", cp[0], len); @@ -438,11 +293,15 @@ 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) - (void)printf("truncated-ip - %d bytes missing!", + (void)printf("truncated-ip - %d bytes missing! ", len - length); len -= hlen; len0 = len; @@ -456,7 +315,11 @@ ip_print(register const u_char *bp, register u_int length) cp = (const u_char *)ip + hlen; nh = ip->ip_p; - if (nh != IPPROTO_TCP && nh != IPPROTO_UDP) { +#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), ipaddr_string(&ip->ip_dst)); } @@ -503,12 +366,16 @@ again: goto again; } + case IPPROTO_SCTP: + sctp_print(cp, (const u_char *)ip, len); + break; + case IPPROTO_TCP: - tcp_print(cp, len, (const u_char *)ip); + tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); break; case IPPROTO_UDP: - udp_print(cp, len, (const u_char *)ip); + udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); break; case IPPROTO_ICMP: @@ -523,10 +390,6 @@ again: break; case IPPROTO_ND: -#if 0 - (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); -#endif (void)printf(" nd %d", len); break; @@ -550,15 +413,9 @@ again: case 4: /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ -#if 0 - if (vflag) - (void)printf("%s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); -#endif ip_print(cp, len); if (! vflag) { - printf(" (ipip)"); + printf(" (ipip-proto-4)"); return; } break; @@ -569,17 +426,7 @@ again: #endif case IP6PROTO_ENCAP: /* ip6-in-ip encapsulation */ -#if 0 - if (vflag) - (void)printf("%s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); -#endif ip6_print(cp, len); - if (! vflag) { - printf(" (encap)"); - return; - } break; #endif /*INET6*/ @@ -588,31 +435,15 @@ again: #define IPPROTO_GRE 47 #endif case IPPROTO_GRE: - if (vflag) - (void)printf("gre %s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); /* do it */ gre_print(cp, len); - if (! vflag) { - printf(" (gre encap)"); - return; - } - break; + break; #ifndef IPPROTO_MOBILE #define IPPROTO_MOBILE 55 #endif case IPPROTO_MOBILE: - if (vflag) - (void)printf("mobile %s > %s: ", - ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); mobile_print(cp, len); - if (! vflag) { - printf(" (mobile encap)"); - return; - } break; #ifndef IPPROTO_PIM @@ -622,16 +453,24 @@ again: pim_print(cp, len); break; - default: -#if 0 - (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), - ipaddr_string(&ip->ip_dst)); +#ifndef IPPROTO_VRRP +#define IPPROTO_VRRP 112 #endif + case IPPROTO_VRRP: + vrrp_print(cp, len, ip->ip_ttl); + break; + + default: (void)printf(" ip-proto-%d %d", nh, len); break; } } + /* 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 @@ -662,10 +501,17 @@ again: if (ip->ip_tos) { (void)printf(" [tos 0x%x", (int)ip->ip_tos); /* ECN bits */ - if (ip->ip_tos&0x02) { - (void)printf(",ECT"); - if (ip->ip_tos&0x01) + if (ip->ip_tos & 0x03) { + switch (ip->ip_tos & 0x03) { + case 1: + (void)printf(",ECT(1)"); + break; + case 2: + (void)printf(",ECT(0)"); + break; + case 3: (void)printf(",CE"); + } } (void)printf("] "); } @@ -686,6 +532,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 +549,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; + } +}