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