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.100 2001/09/17 21:58:03 fenner 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 u_int len, int 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 #ifndef IPPROTO_SCTP 321 #define IPPROTO_SCTP 132 322 #endif 323 if (nh != IPPROTO_TCP && nh != IPPROTO_UDP && 324 nh != IPPROTO_SCTP) { 325 (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), 326 ipaddr_string(&ip->ip_dst)); 327 } 328 again: 329 switch (nh) { 330 331 #ifndef IPPROTO_AH 332 #define IPPROTO_AH 51 333 #endif 334 case IPPROTO_AH: 335 nh = *cp; 336 advance = ah_print(cp, (const u_char *)ip); 337 cp += advance; 338 len -= advance; 339 goto again; 340 341 #ifndef IPPROTO_ESP 342 #define IPPROTO_ESP 50 343 #endif 344 case IPPROTO_ESP: 345 { 346 int enh, padlen; 347 advance = esp_print(cp, (const u_char *)ip, &enh, &padlen); 348 cp += advance; 349 len -= advance + padlen; 350 if (enh < 0) 351 break; 352 nh = enh & 0xff; 353 goto again; 354 } 355 356 #ifndef IPPROTO_IPCOMP 357 #define IPPROTO_IPCOMP 108 358 #endif 359 case IPPROTO_IPCOMP: 360 { 361 int enh; 362 advance = ipcomp_print(cp, (const u_char *)ip, &enh); 363 cp += advance; 364 len -= advance; 365 if (enh < 0) 366 break; 367 nh = enh & 0xff; 368 goto again; 369 } 370 371 case IPPROTO_SCTP: 372 sctp_print(cp, (const u_char *)ip, len); 373 break; 374 375 case IPPROTO_TCP: 376 tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 377 break; 378 379 case IPPROTO_UDP: 380 udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 381 break; 382 383 case IPPROTO_ICMP: 384 icmp_print(cp, len, (const u_char *)ip); 385 break; 386 387 #ifndef IPPROTO_IGRP 388 #define IPPROTO_IGRP 9 389 #endif 390 case IPPROTO_IGRP: 391 igrp_print(cp, len, (const u_char *)ip); 392 break; 393 394 case IPPROTO_ND: 395 (void)printf(" nd %d", len); 396 break; 397 398 case IPPROTO_EGP: 399 egp_print(cp, len, (const u_char *)ip); 400 break; 401 402 #ifndef IPPROTO_OSPF 403 #define IPPROTO_OSPF 89 404 #endif 405 case IPPROTO_OSPF: 406 ospf_print(cp, len, (const u_char *)ip); 407 break; 408 409 #ifndef IPPROTO_IGMP 410 #define IPPROTO_IGMP 2 411 #endif 412 case IPPROTO_IGMP: 413 igmp_print(cp, len); 414 break; 415 416 case 4: 417 /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ 418 ip_print(cp, len); 419 if (! vflag) { 420 printf(" (ipip-proto-4)"); 421 return; 422 } 423 break; 424 425 #ifdef INET6 426 #ifndef IP6PROTO_ENCAP 427 #define IP6PROTO_ENCAP 41 428 #endif 429 case IP6PROTO_ENCAP: 430 /* ip6-in-ip encapsulation */ 431 ip6_print(cp, len); 432 break; 433 #endif /*INET6*/ 434 435 436 #ifndef IPPROTO_GRE 437 #define IPPROTO_GRE 47 438 #endif 439 case IPPROTO_GRE: 440 /* do it */ 441 gre_print(cp, len); 442 break; 443 444 #ifndef IPPROTO_MOBILE 445 #define IPPROTO_MOBILE 55 446 #endif 447 case IPPROTO_MOBILE: 448 mobile_print(cp, len); 449 break; 450 451 #ifndef IPPROTO_PIM 452 #define IPPROTO_PIM 103 453 #endif 454 case IPPROTO_PIM: 455 pim_print(cp, len); 456 break; 457 458 #ifndef IPPROTO_VRRP 459 #define IPPROTO_VRRP 112 460 #endif 461 case IPPROTO_VRRP: 462 vrrp_print(cp, len, ip->ip_ttl); 463 break; 464 465 default: 466 (void)printf(" ip-proto-%d %d", nh, len); 467 break; 468 } 469 } 470 471 /* Ultra quiet now means that all this stuff should be suppressed */ 472 /* res 3-Nov-98 */ 473 if (qflag > 1) return; 474 475 476 /* 477 * for fragmented datagrams, print id:size@offset. On all 478 * but the last stick a "+". For unfragmented datagrams, note 479 * the don't fragment flag. 480 */ 481 len = len0; /* get the original length */ 482 if (off & 0x3fff) { 483 /* 484 * if this isn't the first frag, we're missing the 485 * next level protocol header. print the ip addr. 486 */ 487 if (off & 0x1fff) 488 (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 489 ipaddr_string(&ip->ip_dst)); 490 #ifndef IP_MF 491 #define IP_MF 0x2000 492 #endif /* IP_MF */ 493 #ifndef IP_DF 494 #define IP_DF 0x4000 495 #endif /* IP_DF */ 496 (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len, 497 (off & 0x1fff) * 8, 498 (off & IP_MF)? "+" : ""); 499 500 } else if (off & IP_DF) 501 (void)printf(" (DF)"); 502 503 if (ip->ip_tos) { 504 (void)printf(" [tos 0x%x", (int)ip->ip_tos); 505 /* ECN bits */ 506 if (ip->ip_tos & 0x03) { 507 switch (ip->ip_tos & 0x03) { 508 case 1: 509 (void)printf(",ECT(1)"); 510 break; 511 case 2: 512 (void)printf(",ECT(0)"); 513 break; 514 case 3: 515 (void)printf(",CE"); 516 } 517 } 518 (void)printf("] "); 519 } 520 521 if (ip->ip_ttl <= 1) 522 (void)printf(" [ttl %d]", (int)ip->ip_ttl); 523 524 if (vflag) { 525 int sum; 526 char *sep = ""; 527 528 printf(" ("); 529 if (ip->ip_ttl > 1) { 530 (void)printf("%sttl %d", sep, (int)ip->ip_ttl); 531 sep = ", "; 532 } 533 if ((off & 0x3fff) == 0) { 534 (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id)); 535 sep = ", "; 536 } 537 (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len)); 538 sep = ", "; 539 if ((u_char *)ip + hlen <= snapend) { 540 sum = in_cksum((const u_short *)ip, hlen, 0); 541 if (sum != 0) { 542 (void)printf("%sbad cksum %x!", sep, 543 ntohs(ip->ip_sum)); 544 sep = ", "; 545 } 546 } 547 if ((hlen -= sizeof(struct ip)) > 0) { 548 (void)printf("%soptlen=%d", sep, hlen); 549 ip_optprint((u_char *)(ip + 1), hlen); 550 } 551 printf(")"); 552 } 553 } 554 555 void 556 ipN_print(register const u_char *bp, register u_int length) 557 { 558 struct ip *ip, hdr; 559 560 ip = (struct ip *)bp; 561 if (length < 4) { 562 (void)printf("truncated-ip %d", length); 563 return; 564 } 565 memcpy (&hdr, (char *)ip, 4); 566 switch (IP_V(&hdr)) { 567 case 4: 568 ip_print (bp, length); 569 return; 570 #ifdef INET6 571 case 6: 572 ip6_print (bp, length); 573 return; 574 #endif 575 default: 576 (void)printf("unknown ip %d", IP_V(&hdr)); 577 return; 578 } 579 } 580