xref: /freebsd/contrib/tcpdump/tcpdump.c (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
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 #ifndef lint
29 static const char copyright[] _U_ =
30     "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
31 The Regents of the University of California.  All rights reserved.\n";
32 static const char rcsid[] _U_ =
33     "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.216.2.10 2004/03/17 19:47:48 guy Exp $ (LBL)";
34 #endif
35 
36 /* $FreeBSD$ */
37 
38 /*
39  * tcpdump - monitor tcp/ip traffic on an ethernet.
40  *
41  * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
42  * Mercilessly hacked and occasionally improved since then via the
43  * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
44  */
45 
46 #ifdef HAVE_CONFIG_H
47 #include "config.h"
48 #endif
49 
50 #include <tcpdump-stdinc.h>
51 
52 #ifdef WIN32
53 #include "getopt.h"
54 #include "w32_fzs.h"
55 extern int strcasecmp (const char *__s1, const char *__s2);
56 extern int SIZE_BUF;
57 #define off_t long
58 #define uint UINT
59 #endif /* WIN32 */
60 
61 #include <pcap.h>
62 #include <signal.h>
63 #include <stdio.h>
64 #include <stdlib.h>
65 #include <string.h>
66 
67 #include "interface.h"
68 #include "addrtoname.h"
69 #include "machdep.h"
70 #include "setsignal.h"
71 #include "gmt2local.h"
72 #include "pcap-missing.h"
73 
74 int dflag;			/* print filter code */
75 int eflag;			/* print ethernet header */
76 int fflag;			/* don't translate "foreign" IP address */
77 int Lflag;			/* list available data link types and exit */
78 int nflag;			/* leave addresses as numbers */
79 int Nflag;			/* remove domains from printed host names */
80 int Oflag = 1;			/* run filter code optimizer */
81 int pflag;			/* don't go promiscuous */
82 int qflag;			/* quick (shorter) output */
83 int Rflag = 1;			/* print sequence # field in AH/ESP*/
84 int sflag = 0;			/* use the libsmi to translate OIDs */
85 int Sflag;			/* print raw TCP sequence numbers */
86 int tflag = 1;			/* print packet arrival time */
87 int Uflag = 0;			/* "unbuffered" output of dump files */
88 int uflag = 0;			/* Print undecoded NFS handles */
89 int vflag;			/* verbose */
90 int xflag;			/* print packet in hex */
91 int Xflag;			/* print packet in ascii as well as hex */
92 off_t Cflag = 0;                /* rotate dump files after this many bytes */
93 int Aflag = 0;                  /* print packet only in ascii observing LF, CR, TAB, SPACE */
94 int dlt = -1;		/* if != -1, ask libpcap for the DLT it names */
95 
96 const char *dlt_name = NULL;
97 
98 char *espsecret = NULL;		/* ESP secret key */
99 
100 int packettype;
101 
102 static int infodelay;
103 static int infoprint;
104 
105 char *program_name;
106 
107 int32_t thiszone;		/* seconds offset from gmt to local time */
108 
109 /* Forwards */
110 static RETSIGTYPE cleanup(int);
111 static void usage(void) __attribute__((noreturn));
112 static void show_dlts_and_exit(pcap_t *pd) __attribute__((noreturn));
113 
114 static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
115 static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
116 static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
117 
118 #ifdef SIGINFO
119 RETSIGTYPE requestinfo(int);
120 #endif
121 
122 static void info(int);
123 static u_int packets_captured;
124 
125 /* Length of saved portion of packet. */
126 int snaplen = DEFAULT_SNAPLEN;
127 
128 typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *);
129 
130 struct printer {
131 	if_printer f;
132 	int type;
133 };
134 
135 static struct printer printers[] = {
136 	{ arcnet_if_print,	DLT_ARCNET },
137 #ifdef DLT_ARCNET_LINUX
138 	{ arcnet_linux_if_print, DLT_ARCNET_LINUX },
139 #endif
140 	{ ether_if_print,	DLT_EN10MB },
141 	{ token_if_print,	DLT_IEEE802 },
142 #ifdef DLT_LANE8023
143 	{ lane_if_print,        DLT_LANE8023 },
144 #endif
145 #ifdef DLT_CIP
146 	{ cip_if_print,         DLT_CIP },
147 #endif
148 #ifdef DLT_ATM_CLIP
149 	{ cip_if_print,         DLT_ATM_CLIP },
150 #endif
151 	{ sl_if_print,		DLT_SLIP },
152 #ifdef DLT_SLIP_BSDOS
153 	{ sl_bsdos_if_print,	DLT_SLIP_BSDOS },
154 #endif
155 	{ ppp_if_print,		DLT_PPP },
156 #ifdef DLT_PPP_BSDOS
157 	{ ppp_bsdos_if_print,	DLT_PPP_BSDOS },
158 #endif
159 	{ fddi_if_print,	DLT_FDDI },
160 	{ null_if_print,	DLT_NULL },
161 #ifdef DLT_LOOP
162 	{ null_if_print,	DLT_LOOP },
163 #endif
164 	{ raw_if_print,		DLT_RAW },
165 	{ atm_if_print,		DLT_ATM_RFC1483 },
166 #ifdef DLT_C_HDLC
167 	{ chdlc_if_print,	DLT_C_HDLC },
168 #endif
169 #ifdef DLT_HDLC
170 	{ chdlc_if_print,	DLT_HDLC },
171 #endif
172 #ifdef DLT_PPP_SERIAL
173 	{ ppp_hdlc_if_print,    DLT_PPP_SERIAL },
174 #endif
175 #ifdef DLT_PPP_ETHER
176 	{ pppoe_if_print,	DLT_PPP_ETHER },
177 #endif
178 #ifdef DLT_LINUX_SLL
179 	{ sll_if_print,		DLT_LINUX_SLL },
180 #endif
181 #ifdef DLT_IEEE802_11
182 	{ ieee802_11_if_print,	DLT_IEEE802_11},
183 #endif
184 #ifdef DLT_LTALK
185 	{ ltalk_if_print,	DLT_LTALK },
186 #endif
187 #ifdef DLT_PFLOG
188 	{ pflog_if_print, 	DLT_PFLOG },
189 #endif
190 #ifdef DLT_FR
191 	{ fr_if_print,		DLT_FR },
192 #endif
193 #ifdef DLT_FRELAY
194 	{ fr_if_print,		DLT_FRELAY },
195 #endif
196 #ifdef DLT_SUNATM
197 	{ sunatm_if_print,	DLT_SUNATM },
198 #endif
199 #ifdef DLT_IP_OVER_FC
200 	{ ipfc_if_print,	DLT_IP_OVER_FC },
201 #endif
202 #ifdef DLT_PRISM_HEADER
203 	{ prism_if_print,	DLT_PRISM_HEADER },
204 #endif
205 #ifdef DLT_IEEE802_11_RADIO
206 	{ ieee802_11_radio_if_print,	DLT_IEEE802_11_RADIO },
207 #endif
208 #ifdef DLT_ENC
209 	{ enc_if_print, 	DLT_ENC },
210 #endif
211 #ifdef DLT_APPLE_IP_OVER_IEEE1394
212 	{ ap1394_if_print,	DLT_APPLE_IP_OVER_IEEE1394 },
213 #endif
214 	{ NULL,			0 },
215 };
216 
217 static if_printer
218 lookup_printer(int type)
219 {
220 	struct printer *p;
221 
222 	for (p = printers; p->f; ++p)
223 		if (type == p->type)
224 			return p->f;
225 
226 	return NULL;
227 	/* NOTREACHED */
228 }
229 
230 static pcap_t *pd;
231 
232 extern int optind;
233 extern int opterr;
234 extern char *optarg;
235 
236 struct print_info {
237 	if_printer printer;
238 };
239 
240 struct dump_info {
241 	char	*WFileName;
242 	pcap_t	*pd;
243 	pcap_dumper_t *p;
244 };
245 
246 static void
247 show_dlts_and_exit(pcap_t *pd)
248 {
249 	int n_dlts;
250 	int *dlts = 0;
251 	const char *dlt_name;
252 
253 	n_dlts = pcap_list_datalinks(pd, &dlts);
254 	if (n_dlts < 0)
255 		error("%s", pcap_geterr(pd));
256 	else if (n_dlts == 0 || !dlts)
257 		error("No data link types.");
258 
259 	(void) fprintf(stderr, "Data link types (use option -y to set):\n");
260 
261 	while (--n_dlts >= 0) {
262 		dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]);
263 		if (dlt_name != NULL) {
264 			(void) fprintf(stderr, "  %s (%s)", dlt_name,
265 			    pcap_datalink_val_to_description(dlts[n_dlts]));
266 
267 			/*
268 			 * OK, does tcpdump handle that type?
269 			 */
270 			if (lookup_printer(dlts[n_dlts]) == NULL)
271 				(void) fprintf(stderr, " (not supported)");
272 			putchar('\n');
273 		} else {
274 			(void) fprintf(stderr, "  DLT %d (not supported)\n",
275 			    dlts[n_dlts]);
276 		}
277 	}
278 	free(dlts);
279 	exit(0);
280 }
281 
282 /*
283  * Set up flags that might or might not be supported depending on the
284  * version of libpcap we're using.
285  */
286 #ifdef WIN32
287 #define B_FLAG		"B:"
288 #define B_FLAG_USAGE	" [ -B size ]"
289 #else /* WIN32 */
290 #define B_FLAG
291 #define B_FLAG_USAGE
292 #endif /* WIN32 */
293 
294 #ifdef HAVE_PCAP_FINDALLDEVS
295 #define D_FLAG	"D"
296 #else
297 #define D_FLAG
298 #endif
299 
300 #ifdef HAVE_PCAP_DUMP_FLUSH
301 #define U_FLAG	"U"
302 #else
303 #define U_FLAG
304 #endif
305 
306 int
307 main(int argc, char **argv)
308 {
309 	register int cnt, op, i;
310 	bpf_u_int32 localnet, netmask;
311 	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
312 	pcap_handler callback;
313 	int type;
314 	struct bpf_program fcode;
315 #ifndef WIN32
316 	RETSIGTYPE (*oldhandler)(int);
317 #endif
318 	struct print_info printinfo;
319 	struct dump_info dumpinfo;
320 	u_char *pcap_userdata;
321 	char ebuf[PCAP_ERRBUF_SIZE];
322 #ifdef HAVE_PCAP_FINDALLDEVS
323 	pcap_if_t *devpointer;
324 	int devnum;
325 #endif
326 	int status;
327 #ifdef WIN32
328 	u_int UserBufferSize = 1000000;
329 	if(wsockinit() != 0) return 1;
330 #endif /* WIN32 */
331 
332 	cnt = -1;
333 	device = NULL;
334 	infile = NULL;
335 	RFileName = NULL;
336 	WFileName = NULL;
337 	if ((cp = strrchr(argv[0], '/')) != NULL)
338 		program_name = cp + 1;
339 	else
340 		program_name = argv[0];
341 
342 	if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
343 		error("%s", ebuf);
344 
345 #ifdef LIBSMI
346 	smiInit("tcpdump");
347 #endif
348 
349 	opterr = 0;
350 	while (
351 	    (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nNOpqr:Rs:StT:u" U_FLAG "vw:xXy:Y")) != -1)
352 		switch (op) {
353 
354 		case 'a':
355 			/* compatibility for old -a */
356 			break;
357 
358 		case 'A':
359 			++xflag;
360 			++Xflag;
361 			++Aflag;
362 			break;
363 
364 #ifdef WIN32
365 		case 'B':
366 			UserBufferSize = atoi(optarg)*1024;
367 			if (UserBufferSize < 0)
368 				error("invalid packet buffer size %s", optarg);
369 			break;
370 #endif /* WIN32 */
371 
372 		case 'c':
373 			cnt = atoi(optarg);
374 			if (cnt <= 0)
375 				error("invalid packet count %s", optarg);
376 			break;
377 
378 		case 'C':
379 			Cflag = atoi(optarg) * 1000000;
380 			if (Cflag < 0)
381 				error("invalid file size %s", optarg);
382 			break;
383 
384 		case 'd':
385 			++dflag;
386 			break;
387 
388 #ifdef HAVE_PCAP_FINDALLDEVS
389 		case 'D':
390 			if (pcap_findalldevs(&devpointer, ebuf) < 0)
391 				error("%s", ebuf);
392 			else {
393 				for (i = 0; devpointer != 0; i++) {
394 					printf("%d.%s", i+1, devpointer->name);
395 					if (devpointer->description != NULL)
396 						printf(" (%s)", devpointer->description);
397 					printf("\n");
398 					devpointer = devpointer->next;
399 				}
400 			}
401 			return 0;
402 #endif /* HAVE_PCAP_FINDALLDEVS */
403 
404 		case 'L':
405 			Lflag++;
406 			break;
407 
408 		case 'e':
409 			++eflag;
410 			break;
411 
412 		case 'E':
413 #ifndef HAVE_LIBCRYPTO
414 			warning("crypto code not compiled in");
415 #endif
416 			espsecret = optarg;
417 			break;
418 
419 		case 'f':
420 			++fflag;
421 			break;
422 
423 		case 'F':
424 			infile = optarg;
425 			break;
426 
427 		case 'i':
428 			if (optarg[0] == '0' && optarg[1] == 0)
429 				error("Invalid adapter index");
430 
431 #ifdef HAVE_PCAP_FINDALLDEVS
432 			/*
433 			 * If the argument is a number, treat it as
434 			 * an index into the list of adapters, as
435 			 * printed by "tcpdump -D".
436 			 *
437 			 * This should be OK on UNIX systems, as interfaces
438 			 * shouldn't have names that begin with digits.
439 			 * It can be useful on Windows, where more than
440 			 * one interface can have the same name.
441 			 */
442 			if ((devnum = atoi(optarg)) != 0) {
443 				if (devnum < 0)
444 					error("Invalid adapter index");
445 
446 				if (pcap_findalldevs(&devpointer, ebuf) < 0)
447 					error("%s", ebuf);
448 				else {
449 					for (i = 0; i < devnum-1; i++){
450 						devpointer = devpointer->next;
451 						if (devpointer == NULL)
452 							error("Invalid adapter index");
453 					}
454 				}
455 				device = devpointer->name;
456 				break;
457 			}
458 #endif /* HAVE_PCAP_FINDALLDEVS */
459 			device = optarg;
460 			break;
461 
462 		case 'l':
463 #ifdef WIN32
464 			/*
465 			 * _IOLBF is the same as _IOFBF in Microsoft's C
466 			 * libraries; the only alternative they offer
467 			 * is _IONBF.
468 			 *
469 			 * XXX - this should really be checking for MSVC++,
470 			 * not WIN32, if, for example, MinGW has its own
471 			 * C library that is more UNIX-compatible.
472 			 */
473 			setvbuf(stdout, NULL, _IONBF, 0);
474 #else /* WIN32 */
475 #ifdef HAVE_SETLINEBUF
476 			setlinebuf(stdout);
477 #else
478 			setvbuf(stdout, NULL, _IOLBF, 0);
479 #endif
480 #endif /* WIN32 */
481 			break;
482 
483 		case 'n':
484 			++nflag;
485 			break;
486 
487 		case 'N':
488 			++Nflag;
489 			break;
490 
491 		case 'm':
492 #ifdef LIBSMI
493 		        if (smiLoadModule(optarg) == 0) {
494 				error("could not load MIB module %s", optarg);
495 		        }
496 			sflag = 1;
497 #else
498 			(void)fprintf(stderr, "%s: ignoring option `-m %s' ",
499 				      program_name, optarg);
500 			(void)fprintf(stderr, "(no libsmi support)\n");
501 #endif
502 			break;
503 
504 		case 'O':
505 			Oflag = 0;
506 			break;
507 
508 		case 'p':
509 			++pflag;
510 			break;
511 
512 		case 'q':
513 			++qflag;
514 			break;
515 
516 		case 'r':
517 			RFileName = optarg;
518 			break;
519 
520 		case 'R':
521 			Rflag = 0;
522 			break;
523 
524 		case 's': {
525 			char *end;
526 
527 			snaplen = strtol(optarg, &end, 0);
528 			if (optarg == end || *end != '\0'
529 			    || snaplen < 0 || snaplen > 65535)
530 				error("invalid snaplen %s", optarg);
531 			else if (snaplen == 0)
532 				snaplen = 65535;
533 			break;
534 		}
535 
536 		case 'S':
537 			++Sflag;
538 			break;
539 
540 		case 't':
541 			--tflag;
542 			break;
543 
544 		case 'T':
545 			if (strcasecmp(optarg, "vat") == 0)
546 				packettype = PT_VAT;
547 			else if (strcasecmp(optarg, "wb") == 0)
548 				packettype = PT_WB;
549 			else if (strcasecmp(optarg, "rpc") == 0)
550 				packettype = PT_RPC;
551 			else if (strcasecmp(optarg, "rtp") == 0)
552 				packettype = PT_RTP;
553 			else if (strcasecmp(optarg, "rtcp") == 0)
554 				packettype = PT_RTCP;
555 			else if (strcasecmp(optarg, "snmp") == 0)
556 				packettype = PT_SNMP;
557 			else if (strcasecmp(optarg, "cnfp") == 0)
558 				packettype = PT_CNFP;
559 			else if (strcasecmp(optarg, "tftp") == 0)
560 				packettype = PT_TFTP;
561 			else if (strcasecmp(optarg, "aodv") == 0)
562 				packettype = PT_AODV;
563 			else
564 				error("unknown packet type `%s'", optarg);
565 			break;
566 
567 		case 'u':
568 			++uflag;
569 			break;
570 
571 #ifdef HAVE_PCAP_DUMP_FLUSH
572 		case 'U':
573 			++Uflag;
574 			break;
575 #endif
576 
577 		case 'v':
578 			++vflag;
579 			break;
580 
581 		case 'w':
582 			WFileName = optarg;
583 			break;
584 
585 		case 'x':
586 			++xflag;
587 			break;
588 
589 		case 'X':
590 		        ++xflag;
591 			++Xflag;
592 			break;
593 
594 		case 'y':
595 			dlt_name = optarg;
596 			dlt = pcap_datalink_name_to_val(dlt_name);
597 			if (dlt < 0)
598 				error("invalid data link type %s", dlt_name);
599 			break;
600 
601 #if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
602 		case 'Y':
603 			{
604 			/* Undocumented flag */
605 #ifdef HAVE_PCAP_DEBUG
606 			extern int pcap_debug;
607 			pcap_debug = 1;
608 #else
609 			extern int yydebug;
610 			yydebug = 1;
611 #endif
612 			}
613 			break;
614 #endif
615 		default:
616 			usage();
617 			/* NOTREACHED */
618 		}
619 
620 	if (tflag > 0)
621 		thiszone = gmt2local(0);
622 
623 	if (RFileName != NULL) {
624 		int dlt;
625 		const char *dlt_name;
626 
627 #ifndef WIN32
628 		/*
629 		 * We don't need network access, so relinquish any set-UID
630 		 * or set-GID privileges we have (if any).
631 		 *
632 		 * We do *not* want set-UID privileges when opening a
633 		 * trace file, as that might let the user read other
634 		 * people's trace files (especially if we're set-UID
635 		 * root).
636 		 */
637 		setuid(getuid());
638 #endif /* WIN32 */
639 		pd = pcap_open_offline(RFileName, ebuf);
640 		if (pd == NULL)
641 			error("%s", ebuf);
642 		dlt = pcap_datalink(pd);
643 		dlt_name = pcap_datalink_val_to_name(dlt);
644 		if (dlt_name == NULL) {
645 			fprintf(stderr, "reading from file %s, link-type %u\n",
646 			    RFileName, dlt);
647 		} else {
648 			fprintf(stderr,
649 			    "reading from file %s, link-type %s (%s)\n",
650 			    RFileName, dlt_name,
651 			    pcap_datalink_val_to_description(dlt));
652 		}
653 		localnet = 0;
654 		netmask = 0;
655 		if (fflag != 0)
656 			error("-f and -r options are incompatible");
657 	} else {
658 		if (device == NULL) {
659 			device = pcap_lookupdev(ebuf);
660 			if (device == NULL)
661 				error("%s", ebuf);
662 		}
663 #ifdef WIN32
664 		if(IsTextUnicode(device,
665 			wcslen((short*)device),                // Device always ends with a double \0, so this way to determine its
666 													// length should be always valid
667 			NULL))
668 		{
669 			fprintf(stderr, "%s: listening on %ws\n", program_name, device);
670 		}
671 		else
672 		{
673 			fprintf(stderr, "%s: listening on %s\n", program_name, device);
674 		}
675 
676 		fflush(stderr);
677 #endif /* WIN32 */
678 		*ebuf = '\0';
679 		pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
680 		if (pd == NULL)
681 			error("%s", ebuf);
682 		else if (*ebuf)
683 			warning("%s", ebuf);
684 		if (Lflag)
685 			show_dlts_and_exit(pd);
686 		if (dlt >= 0) {
687 #ifdef HAVE_PCAP_SET_DATALINK
688 			if (pcap_set_datalink(pd, dlt) < 0)
689 				error("%s", pcap_geterr(pd));
690 #else
691 			/*
692 			 * We don't actually support changing the
693 			 * data link type, so we only let them
694 			 * set it to what it already is.
695 			 */
696 			if (dlt != pcap_datalink(pd)) {
697 				error("%s is not one of the DLTs supported by this device\n",
698 				    dlt_name);
699 			}
700 #endif
701 			(void)fprintf(stderr, "%s: data link type %s\n",
702 			              program_name, dlt_name);
703 			(void)fflush(stderr);
704 		}
705 		i = pcap_snapshot(pd);
706 		if (snaplen < i) {
707 			warning("snaplen raised from %d to %d", snaplen, i);
708 			snaplen = i;
709 		}
710 		if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
711 			localnet = 0;
712 			netmask = 0;
713 			warning("%s", ebuf);
714 		}
715 		/*
716 		 * Let user own process after socket has been opened.
717 		 */
718 #ifndef WIN32
719 		setuid(getuid());
720 #endif /* WIN32 */
721 	}
722 	if (infile)
723 		cmdbuf = read_infile(infile);
724 	else
725 		cmdbuf = copy_argv(&argv[optind]);
726 
727 	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
728 		error("%s", pcap_geterr(pd));
729 	if (dflag) {
730 		bpf_dump(&fcode, dflag);
731 		pcap_close(pd);
732 		exit(0);
733 	}
734 	init_addrtoname(localnet, netmask);
735 
736 #ifndef WIN32
737 	(void)setsignal(SIGPIPE, cleanup);
738 #endif /* WIN32 */
739 	(void)setsignal(SIGTERM, cleanup);
740 	(void)setsignal(SIGINT, cleanup);
741 	/* Cooperate with nohup(1) */
742 #ifndef WIN32
743 	if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
744 		(void)setsignal(SIGHUP, oldhandler);
745 #endif /* WIN32 */
746 
747 	if (pcap_setfilter(pd, &fcode) < 0)
748 		error("%s", pcap_geterr(pd));
749 	if (WFileName) {
750 		pcap_dumper_t *p = pcap_dump_open(pd, WFileName);
751 		if (p == NULL)
752 			error("%s", pcap_geterr(pd));
753 		if (Cflag != 0) {
754 			callback = dump_packet_and_trunc;
755 			dumpinfo.WFileName = WFileName;
756 			dumpinfo.pd = pd;
757 			dumpinfo.p = p;
758 			pcap_userdata = (u_char *)&dumpinfo;
759 		} else {
760 			callback = dump_packet;
761 			pcap_userdata = (u_char *)p;
762 		}
763 	} else {
764 		type = pcap_datalink(pd);
765 		printinfo.printer = lookup_printer(type);
766 		if (printinfo.printer == NULL) {
767 			dlt_name = pcap_datalink_val_to_name(type);
768 			if (dlt_name != NULL)
769 				error("unsupported data link type %s", dlt_name);
770 			else
771 				error("unsupported data link type %d", type);
772 		}
773 		callback = print_packet;
774 		pcap_userdata = (u_char *)&printinfo;
775 	}
776 #ifdef SIGINFO
777 	(void)setsignal(SIGINFO, requestinfo);
778 #endif
779 #ifndef WIN32
780 	if (RFileName == NULL) {
781 		int dlt;
782 		const char *dlt_name;
783 
784 		if (!vflag && !WFileName) {
785 			(void)fprintf(stderr,
786 			    "%s: verbose output suppressed, use -v or -vv for full protocol decode\n",
787 			    program_name);
788 		} else
789 			(void)fprintf(stderr, "%s: ", program_name);
790 		dlt = pcap_datalink(pd);
791 		dlt_name = pcap_datalink_val_to_name(dlt);
792 		if (dlt_name == NULL) {
793 			(void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n",
794 			    device, dlt, snaplen);
795 		} else {
796 			(void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n",
797 			    device, dlt_name,
798 			    pcap_datalink_val_to_description(dlt), snaplen);
799 		}
800 		(void)fflush(stderr);
801 	}
802 #endif /* WIN32 */
803 	status = pcap_loop(pd, cnt, callback, pcap_userdata);
804 	if (WFileName == NULL) {
805 		/*
806 		 * We're printing packets.  Flush the printed output,
807 		 * so it doesn't get intermingled with error output.
808 		 */
809 		if (status == -2) {
810 			/*
811 			 * We got interrupted, so perhaps we didn't
812 			 * manage to finish a line we were printing.
813 			 * Print an extra newline, just in case.
814 			 */
815 			putchar('\n');
816 		}
817 		(void)fflush(stdout);
818 	}
819 	if (status == -1) {
820 		/*
821 		 * Error.  Report it.
822 		 */
823 		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
824 		    program_name, pcap_geterr(pd));
825 	}
826 	if (RFileName == NULL) {
827 		/*
828 		 * We're doing a live capture.  Report the capture
829 		 * statistics.
830 		 */
831 		info(1);
832 	}
833 	pcap_close(pd);
834 	exit(status == -1 ? 1 : 0);
835 }
836 
837 /* make a clean exit on interrupts */
838 static RETSIGTYPE
839 cleanup(int signo _U_)
840 {
841 #ifdef HAVE_PCAP_BREAKLOOP
842 	/*
843 	 * We have "pcap_breakloop()"; use it, so that we do as little
844 	 * as possible in the signal handler (it's probably not safe
845 	 * to do anything with standard I/O streams in a signal handler -
846 	 * the ANSI C standard doesn't say it is).
847 	 */
848 	pcap_breakloop(pd);
849 #else
850 	/*
851 	 * We don't have "pcap_breakloop()"; this isn't safe, but
852 	 * it's the best we can do.  Print the summary if we're
853 	 * not reading from a savefile - i.e., if we're doing a
854 	 * live capture - and exit.
855 	 */
856 	if (pd != NULL && pcap_file(pd) == NULL) {
857 		/*
858 		 * We got interrupted, so perhaps we didn't
859 		 * manage to finish a line we were printing.
860 		 * Print an extra newline, just in case.
861 		 */
862 		putchar('\n');
863 		(void)fflush(stdout);
864 		info(1);
865 	}
866 	exit(0);
867 #endif
868 }
869 
870 static void
871 info(register int verbose)
872 {
873 	struct pcap_stat stat;
874 
875 	if (pcap_stats(pd, &stat) < 0) {
876 		(void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd));
877 		return;
878 	}
879 
880 	if (!verbose)
881 		fprintf(stderr, "%s: ", program_name);
882 
883 	(void)fprintf(stderr, "%u packets captured", packets_captured);
884 	if (!verbose)
885 		fputs(", ", stderr);
886 	else
887 		putc('\n', stderr);
888 	(void)fprintf(stderr, "%d packets received by filter", stat.ps_recv);
889 	if (!verbose)
890 		fputs(", ", stderr);
891 	else
892 		putc('\n', stderr);
893 	(void)fprintf(stderr, "%d packets dropped by kernel\n", stat.ps_drop);
894 	infoprint = 0;
895 }
896 
897 static void
898 reverse(char *s)
899 {
900 	int i, j, c;
901 
902 	for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
903 		c = s[i];
904 		s[i] = s[j];
905 		s[j] = c;
906 	}
907 }
908 
909 
910 static void
911 swebitoa(unsigned int n, char *s)
912 {
913 	unsigned int i;
914 
915 	i = 0;
916 	do {
917 		s[i++] = n % 10 + '0';
918 	} while ((n /= 10) > 0);
919 
920 	s[i] = '\0';
921 	reverse(s);
922 }
923 
924 static void
925 dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
926 {
927 	struct dump_info *dump_info;
928 	static uint cnt = 2;
929 	char *name;
930 
931 	++packets_captured;
932 
933 	++infodelay;
934 
935 	dump_info = (struct dump_info *)user;
936 
937 	/*
938 	 * XXX - this won't prevent capture files from getting
939 	 * larger than Cflag - the last packet written to the
940 	 * file could put it over Cflag.
941 	 */
942 	if (ftell((FILE *)dump_info->p) > Cflag) {
943 		/*
944 		 * Close the current file and open a new one.
945 		 */
946 		pcap_dump_close(dump_info->p);
947 		if (cnt >= 1000)
948 			error("too many output files");
949 		name = (char *) malloc(strlen(dump_info->WFileName) + 4);
950 		if (name == NULL)
951 			error("dump_packet_and_trunc: malloc");
952 		strcpy(name, dump_info->WFileName);
953 		swebitoa(cnt, name + strlen(dump_info->WFileName));
954 		cnt++;
955 		dump_info->p = pcap_dump_open(dump_info->pd, name);
956 		free(name);
957 		if (dump_info->p == NULL)
958 			error("%s", pcap_geterr(pd));
959 	}
960 
961 	pcap_dump((u_char *)dump_info->p, h, sp);
962 #ifdef HAVE_PCAP_DUMP_FLUSH
963 	if (Uflag)
964 		pcap_dump_flush(dump_info->p);
965 #endif
966 
967 	--infodelay;
968 	if (infoprint)
969 		info(0);
970 }
971 
972 static void
973 dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
974 {
975 	++packets_captured;
976 
977 	++infodelay;
978 
979 	pcap_dump(user, h, sp);
980 #ifdef HAVE_PCAP_DUMP_FLUSH
981 	if (Uflag)
982 		pcap_dump_flush((pcap_dumper_t *)user);
983 #endif
984 
985 	--infodelay;
986 	if (infoprint)
987 		info(0);
988 }
989 
990 static void
991 print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
992 {
993 	struct print_info *print_info;
994 	u_int hdrlen;
995 
996 	++packets_captured;
997 
998 	++infodelay;
999 	ts_print(&h->ts);
1000 
1001 	print_info = (struct print_info *)user;
1002 
1003 	/*
1004 	 * Some printers want to check that they're not walking off the
1005 	 * end of the packet.
1006 	 * Rather than pass it all the way down, we set this global.
1007 	 */
1008 	snapend = sp + h->caplen;
1009 
1010 	hdrlen = (*print_info->printer)(h, sp);
1011 	if (xflag) {
1012 		/*
1013 		 * Print the raw packet data.
1014 		 */
1015 		if (xflag > 1) {
1016 			/*
1017 			 * Include the link-layer header.
1018 			 */
1019 			default_print(sp, h->caplen);
1020 		} else {
1021 			/*
1022 			 * Don't include the link-layer header - and if
1023 			 * we have nothing past the link-layer header,
1024 			 * print nothing.
1025 			 */
1026 			if (h->caplen > hdrlen)
1027 				default_print(sp + hdrlen,
1028 				    h->caplen - hdrlen);
1029 		}
1030 	}
1031 
1032 	putchar('\n');
1033 
1034 	--infodelay;
1035 	if (infoprint)
1036 		info(0);
1037 }
1038 
1039 #ifdef WIN32
1040 	/*
1041 	 * XXX - there should really be libpcap calls to get the version
1042 	 * number as a string (the string would be generated from #defines
1043 	 * at run time, so that it's not generated from string constants
1044 	 * in the library, as, on many UNIX systems, those constants would
1045 	 * be statically linked into the application executable image, and
1046 	 * would thus reflect the version of libpcap on the system on
1047 	 * which the application was *linked*, not the system on which it's
1048 	 * *running*.
1049 	 *
1050 	 * That routine should be documented, unlike the "version[]"
1051 	 * string, so that UNIX vendors providing their own libpcaps
1052 	 * don't omit it (as a couple of vendors have...).
1053 	 *
1054 	 * Packet.dll should perhaps also export a routine to return the
1055 	 * version number of the Packet.dll code, to supply the
1056 	 * "Wpcap_version" information on Windows.
1057 	 */
1058 	char WDversion[]="current-cvs.tcpdump.org";
1059 	char version[]="current-cvs.tcpdump.org";
1060 	char pcap_version[]="current-cvs.tcpdump.org";
1061 	char Wpcap_version[]="3.0 alpha";
1062 #endif
1063 
1064 /*
1065  * By default, print the specified data out in hex.
1066  */
1067 void
1068 default_print(register const u_char *bp, register u_int length)
1069 {
1070     ascii_print("\n\t", bp, length); /* pass on lf and identation string */
1071 }
1072 
1073 #ifdef SIGINFO
1074 RETSIGTYPE requestinfo(int signo _U_)
1075 {
1076 	if (infodelay)
1077 		++infoprint;
1078 	else
1079 		info(0);
1080 }
1081 #endif
1082 
1083 static void
1084 usage(void)
1085 {
1086 	extern char version[];
1087 #ifndef HAVE_PCAP_LIB_VERSION
1088 #if defined(WIN32) || defined(HAVE_PCAP_VERSION)
1089 	extern char pcap_version[];
1090 #else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */
1091 	static char pcap_version[] = "unknown";
1092 #endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */
1093 #endif /* HAVE_PCAP_LIB_VERSION */
1094 
1095 #ifdef HAVE_PCAP_LIB_VERSION
1096 	(void)fprintf(stderr, "%s version %s\n", program_name, version);
1097 	(void)fprintf(stderr, "%s\n", pcap_lib_version());
1098 #else /* HAVE_PCAP_LIB_VERSION */
1099 #ifdef WIN32
1100 	(void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version);
1101 	(void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version);
1102 #else /* WIN32 */
1103 	(void)fprintf(stderr, "%s version %s\n", program_name, version);
1104 	(void)fprintf(stderr, "libpcap version %s\n", pcap_version);
1105 #endif /* WIN32 */
1106 #endif /* HAVE_PCAP_LIB_VERSION */
1107 	(void)fprintf(stderr,
1108 "Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name);
1109 	(void)fprintf(stderr,
1110 "\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]\n");
1111 	(void)fprintf(stderr,
1112 "\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -y datalinktype ]\n");
1113 	(void)fprintf(stderr,
1114 "\t\t[ expression ]\n");
1115 	exit(1);
1116 }
1117