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#include <sys/cdefs.h>
29#ifndef lint
30#if 0
31static const char copyright[] _U_ =
32    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
33The Regents of the University of California.  All rights reserved.\n";
34static const char rcsid[] _U_ =
35    "@(#) Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp (LBL)";
36#else
37__RCSID("$NetBSD: tcpdump.c,v 1.2 2010/12/05 05:11:31 christos Exp $");
38#endif
39#endif
40
41/*
42 * tcpdump - monitor tcp/ip traffic on an ethernet.
43 *
44 * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
45 * Mercilessly hacked and occasionally improved since then via the
46 * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
47 */
48
49#ifdef HAVE_CONFIG_H
50#include "config.h"
51#endif
52
53#include <tcpdump-stdinc.h>
54
55#ifdef WIN32
56#include "getopt.h"
57#include "w32_fzs.h"
58extern int strcasecmp (const char *__s1, const char *__s2);
59extern int SIZE_BUF;
60#define off_t long
61#define uint UINT
62#endif /* WIN32 */
63
64#ifdef HAVE_SMI_H
65#include <smi.h>
66#endif
67
68#include <pcap.h>
69#include <signal.h>
70#include <stdio.h>
71#include <stdlib.h>
72#include <string.h>
73#include <limits.h>
74#ifndef WIN32
75#include <sys/wait.h>
76#include <sys/resource.h>
77#include <pwd.h>
78#include <grp.h>
79#include <errno.h>
80#endif /* WIN32 */
81
82
83#include "netdissect.h"
84#include "interface.h"
85#include "addrtoname.h"
86#include "machdep.h"
87#include "setsignal.h"
88#include "gmt2local.h"
89#include "pcap-missing.h"
90
91#ifndef NAME_MAX
92#define NAME_MAX 255
93#endif
94
95netdissect_options Gndo;
96netdissect_options *gndo = &Gndo;
97
98static int dflag;			/* print filter code */
99static int Lflag;			/* list available data link types and exit */
100static char *zflag = NULL;		/* compress each savefile using a specified command (like gzip or bzip2) */
101
102static int infodelay;
103static int infoprint;
104
105char *program_name;
106
107int32_t thiszone;		/* seconds offset from gmt to local time */
108
109/* Forwards */
110static RETSIGTYPE cleanup(int);
111static RETSIGTYPE child_cleanup(int);
112static void usage(void) __attribute__((noreturn));
113static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn));
114
115static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
116static void ndo_default_print(netdissect_options *, const u_char *, u_int);
117static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
118static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
119static void droproot(const char *, const char *);
120static void ndo_error(netdissect_options *ndo, const char *fmt, ...);
121static void ndo_warning(netdissect_options *ndo, const char *fmt, ...);
122
123#ifdef SIGINFO
124RETSIGTYPE requestinfo(int);
125#endif
126
127#if defined(USE_WIN32_MM_TIMER)
128  #include <MMsystem.h>
129  static UINT timer_id;
130  static void CALLBACK verbose_stats_dump(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR);
131#elif defined(HAVE_ALARM)
132  static void verbose_stats_dump(int sig);
133#endif
134
135static void info(int);
136static u_int packets_captured;
137
138typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *);
139typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo,
140                                const struct pcap_pkthdr *, const u_char *);
141
142struct printer {
143        if_printer f;
144	int type;
145};
146
147
148struct ndo_printer {
149        if_ndo_printer f;
150	int type;
151};
152
153
154static struct printer printers[] = {
155	{ arcnet_if_print,	DLT_ARCNET },
156#ifdef DLT_ARCNET_LINUX
157	{ arcnet_linux_if_print, DLT_ARCNET_LINUX },
158#endif
159	{ ether_if_print,	DLT_EN10MB },
160	{ token_if_print,	DLT_IEEE802 },
161#ifdef DLT_LANE8023
162	{ lane_if_print,        DLT_LANE8023 },
163#endif
164#ifdef DLT_CIP
165	{ cip_if_print,         DLT_CIP },
166#endif
167#ifdef DLT_ATM_CLIP
168	{ cip_if_print,		DLT_ATM_CLIP },
169#endif
170	{ sl_if_print,		DLT_SLIP },
171#ifdef DLT_SLIP_BSDOS
172	{ sl_bsdos_if_print,	DLT_SLIP_BSDOS },
173#endif
174	{ ppp_if_print,		DLT_PPP },
175#ifdef DLT_PPP_WITHDIRECTION
176	{ ppp_if_print,		DLT_PPP_WITHDIRECTION },
177#endif
178#ifdef DLT_PPP_BSDOS
179	{ ppp_bsdos_if_print,	DLT_PPP_BSDOS },
180#endif
181	{ fddi_if_print,	DLT_FDDI },
182	{ null_if_print,	DLT_NULL },
183#ifdef DLT_LOOP
184	{ null_if_print,	DLT_LOOP },
185#endif
186	{ raw_if_print,		DLT_RAW },
187	{ atm_if_print,		DLT_ATM_RFC1483 },
188#ifdef DLT_C_HDLC
189	{ chdlc_if_print,	DLT_C_HDLC },
190#endif
191#ifdef DLT_HDLC
192	{ chdlc_if_print,	DLT_HDLC },
193#endif
194#ifdef DLT_PPP_SERIAL
195	{ ppp_hdlc_if_print,	DLT_PPP_SERIAL },
196#endif
197#ifdef DLT_PPP_ETHER
198	{ pppoe_if_print,	DLT_PPP_ETHER },
199#endif
200#ifdef DLT_LINUX_SLL
201	{ sll_if_print,		DLT_LINUX_SLL },
202#endif
203#ifdef DLT_IEEE802_11
204	{ ieee802_11_if_print,	DLT_IEEE802_11},
205#endif
206#ifdef DLT_LTALK
207	{ ltalk_if_print,	DLT_LTALK },
208#endif
209#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H)
210	{ pflog_if_print,	DLT_PFLOG },
211#endif
212#ifdef DLT_PFSYNC
213	{ pfsync_if_print,  DLT_PFSYNC },
214#endif
215#ifdef DLT_FR
216	{ fr_if_print,		DLT_FR },
217#endif
218#ifdef DLT_FRELAY
219	{ fr_if_print,		DLT_FRELAY },
220#endif
221#ifdef DLT_SUNATM
222	{ sunatm_if_print,	DLT_SUNATM },
223#endif
224#ifdef DLT_IP_OVER_FC
225	{ ipfc_if_print,	DLT_IP_OVER_FC },
226#endif
227#ifdef DLT_PRISM_HEADER
228	{ prism_if_print,	DLT_PRISM_HEADER },
229#endif
230#ifdef DLT_IEEE802_11_RADIO
231	{ ieee802_11_radio_if_print,	DLT_IEEE802_11_RADIO },
232#endif
233#ifdef DLT_ENC
234	{ enc_if_print,		DLT_ENC },
235#endif
236#ifdef DLT_SYMANTEC_FIREWALL
237	{ symantec_if_print,	DLT_SYMANTEC_FIREWALL },
238#endif
239#ifdef DLT_APPLE_IP_OVER_IEEE1394
240	{ ap1394_if_print,	DLT_APPLE_IP_OVER_IEEE1394 },
241#endif
242#ifdef DLT_IEEE802_11_RADIO_AVS
243	{ ieee802_11_radio_avs_if_print,	DLT_IEEE802_11_RADIO_AVS },
244#endif
245#ifdef DLT_JUNIPER_ATM1
246	{ juniper_atm1_print,	DLT_JUNIPER_ATM1 },
247#endif
248#ifdef DLT_JUNIPER_ATM2
249	{ juniper_atm2_print,	DLT_JUNIPER_ATM2 },
250#endif
251#ifdef DLT_JUNIPER_MFR
252	{ juniper_mfr_print,	DLT_JUNIPER_MFR },
253#endif
254#ifdef DLT_JUNIPER_MLFR
255	{ juniper_mlfr_print,	DLT_JUNIPER_MLFR },
256#endif
257#ifdef DLT_JUNIPER_MLPPP
258	{ juniper_mlppp_print,	DLT_JUNIPER_MLPPP },
259#endif
260#ifdef DLT_JUNIPER_PPPOE
261	{ juniper_pppoe_print,	DLT_JUNIPER_PPPOE },
262#endif
263#ifdef DLT_JUNIPER_PPPOE_ATM
264	{ juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM },
265#endif
266#ifdef DLT_JUNIPER_GGSN
267	{ juniper_ggsn_print,	DLT_JUNIPER_GGSN },
268#endif
269#ifdef DLT_JUNIPER_ES
270	{ juniper_es_print,	DLT_JUNIPER_ES },
271#endif
272#ifdef DLT_JUNIPER_MONITOR
273	{ juniper_monitor_print, DLT_JUNIPER_MONITOR },
274#endif
275#ifdef DLT_JUNIPER_SERVICES
276	{ juniper_services_print, DLT_JUNIPER_SERVICES },
277#endif
278#ifdef DLT_JUNIPER_ETHER
279	{ juniper_ether_print,	DLT_JUNIPER_ETHER },
280#endif
281#ifdef DLT_JUNIPER_PPP
282	{ juniper_ppp_print,	DLT_JUNIPER_PPP },
283#endif
284#ifdef DLT_JUNIPER_FRELAY
285	{ juniper_frelay_print,	DLT_JUNIPER_FRELAY },
286#endif
287#ifdef DLT_JUNIPER_CHDLC
288	{ juniper_chdlc_print,	DLT_JUNIPER_CHDLC },
289#endif
290#ifdef DLT_MFR
291	{ mfr_if_print,		DLT_MFR },
292#endif
293#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
294	{ bt_if_print,		DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
295#endif
296#ifdef HAVE_PCAP_USB_H
297#ifdef DLT_USB_LINUX
298	{ usb_linux_48_byte_print, DLT_USB_LINUX},
299#endif /* DLT_USB_LINUX */
300#ifdef DLT_USB_LINUX_MMAPPED
301	{ usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED},
302#endif /* DLT_USB_LINUX_MMAPPED */
303#endif /* HAVE_PCAP_USB_H */
304#ifdef DLT_IPV4
305	{ raw_if_print,		DLT_IPV4 },
306#endif
307#ifdef DLT_IPV6
308	{ raw_if_print,		DLT_IPV6 },
309#endif
310	{ NULL,			0 },
311};
312
313static struct ndo_printer ndo_printers[] = {
314#ifdef DLT_IPNET
315	{ ipnet_if_print,	DLT_IPNET },
316#endif
317	{ NULL,			0 },
318};
319
320static if_printer
321lookup_printer(int type)
322{
323	struct printer *p;
324
325	for (p = printers; p->f; ++p)
326		if (type == p->type)
327			return p->f;
328
329	return NULL;
330	/* NOTREACHED */
331}
332
333static if_ndo_printer
334lookup_ndo_printer(int type)
335{
336	struct ndo_printer *p;
337
338	for (p = ndo_printers; p->f; ++p)
339		if (type == p->type)
340			return p->f;
341
342	return NULL;
343	/* NOTREACHED */
344}
345
346static pcap_t *pd;
347
348static int supports_monitor_mode;
349
350extern int optind;
351extern int opterr;
352extern char *optarg;
353
354struct print_info {
355        netdissect_options *ndo;
356        union {
357                if_printer     printer;
358                if_ndo_printer ndo_printer;
359        } p;
360        int ndo_type;
361};
362
363struct dump_info {
364	char	*WFileName;
365	char	*CurrentFileName;
366	pcap_t	*pd;
367	pcap_dumper_t *p;
368};
369
370static void
371show_dlts_and_exit(const char *device, pcap_t *pd)
372{
373	int n_dlts;
374	int *dlts = 0;
375	const char *dlt_name;
376
377	n_dlts = pcap_list_datalinks(pd, &dlts);
378	if (n_dlts < 0)
379		error("%s", pcap_geterr(pd));
380	else if (n_dlts == 0 || !dlts)
381		error("No data link types.");
382
383	/*
384	 * If the interface is known to support monitor mode, indicate
385	 * whether these are the data link types available when not in
386	 * monitor mode, if -I wasn't specified, or when in monitor mode,
387	 * when -I was specified (the link-layer types available in
388	 * monitor mode might be different from the ones available when
389	 * not in monitor mode).
390	 */
391	if (supports_monitor_mode)
392		(void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n",
393		    device,
394		    Iflag ? "when in monitor mode" : "when not in monitor mode");
395	else
396		(void) fprintf(stderr, "Data link types for %s (use option -y to set):\n",
397		    device);
398
399	while (--n_dlts >= 0) {
400		dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]);
401		if (dlt_name != NULL) {
402			(void) fprintf(stderr, "  %s (%s)", dlt_name,
403			    pcap_datalink_val_to_description(dlts[n_dlts]));
404
405			/*
406			 * OK, does tcpdump handle that type?
407			 */
408			if (lookup_printer(dlts[n_dlts]) == NULL
409                            && lookup_ndo_printer(dlts[n_dlts]) == NULL)
410				(void) fprintf(stderr, " (printing not supported)");
411			putchar('\n');
412		} else {
413			(void) fprintf(stderr, "  DLT %d (printing not supported)\n",
414			    dlts[n_dlts]);
415		}
416	}
417	free(dlts);
418	exit(0);
419}
420
421/*
422 * Set up flags that might or might not be supported depending on the
423 * version of libpcap we're using.
424 */
425#if defined(HAVE_PCAP_CREATE) || defined(WIN32)
426#define B_FLAG		"B:"
427#define B_FLAG_USAGE	" [ -B size ]"
428#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */
429#define B_FLAG
430#define B_FLAG_USAGE
431#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */
432
433#ifdef HAVE_PCAP_CREATE
434#define I_FLAG		"I"
435#else /* HAVE_PCAP_CREATE */
436#define I_FLAG
437#endif /* HAVE_PCAP_CREATE */
438
439#ifdef HAVE_PCAP_FINDALLDEVS
440#ifndef HAVE_PCAP_IF_T
441#undef HAVE_PCAP_FINDALLDEVS
442#endif
443#endif
444
445#ifdef HAVE_PCAP_FINDALLDEVS
446#define D_FLAG	"D"
447#else
448#define D_FLAG
449#endif
450
451#ifdef HAVE_PCAP_DUMP_FLUSH
452#define U_FLAG	"U"
453#else
454#define U_FLAG
455#endif
456
457#ifndef WIN32
458/* Drop root privileges and chroot if necessary */
459static void
460droproot(const char *username, const char *chroot_dir)
461{
462	struct passwd *pw = NULL;
463
464	if (chroot_dir && !username) {
465		fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n");
466		exit(1);
467	}
468
469	pw = getpwnam(username);
470	if (pw) {
471		if (chroot_dir) {
472			setprotoent(1);
473			if (chroot(chroot_dir) != 0 || chdir ("/") != 0) {
474				fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n",
475				    chroot_dir, pcap_strerror(errno));
476				exit(1);
477			}
478		}
479		if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
480		    setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
481			fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
482			    username,
483			    (unsigned long)pw->pw_uid,
484			    (unsigned long)pw->pw_gid,
485			    pcap_strerror(errno));
486			exit(1);
487		}
488	}
489	else {
490		fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n",
491		    username);
492		exit(1);
493	}
494}
495#endif /* WIN32 */
496
497static int
498getWflagChars(int x)
499{
500	int c = 0;
501
502	x -= 1;
503	while (x > 0) {
504		c += 1;
505		x /= 10;
506	}
507
508	return c;
509}
510
511
512static void
513MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars)
514{
515        char *filename = malloc(NAME_MAX + 1);
516
517        /* Process with strftime if Gflag is set. */
518        if (Gflag != 0) {
519          struct tm *local_tm;
520
521          /* Convert Gflag_time to a usable format */
522          if ((local_tm = localtime(&Gflag_time)) == NULL) {
523                  error("MakeTimedFilename: localtime");
524          }
525
526          /* There's no good way to detect an error in strftime since a return
527           * value of 0 isn't necessarily failure.
528           */
529          strftime(filename, NAME_MAX, orig_name, local_tm);
530        } else {
531          strncpy(filename, orig_name, NAME_MAX);
532        }
533
534	if (cnt == 0 && max_chars == 0)
535		strncpy(buffer, filename, NAME_MAX + 1);
536	else
537		if (snprintf(buffer, NAME_MAX + 1, "%s%0*d", filename, max_chars, cnt) > NAME_MAX)
538                  /* Report an error if the filename is too large */
539                  error("too many output files or filename is too long (> %d)", NAME_MAX);
540        free(filename);
541}
542
543static int tcpdump_printf(netdissect_options *ndo _U_,
544			  const char *fmt, ...)
545{
546
547  va_list args;
548  int ret;
549
550  va_start(args, fmt);
551  ret=vfprintf(stdout, fmt, args);
552  va_end(args);
553
554  return ret;
555}
556
557int
558main(int argc, char **argv)
559{
560	register int cnt, op, i;
561	bpf_u_int32 localnet, netmask;
562	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
563	pcap_handler callback;
564	int type;
565	struct bpf_program fcode;
566#ifndef WIN32
567	RETSIGTYPE (*oldhandler)(int);
568#endif
569	struct print_info printinfo;
570	struct dump_info dumpinfo;
571	u_char *pcap_userdata;
572	char ebuf[PCAP_ERRBUF_SIZE];
573	char *username = NULL;
574	char *chroot_dir = NULL;
575#ifdef HAVE_PCAP_FINDALLDEVS
576	pcap_if_t *devpointer;
577	int devnum;
578#endif
579	int status;
580#ifdef WIN32
581	if(wsockinit() != 0) return 1;
582#endif /* WIN32 */
583
584        gndo->ndo_Oflag=1;
585	gndo->ndo_Rflag=1;
586	gndo->ndo_dlt=-1;
587	gndo->ndo_default_print=ndo_default_print;
588	gndo->ndo_printf=tcpdump_printf;
589	gndo->ndo_error=ndo_error;
590	gndo->ndo_warning=ndo_warning;
591	gndo->ndo_snaplen = DEFAULT_SNAPLEN;
592
593	cnt = -1;
594	device = NULL;
595	infile = NULL;
596	RFileName = NULL;
597	WFileName = NULL;
598	if ((cp = strrchr(argv[0], '/')) != NULL)
599		program_name = cp + 1;
600	else
601		program_name = argv[0];
602
603	if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
604		error("%s", ebuf);
605
606#ifdef LIBSMI
607	smiInit("tcpdump");
608#endif
609
610	opterr = 0;
611	while (
612	    (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1)
613		switch (op) {
614
615		case 'a':
616			/* compatibility for old -a */
617			break;
618
619		case 'A':
620			++Aflag;
621			break;
622
623		case 'b':
624			++bflag;
625			break;
626
627#if defined(HAVE_PCAP_CREATE) || defined(WIN32)
628		case 'B':
629			Bflag = atoi(optarg)*1024;
630			if (Bflag <= 0)
631				error("invalid packet buffer size %s", optarg);
632			break;
633#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */
634
635		case 'c':
636			cnt = atoi(optarg);
637			if (cnt <= 0)
638				error("invalid packet count %s", optarg);
639			break;
640
641		case 'C':
642			Cflag = atoi(optarg) * 1000000;
643			if (Cflag < 0)
644				error("invalid file size %s", optarg);
645			break;
646
647		case 'd':
648			++dflag;
649			break;
650
651#ifdef HAVE_PCAP_FINDALLDEVS
652		case 'D':
653			if (pcap_findalldevs(&devpointer, ebuf) < 0)
654				error("%s", ebuf);
655			else {
656				for (i = 0; devpointer != 0; i++) {
657					printf("%d.%s", i+1, devpointer->name);
658					if (devpointer->description != NULL)
659						printf(" (%s)", devpointer->description);
660					printf("\n");
661					devpointer = devpointer->next;
662				}
663			}
664			return 0;
665#endif /* HAVE_PCAP_FINDALLDEVS */
666
667		case 'L':
668			Lflag++;
669			break;
670
671		case 'e':
672			++eflag;
673			break;
674
675		case 'E':
676#ifndef HAVE_LIBCRYPTO
677			warning("crypto code not compiled in");
678#endif
679			gndo->ndo_espsecret = optarg;
680			break;
681
682		case 'f':
683			++fflag;
684			break;
685
686		case 'F':
687			infile = optarg;
688			break;
689
690		case 'G':
691			Gflag = atoi(optarg);
692			if (Gflag < 0)
693				error("invalid number of seconds %s", optarg);
694
695                        /* We will create one file initially. */
696                        Gflag_count = 0;
697
698			/* Grab the current time for rotation use. */
699			if ((Gflag_time = time(NULL)) == (time_t)-1) {
700				error("main: can't get current time: %s",
701				    pcap_strerror(errno));
702			}
703			break;
704
705		case 'i':
706			if (optarg[0] == '0' && optarg[1] == 0)
707				error("Invalid adapter index");
708
709#ifdef HAVE_PCAP_FINDALLDEVS
710			/*
711			 * If the argument is a number, treat it as
712			 * an index into the list of adapters, as
713			 * printed by "tcpdump -D".
714			 *
715			 * This should be OK on UNIX systems, as interfaces
716			 * shouldn't have names that begin with digits.
717			 * It can be useful on Windows, where more than
718			 * one interface can have the same name.
719			 */
720			if ((devnum = atoi(optarg)) != 0) {
721				if (devnum < 0)
722					error("Invalid adapter index");
723
724				if (pcap_findalldevs(&devpointer, ebuf) < 0)
725					error("%s", ebuf);
726				else {
727					/*
728					 * Look for the devnum-th entry
729					 * in the list of devices
730					 * (1-based).
731					 */
732					for (i = 0;
733					    i < devnum-1 && devpointer != NULL;
734					    i++, devpointer = devpointer->next)
735						;
736					if (devpointer == NULL)
737						error("Invalid adapter index");
738				}
739				device = devpointer->name;
740				break;
741			}
742#endif /* HAVE_PCAP_FINDALLDEVS */
743			device = optarg;
744			break;
745
746#ifdef HAVE_PCAP_CREATE
747		case 'I':
748			++Iflag;
749			break;
750#endif /* HAVE_PCAP_CREATE */
751
752		case 'l':
753#ifdef WIN32
754			/*
755			 * _IOLBF is the same as _IOFBF in Microsoft's C
756			 * libraries; the only alternative they offer
757			 * is _IONBF.
758			 *
759			 * XXX - this should really be checking for MSVC++,
760			 * not WIN32, if, for example, MinGW has its own
761			 * C library that is more UNIX-compatible.
762			 */
763			setvbuf(stdout, NULL, _IONBF, 0);
764#else /* WIN32 */
765#ifdef HAVE_SETLINEBUF
766			setlinebuf(stdout);
767#else
768			setvbuf(stdout, NULL, _IOLBF, 0);
769#endif
770#endif /* WIN32 */
771			break;
772
773		case 'K':
774			++Kflag;
775			break;
776
777		case 'm':
778#ifdef LIBSMI
779			if (smiLoadModule(optarg) == 0) {
780				error("could not load MIB module %s", optarg);
781			}
782			sflag = 1;
783#else
784			(void)fprintf(stderr, "%s: ignoring option `-m %s' ",
785				      program_name, optarg);
786			(void)fprintf(stderr, "(no libsmi support)\n");
787#endif
788			break;
789
790		case 'M':
791			/* TCP-MD5 shared secret */
792#ifndef HAVE_LIBCRYPTO
793			warning("crypto code not compiled in");
794#endif
795			sigsecret = optarg;
796			break;
797
798		case 'n':
799			++nflag;
800			break;
801
802		case 'N':
803			++Nflag;
804			break;
805
806		case 'O':
807			Oflag = 0;
808			break;
809
810		case 'p':
811			++pflag;
812			break;
813
814		case 'q':
815			++qflag;
816			++suppress_default_print;
817			break;
818
819		case 'r':
820			RFileName = optarg;
821			break;
822
823		case 'R':
824			Rflag = 0;
825			break;
826
827		case 's': {
828			char *end;
829
830			snaplen = strtol(optarg, &end, 0);
831			if (optarg == end || *end != '\0'
832			    || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
833				error("invalid snaplen %s", optarg);
834			else if (snaplen == 0)
835				snaplen = MAXIMUM_SNAPLEN;
836			break;
837		}
838
839		case 'S':
840			++Sflag;
841			break;
842
843		case 't':
844			++tflag;
845			break;
846
847		case 'T':
848			if (strcasecmp(optarg, "vat") == 0)
849				packettype = PT_VAT;
850			else if (strcasecmp(optarg, "wb") == 0)
851				packettype = PT_WB;
852			else if (strcasecmp(optarg, "rpc") == 0)
853				packettype = PT_RPC;
854			else if (strcasecmp(optarg, "rtp") == 0)
855				packettype = PT_RTP;
856			else if (strcasecmp(optarg, "rtcp") == 0)
857				packettype = PT_RTCP;
858			else if (strcasecmp(optarg, "snmp") == 0)
859				packettype = PT_SNMP;
860			else if (strcasecmp(optarg, "cnfp") == 0)
861				packettype = PT_CNFP;
862			else if (strcasecmp(optarg, "tftp") == 0)
863				packettype = PT_TFTP;
864			else if (strcasecmp(optarg, "aodv") == 0)
865				packettype = PT_AODV;
866			else
867				error("unknown packet type `%s'", optarg);
868			break;
869
870		case 'u':
871			++uflag;
872			break;
873
874#ifdef HAVE_PCAP_DUMP_FLUSH
875		case 'U':
876			++Uflag;
877			break;
878#endif
879
880		case 'v':
881			++vflag;
882			break;
883
884		case 'w':
885			WFileName = optarg;
886			break;
887
888		case 'W':
889			Wflag = atoi(optarg);
890			if (Wflag < 0)
891				error("invalid number of output files %s", optarg);
892			WflagChars = getWflagChars(Wflag);
893			break;
894
895		case 'x':
896			++xflag;
897			++suppress_default_print;
898			break;
899
900		case 'X':
901			++Xflag;
902			++suppress_default_print;
903			break;
904
905		case 'y':
906			gndo->ndo_dltname = optarg;
907			gndo->ndo_dlt =
908			  pcap_datalink_name_to_val(gndo->ndo_dltname);
909			if (gndo->ndo_dlt < 0)
910				error("invalid data link type %s", gndo->ndo_dltname);
911			break;
912
913#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
914		case 'Y':
915			{
916			/* Undocumented flag */
917#ifdef HAVE_PCAP_DEBUG
918			extern int pcap_debug;
919			pcap_debug = 1;
920#else
921			extern int yydebug;
922			yydebug = 1;
923#endif
924			}
925			break;
926#endif
927		case 'z':
928			if (optarg) {
929				zflag = strdup(optarg);
930			} else {
931				usage();
932				/* NOTREACHED */
933			}
934			break;
935
936		case 'Z':
937			if (optarg) {
938				username = strdup(optarg);
939			}
940			else {
941				usage();
942				/* NOTREACHED */
943			}
944			break;
945
946		default:
947			usage();
948			/* NOTREACHED */
949		}
950
951	switch (tflag) {
952
953	case 0: /* Default */
954	case 4: /* Default + Date*/
955		thiszone = gmt2local(0);
956		break;
957
958	case 1: /* No time stamp */
959	case 2: /* Unix timeval style */
960	case 3: /* Microseconds since previous packet */
961        case 5: /* Microseconds since first packet */
962		break;
963
964	default: /* Not supported */
965		error("only -t, -tt, -ttt, -tttt and -ttttt are supported");
966		break;
967	}
968
969#ifdef WITH_CHROOT
970	/* if run as root, prepare for chrooting */
971	if (getuid() == 0 || geteuid() == 0) {
972		/* future extensibility for cmd-line arguments */
973		if (!chroot_dir)
974			chroot_dir = WITH_CHROOT;
975	}
976#endif
977
978#ifdef WITH_USER
979	/* if run as root, prepare for dropping root privileges */
980	if (getuid() == 0 || geteuid() == 0) {
981		/* Run with '-Z root' to restore old behaviour */
982		if (!username)
983			username = WITH_USER;
984	}
985#endif
986
987	if (RFileName != NULL) {
988		int dlt;
989		const char *dlt_name;
990
991#ifndef WIN32
992		/*
993		 * We don't need network access, so relinquish any set-UID
994		 * or set-GID privileges we have (if any).
995		 *
996		 * We do *not* want set-UID privileges when opening a
997		 * trace file, as that might let the user read other
998		 * people's trace files (especially if we're set-UID
999		 * root).
1000		 */
1001		if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
1002			fprintf(stderr, "Warning: setgid/setuid failed !\n");
1003#endif /* WIN32 */
1004		pd = pcap_open_offline(RFileName, ebuf);
1005		if (pd == NULL)
1006			error("%s", ebuf);
1007		dlt = pcap_datalink(pd);
1008		dlt_name = pcap_datalink_val_to_name(dlt);
1009		if (dlt_name == NULL) {
1010			fprintf(stderr, "reading from file %s, link-type %u\n",
1011			    RFileName, dlt);
1012		} else {
1013			fprintf(stderr,
1014			    "reading from file %s, link-type %s (%s)\n",
1015			    RFileName, dlt_name,
1016			    pcap_datalink_val_to_description(dlt));
1017		}
1018		localnet = 0;
1019		netmask = 0;
1020		if (fflag != 0)
1021			error("-f and -r options are incompatible");
1022	} else {
1023		if (device == NULL) {
1024			device = pcap_lookupdev(ebuf);
1025			if (device == NULL)
1026				error("%s", ebuf);
1027		}
1028#ifdef WIN32
1029		if(strlen(device) == 1)	//we assume that an ASCII string is always longer than 1 char
1030		{						//a Unicode string has a \0 as second byte (so strlen() is 1)
1031			fprintf(stderr, "%s: listening on %ws\n", program_name, device);
1032		}
1033		else
1034		{
1035			fprintf(stderr, "%s: listening on %s\n", program_name, device);
1036		}
1037
1038		fflush(stderr);
1039#endif /* WIN32 */
1040#ifdef HAVE_PCAP_CREATE
1041		pd = pcap_create(device, ebuf);
1042		if (pd == NULL)
1043			error("%s", ebuf);
1044		/*
1045		 * Is this an interface that supports monitor mode?
1046		 */
1047		if (pcap_can_set_rfmon(pd) == 1)
1048			supports_monitor_mode = 1;
1049		else
1050			supports_monitor_mode = 0;
1051		status = pcap_set_snaplen(pd, snaplen);
1052		if (status != 0)
1053			error("%s: pcap_set_snaplen failed: %s",
1054			    device, pcap_statustostr(status));
1055		status = pcap_set_promisc(pd, !pflag);
1056		if (status != 0)
1057			error("%s: pcap_set_promisc failed: %s",
1058			    device, pcap_statustostr(status));
1059		if (Iflag) {
1060			status = pcap_set_rfmon(pd, 1);
1061			if (status != 0)
1062				error("%s: pcap_set_rfmon failed: %s",
1063				    device, pcap_statustostr(status));
1064		}
1065		status = pcap_set_timeout(pd, 1000);
1066		if (status != 0)
1067			error("%s: pcap_set_timeout failed: %s",
1068			    device, pcap_statustostr(status));
1069		if (Bflag != 0) {
1070			status = pcap_set_buffer_size(pd, Bflag);
1071			if (status != 0)
1072				error("%s: pcap_set_buffer_size failed: %s",
1073				    device, pcap_statustostr(status));
1074		}
1075		status = pcap_activate(pd);
1076		if (status < 0) {
1077			/*
1078			 * pcap_activate() failed.
1079			 */
1080			cp = pcap_geterr(pd);
1081			if (status == PCAP_ERROR)
1082				error("%s", cp);
1083			else if ((status == PCAP_ERROR_NO_SUCH_DEVICE ||
1084			          status == PCAP_ERROR_PERM_DENIED) &&
1085			         *cp != '\0')
1086				error("%s: %s\n(%s)", device,
1087				    pcap_statustostr(status), cp);
1088			else
1089				error("%s: %s", device,
1090				    pcap_statustostr(status));
1091		} else if (status > 0) {
1092			/*
1093			 * pcap_activate() succeeded, but it's warning us
1094			 * of a problem it had.
1095			 */
1096			cp = pcap_geterr(pd);
1097			if (status == PCAP_WARNING)
1098				warning("%s", cp);
1099			else if (status == PCAP_WARNING_PROMISC_NOTSUP &&
1100			         *cp != '\0')
1101				warning("%s: %s\n(%s)", device,
1102				    pcap_statustostr(status), cp);
1103			else
1104				warning("%s: %s", device,
1105				    pcap_statustostr(status));
1106		}
1107#else
1108		*ebuf = '\0';
1109		pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
1110		if (pd == NULL)
1111			error("%s", ebuf);
1112		else if (*ebuf)
1113			warning("%s", ebuf);
1114#endif /* HAVE_PCAP_CREATE */
1115		/*
1116		 * Let user own process after socket has been opened.
1117		 */
1118#ifndef WIN32
1119		if (setgid(getgid()) != 0 || setuid(getuid()) != 0)
1120			fprintf(stderr, "Warning: setgid/setuid failed !\n");
1121#endif /* WIN32 */
1122#if !defined(HAVE_PCAP_CREATE) && defined(WIN32)
1123		if(Bflag != 0)
1124			if(pcap_setbuff(pd, Bflag)==-1){
1125				error("%s", pcap_geterr(pd));
1126			}
1127#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */
1128		if (Lflag)
1129			show_dlts_and_exit(device, pd);
1130		if (gndo->ndo_dlt >= 0) {
1131#ifdef HAVE_PCAP_SET_DATALINK
1132			if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0)
1133				error("%s", pcap_geterr(pd));
1134#else
1135			/*
1136			 * We don't actually support changing the
1137			 * data link type, so we only let them
1138			 * set it to what it already is.
1139			 */
1140			if (gndo->ndo_dlt != pcap_datalink(pd)) {
1141				error("%s is not one of the DLTs supported by this device\n",
1142				      gndo->ndo_dltname);
1143			}
1144#endif
1145			(void)fprintf(stderr, "%s: data link type %s\n",
1146				      program_name, gndo->ndo_dltname);
1147			(void)fflush(stderr);
1148		}
1149		i = pcap_snapshot(pd);
1150		if (snaplen < i) {
1151			warning("snaplen raised from %d to %d", snaplen, i);
1152			snaplen = i;
1153		}
1154		if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
1155			localnet = 0;
1156			netmask = 0;
1157			warning("%s", ebuf);
1158		}
1159	}
1160	if (infile)
1161		cmdbuf = read_infile(infile);
1162	else
1163		cmdbuf = copy_argv(&argv[optind]);
1164
1165	if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
1166		error("%s", pcap_geterr(pd));
1167	free(cmdbuf);
1168	if (dflag) {
1169		bpf_dump(&fcode, dflag);
1170		pcap_close(pd);
1171		exit(0);
1172	}
1173	init_addrtoname(localnet, netmask);
1174        init_checksum();
1175
1176#ifndef WIN32
1177	(void)setsignal(SIGPIPE, cleanup);
1178	(void)setsignal(SIGTERM, cleanup);
1179	(void)setsignal(SIGINT, cleanup);
1180	(void)setsignal(SIGCHLD, child_cleanup);
1181#endif /* WIN32 */
1182	/* Cooperate with nohup(1) */
1183#ifndef WIN32
1184	if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
1185		(void)setsignal(SIGHUP, oldhandler);
1186#endif /* WIN32 */
1187
1188	if (pcap_setfilter(pd, &fcode) < 0)
1189		error("%s", pcap_geterr(pd));
1190	if (WFileName) {
1191		pcap_dumper_t *p;
1192		/* Do not exceed the default NAME_MAX for files. */
1193		dumpinfo.CurrentFileName = (char *)malloc(NAME_MAX + 1);
1194
1195		if (dumpinfo.CurrentFileName == NULL)
1196			error("malloc of dumpinfo.CurrentFileName");
1197
1198		/* We do not need numbering for dumpfiles if Cflag isn't set. */
1199		if (Cflag != 0)
1200		  MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars);
1201		else
1202		  MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
1203
1204		p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
1205		if (p == NULL)
1206			error("%s", pcap_geterr(pd));
1207		if (Cflag != 0 || Gflag != 0) {
1208			callback = dump_packet_and_trunc;
1209			dumpinfo.WFileName = WFileName;
1210			dumpinfo.pd = pd;
1211			dumpinfo.p = p;
1212			pcap_userdata = (u_char *)&dumpinfo;
1213		} else {
1214			callback = dump_packet;
1215			pcap_userdata = (u_char *)p;
1216		}
1217	} else {
1218		type = pcap_datalink(pd);
1219                printinfo.ndo_type = 1;
1220                printinfo.ndo = gndo;
1221		printinfo.p.ndo_printer = lookup_ndo_printer(type);
1222                if (printinfo.p.ndo_printer == NULL) {
1223                        printinfo.p.printer = lookup_printer(type);
1224                        printinfo.ndo_type = 0;
1225                        if (printinfo.p.printer == NULL) {
1226                                gndo->ndo_dltname = pcap_datalink_val_to_name(type);
1227                                if (gndo->ndo_dltname != NULL)
1228                                        error("packet printing is not supported for link type %s: use -w",
1229                                              gndo->ndo_dltname);
1230                                else
1231                                        error("packet printing is not supported for link type %d: use -w", type);
1232                        }
1233                }
1234		callback = print_packet;
1235		pcap_userdata = (u_char *)&printinfo;
1236	}
1237#ifndef WIN32
1238	/*
1239	 * We cannot do this earlier, because we want to be able to open
1240	 * the file (if done) for writing before giving up permissions.
1241	 */
1242	if (getuid() == 0 || geteuid() == 0) {
1243		if (username || chroot_dir)
1244			droproot(username, chroot_dir);
1245	}
1246#endif /* WIN32 */
1247#ifdef SIGINFO
1248	/*
1249	 * We can't get statistics when reading from a file rather
1250	 * than capturing from a device.
1251	 */
1252	if (RFileName == NULL)
1253		(void)setsignal(SIGINFO, requestinfo);
1254#endif
1255
1256	if (vflag > 0 && WFileName) {
1257		/*
1258		 * When capturing to a file, "-v" means tcpdump should,
1259		 * every 10 secodns, "v"erbosely report the number of
1260		 * packets captured.
1261		 */
1262#ifdef USE_WIN32_MM_TIMER
1263		/* call verbose_stats_dump() each 1000 +/-100msec */
1264		timer_id = timeSetEvent(1000, 100, verbose_stats_dump, 0, TIME_PERIODIC);
1265		setvbuf(stderr, NULL, _IONBF, 0);
1266#elif defined(HAVE_ALARM)
1267		(void)setsignal(SIGALRM, verbose_stats_dump);
1268		alarm(1);
1269#endif
1270	}
1271
1272#ifndef WIN32
1273	if (RFileName == NULL) {
1274		int dlt;
1275		const char *dlt_name;
1276
1277		if (!vflag && !WFileName) {
1278			(void)fprintf(stderr,
1279			    "%s: verbose output suppressed, use -v or -vv for full protocol decode\n",
1280			    program_name);
1281		} else
1282			(void)fprintf(stderr, "%s: ", program_name);
1283		dlt = pcap_datalink(pd);
1284		dlt_name = pcap_datalink_val_to_name(dlt);
1285		if (dlt_name == NULL) {
1286			(void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n",
1287			    device, dlt, snaplen);
1288		} else {
1289			(void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n",
1290			    device, dlt_name,
1291			    pcap_datalink_val_to_description(dlt), snaplen);
1292		}
1293		(void)fflush(stderr);
1294	}
1295#endif /* WIN32 */
1296	status = pcap_loop(pd, cnt, callback, pcap_userdata);
1297	if (WFileName == NULL) {
1298		/*
1299		 * We're printing packets.  Flush the printed output,
1300		 * so it doesn't get intermingled with error output.
1301		 */
1302		if (status == -2) {
1303			/*
1304			 * We got interrupted, so perhaps we didn't
1305			 * manage to finish a line we were printing.
1306			 * Print an extra newline, just in case.
1307			 */
1308			putchar('\n');
1309		}
1310		(void)fflush(stdout);
1311	}
1312	if (status == -1) {
1313		/*
1314		 * Error.  Report it.
1315		 */
1316		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
1317		    program_name, pcap_geterr(pd));
1318	}
1319	if (RFileName == NULL) {
1320		/*
1321		 * We're doing a live capture.  Report the capture
1322		 * statistics.
1323		 */
1324		info(1);
1325	}
1326	pcap_close(pd);
1327	exit(status == -1 ? 1 : 0);
1328}
1329
1330/* make a clean exit on interrupts */
1331static RETSIGTYPE
1332cleanup(int signo _U_)
1333{
1334#ifdef USE_WIN32_MM_TIMER
1335	if (timer_id)
1336		timeKillEvent(timer_id);
1337	timer_id = 0;
1338#elif defined(HAVE_ALARM)
1339	alarm(0);
1340#endif
1341
1342#ifdef HAVE_PCAP_BREAKLOOP
1343	/*
1344	 * We have "pcap_breakloop()"; use it, so that we do as little
1345	 * as possible in the signal handler (it's probably not safe
1346	 * to do anything with standard I/O streams in a signal handler -
1347	 * the ANSI C standard doesn't say it is).
1348	 */
1349	pcap_breakloop(pd);
1350#else
1351	/*
1352	 * We don't have "pcap_breakloop()"; this isn't safe, but
1353	 * it's the best we can do.  Print the summary if we're
1354	 * not reading from a savefile - i.e., if we're doing a
1355	 * live capture - and exit.
1356	 */
1357	if (pd != NULL && pcap_file(pd) == NULL) {
1358		/*
1359		 * We got interrupted, so perhaps we didn't
1360		 * manage to finish a line we were printing.
1361		 * Print an extra newline, just in case.
1362		 */
1363		putchar('\n');
1364		(void)fflush(stdout);
1365		info(1);
1366	}
1367	exit(0);
1368#endif
1369}
1370
1371/*
1372  On windows, we do not use a fork, so we do not care less about
1373  waiting a child processes to die
1374 */
1375#ifndef WIN32
1376static RETSIGTYPE
1377child_cleanup(int signo _U_)
1378{
1379  wait(NULL);
1380}
1381#endif /* WIN32 */
1382
1383static void
1384info(register int verbose)
1385{
1386	struct pcap_stat stat;
1387
1388	/*
1389	 * Older versions of libpcap didn't set ps_ifdrop on some
1390	 * platforms; initialize it to 0 to handle that.
1391	 */
1392	stat.ps_ifdrop = 0;
1393	if (pcap_stats(pd, &stat) < 0) {
1394		(void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd));
1395		infoprint = 0;
1396		return;
1397	}
1398
1399	if (!verbose)
1400		fprintf(stderr, "%s: ", program_name);
1401
1402	(void)fprintf(stderr, "%u packets captured", packets_captured);
1403	if (!verbose)
1404		fputs(", ", stderr);
1405	else
1406		putc('\n', stderr);
1407	(void)fprintf(stderr, "%u packets received by filter", stat.ps_recv);
1408	if (!verbose)
1409		fputs(", ", stderr);
1410	else
1411		putc('\n', stderr);
1412	(void)fprintf(stderr, "%u packets dropped by kernel", stat.ps_drop);
1413	if (stat.ps_ifdrop != 0) {
1414		if (!verbose)
1415			fputs(", ", stderr);
1416		else
1417			putc('\n', stderr);
1418		(void)fprintf(stderr, "%u packets dropped by interface\n",
1419		    stat.ps_ifdrop);
1420	} else
1421		putc('\n', stderr);
1422	infoprint = 0;
1423}
1424
1425#ifndef WIN32
1426static void
1427compress_savefile(const char *filename)
1428{
1429	if (fork())
1430		return;
1431	/*
1432	 * Set to lowest priority so that this doesn't disturb the capture
1433	 */
1434#ifdef NZERO
1435	setpriority(PRIO_PROCESS, 0, NZERO - 1);
1436#else
1437	setpriority(PRIO_PROCESS, 0, 19);
1438#endif
1439	if (execlp(zflag, zflag, filename, (char *)NULL) == -1)
1440		fprintf(stderr,
1441			"compress_savefile:execlp(%s, %s): %s\n",
1442			zflag,
1443			filename,
1444			strerror(errno));
1445}
1446#else  /* WIN32 */
1447static void
1448compress_savefile(const char *filename)
1449{
1450	fprintf(stderr,
1451		"compress_savefile failed. Functionality not implemented under windows\n");
1452}
1453#endif /* WIN32 */
1454
1455static void
1456dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
1457{
1458	struct dump_info *dump_info;
1459
1460	++packets_captured;
1461
1462	++infodelay;
1463
1464	dump_info = (struct dump_info *)user;
1465
1466	/*
1467	 * XXX - this won't force the file to rotate on the specified time
1468	 * boundary, but it will rotate on the first packet received after the
1469	 * specified Gflag number of seconds. Note: if a Gflag time boundary
1470	 * and a Cflag size boundary coincide, the time rotation will occur
1471	 * first thereby cancelling the Cflag boundary (since the file should
1472	 * be 0).
1473	 */
1474	if (Gflag != 0) {
1475		/* Check if it is time to rotate */
1476		time_t t;
1477
1478		/* Get the current time */
1479		if ((t = time(NULL)) == (time_t)-1) {
1480			error("dump_and_trunc_packet: can't get current_time: %s",
1481			    pcap_strerror(errno));
1482		}
1483
1484
1485		/* If the time is greater than the specified window, rotate */
1486		if (t - Gflag_time >= Gflag) {
1487			/* Update the Gflag_time */
1488			Gflag_time = t;
1489			/* Update Gflag_count */
1490			Gflag_count++;
1491			/*
1492			 * Close the current file and open a new one.
1493			 */
1494			pcap_dump_close(dump_info->p);
1495
1496			/*
1497			 * Compress the file we just closed, if the user asked for it
1498			 */
1499			if (zflag != NULL)
1500				compress_savefile(dump_info->CurrentFileName);
1501
1502			/*
1503			 * Check to see if we've exceeded the Wflag (when
1504			 * not using Cflag).
1505			 */
1506			if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) {
1507				(void)fprintf(stderr, "Maximum file limit reached: %d\n",
1508				    Wflag);
1509				exit(0);
1510				/* NOTREACHED */
1511			}
1512			if (dump_info->CurrentFileName != NULL)
1513				free(dump_info->CurrentFileName);
1514			/* Allocate space for max filename + \0. */
1515			dump_info->CurrentFileName = (char *)malloc(NAME_MAX + 1);
1516			if (dump_info->CurrentFileName == NULL)
1517				error("dump_packet_and_trunc: malloc");
1518			/*
1519			 * This is always the first file in the Cflag
1520			 * rotation: e.g. 0
1521			 * We also don't need numbering if Cflag is not set.
1522			 */
1523			if (Cflag != 0)
1524				MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0,
1525				    WflagChars);
1526			else
1527				MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0);
1528
1529			dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
1530			if (dump_info->p == NULL)
1531				error("%s", pcap_geterr(pd));
1532		}
1533	}
1534
1535	/*
1536	 * XXX - this won't prevent capture files from getting
1537	 * larger than Cflag - the last packet written to the
1538	 * file could put it over Cflag.
1539	 */
1540	if (Cflag != 0 && pcap_dump_ftell(dump_info->p) > Cflag) {
1541		/*
1542		 * Close the current file and open a new one.
1543		 */
1544		pcap_dump_close(dump_info->p);
1545
1546		/*
1547		 * Compress the file we just closed, if the user asked for it
1548		 */
1549		if (zflag != NULL)
1550			compress_savefile(dump_info->CurrentFileName);
1551
1552		Cflag_count++;
1553		if (Wflag > 0) {
1554			if (Cflag_count >= Wflag)
1555				Cflag_count = 0;
1556		}
1557		if (dump_info->CurrentFileName != NULL)
1558			free(dump_info->CurrentFileName);
1559		dump_info->CurrentFileName = (char *)malloc(NAME_MAX + 1);
1560		if (dump_info->CurrentFileName == NULL)
1561			error("dump_packet_and_trunc: malloc");
1562		MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars);
1563		dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
1564		if (dump_info->p == NULL)
1565			error("%s", pcap_geterr(pd));
1566	}
1567
1568	pcap_dump((u_char *)dump_info->p, h, sp);
1569#ifdef HAVE_PCAP_DUMP_FLUSH
1570	if (Uflag)
1571		pcap_dump_flush(dump_info->p);
1572#endif
1573
1574	--infodelay;
1575	if (infoprint)
1576		info(0);
1577}
1578
1579static void
1580dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
1581{
1582	++packets_captured;
1583
1584	++infodelay;
1585
1586	pcap_dump(user, h, sp);
1587#ifdef HAVE_PCAP_DUMP_FLUSH
1588	if (Uflag)
1589		pcap_dump_flush((pcap_dumper_t *)user);
1590#endif
1591
1592	--infodelay;
1593	if (infoprint)
1594		info(0);
1595}
1596
1597static void
1598print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
1599{
1600	struct print_info *print_info;
1601	u_int hdrlen;
1602
1603	++packets_captured;
1604
1605	++infodelay;
1606	ts_print(&h->ts);
1607
1608	print_info = (struct print_info *)user;
1609
1610	/*
1611	 * Some printers want to check that they're not walking off the
1612	 * end of the packet.
1613	 * Rather than pass it all the way down, we set this global.
1614	 */
1615	snapend = sp + h->caplen;
1616
1617        if(print_info->ndo_type) {
1618                hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp);
1619        } else {
1620                hdrlen = (*print_info->p.printer)(h, sp);
1621        }
1622
1623	if (Xflag) {
1624		/*
1625		 * Print the raw packet data in hex and ASCII.
1626		 */
1627		if (Xflag > 1) {
1628			/*
1629			 * Include the link-layer header.
1630			 */
1631			hex_and_ascii_print("\n\t", sp, h->caplen);
1632		} else {
1633			/*
1634			 * Don't include the link-layer header - and if
1635			 * we have nothing past the link-layer header,
1636			 * print nothing.
1637			 */
1638			if (h->caplen > hdrlen)
1639				hex_and_ascii_print("\n\t", sp + hdrlen,
1640				    h->caplen - hdrlen);
1641		}
1642	} else if (xflag) {
1643		/*
1644		 * Print the raw packet data in hex.
1645		 */
1646		if (xflag > 1) {
1647			/*
1648			 * Include the link-layer header.
1649			 */
1650			hex_print("\n\t", sp, h->caplen);
1651		} else {
1652			/*
1653			 * Don't include the link-layer header - and if
1654			 * we have nothing past the link-layer header,
1655			 * print nothing.
1656			 */
1657			if (h->caplen > hdrlen)
1658				hex_print("\n\t", sp + hdrlen,
1659				    h->caplen - hdrlen);
1660		}
1661	} else if (Aflag) {
1662		/*
1663		 * Print the raw packet data in ASCII.
1664		 */
1665		if (Aflag > 1) {
1666			/*
1667			 * Include the link-layer header.
1668			 */
1669			ascii_print(sp, h->caplen);
1670		} else {
1671			/*
1672			 * Don't include the link-layer header - and if
1673			 * we have nothing past the link-layer header,
1674			 * print nothing.
1675			 */
1676			if (h->caplen > hdrlen)
1677				ascii_print(sp + hdrlen, h->caplen - hdrlen);
1678		}
1679	}
1680
1681	putchar('\n');
1682
1683	--infodelay;
1684	if (infoprint)
1685		info(0);
1686}
1687
1688#ifdef WIN32
1689	/*
1690	 * XXX - there should really be libpcap calls to get the version
1691	 * number as a string (the string would be generated from #defines
1692	 * at run time, so that it's not generated from string constants
1693	 * in the library, as, on many UNIX systems, those constants would
1694	 * be statically linked into the application executable image, and
1695	 * would thus reflect the version of libpcap on the system on
1696	 * which the application was *linked*, not the system on which it's
1697	 * *running*.
1698	 *
1699	 * That routine should be documented, unlike the "version[]"
1700	 * string, so that UNIX vendors providing their own libpcaps
1701	 * don't omit it (as a couple of vendors have...).
1702	 *
1703	 * Packet.dll should perhaps also export a routine to return the
1704	 * version number of the Packet.dll code, to supply the
1705	 * "Wpcap_version" information on Windows.
1706	 */
1707	char WDversion[]="current-cvs.tcpdump.org";
1708#if !defined(HAVE_GENERATED_VERSION)
1709	char version[]="current-cvs.tcpdump.org";
1710#endif
1711	char pcap_version[]="current-cvs.tcpdump.org";
1712	char Wpcap_version[]="3.1";
1713#endif
1714
1715/*
1716 * By default, print the specified data out in hex and ASCII.
1717 */
1718static void
1719ndo_default_print(netdissect_options *ndo _U_, const u_char *bp, u_int length)
1720{
1721	hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */
1722}
1723
1724void
1725default_print(const u_char *bp, u_int length)
1726{
1727	ndo_default_print(gndo, bp, length);
1728}
1729
1730#ifdef SIGINFO
1731RETSIGTYPE requestinfo(int signo _U_)
1732{
1733	if (infodelay)
1734		++infoprint;
1735	else
1736		info(0);
1737}
1738#endif
1739
1740/*
1741 * Called once each second in verbose mode while dumping to file
1742 */
1743#ifdef USE_WIN32_MM_TIMER
1744void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_,
1745				  DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_)
1746{
1747	struct pcap_stat stat;
1748
1749	if (infodelay == 0 && pcap_stats(pd, &stat) >= 0)
1750		fprintf(stderr, "Got %u\r", packets_captured);
1751}
1752#elif defined(HAVE_ALARM)
1753static void verbose_stats_dump(int sig _U_)
1754{
1755	struct pcap_stat stat;
1756
1757	if (infodelay == 0 && pcap_stats(pd, &stat) >= 0)
1758		fprintf(stderr, "Got %u\r", packets_captured);
1759	alarm(1);
1760}
1761#endif
1762
1763static void
1764usage(void)
1765{
1766	extern char version[];
1767#ifndef HAVE_PCAP_LIB_VERSION
1768#if defined(WIN32) || defined(HAVE_PCAP_VERSION)
1769	extern char pcap_version[];
1770#else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */
1771	static char pcap_version[] = "unknown";
1772#endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */
1773#endif /* HAVE_PCAP_LIB_VERSION */
1774
1775#ifdef HAVE_PCAP_LIB_VERSION
1776#ifdef WIN32
1777	(void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version);
1778#else /* WIN32 */
1779	(void)fprintf(stderr, "%s version %s\n", program_name, version);
1780#endif /* WIN32 */
1781	(void)fprintf(stderr, "%s\n",pcap_lib_version());
1782#else /* HAVE_PCAP_LIB_VERSION */
1783#ifdef WIN32
1784	(void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version);
1785	(void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version);
1786#else /* WIN32 */
1787	(void)fprintf(stderr, "%s version %s\n", program_name, version);
1788	(void)fprintf(stderr, "libpcap version %s\n", pcap_version);
1789#endif /* WIN32 */
1790#endif /* HAVE_PCAP_LIB_VERSION */
1791	(void)fprintf(stderr,
1792"Usage: %s [-aAbd" D_FLAG "ef" I_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
1793	(void)fprintf(stderr,
1794"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n");
1795	(void)fprintf(stderr,
1796"\t\t[ -i interface ] [ -M secret ] [ -r file ]\n");
1797	(void)fprintf(stderr,
1798"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n");
1799	(void)fprintf(stderr,
1800"\t\t[ -y datalinktype ] [ -z command ] [ -Z user ]\n");
1801	(void)fprintf(stderr,
1802"\t\t[ expression ]\n");
1803	exit(1);
1804}
1805
1806
1807
1808/* VARARGS */
1809static void
1810ndo_error(netdissect_options *ndo _U_, const char *fmt, ...)
1811{
1812	va_list ap;
1813
1814	(void)fprintf(stderr, "%s: ", program_name);
1815	va_start(ap, fmt);
1816	(void)vfprintf(stderr, fmt, ap);
1817	va_end(ap);
1818	if (*fmt) {
1819		fmt += strlen(fmt);
1820		if (fmt[-1] != '\n')
1821			(void)fputc('\n', stderr);
1822	}
1823	exit(1);
1824	/* NOTREACHED */
1825}
1826
1827/* VARARGS */
1828static void
1829ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...)
1830{
1831	va_list ap;
1832
1833	(void)fprintf(stderr, "%s: WARNING: ", program_name);
1834	va_start(ap, fmt);
1835	(void)vfprintf(stderr, fmt, ap);
1836	va_end(ap);
1837	if (*fmt) {
1838		fmt += strlen(fmt);
1839		if (fmt[-1] != '\n')
1840			(void)fputc('\n', stderr);
1841	}
1842}
1843