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