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[] = 26 "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.92 2001/01/02 23:00:01 guy Exp $ (LBL)"; 27 #endif 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #include <sys/param.h> 34 #include <sys/time.h> 35 #include <sys/socket.h> 36 37 #include <netinet/in.h> 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <unistd.h> 43 44 #include "addrtoname.h" 45 #include "interface.h" 46 #include "extract.h" /* must come after interface.h */ 47 48 #include "ip.h" 49 50 /* Compatibility */ 51 #ifndef IPPROTO_ND 52 #define IPPROTO_ND 77 53 #endif 54 55 /* 56 * print the recorded route in an IP RR, LSRR or SSRR option. 57 */ 58 static void 59 ip_printroute(const char *type, register const u_char *cp, u_int length) 60 { 61 register u_int ptr = cp[2] - 1; 62 register u_int len; 63 64 printf(" %s{", type); 65 if ((length + 1) & 3) 66 printf(" [bad length %d]", length); 67 if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) 68 printf(" [bad ptr %d]", cp[2]); 69 70 type = ""; 71 for (len = 3; len < length; len += 4) { 72 if (ptr == len) 73 type = "#"; 74 printf("%s%s", type, ipaddr_string(&cp[len])); 75 type = " "; 76 } 77 printf("%s}", ptr == len? "#" : ""); 78 } 79 80 static void 81 ip_printts(register const u_char *cp, u_int length) 82 { 83 register u_int ptr = cp[2] - 1; 84 register u_int len = 0; 85 int hoplen; 86 char *type; 87 88 printf(" TS{"); 89 hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; 90 if ((length - 4) & (hoplen-1)) 91 printf("[bad length %d]", length); 92 if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) 93 printf("[bad ptr %d]", cp[2]); 94 switch (cp[3]&0xF) { 95 case IPOPT_TS_TSONLY: 96 printf("TSONLY"); 97 break; 98 case IPOPT_TS_TSANDADDR: 99 printf("TS+ADDR"); 100 break; 101 /* 102 * prespecified should really be 3, but some ones might send 2 103 * instead, and the IPOPT_TS_PRESPEC constant can apparently 104 * have both values, so we have to hard-code it here. 105 */ 106 107 case 2: 108 printf("PRESPEC2.0"); 109 break; 110 case 3: /* IPOPT_TS_PRESPEC */ 111 printf("PRESPEC"); 112 break; 113 default: 114 printf("[bad ts type %d]", cp[3]&0xF); 115 goto done; 116 } 117 118 type = " "; 119 for (len = 4; len < length; len += hoplen) { 120 if (ptr == len) 121 type = " ^ "; 122 printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), 123 hoplen!=8 ? "" : ipaddr_string(&cp[len])); 124 type = " "; 125 } 126 127 done: 128 printf("%s", ptr == len ? " ^ " : ""); 129 130 if (cp[3]>>4) 131 printf(" [%d hops not recorded]} ", cp[3]>>4); 132 else 133 printf("}"); 134 } 135 136 /* 137 * print IP options. 138 */ 139 static void 140 ip_optprint(register const u_char *cp, u_int length) 141 { 142 register u_int len; 143 144 for (; length > 0; cp += len, length -= len) { 145 int tt = *cp; 146 147 if (tt == IPOPT_NOP || tt == IPOPT_EOL) 148 len = 1; 149 else { 150 if (&cp[1] >= snapend) { 151 printf("[|ip]"); 152 return; 153 } 154 len = cp[1]; 155 } 156 if (len <= 0) { 157 printf("[|ip op len %d]", len); 158 return; 159 } 160 if (&cp[1] >= snapend || cp + len > snapend) { 161 printf("[|ip]"); 162 return; 163 } 164 switch (tt) { 165 166 case IPOPT_EOL: 167 printf(" EOL"); 168 if (length > 1) 169 printf("-%d", length - 1); 170 return; 171 172 case IPOPT_NOP: 173 printf(" NOP"); 174 break; 175 176 case IPOPT_TS: 177 ip_printts(cp, len); 178 break; 179 180 #ifndef IPOPT_SECURITY 181 #define IPOPT_SECURITY 130 182 #endif /* IPOPT_SECURITY */ 183 case IPOPT_SECURITY: 184 printf(" SECURITY{%d}", len); 185 break; 186 187 case IPOPT_RR: 188 ip_printroute("RR", cp, len); 189 break; 190 191 case IPOPT_SSRR: 192 ip_printroute("SSRR", cp, len); 193 break; 194 195 case IPOPT_LSRR: 196 ip_printroute("LSRR", cp, len); 197 break; 198 199 #ifndef IPOPT_RA 200 #define IPOPT_RA 148 /* router alert */ 201 #endif 202 case IPOPT_RA: 203 printf(" RA"); 204 if (len != 4) 205 printf("{%d}", len); 206 else if (cp[2] || cp[3]) 207 printf("%d.%d", cp[2], cp[3]); 208 break; 209 210 default: 211 printf(" IPOPT-%d{%d}", cp[0], len); 212 break; 213 } 214 } 215 } 216 217 /* 218 * compute an IP header checksum. 219 * don't modifiy the packet. 220 */ 221 u_short 222 in_cksum(const u_short *addr, register int len, u_short csum) 223 { 224 int nleft = len; 225 const u_short *w = addr; 226 u_short answer; 227 int sum = csum; 228 229 /* 230 * Our algorithm is simple, using a 32 bit accumulator (sum), 231 * we add sequential 16 bit words to it, and at the end, fold 232 * back all the carry bits from the top 16 bits into the lower 233 * 16 bits. 234 */ 235 while (nleft > 1) { 236 sum += *w++; 237 nleft -= 2; 238 } 239 if (nleft == 1) 240 sum += htons(*(u_char *)w<<8); 241 242 /* 243 * add back carry outs from top 16 bits to low 16 bits 244 */ 245 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 246 sum += (sum >> 16); /* add carry */ 247 answer = ~sum; /* truncate to 16 bits */ 248 return (answer); 249 } 250 251 /* 252 * print an IP datagram. 253 */ 254 void 255 ip_print(register const u_char *bp, register u_int length) 256 { 257 register const struct ip *ip; 258 register u_int hlen, len, len0, off; 259 register const u_char *cp; 260 u_char nh; 261 int advance; 262 263 ip = (const struct ip *)bp; 264 #ifdef LBL_ALIGN 265 /* 266 * If the IP header is not aligned, copy into abuf. 267 * This will never happen with BPF. It does happen raw packet 268 * dumps from -r. 269 */ 270 if ((long)ip & 3) { 271 static u_char *abuf = NULL; 272 static int didwarn = 0; 273 274 if (abuf == NULL) { 275 abuf = (u_char *)malloc(snaplen); 276 if (abuf == NULL) 277 error("ip_print: malloc"); 278 } 279 memcpy((char *)abuf, (char *)ip, min(length, snaplen)); 280 snapend += abuf - (u_char *)ip; 281 packetp = abuf; 282 ip = (struct ip *)abuf; 283 /* We really want libpcap to give us aligned packets */ 284 if (!didwarn) { 285 warning("compensating for unaligned libpcap packets"); 286 ++didwarn; 287 } 288 } 289 #endif 290 if ((u_char *)(ip + 1) > snapend) { 291 printf("[|ip]"); 292 return; 293 } 294 if (length < sizeof (struct ip)) { 295 (void)printf("truncated-ip %d", length); 296 return; 297 } 298 hlen = IP_HL(ip) * 4; 299 if (hlen < sizeof (struct ip)) { 300 (void)printf("bad-hlen %d", hlen); 301 return; 302 } 303 304 len = ntohs(ip->ip_len); 305 if (length < len) 306 (void)printf("truncated-ip - %d bytes missing!", 307 len - length); 308 len -= hlen; 309 len0 = len; 310 311 /* 312 * If this is fragment zero, hand it to the next higher 313 * level protocol. 314 */ 315 off = ntohs(ip->ip_off); 316 if ((off & 0x1fff) == 0) { 317 cp = (const u_char *)ip + hlen; 318 nh = ip->ip_p; 319 320 if (nh != IPPROTO_TCP && nh != IPPROTO_UDP) { 321 (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), 322 ipaddr_string(&ip->ip_dst)); 323 } 324 again: 325 switch (nh) { 326 327 #ifndef IPPROTO_AH 328 #define IPPROTO_AH 51 329 #endif 330 case IPPROTO_AH: 331 nh = *cp; 332 advance = ah_print(cp, (const u_char *)ip); 333 cp += advance; 334 len -= advance; 335 goto again; 336 337 #ifndef IPPROTO_ESP 338 #define IPPROTO_ESP 50 339 #endif 340 case IPPROTO_ESP: 341 { 342 int enh; 343 advance = esp_print(cp, (const u_char *)ip, &enh); 344 cp += advance; 345 len -= advance; 346 if (enh < 0) 347 break; 348 nh = enh & 0xff; 349 goto again; 350 } 351 352 #ifndef IPPROTO_IPCOMP 353 #define IPPROTO_IPCOMP 108 354 #endif 355 case IPPROTO_IPCOMP: 356 { 357 int enh; 358 advance = ipcomp_print(cp, (const u_char *)ip, &enh); 359 cp += advance; 360 len -= advance; 361 if (enh < 0) 362 break; 363 nh = enh & 0xff; 364 goto again; 365 } 366 367 case IPPROTO_TCP: 368 tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 369 break; 370 371 case IPPROTO_UDP: 372 udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 373 break; 374 375 case IPPROTO_ICMP: 376 icmp_print(cp, len, (const u_char *)ip); 377 break; 378 379 #ifndef IPPROTO_IGRP 380 #define IPPROTO_IGRP 9 381 #endif 382 case IPPROTO_IGRP: 383 igrp_print(cp, len, (const u_char *)ip); 384 break; 385 386 case IPPROTO_ND: 387 #if 0 388 (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 389 ipaddr_string(&ip->ip_dst)); 390 #endif 391 (void)printf(" nd %d", len); 392 break; 393 394 case IPPROTO_EGP: 395 egp_print(cp, len, (const u_char *)ip); 396 break; 397 398 #ifndef IPPROTO_OSPF 399 #define IPPROTO_OSPF 89 400 #endif 401 case IPPROTO_OSPF: 402 ospf_print(cp, len, (const u_char *)ip); 403 break; 404 405 #ifndef IPPROTO_IGMP 406 #define IPPROTO_IGMP 2 407 #endif 408 case IPPROTO_IGMP: 409 igmp_print(cp, len, (const u_char *)ip); 410 break; 411 412 case 4: 413 /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ 414 #if 0 415 if (vflag) 416 (void)printf("%s > %s: ", 417 ipaddr_string(&ip->ip_src), 418 ipaddr_string(&ip->ip_dst)); 419 #endif 420 ip_print(cp, len); 421 if (! vflag) { 422 printf(" (ipip)"); 423 return; 424 } 425 break; 426 427 #ifdef INET6 428 #ifndef IP6PROTO_ENCAP 429 #define IP6PROTO_ENCAP 41 430 #endif 431 case IP6PROTO_ENCAP: 432 /* ip6-in-ip encapsulation */ 433 #if 0 434 if (vflag) 435 (void)printf("%s > %s: ", 436 ipaddr_string(&ip->ip_src), 437 ipaddr_string(&ip->ip_dst)); 438 #endif 439 ip6_print(cp, len); 440 if (! vflag) { 441 printf(" (encap)"); 442 return; 443 } 444 break; 445 #endif /*INET6*/ 446 447 448 #ifndef IPPROTO_GRE 449 #define IPPROTO_GRE 47 450 #endif 451 case IPPROTO_GRE: 452 if (vflag) 453 (void)printf("gre %s > %s: ", 454 ipaddr_string(&ip->ip_src), 455 ipaddr_string(&ip->ip_dst)); 456 /* do it */ 457 gre_print(cp, len); 458 if (! vflag) { 459 printf(" (gre encap)"); 460 return; 461 } 462 break; 463 464 #ifndef IPPROTO_MOBILE 465 #define IPPROTO_MOBILE 55 466 #endif 467 case IPPROTO_MOBILE: 468 if (vflag) 469 (void)printf("mobile %s > %s: ", 470 ipaddr_string(&ip->ip_src), 471 ipaddr_string(&ip->ip_dst)); 472 mobile_print(cp, len); 473 if (! vflag) { 474 printf(" (mobile encap)"); 475 return; 476 } 477 break; 478 479 #ifndef IPPROTO_PIM 480 #define IPPROTO_PIM 103 481 #endif 482 case IPPROTO_PIM: 483 pim_print(cp, len); 484 break; 485 486 #ifndef IPPROTO_VRRP 487 #define IPPROTO_VRRP 112 488 #endif 489 case IPPROTO_VRRP: 490 if (vflag) 491 (void)printf("vrrp %s > %s: ", 492 ipaddr_string(&ip->ip_src), 493 ipaddr_string(&ip->ip_dst)); 494 vrrp_print(cp, len, ip->ip_ttl); 495 break; 496 497 default: 498 #if 0 499 (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 500 ipaddr_string(&ip->ip_dst)); 501 #endif 502 (void)printf(" ip-proto-%d %d", nh, len); 503 break; 504 } 505 } 506 507 /* Ultra quiet now means that all this stuff should be suppressed */ 508 /* res 3-Nov-98 */ 509 if (qflag > 1) return; 510 511 512 /* 513 * for fragmented datagrams, print id:size@offset. On all 514 * but the last stick a "+". For unfragmented datagrams, note 515 * the don't fragment flag. 516 */ 517 len = len0; /* get the original length */ 518 if (off & 0x3fff) { 519 /* 520 * if this isn't the first frag, we're missing the 521 * next level protocol header. print the ip addr. 522 */ 523 if (off & 0x1fff) 524 (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 525 ipaddr_string(&ip->ip_dst)); 526 #ifndef IP_MF 527 #define IP_MF 0x2000 528 #endif /* IP_MF */ 529 #ifndef IP_DF 530 #define IP_DF 0x4000 531 #endif /* IP_DF */ 532 (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len, 533 (off & 0x1fff) * 8, 534 (off & IP_MF)? "+" : ""); 535 536 } else if (off & IP_DF) 537 (void)printf(" (DF)"); 538 539 if (ip->ip_tos) { 540 (void)printf(" [tos 0x%x", (int)ip->ip_tos); 541 /* ECN bits */ 542 if (ip->ip_tos&0x02) { 543 (void)printf(",ECT"); 544 if (ip->ip_tos&0x01) 545 (void)printf(",CE"); 546 } 547 (void)printf("] "); 548 } 549 550 if (ip->ip_ttl <= 1) 551 (void)printf(" [ttl %d]", (int)ip->ip_ttl); 552 553 if (vflag) { 554 int sum; 555 char *sep = ""; 556 557 printf(" ("); 558 if (ip->ip_ttl > 1) { 559 (void)printf("%sttl %d", sep, (int)ip->ip_ttl); 560 sep = ", "; 561 } 562 if ((off & 0x3fff) == 0) { 563 (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id)); 564 sep = ", "; 565 } 566 (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len)); 567 sep = ", "; 568 if ((u_char *)ip + hlen <= snapend) { 569 sum = in_cksum((const u_short *)ip, hlen, 0); 570 if (sum != 0) { 571 (void)printf("%sbad cksum %x!", sep, 572 ntohs(ip->ip_sum)); 573 sep = ", "; 574 } 575 } 576 if ((hlen -= sizeof(struct ip)) > 0) { 577 (void)printf("%soptlen=%d", sep, hlen); 578 ip_optprint((u_char *)(ip + 1), hlen); 579 } 580 printf(")"); 581 } 582 } 583 584 void 585 ipN_print(register const u_char *bp, register u_int length) 586 { 587 struct ip *ip, hdr; 588 589 ip = (struct ip *)bp; 590 if (length < 4) { 591 (void)printf("truncated-ip %d", length); 592 return; 593 } 594 memcpy (&hdr, (char *)ip, 4); 595 switch (IP_V(&hdr)) { 596 case 4: 597 ip_print (bp, length); 598 return; 599 #ifdef INET6 600 case 6: 601 ip6_print (bp, length); 602 return; 603 #endif 604 default: 605 (void)printf("unknown ip %d", IP_V(&hdr)); 606 return; 607 } 608 } 609