print-ip.c revision 146778
1/*
2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * $FreeBSD: head/contrib/tcpdump/print-ip.c 146778 2005-05-29 19:09:28Z sam $
22 */
23
24#ifndef lint
25static const char rcsid[] _U_ =
26    "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.149 2005/04/07 00:28:17 mcr Exp $ (LBL)";
27#endif
28
29#ifdef HAVE_CONFIG_H
30#include "config.h"
31#endif
32
33#include <tcpdump-stdinc.h>
34
35#include <stdio.h>
36#include <stdlib.h>
37#include <string.h>
38
39#include "addrtoname.h"
40#include "interface.h"
41#include "extract.h"			/* must come after interface.h */
42
43#include "ip.h"
44#include "ipproto.h"
45
46struct tok ip_option_values[] = {
47    { IPOPT_EOL, "EOL" },
48    { IPOPT_NOP, "NOP" },
49    { IPOPT_TS, "timestamp" },
50    { IPOPT_SECURITY, "security" },
51    { IPOPT_RR, "RR" },
52    { IPOPT_SSRR, "SSRR" },
53    { IPOPT_LSRR, "LSRR" },
54    { IPOPT_RA, "RA" },
55    { 0, NULL }
56};
57
58/*
59 * print the recorded route in an IP RR, LSRR or SSRR option.
60 */
61static void
62ip_printroute(register const u_char *cp, u_int length)
63{
64	register u_int ptr;
65	register u_int len;
66
67	if (length < 3) {
68		printf(" [bad length %u]", length);
69		return;
70	}
71	if ((length + 1) & 3)
72		printf(" [bad length %u]", length);
73	ptr = cp[2] - 1;
74	if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
75		printf(" [bad ptr %u]", cp[2]);
76
77	for (len = 3; len < length; len += 4) {
78		printf("%s", ipaddr_string(&cp[len]));
79                if (ptr > len)
80                    printf (", ");
81	}
82}
83
84/*
85 * If source-routing is present and valid, return the final destination.
86 * Otherwise, return IP destination.
87 *
88 * This is used for UDP and TCP pseudo-header in the checksum
89 * calculation.
90 */
91u_int32_t
92ip_finddst(const struct ip *ip)
93{
94	int length;
95	int len;
96	const u_char *cp;
97	u_int32_t retval;
98
99	cp = (const u_char *)(ip + 1);
100	length = (IP_HL(ip) << 2) - sizeof(struct ip);
101
102	for (; length > 0; cp += len, length -= len) {
103		int tt;
104
105		TCHECK(*cp);
106		tt = *cp;
107		if (tt == IPOPT_EOL)
108			break;
109		else if (tt == IPOPT_NOP)
110			len = 1;
111		else {
112			TCHECK(cp[1]);
113			len = cp[1];
114			if (len < 2)
115				break;
116		}
117		TCHECK2(*cp, len);
118		switch (tt) {
119
120		case IPOPT_SSRR:
121		case IPOPT_LSRR:
122			if (len < 7)
123				break;
124			memcpy(&retval, cp + len - 4, 4);
125			return retval;
126		}
127	}
128trunc:
129	memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
130	return retval;
131}
132
133static void
134ip_printts(register const u_char *cp, u_int length)
135{
136	register u_int ptr;
137	register u_int len;
138	int hoplen;
139	const char *type;
140
141	if (length < 4) {
142		printf("[bad length %d]", length);
143		return;
144	}
145	printf(" TS{");
146	hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
147	if ((length - 4) & (hoplen-1))
148		printf("[bad length %d]", length);
149	ptr = cp[2] - 1;
150	len = 0;
151	if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
152		printf("[bad ptr %d]", cp[2]);
153	switch (cp[3]&0xF) {
154	case IPOPT_TS_TSONLY:
155		printf("TSONLY");
156		break;
157	case IPOPT_TS_TSANDADDR:
158		printf("TS+ADDR");
159		break;
160	/*
161	 * prespecified should really be 3, but some ones might send 2
162	 * instead, and the IPOPT_TS_PRESPEC constant can apparently
163	 * have both values, so we have to hard-code it here.
164	 */
165
166	case 2:
167		printf("PRESPEC2.0");
168		break;
169	case 3:			/* IPOPT_TS_PRESPEC */
170		printf("PRESPEC");
171		break;
172	default:
173		printf("[bad ts type %d]", cp[3]&0xF);
174		goto done;
175	}
176
177	type = " ";
178	for (len = 4; len < length; len += hoplen) {
179		if (ptr == len)
180			type = " ^ ";
181		printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
182		       hoplen!=8 ? "" : ipaddr_string(&cp[len]));
183		type = " ";
184	}
185
186done:
187	printf("%s", ptr == len ? " ^ " : "");
188
189	if (cp[3]>>4)
190		printf(" [%d hops not recorded]} ", cp[3]>>4);
191	else
192		printf("}");
193}
194
195/*
196 * print IP options.
197 */
198static void
199ip_optprint(register const u_char *cp, u_int length)
200{
201	register u_int option_len;
202
203	for (; length > 0; cp += option_len, length -= option_len) {
204		u_int option_code;
205
206		TCHECK(*cp);
207		option_code = *cp;
208
209		if (option_code == IPOPT_NOP ||
210                    option_code == IPOPT_EOL)
211			option_len = 1;
212
213		else {
214			TCHECK(cp[1]);
215			option_len = cp[1];
216		}
217
218                printf("%s (%u) len %u",
219                       tok2str(ip_option_values,"unknown",option_code),
220                       option_code,
221                       option_len);
222
223                if (option_len < 2)
224                        return;
225
226                TCHECK2(*cp, option_len);
227
228		switch (option_code) {
229		case IPOPT_EOL:
230			return;
231
232		case IPOPT_TS:
233			ip_printts(cp, option_len);
234			break;
235
236		case IPOPT_RR:       /* fall through */
237		case IPOPT_SSRR:
238		case IPOPT_LSRR:
239			ip_printroute( cp, option_len);
240			break;
241
242		case IPOPT_RA:
243                        TCHECK(cp[3]);
244                        if (EXTRACT_16BITS(&cp[2]) != 0)
245                            printf("value %u", EXTRACT_16BITS(&cp[2]));
246			break;
247
248		case IPOPT_NOP:       /* nothing to print - fall through */
249		case IPOPT_SECURITY:
250		default:
251			break;
252		}
253	}
254	return;
255
256trunc:
257	printf("[|ip]");
258}
259
260/*
261 * compute an IP header checksum.
262 * don't modifiy the packet.
263 */
264u_short
265in_cksum(const u_short *addr, register u_int len, int csum)
266{
267	int nleft = len;
268	const u_short *w = addr;
269	u_short answer;
270	int sum = csum;
271
272	/*
273	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
274	 *  we add sequential 16 bit words to it, and at the end, fold
275	 *  back all the carry bits from the top 16 bits into the lower
276	 *  16 bits.
277	 */
278	while (nleft > 1)  {
279		sum += *w++;
280		nleft -= 2;
281	}
282	if (nleft == 1)
283		sum += htons(*(u_char *)w<<8);
284
285	/*
286	 * add back carry outs from top 16 bits to low 16 bits
287	 */
288	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
289	sum += (sum >> 16);			/* add carry */
290	answer = ~sum;				/* truncate to 16 bits */
291	return (answer);
292}
293
294/*
295 * Given the host-byte-order value of the checksum field in a packet
296 * header, and the network-byte-order computed checksum of the data
297 * that the checksum covers (including the checksum itself), compute
298 * what the checksum field *should* have been.
299 */
300u_int16_t
301in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum)
302{
303	u_int32_t shouldbe;
304
305	/*
306	 * The value that should have gone into the checksum field
307	 * is the negative of the value gotten by summing up everything
308	 * *but* the checksum field.
309	 *
310	 * We can compute that by subtracting the value of the checksum
311	 * field from the sum of all the data in the packet, and then
312	 * computing the negative of that value.
313	 *
314	 * "sum" is the value of the checksum field, and "computed_sum"
315	 * is the negative of the sum of all the data in the packets,
316	 * so that's -(-computed_sum - sum), or (sum + computed_sum).
317	 *
318	 * All the arithmetic in question is one's complement, so the
319	 * addition must include an end-around carry; we do this by
320	 * doing the arithmetic in 32 bits (with no sign-extension),
321	 * and then adding the upper 16 bits of the sum, which contain
322	 * the carry, to the lower 16 bits of the sum, and then do it
323	 * again in case *that* sum produced a carry.
324	 *
325	 * As RFC 1071 notes, the checksum can be computed without
326	 * byte-swapping the 16-bit words; summing 16-bit words
327	 * on a big-endian machine gives a big-endian checksum, which
328	 * can be directly stuffed into the big-endian checksum fields
329	 * in protocol headers, and summing words on a little-endian
330	 * machine gives a little-endian checksum, which must be
331	 * byte-swapped before being stuffed into a big-endian checksum
332	 * field.
333	 *
334	 * "computed_sum" is a network-byte-order value, so we must put
335	 * it in host byte order before subtracting it from the
336	 * host-byte-order value from the header; the adjusted checksum
337	 * will be in host byte order, which is what we'll return.
338	 */
339	shouldbe = sum;
340	shouldbe += ntohs(computed_sum);
341	shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
342	shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
343	return shouldbe;
344}
345
346#ifndef IP_MF
347#define IP_MF 0x2000
348#endif /* IP_MF */
349#ifndef IP_DF
350#define IP_DF 0x4000
351#endif /* IP_DF */
352#define IP_RES 0x8000
353
354static struct tok ip_frag_values[] = {
355        { IP_MF,        "+" },
356        { IP_DF,        "DF" },
357	{ IP_RES,       "rsvd" }, /* The RFC3514 evil ;-) bit */
358        { 0,            NULL }
359};
360
361struct ip_print_demux_state {
362	const struct ip *ip;
363	const u_char *cp;
364	u_int   len, off;
365	u_char  nh;
366	int     advance;
367};
368
369static void
370ip_print_demux(netdissect_options *ndo,
371	       struct ip_print_demux_state *ipds)
372{
373	struct protoent *proto;
374
375again:
376	switch (ipds->nh) {
377
378	case IPPROTO_AH:
379		ipds->nh = *ipds->cp;
380		ipds->advance = ah_print(ipds->cp);
381		if (ipds->advance <= 0)
382			break;
383		ipds->cp += ipds->advance;
384		ipds->len -= ipds->advance;
385		goto again;
386
387	case IPPROTO_ESP:
388	{
389		int enh, padlen;
390		ipds->advance = esp_print(ndo, ipds->cp, ipds->len,
391				    (const u_char *)ipds->ip,
392				    &enh, &padlen);
393		if (ipds->advance <= 0)
394			break;
395		ipds->cp += ipds->advance;
396		ipds->len -= ipds->advance + padlen;
397		ipds->nh = enh & 0xff;
398		goto again;
399	}
400
401	case IPPROTO_IPCOMP:
402	{
403		int enh;
404		ipds->advance = ipcomp_print(ipds->cp, &enh);
405		if (ipds->advance <= 0)
406			break;
407		ipds->cp += ipds->advance;
408		ipds->len -= ipds->advance;
409		ipds->nh = enh & 0xff;
410		goto again;
411	}
412
413	case IPPROTO_SCTP:
414		sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
415		break;
416
417	case IPPROTO_TCP:
418		tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
419			  (ipds->off &~ 0x6000));
420		break;
421
422	case IPPROTO_UDP:
423		udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
424			  (ipds->off &~ 0x6000));
425		break;
426
427	case IPPROTO_ICMP:
428		/* pass on the MF bit plus the offset to detect fragments */
429		icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
430			   (ipds->off & 0x3fff));
431		break;
432
433	case IPPROTO_PIGP:
434		/*
435		 * XXX - the current IANA protocol number assignments
436		 * page lists 9 as "any private interior gateway
437		 * (used by Cisco for their IGRP)" and 88 as
438		 * "EIGRP" from Cisco.
439		 *
440		 * Recent BSD <netinet/in.h> headers define
441		 * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
442		 * We define IP_PROTO_PIGP as 9 and
443		 * IP_PROTO_EIGRP as 88; those names better
444		 * match was the current protocol number
445		 * assignments say.
446		 */
447		igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
448		break;
449
450	case IPPROTO_EIGRP:
451		eigrp_print(ipds->cp, ipds->len);
452		break;
453
454	case IPPROTO_ND:
455		ND_PRINT((ndo, " nd %d", ipds->len));
456		break;
457
458	case IPPROTO_EGP:
459		egp_print(ipds->cp, ipds->len);
460		break;
461
462	case IPPROTO_OSPF:
463		ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
464		break;
465
466	case IPPROTO_IGMP:
467		igmp_print(ipds->cp, ipds->len);
468		break;
469
470	case IPPROTO_IPV4:
471		/* DVMRP multicast tunnel (ip-in-ip encapsulation) */
472		ip_print(gndo, ipds->cp, ipds->len);
473		if (! vflag) {
474			ND_PRINT((ndo, " (ipip-proto-4)"));
475			return;
476		}
477		break;
478
479#ifdef INET6
480	case IPPROTO_IPV6:
481		/* ip6-in-ip encapsulation */
482		ip6_print(ipds->cp, ipds->len);
483		break;
484#endif /*INET6*/
485
486	case IPPROTO_RSVP:
487		rsvp_print(ipds->cp, ipds->len);
488		break;
489
490	case IPPROTO_GRE:
491		/* do it */
492		gre_print(ipds->cp, ipds->len);
493		break;
494
495	case IPPROTO_MOBILE:
496		mobile_print(ipds->cp, ipds->len);
497		break;
498
499	case IPPROTO_PIM:
500		pim_print(ipds->cp,  ipds->len);
501		break;
502
503	case IPPROTO_VRRP:
504		vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
505		break;
506
507	default:
508		if ((proto = getprotobynumber(ipds->nh)) != NULL)
509			ND_PRINT((ndo, " %s", proto->p_name));
510		else
511			ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
512		ND_PRINT((ndo, " %d", ipds->len));
513		break;
514	}
515}
516
517void
518ip_print_inner(netdissect_options *ndo,
519	       const u_char *bp,
520	       u_int length, u_int nh,
521	       const u_char *bp2)
522{
523	struct ip_print_demux_state  ipd;
524
525	ipd.ip = (const struct ip *)bp2;
526	ipd.cp = bp;
527	ipd.len  = length;
528	ipd.off  = 0;
529	ipd.nh   = nh;
530	ipd.advance = 0;
531
532	ip_print_demux(ndo, &ipd);
533}
534
535
536/*
537 * print an IP datagram.
538 */
539void
540ip_print(netdissect_options *ndo,
541	 const u_char *bp,
542	 u_int length)
543{
544	struct ip_print_demux_state  ipd;
545	struct ip_print_demux_state *ipds=&ipd;
546	const u_char *ipend;
547	u_int hlen;
548	u_int16_t sum, ip_sum;
549	struct protoent *proto;
550
551	ipds->ip = (const struct ip *)bp;
552	if (IP_V(ipds->ip) != 4) { /* print version if != 4 */
553	    printf("IP%u ", IP_V(ipds->ip));
554	    if (IP_V(ipds->ip) == 6)
555		printf(", wrong link-layer encapsulation");
556	}
557        else if (!eflag)
558	    printf("IP ");
559
560	if ((u_char *)(ipds->ip + 1) > snapend) {
561		printf("[|ip]");
562		return;
563	}
564	if (length < sizeof (struct ip)) {
565		(void)printf("truncated-ip %u", length);
566		return;
567	}
568	hlen = IP_HL(ipds->ip) * 4;
569	if (hlen < sizeof (struct ip)) {
570		(void)printf("bad-hlen %u", hlen);
571		return;
572	}
573
574	ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);
575	if (length < ipds->len)
576		(void)printf("truncated-ip - %u bytes missing! ",
577			ipds->len - length);
578	if (ipds->len < hlen) {
579#ifdef GUESS_TSO
580            if (ipds->len) {
581                (void)printf("bad-len %u", ipds->len);
582                return;
583            }
584            else {
585                /* we guess that it is a TSO send */
586                ipds->len = length;
587            }
588#else
589            (void)printf("bad-len %u", ipds->len);
590            return;
591#endif /* GUESS_TSO */
592	}
593
594	/*
595	 * Cut off the snapshot length to the end of the IP payload.
596	 */
597	ipend = bp + ipds->len;
598	if (ipend < snapend)
599		snapend = ipend;
600
601	ipds->len -= hlen;
602
603	ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off);
604
605        if (vflag) {
606            (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos);
607            /* ECN bits */
608            if (ipds->ip->ip_tos & 0x03) {
609                switch (ipds->ip->ip_tos & 0x03) {
610                case 1:
611                    (void)printf(",ECT(1)");
612                    break;
613                case 2:
614                    (void)printf(",ECT(0)");
615                    break;
616                case 3:
617                    (void)printf(",CE");
618                }
619            }
620
621            if (ipds->ip->ip_ttl >= 1)
622                (void)printf(", ttl %3u", ipds->ip->ip_ttl);
623
624	    /*
625	     * for the firewall guys, print id, offset.
626             * On all but the last stick a "+" in the flags portion.
627	     * For unfragmented datagrams, note the don't fragment flag.
628	     */
629
630	    (void)printf(", id %u, offset %u, flags [%s], proto: %s (%u)",
631                         EXTRACT_16BITS(&ipds->ip->ip_id),
632                         (ipds->off & 0x1fff) * 8,
633                         bittok2str(ip_frag_values, "none", ipds->off&0xe000 ),
634                         tok2str(ipproto_values,"unknown",ipds->ip->ip_p),
635                         ipds->ip->ip_p);
636
637            (void)printf(", length: %u", EXTRACT_16BITS(&ipds->ip->ip_len));
638
639            if ((hlen - sizeof(struct ip)) > 0) {
640                printf(", options ( ");
641                ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip));
642                printf(" )");
643            }
644
645	    if ((u_char *)ipds->ip + hlen <= snapend) {
646	        sum = in_cksum((const u_short *)ipds->ip, hlen, 0);
647		if (sum != 0) {
648		    ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum);
649		    (void)printf(", bad cksum %x (->%x)!", ip_sum,
650			     in_cksum_shouldbe(ip_sum, sum));
651		}
652	    }
653
654            printf(") ");
655	}
656
657	/*
658	 * If this is fragment zero, hand it to the next higher
659	 * level protocol.
660	 */
661	if ((ipds->off & 0x1fff) == 0) {
662		ipds->cp = (const u_char *)ipds->ip + hlen;
663		ipds->nh = ipds->ip->ip_p;
664
665		if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP &&
666		    ipds->nh != IPPROTO_SCTP) {
667			(void)printf("%s > %s: ",
668				     ipaddr_string(&ipds->ip->ip_src),
669				     ipaddr_string(&ipds->ip->ip_dst));
670		}
671		ip_print_demux(ndo, ipds);
672	} else {
673	    /* Ultra quiet now means that all this stuff should be suppressed */
674	    if (qflag > 1) return;
675
676	    /*
677	     * if this isn't the first frag, we're missing the
678	     * next level protocol header.  print the ip addr
679	     * and the protocol.
680	     */
681	    if (ipds->off & 0x1fff) {
682	        (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src),
683			     ipaddr_string(&ipds->ip->ip_dst));
684		if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
685		    (void)printf(" %s", proto->p_name);
686		else
687		    (void)printf(" ip-proto-%d", ipds->ip->ip_p);
688	    }
689	}
690}
691
692void
693ipN_print(register const u_char *bp, register u_int length)
694{
695	struct ip *ip, hdr;
696
697	ip = (struct ip *)bp;
698	if (length < 4) {
699		(void)printf("truncated-ip %d", length);
700		return;
701	}
702	memcpy (&hdr, (char *)ip, 4);
703	switch (IP_V(&hdr)) {
704	case 4:
705		ip_print (gndo, bp, length);
706		return;
707#ifdef INET6
708	case 6:
709		ip6_print (bp, length);
710		return;
711#endif
712	default:
713		(void)printf("unknown ip %d", IP_V(&hdr));
714		return;
715	}
716}
717
718/*
719 * Local Variables:
720 * c-style: whitesmith
721 * c-basic-offset: 8
722 * End:
723 */
724
725
726