13340d773SGleb Smirnoff /* 23340d773SGleb Smirnoff * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 33340d773SGleb Smirnoff * The Regents of the University of California. All rights reserved. 43340d773SGleb Smirnoff * 53340d773SGleb Smirnoff * Redistribution and use in source and binary forms, with or without 63340d773SGleb Smirnoff * modification, are permitted provided that: (1) source code distributions 73340d773SGleb Smirnoff * retain the above copyright notice and this paragraph in its entirety, (2) 83340d773SGleb Smirnoff * distributions including binary code include the above copyright notice and 93340d773SGleb Smirnoff * this paragraph in its entirety in the documentation or other materials 103340d773SGleb Smirnoff * provided with the distribution, and (3) all advertising materials mentioning 113340d773SGleb Smirnoff * features or use of this software display the following acknowledgement: 123340d773SGleb Smirnoff * ``This product includes software developed by the University of California, 133340d773SGleb Smirnoff * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 143340d773SGleb Smirnoff * the University nor the names of its contributors may be used to endorse 153340d773SGleb Smirnoff * or promote products derived from this software without specific prior 163340d773SGleb Smirnoff * written permission. 173340d773SGleb Smirnoff * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 183340d773SGleb Smirnoff * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 193340d773SGleb Smirnoff * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 203340d773SGleb Smirnoff * 213340d773SGleb Smirnoff * Support for splitting captures into multiple files with a maximum 223340d773SGleb Smirnoff * file size: 233340d773SGleb Smirnoff * 243340d773SGleb Smirnoff * Copyright (c) 2001 253340d773SGleb Smirnoff * Seth Webster <swebster@sst.ll.mit.edu> 263340d773SGleb Smirnoff */ 273340d773SGleb Smirnoff 283340d773SGleb Smirnoff #ifdef HAVE_CONFIG_H 29ee67461eSJoseph Mingrone #include <config.h> 303340d773SGleb Smirnoff #endif 313340d773SGleb Smirnoff 323340d773SGleb Smirnoff #include <stdlib.h> 333340d773SGleb Smirnoff #include <string.h> 34ee67461eSJoseph Mingrone #include <setjmp.h> 353340d773SGleb Smirnoff 36ee67461eSJoseph Mingrone #include "netdissect-stdinc.h" 373340d773SGleb Smirnoff 383340d773SGleb Smirnoff #include "netdissect.h" 393340d773SGleb Smirnoff #include "addrtoname.h" 403340d773SGleb Smirnoff #include "print.h" 41ee67461eSJoseph Mingrone #include "netdissect-alloc.h" 42ee67461eSJoseph Mingrone 43ee67461eSJoseph Mingrone #include "pcap-missing.h" 443340d773SGleb Smirnoff 453340d773SGleb Smirnoff struct printer { 463340d773SGleb Smirnoff if_printer f; 473340d773SGleb Smirnoff int type; 483340d773SGleb Smirnoff }; 493340d773SGleb Smirnoff 503340d773SGleb Smirnoff static const struct printer printers[] = { 51ee67461eSJoseph Mingrone #ifdef DLT_APPLE_IP_OVER_IEEE1394 52ee67461eSJoseph Mingrone { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, 53ee67461eSJoseph Mingrone #endif 54ee67461eSJoseph Mingrone { arcnet_if_print, DLT_ARCNET }, 55ee67461eSJoseph Mingrone #ifdef DLT_ARCNET_LINUX 56ee67461eSJoseph Mingrone { arcnet_linux_if_print, DLT_ARCNET_LINUX }, 57ee67461eSJoseph Mingrone #endif 58ee67461eSJoseph Mingrone { atm_if_print, DLT_ATM_RFC1483 }, 59ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_BRCM 60ee67461eSJoseph Mingrone { brcm_tag_if_print, DLT_DSA_TAG_BRCM }, 61ee67461eSJoseph Mingrone #endif 62ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_BRCM_PREPEND 63ee67461eSJoseph Mingrone { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND }, 64ee67461eSJoseph Mingrone #endif 65ee67461eSJoseph Mingrone #ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR 66ee67461eSJoseph Mingrone { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, 67ee67461eSJoseph Mingrone #endif 68ee67461eSJoseph Mingrone #ifdef DLT_C_HDLC 69ee67461eSJoseph Mingrone { chdlc_if_print, DLT_C_HDLC }, 70ee67461eSJoseph Mingrone #endif 71ee67461eSJoseph Mingrone #ifdef DLT_HDLC 72ee67461eSJoseph Mingrone { chdlc_if_print, DLT_HDLC }, 73ee67461eSJoseph Mingrone #endif 74ee67461eSJoseph Mingrone #ifdef DLT_ATM_CLIP 75ee67461eSJoseph Mingrone { cip_if_print, DLT_ATM_CLIP }, 76ee67461eSJoseph Mingrone #endif 77ee67461eSJoseph Mingrone #ifdef DLT_CIP 78ee67461eSJoseph Mingrone { cip_if_print, DLT_CIP }, 79ee67461eSJoseph Mingrone #endif 80ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_DSA 81ee67461eSJoseph Mingrone { dsa_if_print, DLT_DSA_TAG_DSA }, 82ee67461eSJoseph Mingrone #endif 83ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_EDSA 84ee67461eSJoseph Mingrone { edsa_if_print, DLT_DSA_TAG_EDSA }, 85ee67461eSJoseph Mingrone #endif 86ee67461eSJoseph Mingrone #ifdef DLT_ENC 87ee67461eSJoseph Mingrone { enc_if_print, DLT_ENC }, 88ee67461eSJoseph Mingrone #endif 893340d773SGleb Smirnoff { ether_if_print, DLT_EN10MB }, 90ee67461eSJoseph Mingrone { fddi_if_print, DLT_FDDI }, 91ee67461eSJoseph Mingrone #ifdef DLT_FR 92ee67461eSJoseph Mingrone { fr_if_print, DLT_FR }, 93ee67461eSJoseph Mingrone #endif 94ee67461eSJoseph Mingrone #ifdef DLT_FRELAY 95ee67461eSJoseph Mingrone { fr_if_print, DLT_FRELAY }, 96ee67461eSJoseph Mingrone #endif 97ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_11 98ee67461eSJoseph Mingrone { ieee802_11_if_print, DLT_IEEE802_11}, 99ee67461eSJoseph Mingrone #endif 100ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_11_RADIO_AVS 101ee67461eSJoseph Mingrone { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, 102ee67461eSJoseph Mingrone #endif 103ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_11_RADIO 104ee67461eSJoseph Mingrone { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, 1053340d773SGleb Smirnoff #endif 1063340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4 1073340d773SGleb Smirnoff { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, 1083340d773SGleb Smirnoff #endif 1093340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4_NOFCS 1103340d773SGleb Smirnoff { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, 1113340d773SGleb Smirnoff #endif 112ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_15_4_TAP 113ee67461eSJoseph Mingrone { ieee802_15_4_tap_if_print, DLT_IEEE802_15_4_TAP }, 114ee67461eSJoseph Mingrone #endif 115ee67461eSJoseph Mingrone #ifdef DLT_IP_OVER_FC 116ee67461eSJoseph Mingrone { ipfc_if_print, DLT_IP_OVER_FC }, 117ee67461eSJoseph Mingrone #endif 118ee67461eSJoseph Mingrone #ifdef DLT_IPNET 119ee67461eSJoseph Mingrone { ipnet_if_print, DLT_IPNET }, 120ee67461eSJoseph Mingrone #endif 121ee67461eSJoseph Mingrone #ifdef DLT_IPOIB 122ee67461eSJoseph Mingrone { ipoib_if_print, DLT_IPOIB }, 123ee67461eSJoseph Mingrone #endif 124ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ATM1 125ee67461eSJoseph Mingrone { juniper_atm1_if_print, DLT_JUNIPER_ATM1 }, 126ee67461eSJoseph Mingrone #endif 127ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ATM2 128ee67461eSJoseph Mingrone { juniper_atm2_if_print, DLT_JUNIPER_ATM2 }, 129ee67461eSJoseph Mingrone #endif 130ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_CHDLC 131ee67461eSJoseph Mingrone { juniper_chdlc_if_print, DLT_JUNIPER_CHDLC }, 132ee67461eSJoseph Mingrone #endif 133ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ES 134ee67461eSJoseph Mingrone { juniper_es_if_print, DLT_JUNIPER_ES }, 135ee67461eSJoseph Mingrone #endif 136ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ETHER 137ee67461eSJoseph Mingrone { juniper_ether_if_print, DLT_JUNIPER_ETHER }, 138ee67461eSJoseph Mingrone #endif 139ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_FRELAY 140ee67461eSJoseph Mingrone { juniper_frelay_if_print, DLT_JUNIPER_FRELAY }, 141ee67461eSJoseph Mingrone #endif 142ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_GGSN 143ee67461eSJoseph Mingrone { juniper_ggsn_if_print, DLT_JUNIPER_GGSN }, 144ee67461eSJoseph Mingrone #endif 145ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MFR 146ee67461eSJoseph Mingrone { juniper_mfr_if_print, DLT_JUNIPER_MFR }, 147ee67461eSJoseph Mingrone #endif 148ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MLFR 149ee67461eSJoseph Mingrone { juniper_mlfr_if_print, DLT_JUNIPER_MLFR }, 150ee67461eSJoseph Mingrone #endif 151ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MLPPP 152ee67461eSJoseph Mingrone { juniper_mlppp_if_print, DLT_JUNIPER_MLPPP }, 153ee67461eSJoseph Mingrone #endif 154ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MONITOR 155ee67461eSJoseph Mingrone { juniper_monitor_if_print, DLT_JUNIPER_MONITOR }, 156ee67461eSJoseph Mingrone #endif 157ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_PPP 158ee67461eSJoseph Mingrone { juniper_ppp_if_print, DLT_JUNIPER_PPP }, 159ee67461eSJoseph Mingrone #endif 160ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_PPPOE_ATM 161ee67461eSJoseph Mingrone { juniper_pppoe_atm_if_print, DLT_JUNIPER_PPPOE_ATM }, 162ee67461eSJoseph Mingrone #endif 163ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_PPPOE 164ee67461eSJoseph Mingrone { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE }, 165ee67461eSJoseph Mingrone #endif 166ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_SERVICES 167ee67461eSJoseph Mingrone { juniper_services_if_print, DLT_JUNIPER_SERVICES }, 168ee67461eSJoseph Mingrone #endif 169ee67461eSJoseph Mingrone #ifdef DLT_LTALK 170ee67461eSJoseph Mingrone { ltalk_if_print, DLT_LTALK }, 171ee67461eSJoseph Mingrone #endif 172ee67461eSJoseph Mingrone #ifdef DLT_MFR 173ee67461eSJoseph Mingrone { mfr_if_print, DLT_MFR }, 1743340d773SGleb Smirnoff #endif 1753340d773SGleb Smirnoff #ifdef DLT_NETANALYZER 1763340d773SGleb Smirnoff { netanalyzer_if_print, DLT_NETANALYZER }, 1773340d773SGleb Smirnoff #endif 1783340d773SGleb Smirnoff #ifdef DLT_NETANALYZER_TRANSPARENT 1793340d773SGleb Smirnoff { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT }, 1803340d773SGleb Smirnoff #endif 181ee67461eSJoseph Mingrone #ifdef DLT_NFLOG 1823340d773SGleb Smirnoff { nflog_if_print, DLT_NFLOG}, 1833340d773SGleb Smirnoff #endif 1843340d773SGleb Smirnoff { null_if_print, DLT_NULL }, 1853340d773SGleb Smirnoff #ifdef DLT_LOOP 1863340d773SGleb Smirnoff { null_if_print, DLT_LOOP }, 1873340d773SGleb Smirnoff #endif 188171a7bbfSGleb Smirnoff #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H) 189ee67461eSJoseph Mingrone { pflog_if_print, DLT_PFLOG }, 1903340d773SGleb Smirnoff #endif 191*1ad8d2eeSJoseph Mingrone #if defined(DLT_PFSYNC) && defined(HAVE_NET_PFVAR_H) 192*1ad8d2eeSJoseph Mingrone { pfsync_if_print, DLT_PFSYNC}, 193*1ad8d2eeSJoseph Mingrone #endif 194ee67461eSJoseph Mingrone #ifdef DLT_PKTAP 195ee67461eSJoseph Mingrone { pktap_if_print, DLT_PKTAP }, 1963340d773SGleb Smirnoff #endif 197ee67461eSJoseph Mingrone #ifdef DLT_PPI 198ee67461eSJoseph Mingrone { ppi_if_print, DLT_PPI }, 1993340d773SGleb Smirnoff #endif 200ee67461eSJoseph Mingrone #ifdef DLT_PPP_BSDOS 201ee67461eSJoseph Mingrone { ppp_bsdos_if_print, DLT_PPP_BSDOS }, 202ee67461eSJoseph Mingrone #endif 203ee67461eSJoseph Mingrone #ifdef DLT_PPP_SERIAL 204ee67461eSJoseph Mingrone { ppp_hdlc_if_print, DLT_PPP_SERIAL }, 205ee67461eSJoseph Mingrone #endif 206ee67461eSJoseph Mingrone { ppp_if_print, DLT_PPP }, 207ee67461eSJoseph Mingrone #ifdef DLT_PPP_PPPD 208ee67461eSJoseph Mingrone { ppp_if_print, DLT_PPP_PPPD }, 209ee67461eSJoseph Mingrone #endif 210ee67461eSJoseph Mingrone #ifdef DLT_PPP_ETHER 211ee67461eSJoseph Mingrone { pppoe_if_print, DLT_PPP_ETHER }, 212ee67461eSJoseph Mingrone #endif 213ee67461eSJoseph Mingrone #ifdef DLT_PRISM_HEADER 214ee67461eSJoseph Mingrone { prism_if_print, DLT_PRISM_HEADER }, 2153340d773SGleb Smirnoff #endif 2163340d773SGleb Smirnoff { raw_if_print, DLT_RAW }, 2173340d773SGleb Smirnoff #ifdef DLT_IPV4 2183340d773SGleb Smirnoff { raw_if_print, DLT_IPV4 }, 2193340d773SGleb Smirnoff #endif 2203340d773SGleb Smirnoff #ifdef DLT_IPV6 2213340d773SGleb Smirnoff { raw_if_print, DLT_IPV6 }, 2223340d773SGleb Smirnoff #endif 2233340d773SGleb Smirnoff #ifdef DLT_SLIP_BSDOS 2243340d773SGleb Smirnoff { sl_bsdos_if_print, DLT_SLIP_BSDOS }, 2253340d773SGleb Smirnoff #endif 226ee67461eSJoseph Mingrone { sl_if_print, DLT_SLIP }, 227ee67461eSJoseph Mingrone #ifdef DLT_LINUX_SLL 228ee67461eSJoseph Mingrone { sll_if_print, DLT_LINUX_SLL }, 2293340d773SGleb Smirnoff #endif 230ee67461eSJoseph Mingrone #ifdef DLT_LINUX_SLL2 231ee67461eSJoseph Mingrone { sll2_if_print, DLT_LINUX_SLL2 }, 2323340d773SGleb Smirnoff #endif 233ee67461eSJoseph Mingrone #ifdef DLT_SUNATM 234ee67461eSJoseph Mingrone { sunatm_if_print, DLT_SUNATM }, 2353340d773SGleb Smirnoff #endif 236ee67461eSJoseph Mingrone #ifdef DLT_SYMANTEC_FIREWALL 237ee67461eSJoseph Mingrone { symantec_if_print, DLT_SYMANTEC_FIREWALL }, 2383340d773SGleb Smirnoff #endif 239ee67461eSJoseph Mingrone { token_if_print, DLT_IEEE802 }, 240ee67461eSJoseph Mingrone #ifdef DLT_USB_LINUX 241ee67461eSJoseph Mingrone { usb_linux_48_byte_if_print, DLT_USB_LINUX}, 242ee67461eSJoseph Mingrone #endif /* DLT_USB_LINUX */ 243ee67461eSJoseph Mingrone #ifdef DLT_USB_LINUX_MMAPPED 244ee67461eSJoseph Mingrone { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED}, 245ee67461eSJoseph Mingrone #endif /* DLT_USB_LINUX_MMAPPED */ 246ee67461eSJoseph Mingrone #ifdef DLT_VSOCK 247ee67461eSJoseph Mingrone { vsock_if_print, DLT_VSOCK }, 2483340d773SGleb Smirnoff #endif 2493340d773SGleb Smirnoff { NULL, 0 }, 2503340d773SGleb Smirnoff }; 2513340d773SGleb Smirnoff 2523340d773SGleb Smirnoff static void ndo_default_print(netdissect_options *ndo, const u_char *bp, 2533340d773SGleb Smirnoff u_int length); 2543340d773SGleb Smirnoff 255ee67461eSJoseph Mingrone static void NORETURN ndo_error(netdissect_options *ndo, 256ee67461eSJoseph Mingrone status_exit_codes_t status, 2570bff6a5aSEd Maste FORMAT_STRING(const char *fmt), ...) 258ee67461eSJoseph Mingrone PRINTFLIKE(3, 4); 2590bff6a5aSEd Maste static void ndo_warning(netdissect_options *ndo, 2600bff6a5aSEd Maste FORMAT_STRING(const char *fmt), ...) 2610bff6a5aSEd Maste PRINTFLIKE(2, 3); 2623340d773SGleb Smirnoff 2630bff6a5aSEd Maste static int ndo_printf(netdissect_options *ndo, 2640bff6a5aSEd Maste FORMAT_STRING(const char *fmt), ...) 2650bff6a5aSEd Maste PRINTFLIKE(2, 3); 2663340d773SGleb Smirnoff 2673340d773SGleb Smirnoff void 268ee67461eSJoseph Mingrone init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask) 2693340d773SGleb Smirnoff { 2703340d773SGleb Smirnoff 2713340d773SGleb Smirnoff init_addrtoname(ndo, localnet, mask); 2723340d773SGleb Smirnoff init_checksum(); 2733340d773SGleb Smirnoff } 2743340d773SGleb Smirnoff 2753340d773SGleb Smirnoff if_printer 2763340d773SGleb Smirnoff lookup_printer(int type) 2773340d773SGleb Smirnoff { 2783340d773SGleb Smirnoff const struct printer *p; 2793340d773SGleb Smirnoff 2803340d773SGleb Smirnoff for (p = printers; p->f; ++p) 2813340d773SGleb Smirnoff if (type == p->type) 2823340d773SGleb Smirnoff return p->f; 2833340d773SGleb Smirnoff 2843340d773SGleb Smirnoff #if defined(DLT_USER2) && defined(DLT_PKTAP) 2853340d773SGleb Smirnoff /* 2863340d773SGleb Smirnoff * Apple incorrectly chose to use DLT_USER2 for their PKTAP 2873340d773SGleb Smirnoff * header. 2883340d773SGleb Smirnoff * 2893340d773SGleb Smirnoff * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- 2903340d773SGleb Smirnoff * based OSes or the same value as LINKTYPE_PKTAP as it is on 2913340d773SGleb Smirnoff * other OSes, to LINKTYPE_PKTAP, so files written with 2923340d773SGleb Smirnoff * this version of libpcap for a DLT_PKTAP capture have a link- 2933340d773SGleb Smirnoff * layer header type of LINKTYPE_PKTAP. 2943340d773SGleb Smirnoff * 2953340d773SGleb Smirnoff * However, files written on OS X Mavericks for a DLT_PKTAP 2963340d773SGleb Smirnoff * capture have a link-layer header type of LINKTYPE_USER2. 2973340d773SGleb Smirnoff * If we don't have a printer for DLT_USER2, and type is 2983340d773SGleb Smirnoff * DLT_USER2, we look up the printer for DLT_PKTAP and use 2993340d773SGleb Smirnoff * that. 3003340d773SGleb Smirnoff */ 3013340d773SGleb Smirnoff if (type == DLT_USER2) { 3023340d773SGleb Smirnoff for (p = printers; p->f; ++p) 3033340d773SGleb Smirnoff if (DLT_PKTAP == p->type) 3043340d773SGleb Smirnoff return p->f; 3053340d773SGleb Smirnoff } 3063340d773SGleb Smirnoff #endif 3073340d773SGleb Smirnoff 3083340d773SGleb Smirnoff return NULL; 3093340d773SGleb Smirnoff /* NOTREACHED */ 3103340d773SGleb Smirnoff } 3113340d773SGleb Smirnoff 3123340d773SGleb Smirnoff int 3133340d773SGleb Smirnoff has_printer(int type) 3143340d773SGleb Smirnoff { 3153340d773SGleb Smirnoff return (lookup_printer(type) != NULL); 3163340d773SGleb Smirnoff } 3173340d773SGleb Smirnoff 3183340d773SGleb Smirnoff if_printer 319ee67461eSJoseph Mingrone get_if_printer(int type) 3203340d773SGleb Smirnoff { 3213340d773SGleb Smirnoff if_printer printer; 3223340d773SGleb Smirnoff 3233340d773SGleb Smirnoff printer = lookup_printer(type); 324ee67461eSJoseph Mingrone if (printer == NULL) 325ee67461eSJoseph Mingrone printer = unsupported_if_print; 3263340d773SGleb Smirnoff return printer; 3273340d773SGleb Smirnoff } 3283340d773SGleb Smirnoff 3293340d773SGleb Smirnoff void 3303340d773SGleb Smirnoff pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h, 3313340d773SGleb Smirnoff const u_char *sp, u_int packets_captured) 3323340d773SGleb Smirnoff { 333ee67461eSJoseph Mingrone u_int hdrlen = 0; 334ee67461eSJoseph Mingrone int invalid_header = 0; 3353340d773SGleb Smirnoff 3363340d773SGleb Smirnoff if (ndo->ndo_packet_number) 337ee67461eSJoseph Mingrone ND_PRINT("%5u ", packets_captured); 3383340d773SGleb Smirnoff 339ee67461eSJoseph Mingrone /* Sanity checks on packet length / capture length */ 340ee67461eSJoseph Mingrone if (h->caplen == 0) { 341ee67461eSJoseph Mingrone invalid_header = 1; 342ee67461eSJoseph Mingrone ND_PRINT("[Invalid header: caplen==0"); 343ee67461eSJoseph Mingrone } 344ee67461eSJoseph Mingrone if (h->len == 0) { 345ee67461eSJoseph Mingrone if (!invalid_header) { 346ee67461eSJoseph Mingrone invalid_header = 1; 347ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:"); 348ee67461eSJoseph Mingrone } else 349ee67461eSJoseph Mingrone ND_PRINT(","); 350ee67461eSJoseph Mingrone ND_PRINT(" len==0"); 351ee67461eSJoseph Mingrone } else if (h->len < h->caplen) { 352ee67461eSJoseph Mingrone if (!invalid_header) { 353ee67461eSJoseph Mingrone invalid_header = 1; 354ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:"); 355ee67461eSJoseph Mingrone } else 356ee67461eSJoseph Mingrone ND_PRINT(","); 357ee67461eSJoseph Mingrone ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen); 358ee67461eSJoseph Mingrone } 359ee67461eSJoseph Mingrone if (h->caplen > MAXIMUM_SNAPLEN) { 360ee67461eSJoseph Mingrone if (!invalid_header) { 361ee67461eSJoseph Mingrone invalid_header = 1; 362ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:"); 363ee67461eSJoseph Mingrone } else 364ee67461eSJoseph Mingrone ND_PRINT(","); 365ee67461eSJoseph Mingrone ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN); 366ee67461eSJoseph Mingrone } 367ee67461eSJoseph Mingrone if (h->len > MAXIMUM_SNAPLEN) { 368ee67461eSJoseph Mingrone if (!invalid_header) { 369ee67461eSJoseph Mingrone invalid_header = 1; 370ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:"); 371ee67461eSJoseph Mingrone } else 372ee67461eSJoseph Mingrone ND_PRINT(","); 373ee67461eSJoseph Mingrone ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN); 374ee67461eSJoseph Mingrone } 375ee67461eSJoseph Mingrone if (invalid_header) { 376ee67461eSJoseph Mingrone ND_PRINT("]\n"); 377ee67461eSJoseph Mingrone return; 378ee67461eSJoseph Mingrone } 3793340d773SGleb Smirnoff 3803340d773SGleb Smirnoff /* 381ee67461eSJoseph Mingrone * At this point: 382ee67461eSJoseph Mingrone * capture length != 0, 383ee67461eSJoseph Mingrone * packet length != 0, 384ee67461eSJoseph Mingrone * capture length <= MAXIMUM_SNAPLEN, 385ee67461eSJoseph Mingrone * packet length <= MAXIMUM_SNAPLEN, 386ee67461eSJoseph Mingrone * packet length >= capture length. 387ee67461eSJoseph Mingrone * 388ee67461eSJoseph Mingrone * Currently, there is no D-Bus printer, thus no need for 389ee67461eSJoseph Mingrone * bigger lengths. 390ee67461eSJoseph Mingrone */ 391ee67461eSJoseph Mingrone 392ee67461eSJoseph Mingrone /* 393ee67461eSJoseph Mingrone * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as 394ee67461eSJoseph Mingrone * struct bpf_timeval, not struct timeval. The former comes from 395ee67461eSJoseph Mingrone * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of 396ee67461eSJoseph Mingrone * the types used in struct timeval. 397ee67461eSJoseph Mingrone */ 398ee67461eSJoseph Mingrone struct timeval tvbuf; 399ee67461eSJoseph Mingrone tvbuf.tv_sec = h->ts.tv_sec; 400ee67461eSJoseph Mingrone tvbuf.tv_usec = h->ts.tv_usec; 401ee67461eSJoseph Mingrone ts_print(ndo, &tvbuf); 402ee67461eSJoseph Mingrone 403ee67461eSJoseph Mingrone /* 404ee67461eSJoseph Mingrone * Printers must check that they're not walking off the end of 405ee67461eSJoseph Mingrone * the packet. 4063340d773SGleb Smirnoff * Rather than pass it all the way down, we set this member 4073340d773SGleb Smirnoff * of the netdissect_options structure. 4083340d773SGleb Smirnoff */ 4093340d773SGleb Smirnoff ndo->ndo_snapend = sp + h->caplen; 410ee67461eSJoseph Mingrone ndo->ndo_packetp = sp; 4113340d773SGleb Smirnoff 412ee67461eSJoseph Mingrone ndo->ndo_protocol = ""; 413ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len = 0; 414ee67461eSJoseph Mingrone switch (setjmp(ndo->ndo_early_end)) { 415ee67461eSJoseph Mingrone case 0: 416ee67461eSJoseph Mingrone /* Print the packet. */ 417ee67461eSJoseph Mingrone (ndo->ndo_if_printer)(ndo, h, sp); 418ee67461eSJoseph Mingrone break; 419ee67461eSJoseph Mingrone case ND_TRUNCATED: 420ee67461eSJoseph Mingrone /* A printer quit because the packet was truncated; report it */ 421ee67461eSJoseph Mingrone nd_print_trunc(ndo); 422ee67461eSJoseph Mingrone /* Print the full packet */ 423ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len = 0; 424ee67461eSJoseph Mingrone break; 425ee67461eSJoseph Mingrone } 426ee67461eSJoseph Mingrone hdrlen = ndo->ndo_ll_hdr_len; 427ee67461eSJoseph Mingrone 428ee67461eSJoseph Mingrone /* 429ee67461eSJoseph Mingrone * Empty the stack of packet information, freeing all pushed buffers; 430ee67461eSJoseph Mingrone * if we got here by a printer quitting, we need to release anything 431ee67461eSJoseph Mingrone * that didn't get released because we longjmped out of the code 432ee67461eSJoseph Mingrone * before it popped the packet information. 433ee67461eSJoseph Mingrone */ 434ee67461eSJoseph Mingrone nd_pop_all_packet_info(ndo); 4353340d773SGleb Smirnoff 4363340d773SGleb Smirnoff /* 4373340d773SGleb Smirnoff * Restore the original snapend, as a printer might have 4383340d773SGleb Smirnoff * changed it. 4393340d773SGleb Smirnoff */ 4403340d773SGleb Smirnoff ndo->ndo_snapend = sp + h->caplen; 4413340d773SGleb Smirnoff if (ndo->ndo_Xflag) { 4423340d773SGleb Smirnoff /* 4433340d773SGleb Smirnoff * Print the raw packet data in hex and ASCII. 4443340d773SGleb Smirnoff */ 4453340d773SGleb Smirnoff if (ndo->ndo_Xflag > 1) { 4463340d773SGleb Smirnoff /* 4473340d773SGleb Smirnoff * Include the link-layer header. 4483340d773SGleb Smirnoff */ 4493340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); 4503340d773SGleb Smirnoff } else { 4513340d773SGleb Smirnoff /* 4523340d773SGleb Smirnoff * Don't include the link-layer header - and if 4533340d773SGleb Smirnoff * we have nothing past the link-layer header, 4543340d773SGleb Smirnoff * print nothing. 4553340d773SGleb Smirnoff */ 4563340d773SGleb Smirnoff if (h->caplen > hdrlen) 4573340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, 4583340d773SGleb Smirnoff h->caplen - hdrlen); 4593340d773SGleb Smirnoff } 4603340d773SGleb Smirnoff } else if (ndo->ndo_xflag) { 4613340d773SGleb Smirnoff /* 4623340d773SGleb Smirnoff * Print the raw packet data in hex. 4633340d773SGleb Smirnoff */ 4643340d773SGleb Smirnoff if (ndo->ndo_xflag > 1) { 4653340d773SGleb Smirnoff /* 4663340d773SGleb Smirnoff * Include the link-layer header. 4673340d773SGleb Smirnoff */ 4683340d773SGleb Smirnoff hex_print(ndo, "\n\t", sp, h->caplen); 4693340d773SGleb Smirnoff } else { 4703340d773SGleb Smirnoff /* 4713340d773SGleb Smirnoff * Don't include the link-layer header - and if 4723340d773SGleb Smirnoff * we have nothing past the link-layer header, 4733340d773SGleb Smirnoff * print nothing. 4743340d773SGleb Smirnoff */ 4753340d773SGleb Smirnoff if (h->caplen > hdrlen) 4763340d773SGleb Smirnoff hex_print(ndo, "\n\t", sp + hdrlen, 4773340d773SGleb Smirnoff h->caplen - hdrlen); 4783340d773SGleb Smirnoff } 4793340d773SGleb Smirnoff } else if (ndo->ndo_Aflag) { 4803340d773SGleb Smirnoff /* 4813340d773SGleb Smirnoff * Print the raw packet data in ASCII. 4823340d773SGleb Smirnoff */ 4833340d773SGleb Smirnoff if (ndo->ndo_Aflag > 1) { 4843340d773SGleb Smirnoff /* 4853340d773SGleb Smirnoff * Include the link-layer header. 4863340d773SGleb Smirnoff */ 4873340d773SGleb Smirnoff ascii_print(ndo, sp, h->caplen); 4883340d773SGleb Smirnoff } else { 4893340d773SGleb Smirnoff /* 4903340d773SGleb Smirnoff * Don't include the link-layer header - and if 4913340d773SGleb Smirnoff * we have nothing past the link-layer header, 4923340d773SGleb Smirnoff * print nothing. 4933340d773SGleb Smirnoff */ 4943340d773SGleb Smirnoff if (h->caplen > hdrlen) 4953340d773SGleb Smirnoff ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); 4963340d773SGleb Smirnoff } 4973340d773SGleb Smirnoff } 4983340d773SGleb Smirnoff 499ee67461eSJoseph Mingrone ND_PRINT("\n"); 500ee67461eSJoseph Mingrone nd_free_all(ndo); 5013340d773SGleb Smirnoff } 5023340d773SGleb Smirnoff 5033340d773SGleb Smirnoff /* 5043340d773SGleb Smirnoff * By default, print the specified data out in hex and ASCII. 5053340d773SGleb Smirnoff */ 5063340d773SGleb Smirnoff static void 5073340d773SGleb Smirnoff ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) 5083340d773SGleb Smirnoff { 5093340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ 5103340d773SGleb Smirnoff } 5113340d773SGleb Smirnoff 5123340d773SGleb Smirnoff /* VARARGS */ 5133340d773SGleb Smirnoff static void 514ee67461eSJoseph Mingrone ndo_error(netdissect_options *ndo, status_exit_codes_t status, 515ee67461eSJoseph Mingrone const char *fmt, ...) 5163340d773SGleb Smirnoff { 5173340d773SGleb Smirnoff va_list ap; 5183340d773SGleb Smirnoff 5193340d773SGleb Smirnoff if (ndo->program_name) 5203340d773SGleb Smirnoff (void)fprintf(stderr, "%s: ", ndo->program_name); 5213340d773SGleb Smirnoff va_start(ap, fmt); 5223340d773SGleb Smirnoff (void)vfprintf(stderr, fmt, ap); 5233340d773SGleb Smirnoff va_end(ap); 5243340d773SGleb Smirnoff if (*fmt) { 5253340d773SGleb Smirnoff fmt += strlen(fmt); 5263340d773SGleb Smirnoff if (fmt[-1] != '\n') 5273340d773SGleb Smirnoff (void)fputc('\n', stderr); 5283340d773SGleb Smirnoff } 5293340d773SGleb Smirnoff nd_cleanup(); 530ee67461eSJoseph Mingrone exit(status); 5313340d773SGleb Smirnoff /* NOTREACHED */ 5323340d773SGleb Smirnoff } 5333340d773SGleb Smirnoff 5343340d773SGleb Smirnoff /* VARARGS */ 5353340d773SGleb Smirnoff static void 5363340d773SGleb Smirnoff ndo_warning(netdissect_options *ndo, const char *fmt, ...) 5373340d773SGleb Smirnoff { 5383340d773SGleb Smirnoff va_list ap; 5393340d773SGleb Smirnoff 5403340d773SGleb Smirnoff if (ndo->program_name) 5413340d773SGleb Smirnoff (void)fprintf(stderr, "%s: ", ndo->program_name); 5423340d773SGleb Smirnoff (void)fprintf(stderr, "WARNING: "); 5433340d773SGleb Smirnoff va_start(ap, fmt); 5443340d773SGleb Smirnoff (void)vfprintf(stderr, fmt, ap); 5453340d773SGleb Smirnoff va_end(ap); 5463340d773SGleb Smirnoff if (*fmt) { 5473340d773SGleb Smirnoff fmt += strlen(fmt); 5483340d773SGleb Smirnoff if (fmt[-1] != '\n') 5493340d773SGleb Smirnoff (void)fputc('\n', stderr); 5503340d773SGleb Smirnoff } 5513340d773SGleb Smirnoff } 5523340d773SGleb Smirnoff 5533340d773SGleb Smirnoff static int 5543340d773SGleb Smirnoff ndo_printf(netdissect_options *ndo, const char *fmt, ...) 5553340d773SGleb Smirnoff { 5563340d773SGleb Smirnoff va_list args; 5573340d773SGleb Smirnoff int ret; 5583340d773SGleb Smirnoff 5593340d773SGleb Smirnoff va_start(args, fmt); 5603340d773SGleb Smirnoff ret = vfprintf(stdout, fmt, args); 5613340d773SGleb Smirnoff va_end(args); 5623340d773SGleb Smirnoff 5633340d773SGleb Smirnoff if (ret < 0) 564ee67461eSJoseph Mingrone ndo_error(ndo, S_ERR_ND_WRITE_FILE, 565ee67461eSJoseph Mingrone "Unable to write output: %s", pcap_strerror(errno)); 5663340d773SGleb Smirnoff return (ret); 5673340d773SGleb Smirnoff } 5683340d773SGleb Smirnoff 5693340d773SGleb Smirnoff void 5703340d773SGleb Smirnoff ndo_set_function_pointers(netdissect_options *ndo) 5713340d773SGleb Smirnoff { 5723340d773SGleb Smirnoff ndo->ndo_default_print=ndo_default_print; 5733340d773SGleb Smirnoff ndo->ndo_printf=ndo_printf; 5743340d773SGleb Smirnoff ndo->ndo_error=ndo_error; 5753340d773SGleb Smirnoff ndo->ndo_warning=ndo_warning; 5763340d773SGleb Smirnoff } 577