xref: /freebsd/contrib/tcpdump/print.c (revision 3340d77368116708ab5b5b95acf6c9c710528300)
1*3340d773SGleb Smirnoff /*
2*3340d773SGleb Smirnoff  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3*3340d773SGleb Smirnoff  *	The Regents of the University of California.  All rights reserved.
4*3340d773SGleb Smirnoff  *
5*3340d773SGleb Smirnoff  * Redistribution and use in source and binary forms, with or without
6*3340d773SGleb Smirnoff  * modification, are permitted provided that: (1) source code distributions
7*3340d773SGleb Smirnoff  * retain the above copyright notice and this paragraph in its entirety, (2)
8*3340d773SGleb Smirnoff  * distributions including binary code include the above copyright notice and
9*3340d773SGleb Smirnoff  * this paragraph in its entirety in the documentation or other materials
10*3340d773SGleb Smirnoff  * provided with the distribution, and (3) all advertising materials mentioning
11*3340d773SGleb Smirnoff  * features or use of this software display the following acknowledgement:
12*3340d773SGleb Smirnoff  * ``This product includes software developed by the University of California,
13*3340d773SGleb Smirnoff  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*3340d773SGleb Smirnoff  * the University nor the names of its contributors may be used to endorse
15*3340d773SGleb Smirnoff  * or promote products derived from this software without specific prior
16*3340d773SGleb Smirnoff  * written permission.
17*3340d773SGleb Smirnoff  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*3340d773SGleb Smirnoff  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*3340d773SGleb Smirnoff  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*3340d773SGleb Smirnoff  *
21*3340d773SGleb Smirnoff  * Support for splitting captures into multiple files with a maximum
22*3340d773SGleb Smirnoff  * file size:
23*3340d773SGleb Smirnoff  *
24*3340d773SGleb Smirnoff  * Copyright (c) 2001
25*3340d773SGleb Smirnoff  *	Seth Webster <swebster@sst.ll.mit.edu>
26*3340d773SGleb Smirnoff  */
27*3340d773SGleb Smirnoff 
28*3340d773SGleb Smirnoff #ifdef HAVE_CONFIG_H
29*3340d773SGleb Smirnoff #include "config.h"
30*3340d773SGleb Smirnoff #endif
31*3340d773SGleb Smirnoff 
32*3340d773SGleb Smirnoff #include <stdlib.h>
33*3340d773SGleb Smirnoff #include <string.h>
34*3340d773SGleb Smirnoff 
35*3340d773SGleb Smirnoff #include <netdissect-stdinc.h>
36*3340d773SGleb Smirnoff 
37*3340d773SGleb Smirnoff #include "netdissect.h"
38*3340d773SGleb Smirnoff #include "addrtoname.h"
39*3340d773SGleb Smirnoff #include "print.h"
40*3340d773SGleb Smirnoff 
41*3340d773SGleb Smirnoff struct printer {
42*3340d773SGleb Smirnoff 	if_printer f;
43*3340d773SGleb Smirnoff 	int type;
44*3340d773SGleb Smirnoff };
45*3340d773SGleb Smirnoff 
46*3340d773SGleb Smirnoff static const struct printer printers[] = {
47*3340d773SGleb Smirnoff 	{ ether_if_print,	DLT_EN10MB },
48*3340d773SGleb Smirnoff #ifdef DLT_IPNET
49*3340d773SGleb Smirnoff 	{ ipnet_if_print,	DLT_IPNET },
50*3340d773SGleb Smirnoff #endif
51*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4
52*3340d773SGleb Smirnoff 	{ ieee802_15_4_if_print, DLT_IEEE802_15_4 },
53*3340d773SGleb Smirnoff #endif
54*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_15_4_NOFCS
55*3340d773SGleb Smirnoff 	{ ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
56*3340d773SGleb Smirnoff #endif
57*3340d773SGleb Smirnoff #ifdef DLT_PPI
58*3340d773SGleb Smirnoff 	{ ppi_if_print,		DLT_PPI },
59*3340d773SGleb Smirnoff #endif
60*3340d773SGleb Smirnoff #ifdef DLT_NETANALYZER
61*3340d773SGleb Smirnoff 	{ netanalyzer_if_print, DLT_NETANALYZER },
62*3340d773SGleb Smirnoff #endif
63*3340d773SGleb Smirnoff #ifdef DLT_NETANALYZER_TRANSPARENT
64*3340d773SGleb Smirnoff 	{ netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
65*3340d773SGleb Smirnoff #endif
66*3340d773SGleb Smirnoff #if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H)
67*3340d773SGleb Smirnoff 	{ nflog_if_print,	DLT_NFLOG},
68*3340d773SGleb Smirnoff #endif
69*3340d773SGleb Smirnoff #ifdef DLT_CIP
70*3340d773SGleb Smirnoff 	{ cip_if_print,         DLT_CIP },
71*3340d773SGleb Smirnoff #endif
72*3340d773SGleb Smirnoff #ifdef DLT_ATM_CLIP
73*3340d773SGleb Smirnoff 	{ cip_if_print,		DLT_ATM_CLIP },
74*3340d773SGleb Smirnoff #endif
75*3340d773SGleb Smirnoff #ifdef DLT_IP_OVER_FC
76*3340d773SGleb Smirnoff 	{ ipfc_if_print,	DLT_IP_OVER_FC },
77*3340d773SGleb Smirnoff #endif
78*3340d773SGleb Smirnoff 	{ null_if_print,	DLT_NULL },
79*3340d773SGleb Smirnoff #ifdef DLT_LOOP
80*3340d773SGleb Smirnoff 	{ null_if_print,	DLT_LOOP },
81*3340d773SGleb Smirnoff #endif
82*3340d773SGleb Smirnoff #ifdef DLT_APPLE_IP_OVER_IEEE1394
83*3340d773SGleb Smirnoff 	{ ap1394_if_print,	DLT_APPLE_IP_OVER_IEEE1394 },
84*3340d773SGleb Smirnoff #endif
85*3340d773SGleb Smirnoff #if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
86*3340d773SGleb Smirnoff 	{ bt_if_print,		DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
87*3340d773SGleb Smirnoff #endif
88*3340d773SGleb Smirnoff #ifdef DLT_LANE8023
89*3340d773SGleb Smirnoff 	{ lane_if_print,        DLT_LANE8023 },
90*3340d773SGleb Smirnoff #endif
91*3340d773SGleb Smirnoff 	{ arcnet_if_print,	DLT_ARCNET },
92*3340d773SGleb Smirnoff #ifdef DLT_ARCNET_LINUX
93*3340d773SGleb Smirnoff 	{ arcnet_linux_if_print, DLT_ARCNET_LINUX },
94*3340d773SGleb Smirnoff #endif
95*3340d773SGleb Smirnoff 	{ raw_if_print,		DLT_RAW },
96*3340d773SGleb Smirnoff #ifdef DLT_IPV4
97*3340d773SGleb Smirnoff 	{ raw_if_print,		DLT_IPV4 },
98*3340d773SGleb Smirnoff #endif
99*3340d773SGleb Smirnoff #ifdef DLT_IPV6
100*3340d773SGleb Smirnoff 	{ raw_if_print,		DLT_IPV6 },
101*3340d773SGleb Smirnoff #endif
102*3340d773SGleb Smirnoff #ifdef HAVE_PCAP_USB_H
103*3340d773SGleb Smirnoff #ifdef DLT_USB_LINUX
104*3340d773SGleb Smirnoff 	{ usb_linux_48_byte_print, DLT_USB_LINUX},
105*3340d773SGleb Smirnoff #endif /* DLT_USB_LINUX */
106*3340d773SGleb Smirnoff #ifdef DLT_USB_LINUX_MMAPPED
107*3340d773SGleb Smirnoff 	{ usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED},
108*3340d773SGleb Smirnoff #endif /* DLT_USB_LINUX_MMAPPED */
109*3340d773SGleb Smirnoff #endif /* HAVE_PCAP_USB_H */
110*3340d773SGleb Smirnoff #ifdef DLT_SYMANTEC_FIREWALL
111*3340d773SGleb Smirnoff 	{ symantec_if_print,	DLT_SYMANTEC_FIREWALL },
112*3340d773SGleb Smirnoff #endif
113*3340d773SGleb Smirnoff #ifdef DLT_C_HDLC
114*3340d773SGleb Smirnoff 	{ chdlc_if_print,	DLT_C_HDLC },
115*3340d773SGleb Smirnoff #endif
116*3340d773SGleb Smirnoff #ifdef DLT_HDLC
117*3340d773SGleb Smirnoff 	{ chdlc_if_print,	DLT_HDLC },
118*3340d773SGleb Smirnoff #endif
119*3340d773SGleb Smirnoff #ifdef DLT_PPP_ETHER
120*3340d773SGleb Smirnoff 	{ pppoe_if_print,	DLT_PPP_ETHER },
121*3340d773SGleb Smirnoff #endif
122*3340d773SGleb Smirnoff #if defined(DLT_PFLOG) && defined(HAVE_NET_IF_PFLOG_H)
123*3340d773SGleb Smirnoff 	{ pflog_if_print,	DLT_PFLOG },
124*3340d773SGleb Smirnoff #endif
125*3340d773SGleb Smirnoff 	{ token_if_print,	DLT_IEEE802 },
126*3340d773SGleb Smirnoff 	{ fddi_if_print,	DLT_FDDI },
127*3340d773SGleb Smirnoff #ifdef DLT_LINUX_SLL
128*3340d773SGleb Smirnoff 	{ sll_if_print,		DLT_LINUX_SLL },
129*3340d773SGleb Smirnoff #endif
130*3340d773SGleb Smirnoff #ifdef DLT_FR
131*3340d773SGleb Smirnoff 	{ fr_if_print,		DLT_FR },
132*3340d773SGleb Smirnoff #endif
133*3340d773SGleb Smirnoff #ifdef DLT_FRELAY
134*3340d773SGleb Smirnoff 	{ fr_if_print,		DLT_FRELAY },
135*3340d773SGleb Smirnoff #endif
136*3340d773SGleb Smirnoff #ifdef DLT_MFR
137*3340d773SGleb Smirnoff 	{ mfr_if_print,		DLT_MFR },
138*3340d773SGleb Smirnoff #endif
139*3340d773SGleb Smirnoff 	{ atm_if_print,		DLT_ATM_RFC1483 },
140*3340d773SGleb Smirnoff #ifdef DLT_SUNATM
141*3340d773SGleb Smirnoff 	{ sunatm_if_print,	DLT_SUNATM },
142*3340d773SGleb Smirnoff #endif
143*3340d773SGleb Smirnoff #ifdef DLT_ENC
144*3340d773SGleb Smirnoff 	{ enc_if_print,		DLT_ENC },
145*3340d773SGleb Smirnoff #endif
146*3340d773SGleb Smirnoff 	{ sl_if_print,		DLT_SLIP },
147*3340d773SGleb Smirnoff #ifdef DLT_SLIP_BSDOS
148*3340d773SGleb Smirnoff 	{ sl_bsdos_if_print,	DLT_SLIP_BSDOS },
149*3340d773SGleb Smirnoff #endif
150*3340d773SGleb Smirnoff #ifdef DLT_LTALK
151*3340d773SGleb Smirnoff 	{ ltalk_if_print,	DLT_LTALK },
152*3340d773SGleb Smirnoff #endif
153*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ATM1
154*3340d773SGleb Smirnoff 	{ juniper_atm1_print,	DLT_JUNIPER_ATM1 },
155*3340d773SGleb Smirnoff #endif
156*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ATM2
157*3340d773SGleb Smirnoff 	{ juniper_atm2_print,	DLT_JUNIPER_ATM2 },
158*3340d773SGleb Smirnoff #endif
159*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MFR
160*3340d773SGleb Smirnoff 	{ juniper_mfr_print,	DLT_JUNIPER_MFR },
161*3340d773SGleb Smirnoff #endif
162*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MLFR
163*3340d773SGleb Smirnoff 	{ juniper_mlfr_print,	DLT_JUNIPER_MLFR },
164*3340d773SGleb Smirnoff #endif
165*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MLPPP
166*3340d773SGleb Smirnoff 	{ juniper_mlppp_print,	DLT_JUNIPER_MLPPP },
167*3340d773SGleb Smirnoff #endif
168*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_PPPOE
169*3340d773SGleb Smirnoff 	{ juniper_pppoe_print,	DLT_JUNIPER_PPPOE },
170*3340d773SGleb Smirnoff #endif
171*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_PPPOE_ATM
172*3340d773SGleb Smirnoff 	{ juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM },
173*3340d773SGleb Smirnoff #endif
174*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_GGSN
175*3340d773SGleb Smirnoff 	{ juniper_ggsn_print,	DLT_JUNIPER_GGSN },
176*3340d773SGleb Smirnoff #endif
177*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ES
178*3340d773SGleb Smirnoff 	{ juniper_es_print,	DLT_JUNIPER_ES },
179*3340d773SGleb Smirnoff #endif
180*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_MONITOR
181*3340d773SGleb Smirnoff 	{ juniper_monitor_print, DLT_JUNIPER_MONITOR },
182*3340d773SGleb Smirnoff #endif
183*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_SERVICES
184*3340d773SGleb Smirnoff 	{ juniper_services_print, DLT_JUNIPER_SERVICES },
185*3340d773SGleb Smirnoff #endif
186*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_ETHER
187*3340d773SGleb Smirnoff 	{ juniper_ether_print,	DLT_JUNIPER_ETHER },
188*3340d773SGleb Smirnoff #endif
189*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_PPP
190*3340d773SGleb Smirnoff 	{ juniper_ppp_print,	DLT_JUNIPER_PPP },
191*3340d773SGleb Smirnoff #endif
192*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_FRELAY
193*3340d773SGleb Smirnoff 	{ juniper_frelay_print,	DLT_JUNIPER_FRELAY },
194*3340d773SGleb Smirnoff #endif
195*3340d773SGleb Smirnoff #ifdef DLT_JUNIPER_CHDLC
196*3340d773SGleb Smirnoff 	{ juniper_chdlc_print,	DLT_JUNIPER_CHDLC },
197*3340d773SGleb Smirnoff #endif
198*3340d773SGleb Smirnoff #ifdef DLT_PKTAP
199*3340d773SGleb Smirnoff 	{ pktap_if_print,	DLT_PKTAP },
200*3340d773SGleb Smirnoff #endif
201*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_11_RADIO
202*3340d773SGleb Smirnoff 	{ ieee802_11_radio_if_print,	DLT_IEEE802_11_RADIO },
203*3340d773SGleb Smirnoff #endif
204*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_11
205*3340d773SGleb Smirnoff 	{ ieee802_11_if_print,	DLT_IEEE802_11},
206*3340d773SGleb Smirnoff #endif
207*3340d773SGleb Smirnoff #ifdef DLT_IEEE802_11_RADIO_AVS
208*3340d773SGleb Smirnoff 	{ ieee802_11_radio_avs_if_print,	DLT_IEEE802_11_RADIO_AVS },
209*3340d773SGleb Smirnoff #endif
210*3340d773SGleb Smirnoff #ifdef DLT_PRISM_HEADER
211*3340d773SGleb Smirnoff 	{ prism_if_print,	DLT_PRISM_HEADER },
212*3340d773SGleb Smirnoff #endif
213*3340d773SGleb Smirnoff 	{ ppp_if_print,		DLT_PPP },
214*3340d773SGleb Smirnoff #ifdef DLT_PPP_WITHDIRECTION
215*3340d773SGleb Smirnoff 	{ ppp_if_print,		DLT_PPP_WITHDIRECTION },
216*3340d773SGleb Smirnoff #endif
217*3340d773SGleb Smirnoff #ifdef DLT_PPP_BSDOS
218*3340d773SGleb Smirnoff 	{ ppp_bsdos_if_print,	DLT_PPP_BSDOS },
219*3340d773SGleb Smirnoff #endif
220*3340d773SGleb Smirnoff #ifdef DLT_PPP_SERIAL
221*3340d773SGleb Smirnoff 	{ ppp_hdlc_if_print,	DLT_PPP_SERIAL },
222*3340d773SGleb Smirnoff #endif
223*3340d773SGleb Smirnoff 	{ NULL,			0 },
224*3340d773SGleb Smirnoff };
225*3340d773SGleb Smirnoff 
226*3340d773SGleb Smirnoff static void	ndo_default_print(netdissect_options *ndo, const u_char *bp,
227*3340d773SGleb Smirnoff 		    u_int length);
228*3340d773SGleb Smirnoff 
229*3340d773SGleb Smirnoff static void	ndo_error(netdissect_options *ndo, const char *fmt, ...)
230*3340d773SGleb Smirnoff 		    __attribute__((noreturn))
231*3340d773SGleb Smirnoff #ifdef __ATTRIBUTE___FORMAT_OK
232*3340d773SGleb Smirnoff 		    __attribute__((format (printf, 2, 3)))
233*3340d773SGleb Smirnoff #endif /* __ATTRIBUTE___FORMAT_OK */
234*3340d773SGleb Smirnoff 		    ;
235*3340d773SGleb Smirnoff static void	ndo_warning(netdissect_options *ndo, const char *fmt, ...)
236*3340d773SGleb Smirnoff #ifdef __ATTRIBUTE___FORMAT_OK
237*3340d773SGleb Smirnoff 		    __attribute__((format (printf, 2, 3)))
238*3340d773SGleb Smirnoff #endif /* __ATTRIBUTE___FORMAT_OK */
239*3340d773SGleb Smirnoff 		    ;
240*3340d773SGleb Smirnoff 
241*3340d773SGleb Smirnoff static int	ndo_printf(netdissect_options *ndo, const char *fmt, ...)
242*3340d773SGleb Smirnoff #ifdef __ATTRIBUTE___FORMAT_OK
243*3340d773SGleb Smirnoff 		     __attribute ((format (printf, 2, 3)))
244*3340d773SGleb Smirnoff #endif /* __ATTRIBUTE___FORMAT_OK */
245*3340d773SGleb Smirnoff 		     ;
246*3340d773SGleb Smirnoff 
247*3340d773SGleb Smirnoff void
248*3340d773SGleb Smirnoff init_print(netdissect_options *ndo, uint32_t localnet, uint32_t mask,
249*3340d773SGleb Smirnoff     uint32_t timezone_offset)
250*3340d773SGleb Smirnoff {
251*3340d773SGleb Smirnoff 
252*3340d773SGleb Smirnoff 	thiszone = timezone_offset;
253*3340d773SGleb Smirnoff 	init_addrtoname(ndo, localnet, mask);
254*3340d773SGleb Smirnoff 	init_checksum();
255*3340d773SGleb Smirnoff }
256*3340d773SGleb Smirnoff 
257*3340d773SGleb Smirnoff if_printer
258*3340d773SGleb Smirnoff lookup_printer(int type)
259*3340d773SGleb Smirnoff {
260*3340d773SGleb Smirnoff 	const struct printer *p;
261*3340d773SGleb Smirnoff 
262*3340d773SGleb Smirnoff 	for (p = printers; p->f; ++p)
263*3340d773SGleb Smirnoff 		if (type == p->type)
264*3340d773SGleb Smirnoff 			return p->f;
265*3340d773SGleb Smirnoff 
266*3340d773SGleb Smirnoff #if defined(DLT_USER2) && defined(DLT_PKTAP)
267*3340d773SGleb Smirnoff 	/*
268*3340d773SGleb Smirnoff 	 * Apple incorrectly chose to use DLT_USER2 for their PKTAP
269*3340d773SGleb Smirnoff 	 * header.
270*3340d773SGleb Smirnoff 	 *
271*3340d773SGleb Smirnoff 	 * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin-
272*3340d773SGleb Smirnoff 	 * based OSes or the same value as LINKTYPE_PKTAP as it is on
273*3340d773SGleb Smirnoff 	 * other OSes, to LINKTYPE_PKTAP, so files written with
274*3340d773SGleb Smirnoff 	 * this version of libpcap for a DLT_PKTAP capture have a link-
275*3340d773SGleb Smirnoff 	 * layer header type of LINKTYPE_PKTAP.
276*3340d773SGleb Smirnoff 	 *
277*3340d773SGleb Smirnoff 	 * However, files written on OS X Mavericks for a DLT_PKTAP
278*3340d773SGleb Smirnoff 	 * capture have a link-layer header type of LINKTYPE_USER2.
279*3340d773SGleb Smirnoff 	 * If we don't have a printer for DLT_USER2, and type is
280*3340d773SGleb Smirnoff 	 * DLT_USER2, we look up the printer for DLT_PKTAP and use
281*3340d773SGleb Smirnoff 	 * that.
282*3340d773SGleb Smirnoff 	 */
283*3340d773SGleb Smirnoff 	if (type == DLT_USER2) {
284*3340d773SGleb Smirnoff 		for (p = printers; p->f; ++p)
285*3340d773SGleb Smirnoff 			if (DLT_PKTAP == p->type)
286*3340d773SGleb Smirnoff 				return p->f;
287*3340d773SGleb Smirnoff 	}
288*3340d773SGleb Smirnoff #endif
289*3340d773SGleb Smirnoff 
290*3340d773SGleb Smirnoff 	return NULL;
291*3340d773SGleb Smirnoff 	/* NOTREACHED */
292*3340d773SGleb Smirnoff }
293*3340d773SGleb Smirnoff 
294*3340d773SGleb Smirnoff int
295*3340d773SGleb Smirnoff has_printer(int type)
296*3340d773SGleb Smirnoff {
297*3340d773SGleb Smirnoff 	return (lookup_printer(type) != NULL);
298*3340d773SGleb Smirnoff }
299*3340d773SGleb Smirnoff 
300*3340d773SGleb Smirnoff if_printer
301*3340d773SGleb Smirnoff get_if_printer(netdissect_options *ndo, int type)
302*3340d773SGleb Smirnoff {
303*3340d773SGleb Smirnoff 	const char *dltname;
304*3340d773SGleb Smirnoff 	if_printer printer;
305*3340d773SGleb Smirnoff 
306*3340d773SGleb Smirnoff 	printer = lookup_printer(type);
307*3340d773SGleb Smirnoff 	if (printer == NULL) {
308*3340d773SGleb Smirnoff 		dltname = pcap_datalink_val_to_name(type);
309*3340d773SGleb Smirnoff 		if (dltname != NULL)
310*3340d773SGleb Smirnoff 			(*ndo->ndo_error)(ndo,
311*3340d773SGleb Smirnoff 					  "packet printing is not supported for link type %s: use -w",
312*3340d773SGleb Smirnoff 					  dltname);
313*3340d773SGleb Smirnoff 		else
314*3340d773SGleb Smirnoff 			(*ndo->ndo_error)(ndo,
315*3340d773SGleb Smirnoff 					  "packet printing is not supported for link type %d: use -w", type);
316*3340d773SGleb Smirnoff 	}
317*3340d773SGleb Smirnoff 	return printer;
318*3340d773SGleb Smirnoff }
319*3340d773SGleb Smirnoff 
320*3340d773SGleb Smirnoff void
321*3340d773SGleb Smirnoff pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
322*3340d773SGleb Smirnoff     const u_char *sp, u_int packets_captured)
323*3340d773SGleb Smirnoff {
324*3340d773SGleb Smirnoff 	u_int hdrlen;
325*3340d773SGleb Smirnoff 
326*3340d773SGleb Smirnoff 	if(ndo->ndo_packet_number)
327*3340d773SGleb Smirnoff 		ND_PRINT((ndo, "%5u  ", packets_captured));
328*3340d773SGleb Smirnoff 
329*3340d773SGleb Smirnoff 	ts_print(ndo, &h->ts);
330*3340d773SGleb Smirnoff 
331*3340d773SGleb Smirnoff 	/*
332*3340d773SGleb Smirnoff 	 * Some printers want to check that they're not walking off the
333*3340d773SGleb Smirnoff 	 * end of the packet.
334*3340d773SGleb Smirnoff 	 * Rather than pass it all the way down, we set this member
335*3340d773SGleb Smirnoff 	 * of the netdissect_options structure.
336*3340d773SGleb Smirnoff 	 */
337*3340d773SGleb Smirnoff 	ndo->ndo_snapend = sp + h->caplen;
338*3340d773SGleb Smirnoff 
339*3340d773SGleb Smirnoff         hdrlen = (ndo->ndo_if_printer)(ndo, h, sp);
340*3340d773SGleb Smirnoff 
341*3340d773SGleb Smirnoff 	/*
342*3340d773SGleb Smirnoff 	 * Restore the original snapend, as a printer might have
343*3340d773SGleb Smirnoff 	 * changed it.
344*3340d773SGleb Smirnoff 	 */
345*3340d773SGleb Smirnoff 	ndo->ndo_snapend = sp + h->caplen;
346*3340d773SGleb Smirnoff 	if (ndo->ndo_Xflag) {
347*3340d773SGleb Smirnoff 		/*
348*3340d773SGleb Smirnoff 		 * Print the raw packet data in hex and ASCII.
349*3340d773SGleb Smirnoff 		 */
350*3340d773SGleb Smirnoff 		if (ndo->ndo_Xflag > 1) {
351*3340d773SGleb Smirnoff 			/*
352*3340d773SGleb Smirnoff 			 * Include the link-layer header.
353*3340d773SGleb Smirnoff 			 */
354*3340d773SGleb Smirnoff 			hex_and_ascii_print(ndo, "\n\t", sp, h->caplen);
355*3340d773SGleb Smirnoff 		} else {
356*3340d773SGleb Smirnoff 			/*
357*3340d773SGleb Smirnoff 			 * Don't include the link-layer header - and if
358*3340d773SGleb Smirnoff 			 * we have nothing past the link-layer header,
359*3340d773SGleb Smirnoff 			 * print nothing.
360*3340d773SGleb Smirnoff 			 */
361*3340d773SGleb Smirnoff 			if (h->caplen > hdrlen)
362*3340d773SGleb Smirnoff 				hex_and_ascii_print(ndo, "\n\t", sp + hdrlen,
363*3340d773SGleb Smirnoff 				    h->caplen - hdrlen);
364*3340d773SGleb Smirnoff 		}
365*3340d773SGleb Smirnoff 	} else if (ndo->ndo_xflag) {
366*3340d773SGleb Smirnoff 		/*
367*3340d773SGleb Smirnoff 		 * Print the raw packet data in hex.
368*3340d773SGleb Smirnoff 		 */
369*3340d773SGleb Smirnoff 		if (ndo->ndo_xflag > 1) {
370*3340d773SGleb Smirnoff 			/*
371*3340d773SGleb Smirnoff 			 * Include the link-layer header.
372*3340d773SGleb Smirnoff 			 */
373*3340d773SGleb Smirnoff                         hex_print(ndo, "\n\t", sp, h->caplen);
374*3340d773SGleb Smirnoff 		} else {
375*3340d773SGleb Smirnoff 			/*
376*3340d773SGleb Smirnoff 			 * Don't include the link-layer header - and if
377*3340d773SGleb Smirnoff 			 * we have nothing past the link-layer header,
378*3340d773SGleb Smirnoff 			 * print nothing.
379*3340d773SGleb Smirnoff 			 */
380*3340d773SGleb Smirnoff 			if (h->caplen > hdrlen)
381*3340d773SGleb Smirnoff 				hex_print(ndo, "\n\t", sp + hdrlen,
382*3340d773SGleb Smirnoff                                           h->caplen - hdrlen);
383*3340d773SGleb Smirnoff 		}
384*3340d773SGleb Smirnoff 	} else if (ndo->ndo_Aflag) {
385*3340d773SGleb Smirnoff 		/*
386*3340d773SGleb Smirnoff 		 * Print the raw packet data in ASCII.
387*3340d773SGleb Smirnoff 		 */
388*3340d773SGleb Smirnoff 		if (ndo->ndo_Aflag > 1) {
389*3340d773SGleb Smirnoff 			/*
390*3340d773SGleb Smirnoff 			 * Include the link-layer header.
391*3340d773SGleb Smirnoff 			 */
392*3340d773SGleb Smirnoff 			ascii_print(ndo, sp, h->caplen);
393*3340d773SGleb Smirnoff 		} else {
394*3340d773SGleb Smirnoff 			/*
395*3340d773SGleb Smirnoff 			 * Don't include the link-layer header - and if
396*3340d773SGleb Smirnoff 			 * we have nothing past the link-layer header,
397*3340d773SGleb Smirnoff 			 * print nothing.
398*3340d773SGleb Smirnoff 			 */
399*3340d773SGleb Smirnoff 			if (h->caplen > hdrlen)
400*3340d773SGleb Smirnoff 				ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen);
401*3340d773SGleb Smirnoff 		}
402*3340d773SGleb Smirnoff 	}
403*3340d773SGleb Smirnoff 
404*3340d773SGleb Smirnoff 	ND_PRINT((ndo, "\n"));
405*3340d773SGleb Smirnoff }
406*3340d773SGleb Smirnoff 
407*3340d773SGleb Smirnoff /*
408*3340d773SGleb Smirnoff  * By default, print the specified data out in hex and ASCII.
409*3340d773SGleb Smirnoff  */
410*3340d773SGleb Smirnoff static void
411*3340d773SGleb Smirnoff ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length)
412*3340d773SGleb Smirnoff {
413*3340d773SGleb Smirnoff 	hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */
414*3340d773SGleb Smirnoff }
415*3340d773SGleb Smirnoff 
416*3340d773SGleb Smirnoff /* VARARGS */
417*3340d773SGleb Smirnoff static void
418*3340d773SGleb Smirnoff ndo_error(netdissect_options *ndo, const char *fmt, ...)
419*3340d773SGleb Smirnoff {
420*3340d773SGleb Smirnoff 	va_list ap;
421*3340d773SGleb Smirnoff 
422*3340d773SGleb Smirnoff 	if(ndo->program_name)
423*3340d773SGleb Smirnoff 		(void)fprintf(stderr, "%s: ", ndo->program_name);
424*3340d773SGleb Smirnoff 	va_start(ap, fmt);
425*3340d773SGleb Smirnoff 	(void)vfprintf(stderr, fmt, ap);
426*3340d773SGleb Smirnoff 	va_end(ap);
427*3340d773SGleb Smirnoff 	if (*fmt) {
428*3340d773SGleb Smirnoff 		fmt += strlen(fmt);
429*3340d773SGleb Smirnoff 		if (fmt[-1] != '\n')
430*3340d773SGleb Smirnoff 			(void)fputc('\n', stderr);
431*3340d773SGleb Smirnoff 	}
432*3340d773SGleb Smirnoff 	nd_cleanup();
433*3340d773SGleb Smirnoff 	exit(1);
434*3340d773SGleb Smirnoff 	/* NOTREACHED */
435*3340d773SGleb Smirnoff }
436*3340d773SGleb Smirnoff 
437*3340d773SGleb Smirnoff /* VARARGS */
438*3340d773SGleb Smirnoff static void
439*3340d773SGleb Smirnoff ndo_warning(netdissect_options *ndo, const char *fmt, ...)
440*3340d773SGleb Smirnoff {
441*3340d773SGleb Smirnoff 	va_list ap;
442*3340d773SGleb Smirnoff 
443*3340d773SGleb Smirnoff 	if(ndo->program_name)
444*3340d773SGleb Smirnoff 		(void)fprintf(stderr, "%s: ", ndo->program_name);
445*3340d773SGleb Smirnoff 	(void)fprintf(stderr, "WARNING: ");
446*3340d773SGleb Smirnoff 	va_start(ap, fmt);
447*3340d773SGleb Smirnoff 	(void)vfprintf(stderr, fmt, ap);
448*3340d773SGleb Smirnoff 	va_end(ap);
449*3340d773SGleb Smirnoff 	if (*fmt) {
450*3340d773SGleb Smirnoff 		fmt += strlen(fmt);
451*3340d773SGleb Smirnoff 		if (fmt[-1] != '\n')
452*3340d773SGleb Smirnoff 			(void)fputc('\n', stderr);
453*3340d773SGleb Smirnoff 	}
454*3340d773SGleb Smirnoff }
455*3340d773SGleb Smirnoff 
456*3340d773SGleb Smirnoff static int
457*3340d773SGleb Smirnoff ndo_printf(netdissect_options *ndo, const char *fmt, ...)
458*3340d773SGleb Smirnoff {
459*3340d773SGleb Smirnoff 	va_list args;
460*3340d773SGleb Smirnoff 	int ret;
461*3340d773SGleb Smirnoff 
462*3340d773SGleb Smirnoff 	va_start(args, fmt);
463*3340d773SGleb Smirnoff 	ret = vfprintf(stdout, fmt, args);
464*3340d773SGleb Smirnoff 	va_end(args);
465*3340d773SGleb Smirnoff 
466*3340d773SGleb Smirnoff 	if (ret < 0)
467*3340d773SGleb Smirnoff 		ndo_error(ndo, "Unable to write output: %s", pcap_strerror(errno));
468*3340d773SGleb Smirnoff 	return (ret);
469*3340d773SGleb Smirnoff }
470*3340d773SGleb Smirnoff 
471*3340d773SGleb Smirnoff void
472*3340d773SGleb Smirnoff ndo_set_function_pointers(netdissect_options *ndo)
473*3340d773SGleb Smirnoff {
474*3340d773SGleb Smirnoff 	ndo->ndo_default_print=ndo_default_print;
475*3340d773SGleb Smirnoff 	ndo->ndo_printf=ndo_printf;
476*3340d773SGleb Smirnoff 	ndo->ndo_error=ndo_error;
477*3340d773SGleb Smirnoff 	ndo->ndo_warning=ndo_warning;
478*3340d773SGleb Smirnoff }
479*3340d773SGleb Smirnoff /*
480*3340d773SGleb Smirnoff  * Local Variables:
481*3340d773SGleb Smirnoff  * c-style: whitesmith
482*3340d773SGleb Smirnoff  * c-basic-offset: 8
483*3340d773SGleb Smirnoff  * End:
484*3340d773SGleb Smirnoff  */
485