1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 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 * Support for splitting captures into multiple files with a maximum 22 * file size: 23 * 24 * Copyright (c) 2001 25 * Seth Webster <swebster@sst.ll.mit.edu> 26 */ 27 28 #include <config.h> 29 30 #include <stdlib.h> 31 #include <string.h> 32 #include <setjmp.h> 33 34 #include "netdissect-stdinc.h" 35 36 #include "netdissect.h" 37 #include "addrtoname.h" 38 #include "print.h" 39 #include "netdissect-alloc.h" 40 41 #include "pcap-missing.h" 42 43 struct printer { 44 if_printer f; 45 int type; 46 }; 47 48 static const struct printer printers[] = { 49 #ifdef DLT_APPLE_IP_OVER_IEEE1394 50 { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, 51 #endif 52 { arcnet_if_print, DLT_ARCNET }, 53 #ifdef DLT_ARCNET_LINUX 54 { arcnet_linux_if_print, DLT_ARCNET_LINUX }, 55 #endif 56 { atm_if_print, DLT_ATM_RFC1483 }, 57 #ifdef DLT_DSA_TAG_BRCM 58 { brcm_tag_if_print, DLT_DSA_TAG_BRCM }, 59 #endif 60 #ifdef DLT_DSA_TAG_BRCM_PREPEND 61 { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND }, 62 #endif 63 #ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR 64 { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, 65 #endif 66 #ifdef DLT_C_HDLC 67 { chdlc_if_print, DLT_C_HDLC }, 68 #endif 69 #ifdef DLT_HDLC 70 { chdlc_if_print, DLT_HDLC }, 71 #endif 72 #ifdef DLT_ATM_CLIP 73 { cip_if_print, DLT_ATM_CLIP }, 74 #endif 75 #ifdef DLT_CIP 76 { cip_if_print, DLT_CIP }, 77 #endif 78 #ifdef DLT_DSA_TAG_DSA 79 { dsa_if_print, DLT_DSA_TAG_DSA }, 80 #endif 81 #ifdef DLT_DSA_TAG_EDSA 82 { edsa_if_print, DLT_DSA_TAG_EDSA }, 83 #endif 84 #ifdef DLT_ENC 85 { enc_if_print, DLT_ENC }, 86 #endif 87 { ether_if_print, DLT_EN10MB }, 88 { fddi_if_print, DLT_FDDI }, 89 #ifdef DLT_FR 90 { fr_if_print, DLT_FR }, 91 #endif 92 #ifdef DLT_FRELAY 93 { fr_if_print, DLT_FRELAY }, 94 #endif 95 #ifdef DLT_IEEE802_11 96 { ieee802_11_if_print, DLT_IEEE802_11}, 97 #endif 98 #ifdef DLT_IEEE802_11_RADIO_AVS 99 { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, 100 #endif 101 #ifdef DLT_IEEE802_11_RADIO 102 { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, 103 #endif 104 #ifdef DLT_IEEE802_15_4 105 { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, 106 #endif 107 #ifdef DLT_IEEE802_15_4_NOFCS 108 { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, 109 #endif 110 #ifdef DLT_IEEE802_15_4_TAP 111 { ieee802_15_4_tap_if_print, DLT_IEEE802_15_4_TAP }, 112 #endif 113 #ifdef DLT_IP_OVER_FC 114 { ipfc_if_print, DLT_IP_OVER_FC }, 115 #endif 116 #ifdef DLT_IPNET 117 { ipnet_if_print, DLT_IPNET }, 118 #endif 119 #ifdef DLT_IPOIB 120 { ipoib_if_print, DLT_IPOIB }, 121 #endif 122 #ifdef DLT_JUNIPER_ATM1 123 { juniper_atm1_if_print, DLT_JUNIPER_ATM1 }, 124 #endif 125 #ifdef DLT_JUNIPER_ATM2 126 { juniper_atm2_if_print, DLT_JUNIPER_ATM2 }, 127 #endif 128 #ifdef DLT_JUNIPER_CHDLC 129 { juniper_chdlc_if_print, DLT_JUNIPER_CHDLC }, 130 #endif 131 #ifdef DLT_JUNIPER_ES 132 { juniper_es_if_print, DLT_JUNIPER_ES }, 133 #endif 134 #ifdef DLT_JUNIPER_ETHER 135 { juniper_ether_if_print, DLT_JUNIPER_ETHER }, 136 #endif 137 #ifdef DLT_JUNIPER_FRELAY 138 { juniper_frelay_if_print, DLT_JUNIPER_FRELAY }, 139 #endif 140 #ifdef DLT_JUNIPER_GGSN 141 { juniper_ggsn_if_print, DLT_JUNIPER_GGSN }, 142 #endif 143 #ifdef DLT_JUNIPER_MFR 144 { juniper_mfr_if_print, DLT_JUNIPER_MFR }, 145 #endif 146 #ifdef DLT_JUNIPER_MLFR 147 { juniper_mlfr_if_print, DLT_JUNIPER_MLFR }, 148 #endif 149 #ifdef DLT_JUNIPER_MLPPP 150 { juniper_mlppp_if_print, DLT_JUNIPER_MLPPP }, 151 #endif 152 #ifdef DLT_JUNIPER_MONITOR 153 { juniper_monitor_if_print, DLT_JUNIPER_MONITOR }, 154 #endif 155 #ifdef DLT_JUNIPER_PPP 156 { juniper_ppp_if_print, DLT_JUNIPER_PPP }, 157 #endif 158 #ifdef DLT_JUNIPER_PPPOE_ATM 159 { juniper_pppoe_atm_if_print, DLT_JUNIPER_PPPOE_ATM }, 160 #endif 161 #ifdef DLT_JUNIPER_PPPOE 162 { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE }, 163 #endif 164 #ifdef DLT_JUNIPER_SERVICES 165 { juniper_services_if_print, DLT_JUNIPER_SERVICES }, 166 #endif 167 #ifdef DLT_LTALK 168 { ltalk_if_print, DLT_LTALK }, 169 #endif 170 #ifdef DLT_MFR 171 { mfr_if_print, DLT_MFR }, 172 #endif 173 #ifdef DLT_NETANALYZER 174 { netanalyzer_if_print, DLT_NETANALYZER }, 175 #endif 176 #ifdef DLT_NETANALYZER_TRANSPARENT 177 { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, 178 #endif 179 #ifdef DLT_NFLOG 180 { nflog_if_print, DLT_NFLOG}, 181 #endif 182 { null_if_print, DLT_NULL }, 183 #ifdef DLT_LOOP 184 { null_if_print, DLT_LOOP }, 185 #endif 186 #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) 187 { pflog_if_print, DLT_PFLOG }, 188 #endif 189 #if defined(DLT_PFSYNC) && defined(HAVE_NET_PFVAR_H) 190 { pfsync_if_print, DLT_PFSYNC}, 191 #endif 192 #ifdef DLT_PKTAP 193 { pktap_if_print, DLT_PKTAP }, 194 #endif 195 #ifdef DLT_PPI 196 { ppi_if_print, DLT_PPI }, 197 #endif 198 #ifdef DLT_PPP_BSDOS 199 { ppp_bsdos_if_print, DLT_PPP_BSDOS }, 200 #endif 201 #ifdef DLT_PPP_SERIAL 202 { ppp_hdlc_if_print, DLT_PPP_SERIAL }, 203 #endif 204 { ppp_if_print, DLT_PPP }, 205 #ifdef DLT_PPP_PPPD 206 { ppp_if_print, DLT_PPP_PPPD }, 207 #endif 208 #ifdef DLT_PPP_ETHER 209 { pppoe_if_print, DLT_PPP_ETHER }, 210 #endif 211 #ifdef DLT_PRISM_HEADER 212 { prism_if_print, DLT_PRISM_HEADER }, 213 #endif 214 { raw_if_print, DLT_RAW }, 215 #ifdef DLT_IPV4 216 { raw_if_print, DLT_IPV4 }, 217 #endif 218 #ifdef DLT_IPV6 219 { raw_if_print, DLT_IPV6 }, 220 #endif 221 #ifdef DLT_SLIP_BSDOS 222 { sl_bsdos_if_print, DLT_SLIP_BSDOS }, 223 #endif 224 { sl_if_print, DLT_SLIP }, 225 #ifdef DLT_LINUX_SLL 226 { sll_if_print, DLT_LINUX_SLL }, 227 #endif 228 #ifdef DLT_LINUX_SLL2 229 { sll2_if_print, DLT_LINUX_SLL2 }, 230 #endif 231 #ifdef DLT_SUNATM 232 { sunatm_if_print, DLT_SUNATM }, 233 #endif 234 #ifdef DLT_SYMANTEC_FIREWALL 235 { symantec_if_print, DLT_SYMANTEC_FIREWALL }, 236 #endif 237 { token_if_print, DLT_IEEE802 }, 238 #ifdef DLT_USB_LINUX 239 { usb_linux_48_byte_if_print, DLT_USB_LINUX}, 240 #endif /* DLT_USB_LINUX */ 241 #ifdef DLT_USB_LINUX_MMAPPED 242 { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED}, 243 #endif /* DLT_USB_LINUX_MMAPPED */ 244 #ifdef DLT_VSOCK 245 { vsock_if_print, DLT_VSOCK }, 246 #endif 247 { NULL, 0 }, 248 }; 249 250 static void ndo_default_print(netdissect_options *ndo, const u_char *bp, 251 u_int length); 252 253 static void NORETURN ndo_error(netdissect_options *ndo, 254 status_exit_codes_t status, 255 FORMAT_STRING(const char *fmt), ...) 256 PRINTFLIKE(3, 4); 257 static void ndo_warning(netdissect_options *ndo, 258 FORMAT_STRING(const char *fmt), ...) 259 PRINTFLIKE(2, 3); 260 261 static int ndo_printf(netdissect_options *ndo, 262 FORMAT_STRING(const char *fmt), ...) 263 PRINTFLIKE(2, 3); 264 265 void 266 init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask) 267 { 268 init_addrtoname(ndo, localnet, mask); 269 } 270 271 if_printer 272 lookup_printer(int type) 273 { 274 const struct printer *p; 275 276 for (p = printers; p->f; ++p) 277 if (type == p->type) 278 return p->f; 279 280 #if defined(DLT_USER2) && defined(DLT_PKTAP) 281 /* 282 * Apple incorrectly chose to use DLT_USER2 for their PKTAP 283 * header. 284 * 285 * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- 286 * based OSes or the same value as LINKTYPE_PKTAP as it is on 287 * other OSes, to LINKTYPE_PKTAP, so files written with 288 * this version of libpcap for a DLT_PKTAP capture have a link- 289 * layer header type of LINKTYPE_PKTAP. 290 * 291 * However, files written on OS X Mavericks for a DLT_PKTAP 292 * capture have a link-layer header type of LINKTYPE_USER2. 293 * If we don't have a printer for DLT_USER2, and type is 294 * DLT_USER2, we look up the printer for DLT_PKTAP and use 295 * that. 296 */ 297 if (type == DLT_USER2) { 298 for (p = printers; p->f; ++p) 299 if (DLT_PKTAP == p->type) 300 return p->f; 301 } 302 #endif 303 304 return NULL; 305 /* NOTREACHED */ 306 } 307 308 int 309 has_printer(int type) 310 { 311 return (lookup_printer(type) != NULL); 312 } 313 314 if_printer 315 get_if_printer(int type) 316 { 317 if_printer printer; 318 319 printer = lookup_printer(type); 320 if (printer == NULL) 321 printer = unsupported_if_print; 322 return printer; 323 } 324 325 #ifdef ENABLE_INSTRUMENT_FUNCTIONS 326 extern int profile_func_level; 327 static int pretty_print_packet_level = -1; 328 #endif 329 330 void 331 pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, 332 const u_char *sp, u_int packets_captured) 333 { 334 u_int hdrlen = 0; 335 int invalid_header = 0; 336 337 #ifdef ENABLE_INSTRUMENT_FUNCTIONS 338 if (pretty_print_packet_level == -1) 339 pretty_print_packet_level = profile_func_level; 340 #endif 341 342 if (ndo->ndo_packet_number) 343 ND_PRINT("%5u ", packets_captured); 344 345 /* Sanity checks on packet length / capture length */ 346 if (h->caplen == 0) { 347 invalid_header = 1; 348 ND_PRINT("[Invalid header: caplen==0"); 349 } 350 if (h->len == 0) { 351 if (!invalid_header) { 352 invalid_header = 1; 353 ND_PRINT("[Invalid header:"); 354 } else 355 ND_PRINT(","); 356 ND_PRINT(" len==0"); 357 } else if (h->len < h->caplen) { 358 if (!invalid_header) { 359 invalid_header = 1; 360 ND_PRINT("[Invalid header:"); 361 } else 362 ND_PRINT(","); 363 ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen); 364 } 365 if (h->caplen > MAXIMUM_SNAPLEN) { 366 if (!invalid_header) { 367 invalid_header = 1; 368 ND_PRINT("[Invalid header:"); 369 } else 370 ND_PRINT(","); 371 ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN); 372 } 373 if (h->len > MAXIMUM_SNAPLEN) { 374 if (!invalid_header) { 375 invalid_header = 1; 376 ND_PRINT("[Invalid header:"); 377 } else 378 ND_PRINT(","); 379 ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN); 380 } 381 if (invalid_header) { 382 ND_PRINT("]\n"); 383 return; 384 } 385 386 /* 387 * At this point: 388 * capture length != 0, 389 * packet length != 0, 390 * capture length <= MAXIMUM_SNAPLEN, 391 * packet length <= MAXIMUM_SNAPLEN, 392 * packet length >= capture length. 393 * 394 * Currently, there is no D-Bus printer, thus no need for 395 * bigger lengths. 396 */ 397 398 /* 399 * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as 400 * struct bpf_timeval, not struct timeval. The former comes from 401 * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of 402 * the types used in struct timeval. 403 */ 404 struct timeval tvbuf; 405 tvbuf.tv_sec = h->ts.tv_sec; 406 tvbuf.tv_usec = h->ts.tv_usec; 407 ts_print(ndo, &tvbuf); 408 409 /* 410 * Printers must check that they're not walking off the end of 411 * the packet. 412 * Rather than pass it all the way down, we set this member 413 * of the netdissect_options structure. 414 */ 415 ndo->ndo_snapend = sp + h->caplen; 416 ndo->ndo_packetp = sp; 417 418 ndo->ndo_protocol = ""; 419 ndo->ndo_ll_hdr_len = 0; 420 switch (setjmp(ndo->ndo_early_end)) { 421 case 0: 422 /* Print the packet. */ 423 (ndo->ndo_if_printer)(ndo, h, sp); 424 break; 425 case ND_TRUNCATED: 426 /* A printer quit because the packet was truncated; report it */ 427 nd_print_trunc(ndo); 428 /* Print the full packet */ 429 ndo->ndo_ll_hdr_len = 0; 430 #ifdef ENABLE_INSTRUMENT_FUNCTIONS 431 /* truncation => reassignment */ 432 profile_func_level = pretty_print_packet_level; 433 #endif 434 break; 435 } 436 hdrlen = ndo->ndo_ll_hdr_len; 437 438 /* 439 * Empty the stack of packet information, freeing all pushed buffers; 440 * if we got here by a printer quitting, we need to release anything 441 * that didn't get released because we longjmped out of the code 442 * before it popped the packet information. 443 */ 444 nd_pop_all_packet_info(ndo); 445 446 /* 447 * Restore the originals snapend and packetp, as a printer 448 * might have changed them. 449 * 450 * XXX - nd_pop_all_packet_info() should have restored the 451 * original values, but, just in case.... 452 */ 453 ndo->ndo_snapend = sp + h->caplen; 454 ndo->ndo_packetp = sp; 455 if (ndo->ndo_Xflag) { 456 /* 457 * Print the raw packet data in hex and ASCII. 458 */ 459 if (ndo->ndo_Xflag > 1) { 460 /* 461 * Include the link-layer header. 462 */ 463 hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); 464 } else { 465 /* 466 * Don't include the link-layer header - and if 467 * we have nothing past the link-layer header, 468 * print nothing. 469 */ 470 if (h->caplen > hdrlen) 471 hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, 472 h->caplen - hdrlen); 473 } 474 } else if (ndo->ndo_xflag) { 475 /* 476 * Print the raw packet data in hex. 477 */ 478 if (ndo->ndo_xflag > 1) { 479 /* 480 * Include the link-layer header. 481 */ 482 hex_print(ndo, "\n\t", sp, h->caplen); 483 } else { 484 /* 485 * Don't include the link-layer header - and if 486 * we have nothing past the link-layer header, 487 * print nothing. 488 */ 489 if (h->caplen > hdrlen) 490 hex_print(ndo, "\n\t", sp + hdrlen, 491 h->caplen - hdrlen); 492 } 493 } else if (ndo->ndo_Aflag) { 494 /* 495 * Print the raw packet data in ASCII. 496 */ 497 if (ndo->ndo_Aflag > 1) { 498 /* 499 * Include the link-layer header. 500 */ 501 ascii_print(ndo, sp, h->caplen); 502 } else { 503 /* 504 * Don't include the link-layer header - and if 505 * we have nothing past the link-layer header, 506 * print nothing. 507 */ 508 if (h->caplen > hdrlen) 509 ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); 510 } 511 } 512 513 ND_PRINT("\n"); 514 nd_free_all(ndo); 515 } 516 517 /* 518 * By default, print the specified data out in hex and ASCII. 519 */ 520 static void 521 ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) 522 { 523 hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ 524 } 525 526 /* VARARGS */ 527 static void 528 ndo_error(netdissect_options *ndo, status_exit_codes_t status, 529 const char *fmt, ...) 530 { 531 va_list ap; 532 533 if (ndo->program_name) 534 (void)fprintf(stderr, "%s: ", ndo->program_name); 535 va_start(ap, fmt); 536 (void)vfprintf(stderr, fmt, ap); 537 va_end(ap); 538 if (*fmt) { 539 fmt += strlen(fmt); 540 if (fmt[-1] != '\n') 541 (void)fputc('\n', stderr); 542 } 543 nd_cleanup(); 544 exit(status); 545 /* NOTREACHED */ 546 } 547 548 /* VARARGS */ 549 static void 550 ndo_warning(netdissect_options *ndo, const char *fmt, ...) 551 { 552 va_list ap; 553 554 if (ndo->program_name) 555 (void)fprintf(stderr, "%s: ", ndo->program_name); 556 (void)fprintf(stderr, "WARNING: "); 557 va_start(ap, fmt); 558 (void)vfprintf(stderr, fmt, ap); 559 va_end(ap); 560 if (*fmt) { 561 fmt += strlen(fmt); 562 if (fmt[-1] != '\n') 563 (void)fputc('\n', stderr); 564 } 565 } 566 567 static int 568 ndo_printf(netdissect_options *ndo, const char *fmt, ...) 569 { 570 va_list args; 571 int ret; 572 573 va_start(args, fmt); 574 ret = vfprintf(stdout, fmt, args); 575 va_end(args); 576 577 if (ret < 0) 578 ndo_error(ndo, S_ERR_ND_WRITE_FILE, 579 "Unable to write output: %s", pcap_strerror(errno)); 580 return (ret); 581 } 582 583 void 584 ndo_set_function_pointers(netdissect_options *ndo) 585 { 586 ndo->ndo_default_print=ndo_default_print; 587 ndo->ndo_printf=ndo_printf; 588 ndo->ndo_error=ndo_error; 589 ndo->ndo_warning=ndo_warning; 590 } 591