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