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.4.1 2002/01/25 05:39:54 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 <netdb.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 #include <string.h> 43 #include <unistd.h> 44 45 #include "addrtoname.h" 46 #include "interface.h" 47 #include "extract.h" /* must come after interface.h */ 48 49 #include "ip.h" 50 51 /* Compatibility */ 52 #ifndef IPPROTO_ND 53 #define IPPROTO_ND 77 54 #endif 55 56 /* 57 * print the recorded route in an IP RR, LSRR or SSRR option. 58 */ 59 static void 60 ip_printroute(const char *type, register const u_char *cp, u_int length) 61 { 62 register u_int ptr = cp[2] - 1; 63 register u_int len; 64 65 printf(" %s{", type); 66 if ((length + 1) & 3) 67 printf(" [bad length %d]", length); 68 if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) 69 printf(" [bad ptr %d]", cp[2]); 70 71 type = ""; 72 for (len = 3; len < length; len += 4) { 73 if (ptr == len) 74 type = "#"; 75 printf("%s%s", type, ipaddr_string(&cp[len])); 76 type = " "; 77 } 78 printf("%s}", ptr == len? "#" : ""); 79 } 80 81 static void 82 ip_printts(register const u_char *cp, u_int length) 83 { 84 register u_int ptr = cp[2] - 1; 85 register u_int len = 0; 86 int hoplen; 87 char *type; 88 89 printf(" TS{"); 90 hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; 91 if ((length - 4) & (hoplen-1)) 92 printf("[bad length %d]", length); 93 if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) 94 printf("[bad ptr %d]", cp[2]); 95 switch (cp[3]&0xF) { 96 case IPOPT_TS_TSONLY: 97 printf("TSONLY"); 98 break; 99 case IPOPT_TS_TSANDADDR: 100 printf("TS+ADDR"); 101 break; 102 /* 103 * prespecified should really be 3, but some ones might send 2 104 * instead, and the IPOPT_TS_PRESPEC constant can apparently 105 * have both values, so we have to hard-code it here. 106 */ 107 108 case 2: 109 printf("PRESPEC2.0"); 110 break; 111 case 3: /* IPOPT_TS_PRESPEC */ 112 printf("PRESPEC"); 113 break; 114 default: 115 printf("[bad ts type %d]", cp[3]&0xF); 116 goto done; 117 } 118 119 type = " "; 120 for (len = 4; len < length; len += hoplen) { 121 if (ptr == len) 122 type = " ^ "; 123 printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), 124 hoplen!=8 ? "" : ipaddr_string(&cp[len])); 125 type = " "; 126 } 127 128 done: 129 printf("%s", ptr == len ? " ^ " : ""); 130 131 if (cp[3]>>4) 132 printf(" [%d hops not recorded]} ", cp[3]>>4); 133 else 134 printf("}"); 135 } 136 137 /* 138 * print IP options. 139 */ 140 static void 141 ip_optprint(register const u_char *cp, u_int length) 142 { 143 register u_int len; 144 145 for (; length > 0; cp += len, length -= len) { 146 int tt = *cp; 147 148 if (tt == IPOPT_NOP || tt == IPOPT_EOL) 149 len = 1; 150 else { 151 if (&cp[1] >= snapend) { 152 printf("[|ip]"); 153 return; 154 } 155 len = cp[1]; 156 } 157 if (len <= 0) { 158 printf("[|ip op len %d]", len); 159 return; 160 } 161 if (&cp[1] >= snapend || cp + len > snapend) { 162 printf("[|ip]"); 163 return; 164 } 165 switch (tt) { 166 167 case IPOPT_EOL: 168 printf(" EOL"); 169 if (length > 1) 170 printf("-%d", length - 1); 171 return; 172 173 case IPOPT_NOP: 174 printf(" NOP"); 175 break; 176 177 case IPOPT_TS: 178 ip_printts(cp, len); 179 break; 180 181 #ifndef IPOPT_SECURITY 182 #define IPOPT_SECURITY 130 183 #endif /* IPOPT_SECURITY */ 184 case IPOPT_SECURITY: 185 printf(" SECURITY{%d}", len); 186 break; 187 188 case IPOPT_RR: 189 ip_printroute("RR", cp, len); 190 break; 191 192 case IPOPT_SSRR: 193 ip_printroute("SSRR", cp, len); 194 break; 195 196 case IPOPT_LSRR: 197 ip_printroute("LSRR", cp, len); 198 break; 199 200 #ifndef IPOPT_RA 201 #define IPOPT_RA 148 /* router alert */ 202 #endif 203 case IPOPT_RA: 204 printf(" RA"); 205 if (len != 4) 206 printf("{%d}", len); 207 else if (cp[2] || cp[3]) 208 printf("%d.%d", cp[2], cp[3]); 209 break; 210 211 default: 212 printf(" IPOPT-%d{%d}", cp[0], len); 213 break; 214 } 215 } 216 } 217 218 /* 219 * compute an IP header checksum. 220 * don't modifiy the packet. 221 */ 222 u_short 223 in_cksum(const u_short *addr, register u_int len, int csum) 224 { 225 int nleft = len; 226 const u_short *w = addr; 227 u_short answer; 228 int sum = csum; 229 230 /* 231 * Our algorithm is simple, using a 32 bit accumulator (sum), 232 * we add sequential 16 bit words to it, and at the end, fold 233 * back all the carry bits from the top 16 bits into the lower 234 * 16 bits. 235 */ 236 while (nleft > 1) { 237 sum += *w++; 238 nleft -= 2; 239 } 240 if (nleft == 1) 241 sum += htons(*(u_char *)w<<8); 242 243 /* 244 * add back carry outs from top 16 bits to low 16 bits 245 */ 246 sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 247 sum += (sum >> 16); /* add carry */ 248 answer = ~sum; /* truncate to 16 bits */ 249 return (answer); 250 } 251 252 /* 253 * print an IP datagram. 254 */ 255 void 256 ip_print(register const u_char *bp, register u_int length) 257 { 258 register const struct ip *ip; 259 register u_int hlen, len, len0, off; 260 register const u_char *cp; 261 u_char nh; 262 int advance; 263 struct protoent *proto; 264 265 ip = (const struct ip *)bp; 266 #ifdef LBL_ALIGN 267 /* 268 * If the IP header is not aligned, copy into abuf. 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 if ((proto = getprotobynumber(nh)) != NULL) 467 (void)printf(" %s", proto->p_name); 468 else 469 (void)printf(" ip-proto-%d", nh); 470 printf(" %d", len); 471 break; 472 } 473 } 474 475 /* Ultra quiet now means that all this stuff should be suppressed */ 476 /* res 3-Nov-98 */ 477 if (qflag > 1) return; 478 479 480 /* 481 * for fragmented datagrams, print id:size@offset. On all 482 * but the last stick a "+". For unfragmented datagrams, note 483 * the don't fragment flag. 484 */ 485 len = len0; /* get the original length */ 486 if (off & 0x3fff) { 487 /* 488 * if this isn't the first frag, we're missing the 489 * next level protocol header. print the ip addr 490 * and the protocol. 491 */ 492 if (off & 0x1fff) { 493 (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 494 ipaddr_string(&ip->ip_dst)); 495 if ((proto = getprotobynumber(ip->ip_p)) != NULL) 496 (void)printf(" %s", proto->p_name); 497 else 498 (void)printf(" ip-proto-%d", ip->ip_p); 499 } 500 #ifndef IP_MF 501 #define IP_MF 0x2000 502 #endif /* IP_MF */ 503 #ifndef IP_DF 504 #define IP_DF 0x4000 505 #endif /* IP_DF */ 506 (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len, 507 (off & 0x1fff) * 8, 508 (off & IP_MF)? "+" : ""); 509 510 } else if (off & IP_DF) 511 (void)printf(" (DF)"); 512 513 if (ip->ip_tos) { 514 (void)printf(" [tos 0x%x", (int)ip->ip_tos); 515 /* ECN bits */ 516 if (ip->ip_tos & 0x03) { 517 switch (ip->ip_tos & 0x03) { 518 case 1: 519 (void)printf(",ECT(1)"); 520 break; 521 case 2: 522 (void)printf(",ECT(0)"); 523 break; 524 case 3: 525 (void)printf(",CE"); 526 } 527 } 528 (void)printf("] "); 529 } 530 531 if (ip->ip_ttl <= 1) 532 (void)printf(" [ttl %d]", (int)ip->ip_ttl); 533 534 if (vflag) { 535 int sum; 536 char *sep = ""; 537 538 printf(" ("); 539 if (ip->ip_ttl > 1) { 540 (void)printf("%sttl %d", sep, (int)ip->ip_ttl); 541 sep = ", "; 542 } 543 if ((off & 0x3fff) == 0) { 544 (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id)); 545 sep = ", "; 546 } 547 (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len)); 548 sep = ", "; 549 if ((u_char *)ip + hlen <= snapend) { 550 sum = in_cksum((const u_short *)ip, hlen, 0); 551 if (sum != 0) { 552 (void)printf("%sbad cksum %x!", sep, 553 ntohs(ip->ip_sum)); 554 sep = ", "; 555 } 556 } 557 if ((hlen -= sizeof(struct ip)) > 0) { 558 (void)printf("%soptlen=%d", sep, hlen); 559 ip_optprint((u_char *)(ip + 1), hlen); 560 } 561 printf(")"); 562 } 563 } 564 565 void 566 ipN_print(register const u_char *bp, register u_int length) 567 { 568 struct ip *ip, hdr; 569 570 ip = (struct ip *)bp; 571 if (length < 4) { 572 (void)printf("truncated-ip %d", length); 573 return; 574 } 575 memcpy (&hdr, (char *)ip, 4); 576 switch (IP_V(&hdr)) { 577 case 4: 578 ip_print (bp, length); 579 return; 580 #ifdef INET6 581 case 6: 582 ip6_print (bp, length); 583 return; 584 #endif 585 default: 586 (void)printf("unknown ip %d", IP_V(&hdr)); 587 return; 588 } 589 } 590