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