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