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