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 45 struct printer { 46 if_printer f; 47 int type; 48 }; 49 50 static 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 #ifdef DLT_PKTAP 192 { pktap_if_print, DLT_PKTAP }, 193 #endif 194 #ifdef DLT_PPI 195 { ppi_if_print, DLT_PPI }, 196 #endif 197 #ifdef DLT_PPP_BSDOS 198 { ppp_bsdos_if_print, DLT_PPP_BSDOS }, 199 #endif 200 #ifdef DLT_PPP_SERIAL 201 { ppp_hdlc_if_print, DLT_PPP_SERIAL }, 202 #endif 203 { ppp_if_print, DLT_PPP }, 204 #ifdef DLT_PPP_PPPD 205 { ppp_if_print, DLT_PPP_PPPD }, 206 #endif 207 #ifdef DLT_PPP_ETHER 208 { pppoe_if_print, DLT_PPP_ETHER }, 209 #endif 210 #ifdef DLT_PRISM_HEADER 211 { prism_if_print, DLT_PRISM_HEADER }, 212 #endif 213 { raw_if_print, DLT_RAW }, 214 #ifdef DLT_IPV4 215 { raw_if_print, DLT_IPV4 }, 216 #endif 217 #ifdef DLT_IPV6 218 { raw_if_print, DLT_IPV6 }, 219 #endif 220 #ifdef DLT_SLIP_BSDOS 221 { sl_bsdos_if_print, DLT_SLIP_BSDOS }, 222 #endif 223 { sl_if_print, DLT_SLIP }, 224 #ifdef DLT_LINUX_SLL 225 { sll_if_print, DLT_LINUX_SLL }, 226 #endif 227 #ifdef DLT_LINUX_SLL2 228 { sll2_if_print, DLT_LINUX_SLL2 }, 229 #endif 230 #ifdef DLT_SUNATM 231 { sunatm_if_print, DLT_SUNATM }, 232 #endif 233 #ifdef DLT_SYMANTEC_FIREWALL 234 { symantec_if_print, DLT_SYMANTEC_FIREWALL }, 235 #endif 236 { token_if_print, DLT_IEEE802 }, 237 #ifdef DLT_USB_LINUX 238 { usb_linux_48_byte_if_print, DLT_USB_LINUX}, 239 #endif /* DLT_USB_LINUX */ 240 #ifdef DLT_USB_LINUX_MMAPPED 241 { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED}, 242 #endif /* DLT_USB_LINUX_MMAPPED */ 243 #ifdef DLT_VSOCK 244 { vsock_if_print, DLT_VSOCK }, 245 #endif 246 { NULL, 0 }, 247 }; 248 249 static void ndo_default_print(netdissect_options *ndo, const u_char *bp, 250 u_int length); 251 252 static void NORETURN ndo_error(netdissect_options *ndo, 253 status_exit_codes_t status, 254 FORMAT_STRING(const char *fmt), ...) 255 PRINTFLIKE(3, 4); 256 static void ndo_warning(netdissect_options *ndo, 257 FORMAT_STRING(const char *fmt), ...) 258 PRINTFLIKE(2, 3); 259 260 static int ndo_printf(netdissect_options *ndo, 261 FORMAT_STRING(const char *fmt), ...) 262 PRINTFLIKE(2, 3); 263 264 void 265 init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask) 266 { 267 268 init_addrtoname(ndo, localnet, mask); 269 init_checksum(); 270 } 271 272 if_printer 273 lookup_printer(int type) 274 { 275 const struct printer *p; 276 277 for (p = printers; p->f; ++p) 278 if (type == p->type) 279 return p->f; 280 281 #if defined(DLT_USER2) && defined(DLT_PKTAP) 282 /* 283 * Apple incorrectly chose to use DLT_USER2 for their PKTAP 284 * header. 285 * 286 * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- 287 * based OSes or the same value as LINKTYPE_PKTAP as it is on 288 * other OSes, to LINKTYPE_PKTAP, so files written with 289 * this version of libpcap for a DLT_PKTAP capture have a link- 290 * layer header type of LINKTYPE_PKTAP. 291 * 292 * However, files written on OS X Mavericks for a DLT_PKTAP 293 * capture have a link-layer header type of LINKTYPE_USER2. 294 * If we don't have a printer for DLT_USER2, and type is 295 * DLT_USER2, we look up the printer for DLT_PKTAP and use 296 * that. 297 */ 298 if (type == DLT_USER2) { 299 for (p = printers; p->f; ++p) 300 if (DLT_PKTAP == p->type) 301 return p->f; 302 } 303 #endif 304 305 return NULL; 306 /* NOTREACHED */ 307 } 308 309 int 310 has_printer(int type) 311 { 312 return (lookup_printer(type) != NULL); 313 } 314 315 if_printer 316 get_if_printer(int type) 317 { 318 if_printer printer; 319 320 printer = lookup_printer(type); 321 if (printer == NULL) 322 printer = unsupported_if_print; 323 return printer; 324 } 325 326 void 327 pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, 328 const u_char *sp, u_int packets_captured) 329 { 330 u_int hdrlen = 0; 331 int invalid_header = 0; 332 333 if (ndo->ndo_packet_number) 334 ND_PRINT("%5u ", packets_captured); 335 336 /* Sanity checks on packet length / capture length */ 337 if (h->caplen == 0) { 338 invalid_header = 1; 339 ND_PRINT("[Invalid header: caplen==0"); 340 } 341 if (h->len == 0) { 342 if (!invalid_header) { 343 invalid_header = 1; 344 ND_PRINT("[Invalid header:"); 345 } else 346 ND_PRINT(","); 347 ND_PRINT(" len==0"); 348 } else if (h->len < h->caplen) { 349 if (!invalid_header) { 350 invalid_header = 1; 351 ND_PRINT("[Invalid header:"); 352 } else 353 ND_PRINT(","); 354 ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen); 355 } 356 if (h->caplen > MAXIMUM_SNAPLEN) { 357 if (!invalid_header) { 358 invalid_header = 1; 359 ND_PRINT("[Invalid header:"); 360 } else 361 ND_PRINT(","); 362 ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN); 363 } 364 if (h->len > MAXIMUM_SNAPLEN) { 365 if (!invalid_header) { 366 invalid_header = 1; 367 ND_PRINT("[Invalid header:"); 368 } else 369 ND_PRINT(","); 370 ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN); 371 } 372 if (invalid_header) { 373 ND_PRINT("]\n"); 374 return; 375 } 376 377 /* 378 * At this point: 379 * capture length != 0, 380 * packet length != 0, 381 * capture length <= MAXIMUM_SNAPLEN, 382 * packet length <= MAXIMUM_SNAPLEN, 383 * packet length >= capture length. 384 * 385 * Currently, there is no D-Bus printer, thus no need for 386 * bigger lengths. 387 */ 388 389 /* 390 * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as 391 * struct bpf_timeval, not struct timeval. The former comes from 392 * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of 393 * the types used in struct timeval. 394 */ 395 struct timeval tvbuf; 396 tvbuf.tv_sec = h->ts.tv_sec; 397 tvbuf.tv_usec = h->ts.tv_usec; 398 ts_print(ndo, &tvbuf); 399 400 /* 401 * Printers must check that they're not walking off the end of 402 * the packet. 403 * Rather than pass it all the way down, we set this member 404 * of the netdissect_options structure. 405 */ 406 ndo->ndo_snapend = sp + h->caplen; 407 ndo->ndo_packetp = sp; 408 409 ndo->ndo_protocol = ""; 410 ndo->ndo_ll_hdr_len = 0; 411 switch (setjmp(ndo->ndo_early_end)) { 412 case 0: 413 /* Print the packet. */ 414 (ndo->ndo_if_printer)(ndo, h, sp); 415 break; 416 case ND_TRUNCATED: 417 /* A printer quit because the packet was truncated; report it */ 418 nd_print_trunc(ndo); 419 /* Print the full packet */ 420 ndo->ndo_ll_hdr_len = 0; 421 break; 422 } 423 hdrlen = ndo->ndo_ll_hdr_len; 424 425 /* 426 * Empty the stack of packet information, freeing all pushed buffers; 427 * if we got here by a printer quitting, we need to release anything 428 * that didn't get released because we longjmped out of the code 429 * before it popped the packet information. 430 */ 431 nd_pop_all_packet_info(ndo); 432 433 /* 434 * Restore the original snapend, as a printer might have 435 * changed it. 436 */ 437 ndo->ndo_snapend = sp + h->caplen; 438 if (ndo->ndo_Xflag) { 439 /* 440 * Print the raw packet data in hex and ASCII. 441 */ 442 if (ndo->ndo_Xflag > 1) { 443 /* 444 * Include the link-layer header. 445 */ 446 hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); 447 } else { 448 /* 449 * Don't include the link-layer header - and if 450 * we have nothing past the link-layer header, 451 * print nothing. 452 */ 453 if (h->caplen > hdrlen) 454 hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, 455 h->caplen - hdrlen); 456 } 457 } else if (ndo->ndo_xflag) { 458 /* 459 * Print the raw packet data in hex. 460 */ 461 if (ndo->ndo_xflag > 1) { 462 /* 463 * Include the link-layer header. 464 */ 465 hex_print(ndo, "\n\t", sp, h->caplen); 466 } else { 467 /* 468 * Don't include the link-layer header - and if 469 * we have nothing past the link-layer header, 470 * print nothing. 471 */ 472 if (h->caplen > hdrlen) 473 hex_print(ndo, "\n\t", sp + hdrlen, 474 h->caplen - hdrlen); 475 } 476 } else if (ndo->ndo_Aflag) { 477 /* 478 * Print the raw packet data in ASCII. 479 */ 480 if (ndo->ndo_Aflag > 1) { 481 /* 482 * Include the link-layer header. 483 */ 484 ascii_print(ndo, sp, h->caplen); 485 } else { 486 /* 487 * Don't include the link-layer header - and if 488 * we have nothing past the link-layer header, 489 * print nothing. 490 */ 491 if (h->caplen > hdrlen) 492 ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); 493 } 494 } 495 496 ND_PRINT("\n"); 497 nd_free_all(ndo); 498 } 499 500 /* 501 * By default, print the specified data out in hex and ASCII. 502 */ 503 static void 504 ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) 505 { 506 hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ 507 } 508 509 /* VARARGS */ 510 static void 511 ndo_error(netdissect_options *ndo, status_exit_codes_t status, 512 const char *fmt, ...) 513 { 514 va_list ap; 515 516 if (ndo->program_name) 517 (void)fprintf(stderr, "%s: ", ndo->program_name); 518 va_start(ap, fmt); 519 (void)vfprintf(stderr, fmt, ap); 520 va_end(ap); 521 if (*fmt) { 522 fmt += strlen(fmt); 523 if (fmt[-1] != '\n') 524 (void)fputc('\n', stderr); 525 } 526 nd_cleanup(); 527 exit(status); 528 /* NOTREACHED */ 529 } 530 531 /* VARARGS */ 532 static void 533 ndo_warning(netdissect_options *ndo, const char *fmt, ...) 534 { 535 va_list ap; 536 537 if (ndo->program_name) 538 (void)fprintf(stderr, "%s: ", ndo->program_name); 539 (void)fprintf(stderr, "WARNING: "); 540 va_start(ap, fmt); 541 (void)vfprintf(stderr, fmt, ap); 542 va_end(ap); 543 if (*fmt) { 544 fmt += strlen(fmt); 545 if (fmt[-1] != '\n') 546 (void)fputc('\n', stderr); 547 } 548 } 549 550 static int 551 ndo_printf(netdissect_options *ndo, const char *fmt, ...) 552 { 553 va_list args; 554 int ret; 555 556 va_start(args, fmt); 557 ret = vfprintf(stdout, fmt, args); 558 va_end(args); 559 560 if (ret < 0) 561 ndo_error(ndo, S_ERR_ND_WRITE_FILE, 562 "Unable to write output: %s", pcap_strerror(errno)); 563 return (ret); 564 } 565 566 void 567 ndo_set_function_pointers(netdissect_options *ndo) 568 { 569 ndo->ndo_default_print=ndo_default_print; 570 ndo->ndo_printf=ndo_printf; 571 ndo->ndo_error=ndo_error; 572 ndo->ndo_warning=ndo_warning; 573 } 574