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.2.9 2007/09/14 01:30:02 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(") "); 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 743