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