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.2 2005/09/20 06:05:38 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 { 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_DCCP: 418 dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len); 419 break; 420 421 case IPPROTO_TCP: 422 tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, 423 (ipds->off &~ 0x6000)); 424 break; 425 426 case IPPROTO_UDP: 427 udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, 428 (ipds->off &~ 0x6000)); 429 break; 430 431 case IPPROTO_ICMP: 432 /* pass on the MF bit plus the offset to detect fragments */ 433 icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip, 434 (ipds->off & 0x3fff)); 435 break; 436 437 case IPPROTO_PIGP: 438 /* 439 * XXX - the current IANA protocol number assignments 440 * page lists 9 as "any private interior gateway 441 * (used by Cisco for their IGRP)" and 88 as 442 * "EIGRP" from Cisco. 443 * 444 * Recent BSD <netinet/in.h> headers define 445 * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88. 446 * We define IP_PROTO_PIGP as 9 and 447 * IP_PROTO_EIGRP as 88; those names better 448 * match was the current protocol number 449 * assignments say. 450 */ 451 igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); 452 break; 453 454 case IPPROTO_EIGRP: 455 eigrp_print(ipds->cp, ipds->len); 456 break; 457 458 case IPPROTO_ND: 459 ND_PRINT((ndo, " nd %d", ipds->len)); 460 break; 461 462 case IPPROTO_EGP: 463 egp_print(ipds->cp, ipds->len); 464 break; 465 466 case IPPROTO_OSPF: 467 ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); 468 break; 469 470 case IPPROTO_IGMP: 471 igmp_print(ipds->cp, ipds->len); 472 break; 473 474 case IPPROTO_IPV4: 475 /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ 476 ip_print(gndo, ipds->cp, ipds->len); 477 if (! vflag) { 478 ND_PRINT((ndo, " (ipip-proto-4)")); 479 return; 480 } 481 break; 482 483 #ifdef INET6 484 case IPPROTO_IPV6: 485 /* ip6-in-ip encapsulation */ 486 ip6_print(ipds->cp, ipds->len); 487 break; 488 #endif /*INET6*/ 489 490 case IPPROTO_RSVP: 491 rsvp_print(ipds->cp, ipds->len); 492 break; 493 494 case IPPROTO_GRE: 495 /* do it */ 496 gre_print(ipds->cp, ipds->len); 497 break; 498 499 case IPPROTO_MOBILE: 500 mobile_print(ipds->cp, ipds->len); 501 break; 502 503 case IPPROTO_PIM: 504 pim_print(ipds->cp, ipds->len); 505 break; 506 507 case IPPROTO_VRRP: 508 vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl); 509 break; 510 511 case IPPROTO_PGM: 512 pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip); 513 break; 514 515 default: 516 if ((proto = getprotobynumber(ipds->nh)) != NULL) 517 ND_PRINT((ndo, " %s", proto->p_name)); 518 else 519 ND_PRINT((ndo, " ip-proto-%d", ipds->nh)); 520 ND_PRINT((ndo, " %d", ipds->len)); 521 break; 522 } 523 } 524 525 void 526 ip_print_inner(netdissect_options *ndo, 527 const u_char *bp, 528 u_int length, u_int nh, 529 const u_char *bp2) 530 { 531 struct ip_print_demux_state ipd; 532 533 ipd.ip = (const struct ip *)bp2; 534 ipd.cp = bp; 535 ipd.len = length; 536 ipd.off = 0; 537 ipd.nh = nh; 538 ipd.advance = 0; 539 540 ip_print_demux(ndo, &ipd); 541 } 542 543 544 /* 545 * print an IP datagram. 546 */ 547 void 548 ip_print(netdissect_options *ndo, 549 const u_char *bp, 550 u_int length) 551 { 552 struct ip_print_demux_state ipd; 553 struct ip_print_demux_state *ipds=&ipd; 554 const u_char *ipend; 555 u_int hlen; 556 u_int16_t sum, ip_sum; 557 struct protoent *proto; 558 559 ipds->ip = (const struct ip *)bp; 560 if (IP_V(ipds->ip) != 4) { /* print version if != 4 */ 561 printf("IP%u ", IP_V(ipds->ip)); 562 if (IP_V(ipds->ip) == 6) 563 printf(", wrong link-layer encapsulation"); 564 } 565 else if (!eflag) 566 printf("IP "); 567 568 if ((u_char *)(ipds->ip + 1) > snapend) { 569 printf("[|ip]"); 570 return; 571 } 572 if (length < sizeof (struct ip)) { 573 (void)printf("truncated-ip %u", length); 574 return; 575 } 576 hlen = IP_HL(ipds->ip) * 4; 577 if (hlen < sizeof (struct ip)) { 578 (void)printf("bad-hlen %u", hlen); 579 return; 580 } 581 582 ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len); 583 if (length < ipds->len) 584 (void)printf("truncated-ip - %u bytes missing! ", 585 ipds->len - length); 586 if (ipds->len < hlen) { 587 #ifdef GUESS_TSO 588 if (ipds->len) { 589 (void)printf("bad-len %u", ipds->len); 590 return; 591 } 592 else { 593 /* we guess that it is a TSO send */ 594 ipds->len = length; 595 } 596 #else 597 (void)printf("bad-len %u", ipds->len); 598 return; 599 #endif /* GUESS_TSO */ 600 } 601 602 /* 603 * Cut off the snapshot length to the end of the IP payload. 604 */ 605 ipend = bp + ipds->len; 606 if (ipend < snapend) 607 snapend = ipend; 608 609 ipds->len -= hlen; 610 611 ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off); 612 613 if (vflag) { 614 (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos); 615 /* ECN bits */ 616 if (ipds->ip->ip_tos & 0x03) { 617 switch (ipds->ip->ip_tos & 0x03) { 618 case 1: 619 (void)printf(",ECT(1)"); 620 break; 621 case 2: 622 (void)printf(",ECT(0)"); 623 break; 624 case 3: 625 (void)printf(",CE"); 626 } 627 } 628 629 if (ipds->ip->ip_ttl >= 1) 630 (void)printf(", ttl %3u", ipds->ip->ip_ttl); 631 632 /* 633 * for the firewall guys, print id, offset. 634 * On all but the last stick a "+" in the flags portion. 635 * For unfragmented datagrams, note the don't fragment flag. 636 */ 637 638 (void)printf(", id %u, offset %u, flags [%s], proto: %s (%u)", 639 EXTRACT_16BITS(&ipds->ip->ip_id), 640 (ipds->off & 0x1fff) * 8, 641 bittok2str(ip_frag_values, "none", ipds->off&0xe000 ), 642 tok2str(ipproto_values,"unknown",ipds->ip->ip_p), 643 ipds->ip->ip_p); 644 645 (void)printf(", length: %u", EXTRACT_16BITS(&ipds->ip->ip_len)); 646 647 if ((hlen - sizeof(struct ip)) > 0) { 648 printf(", options ( "); 649 ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip)); 650 printf(" )"); 651 } 652 653 if ((u_char *)ipds->ip + hlen <= snapend) { 654 sum = in_cksum((const u_short *)ipds->ip, hlen, 0); 655 if (sum != 0) { 656 ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum); 657 (void)printf(", bad cksum %x (->%x)!", ip_sum, 658 in_cksum_shouldbe(ip_sum, sum)); 659 } 660 } 661 662 printf(") "); 663 } 664 665 /* 666 * If this is fragment zero, hand it to the next higher 667 * level protocol. 668 */ 669 if ((ipds->off & 0x1fff) == 0) { 670 ipds->cp = (const u_char *)ipds->ip + hlen; 671 ipds->nh = ipds->ip->ip_p; 672 673 if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP && 674 ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) { 675 (void)printf("%s > %s: ", 676 ipaddr_string(&ipds->ip->ip_src), 677 ipaddr_string(&ipds->ip->ip_dst)); 678 } 679 ip_print_demux(ndo, ipds); 680 } else { 681 /* Ultra quiet now means that all this stuff should be suppressed */ 682 if (qflag > 1) return; 683 684 /* 685 * if this isn't the first frag, we're missing the 686 * next level protocol header. print the ip addr 687 * and the protocol. 688 */ 689 if (ipds->off & 0x1fff) { 690 (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src), 691 ipaddr_string(&ipds->ip->ip_dst)); 692 if ((proto = getprotobynumber(ipds->ip->ip_p)) != NULL) 693 (void)printf(" %s", proto->p_name); 694 else 695 (void)printf(" ip-proto-%d", ipds->ip->ip_p); 696 } 697 } 698 } 699 700 void 701 ipN_print(register const u_char *bp, register u_int length) 702 { 703 struct ip *ip, hdr; 704 705 ip = (struct ip *)bp; 706 if (length < 4) { 707 (void)printf("truncated-ip %d", length); 708 return; 709 } 710 memcpy (&hdr, (char *)ip, 4); 711 switch (IP_V(&hdr)) { 712 case 4: 713 ip_print (gndo, bp, length); 714 return; 715 #ifdef INET6 716 case 6: 717 ip6_print (bp, length); 718 return; 719 #endif 720 default: 721 (void)printf("unknown ip %d", IP_V(&hdr)); 722 return; 723 } 724 } 725 726 /* 727 * Local Variables: 728 * c-style: whitesmith 729 * c-basic-offset: 8 730 * End: 731 */ 732 733 734