xref: /freebsd/contrib/tcpdump/print.c (revision 0a7e5f1f02aad2ff5fff1c60f44c6975fd07e1d9)
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