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