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
28ee67461eSJoseph Mingrone #include <config.h>
293340d773SGleb Smirnoff
303340d773SGleb Smirnoff #include <stdlib.h>
313340d773SGleb Smirnoff #include <string.h>
32ee67461eSJoseph Mingrone #include <setjmp.h>
333340d773SGleb Smirnoff
34ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
353340d773SGleb Smirnoff
363340d773SGleb Smirnoff #include "netdissect.h"
373340d773SGleb Smirnoff #include "addrtoname.h"
383340d773SGleb Smirnoff #include "print.h"
39ee67461eSJoseph Mingrone #include "netdissect-alloc.h"
40ee67461eSJoseph Mingrone
41ee67461eSJoseph Mingrone #include "pcap-missing.h"
423340d773SGleb Smirnoff
433340d773SGleb Smirnoff struct printer {
443340d773SGleb Smirnoff if_printer f;
453340d773SGleb Smirnoff int type;
463340d773SGleb Smirnoff };
473340d773SGleb Smirnoff
483340d773SGleb Smirnoff static const struct printer printers[] = {
49ee67461eSJoseph Mingrone #ifdef DLT_APPLE_IP_OVER_IEEE1394
50ee67461eSJoseph Mingrone { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 },
51ee67461eSJoseph Mingrone #endif
52ee67461eSJoseph Mingrone { arcnet_if_print, DLT_ARCNET },
53ee67461eSJoseph Mingrone #ifdef DLT_ARCNET_LINUX
54ee67461eSJoseph Mingrone { arcnet_linux_if_print, DLT_ARCNET_LINUX },
55ee67461eSJoseph Mingrone #endif
56ee67461eSJoseph Mingrone { atm_if_print, DLT_ATM_RFC1483 },
57ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_BRCM
58ee67461eSJoseph Mingrone { brcm_tag_if_print, DLT_DSA_TAG_BRCM },
59ee67461eSJoseph Mingrone #endif
60ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_BRCM_PREPEND
61ee67461eSJoseph Mingrone { brcm_tag_prepend_if_print, DLT_DSA_TAG_BRCM_PREPEND },
62ee67461eSJoseph Mingrone #endif
63ee67461eSJoseph Mingrone #ifdef DLT_BLUETOOTH_HCI_H4_WITH_PHDR
64ee67461eSJoseph Mingrone { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
65ee67461eSJoseph Mingrone #endif
66ee67461eSJoseph Mingrone #ifdef DLT_C_HDLC
67ee67461eSJoseph Mingrone { chdlc_if_print, DLT_C_HDLC },
68ee67461eSJoseph Mingrone #endif
69ee67461eSJoseph Mingrone #ifdef DLT_HDLC
70ee67461eSJoseph Mingrone { chdlc_if_print, DLT_HDLC },
71ee67461eSJoseph Mingrone #endif
72ee67461eSJoseph Mingrone #ifdef DLT_ATM_CLIP
73ee67461eSJoseph Mingrone { cip_if_print, DLT_ATM_CLIP },
74ee67461eSJoseph Mingrone #endif
75ee67461eSJoseph Mingrone #ifdef DLT_CIP
76ee67461eSJoseph Mingrone { cip_if_print, DLT_CIP },
77ee67461eSJoseph Mingrone #endif
78ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_DSA
79ee67461eSJoseph Mingrone { dsa_if_print, DLT_DSA_TAG_DSA },
80ee67461eSJoseph Mingrone #endif
81ee67461eSJoseph Mingrone #ifdef DLT_DSA_TAG_EDSA
82ee67461eSJoseph Mingrone { edsa_if_print, DLT_DSA_TAG_EDSA },
83ee67461eSJoseph Mingrone #endif
84ee67461eSJoseph Mingrone #ifdef DLT_ENC
85ee67461eSJoseph Mingrone { enc_if_print, DLT_ENC },
86ee67461eSJoseph Mingrone #endif
873340d773SGleb Smirnoff { ether_if_print, DLT_EN10MB },
88ee67461eSJoseph Mingrone { fddi_if_print, DLT_FDDI },
89ee67461eSJoseph Mingrone #ifdef DLT_FR
90ee67461eSJoseph Mingrone { fr_if_print, DLT_FR },
91ee67461eSJoseph Mingrone #endif
92ee67461eSJoseph Mingrone #ifdef DLT_FRELAY
93ee67461eSJoseph Mingrone { fr_if_print, DLT_FRELAY },
94ee67461eSJoseph Mingrone #endif
95ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_11
96ee67461eSJoseph Mingrone { ieee802_11_if_print, DLT_IEEE802_11},
97ee67461eSJoseph Mingrone #endif
98ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_11_RADIO_AVS
99ee67461eSJoseph Mingrone { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
100ee67461eSJoseph Mingrone #endif
101ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_11_RADIO
102ee67461eSJoseph Mingrone { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
1033340d773SGleb Smirnoff #endif
1043340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4
1053340d773SGleb Smirnoff { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
1063340d773SGleb Smirnoff #endif
1073340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4_NOFCS
1083340d773SGleb Smirnoff { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
1093340d773SGleb Smirnoff #endif
110ee67461eSJoseph Mingrone #ifdef DLT_IEEE802_15_4_TAP
111ee67461eSJoseph Mingrone { ieee802_15_4_tap_if_print, DLT_IEEE802_15_4_TAP },
112ee67461eSJoseph Mingrone #endif
113ee67461eSJoseph Mingrone #ifdef DLT_IP_OVER_FC
114ee67461eSJoseph Mingrone { ipfc_if_print, DLT_IP_OVER_FC },
115ee67461eSJoseph Mingrone #endif
116ee67461eSJoseph Mingrone #ifdef DLT_IPNET
117ee67461eSJoseph Mingrone { ipnet_if_print, DLT_IPNET },
118ee67461eSJoseph Mingrone #endif
119ee67461eSJoseph Mingrone #ifdef DLT_IPOIB
120ee67461eSJoseph Mingrone { ipoib_if_print, DLT_IPOIB },
121ee67461eSJoseph Mingrone #endif
122ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ATM1
123ee67461eSJoseph Mingrone { juniper_atm1_if_print, DLT_JUNIPER_ATM1 },
124ee67461eSJoseph Mingrone #endif
125ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ATM2
126ee67461eSJoseph Mingrone { juniper_atm2_if_print, DLT_JUNIPER_ATM2 },
127ee67461eSJoseph Mingrone #endif
128ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_CHDLC
129ee67461eSJoseph Mingrone { juniper_chdlc_if_print, DLT_JUNIPER_CHDLC },
130ee67461eSJoseph Mingrone #endif
131ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ES
132ee67461eSJoseph Mingrone { juniper_es_if_print, DLT_JUNIPER_ES },
133ee67461eSJoseph Mingrone #endif
134ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_ETHER
135ee67461eSJoseph Mingrone { juniper_ether_if_print, DLT_JUNIPER_ETHER },
136ee67461eSJoseph Mingrone #endif
137ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_FRELAY
138ee67461eSJoseph Mingrone { juniper_frelay_if_print, DLT_JUNIPER_FRELAY },
139ee67461eSJoseph Mingrone #endif
140ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_GGSN
141ee67461eSJoseph Mingrone { juniper_ggsn_if_print, DLT_JUNIPER_GGSN },
142ee67461eSJoseph Mingrone #endif
143ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MFR
144ee67461eSJoseph Mingrone { juniper_mfr_if_print, DLT_JUNIPER_MFR },
145ee67461eSJoseph Mingrone #endif
146ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MLFR
147ee67461eSJoseph Mingrone { juniper_mlfr_if_print, DLT_JUNIPER_MLFR },
148ee67461eSJoseph Mingrone #endif
149ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MLPPP
150ee67461eSJoseph Mingrone { juniper_mlppp_if_print, DLT_JUNIPER_MLPPP },
151ee67461eSJoseph Mingrone #endif
152ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_MONITOR
153ee67461eSJoseph Mingrone { juniper_monitor_if_print, DLT_JUNIPER_MONITOR },
154ee67461eSJoseph Mingrone #endif
155ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_PPP
156ee67461eSJoseph Mingrone { juniper_ppp_if_print, DLT_JUNIPER_PPP },
157ee67461eSJoseph Mingrone #endif
158ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_PPPOE_ATM
159ee67461eSJoseph Mingrone { juniper_pppoe_atm_if_print, DLT_JUNIPER_PPPOE_ATM },
160ee67461eSJoseph Mingrone #endif
161ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_PPPOE
162ee67461eSJoseph Mingrone { juniper_pppoe_if_print, DLT_JUNIPER_PPPOE },
163ee67461eSJoseph Mingrone #endif
164ee67461eSJoseph Mingrone #ifdef DLT_JUNIPER_SERVICES
165ee67461eSJoseph Mingrone { juniper_services_if_print, DLT_JUNIPER_SERVICES },
166ee67461eSJoseph Mingrone #endif
167ee67461eSJoseph Mingrone #ifdef DLT_LTALK
168ee67461eSJoseph Mingrone { ltalk_if_print, DLT_LTALK },
169ee67461eSJoseph Mingrone #endif
170ee67461eSJoseph Mingrone #ifdef DLT_MFR
171ee67461eSJoseph Mingrone { mfr_if_print, DLT_MFR },
1723340d773SGleb Smirnoff #endif
1733340d773SGleb Smirnoff #ifdef DLT_NETANALYZER
1743340d773SGleb Smirnoff { netanalyzer_if_print, DLT_NETANALYZER },
1753340d773SGleb Smirnoff #endif
1763340d773SGleb Smirnoff #ifdef DLT_NETANALYZER_TRANSPARENT
1773340d773SGleb Smirnoff { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
1783340d773SGleb Smirnoff #endif
179ee67461eSJoseph Mingrone #ifdef DLT_NFLOG
1803340d773SGleb Smirnoff { nflog_if_print, DLT_NFLOG},
1813340d773SGleb Smirnoff #endif
1823340d773SGleb Smirnoff { null_if_print, DLT_NULL },
1833340d773SGleb Smirnoff #ifdef DLT_LOOP
1843340d773SGleb Smirnoff { null_if_print, DLT_LOOP },
1853340d773SGleb Smirnoff #endif
186171a7bbfSGleb Smirnoff #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H)
187ee67461eSJoseph Mingrone { pflog_if_print, DLT_PFLOG },
1883340d773SGleb Smirnoff #endif
1891ad8d2eeSJoseph Mingrone #if defined(DLT_PFSYNC) && defined(HAVE_NET_PFVAR_H)
1901ad8d2eeSJoseph Mingrone { pfsync_if_print, DLT_PFSYNC},
1911ad8d2eeSJoseph Mingrone #endif
192ee67461eSJoseph Mingrone #ifdef DLT_PKTAP
193ee67461eSJoseph Mingrone { pktap_if_print, DLT_PKTAP },
1943340d773SGleb Smirnoff #endif
195ee67461eSJoseph Mingrone #ifdef DLT_PPI
196ee67461eSJoseph Mingrone { ppi_if_print, DLT_PPI },
1973340d773SGleb Smirnoff #endif
198ee67461eSJoseph Mingrone #ifdef DLT_PPP_BSDOS
199ee67461eSJoseph Mingrone { ppp_bsdos_if_print, DLT_PPP_BSDOS },
200ee67461eSJoseph Mingrone #endif
201ee67461eSJoseph Mingrone #ifdef DLT_PPP_SERIAL
202ee67461eSJoseph Mingrone { ppp_hdlc_if_print, DLT_PPP_SERIAL },
203ee67461eSJoseph Mingrone #endif
204ee67461eSJoseph Mingrone { ppp_if_print, DLT_PPP },
205ee67461eSJoseph Mingrone #ifdef DLT_PPP_PPPD
206ee67461eSJoseph Mingrone { ppp_if_print, DLT_PPP_PPPD },
207ee67461eSJoseph Mingrone #endif
208ee67461eSJoseph Mingrone #ifdef DLT_PPP_ETHER
209ee67461eSJoseph Mingrone { pppoe_if_print, DLT_PPP_ETHER },
210ee67461eSJoseph Mingrone #endif
211ee67461eSJoseph Mingrone #ifdef DLT_PRISM_HEADER
212ee67461eSJoseph Mingrone { prism_if_print, DLT_PRISM_HEADER },
2133340d773SGleb Smirnoff #endif
2143340d773SGleb Smirnoff { raw_if_print, DLT_RAW },
2153340d773SGleb Smirnoff #ifdef DLT_IPV4
2163340d773SGleb Smirnoff { raw_if_print, DLT_IPV4 },
2173340d773SGleb Smirnoff #endif
2183340d773SGleb Smirnoff #ifdef DLT_IPV6
2193340d773SGleb Smirnoff { raw_if_print, DLT_IPV6 },
2203340d773SGleb Smirnoff #endif
2213340d773SGleb Smirnoff #ifdef DLT_SLIP_BSDOS
2223340d773SGleb Smirnoff { sl_bsdos_if_print, DLT_SLIP_BSDOS },
2233340d773SGleb Smirnoff #endif
224ee67461eSJoseph Mingrone { sl_if_print, DLT_SLIP },
225ee67461eSJoseph Mingrone #ifdef DLT_LINUX_SLL
226ee67461eSJoseph Mingrone { sll_if_print, DLT_LINUX_SLL },
2273340d773SGleb Smirnoff #endif
228ee67461eSJoseph Mingrone #ifdef DLT_LINUX_SLL2
229ee67461eSJoseph Mingrone { sll2_if_print, DLT_LINUX_SLL2 },
2303340d773SGleb Smirnoff #endif
231ee67461eSJoseph Mingrone #ifdef DLT_SUNATM
232ee67461eSJoseph Mingrone { sunatm_if_print, DLT_SUNATM },
2333340d773SGleb Smirnoff #endif
234ee67461eSJoseph Mingrone #ifdef DLT_SYMANTEC_FIREWALL
235ee67461eSJoseph Mingrone { symantec_if_print, DLT_SYMANTEC_FIREWALL },
2363340d773SGleb Smirnoff #endif
237ee67461eSJoseph Mingrone { token_if_print, DLT_IEEE802 },
238ee67461eSJoseph Mingrone #ifdef DLT_USB_LINUX
239ee67461eSJoseph Mingrone { usb_linux_48_byte_if_print, DLT_USB_LINUX},
240ee67461eSJoseph Mingrone #endif /* DLT_USB_LINUX */
241ee67461eSJoseph Mingrone #ifdef DLT_USB_LINUX_MMAPPED
242ee67461eSJoseph Mingrone { usb_linux_64_byte_if_print, DLT_USB_LINUX_MMAPPED},
243ee67461eSJoseph Mingrone #endif /* DLT_USB_LINUX_MMAPPED */
244ee67461eSJoseph Mingrone #ifdef DLT_VSOCK
245ee67461eSJoseph Mingrone { vsock_if_print, DLT_VSOCK },
2463340d773SGleb Smirnoff #endif
2473340d773SGleb Smirnoff { NULL, 0 },
2483340d773SGleb Smirnoff };
2493340d773SGleb Smirnoff
2503340d773SGleb Smirnoff static void ndo_default_print(netdissect_options *ndo, const u_char *bp,
2513340d773SGleb Smirnoff u_int length);
2523340d773SGleb Smirnoff
253ee67461eSJoseph Mingrone static void NORETURN ndo_error(netdissect_options *ndo,
254ee67461eSJoseph Mingrone status_exit_codes_t status,
2550bff6a5aSEd Maste FORMAT_STRING(const char *fmt), ...)
256ee67461eSJoseph Mingrone PRINTFLIKE(3, 4);
2570bff6a5aSEd Maste static void ndo_warning(netdissect_options *ndo,
2580bff6a5aSEd Maste FORMAT_STRING(const char *fmt), ...)
2590bff6a5aSEd Maste PRINTFLIKE(2, 3);
2603340d773SGleb Smirnoff
2610bff6a5aSEd Maste static int ndo_printf(netdissect_options *ndo,
2620bff6a5aSEd Maste FORMAT_STRING(const char *fmt), ...)
2630bff6a5aSEd Maste PRINTFLIKE(2, 3);
2643340d773SGleb Smirnoff
2653340d773SGleb Smirnoff void
init_print(netdissect_options * ndo,uint32_t localnet,uint32_t mask)266ee67461eSJoseph Mingrone init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
2673340d773SGleb Smirnoff {
2683340d773SGleb Smirnoff init_addrtoname(ndo, localnet, mask);
2693340d773SGleb Smirnoff }
2703340d773SGleb Smirnoff
2713340d773SGleb Smirnoff if_printer
lookup_printer(int type)2723340d773SGleb Smirnoff lookup_printer(int type)
2733340d773SGleb Smirnoff {
2743340d773SGleb Smirnoff const struct printer *p;
2753340d773SGleb Smirnoff
2763340d773SGleb Smirnoff for (p = printers; p->f; ++p)
2773340d773SGleb Smirnoff if (type == p->type)
2783340d773SGleb Smirnoff return p->f;
2793340d773SGleb Smirnoff
2803340d773SGleb Smirnoff #if defined(DLT_USER2) && defined(DLT_PKTAP)
2813340d773SGleb Smirnoff /*
2823340d773SGleb Smirnoff * Apple incorrectly chose to use DLT_USER2 for their PKTAP
2833340d773SGleb Smirnoff * header.
2843340d773SGleb Smirnoff *
2853340d773SGleb Smirnoff * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin-
2863340d773SGleb Smirnoff * based OSes or the same value as LINKTYPE_PKTAP as it is on
2873340d773SGleb Smirnoff * other OSes, to LINKTYPE_PKTAP, so files written with
2883340d773SGleb Smirnoff * this version of libpcap for a DLT_PKTAP capture have a link-
2893340d773SGleb Smirnoff * layer header type of LINKTYPE_PKTAP.
2903340d773SGleb Smirnoff *
2913340d773SGleb Smirnoff * However, files written on OS X Mavericks for a DLT_PKTAP
2923340d773SGleb Smirnoff * capture have a link-layer header type of LINKTYPE_USER2.
2933340d773SGleb Smirnoff * If we don't have a printer for DLT_USER2, and type is
2943340d773SGleb Smirnoff * DLT_USER2, we look up the printer for DLT_PKTAP and use
2953340d773SGleb Smirnoff * that.
2963340d773SGleb Smirnoff */
2973340d773SGleb Smirnoff if (type == DLT_USER2) {
2983340d773SGleb Smirnoff for (p = printers; p->f; ++p)
2993340d773SGleb Smirnoff if (DLT_PKTAP == p->type)
3003340d773SGleb Smirnoff return p->f;
3013340d773SGleb Smirnoff }
3023340d773SGleb Smirnoff #endif
3033340d773SGleb Smirnoff
3043340d773SGleb Smirnoff return NULL;
3053340d773SGleb Smirnoff /* NOTREACHED */
3063340d773SGleb Smirnoff }
3073340d773SGleb Smirnoff
3083340d773SGleb Smirnoff int
has_printer(int type)3093340d773SGleb Smirnoff has_printer(int type)
3103340d773SGleb Smirnoff {
3113340d773SGleb Smirnoff return (lookup_printer(type) != NULL);
3123340d773SGleb Smirnoff }
3133340d773SGleb Smirnoff
3143340d773SGleb Smirnoff if_printer
get_if_printer(int type)315ee67461eSJoseph Mingrone get_if_printer(int type)
3163340d773SGleb Smirnoff {
3173340d773SGleb Smirnoff if_printer printer;
3183340d773SGleb Smirnoff
3193340d773SGleb Smirnoff printer = lookup_printer(type);
320ee67461eSJoseph Mingrone if (printer == NULL)
321ee67461eSJoseph Mingrone printer = unsupported_if_print;
3223340d773SGleb Smirnoff return printer;
3233340d773SGleb Smirnoff }
3243340d773SGleb Smirnoff
325*0a7e5f1fSJoseph Mingrone #ifdef ENABLE_INSTRUMENT_FUNCTIONS
326*0a7e5f1fSJoseph Mingrone extern int profile_func_level;
327*0a7e5f1fSJoseph Mingrone static int pretty_print_packet_level = -1;
328*0a7e5f1fSJoseph Mingrone #endif
329*0a7e5f1fSJoseph Mingrone
3303340d773SGleb Smirnoff void
pretty_print_packet(netdissect_options * ndo,const struct pcap_pkthdr * h,const u_char * sp,u_int packets_captured)3313340d773SGleb Smirnoff pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
3323340d773SGleb Smirnoff const u_char *sp, u_int packets_captured)
3333340d773SGleb Smirnoff {
334ee67461eSJoseph Mingrone u_int hdrlen = 0;
335ee67461eSJoseph Mingrone int invalid_header = 0;
3363340d773SGleb Smirnoff
337*0a7e5f1fSJoseph Mingrone #ifdef ENABLE_INSTRUMENT_FUNCTIONS
338*0a7e5f1fSJoseph Mingrone if (pretty_print_packet_level == -1)
339*0a7e5f1fSJoseph Mingrone pretty_print_packet_level = profile_func_level;
340*0a7e5f1fSJoseph Mingrone #endif
341*0a7e5f1fSJoseph Mingrone
3423340d773SGleb Smirnoff if (ndo->ndo_packet_number)
343ee67461eSJoseph Mingrone ND_PRINT("%5u ", packets_captured);
3443340d773SGleb Smirnoff
345ee67461eSJoseph Mingrone /* Sanity checks on packet length / capture length */
346ee67461eSJoseph Mingrone if (h->caplen == 0) {
347ee67461eSJoseph Mingrone invalid_header = 1;
348ee67461eSJoseph Mingrone ND_PRINT("[Invalid header: caplen==0");
349ee67461eSJoseph Mingrone }
350ee67461eSJoseph Mingrone if (h->len == 0) {
351ee67461eSJoseph Mingrone if (!invalid_header) {
352ee67461eSJoseph Mingrone invalid_header = 1;
353ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:");
354ee67461eSJoseph Mingrone } else
355ee67461eSJoseph Mingrone ND_PRINT(",");
356ee67461eSJoseph Mingrone ND_PRINT(" len==0");
357ee67461eSJoseph Mingrone } else if (h->len < h->caplen) {
358ee67461eSJoseph Mingrone if (!invalid_header) {
359ee67461eSJoseph Mingrone invalid_header = 1;
360ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:");
361ee67461eSJoseph Mingrone } else
362ee67461eSJoseph Mingrone ND_PRINT(",");
363ee67461eSJoseph Mingrone ND_PRINT(" len(%u) < caplen(%u)", h->len, h->caplen);
364ee67461eSJoseph Mingrone }
365ee67461eSJoseph Mingrone if (h->caplen > MAXIMUM_SNAPLEN) {
366ee67461eSJoseph Mingrone if (!invalid_header) {
367ee67461eSJoseph Mingrone invalid_header = 1;
368ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:");
369ee67461eSJoseph Mingrone } else
370ee67461eSJoseph Mingrone ND_PRINT(",");
371ee67461eSJoseph Mingrone ND_PRINT(" caplen(%u) > %u", h->caplen, MAXIMUM_SNAPLEN);
372ee67461eSJoseph Mingrone }
373ee67461eSJoseph Mingrone if (h->len > MAXIMUM_SNAPLEN) {
374ee67461eSJoseph Mingrone if (!invalid_header) {
375ee67461eSJoseph Mingrone invalid_header = 1;
376ee67461eSJoseph Mingrone ND_PRINT("[Invalid header:");
377ee67461eSJoseph Mingrone } else
378ee67461eSJoseph Mingrone ND_PRINT(",");
379ee67461eSJoseph Mingrone ND_PRINT(" len(%u) > %u", h->len, MAXIMUM_SNAPLEN);
380ee67461eSJoseph Mingrone }
381ee67461eSJoseph Mingrone if (invalid_header) {
382ee67461eSJoseph Mingrone ND_PRINT("]\n");
383ee67461eSJoseph Mingrone return;
384ee67461eSJoseph Mingrone }
3853340d773SGleb Smirnoff
3863340d773SGleb Smirnoff /*
387ee67461eSJoseph Mingrone * At this point:
388ee67461eSJoseph Mingrone * capture length != 0,
389ee67461eSJoseph Mingrone * packet length != 0,
390ee67461eSJoseph Mingrone * capture length <= MAXIMUM_SNAPLEN,
391ee67461eSJoseph Mingrone * packet length <= MAXIMUM_SNAPLEN,
392ee67461eSJoseph Mingrone * packet length >= capture length.
393ee67461eSJoseph Mingrone *
394ee67461eSJoseph Mingrone * Currently, there is no D-Bus printer, thus no need for
395ee67461eSJoseph Mingrone * bigger lengths.
396ee67461eSJoseph Mingrone */
397ee67461eSJoseph Mingrone
398ee67461eSJoseph Mingrone /*
399ee67461eSJoseph Mingrone * The header /usr/include/pcap/pcap.h in OpenBSD declares h->ts as
400ee67461eSJoseph Mingrone * struct bpf_timeval, not struct timeval. The former comes from
401ee67461eSJoseph Mingrone * /usr/include/net/bpf.h and uses 32-bit unsigned types instead of
402ee67461eSJoseph Mingrone * the types used in struct timeval.
403ee67461eSJoseph Mingrone */
404ee67461eSJoseph Mingrone struct timeval tvbuf;
405ee67461eSJoseph Mingrone tvbuf.tv_sec = h->ts.tv_sec;
406ee67461eSJoseph Mingrone tvbuf.tv_usec = h->ts.tv_usec;
407ee67461eSJoseph Mingrone ts_print(ndo, &tvbuf);
408ee67461eSJoseph Mingrone
409ee67461eSJoseph Mingrone /*
410ee67461eSJoseph Mingrone * Printers must check that they're not walking off the end of
411ee67461eSJoseph Mingrone * the packet.
4123340d773SGleb Smirnoff * Rather than pass it all the way down, we set this member
4133340d773SGleb Smirnoff * of the netdissect_options structure.
4143340d773SGleb Smirnoff */
4153340d773SGleb Smirnoff ndo->ndo_snapend = sp + h->caplen;
416ee67461eSJoseph Mingrone ndo->ndo_packetp = sp;
4173340d773SGleb Smirnoff
418ee67461eSJoseph Mingrone ndo->ndo_protocol = "";
419ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len = 0;
420ee67461eSJoseph Mingrone switch (setjmp(ndo->ndo_early_end)) {
421ee67461eSJoseph Mingrone case 0:
422ee67461eSJoseph Mingrone /* Print the packet. */
423ee67461eSJoseph Mingrone (ndo->ndo_if_printer)(ndo, h, sp);
424ee67461eSJoseph Mingrone break;
425ee67461eSJoseph Mingrone case ND_TRUNCATED:
426ee67461eSJoseph Mingrone /* A printer quit because the packet was truncated; report it */
427ee67461eSJoseph Mingrone nd_print_trunc(ndo);
428ee67461eSJoseph Mingrone /* Print the full packet */
429ee67461eSJoseph Mingrone ndo->ndo_ll_hdr_len = 0;
430*0a7e5f1fSJoseph Mingrone #ifdef ENABLE_INSTRUMENT_FUNCTIONS
431*0a7e5f1fSJoseph Mingrone /* truncation => reassignment */
432*0a7e5f1fSJoseph Mingrone profile_func_level = pretty_print_packet_level;
433*0a7e5f1fSJoseph Mingrone #endif
434ee67461eSJoseph Mingrone break;
435ee67461eSJoseph Mingrone }
436ee67461eSJoseph Mingrone hdrlen = ndo->ndo_ll_hdr_len;
437ee67461eSJoseph Mingrone
438ee67461eSJoseph Mingrone /*
439ee67461eSJoseph Mingrone * Empty the stack of packet information, freeing all pushed buffers;
440ee67461eSJoseph Mingrone * if we got here by a printer quitting, we need to release anything
441ee67461eSJoseph Mingrone * that didn't get released because we longjmped out of the code
442ee67461eSJoseph Mingrone * before it popped the packet information.
443ee67461eSJoseph Mingrone */
444ee67461eSJoseph Mingrone nd_pop_all_packet_info(ndo);
4453340d773SGleb Smirnoff
4463340d773SGleb Smirnoff /*
447f8860353SGuy Harris * Restore the originals snapend and packetp, as a printer
448f8860353SGuy Harris * might have changed them.
449f8860353SGuy Harris *
450f8860353SGuy Harris * XXX - nd_pop_all_packet_info() should have restored the
451f8860353SGuy Harris * original values, but, just in case....
4523340d773SGleb Smirnoff */
4533340d773SGleb Smirnoff ndo->ndo_snapend = sp + h->caplen;
454f8860353SGuy Harris ndo->ndo_packetp = sp;
4553340d773SGleb Smirnoff if (ndo->ndo_Xflag) {
4563340d773SGleb Smirnoff /*
4573340d773SGleb Smirnoff * Print the raw packet data in hex and ASCII.
4583340d773SGleb Smirnoff */
4593340d773SGleb Smirnoff if (ndo->ndo_Xflag > 1) {
4603340d773SGleb Smirnoff /*
4613340d773SGleb Smirnoff * Include the link-layer header.
4623340d773SGleb Smirnoff */
4633340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", sp, h->caplen);
4643340d773SGleb Smirnoff } else {
4653340d773SGleb Smirnoff /*
4663340d773SGleb Smirnoff * Don't include the link-layer header - and if
4673340d773SGleb Smirnoff * we have nothing past the link-layer header,
4683340d773SGleb Smirnoff * print nothing.
4693340d773SGleb Smirnoff */
4703340d773SGleb Smirnoff if (h->caplen > hdrlen)
4713340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", sp + hdrlen,
4723340d773SGleb Smirnoff h->caplen - hdrlen);
4733340d773SGleb Smirnoff }
4743340d773SGleb Smirnoff } else if (ndo->ndo_xflag) {
4753340d773SGleb Smirnoff /*
4763340d773SGleb Smirnoff * Print the raw packet data in hex.
4773340d773SGleb Smirnoff */
4783340d773SGleb Smirnoff if (ndo->ndo_xflag > 1) {
4793340d773SGleb Smirnoff /*
4803340d773SGleb Smirnoff * Include the link-layer header.
4813340d773SGleb Smirnoff */
4823340d773SGleb Smirnoff hex_print(ndo, "\n\t", sp, h->caplen);
4833340d773SGleb Smirnoff } else {
4843340d773SGleb Smirnoff /*
4853340d773SGleb Smirnoff * Don't include the link-layer header - and if
4863340d773SGleb Smirnoff * we have nothing past the link-layer header,
4873340d773SGleb Smirnoff * print nothing.
4883340d773SGleb Smirnoff */
4893340d773SGleb Smirnoff if (h->caplen > hdrlen)
4903340d773SGleb Smirnoff hex_print(ndo, "\n\t", sp + hdrlen,
4913340d773SGleb Smirnoff h->caplen - hdrlen);
4923340d773SGleb Smirnoff }
4933340d773SGleb Smirnoff } else if (ndo->ndo_Aflag) {
4943340d773SGleb Smirnoff /*
4953340d773SGleb Smirnoff * Print the raw packet data in ASCII.
4963340d773SGleb Smirnoff */
4973340d773SGleb Smirnoff if (ndo->ndo_Aflag > 1) {
4983340d773SGleb Smirnoff /*
4993340d773SGleb Smirnoff * Include the link-layer header.
5003340d773SGleb Smirnoff */
5013340d773SGleb Smirnoff ascii_print(ndo, sp, h->caplen);
5023340d773SGleb Smirnoff } else {
5033340d773SGleb Smirnoff /*
5043340d773SGleb Smirnoff * Don't include the link-layer header - and if
5053340d773SGleb Smirnoff * we have nothing past the link-layer header,
5063340d773SGleb Smirnoff * print nothing.
5073340d773SGleb Smirnoff */
5083340d773SGleb Smirnoff if (h->caplen > hdrlen)
5093340d773SGleb Smirnoff ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen);
5103340d773SGleb Smirnoff }
5113340d773SGleb Smirnoff }
5123340d773SGleb Smirnoff
513ee67461eSJoseph Mingrone ND_PRINT("\n");
514ee67461eSJoseph Mingrone nd_free_all(ndo);
5153340d773SGleb Smirnoff }
5163340d773SGleb Smirnoff
5173340d773SGleb Smirnoff /*
5183340d773SGleb Smirnoff * By default, print the specified data out in hex and ASCII.
5193340d773SGleb Smirnoff */
5203340d773SGleb Smirnoff static void
ndo_default_print(netdissect_options * ndo,const u_char * bp,u_int length)5213340d773SGleb Smirnoff ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length)
5223340d773SGleb Smirnoff {
5233340d773SGleb Smirnoff hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */
5243340d773SGleb Smirnoff }
5253340d773SGleb Smirnoff
5263340d773SGleb Smirnoff /* VARARGS */
5273340d773SGleb Smirnoff static void
ndo_error(netdissect_options * ndo,status_exit_codes_t status,const char * fmt,...)528ee67461eSJoseph Mingrone ndo_error(netdissect_options *ndo, status_exit_codes_t status,
529ee67461eSJoseph Mingrone const char *fmt, ...)
5303340d773SGleb Smirnoff {
5313340d773SGleb Smirnoff va_list ap;
5323340d773SGleb Smirnoff
5333340d773SGleb Smirnoff if (ndo->program_name)
5343340d773SGleb Smirnoff (void)fprintf(stderr, "%s: ", ndo->program_name);
5353340d773SGleb Smirnoff va_start(ap, fmt);
5363340d773SGleb Smirnoff (void)vfprintf(stderr, fmt, ap);
5373340d773SGleb Smirnoff va_end(ap);
5383340d773SGleb Smirnoff if (*fmt) {
5393340d773SGleb Smirnoff fmt += strlen(fmt);
5403340d773SGleb Smirnoff if (fmt[-1] != '\n')
5413340d773SGleb Smirnoff (void)fputc('\n', stderr);
5423340d773SGleb Smirnoff }
5433340d773SGleb Smirnoff nd_cleanup();
544ee67461eSJoseph Mingrone exit(status);
5453340d773SGleb Smirnoff /* NOTREACHED */
5463340d773SGleb Smirnoff }
5473340d773SGleb Smirnoff
5483340d773SGleb Smirnoff /* VARARGS */
5493340d773SGleb Smirnoff static void
ndo_warning(netdissect_options * ndo,const char * fmt,...)5503340d773SGleb Smirnoff ndo_warning(netdissect_options *ndo, const char *fmt, ...)
5513340d773SGleb Smirnoff {
5523340d773SGleb Smirnoff va_list ap;
5533340d773SGleb Smirnoff
5543340d773SGleb Smirnoff if (ndo->program_name)
5553340d773SGleb Smirnoff (void)fprintf(stderr, "%s: ", ndo->program_name);
5563340d773SGleb Smirnoff (void)fprintf(stderr, "WARNING: ");
5573340d773SGleb Smirnoff va_start(ap, fmt);
5583340d773SGleb Smirnoff (void)vfprintf(stderr, fmt, ap);
5593340d773SGleb Smirnoff va_end(ap);
5603340d773SGleb Smirnoff if (*fmt) {
5613340d773SGleb Smirnoff fmt += strlen(fmt);
5623340d773SGleb Smirnoff if (fmt[-1] != '\n')
5633340d773SGleb Smirnoff (void)fputc('\n', stderr);
5643340d773SGleb Smirnoff }
5653340d773SGleb Smirnoff }
5663340d773SGleb Smirnoff
5673340d773SGleb Smirnoff static int
ndo_printf(netdissect_options * ndo,const char * fmt,...)5683340d773SGleb Smirnoff ndo_printf(netdissect_options *ndo, const char *fmt, ...)
5693340d773SGleb Smirnoff {
5703340d773SGleb Smirnoff va_list args;
5713340d773SGleb Smirnoff int ret;
5723340d773SGleb Smirnoff
5733340d773SGleb Smirnoff va_start(args, fmt);
5743340d773SGleb Smirnoff ret = vfprintf(stdout, fmt, args);
5753340d773SGleb Smirnoff va_end(args);
5763340d773SGleb Smirnoff
5773340d773SGleb Smirnoff if (ret < 0)
578ee67461eSJoseph Mingrone ndo_error(ndo, S_ERR_ND_WRITE_FILE,
579ee67461eSJoseph Mingrone "Unable to write output: %s", pcap_strerror(errno));
5803340d773SGleb Smirnoff return (ret);
5813340d773SGleb Smirnoff }
5823340d773SGleb Smirnoff
5833340d773SGleb Smirnoff void
ndo_set_function_pointers(netdissect_options * ndo)5843340d773SGleb Smirnoff ndo_set_function_pointers(netdissect_options *ndo)
5853340d773SGleb Smirnoff {
5863340d773SGleb Smirnoff ndo->ndo_default_print=ndo_default_print;
5873340d773SGleb Smirnoff ndo->ndo_printf=ndo_printf;
5883340d773SGleb Smirnoff ndo->ndo_error=ndo_error;
5893340d773SGleb Smirnoff ndo->ndo_warning=ndo_warning;
5903340d773SGleb Smirnoff }
591