Our pf includes are in /usr/include/net/pf/, so adjust the appropriate
[dragonfly.git] / contrib / tcpdump-3.9 / 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
22 #ifndef lint
23 static const char rcsid[] _U_ =
24     "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.149.2.8 2007/01/29 20:57:47 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
44 struct 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  */
59 static void
60 ip_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  */
89 u_int32_t
90 ip_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         }
126 trunc:
127         memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
128         return retval;
129 }
130
131 static void
132 ip_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
184 done:
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  */
196 static void
197 ip_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
266 trunc:
267         printf("[|ip]");
268 }
269
270 /*
271  * compute an IP header checksum.
272  * don't modifiy the packet.
273  */
274 u_short
275 in_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  */
310 u_int16_t
311 in_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
358 static 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
365 struct 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
373 static void
374 ip_print_demux(netdissect_options *ndo,
375                struct ip_print_demux_state *ipds)
376 {
377         struct protoent *proto;
378
379 again:
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                
531 void
532 ip_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  */
553 void
554 ip_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 %u", 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
706 void
707 ipN_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