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