1*05b00f60SXin Li /*
2*05b00f60SXin Li * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
3*05b00f60SXin Li * The Regents of the University of California. All rights reserved.
4*05b00f60SXin Li *
5*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without
6*05b00f60SXin Li * modification, are permitted provided that: (1) source code distributions
7*05b00f60SXin Li * retain the above copyright notice and this paragraph in its entirety, (2)
8*05b00f60SXin Li * distributions including binary code include the above copyright notice and
9*05b00f60SXin Li * this paragraph in its entirety in the documentation or other materials
10*05b00f60SXin Li * provided with the distribution, and (3) all advertising materials mentioning
11*05b00f60SXin Li * features or use of this software display the following acknowledgement:
12*05b00f60SXin Li * ``This product includes software developed by the University of California,
13*05b00f60SXin Li * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14*05b00f60SXin Li * the University nor the names of its contributors may be used to endorse
15*05b00f60SXin Li * or promote products derived from this software without specific prior
16*05b00f60SXin Li * written permission.
17*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18*05b00f60SXin Li * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19*05b00f60SXin Li * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20*05b00f60SXin Li *
21*05b00f60SXin Li * Support for splitting captures into multiple files with a maximum
22*05b00f60SXin Li * file size:
23*05b00f60SXin Li *
24*05b00f60SXin Li * Copyright (c) 2001
25*05b00f60SXin Li * Seth Webster <[email protected]>
26*05b00f60SXin Li */
27*05b00f60SXin Li
28*05b00f60SXin Li /*
29*05b00f60SXin Li * tcpdump - dump traffic on a network
30*05b00f60SXin Li *
31*05b00f60SXin Li * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
32*05b00f60SXin Li * Mercilessly hacked and occasionally improved since then via the
33*05b00f60SXin Li * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
34*05b00f60SXin Li */
35*05b00f60SXin Li
36*05b00f60SXin Li #ifdef HAVE_CONFIG_H
37*05b00f60SXin Li #include <config.h>
38*05b00f60SXin Li #endif
39*05b00f60SXin Li
40*05b00f60SXin Li /*
41*05b00f60SXin Li * Some older versions of Mac OS X may ship pcap.h from libpcap 0.6 with a
42*05b00f60SXin Li * libpcap based on 0.8. That means it has pcap_findalldevs() but the
43*05b00f60SXin Li * header doesn't define pcap_if_t, meaning that we can't actually *use*
44*05b00f60SXin Li * pcap_findalldevs().
45*05b00f60SXin Li */
46*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
47*05b00f60SXin Li #ifndef HAVE_PCAP_IF_T
48*05b00f60SXin Li #undef HAVE_PCAP_FINDALLDEVS
49*05b00f60SXin Li #endif
50*05b00f60SXin Li #endif
51*05b00f60SXin Li
52*05b00f60SXin Li #include "netdissect-stdinc.h"
53*05b00f60SXin Li
54*05b00f60SXin Li /*
55*05b00f60SXin Li * This must appear after including netdissect-stdinc.h, so that _U_ is
56*05b00f60SXin Li * defined.
57*05b00f60SXin Li */
58*05b00f60SXin Li #ifndef lint
59*05b00f60SXin Li static const char copyright[] _U_ =
60*05b00f60SXin Li "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
61*05b00f60SXin Li The Regents of the University of California. All rights reserved.\n";
62*05b00f60SXin Li #endif
63*05b00f60SXin Li
64*05b00f60SXin Li #include <sys/stat.h>
65*05b00f60SXin Li
66*05b00f60SXin Li #ifdef HAVE_FCNTL_H
67*05b00f60SXin Li #include <fcntl.h>
68*05b00f60SXin Li #endif
69*05b00f60SXin Li
70*05b00f60SXin Li #ifdef HAVE_LIBCRYPTO
71*05b00f60SXin Li #include <openssl/crypto.h>
72*05b00f60SXin Li #endif
73*05b00f60SXin Li
74*05b00f60SXin Li #ifdef HAVE_GETOPT_LONG
75*05b00f60SXin Li #include <getopt.h>
76*05b00f60SXin Li #else
77*05b00f60SXin Li #include "missing/getopt_long.h"
78*05b00f60SXin Li #endif
79*05b00f60SXin Li /* Capsicum-specific code requires macros from <net/bpf.h>, which will fail
80*05b00f60SXin Li * to compile if <pcap.h> has already been included; including the headers
81*05b00f60SXin Li * in the opposite order works fine. For the most part anyway, because in
82*05b00f60SXin Li * FreeBSD <pcap/pcap.h> declares bpf_dump() instead of <net/bpf.h>. Thus
83*05b00f60SXin Li * interface.h takes care of it later to avoid a compiler warning.
84*05b00f60SXin Li */
85*05b00f60SXin Li #ifdef HAVE_CAPSICUM
86*05b00f60SXin Li #include <sys/capsicum.h>
87*05b00f60SXin Li #include <sys/ioccom.h>
88*05b00f60SXin Li #include <net/bpf.h>
89*05b00f60SXin Li #include <libgen.h>
90*05b00f60SXin Li #ifdef HAVE_CASPER
91*05b00f60SXin Li #include <libcasper.h>
92*05b00f60SXin Li #include <casper/cap_dns.h>
93*05b00f60SXin Li #include <sys/nv.h>
94*05b00f60SXin Li #endif /* HAVE_CASPER */
95*05b00f60SXin Li #endif /* HAVE_CAPSICUM */
96*05b00f60SXin Li #ifdef HAVE_PCAP_OPEN
97*05b00f60SXin Li /*
98*05b00f60SXin Li * We found pcap_open() in the capture library, so we'll be using
99*05b00f60SXin Li * the remote capture APIs; define PCAP_REMOTE before we include pcap.h,
100*05b00f60SXin Li * so we get those APIs declared, and the types and #defines that they
101*05b00f60SXin Li * use defined.
102*05b00f60SXin Li *
103*05b00f60SXin Li * WinPcap's headers require that PCAP_REMOTE be defined in order to get
104*05b00f60SXin Li * remote-capture APIs declared and types and #defines that they use
105*05b00f60SXin Li * defined.
106*05b00f60SXin Li *
107*05b00f60SXin Li * (Versions of libpcap with those APIs, and thus Npcap, which is based on
108*05b00f60SXin Li * those versions of libpcap, don't require it.)
109*05b00f60SXin Li */
110*05b00f60SXin Li #define HAVE_REMOTE
111*05b00f60SXin Li #endif
112*05b00f60SXin Li #include <pcap.h>
113*05b00f60SXin Li #include <signal.h>
114*05b00f60SXin Li #include <stdio.h>
115*05b00f60SXin Li #include <stdarg.h>
116*05b00f60SXin Li #include <stdlib.h>
117*05b00f60SXin Li #include <string.h>
118*05b00f60SXin Li #include <limits.h>
119*05b00f60SXin Li #ifdef _WIN32
120*05b00f60SXin Li #include <windows.h>
121*05b00f60SXin Li #else
122*05b00f60SXin Li #include <sys/time.h>
123*05b00f60SXin Li #include <sys/wait.h>
124*05b00f60SXin Li #include <sys/resource.h>
125*05b00f60SXin Li #include <pwd.h>
126*05b00f60SXin Li #include <grp.h>
127*05b00f60SXin Li #endif /* _WIN32 */
128*05b00f60SXin Li
129*05b00f60SXin Li /*
130*05b00f60SXin Li * Pathname separator.
131*05b00f60SXin Li * Use this in pathnames, but do *not* use it in URLs.
132*05b00f60SXin Li */
133*05b00f60SXin Li #ifdef _WIN32
134*05b00f60SXin Li #define PATH_SEPARATOR '\\'
135*05b00f60SXin Li #else
136*05b00f60SXin Li #define PATH_SEPARATOR '/'
137*05b00f60SXin Li #endif
138*05b00f60SXin Li
139*05b00f60SXin Li /* capabilities convenience library */
140*05b00f60SXin Li /* If a code depends on HAVE_LIBCAP_NG, it depends also on HAVE_CAP_NG_H.
141*05b00f60SXin Li * If HAVE_CAP_NG_H is not defined, undefine HAVE_LIBCAP_NG.
142*05b00f60SXin Li * Thus, the later tests are done only on HAVE_LIBCAP_NG.
143*05b00f60SXin Li */
144*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
145*05b00f60SXin Li #ifdef HAVE_CAP_NG_H
146*05b00f60SXin Li #include <cap-ng.h>
147*05b00f60SXin Li #else
148*05b00f60SXin Li #undef HAVE_LIBCAP_NG
149*05b00f60SXin Li #endif /* HAVE_CAP_NG_H */
150*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
151*05b00f60SXin Li
152*05b00f60SXin Li #ifdef __FreeBSD__
153*05b00f60SXin Li #include <sys/sysctl.h>
154*05b00f60SXin Li #endif /* __FreeBSD__ */
155*05b00f60SXin Li
156*05b00f60SXin Li #include "netdissect-stdinc.h"
157*05b00f60SXin Li #include "netdissect.h"
158*05b00f60SXin Li #include "interface.h"
159*05b00f60SXin Li #include "addrtoname.h"
160*05b00f60SXin Li #include "machdep.h"
161*05b00f60SXin Li #include "pcap-missing.h"
162*05b00f60SXin Li #include "ascii_strcasecmp.h"
163*05b00f60SXin Li
164*05b00f60SXin Li #include "print.h"
165*05b00f60SXin Li
166*05b00f60SXin Li #include "diag-control.h"
167*05b00f60SXin Li
168*05b00f60SXin Li #include "fptype.h"
169*05b00f60SXin Li
170*05b00f60SXin Li #ifndef PATH_MAX
171*05b00f60SXin Li #define PATH_MAX 1024
172*05b00f60SXin Li #endif
173*05b00f60SXin Li
174*05b00f60SXin Li #if defined(SIGINFO)
175*05b00f60SXin Li #define SIGNAL_REQ_INFO SIGINFO
176*05b00f60SXin Li #elif defined(SIGUSR1)
177*05b00f60SXin Li #define SIGNAL_REQ_INFO SIGUSR1
178*05b00f60SXin Li #endif
179*05b00f60SXin Li
180*05b00f60SXin Li #if defined(HAVE_PCAP_DUMP_FLUSH) && defined(SIGUSR2)
181*05b00f60SXin Li #define SIGNAL_FLUSH_PCAP SIGUSR2
182*05b00f60SXin Li #endif
183*05b00f60SXin Li
184*05b00f60SXin Li #if defined(HAVE_PCAP_CREATE) || defined(_WIN32)
185*05b00f60SXin Li static int Bflag; /* buffer size */
186*05b00f60SXin Li #endif
187*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FTELL64
188*05b00f60SXin Li static int64_t Cflag; /* rotate dump files after this many bytes */
189*05b00f60SXin Li #else
190*05b00f60SXin Li static long Cflag; /* rotate dump files after this many bytes */
191*05b00f60SXin Li #endif
192*05b00f60SXin Li static int Cflag_count; /* Keep track of which file number we're writing */
193*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
194*05b00f60SXin Li static int Dflag; /* list available devices and exit */
195*05b00f60SXin Li #endif
196*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
197*05b00f60SXin Li static char *remote_interfaces_source; /* list available devices from this source and exit */
198*05b00f60SXin Li #endif
199*05b00f60SXin Li
200*05b00f60SXin Li /*
201*05b00f60SXin Li * This is exported because, in some versions of libpcap, if libpcap
202*05b00f60SXin Li * is built with optimizer debugging code (which is *NOT* the default
203*05b00f60SXin Li * configuration!), the library *imports*(!) a variable named dflag,
204*05b00f60SXin Li * under the expectation that tcpdump is exporting it, to govern
205*05b00f60SXin Li * how much debugging information to print when optimizing
206*05b00f60SXin Li * the generated BPF code.
207*05b00f60SXin Li *
208*05b00f60SXin Li * This is a horrible hack; newer versions of libpcap don't import
209*05b00f60SXin Li * dflag but, instead, *if* built with optimizer debugging code,
210*05b00f60SXin Li * *export* a routine to set that flag.
211*05b00f60SXin Li */
212*05b00f60SXin Li extern int dflag;
213*05b00f60SXin Li int dflag; /* print filter code */
214*05b00f60SXin Li static int Gflag; /* rotate dump files after this many seconds */
215*05b00f60SXin Li static int Gflag_count; /* number of files created with Gflag rotation */
216*05b00f60SXin Li static time_t Gflag_time; /* The last time_t the dump file was rotated. */
217*05b00f60SXin Li static int Lflag; /* list available data link types and exit */
218*05b00f60SXin Li static int Iflag; /* rfmon (monitor) mode */
219*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
220*05b00f60SXin Li static int Jflag; /* list available time stamp types */
221*05b00f60SXin Li static int jflag = -1; /* packet time stamp source */
222*05b00f60SXin Li #endif
223*05b00f60SXin Li static int lflag; /* line-buffered output */
224*05b00f60SXin Li static int pflag; /* don't go promiscuous */
225*05b00f60SXin Li #ifdef HAVE_PCAP_SETDIRECTION
226*05b00f60SXin Li static int Qflag = -1; /* restrict captured packet by send/receive direction */
227*05b00f60SXin Li #endif
228*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
229*05b00f60SXin Li static int Uflag; /* "unbuffered" output of dump files */
230*05b00f60SXin Li #endif
231*05b00f60SXin Li static int Wflag; /* recycle output files after this number of files */
232*05b00f60SXin Li static int WflagChars;
233*05b00f60SXin Li static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */
234*05b00f60SXin Li static int timeout = 1000; /* default timeout = 1000 ms = 1 s */
235*05b00f60SXin Li #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
236*05b00f60SXin Li static int immediate_mode;
237*05b00f60SXin Li #endif
238*05b00f60SXin Li static int count_mode;
239*05b00f60SXin Li
240*05b00f60SXin Li static int infodelay;
241*05b00f60SXin Li static int infoprint;
242*05b00f60SXin Li
243*05b00f60SXin Li char *program_name;
244*05b00f60SXin Li
245*05b00f60SXin Li /* Forwards */
246*05b00f60SXin Li static NORETURN void error(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2);
247*05b00f60SXin Li static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2);
248*05b00f60SXin Li static NORETURN void exit_tcpdump(int);
249*05b00f60SXin Li static void (*setsignal (int sig, void (*func)(int)))(int);
250*05b00f60SXin Li static void cleanup(int);
251*05b00f60SXin Li static void child_cleanup(int);
252*05b00f60SXin Li static void print_version(FILE *);
253*05b00f60SXin Li static void print_usage(FILE *);
254*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
255*05b00f60SXin Li static NORETURN void show_tstamp_types_and_exit(pcap_t *, const char *device);
256*05b00f60SXin Li #endif
257*05b00f60SXin Li static NORETURN void show_dlts_and_exit(pcap_t *, const char *device);
258*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
259*05b00f60SXin Li static NORETURN void show_devices_and_exit(void);
260*05b00f60SXin Li #endif
261*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
262*05b00f60SXin Li static NORETURN void show_remote_devices_and_exit(void);
263*05b00f60SXin Li #endif
264*05b00f60SXin Li
265*05b00f60SXin Li static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
266*05b00f60SXin Li static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
267*05b00f60SXin Li static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
268*05b00f60SXin Li static void droproot(const char *, const char *);
269*05b00f60SXin Li
270*05b00f60SXin Li #ifdef SIGNAL_REQ_INFO
271*05b00f60SXin Li static void requestinfo(int);
272*05b00f60SXin Li #endif
273*05b00f60SXin Li
274*05b00f60SXin Li #ifdef SIGNAL_FLUSH_PCAP
275*05b00f60SXin Li static void flushpcap(int);
276*05b00f60SXin Li #endif
277*05b00f60SXin Li
278*05b00f60SXin Li #ifdef _WIN32
279*05b00f60SXin Li static HANDLE timer_handle = INVALID_HANDLE_VALUE;
280*05b00f60SXin Li static void CALLBACK verbose_stats_dump(PVOID param, BOOLEAN timer_fired);
281*05b00f60SXin Li #else /* _WIN32 */
282*05b00f60SXin Li static void verbose_stats_dump(int sig);
283*05b00f60SXin Li #endif /* _WIN32 */
284*05b00f60SXin Li
285*05b00f60SXin Li static void info(int);
286*05b00f60SXin Li static u_int packets_captured;
287*05b00f60SXin Li
288*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
289*05b00f60SXin Li static const struct tok status_flags[] = {
290*05b00f60SXin Li #ifdef PCAP_IF_UP
291*05b00f60SXin Li { PCAP_IF_UP, "Up" },
292*05b00f60SXin Li #endif
293*05b00f60SXin Li #ifdef PCAP_IF_RUNNING
294*05b00f60SXin Li { PCAP_IF_RUNNING, "Running" },
295*05b00f60SXin Li #endif
296*05b00f60SXin Li { PCAP_IF_LOOPBACK, "Loopback" },
297*05b00f60SXin Li #ifdef PCAP_IF_WIRELESS
298*05b00f60SXin Li { PCAP_IF_WIRELESS, "Wireless" },
299*05b00f60SXin Li #endif
300*05b00f60SXin Li { 0, NULL }
301*05b00f60SXin Li };
302*05b00f60SXin Li #endif
303*05b00f60SXin Li
304*05b00f60SXin Li static pcap_t *pd;
305*05b00f60SXin Li static pcap_dumper_t *pdd = NULL;
306*05b00f60SXin Li
307*05b00f60SXin Li static int supports_monitor_mode;
308*05b00f60SXin Li
309*05b00f60SXin Li extern int optind;
310*05b00f60SXin Li extern int opterr;
311*05b00f60SXin Li extern char *optarg;
312*05b00f60SXin Li
313*05b00f60SXin Li struct dump_info {
314*05b00f60SXin Li char *WFileName;
315*05b00f60SXin Li char *CurrentFileName;
316*05b00f60SXin Li pcap_t *pd;
317*05b00f60SXin Li pcap_dumper_t *pdd;
318*05b00f60SXin Li netdissect_options *ndo;
319*05b00f60SXin Li #ifdef HAVE_CAPSICUM
320*05b00f60SXin Li int dirfd;
321*05b00f60SXin Li #endif
322*05b00f60SXin Li };
323*05b00f60SXin Li
324*05b00f60SXin Li #if defined(HAVE_PCAP_SET_PARSER_DEBUG)
325*05b00f60SXin Li /*
326*05b00f60SXin Li * We have pcap_set_parser_debug() in libpcap; declare it (it's not declared
327*05b00f60SXin Li * by any libpcap header, because it's a special hack, only available if
328*05b00f60SXin Li * libpcap was configured to include it, and only intended for use by
329*05b00f60SXin Li * libpcap developers trying to debug the parser for filter expressions).
330*05b00f60SXin Li */
331*05b00f60SXin Li #ifdef _WIN32
332*05b00f60SXin Li __declspec(dllimport)
333*05b00f60SXin Li #else /* _WIN32 */
334*05b00f60SXin Li extern
335*05b00f60SXin Li #endif /* _WIN32 */
336*05b00f60SXin Li void pcap_set_parser_debug(int);
337*05b00f60SXin Li #elif defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
338*05b00f60SXin Li /*
339*05b00f60SXin Li * We don't have pcap_set_parser_debug() in libpcap, but we do have
340*05b00f60SXin Li * pcap_debug or yydebug. Make a local version of pcap_set_parser_debug()
341*05b00f60SXin Li * to set the flag, and define HAVE_PCAP_SET_PARSER_DEBUG.
342*05b00f60SXin Li */
343*05b00f60SXin Li static void
pcap_set_parser_debug(int value)344*05b00f60SXin Li pcap_set_parser_debug(int value)
345*05b00f60SXin Li {
346*05b00f60SXin Li #ifdef HAVE_PCAP_DEBUG
347*05b00f60SXin Li extern int pcap_debug;
348*05b00f60SXin Li
349*05b00f60SXin Li pcap_debug = value;
350*05b00f60SXin Li #else /* HAVE_PCAP_DEBUG */
351*05b00f60SXin Li extern int yydebug;
352*05b00f60SXin Li
353*05b00f60SXin Li yydebug = value;
354*05b00f60SXin Li #endif /* HAVE_PCAP_DEBUG */
355*05b00f60SXin Li }
356*05b00f60SXin Li
357*05b00f60SXin Li #define HAVE_PCAP_SET_PARSER_DEBUG
358*05b00f60SXin Li #endif
359*05b00f60SXin Li
360*05b00f60SXin Li #if defined(HAVE_PCAP_SET_OPTIMIZER_DEBUG)
361*05b00f60SXin Li /*
362*05b00f60SXin Li * We have pcap_set_optimizer_debug() in libpcap; declare it (it's not declared
363*05b00f60SXin Li * by any libpcap header, because it's a special hack, only available if
364*05b00f60SXin Li * libpcap was configured to include it, and only intended for use by
365*05b00f60SXin Li * libpcap developers trying to debug the optimizer for filter expressions).
366*05b00f60SXin Li */
367*05b00f60SXin Li #ifdef _WIN32
368*05b00f60SXin Li __declspec(dllimport)
369*05b00f60SXin Li #else /* _WIN32 */
370*05b00f60SXin Li extern
371*05b00f60SXin Li #endif /* _WIN32 */
372*05b00f60SXin Li void pcap_set_optimizer_debug(int);
373*05b00f60SXin Li #endif
374*05b00f60SXin Li
375*05b00f60SXin Li /* VARARGS */
376*05b00f60SXin Li static void
error(const char * fmt,...)377*05b00f60SXin Li error(const char *fmt, ...)
378*05b00f60SXin Li {
379*05b00f60SXin Li va_list ap;
380*05b00f60SXin Li
381*05b00f60SXin Li (void)fprintf(stderr, "%s: ", program_name);
382*05b00f60SXin Li va_start(ap, fmt);
383*05b00f60SXin Li (void)vfprintf(stderr, fmt, ap);
384*05b00f60SXin Li va_end(ap);
385*05b00f60SXin Li if (*fmt) {
386*05b00f60SXin Li fmt += strlen(fmt);
387*05b00f60SXin Li if (fmt[-1] != '\n')
388*05b00f60SXin Li (void)fputc('\n', stderr);
389*05b00f60SXin Li }
390*05b00f60SXin Li exit_tcpdump(S_ERR_HOST_PROGRAM);
391*05b00f60SXin Li /* NOTREACHED */
392*05b00f60SXin Li }
393*05b00f60SXin Li
394*05b00f60SXin Li /* VARARGS */
395*05b00f60SXin Li static void
warning(const char * fmt,...)396*05b00f60SXin Li warning(const char *fmt, ...)
397*05b00f60SXin Li {
398*05b00f60SXin Li va_list ap;
399*05b00f60SXin Li
400*05b00f60SXin Li (void)fprintf(stderr, "%s: WARNING: ", program_name);
401*05b00f60SXin Li va_start(ap, fmt);
402*05b00f60SXin Li (void)vfprintf(stderr, fmt, ap);
403*05b00f60SXin Li va_end(ap);
404*05b00f60SXin Li if (*fmt) {
405*05b00f60SXin Li fmt += strlen(fmt);
406*05b00f60SXin Li if (fmt[-1] != '\n')
407*05b00f60SXin Li (void)fputc('\n', stderr);
408*05b00f60SXin Li }
409*05b00f60SXin Li }
410*05b00f60SXin Li
411*05b00f60SXin Li static void
exit_tcpdump(int status)412*05b00f60SXin Li exit_tcpdump(int status)
413*05b00f60SXin Li {
414*05b00f60SXin Li nd_cleanup();
415*05b00f60SXin Li exit(status);
416*05b00f60SXin Li }
417*05b00f60SXin Li
418*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
419*05b00f60SXin Li static void
show_tstamp_types_and_exit(pcap_t * pc,const char * device)420*05b00f60SXin Li show_tstamp_types_and_exit(pcap_t *pc, const char *device)
421*05b00f60SXin Li {
422*05b00f60SXin Li int n_tstamp_types;
423*05b00f60SXin Li int *tstamp_types = 0;
424*05b00f60SXin Li const char *tstamp_type_name;
425*05b00f60SXin Li int i;
426*05b00f60SXin Li
427*05b00f60SXin Li n_tstamp_types = pcap_list_tstamp_types(pc, &tstamp_types);
428*05b00f60SXin Li if (n_tstamp_types < 0)
429*05b00f60SXin Li error("%s", pcap_geterr(pc));
430*05b00f60SXin Li
431*05b00f60SXin Li if (n_tstamp_types == 0) {
432*05b00f60SXin Li fprintf(stderr, "Time stamp type cannot be set for %s\n",
433*05b00f60SXin Li device);
434*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
435*05b00f60SXin Li }
436*05b00f60SXin Li fprintf(stderr, "Time stamp types for %s (use option -j to set):\n",
437*05b00f60SXin Li device);
438*05b00f60SXin Li for (i = 0; i < n_tstamp_types; i++) {
439*05b00f60SXin Li tstamp_type_name = pcap_tstamp_type_val_to_name(tstamp_types[i]);
440*05b00f60SXin Li if (tstamp_type_name != NULL) {
441*05b00f60SXin Li (void) fprintf(stderr, " %s (%s)\n", tstamp_type_name,
442*05b00f60SXin Li pcap_tstamp_type_val_to_description(tstamp_types[i]));
443*05b00f60SXin Li } else {
444*05b00f60SXin Li (void) fprintf(stderr, " %d\n", tstamp_types[i]);
445*05b00f60SXin Li }
446*05b00f60SXin Li }
447*05b00f60SXin Li pcap_free_tstamp_types(tstamp_types);
448*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
449*05b00f60SXin Li }
450*05b00f60SXin Li #endif
451*05b00f60SXin Li
452*05b00f60SXin Li static void
show_dlts_and_exit(pcap_t * pc,const char * device)453*05b00f60SXin Li show_dlts_and_exit(pcap_t *pc, const char *device)
454*05b00f60SXin Li {
455*05b00f60SXin Li int n_dlts, i;
456*05b00f60SXin Li int *dlts = 0;
457*05b00f60SXin Li const char *dlt_name;
458*05b00f60SXin Li
459*05b00f60SXin Li n_dlts = pcap_list_datalinks(pc, &dlts);
460*05b00f60SXin Li if (n_dlts < 0)
461*05b00f60SXin Li error("%s", pcap_geterr(pc));
462*05b00f60SXin Li else if (n_dlts == 0 || !dlts)
463*05b00f60SXin Li error("No data link types.");
464*05b00f60SXin Li
465*05b00f60SXin Li /*
466*05b00f60SXin Li * If the interface is known to support monitor mode, indicate
467*05b00f60SXin Li * whether these are the data link types available when not in
468*05b00f60SXin Li * monitor mode, if -I wasn't specified, or when in monitor mode,
469*05b00f60SXin Li * when -I was specified (the link-layer types available in
470*05b00f60SXin Li * monitor mode might be different from the ones available when
471*05b00f60SXin Li * not in monitor mode).
472*05b00f60SXin Li */
473*05b00f60SXin Li if (supports_monitor_mode)
474*05b00f60SXin Li (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n",
475*05b00f60SXin Li device,
476*05b00f60SXin Li Iflag ? "when in monitor mode" : "when not in monitor mode");
477*05b00f60SXin Li else
478*05b00f60SXin Li (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n",
479*05b00f60SXin Li device);
480*05b00f60SXin Li
481*05b00f60SXin Li for (i = 0; i < n_dlts; i++) {
482*05b00f60SXin Li dlt_name = pcap_datalink_val_to_name(dlts[i]);
483*05b00f60SXin Li if (dlt_name != NULL) {
484*05b00f60SXin Li (void) fprintf(stderr, " %s (%s)", dlt_name,
485*05b00f60SXin Li pcap_datalink_val_to_description(dlts[i]));
486*05b00f60SXin Li
487*05b00f60SXin Li /*
488*05b00f60SXin Li * OK, does tcpdump handle that type?
489*05b00f60SXin Li */
490*05b00f60SXin Li if (!has_printer(dlts[i]))
491*05b00f60SXin Li (void) fprintf(stderr, " (printing not supported)");
492*05b00f60SXin Li fprintf(stderr, "\n");
493*05b00f60SXin Li } else {
494*05b00f60SXin Li (void) fprintf(stderr, " DLT %d (printing not supported)\n",
495*05b00f60SXin Li dlts[i]);
496*05b00f60SXin Li }
497*05b00f60SXin Li }
498*05b00f60SXin Li #ifdef HAVE_PCAP_FREE_DATALINKS
499*05b00f60SXin Li pcap_free_datalinks(dlts);
500*05b00f60SXin Li #endif
501*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
502*05b00f60SXin Li }
503*05b00f60SXin Li
504*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
505*05b00f60SXin Li static void
show_devices_and_exit(void)506*05b00f60SXin Li show_devices_and_exit(void)
507*05b00f60SXin Li {
508*05b00f60SXin Li pcap_if_t *dev, *devlist;
509*05b00f60SXin Li char ebuf[PCAP_ERRBUF_SIZE];
510*05b00f60SXin Li int i;
511*05b00f60SXin Li
512*05b00f60SXin Li if (pcap_findalldevs(&devlist, ebuf) < 0)
513*05b00f60SXin Li error("%s", ebuf);
514*05b00f60SXin Li for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) {
515*05b00f60SXin Li printf("%d.%s", i+1, dev->name);
516*05b00f60SXin Li if (dev->description != NULL)
517*05b00f60SXin Li printf(" (%s)", dev->description);
518*05b00f60SXin Li if (dev->flags != 0) {
519*05b00f60SXin Li printf(" [");
520*05b00f60SXin Li printf("%s", bittok2str(status_flags, "none", dev->flags));
521*05b00f60SXin Li #ifdef PCAP_IF_WIRELESS
522*05b00f60SXin Li if (dev->flags & PCAP_IF_WIRELESS) {
523*05b00f60SXin Li switch (dev->flags & PCAP_IF_CONNECTION_STATUS) {
524*05b00f60SXin Li
525*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
526*05b00f60SXin Li printf(", Association status unknown");
527*05b00f60SXin Li break;
528*05b00f60SXin Li
529*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_CONNECTED:
530*05b00f60SXin Li printf(", Associated");
531*05b00f60SXin Li break;
532*05b00f60SXin Li
533*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
534*05b00f60SXin Li printf(", Not associated");
535*05b00f60SXin Li break;
536*05b00f60SXin Li
537*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
538*05b00f60SXin Li break;
539*05b00f60SXin Li }
540*05b00f60SXin Li } else {
541*05b00f60SXin Li switch (dev->flags & PCAP_IF_CONNECTION_STATUS) {
542*05b00f60SXin Li
543*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
544*05b00f60SXin Li printf(", Connection status unknown");
545*05b00f60SXin Li break;
546*05b00f60SXin Li
547*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_CONNECTED:
548*05b00f60SXin Li printf(", Connected");
549*05b00f60SXin Li break;
550*05b00f60SXin Li
551*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
552*05b00f60SXin Li printf(", Disconnected");
553*05b00f60SXin Li break;
554*05b00f60SXin Li
555*05b00f60SXin Li case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
556*05b00f60SXin Li break;
557*05b00f60SXin Li }
558*05b00f60SXin Li }
559*05b00f60SXin Li #endif
560*05b00f60SXin Li printf("]");
561*05b00f60SXin Li }
562*05b00f60SXin Li printf("\n");
563*05b00f60SXin Li }
564*05b00f60SXin Li pcap_freealldevs(devlist);
565*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
566*05b00f60SXin Li }
567*05b00f60SXin Li #endif /* HAVE_PCAP_FINDALLDEVS */
568*05b00f60SXin Li
569*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
570*05b00f60SXin Li static void
show_remote_devices_and_exit(void)571*05b00f60SXin Li show_remote_devices_and_exit(void)
572*05b00f60SXin Li {
573*05b00f60SXin Li pcap_if_t *dev, *devlist;
574*05b00f60SXin Li char ebuf[PCAP_ERRBUF_SIZE];
575*05b00f60SXin Li int i;
576*05b00f60SXin Li
577*05b00f60SXin Li if (pcap_findalldevs_ex(remote_interfaces_source, NULL, &devlist,
578*05b00f60SXin Li ebuf) < 0)
579*05b00f60SXin Li error("%s", ebuf);
580*05b00f60SXin Li for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) {
581*05b00f60SXin Li printf("%d.%s", i+1, dev->name);
582*05b00f60SXin Li if (dev->description != NULL)
583*05b00f60SXin Li printf(" (%s)", dev->description);
584*05b00f60SXin Li if (dev->flags != 0)
585*05b00f60SXin Li printf(" [%s]", bittok2str(status_flags, "none", dev->flags));
586*05b00f60SXin Li printf("\n");
587*05b00f60SXin Li }
588*05b00f60SXin Li pcap_freealldevs(devlist);
589*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
590*05b00f60SXin Li }
591*05b00f60SXin Li #endif /* HAVE_PCAP_FINDALLDEVS */
592*05b00f60SXin Li
593*05b00f60SXin Li /*
594*05b00f60SXin Li * Short options.
595*05b00f60SXin Li *
596*05b00f60SXin Li * Note that there we use all letters for short options except for g, k,
597*05b00f60SXin Li * o, and P, and those are used by other versions of tcpdump, and we should
598*05b00f60SXin Li * only use them for the same purposes that the other versions of tcpdump
599*05b00f60SXin Li * use them:
600*05b00f60SXin Li *
601*05b00f60SXin Li * macOS tcpdump uses -g to force non--v output for IP to be on one
602*05b00f60SXin Li * line, making it more "g"repable;
603*05b00f60SXin Li *
604*05b00f60SXin Li * macOS tcpdump uses -k to specify that packet comments in pcapng files
605*05b00f60SXin Li * should be printed;
606*05b00f60SXin Li *
607*05b00f60SXin Li * OpenBSD tcpdump uses -o to indicate that OS fingerprinting should be done
608*05b00f60SXin Li * for hosts sending TCP SYN packets;
609*05b00f60SXin Li *
610*05b00f60SXin Li * macOS tcpdump uses -P to indicate that -w should write pcapng rather
611*05b00f60SXin Li * than pcap files.
612*05b00f60SXin Li *
613*05b00f60SXin Li * macOS tcpdump also uses -Q to specify expressions that match packet
614*05b00f60SXin Li * metadata, including but not limited to the packet direction.
615*05b00f60SXin Li * The expression syntax is different from a simple "in|out|inout",
616*05b00f60SXin Li * and those expressions aren't accepted by macOS tcpdump, but the
617*05b00f60SXin Li * equivalents would be "in" = "dir=in", "out" = "dir=out", and
618*05b00f60SXin Li * "inout" = "dir=in or dir=out", and the parser could conceivably
619*05b00f60SXin Li * special-case "in", "out", and "inout" as expressions for backwards
620*05b00f60SXin Li * compatibility, so all is not (yet) lost.
621*05b00f60SXin Li */
622*05b00f60SXin Li
623*05b00f60SXin Li /*
624*05b00f60SXin Li * Set up flags that might or might not be supported depending on the
625*05b00f60SXin Li * version of libpcap we're using.
626*05b00f60SXin Li */
627*05b00f60SXin Li #if defined(HAVE_PCAP_CREATE) || defined(_WIN32)
628*05b00f60SXin Li #define B_FLAG "B:"
629*05b00f60SXin Li #define B_FLAG_USAGE " [ -B size ]"
630*05b00f60SXin Li #else /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */
631*05b00f60SXin Li #define B_FLAG
632*05b00f60SXin Li #define B_FLAG_USAGE
633*05b00f60SXin Li #endif /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */
634*05b00f60SXin Li
635*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
636*05b00f60SXin Li #define D_FLAG "D"
637*05b00f60SXin Li #else
638*05b00f60SXin Li #define D_FLAG
639*05b00f60SXin Li #endif
640*05b00f60SXin Li
641*05b00f60SXin Li #ifdef HAVE_PCAP_CREATE
642*05b00f60SXin Li #define I_FLAG "I"
643*05b00f60SXin Li #else /* HAVE_PCAP_CREATE */
644*05b00f60SXin Li #define I_FLAG
645*05b00f60SXin Li #endif /* HAVE_PCAP_CREATE */
646*05b00f60SXin Li
647*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
648*05b00f60SXin Li #define j_FLAG "j:"
649*05b00f60SXin Li #define j_FLAG_USAGE " [ -j tstamptype ]"
650*05b00f60SXin Li #define J_FLAG "J"
651*05b00f60SXin Li #else /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */
652*05b00f60SXin Li #define j_FLAG
653*05b00f60SXin Li #define j_FLAG_USAGE
654*05b00f60SXin Li #define J_FLAG
655*05b00f60SXin Li #endif /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */
656*05b00f60SXin Li
657*05b00f60SXin Li #ifdef USE_LIBSMI
658*05b00f60SXin Li #define m_FLAG_USAGE "[ -m module ] ..."
659*05b00f60SXin Li #endif
660*05b00f60SXin Li
661*05b00f60SXin Li #ifdef HAVE_PCAP_SETDIRECTION
662*05b00f60SXin Li #define Q_FLAG "Q:"
663*05b00f60SXin Li #define Q_FLAG_USAGE " [ -Q in|out|inout ]"
664*05b00f60SXin Li #else
665*05b00f60SXin Li #define Q_FLAG
666*05b00f60SXin Li #define Q_FLAG_USAGE
667*05b00f60SXin Li #endif
668*05b00f60SXin Li
669*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
670*05b00f60SXin Li #define U_FLAG "U"
671*05b00f60SXin Li #else
672*05b00f60SXin Li #define U_FLAG
673*05b00f60SXin Li #endif
674*05b00f60SXin Li
675*05b00f60SXin Li #define SHORTOPTS "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:s:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:#"
676*05b00f60SXin Li
677*05b00f60SXin Li /*
678*05b00f60SXin Li * Long options.
679*05b00f60SXin Li *
680*05b00f60SXin Li * We do not currently have long options corresponding to all short
681*05b00f60SXin Li * options; we should probably pick appropriate option names for them.
682*05b00f60SXin Li *
683*05b00f60SXin Li * However, the short options where the number of times the option is
684*05b00f60SXin Li * specified matters, such as -v and -d and -t, should probably not
685*05b00f60SXin Li * just map to a long option, as saying
686*05b00f60SXin Li *
687*05b00f60SXin Li * tcpdump --verbose --verbose
688*05b00f60SXin Li *
689*05b00f60SXin Li * doesn't make sense; it should be --verbosity={N} or something such
690*05b00f60SXin Li * as that.
691*05b00f60SXin Li *
692*05b00f60SXin Li * For long options with no corresponding short options, we define values
693*05b00f60SXin Li * outside the range of ASCII graphic characters, make that the last
694*05b00f60SXin Li * component of the entry for the long option, and have a case for that
695*05b00f60SXin Li * option in the switch statement.
696*05b00f60SXin Li */
697*05b00f60SXin Li #define OPTION_VERSION 128
698*05b00f60SXin Li #define OPTION_TSTAMP_PRECISION 129
699*05b00f60SXin Li #define OPTION_IMMEDIATE_MODE 130
700*05b00f60SXin Li #define OPTION_PRINT 131
701*05b00f60SXin Li #define OPTION_LIST_REMOTE_INTERFACES 132
702*05b00f60SXin Li #define OPTION_TSTAMP_MICRO 133
703*05b00f60SXin Li #define OPTION_TSTAMP_NANO 134
704*05b00f60SXin Li #define OPTION_FP_TYPE 135
705*05b00f60SXin Li #define OPTION_COUNT 136
706*05b00f60SXin Li
707*05b00f60SXin Li static const struct option longopts[] = {
708*05b00f60SXin Li #if defined(HAVE_PCAP_CREATE) || defined(_WIN32)
709*05b00f60SXin Li { "buffer-size", required_argument, NULL, 'B' },
710*05b00f60SXin Li #endif
711*05b00f60SXin Li { "list-interfaces", no_argument, NULL, 'D' },
712*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
713*05b00f60SXin Li { "list-remote-interfaces", required_argument, NULL, OPTION_LIST_REMOTE_INTERFACES },
714*05b00f60SXin Li #endif
715*05b00f60SXin Li { "help", no_argument, NULL, 'h' },
716*05b00f60SXin Li { "interface", required_argument, NULL, 'i' },
717*05b00f60SXin Li #ifdef HAVE_PCAP_CREATE
718*05b00f60SXin Li { "monitor-mode", no_argument, NULL, 'I' },
719*05b00f60SXin Li #endif
720*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
721*05b00f60SXin Li { "time-stamp-type", required_argument, NULL, 'j' },
722*05b00f60SXin Li { "list-time-stamp-types", no_argument, NULL, 'J' },
723*05b00f60SXin Li #endif
724*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
725*05b00f60SXin Li { "micro", no_argument, NULL, OPTION_TSTAMP_MICRO},
726*05b00f60SXin Li { "nano", no_argument, NULL, OPTION_TSTAMP_NANO},
727*05b00f60SXin Li { "time-stamp-precision", required_argument, NULL, OPTION_TSTAMP_PRECISION},
728*05b00f60SXin Li #endif
729*05b00f60SXin Li { "dont-verify-checksums", no_argument, NULL, 'K' },
730*05b00f60SXin Li { "list-data-link-types", no_argument, NULL, 'L' },
731*05b00f60SXin Li { "no-optimize", no_argument, NULL, 'O' },
732*05b00f60SXin Li { "no-promiscuous-mode", no_argument, NULL, 'p' },
733*05b00f60SXin Li #ifdef HAVE_PCAP_SETDIRECTION
734*05b00f60SXin Li { "direction", required_argument, NULL, 'Q' },
735*05b00f60SXin Li #endif
736*05b00f60SXin Li { "snapshot-length", required_argument, NULL, 's' },
737*05b00f60SXin Li { "absolute-tcp-sequence-numbers", no_argument, NULL, 'S' },
738*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
739*05b00f60SXin Li { "packet-buffered", no_argument, NULL, 'U' },
740*05b00f60SXin Li #endif
741*05b00f60SXin Li { "linktype", required_argument, NULL, 'y' },
742*05b00f60SXin Li #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
743*05b00f60SXin Li { "immediate-mode", no_argument, NULL, OPTION_IMMEDIATE_MODE },
744*05b00f60SXin Li #endif
745*05b00f60SXin Li #ifdef HAVE_PCAP_SET_PARSER_DEBUG
746*05b00f60SXin Li { "debug-filter-parser", no_argument, NULL, 'Y' },
747*05b00f60SXin Li #endif
748*05b00f60SXin Li { "relinquish-privileges", required_argument, NULL, 'Z' },
749*05b00f60SXin Li { "count", no_argument, NULL, OPTION_COUNT },
750*05b00f60SXin Li { "fp-type", no_argument, NULL, OPTION_FP_TYPE },
751*05b00f60SXin Li { "number", no_argument, NULL, '#' },
752*05b00f60SXin Li { "print", no_argument, NULL, OPTION_PRINT },
753*05b00f60SXin Li { "version", no_argument, NULL, OPTION_VERSION },
754*05b00f60SXin Li { NULL, 0, NULL, 0 }
755*05b00f60SXin Li };
756*05b00f60SXin Li
757*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
758*05b00f60SXin Li #define LIST_REMOTE_INTERFACES_USAGE "[ --list-remote-interfaces remote-source ]"
759*05b00f60SXin Li #else
760*05b00f60SXin Li #define LIST_REMOTE_INTERFACES_USAGE
761*05b00f60SXin Li #endif
762*05b00f60SXin Li
763*05b00f60SXin Li #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
764*05b00f60SXin Li #define IMMEDIATE_MODE_USAGE " [ --immediate-mode ]"
765*05b00f60SXin Li #else
766*05b00f60SXin Li #define IMMEDIATE_MODE_USAGE ""
767*05b00f60SXin Li #endif
768*05b00f60SXin Li
769*05b00f60SXin Li #ifndef _WIN32
770*05b00f60SXin Li /* Drop root privileges and chroot if necessary */
771*05b00f60SXin Li static void
droproot(const char * username,const char * chroot_dir)772*05b00f60SXin Li droproot(const char *username, const char *chroot_dir)
773*05b00f60SXin Li {
774*05b00f60SXin Li struct passwd *pw = NULL;
775*05b00f60SXin Li
776*05b00f60SXin Li if (chroot_dir && !username)
777*05b00f60SXin Li error("Chroot without dropping root is insecure");
778*05b00f60SXin Li
779*05b00f60SXin Li pw = getpwnam(username);
780*05b00f60SXin Li if (pw) {
781*05b00f60SXin Li if (chroot_dir) {
782*05b00f60SXin Li if (chroot(chroot_dir) != 0 || chdir ("/") != 0)
783*05b00f60SXin Li error("Couldn't chroot/chdir to '%.64s': %s",
784*05b00f60SXin Li chroot_dir, pcap_strerror(errno));
785*05b00f60SXin Li }
786*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
787*05b00f60SXin Li {
788*05b00f60SXin Li int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG);
789*05b00f60SXin Li if (ret < 0)
790*05b00f60SXin Li error("capng_change_id(): return %d\n", ret);
791*05b00f60SXin Li else
792*05b00f60SXin Li fprintf(stderr, "dropped privs to %s\n", username);
793*05b00f60SXin Li }
794*05b00f60SXin Li #else
795*05b00f60SXin Li if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
796*05b00f60SXin Li setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0)
797*05b00f60SXin Li error("Couldn't change to '%.32s' uid=%lu gid=%lu: %s",
798*05b00f60SXin Li username,
799*05b00f60SXin Li (unsigned long)pw->pw_uid,
800*05b00f60SXin Li (unsigned long)pw->pw_gid,
801*05b00f60SXin Li pcap_strerror(errno));
802*05b00f60SXin Li else {
803*05b00f60SXin Li fprintf(stderr, "dropped privs to %s\n", username);
804*05b00f60SXin Li }
805*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
806*05b00f60SXin Li } else
807*05b00f60SXin Li error("Couldn't find user '%.32s'", username);
808*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
809*05b00f60SXin Li /* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT any more. */
810*05b00f60SXin Li DIAG_OFF_ASSIGN_ENUM
811*05b00f60SXin Li capng_updatev(
812*05b00f60SXin Li CAPNG_DROP,
813*05b00f60SXin Li CAPNG_EFFECTIVE | CAPNG_PERMITTED,
814*05b00f60SXin Li CAP_SETUID,
815*05b00f60SXin Li CAP_SETGID,
816*05b00f60SXin Li CAP_SYS_CHROOT,
817*05b00f60SXin Li -1);
818*05b00f60SXin Li DIAG_ON_ASSIGN_ENUM
819*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
820*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
821*05b00f60SXin Li
822*05b00f60SXin Li }
823*05b00f60SXin Li #endif /* _WIN32 */
824*05b00f60SXin Li
825*05b00f60SXin Li static int
getWflagChars(int x)826*05b00f60SXin Li getWflagChars(int x)
827*05b00f60SXin Li {
828*05b00f60SXin Li int c = 0;
829*05b00f60SXin Li
830*05b00f60SXin Li x -= 1;
831*05b00f60SXin Li while (x > 0) {
832*05b00f60SXin Li c += 1;
833*05b00f60SXin Li x /= 10;
834*05b00f60SXin Li }
835*05b00f60SXin Li
836*05b00f60SXin Li return c;
837*05b00f60SXin Li }
838*05b00f60SXin Li
839*05b00f60SXin Li
840*05b00f60SXin Li static void
MakeFilename(char * buffer,char * orig_name,int cnt,int max_chars)841*05b00f60SXin Li MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars)
842*05b00f60SXin Li {
843*05b00f60SXin Li char *filename = malloc(PATH_MAX + 1);
844*05b00f60SXin Li if (filename == NULL)
845*05b00f60SXin Li error("%s: malloc", __func__);
846*05b00f60SXin Li if (strlen(orig_name) == 0)
847*05b00f60SXin Li error("an empty string is not a valid file name");
848*05b00f60SXin Li
849*05b00f60SXin Li /* Process with strftime if Gflag is set. */
850*05b00f60SXin Li if (Gflag != 0) {
851*05b00f60SXin Li struct tm *local_tm;
852*05b00f60SXin Li
853*05b00f60SXin Li /* Convert Gflag_time to a usable format */
854*05b00f60SXin Li if ((local_tm = localtime(&Gflag_time)) == NULL) {
855*05b00f60SXin Li error("%s: localtime", __func__);
856*05b00f60SXin Li }
857*05b00f60SXin Li
858*05b00f60SXin Li /* There's no good way to detect an error in strftime since a return
859*05b00f60SXin Li * value of 0 isn't necessarily failure; if orig_name is an empty
860*05b00f60SXin Li * string, the formatted string will be empty.
861*05b00f60SXin Li *
862*05b00f60SXin Li * However, the C90 standard says that, if there *is* a
863*05b00f60SXin Li * buffer overflow, the content of the buffer is undefined,
864*05b00f60SXin Li * so we must check for a buffer overflow.
865*05b00f60SXin Li *
866*05b00f60SXin Li * So we check above for an empty orig_name, and only call
867*05b00f60SXin Li * strftime() if it's non-empty, in which case the return
868*05b00f60SXin Li * value will only be 0 if the formatted date doesn't fit
869*05b00f60SXin Li * in the buffer.
870*05b00f60SXin Li *
871*05b00f60SXin Li * (We check above because, even if we don't use -G, we
872*05b00f60SXin Li * want a better error message than "tcpdump: : No such
873*05b00f60SXin Li * file or directory" for this case.)
874*05b00f60SXin Li */
875*05b00f60SXin Li if (strftime(filename, PATH_MAX, orig_name, local_tm) == 0) {
876*05b00f60SXin Li error("%s: strftime", __func__);
877*05b00f60SXin Li }
878*05b00f60SXin Li } else {
879*05b00f60SXin Li strncpy(filename, orig_name, PATH_MAX);
880*05b00f60SXin Li }
881*05b00f60SXin Li
882*05b00f60SXin Li if (cnt == 0 && max_chars == 0)
883*05b00f60SXin Li strncpy(buffer, filename, PATH_MAX + 1);
884*05b00f60SXin Li else
885*05b00f60SXin Li if (snprintf(buffer, PATH_MAX + 1, "%s%0*d", filename, max_chars, cnt) > PATH_MAX)
886*05b00f60SXin Li /* Report an error if the filename is too large */
887*05b00f60SXin Li error("too many output files or filename is too long (> %d)", PATH_MAX);
888*05b00f60SXin Li free(filename);
889*05b00f60SXin Li }
890*05b00f60SXin Li
891*05b00f60SXin Li static char *
get_next_file(FILE * VFile,char * ptr)892*05b00f60SXin Li get_next_file(FILE *VFile, char *ptr)
893*05b00f60SXin Li {
894*05b00f60SXin Li char *ret;
895*05b00f60SXin Li size_t len;
896*05b00f60SXin Li
897*05b00f60SXin Li ret = fgets(ptr, PATH_MAX, VFile);
898*05b00f60SXin Li if (!ret)
899*05b00f60SXin Li return NULL;
900*05b00f60SXin Li
901*05b00f60SXin Li len = strlen (ptr);
902*05b00f60SXin Li if (len > 0 && ptr[len - 1] == '\n')
903*05b00f60SXin Li ptr[len - 1] = '\0';
904*05b00f60SXin Li
905*05b00f60SXin Li return ret;
906*05b00f60SXin Li }
907*05b00f60SXin Li
908*05b00f60SXin Li #ifdef HAVE_CASPER
909*05b00f60SXin Li static cap_channel_t *
capdns_setup(void)910*05b00f60SXin Li capdns_setup(void)
911*05b00f60SXin Li {
912*05b00f60SXin Li cap_channel_t *capcas, *capdnsloc;
913*05b00f60SXin Li const char *types[1];
914*05b00f60SXin Li int families[2];
915*05b00f60SXin Li
916*05b00f60SXin Li capcas = cap_init();
917*05b00f60SXin Li if (capcas == NULL)
918*05b00f60SXin Li error("unable to create casper process");
919*05b00f60SXin Li capdnsloc = cap_service_open(capcas, "system.dns");
920*05b00f60SXin Li /* Casper capability no longer needed. */
921*05b00f60SXin Li cap_close(capcas);
922*05b00f60SXin Li if (capdnsloc == NULL)
923*05b00f60SXin Li error("unable to open system.dns service");
924*05b00f60SXin Li /* Limit system.dns to reverse DNS lookups. */
925*05b00f60SXin Li types[0] = "ADDR";
926*05b00f60SXin Li if (cap_dns_type_limit(capdnsloc, types, 1) < 0)
927*05b00f60SXin Li error("unable to limit access to system.dns service");
928*05b00f60SXin Li families[0] = AF_INET;
929*05b00f60SXin Li families[1] = AF_INET6;
930*05b00f60SXin Li if (cap_dns_family_limit(capdnsloc, families, 2) < 0)
931*05b00f60SXin Li error("unable to limit access to system.dns service");
932*05b00f60SXin Li
933*05b00f60SXin Li return (capdnsloc);
934*05b00f60SXin Li }
935*05b00f60SXin Li #endif /* HAVE_CASPER */
936*05b00f60SXin Li
937*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
938*05b00f60SXin Li static int
tstamp_precision_from_string(const char * precision)939*05b00f60SXin Li tstamp_precision_from_string(const char *precision)
940*05b00f60SXin Li {
941*05b00f60SXin Li if (strncmp(precision, "nano", strlen("nano")) == 0)
942*05b00f60SXin Li return PCAP_TSTAMP_PRECISION_NANO;
943*05b00f60SXin Li
944*05b00f60SXin Li if (strncmp(precision, "micro", strlen("micro")) == 0)
945*05b00f60SXin Li return PCAP_TSTAMP_PRECISION_MICRO;
946*05b00f60SXin Li
947*05b00f60SXin Li return -EINVAL;
948*05b00f60SXin Li }
949*05b00f60SXin Li
950*05b00f60SXin Li static const char *
tstamp_precision_to_string(int precision)951*05b00f60SXin Li tstamp_precision_to_string(int precision)
952*05b00f60SXin Li {
953*05b00f60SXin Li switch (precision) {
954*05b00f60SXin Li
955*05b00f60SXin Li case PCAP_TSTAMP_PRECISION_MICRO:
956*05b00f60SXin Li return "micro";
957*05b00f60SXin Li
958*05b00f60SXin Li case PCAP_TSTAMP_PRECISION_NANO:
959*05b00f60SXin Li return "nano";
960*05b00f60SXin Li
961*05b00f60SXin Li default:
962*05b00f60SXin Li return "unknown";
963*05b00f60SXin Li }
964*05b00f60SXin Li }
965*05b00f60SXin Li #endif
966*05b00f60SXin Li
967*05b00f60SXin Li #ifdef HAVE_CAPSICUM
968*05b00f60SXin Li /*
969*05b00f60SXin Li * Ensure that, on a dump file's descriptor, we have all the rights
970*05b00f60SXin Li * necessary to make the standard I/O library work with an fdopen()ed
971*05b00f60SXin Li * FILE * from that descriptor.
972*05b00f60SXin Li *
973*05b00f60SXin Li * A long time ago in a galaxy far, far away, AT&T decided that, instead
974*05b00f60SXin Li * of providing separate APIs for getting and setting the FD_ flags on a
975*05b00f60SXin Li * descriptor, getting and setting the O_ flags on a descriptor, and
976*05b00f60SXin Li * locking files, they'd throw them all into a kitchen-sink fcntl() call
977*05b00f60SXin Li * along the lines of ioctl(), the fact that ioctl() operations are
978*05b00f60SXin Li * largely specific to particular character devices but fcntl() operations
979*05b00f60SXin Li * are either generic to all descriptors or generic to all descriptors for
980*05b00f60SXin Li * regular files nonwithstanding.
981*05b00f60SXin Li *
982*05b00f60SXin Li * The Capsicum people decided that fine-grained control of descriptor
983*05b00f60SXin Li * operations was required, so that you need to grant permission for
984*05b00f60SXin Li * reading, writing, seeking, and fcntl-ing. The latter, courtesy of
985*05b00f60SXin Li * AT&T's decision, means that "fcntl-ing" isn't a thing, but a motley
986*05b00f60SXin Li * collection of things, so there are *individual* fcntls for which
987*05b00f60SXin Li * permission needs to be granted.
988*05b00f60SXin Li *
989*05b00f60SXin Li * The FreeBSD standard I/O people implemented some optimizations that
990*05b00f60SXin Li * requires that the standard I/O routines be able to determine whether
991*05b00f60SXin Li * the descriptor for the FILE * is open append-only or not; as that
992*05b00f60SXin Li * descriptor could have come from an open() rather than an fopen(),
993*05b00f60SXin Li * that requires that it be able to do an F_GETFL fcntl() to read
994*05b00f60SXin Li * the O_ flags.
995*05b00f60SXin Li *
996*05b00f60SXin Li * Tcpdump uses ftell() to determine how much data has been written
997*05b00f60SXin Li * to a file in order to, when used with -C, determine when it's time
998*05b00f60SXin Li * to rotate capture files. ftell() therefore needs to do an lseek()
999*05b00f60SXin Li * to find out the file offset and must, thanks to the aforementioned
1000*05b00f60SXin Li * optimization, also know whether the descriptor is open append-only
1001*05b00f60SXin Li * or not.
1002*05b00f60SXin Li *
1003*05b00f60SXin Li * The net result of all the above is that we need to grant CAP_SEEK,
1004*05b00f60SXin Li * CAP_WRITE, and CAP_FCNTL with the CAP_FCNTL_GETFL subcapability.
1005*05b00f60SXin Li *
1006*05b00f60SXin Li * Perhaps this is the universe's way of saying that either
1007*05b00f60SXin Li *
1008*05b00f60SXin Li * 1) there needs to be an fopenat() call and a pcap_dump_openat() call
1009*05b00f60SXin Li * using it, so that Capsicum-capable tcpdump wouldn't need to do
1010*05b00f60SXin Li * an fdopen()
1011*05b00f60SXin Li *
1012*05b00f60SXin Li * or
1013*05b00f60SXin Li *
1014*05b00f60SXin Li * 2) there needs to be a cap_fdopen() call in the FreeBSD standard
1015*05b00f60SXin Li * I/O library that knows what rights are needed by the standard
1016*05b00f60SXin Li * I/O library, based on the open mode, and assigns them, perhaps
1017*05b00f60SXin Li * with an additional argument indicating, for example, whether
1018*05b00f60SXin Li * seeking should be allowed, so that tcpdump doesn't need to know
1019*05b00f60SXin Li * what the standard I/O library happens to require this week.
1020*05b00f60SXin Li */
1021*05b00f60SXin Li static void
set_dumper_capsicum_rights(pcap_dumper_t * p)1022*05b00f60SXin Li set_dumper_capsicum_rights(pcap_dumper_t *p)
1023*05b00f60SXin Li {
1024*05b00f60SXin Li int fd = fileno(pcap_dump_file(p));
1025*05b00f60SXin Li cap_rights_t rights;
1026*05b00f60SXin Li
1027*05b00f60SXin Li cap_rights_init(&rights, CAP_SEEK, CAP_WRITE, CAP_FCNTL);
1028*05b00f60SXin Li if (cap_rights_limit(fd, &rights) < 0 && errno != ENOSYS) {
1029*05b00f60SXin Li error("unable to limit dump descriptor");
1030*05b00f60SXin Li }
1031*05b00f60SXin Li if (cap_fcntls_limit(fd, CAP_FCNTL_GETFL) < 0 && errno != ENOSYS) {
1032*05b00f60SXin Li error("unable to limit dump descriptor fcntls");
1033*05b00f60SXin Li }
1034*05b00f60SXin Li }
1035*05b00f60SXin Li #endif
1036*05b00f60SXin Li
1037*05b00f60SXin Li /*
1038*05b00f60SXin Li * Copy arg vector into a new buffer, concatenating arguments with spaces.
1039*05b00f60SXin Li */
1040*05b00f60SXin Li static char *
copy_argv(char ** argv)1041*05b00f60SXin Li copy_argv(char **argv)
1042*05b00f60SXin Li {
1043*05b00f60SXin Li char **p;
1044*05b00f60SXin Li size_t len = 0;
1045*05b00f60SXin Li char *buf;
1046*05b00f60SXin Li char *src, *dst;
1047*05b00f60SXin Li
1048*05b00f60SXin Li p = argv;
1049*05b00f60SXin Li if (*p == NULL)
1050*05b00f60SXin Li return 0;
1051*05b00f60SXin Li
1052*05b00f60SXin Li while (*p)
1053*05b00f60SXin Li len += strlen(*p++) + 1;
1054*05b00f60SXin Li
1055*05b00f60SXin Li buf = (char *)malloc(len);
1056*05b00f60SXin Li if (buf == NULL)
1057*05b00f60SXin Li error("%s: malloc", __func__);
1058*05b00f60SXin Li
1059*05b00f60SXin Li p = argv;
1060*05b00f60SXin Li dst = buf;
1061*05b00f60SXin Li while ((src = *p++) != NULL) {
1062*05b00f60SXin Li while ((*dst++ = *src++) != '\0')
1063*05b00f60SXin Li ;
1064*05b00f60SXin Li dst[-1] = ' ';
1065*05b00f60SXin Li }
1066*05b00f60SXin Li dst[-1] = '\0';
1067*05b00f60SXin Li
1068*05b00f60SXin Li return buf;
1069*05b00f60SXin Li }
1070*05b00f60SXin Li
1071*05b00f60SXin Li /*
1072*05b00f60SXin Li * On Windows, we need to open the file in binary mode, so that
1073*05b00f60SXin Li * we get all the bytes specified by the size we get from "fstat()".
1074*05b00f60SXin Li * On UNIX, that's not necessary. O_BINARY is defined on Windows;
1075*05b00f60SXin Li * we define it as 0 if it's not defined, so it does nothing.
1076*05b00f60SXin Li */
1077*05b00f60SXin Li #ifndef O_BINARY
1078*05b00f60SXin Li #define O_BINARY 0
1079*05b00f60SXin Li #endif
1080*05b00f60SXin Li
1081*05b00f60SXin Li static char *
read_infile(char * fname)1082*05b00f60SXin Li read_infile(char *fname)
1083*05b00f60SXin Li {
1084*05b00f60SXin Li int i, fd;
1085*05b00f60SXin Li ssize_t cc;
1086*05b00f60SXin Li char *cp;
1087*05b00f60SXin Li our_statb buf;
1088*05b00f60SXin Li
1089*05b00f60SXin Li fd = open(fname, O_RDONLY|O_BINARY);
1090*05b00f60SXin Li if (fd < 0)
1091*05b00f60SXin Li error("can't open %s: %s", fname, pcap_strerror(errno));
1092*05b00f60SXin Li
1093*05b00f60SXin Li if (our_fstat(fd, &buf) < 0)
1094*05b00f60SXin Li error("can't stat %s: %s", fname, pcap_strerror(errno));
1095*05b00f60SXin Li
1096*05b00f60SXin Li /*
1097*05b00f60SXin Li * Reject files whose size doesn't fit into an int; a filter
1098*05b00f60SXin Li * *that* large will probably be too big.
1099*05b00f60SXin Li */
1100*05b00f60SXin Li if (buf.st_size > INT_MAX)
1101*05b00f60SXin Li error("%s is too large", fname);
1102*05b00f60SXin Li
1103*05b00f60SXin Li cp = malloc((u_int)buf.st_size + 1);
1104*05b00f60SXin Li if (cp == NULL)
1105*05b00f60SXin Li error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
1106*05b00f60SXin Li fname, pcap_strerror(errno));
1107*05b00f60SXin Li cc = read(fd, cp, (u_int)buf.st_size);
1108*05b00f60SXin Li if (cc < 0)
1109*05b00f60SXin Li error("read %s: %s", fname, pcap_strerror(errno));
1110*05b00f60SXin Li if (cc != buf.st_size)
1111*05b00f60SXin Li error("short read %s (%d != %d)", fname, (int) cc,
1112*05b00f60SXin Li (int)buf.st_size);
1113*05b00f60SXin Li
1114*05b00f60SXin Li close(fd);
1115*05b00f60SXin Li /* replace "# comment" with spaces */
1116*05b00f60SXin Li for (i = 0; i < cc; i++) {
1117*05b00f60SXin Li if (cp[i] == '#')
1118*05b00f60SXin Li while (i < cc && cp[i] != '\n')
1119*05b00f60SXin Li cp[i++] = ' ';
1120*05b00f60SXin Li }
1121*05b00f60SXin Li cp[cc] = '\0';
1122*05b00f60SXin Li return (cp);
1123*05b00f60SXin Li }
1124*05b00f60SXin Li
1125*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
1126*05b00f60SXin Li static long
parse_interface_number(const char * device)1127*05b00f60SXin Li parse_interface_number(const char *device)
1128*05b00f60SXin Li {
1129*05b00f60SXin Li const char *p;
1130*05b00f60SXin Li long devnum;
1131*05b00f60SXin Li char *end;
1132*05b00f60SXin Li
1133*05b00f60SXin Li /*
1134*05b00f60SXin Li * Search for a colon, terminating any scheme at the beginning
1135*05b00f60SXin Li * of the device.
1136*05b00f60SXin Li */
1137*05b00f60SXin Li p = strchr(device, ':');
1138*05b00f60SXin Li if (p != NULL) {
1139*05b00f60SXin Li /*
1140*05b00f60SXin Li * We found it. Is it followed by "//"?
1141*05b00f60SXin Li */
1142*05b00f60SXin Li p++; /* skip the : */
1143*05b00f60SXin Li if (strncmp(p, "//", 2) == 0) {
1144*05b00f60SXin Li /*
1145*05b00f60SXin Li * Yes. Search for the next /, at the end of the
1146*05b00f60SXin Li * authority part of the URL.
1147*05b00f60SXin Li */
1148*05b00f60SXin Li p += 2; /* skip the // */
1149*05b00f60SXin Li p = strchr(p, '/');
1150*05b00f60SXin Li if (p != NULL) {
1151*05b00f60SXin Li /*
1152*05b00f60SXin Li * OK, past the / is the path.
1153*05b00f60SXin Li */
1154*05b00f60SXin Li device = p + 1;
1155*05b00f60SXin Li }
1156*05b00f60SXin Li }
1157*05b00f60SXin Li }
1158*05b00f60SXin Li devnum = strtol(device, &end, 10);
1159*05b00f60SXin Li if (device != end && *end == '\0') {
1160*05b00f60SXin Li /*
1161*05b00f60SXin Li * It's all-numeric, but is it a valid number?
1162*05b00f60SXin Li */
1163*05b00f60SXin Li if (devnum <= 0) {
1164*05b00f60SXin Li /*
1165*05b00f60SXin Li * No, it's not an ordinal.
1166*05b00f60SXin Li */
1167*05b00f60SXin Li error("Invalid adapter index");
1168*05b00f60SXin Li }
1169*05b00f60SXin Li return (devnum);
1170*05b00f60SXin Li } else {
1171*05b00f60SXin Li /*
1172*05b00f60SXin Li * It's not all-numeric; return -1, so our caller
1173*05b00f60SXin Li * knows that.
1174*05b00f60SXin Li */
1175*05b00f60SXin Li return (-1);
1176*05b00f60SXin Li }
1177*05b00f60SXin Li }
1178*05b00f60SXin Li
1179*05b00f60SXin Li static char *
find_interface_by_number(const char * url _U_,long devnum)1180*05b00f60SXin Li find_interface_by_number(const char *url
1181*05b00f60SXin Li #ifndef HAVE_PCAP_FINDALLDEVS_EX
1182*05b00f60SXin Li _U_
1183*05b00f60SXin Li #endif
1184*05b00f60SXin Li , long devnum)
1185*05b00f60SXin Li {
1186*05b00f60SXin Li pcap_if_t *dev, *devlist;
1187*05b00f60SXin Li long i;
1188*05b00f60SXin Li char ebuf[PCAP_ERRBUF_SIZE];
1189*05b00f60SXin Li char *device;
1190*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
1191*05b00f60SXin Li const char *endp;
1192*05b00f60SXin Li char *host_url;
1193*05b00f60SXin Li #endif
1194*05b00f60SXin Li int status;
1195*05b00f60SXin Li
1196*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
1197*05b00f60SXin Li /*
1198*05b00f60SXin Li * Search for a colon, terminating any scheme at the beginning
1199*05b00f60SXin Li * of the URL.
1200*05b00f60SXin Li */
1201*05b00f60SXin Li endp = strchr(url, ':');
1202*05b00f60SXin Li if (endp != NULL) {
1203*05b00f60SXin Li /*
1204*05b00f60SXin Li * We found it. Is it followed by "//"?
1205*05b00f60SXin Li */
1206*05b00f60SXin Li endp++; /* skip the : */
1207*05b00f60SXin Li if (strncmp(endp, "//", 2) == 0) {
1208*05b00f60SXin Li /*
1209*05b00f60SXin Li * Yes. Search for the next /, at the end of the
1210*05b00f60SXin Li * authority part of the URL.
1211*05b00f60SXin Li */
1212*05b00f60SXin Li endp += 2; /* skip the // */
1213*05b00f60SXin Li endp = strchr(endp, '/');
1214*05b00f60SXin Li } else
1215*05b00f60SXin Li endp = NULL;
1216*05b00f60SXin Li }
1217*05b00f60SXin Li if (endp != NULL) {
1218*05b00f60SXin Li /*
1219*05b00f60SXin Li * OK, everything from device to endp is a URL to hand
1220*05b00f60SXin Li * to pcap_findalldevs_ex().
1221*05b00f60SXin Li */
1222*05b00f60SXin Li endp++; /* Include the trailing / in the URL; pcap_findalldevs_ex() requires it */
1223*05b00f60SXin Li host_url = malloc(endp - url + 1);
1224*05b00f60SXin Li if (host_url == NULL && (endp - url + 1) > 0)
1225*05b00f60SXin Li error("Invalid allocation for host");
1226*05b00f60SXin Li
1227*05b00f60SXin Li memcpy(host_url, url, endp - url);
1228*05b00f60SXin Li host_url[endp - url] = '\0';
1229*05b00f60SXin Li status = pcap_findalldevs_ex(host_url, NULL, &devlist, ebuf);
1230*05b00f60SXin Li free(host_url);
1231*05b00f60SXin Li } else
1232*05b00f60SXin Li #endif
1233*05b00f60SXin Li status = pcap_findalldevs(&devlist, ebuf);
1234*05b00f60SXin Li if (status < 0)
1235*05b00f60SXin Li error("%s", ebuf);
1236*05b00f60SXin Li /*
1237*05b00f60SXin Li * Look for the devnum-th entry in the list of devices (1-based).
1238*05b00f60SXin Li */
1239*05b00f60SXin Li for (i = 0, dev = devlist; i < devnum-1 && dev != NULL;
1240*05b00f60SXin Li i++, dev = dev->next)
1241*05b00f60SXin Li ;
1242*05b00f60SXin Li if (dev == NULL)
1243*05b00f60SXin Li error("Invalid adapter index");
1244*05b00f60SXin Li device = strdup(dev->name);
1245*05b00f60SXin Li pcap_freealldevs(devlist);
1246*05b00f60SXin Li return (device);
1247*05b00f60SXin Li }
1248*05b00f60SXin Li #endif
1249*05b00f60SXin Li
1250*05b00f60SXin Li #ifdef HAVE_PCAP_OPEN
1251*05b00f60SXin Li /*
1252*05b00f60SXin Li * Prefixes for rpcap URLs.
1253*05b00f60SXin Li */
1254*05b00f60SXin Li static char rpcap_prefix[] = "rpcap://";
1255*05b00f60SXin Li static char rpcap_ssl_prefix[] = "rpcaps://";
1256*05b00f60SXin Li #endif
1257*05b00f60SXin Li
1258*05b00f60SXin Li static pcap_t *
open_interface(const char * device,netdissect_options * ndo,char * ebuf)1259*05b00f60SXin Li open_interface(const char *device, netdissect_options *ndo, char *ebuf)
1260*05b00f60SXin Li {
1261*05b00f60SXin Li pcap_t *pc;
1262*05b00f60SXin Li #ifdef HAVE_PCAP_CREATE
1263*05b00f60SXin Li int status;
1264*05b00f60SXin Li char *cp;
1265*05b00f60SXin Li #endif
1266*05b00f60SXin Li
1267*05b00f60SXin Li #ifdef HAVE_PCAP_OPEN
1268*05b00f60SXin Li /*
1269*05b00f60SXin Li * Is this an rpcap URL?
1270*05b00f60SXin Li */
1271*05b00f60SXin Li if (strncmp(device, rpcap_prefix, sizeof(rpcap_prefix) - 1) == 0 ||
1272*05b00f60SXin Li strncmp(device, rpcap_ssl_prefix, sizeof(rpcap_ssl_prefix) - 1) == 0) {
1273*05b00f60SXin Li /*
1274*05b00f60SXin Li * Yes. Open it with pcap_open().
1275*05b00f60SXin Li */
1276*05b00f60SXin Li *ebuf = '\0';
1277*05b00f60SXin Li pc = pcap_open(device, ndo->ndo_snaplen,
1278*05b00f60SXin Li pflag ? 0 : PCAP_OPENFLAG_PROMISCUOUS, timeout, NULL,
1279*05b00f60SXin Li ebuf);
1280*05b00f60SXin Li if (pc == NULL) {
1281*05b00f60SXin Li /*
1282*05b00f60SXin Li * If this failed with "No such device" or "The system
1283*05b00f60SXin Li * cannot find the device specified", that means
1284*05b00f60SXin Li * the interface doesn't exist; return NULL, so that
1285*05b00f60SXin Li * the caller can see whether the device name is
1286*05b00f60SXin Li * actually an interface index.
1287*05b00f60SXin Li */
1288*05b00f60SXin Li if (strstr(ebuf, "No such device") != NULL ||
1289*05b00f60SXin Li strstr(ebuf, "The system cannot find the device specified") != NULL)
1290*05b00f60SXin Li return (NULL);
1291*05b00f60SXin Li error("%s", ebuf);
1292*05b00f60SXin Li }
1293*05b00f60SXin Li if (*ebuf)
1294*05b00f60SXin Li warning("%s", ebuf);
1295*05b00f60SXin Li return (pc);
1296*05b00f60SXin Li }
1297*05b00f60SXin Li #endif /* HAVE_PCAP_OPEN */
1298*05b00f60SXin Li
1299*05b00f60SXin Li #ifdef HAVE_PCAP_CREATE
1300*05b00f60SXin Li pc = pcap_create(device, ebuf);
1301*05b00f60SXin Li if (pc == NULL) {
1302*05b00f60SXin Li /*
1303*05b00f60SXin Li * If this failed with "No such device", that means
1304*05b00f60SXin Li * the interface doesn't exist; return NULL, so that
1305*05b00f60SXin Li * the caller can see whether the device name is
1306*05b00f60SXin Li * actually an interface index.
1307*05b00f60SXin Li */
1308*05b00f60SXin Li if (strstr(ebuf, "No such device") != NULL)
1309*05b00f60SXin Li return (NULL);
1310*05b00f60SXin Li error("%s", ebuf);
1311*05b00f60SXin Li }
1312*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
1313*05b00f60SXin Li if (Jflag)
1314*05b00f60SXin Li show_tstamp_types_and_exit(pc, device);
1315*05b00f60SXin Li #endif
1316*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
1317*05b00f60SXin Li status = pcap_set_tstamp_precision(pc, ndo->ndo_tstamp_precision);
1318*05b00f60SXin Li if (status != 0)
1319*05b00f60SXin Li error("%s: Can't set %ssecond time stamp precision: %s",
1320*05b00f60SXin Li device,
1321*05b00f60SXin Li tstamp_precision_to_string(ndo->ndo_tstamp_precision),
1322*05b00f60SXin Li pcap_statustostr(status));
1323*05b00f60SXin Li #endif
1324*05b00f60SXin Li
1325*05b00f60SXin Li #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
1326*05b00f60SXin Li if (immediate_mode) {
1327*05b00f60SXin Li status = pcap_set_immediate_mode(pc, 1);
1328*05b00f60SXin Li if (status != 0)
1329*05b00f60SXin Li error("%s: Can't set immediate mode: %s",
1330*05b00f60SXin Li device, pcap_statustostr(status));
1331*05b00f60SXin Li }
1332*05b00f60SXin Li #endif
1333*05b00f60SXin Li /*
1334*05b00f60SXin Li * Is this an interface that supports monitor mode?
1335*05b00f60SXin Li */
1336*05b00f60SXin Li if (pcap_can_set_rfmon(pc) == 1)
1337*05b00f60SXin Li supports_monitor_mode = 1;
1338*05b00f60SXin Li else
1339*05b00f60SXin Li supports_monitor_mode = 0;
1340*05b00f60SXin Li if (ndo->ndo_snaplen != 0) {
1341*05b00f60SXin Li /*
1342*05b00f60SXin Li * A snapshot length was explicitly specified;
1343*05b00f60SXin Li * use it.
1344*05b00f60SXin Li */
1345*05b00f60SXin Li status = pcap_set_snaplen(pc, ndo->ndo_snaplen);
1346*05b00f60SXin Li if (status != 0)
1347*05b00f60SXin Li error("%s: Can't set snapshot length: %s",
1348*05b00f60SXin Li device, pcap_statustostr(status));
1349*05b00f60SXin Li }
1350*05b00f60SXin Li status = pcap_set_promisc(pc, !pflag);
1351*05b00f60SXin Li if (status != 0)
1352*05b00f60SXin Li error("%s: Can't set promiscuous mode: %s",
1353*05b00f60SXin Li device, pcap_statustostr(status));
1354*05b00f60SXin Li if (Iflag) {
1355*05b00f60SXin Li status = pcap_set_rfmon(pc, 1);
1356*05b00f60SXin Li if (status != 0)
1357*05b00f60SXin Li error("%s: Can't set monitor mode: %s",
1358*05b00f60SXin Li device, pcap_statustostr(status));
1359*05b00f60SXin Li }
1360*05b00f60SXin Li status = pcap_set_timeout(pc, timeout);
1361*05b00f60SXin Li if (status != 0)
1362*05b00f60SXin Li error("%s: pcap_set_timeout failed: %s",
1363*05b00f60SXin Li device, pcap_statustostr(status));
1364*05b00f60SXin Li if (Bflag != 0) {
1365*05b00f60SXin Li status = pcap_set_buffer_size(pc, Bflag);
1366*05b00f60SXin Li if (status != 0)
1367*05b00f60SXin Li error("%s: Can't set buffer size: %s",
1368*05b00f60SXin Li device, pcap_statustostr(status));
1369*05b00f60SXin Li }
1370*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
1371*05b00f60SXin Li if (jflag != -1) {
1372*05b00f60SXin Li status = pcap_set_tstamp_type(pc, jflag);
1373*05b00f60SXin Li if (status < 0)
1374*05b00f60SXin Li error("%s: Can't set time stamp type: %s",
1375*05b00f60SXin Li device, pcap_statustostr(status));
1376*05b00f60SXin Li else if (status > 0)
1377*05b00f60SXin Li warning("When trying to set timestamp type '%s' on %s: %s",
1378*05b00f60SXin Li pcap_tstamp_type_val_to_name(jflag), device,
1379*05b00f60SXin Li pcap_statustostr(status));
1380*05b00f60SXin Li }
1381*05b00f60SXin Li #endif
1382*05b00f60SXin Li status = pcap_activate(pc);
1383*05b00f60SXin Li if (status < 0) {
1384*05b00f60SXin Li /*
1385*05b00f60SXin Li * pcap_activate() failed.
1386*05b00f60SXin Li */
1387*05b00f60SXin Li cp = pcap_geterr(pc);
1388*05b00f60SXin Li if (status == PCAP_ERROR)
1389*05b00f60SXin Li error("%s", cp);
1390*05b00f60SXin Li else if (status == PCAP_ERROR_NO_SUCH_DEVICE) {
1391*05b00f60SXin Li /*
1392*05b00f60SXin Li * Return an error for our caller to handle.
1393*05b00f60SXin Li */
1394*05b00f60SXin Li snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)",
1395*05b00f60SXin Li device, pcap_statustostr(status), cp);
1396*05b00f60SXin Li } else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0')
1397*05b00f60SXin Li error("%s: %s\n(%s)", device,
1398*05b00f60SXin Li pcap_statustostr(status), cp);
1399*05b00f60SXin Li #ifdef __FreeBSD__
1400*05b00f60SXin Li else if (status == PCAP_ERROR_RFMON_NOTSUP &&
1401*05b00f60SXin Li strncmp(device, "wlan", 4) == 0) {
1402*05b00f60SXin Li char parent[8], newdev[8];
1403*05b00f60SXin Li char sysctl[32];
1404*05b00f60SXin Li size_t s = sizeof(parent);
1405*05b00f60SXin Li
1406*05b00f60SXin Li snprintf(sysctl, sizeof(sysctl),
1407*05b00f60SXin Li "net.wlan.%d.%%parent", atoi(device + 4));
1408*05b00f60SXin Li sysctlbyname(sysctl, parent, &s, NULL, 0);
1409*05b00f60SXin Li strlcpy(newdev, device, sizeof(newdev));
1410*05b00f60SXin Li /* Suggest a new wlan device. */
1411*05b00f60SXin Li /* FIXME: incrementing the index this way is not going to work well
1412*05b00f60SXin Li * when the index is 9 or greater but the only consequence in this
1413*05b00f60SXin Li * specific case would be an error message that looks a bit odd.
1414*05b00f60SXin Li */
1415*05b00f60SXin Li newdev[strlen(newdev)-1]++;
1416*05b00f60SXin Li error("%s is not a monitor mode VAP\n"
1417*05b00f60SXin Li "To create a new monitor mode VAP use:\n"
1418*05b00f60SXin Li " ifconfig %s create wlandev %s wlanmode monitor\n"
1419*05b00f60SXin Li "and use %s as the tcpdump interface",
1420*05b00f60SXin Li device, newdev, parent, newdev);
1421*05b00f60SXin Li }
1422*05b00f60SXin Li #endif
1423*05b00f60SXin Li else
1424*05b00f60SXin Li error("%s: %s", device,
1425*05b00f60SXin Li pcap_statustostr(status));
1426*05b00f60SXin Li pcap_close(pc);
1427*05b00f60SXin Li return (NULL);
1428*05b00f60SXin Li } else if (status > 0) {
1429*05b00f60SXin Li /*
1430*05b00f60SXin Li * pcap_activate() succeeded, but it's warning us
1431*05b00f60SXin Li * of a problem it had.
1432*05b00f60SXin Li */
1433*05b00f60SXin Li cp = pcap_geterr(pc);
1434*05b00f60SXin Li if (status == PCAP_WARNING)
1435*05b00f60SXin Li warning("%s", cp);
1436*05b00f60SXin Li else if (status == PCAP_WARNING_PROMISC_NOTSUP &&
1437*05b00f60SXin Li *cp != '\0')
1438*05b00f60SXin Li warning("%s: %s\n(%s)", device,
1439*05b00f60SXin Li pcap_statustostr(status), cp);
1440*05b00f60SXin Li else
1441*05b00f60SXin Li warning("%s: %s", device,
1442*05b00f60SXin Li pcap_statustostr(status));
1443*05b00f60SXin Li }
1444*05b00f60SXin Li #ifdef HAVE_PCAP_SETDIRECTION
1445*05b00f60SXin Li if (Qflag != -1) {
1446*05b00f60SXin Li status = pcap_setdirection(pc, Qflag);
1447*05b00f60SXin Li if (status != 0)
1448*05b00f60SXin Li error("%s: pcap_setdirection() failed: %s",
1449*05b00f60SXin Li device, pcap_geterr(pc));
1450*05b00f60SXin Li }
1451*05b00f60SXin Li #endif /* HAVE_PCAP_SETDIRECTION */
1452*05b00f60SXin Li #else /* HAVE_PCAP_CREATE */
1453*05b00f60SXin Li *ebuf = '\0';
1454*05b00f60SXin Li /*
1455*05b00f60SXin Li * If no snapshot length was specified, or a length of 0 was
1456*05b00f60SXin Li * specified, default to 256KB.
1457*05b00f60SXin Li */
1458*05b00f60SXin Li if (ndo->ndo_snaplen == 0)
1459*05b00f60SXin Li ndo->ndo_snaplen = MAXIMUM_SNAPLEN;
1460*05b00f60SXin Li pc = pcap_open_live(device, ndo->ndo_snaplen, !pflag, timeout, ebuf);
1461*05b00f60SXin Li if (pc == NULL) {
1462*05b00f60SXin Li /*
1463*05b00f60SXin Li * If this failed with "No such device", that means
1464*05b00f60SXin Li * the interface doesn't exist; return NULL, so that
1465*05b00f60SXin Li * the caller can see whether the device name is
1466*05b00f60SXin Li * actually an interface index.
1467*05b00f60SXin Li */
1468*05b00f60SXin Li if (strstr(ebuf, "No such device") != NULL)
1469*05b00f60SXin Li return (NULL);
1470*05b00f60SXin Li error("%s", ebuf);
1471*05b00f60SXin Li }
1472*05b00f60SXin Li if (*ebuf)
1473*05b00f60SXin Li warning("%s", ebuf);
1474*05b00f60SXin Li #endif /* HAVE_PCAP_CREATE */
1475*05b00f60SXin Li
1476*05b00f60SXin Li return (pc);
1477*05b00f60SXin Li }
1478*05b00f60SXin Li
1479*05b00f60SXin Li int
main(int argc,char ** argv)1480*05b00f60SXin Li main(int argc, char **argv)
1481*05b00f60SXin Li {
1482*05b00f60SXin Li int cnt, op, i;
1483*05b00f60SXin Li bpf_u_int32 localnet = 0, netmask = 0;
1484*05b00f60SXin Li char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName;
1485*05b00f60SXin Li char *endp;
1486*05b00f60SXin Li pcap_handler callback;
1487*05b00f60SXin Li int dlt;
1488*05b00f60SXin Li const char *dlt_name;
1489*05b00f60SXin Li struct bpf_program fcode;
1490*05b00f60SXin Li #ifndef _WIN32
1491*05b00f60SXin Li void (*oldhandler)(int);
1492*05b00f60SXin Li #endif
1493*05b00f60SXin Li struct dump_info dumpinfo;
1494*05b00f60SXin Li u_char *pcap_userdata;
1495*05b00f60SXin Li char ebuf[PCAP_ERRBUF_SIZE];
1496*05b00f60SXin Li char VFileLine[PATH_MAX + 1];
1497*05b00f60SXin Li const char *username = NULL;
1498*05b00f60SXin Li #ifndef _WIN32
1499*05b00f60SXin Li const char *chroot_dir = NULL;
1500*05b00f60SXin Li #endif
1501*05b00f60SXin Li char *ret = NULL;
1502*05b00f60SXin Li char *end;
1503*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
1504*05b00f60SXin Li pcap_if_t *devlist;
1505*05b00f60SXin Li long devnum;
1506*05b00f60SXin Li #endif
1507*05b00f60SXin Li int status;
1508*05b00f60SXin Li FILE *VFile;
1509*05b00f60SXin Li #ifdef HAVE_CAPSICUM
1510*05b00f60SXin Li cap_rights_t rights;
1511*05b00f60SXin Li int cansandbox;
1512*05b00f60SXin Li #endif /* HAVE_CAPSICUM */
1513*05b00f60SXin Li int Oflag = 1; /* run filter code optimizer */
1514*05b00f60SXin Li int yflag_dlt = -1;
1515*05b00f60SXin Li const char *yflag_dlt_name = NULL;
1516*05b00f60SXin Li int print = 0;
1517*05b00f60SXin Li
1518*05b00f60SXin Li netdissect_options Ndo;
1519*05b00f60SXin Li netdissect_options *ndo = &Ndo;
1520*05b00f60SXin Li
1521*05b00f60SXin Li /*
1522*05b00f60SXin Li * Initialize the netdissect code.
1523*05b00f60SXin Li */
1524*05b00f60SXin Li if (nd_init(ebuf, sizeof(ebuf)) == -1)
1525*05b00f60SXin Li error("%s", ebuf);
1526*05b00f60SXin Li
1527*05b00f60SXin Li memset(ndo, 0, sizeof(*ndo));
1528*05b00f60SXin Li ndo_set_function_pointers(ndo);
1529*05b00f60SXin Li
1530*05b00f60SXin Li cnt = -1;
1531*05b00f60SXin Li device = NULL;
1532*05b00f60SXin Li infile = NULL;
1533*05b00f60SXin Li RFileName = NULL;
1534*05b00f60SXin Li VFileName = NULL;
1535*05b00f60SXin Li VFile = NULL;
1536*05b00f60SXin Li WFileName = NULL;
1537*05b00f60SXin Li dlt = -1;
1538*05b00f60SXin Li if ((cp = strrchr(argv[0], PATH_SEPARATOR)) != NULL)
1539*05b00f60SXin Li ndo->program_name = program_name = cp + 1;
1540*05b00f60SXin Li else
1541*05b00f60SXin Li ndo->program_name = program_name = argv[0];
1542*05b00f60SXin Li
1543*05b00f60SXin Li #if defined(HAVE_PCAP_WSOCKINIT)
1544*05b00f60SXin Li if (pcap_wsockinit() != 0)
1545*05b00f60SXin Li error("Attempting to initialize Winsock failed");
1546*05b00f60SXin Li #elif defined(HAVE_WSOCKINIT)
1547*05b00f60SXin Li if (wsockinit() != 0)
1548*05b00f60SXin Li error("Attempting to initialize Winsock failed");
1549*05b00f60SXin Li #endif
1550*05b00f60SXin Li
1551*05b00f60SXin Li /*
1552*05b00f60SXin Li * On platforms where the CPU doesn't support unaligned loads,
1553*05b00f60SXin Li * force unaligned accesses to abort with SIGBUS, rather than
1554*05b00f60SXin Li * being fixed up (slowly) by the OS kernel; on those platforms,
1555*05b00f60SXin Li * misaligned accesses are bugs, and we want tcpdump to crash so
1556*05b00f60SXin Li * that the bugs are reported.
1557*05b00f60SXin Li */
1558*05b00f60SXin Li if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
1559*05b00f60SXin Li error("%s", ebuf);
1560*05b00f60SXin Li
1561*05b00f60SXin Li while (
1562*05b00f60SXin Li (op = getopt_long(argc, argv, SHORTOPTS, longopts, NULL)) != -1)
1563*05b00f60SXin Li switch (op) {
1564*05b00f60SXin Li
1565*05b00f60SXin Li case 'a':
1566*05b00f60SXin Li /* compatibility for old -a */
1567*05b00f60SXin Li break;
1568*05b00f60SXin Li
1569*05b00f60SXin Li case 'A':
1570*05b00f60SXin Li ++ndo->ndo_Aflag;
1571*05b00f60SXin Li break;
1572*05b00f60SXin Li
1573*05b00f60SXin Li case 'b':
1574*05b00f60SXin Li ++ndo->ndo_bflag;
1575*05b00f60SXin Li break;
1576*05b00f60SXin Li
1577*05b00f60SXin Li #if defined(HAVE_PCAP_CREATE) || defined(_WIN32)
1578*05b00f60SXin Li case 'B':
1579*05b00f60SXin Li Bflag = atoi(optarg)*1024;
1580*05b00f60SXin Li if (Bflag <= 0)
1581*05b00f60SXin Li error("invalid packet buffer size %s", optarg);
1582*05b00f60SXin Li break;
1583*05b00f60SXin Li #endif /* defined(HAVE_PCAP_CREATE) || defined(_WIN32) */
1584*05b00f60SXin Li
1585*05b00f60SXin Li case 'c':
1586*05b00f60SXin Li cnt = atoi(optarg);
1587*05b00f60SXin Li if (cnt <= 0)
1588*05b00f60SXin Li error("invalid packet count %s", optarg);
1589*05b00f60SXin Li break;
1590*05b00f60SXin Li
1591*05b00f60SXin Li case 'C':
1592*05b00f60SXin Li errno = 0;
1593*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FTELL64
1594*05b00f60SXin Li Cflag = strtoint64_t(optarg, &endp, 10);
1595*05b00f60SXin Li #else
1596*05b00f60SXin Li Cflag = strtol(optarg, &endp, 10);
1597*05b00f60SXin Li #endif
1598*05b00f60SXin Li if (endp == optarg || *endp != '\0' || errno != 0
1599*05b00f60SXin Li || Cflag <= 0)
1600*05b00f60SXin Li error("invalid file size %s", optarg);
1601*05b00f60SXin Li /*
1602*05b00f60SXin Li * Will multiplying it by 1000000 overflow?
1603*05b00f60SXin Li */
1604*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FTELL64
1605*05b00f60SXin Li if (Cflag > INT64_T_CONSTANT(0x7fffffffffffffff) / 1000000)
1606*05b00f60SXin Li #else
1607*05b00f60SXin Li if (Cflag > LONG_MAX / 1000000)
1608*05b00f60SXin Li #endif
1609*05b00f60SXin Li error("file size %s is too large", optarg);
1610*05b00f60SXin Li Cflag *= 1000000;
1611*05b00f60SXin Li break;
1612*05b00f60SXin Li
1613*05b00f60SXin Li case 'd':
1614*05b00f60SXin Li ++dflag;
1615*05b00f60SXin Li break;
1616*05b00f60SXin Li
1617*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
1618*05b00f60SXin Li case 'D':
1619*05b00f60SXin Li Dflag++;
1620*05b00f60SXin Li break;
1621*05b00f60SXin Li #endif
1622*05b00f60SXin Li
1623*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
1624*05b00f60SXin Li case OPTION_LIST_REMOTE_INTERFACES:
1625*05b00f60SXin Li remote_interfaces_source = optarg;
1626*05b00f60SXin Li break;
1627*05b00f60SXin Li #endif
1628*05b00f60SXin Li
1629*05b00f60SXin Li case 'L':
1630*05b00f60SXin Li Lflag++;
1631*05b00f60SXin Li break;
1632*05b00f60SXin Li
1633*05b00f60SXin Li case 'e':
1634*05b00f60SXin Li ++ndo->ndo_eflag;
1635*05b00f60SXin Li break;
1636*05b00f60SXin Li
1637*05b00f60SXin Li case 'E':
1638*05b00f60SXin Li #ifndef HAVE_LIBCRYPTO
1639*05b00f60SXin Li warning("crypto code not compiled in");
1640*05b00f60SXin Li #endif
1641*05b00f60SXin Li ndo->ndo_espsecret = optarg;
1642*05b00f60SXin Li break;
1643*05b00f60SXin Li
1644*05b00f60SXin Li case 'f':
1645*05b00f60SXin Li ++ndo->ndo_fflag;
1646*05b00f60SXin Li break;
1647*05b00f60SXin Li
1648*05b00f60SXin Li case 'F':
1649*05b00f60SXin Li infile = optarg;
1650*05b00f60SXin Li break;
1651*05b00f60SXin Li
1652*05b00f60SXin Li case 'G':
1653*05b00f60SXin Li Gflag = atoi(optarg);
1654*05b00f60SXin Li if (Gflag < 0)
1655*05b00f60SXin Li error("invalid number of seconds %s", optarg);
1656*05b00f60SXin Li
1657*05b00f60SXin Li /* We will create one file initially. */
1658*05b00f60SXin Li Gflag_count = 0;
1659*05b00f60SXin Li
1660*05b00f60SXin Li /* Grab the current time for rotation use. */
1661*05b00f60SXin Li if ((Gflag_time = time(NULL)) == (time_t)-1) {
1662*05b00f60SXin Li error("%s: can't get current time: %s",
1663*05b00f60SXin Li __func__, pcap_strerror(errno));
1664*05b00f60SXin Li }
1665*05b00f60SXin Li break;
1666*05b00f60SXin Li
1667*05b00f60SXin Li case 'h':
1668*05b00f60SXin Li print_usage(stdout);
1669*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
1670*05b00f60SXin Li break;
1671*05b00f60SXin Li
1672*05b00f60SXin Li case 'H':
1673*05b00f60SXin Li ++ndo->ndo_Hflag;
1674*05b00f60SXin Li break;
1675*05b00f60SXin Li
1676*05b00f60SXin Li case 'i':
1677*05b00f60SXin Li device = optarg;
1678*05b00f60SXin Li break;
1679*05b00f60SXin Li
1680*05b00f60SXin Li #ifdef HAVE_PCAP_CREATE
1681*05b00f60SXin Li case 'I':
1682*05b00f60SXin Li ++Iflag;
1683*05b00f60SXin Li break;
1684*05b00f60SXin Li #endif /* HAVE_PCAP_CREATE */
1685*05b00f60SXin Li
1686*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_TYPE
1687*05b00f60SXin Li case 'j':
1688*05b00f60SXin Li jflag = pcap_tstamp_type_name_to_val(optarg);
1689*05b00f60SXin Li if (jflag < 0)
1690*05b00f60SXin Li error("invalid time stamp type %s", optarg);
1691*05b00f60SXin Li break;
1692*05b00f60SXin Li
1693*05b00f60SXin Li case 'J':
1694*05b00f60SXin Li Jflag++;
1695*05b00f60SXin Li break;
1696*05b00f60SXin Li #endif
1697*05b00f60SXin Li
1698*05b00f60SXin Li case 'l':
1699*05b00f60SXin Li #ifdef _WIN32
1700*05b00f60SXin Li /*
1701*05b00f60SXin Li * _IOLBF is the same as _IOFBF in Microsoft's C
1702*05b00f60SXin Li * libraries; the only alternative they offer
1703*05b00f60SXin Li * is _IONBF.
1704*05b00f60SXin Li *
1705*05b00f60SXin Li * XXX - this should really be checking for MSVC++,
1706*05b00f60SXin Li * not _WIN32, if, for example, MinGW has its own
1707*05b00f60SXin Li * C library that is more UNIX-compatible.
1708*05b00f60SXin Li */
1709*05b00f60SXin Li setvbuf(stdout, NULL, _IONBF, 0);
1710*05b00f60SXin Li #else /* _WIN32 */
1711*05b00f60SXin Li #ifdef HAVE_SETLINEBUF
1712*05b00f60SXin Li setlinebuf(stdout);
1713*05b00f60SXin Li #else
1714*05b00f60SXin Li setvbuf(stdout, NULL, _IOLBF, 0);
1715*05b00f60SXin Li #endif
1716*05b00f60SXin Li #endif /* _WIN32 */
1717*05b00f60SXin Li lflag = 1;
1718*05b00f60SXin Li break;
1719*05b00f60SXin Li
1720*05b00f60SXin Li case 'K':
1721*05b00f60SXin Li ++ndo->ndo_Kflag;
1722*05b00f60SXin Li break;
1723*05b00f60SXin Li
1724*05b00f60SXin Li case 'm':
1725*05b00f60SXin Li if (nd_have_smi_support()) {
1726*05b00f60SXin Li if (nd_load_smi_module(optarg, ebuf, sizeof(ebuf)) == -1)
1727*05b00f60SXin Li error("%s", ebuf);
1728*05b00f60SXin Li } else {
1729*05b00f60SXin Li (void)fprintf(stderr, "%s: ignoring option `-m %s' ",
1730*05b00f60SXin Li program_name, optarg);
1731*05b00f60SXin Li (void)fprintf(stderr, "(no libsmi support)\n");
1732*05b00f60SXin Li }
1733*05b00f60SXin Li break;
1734*05b00f60SXin Li
1735*05b00f60SXin Li case 'M':
1736*05b00f60SXin Li /* TCP-MD5 shared secret */
1737*05b00f60SXin Li #ifndef HAVE_LIBCRYPTO
1738*05b00f60SXin Li warning("crypto code not compiled in");
1739*05b00f60SXin Li #endif
1740*05b00f60SXin Li ndo->ndo_sigsecret = optarg;
1741*05b00f60SXin Li break;
1742*05b00f60SXin Li
1743*05b00f60SXin Li case 'n':
1744*05b00f60SXin Li ++ndo->ndo_nflag;
1745*05b00f60SXin Li break;
1746*05b00f60SXin Li
1747*05b00f60SXin Li case 'N':
1748*05b00f60SXin Li ++ndo->ndo_Nflag;
1749*05b00f60SXin Li break;
1750*05b00f60SXin Li
1751*05b00f60SXin Li case 'O':
1752*05b00f60SXin Li Oflag = 0;
1753*05b00f60SXin Li break;
1754*05b00f60SXin Li
1755*05b00f60SXin Li case 'p':
1756*05b00f60SXin Li ++pflag;
1757*05b00f60SXin Li break;
1758*05b00f60SXin Li
1759*05b00f60SXin Li case 'q':
1760*05b00f60SXin Li ++ndo->ndo_qflag;
1761*05b00f60SXin Li ++ndo->ndo_suppress_default_print;
1762*05b00f60SXin Li break;
1763*05b00f60SXin Li
1764*05b00f60SXin Li #ifdef HAVE_PCAP_SETDIRECTION
1765*05b00f60SXin Li case 'Q':
1766*05b00f60SXin Li if (ascii_strcasecmp(optarg, "in") == 0)
1767*05b00f60SXin Li Qflag = PCAP_D_IN;
1768*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "out") == 0)
1769*05b00f60SXin Li Qflag = PCAP_D_OUT;
1770*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "inout") == 0)
1771*05b00f60SXin Li Qflag = PCAP_D_INOUT;
1772*05b00f60SXin Li else
1773*05b00f60SXin Li error("unknown capture direction `%s'", optarg);
1774*05b00f60SXin Li break;
1775*05b00f60SXin Li #endif /* HAVE_PCAP_SETDIRECTION */
1776*05b00f60SXin Li
1777*05b00f60SXin Li case 'r':
1778*05b00f60SXin Li RFileName = optarg;
1779*05b00f60SXin Li break;
1780*05b00f60SXin Li
1781*05b00f60SXin Li case 's':
1782*05b00f60SXin Li ndo->ndo_snaplen = (int)strtol(optarg, &end, 0);
1783*05b00f60SXin Li if (optarg == end || *end != '\0'
1784*05b00f60SXin Li || ndo->ndo_snaplen < 0 || ndo->ndo_snaplen > MAXIMUM_SNAPLEN)
1785*05b00f60SXin Li error("invalid snaplen %s (must be >= 0 and <= %d)",
1786*05b00f60SXin Li optarg, MAXIMUM_SNAPLEN);
1787*05b00f60SXin Li break;
1788*05b00f60SXin Li
1789*05b00f60SXin Li case 'S':
1790*05b00f60SXin Li ++ndo->ndo_Sflag;
1791*05b00f60SXin Li break;
1792*05b00f60SXin Li
1793*05b00f60SXin Li case 't':
1794*05b00f60SXin Li ++ndo->ndo_tflag;
1795*05b00f60SXin Li break;
1796*05b00f60SXin Li
1797*05b00f60SXin Li case 'T':
1798*05b00f60SXin Li if (ascii_strcasecmp(optarg, "vat") == 0)
1799*05b00f60SXin Li ndo->ndo_packettype = PT_VAT;
1800*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "wb") == 0)
1801*05b00f60SXin Li ndo->ndo_packettype = PT_WB;
1802*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "rpc") == 0)
1803*05b00f60SXin Li ndo->ndo_packettype = PT_RPC;
1804*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "rtp") == 0)
1805*05b00f60SXin Li ndo->ndo_packettype = PT_RTP;
1806*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "rtcp") == 0)
1807*05b00f60SXin Li ndo->ndo_packettype = PT_RTCP;
1808*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "snmp") == 0)
1809*05b00f60SXin Li ndo->ndo_packettype = PT_SNMP;
1810*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "cnfp") == 0)
1811*05b00f60SXin Li ndo->ndo_packettype = PT_CNFP;
1812*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "tftp") == 0)
1813*05b00f60SXin Li ndo->ndo_packettype = PT_TFTP;
1814*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "aodv") == 0)
1815*05b00f60SXin Li ndo->ndo_packettype = PT_AODV;
1816*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "carp") == 0)
1817*05b00f60SXin Li ndo->ndo_packettype = PT_CARP;
1818*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "radius") == 0)
1819*05b00f60SXin Li ndo->ndo_packettype = PT_RADIUS;
1820*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "zmtp1") == 0)
1821*05b00f60SXin Li ndo->ndo_packettype = PT_ZMTP1;
1822*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "vxlan") == 0)
1823*05b00f60SXin Li ndo->ndo_packettype = PT_VXLAN;
1824*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "pgm") == 0)
1825*05b00f60SXin Li ndo->ndo_packettype = PT_PGM;
1826*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "pgm_zmtp1") == 0)
1827*05b00f60SXin Li ndo->ndo_packettype = PT_PGM_ZMTP1;
1828*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "lmp") == 0)
1829*05b00f60SXin Li ndo->ndo_packettype = PT_LMP;
1830*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "resp") == 0)
1831*05b00f60SXin Li ndo->ndo_packettype = PT_RESP;
1832*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "ptp") == 0)
1833*05b00f60SXin Li ndo->ndo_packettype = PT_PTP;
1834*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "someip") == 0)
1835*05b00f60SXin Li ndo->ndo_packettype = PT_SOMEIP;
1836*05b00f60SXin Li else if (ascii_strcasecmp(optarg, "domain") == 0)
1837*05b00f60SXin Li ndo->ndo_packettype = PT_DOMAIN;
1838*05b00f60SXin Li else
1839*05b00f60SXin Li error("unknown packet type `%s'", optarg);
1840*05b00f60SXin Li break;
1841*05b00f60SXin Li
1842*05b00f60SXin Li case 'u':
1843*05b00f60SXin Li ++ndo->ndo_uflag;
1844*05b00f60SXin Li break;
1845*05b00f60SXin Li
1846*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
1847*05b00f60SXin Li case 'U':
1848*05b00f60SXin Li ++Uflag;
1849*05b00f60SXin Li break;
1850*05b00f60SXin Li #endif
1851*05b00f60SXin Li
1852*05b00f60SXin Li case 'v':
1853*05b00f60SXin Li ++ndo->ndo_vflag;
1854*05b00f60SXin Li break;
1855*05b00f60SXin Li
1856*05b00f60SXin Li case 'V':
1857*05b00f60SXin Li VFileName = optarg;
1858*05b00f60SXin Li break;
1859*05b00f60SXin Li
1860*05b00f60SXin Li case 'w':
1861*05b00f60SXin Li WFileName = optarg;
1862*05b00f60SXin Li break;
1863*05b00f60SXin Li
1864*05b00f60SXin Li case 'W':
1865*05b00f60SXin Li Wflag = atoi(optarg);
1866*05b00f60SXin Li if (Wflag <= 0)
1867*05b00f60SXin Li error("invalid number of output files %s", optarg);
1868*05b00f60SXin Li WflagChars = getWflagChars(Wflag);
1869*05b00f60SXin Li break;
1870*05b00f60SXin Li
1871*05b00f60SXin Li case 'x':
1872*05b00f60SXin Li ++ndo->ndo_xflag;
1873*05b00f60SXin Li ++ndo->ndo_suppress_default_print;
1874*05b00f60SXin Li break;
1875*05b00f60SXin Li
1876*05b00f60SXin Li case 'X':
1877*05b00f60SXin Li ++ndo->ndo_Xflag;
1878*05b00f60SXin Li ++ndo->ndo_suppress_default_print;
1879*05b00f60SXin Li break;
1880*05b00f60SXin Li
1881*05b00f60SXin Li case 'y':
1882*05b00f60SXin Li yflag_dlt_name = optarg;
1883*05b00f60SXin Li yflag_dlt =
1884*05b00f60SXin Li pcap_datalink_name_to_val(yflag_dlt_name);
1885*05b00f60SXin Li if (yflag_dlt < 0)
1886*05b00f60SXin Li error("invalid data link type %s", yflag_dlt_name);
1887*05b00f60SXin Li break;
1888*05b00f60SXin Li
1889*05b00f60SXin Li #ifdef HAVE_PCAP_SET_PARSER_DEBUG
1890*05b00f60SXin Li case 'Y':
1891*05b00f60SXin Li {
1892*05b00f60SXin Li /* Undocumented flag */
1893*05b00f60SXin Li pcap_set_parser_debug(1);
1894*05b00f60SXin Li }
1895*05b00f60SXin Li break;
1896*05b00f60SXin Li #endif
1897*05b00f60SXin Li case 'z':
1898*05b00f60SXin Li zflag = optarg;
1899*05b00f60SXin Li break;
1900*05b00f60SXin Li
1901*05b00f60SXin Li case 'Z':
1902*05b00f60SXin Li username = optarg;
1903*05b00f60SXin Li break;
1904*05b00f60SXin Li
1905*05b00f60SXin Li case '#':
1906*05b00f60SXin Li ndo->ndo_packet_number = 1;
1907*05b00f60SXin Li break;
1908*05b00f60SXin Li
1909*05b00f60SXin Li case OPTION_VERSION:
1910*05b00f60SXin Li print_version(stdout);
1911*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
1912*05b00f60SXin Li break;
1913*05b00f60SXin Li
1914*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
1915*05b00f60SXin Li case OPTION_TSTAMP_PRECISION:
1916*05b00f60SXin Li ndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg);
1917*05b00f60SXin Li if (ndo->ndo_tstamp_precision < 0)
1918*05b00f60SXin Li error("unsupported time stamp precision");
1919*05b00f60SXin Li break;
1920*05b00f60SXin Li #endif
1921*05b00f60SXin Li
1922*05b00f60SXin Li #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE
1923*05b00f60SXin Li case OPTION_IMMEDIATE_MODE:
1924*05b00f60SXin Li immediate_mode = 1;
1925*05b00f60SXin Li break;
1926*05b00f60SXin Li #endif
1927*05b00f60SXin Li
1928*05b00f60SXin Li case OPTION_PRINT:
1929*05b00f60SXin Li print = 1;
1930*05b00f60SXin Li break;
1931*05b00f60SXin Li
1932*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
1933*05b00f60SXin Li case OPTION_TSTAMP_MICRO:
1934*05b00f60SXin Li ndo->ndo_tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
1935*05b00f60SXin Li break;
1936*05b00f60SXin Li
1937*05b00f60SXin Li case OPTION_TSTAMP_NANO:
1938*05b00f60SXin Li ndo->ndo_tstamp_precision = PCAP_TSTAMP_PRECISION_NANO;
1939*05b00f60SXin Li break;
1940*05b00f60SXin Li #endif
1941*05b00f60SXin Li
1942*05b00f60SXin Li case OPTION_FP_TYPE:
1943*05b00f60SXin Li /*
1944*05b00f60SXin Li * Print out the type of floating-point arithmetic
1945*05b00f60SXin Li * we're doing; it's probably IEEE, unless somebody
1946*05b00f60SXin Li * tries to run this on a VAX, but the precision
1947*05b00f60SXin Li * may differ (e.g., it might be 32-bit, 64-bit,
1948*05b00f60SXin Li * or 80-bit).
1949*05b00f60SXin Li */
1950*05b00f60SXin Li float_type_check(0x4e93312d);
1951*05b00f60SXin Li return 0;
1952*05b00f60SXin Li
1953*05b00f60SXin Li case OPTION_COUNT:
1954*05b00f60SXin Li count_mode = 1;
1955*05b00f60SXin Li break;
1956*05b00f60SXin Li
1957*05b00f60SXin Li default:
1958*05b00f60SXin Li print_usage(stderr);
1959*05b00f60SXin Li exit_tcpdump(S_ERR_HOST_PROGRAM);
1960*05b00f60SXin Li /* NOTREACHED */
1961*05b00f60SXin Li }
1962*05b00f60SXin Li
1963*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
1964*05b00f60SXin Li if (Dflag)
1965*05b00f60SXin Li show_devices_and_exit();
1966*05b00f60SXin Li #endif
1967*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
1968*05b00f60SXin Li if (remote_interfaces_source != NULL)
1969*05b00f60SXin Li show_remote_devices_and_exit();
1970*05b00f60SXin Li #endif
1971*05b00f60SXin Li
1972*05b00f60SXin Li #if defined(DLT_LINUX_SLL2) && defined(HAVE_PCAP_SET_DATALINK)
1973*05b00f60SXin Li /* Set default linktype DLT_LINUX_SLL2 when capturing on the "any" device */
1974*05b00f60SXin Li if (device != NULL &&
1975*05b00f60SXin Li strncmp (device, "any", strlen("any")) == 0
1976*05b00f60SXin Li && yflag_dlt == -1)
1977*05b00f60SXin Li yflag_dlt = DLT_LINUX_SLL2;
1978*05b00f60SXin Li #endif
1979*05b00f60SXin Li
1980*05b00f60SXin Li switch (ndo->ndo_tflag) {
1981*05b00f60SXin Li
1982*05b00f60SXin Li case 0: /* Default */
1983*05b00f60SXin Li case 1: /* No time stamp */
1984*05b00f60SXin Li case 2: /* Unix timeval style */
1985*05b00f60SXin Li case 3: /* Microseconds/nanoseconds since previous packet */
1986*05b00f60SXin Li case 4: /* Date + Default */
1987*05b00f60SXin Li case 5: /* Microseconds/nanoseconds since first packet */
1988*05b00f60SXin Li break;
1989*05b00f60SXin Li
1990*05b00f60SXin Li default: /* Not supported */
1991*05b00f60SXin Li error("only -t, -tt, -ttt, -tttt and -ttttt are supported");
1992*05b00f60SXin Li break;
1993*05b00f60SXin Li }
1994*05b00f60SXin Li
1995*05b00f60SXin Li if (ndo->ndo_fflag != 0 && (VFileName != NULL || RFileName != NULL))
1996*05b00f60SXin Li error("-f can not be used with -V or -r");
1997*05b00f60SXin Li
1998*05b00f60SXin Li if (VFileName != NULL && RFileName != NULL)
1999*05b00f60SXin Li error("-V and -r are mutually exclusive.");
2000*05b00f60SXin Li
2001*05b00f60SXin Li /*
2002*05b00f60SXin Li * If we're printing dissected packets to the standard output,
2003*05b00f60SXin Li * and either the standard output is a terminal or we're doing
2004*05b00f60SXin Li * "line" buffering, set the capture timeout to .1 second rather
2005*05b00f60SXin Li * than 1 second, as the user's probably expecting to see packets
2006*05b00f60SXin Li * pop up immediately shortly after they arrive.
2007*05b00f60SXin Li *
2008*05b00f60SXin Li * XXX - would there be some value appropriate for all cases,
2009*05b00f60SXin Li * based on, say, the buffer size and packet input rate?
2010*05b00f60SXin Li */
2011*05b00f60SXin Li if ((WFileName == NULL || print) && (isatty(1) || lflag))
2012*05b00f60SXin Li timeout = 100;
2013*05b00f60SXin Li
2014*05b00f60SXin Li #ifdef WITH_CHROOT
2015*05b00f60SXin Li /* if run as root, prepare for chrooting */
2016*05b00f60SXin Li if (getuid() == 0 || geteuid() == 0) {
2017*05b00f60SXin Li /* future extensibility for cmd-line arguments */
2018*05b00f60SXin Li if (!chroot_dir)
2019*05b00f60SXin Li chroot_dir = WITH_CHROOT;
2020*05b00f60SXin Li }
2021*05b00f60SXin Li #endif
2022*05b00f60SXin Li
2023*05b00f60SXin Li #ifdef WITH_USER
2024*05b00f60SXin Li /* if run as root, prepare for dropping root privileges */
2025*05b00f60SXin Li if (getuid() == 0 || geteuid() == 0) {
2026*05b00f60SXin Li /* Run with '-Z root' to restore old behaviour */
2027*05b00f60SXin Li if (!username)
2028*05b00f60SXin Li username = WITH_USER;
2029*05b00f60SXin Li }
2030*05b00f60SXin Li #endif
2031*05b00f60SXin Li
2032*05b00f60SXin Li if (RFileName != NULL || VFileName != NULL) {
2033*05b00f60SXin Li /*
2034*05b00f60SXin Li * If RFileName is non-null, it's the pathname of a
2035*05b00f60SXin Li * savefile to read. If VFileName is non-null, it's
2036*05b00f60SXin Li * the pathname of a file containing a list of pathnames
2037*05b00f60SXin Li * (one per line) of savefiles to read.
2038*05b00f60SXin Li *
2039*05b00f60SXin Li * In either case, we're reading a savefile, not doing
2040*05b00f60SXin Li * a live capture.
2041*05b00f60SXin Li */
2042*05b00f60SXin Li #ifndef _WIN32
2043*05b00f60SXin Li /*
2044*05b00f60SXin Li * We don't need network access, so relinquish any set-UID
2045*05b00f60SXin Li * or set-GID privileges we have (if any).
2046*05b00f60SXin Li *
2047*05b00f60SXin Li * We do *not* want set-UID privileges when opening a
2048*05b00f60SXin Li * trace file, as that might let the user read other
2049*05b00f60SXin Li * people's trace files (especially if we're set-UID
2050*05b00f60SXin Li * root).
2051*05b00f60SXin Li */
2052*05b00f60SXin Li if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
2053*05b00f60SXin Li fprintf(stderr, "Warning: setgid/setuid failed !\n");
2054*05b00f60SXin Li #endif /* _WIN32 */
2055*05b00f60SXin Li if (VFileName != NULL) {
2056*05b00f60SXin Li if (VFileName[0] == '-' && VFileName[1] == '\0')
2057*05b00f60SXin Li VFile = stdin;
2058*05b00f60SXin Li else
2059*05b00f60SXin Li VFile = fopen(VFileName, "r");
2060*05b00f60SXin Li
2061*05b00f60SXin Li if (VFile == NULL)
2062*05b00f60SXin Li error("Unable to open file: %s\n", pcap_strerror(errno));
2063*05b00f60SXin Li
2064*05b00f60SXin Li ret = get_next_file(VFile, VFileLine);
2065*05b00f60SXin Li if (!ret)
2066*05b00f60SXin Li error("Nothing in %s\n", VFileName);
2067*05b00f60SXin Li RFileName = VFileLine;
2068*05b00f60SXin Li }
2069*05b00f60SXin Li
2070*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
2071*05b00f60SXin Li pd = pcap_open_offline_with_tstamp_precision(RFileName,
2072*05b00f60SXin Li ndo->ndo_tstamp_precision, ebuf);
2073*05b00f60SXin Li #else
2074*05b00f60SXin Li pd = pcap_open_offline(RFileName, ebuf);
2075*05b00f60SXin Li #endif
2076*05b00f60SXin Li
2077*05b00f60SXin Li if (pd == NULL)
2078*05b00f60SXin Li error("%s", ebuf);
2079*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2080*05b00f60SXin Li cap_rights_init(&rights, CAP_READ);
2081*05b00f60SXin Li if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 &&
2082*05b00f60SXin Li errno != ENOSYS) {
2083*05b00f60SXin Li error("unable to limit pcap descriptor");
2084*05b00f60SXin Li }
2085*05b00f60SXin Li #endif
2086*05b00f60SXin Li dlt = pcap_datalink(pd);
2087*05b00f60SXin Li dlt_name = pcap_datalink_val_to_name(dlt);
2088*05b00f60SXin Li fprintf(stderr, "reading from file %s", RFileName);
2089*05b00f60SXin Li if (dlt_name == NULL) {
2090*05b00f60SXin Li fprintf(stderr, ", link-type %u", dlt);
2091*05b00f60SXin Li } else {
2092*05b00f60SXin Li fprintf(stderr, ", link-type %s (%s)", dlt_name,
2093*05b00f60SXin Li pcap_datalink_val_to_description(dlt));
2094*05b00f60SXin Li }
2095*05b00f60SXin Li fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
2096*05b00f60SXin Li #ifdef DLT_LINUX_SLL2
2097*05b00f60SXin Li if (dlt == DLT_LINUX_SLL2)
2098*05b00f60SXin Li fprintf(stderr, "Warning: interface names might be incorrect\n");
2099*05b00f60SXin Li #endif
2100*05b00f60SXin Li } else if (dflag && !device) {
2101*05b00f60SXin Li int dump_dlt = DLT_EN10MB;
2102*05b00f60SXin Li /*
2103*05b00f60SXin Li * We're dumping the compiled code without an explicit
2104*05b00f60SXin Li * device specification. (If a device is specified, we
2105*05b00f60SXin Li * definitely want to open it to use the DLT of that device.)
2106*05b00f60SXin Li * Either default to DLT_EN10MB with a warning, or use
2107*05b00f60SXin Li * the user-specified value if supplied.
2108*05b00f60SXin Li */
2109*05b00f60SXin Li /*
2110*05b00f60SXin Li * If no snapshot length was specified, or a length of 0 was
2111*05b00f60SXin Li * specified, default to 256KB.
2112*05b00f60SXin Li */
2113*05b00f60SXin Li if (ndo->ndo_snaplen == 0)
2114*05b00f60SXin Li ndo->ndo_snaplen = MAXIMUM_SNAPLEN;
2115*05b00f60SXin Li /*
2116*05b00f60SXin Li * If a DLT was specified with the -y flag, use that instead.
2117*05b00f60SXin Li */
2118*05b00f60SXin Li if (yflag_dlt != -1)
2119*05b00f60SXin Li dump_dlt = yflag_dlt;
2120*05b00f60SXin Li else
2121*05b00f60SXin Li fprintf(stderr, "Warning: assuming Ethernet\n");
2122*05b00f60SXin Li pd = pcap_open_dead(dump_dlt, ndo->ndo_snaplen);
2123*05b00f60SXin Li } else {
2124*05b00f60SXin Li /*
2125*05b00f60SXin Li * We're doing a live capture.
2126*05b00f60SXin Li */
2127*05b00f60SXin Li if (device == NULL) {
2128*05b00f60SXin Li /*
2129*05b00f60SXin Li * No interface was specified. Pick one.
2130*05b00f60SXin Li */
2131*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
2132*05b00f60SXin Li /*
2133*05b00f60SXin Li * Find the list of interfaces, and pick
2134*05b00f60SXin Li * the first interface.
2135*05b00f60SXin Li */
2136*05b00f60SXin Li if (pcap_findalldevs(&devlist, ebuf) == -1)
2137*05b00f60SXin Li error("%s", ebuf);
2138*05b00f60SXin Li if (devlist == NULL)
2139*05b00f60SXin Li error("no interfaces available for capture");
2140*05b00f60SXin Li device = strdup(devlist->name);
2141*05b00f60SXin Li pcap_freealldevs(devlist);
2142*05b00f60SXin Li #else /* HAVE_PCAP_FINDALLDEVS */
2143*05b00f60SXin Li /*
2144*05b00f60SXin Li * Use whatever interface pcap_lookupdev()
2145*05b00f60SXin Li * chooses.
2146*05b00f60SXin Li */
2147*05b00f60SXin Li device = pcap_lookupdev(ebuf);
2148*05b00f60SXin Li if (device == NULL)
2149*05b00f60SXin Li error("%s", ebuf);
2150*05b00f60SXin Li #endif
2151*05b00f60SXin Li }
2152*05b00f60SXin Li
2153*05b00f60SXin Li /*
2154*05b00f60SXin Li * Try to open the interface with the specified name.
2155*05b00f60SXin Li */
2156*05b00f60SXin Li pd = open_interface(device, ndo, ebuf);
2157*05b00f60SXin Li if (pd == NULL) {
2158*05b00f60SXin Li /*
2159*05b00f60SXin Li * That failed. If we can get a list of
2160*05b00f60SXin Li * interfaces, and the interface name
2161*05b00f60SXin Li * is purely numeric, try to use it as
2162*05b00f60SXin Li * a 1-based index in the list of
2163*05b00f60SXin Li * interfaces.
2164*05b00f60SXin Li */
2165*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS
2166*05b00f60SXin Li devnum = parse_interface_number(device);
2167*05b00f60SXin Li if (devnum == -1) {
2168*05b00f60SXin Li /*
2169*05b00f60SXin Li * It's not a number; just report
2170*05b00f60SXin Li * the open error and fail.
2171*05b00f60SXin Li */
2172*05b00f60SXin Li error("%s", ebuf);
2173*05b00f60SXin Li }
2174*05b00f60SXin Li
2175*05b00f60SXin Li /*
2176*05b00f60SXin Li * OK, it's a number; try to find the
2177*05b00f60SXin Li * interface with that index, and try
2178*05b00f60SXin Li * to open it.
2179*05b00f60SXin Li *
2180*05b00f60SXin Li * find_interface_by_number() exits if it
2181*05b00f60SXin Li * couldn't be found.
2182*05b00f60SXin Li */
2183*05b00f60SXin Li device = find_interface_by_number(device, devnum);
2184*05b00f60SXin Li pd = open_interface(device, ndo, ebuf);
2185*05b00f60SXin Li if (pd == NULL)
2186*05b00f60SXin Li error("%s", ebuf);
2187*05b00f60SXin Li #else /* HAVE_PCAP_FINDALLDEVS */
2188*05b00f60SXin Li /*
2189*05b00f60SXin Li * We can't get a list of interfaces; just
2190*05b00f60SXin Li * fail.
2191*05b00f60SXin Li */
2192*05b00f60SXin Li error("%s", ebuf);
2193*05b00f60SXin Li #endif /* HAVE_PCAP_FINDALLDEVS */
2194*05b00f60SXin Li }
2195*05b00f60SXin Li
2196*05b00f60SXin Li /*
2197*05b00f60SXin Li * Let user own process after capture device has
2198*05b00f60SXin Li * been opened.
2199*05b00f60SXin Li */
2200*05b00f60SXin Li #ifndef _WIN32
2201*05b00f60SXin Li if (setgid(getgid()) != 0 || setuid(getuid()) != 0)
2202*05b00f60SXin Li fprintf(stderr, "Warning: setgid/setuid failed !\n");
2203*05b00f60SXin Li #endif /* _WIN32 */
2204*05b00f60SXin Li #if !defined(HAVE_PCAP_CREATE) && defined(_WIN32)
2205*05b00f60SXin Li if(Bflag != 0)
2206*05b00f60SXin Li if(pcap_setbuff(pd, Bflag)==-1){
2207*05b00f60SXin Li error("%s", pcap_geterr(pd));
2208*05b00f60SXin Li }
2209*05b00f60SXin Li #endif /* !defined(HAVE_PCAP_CREATE) && defined(_WIN32) */
2210*05b00f60SXin Li if (Lflag)
2211*05b00f60SXin Li show_dlts_and_exit(pd, device);
2212*05b00f60SXin Li if (yflag_dlt >= 0) {
2213*05b00f60SXin Li #ifdef HAVE_PCAP_SET_DATALINK
2214*05b00f60SXin Li if (pcap_set_datalink(pd, yflag_dlt) < 0)
2215*05b00f60SXin Li error("%s", pcap_geterr(pd));
2216*05b00f60SXin Li #else
2217*05b00f60SXin Li /*
2218*05b00f60SXin Li * We don't actually support changing the
2219*05b00f60SXin Li * data link type, so we only let them
2220*05b00f60SXin Li * set it to what it already is.
2221*05b00f60SXin Li */
2222*05b00f60SXin Li if (yflag_dlt != pcap_datalink(pd)) {
2223*05b00f60SXin Li error("%s is not one of the DLTs supported by this device\n",
2224*05b00f60SXin Li yflag_dlt_name);
2225*05b00f60SXin Li }
2226*05b00f60SXin Li #endif
2227*05b00f60SXin Li (void)fprintf(stderr, "%s: data link type %s\n",
2228*05b00f60SXin Li program_name,
2229*05b00f60SXin Li pcap_datalink_val_to_name(yflag_dlt));
2230*05b00f60SXin Li (void)fflush(stderr);
2231*05b00f60SXin Li }
2232*05b00f60SXin Li i = pcap_snapshot(pd);
2233*05b00f60SXin Li if (ndo->ndo_snaplen < i) {
2234*05b00f60SXin Li if (ndo->ndo_snaplen != 0)
2235*05b00f60SXin Li warning("snaplen raised from %d to %d", ndo->ndo_snaplen, i);
2236*05b00f60SXin Li ndo->ndo_snaplen = i;
2237*05b00f60SXin Li } else if (ndo->ndo_snaplen > i) {
2238*05b00f60SXin Li warning("snaplen lowered from %d to %d", ndo->ndo_snaplen, i);
2239*05b00f60SXin Li ndo->ndo_snaplen = i;
2240*05b00f60SXin Li }
2241*05b00f60SXin Li if(ndo->ndo_fflag != 0) {
2242*05b00f60SXin Li if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
2243*05b00f60SXin Li warning("foreign (-f) flag used but: %s", ebuf);
2244*05b00f60SXin Li }
2245*05b00f60SXin Li }
2246*05b00f60SXin Li
2247*05b00f60SXin Li }
2248*05b00f60SXin Li if (infile)
2249*05b00f60SXin Li cmdbuf = read_infile(infile);
2250*05b00f60SXin Li else
2251*05b00f60SXin Li cmdbuf = copy_argv(&argv[optind]);
2252*05b00f60SXin Li
2253*05b00f60SXin Li #ifdef HAVE_PCAP_SET_OPTIMIZER_DEBUG
2254*05b00f60SXin Li pcap_set_optimizer_debug(dflag);
2255*05b00f60SXin Li #endif
2256*05b00f60SXin Li if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
2257*05b00f60SXin Li error("%s", pcap_geterr(pd));
2258*05b00f60SXin Li if (dflag) {
2259*05b00f60SXin Li bpf_dump(&fcode, dflag);
2260*05b00f60SXin Li pcap_close(pd);
2261*05b00f60SXin Li free(cmdbuf);
2262*05b00f60SXin Li pcap_freecode(&fcode);
2263*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
2264*05b00f60SXin Li }
2265*05b00f60SXin Li
2266*05b00f60SXin Li #ifdef HAVE_CASPER
2267*05b00f60SXin Li if (!ndo->ndo_nflag)
2268*05b00f60SXin Li capdns = capdns_setup();
2269*05b00f60SXin Li #endif /* HAVE_CASPER */
2270*05b00f60SXin Li
2271*05b00f60SXin Li init_print(ndo, localnet, netmask);
2272*05b00f60SXin Li
2273*05b00f60SXin Li #ifndef _WIN32
2274*05b00f60SXin Li (void)setsignal(SIGPIPE, cleanup);
2275*05b00f60SXin Li (void)setsignal(SIGTERM, cleanup);
2276*05b00f60SXin Li #endif /* _WIN32 */
2277*05b00f60SXin Li (void)setsignal(SIGINT, cleanup);
2278*05b00f60SXin Li #if defined(HAVE_FORK) || defined(HAVE_VFORK)
2279*05b00f60SXin Li (void)setsignal(SIGCHLD, child_cleanup);
2280*05b00f60SXin Li #endif
2281*05b00f60SXin Li /* Cooperate with nohup(1) */
2282*05b00f60SXin Li #ifndef _WIN32
2283*05b00f60SXin Li if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
2284*05b00f60SXin Li (void)setsignal(SIGHUP, oldhandler);
2285*05b00f60SXin Li #endif /* _WIN32 */
2286*05b00f60SXin Li
2287*05b00f60SXin Li #ifndef _WIN32
2288*05b00f60SXin Li /*
2289*05b00f60SXin Li * If a user name was specified with "-Z", attempt to switch to
2290*05b00f60SXin Li * that user's UID. This would probably be used with sudo,
2291*05b00f60SXin Li * to allow tcpdump to be run in a special restricted
2292*05b00f60SXin Li * account (if you just want to allow users to open capture
2293*05b00f60SXin Li * devices, and can't just give users that permission,
2294*05b00f60SXin Li * you'd make tcpdump set-UID or set-GID).
2295*05b00f60SXin Li *
2296*05b00f60SXin Li * Tcpdump doesn't necessarily write only to one savefile;
2297*05b00f60SXin Li * the general only way to allow a -Z instance to write to
2298*05b00f60SXin Li * savefiles as the user under whose UID it's run, rather
2299*05b00f60SXin Li * than as the user specified with -Z, would thus be to switch
2300*05b00f60SXin Li * to the original user ID before opening a capture file and
2301*05b00f60SXin Li * then switch back to the -Z user ID after opening the savefile.
2302*05b00f60SXin Li * Switching to the -Z user ID only after opening the first
2303*05b00f60SXin Li * savefile doesn't handle the general case.
2304*05b00f60SXin Li */
2305*05b00f60SXin Li
2306*05b00f60SXin Li if (getuid() == 0 || geteuid() == 0) {
2307*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
2308*05b00f60SXin Li /* Initialize capng */
2309*05b00f60SXin Li capng_clear(CAPNG_SELECT_BOTH);
2310*05b00f60SXin Li if (username) {
2311*05b00f60SXin Li DIAG_OFF_ASSIGN_ENUM
2312*05b00f60SXin Li capng_updatev(
2313*05b00f60SXin Li CAPNG_ADD,
2314*05b00f60SXin Li CAPNG_PERMITTED | CAPNG_EFFECTIVE,
2315*05b00f60SXin Li CAP_SETUID,
2316*05b00f60SXin Li CAP_SETGID,
2317*05b00f60SXin Li -1);
2318*05b00f60SXin Li DIAG_ON_ASSIGN_ENUM
2319*05b00f60SXin Li }
2320*05b00f60SXin Li if (chroot_dir) {
2321*05b00f60SXin Li DIAG_OFF_ASSIGN_ENUM
2322*05b00f60SXin Li capng_update(
2323*05b00f60SXin Li CAPNG_ADD,
2324*05b00f60SXin Li CAPNG_PERMITTED | CAPNG_EFFECTIVE,
2325*05b00f60SXin Li CAP_SYS_CHROOT
2326*05b00f60SXin Li );
2327*05b00f60SXin Li DIAG_ON_ASSIGN_ENUM
2328*05b00f60SXin Li }
2329*05b00f60SXin Li
2330*05b00f60SXin Li if (WFileName) {
2331*05b00f60SXin Li DIAG_OFF_ASSIGN_ENUM
2332*05b00f60SXin Li capng_update(
2333*05b00f60SXin Li CAPNG_ADD,
2334*05b00f60SXin Li CAPNG_PERMITTED | CAPNG_EFFECTIVE,
2335*05b00f60SXin Li CAP_DAC_OVERRIDE
2336*05b00f60SXin Li );
2337*05b00f60SXin Li DIAG_ON_ASSIGN_ENUM
2338*05b00f60SXin Li }
2339*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
2340*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
2341*05b00f60SXin Li if (username || chroot_dir)
2342*05b00f60SXin Li droproot(username, chroot_dir);
2343*05b00f60SXin Li
2344*05b00f60SXin Li }
2345*05b00f60SXin Li #endif /* _WIN32 */
2346*05b00f60SXin Li
2347*05b00f60SXin Li if (pcap_setfilter(pd, &fcode) < 0)
2348*05b00f60SXin Li error("%s", pcap_geterr(pd));
2349*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2350*05b00f60SXin Li if (RFileName == NULL && VFileName == NULL && pcap_fileno(pd) != -1) {
2351*05b00f60SXin Li static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF };
2352*05b00f60SXin Li
2353*05b00f60SXin Li /*
2354*05b00f60SXin Li * The various libpcap devices use a combination of
2355*05b00f60SXin Li * read (bpf), ioctl (bpf, netmap), poll (netmap)
2356*05b00f60SXin Li * so we add the relevant access rights.
2357*05b00f60SXin Li */
2358*05b00f60SXin Li cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT);
2359*05b00f60SXin Li if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 &&
2360*05b00f60SXin Li errno != ENOSYS) {
2361*05b00f60SXin Li error("unable to limit pcap descriptor");
2362*05b00f60SXin Li }
2363*05b00f60SXin Li if (cap_ioctls_limit(pcap_fileno(pd), cmds,
2364*05b00f60SXin Li sizeof(cmds) / sizeof(cmds[0])) < 0 && errno != ENOSYS) {
2365*05b00f60SXin Li error("unable to limit ioctls on pcap descriptor");
2366*05b00f60SXin Li }
2367*05b00f60SXin Li }
2368*05b00f60SXin Li #endif
2369*05b00f60SXin Li if (WFileName) {
2370*05b00f60SXin Li /* Do not exceed the default PATH_MAX for files. */
2371*05b00f60SXin Li dumpinfo.CurrentFileName = (char *)malloc(PATH_MAX + 1);
2372*05b00f60SXin Li
2373*05b00f60SXin Li if (dumpinfo.CurrentFileName == NULL)
2374*05b00f60SXin Li error("malloc of dumpinfo.CurrentFileName");
2375*05b00f60SXin Li
2376*05b00f60SXin Li /* We do not need numbering for dumpfiles if Cflag isn't set. */
2377*05b00f60SXin Li if (Cflag != 0)
2378*05b00f60SXin Li MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars);
2379*05b00f60SXin Li else
2380*05b00f60SXin Li MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
2381*05b00f60SXin Li
2382*05b00f60SXin Li pdd = pcap_dump_open(pd, dumpinfo.CurrentFileName);
2383*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
2384*05b00f60SXin Li /* Give up CAP_DAC_OVERRIDE capability.
2385*05b00f60SXin Li * Only allow it to be restored if the -C or -G flag have been
2386*05b00f60SXin Li * set since we may need to create more files later on.
2387*05b00f60SXin Li */
2388*05b00f60SXin Li capng_update(
2389*05b00f60SXin Li CAPNG_DROP,
2390*05b00f60SXin Li (Cflag || Gflag ? 0 : CAPNG_PERMITTED)
2391*05b00f60SXin Li | CAPNG_EFFECTIVE,
2392*05b00f60SXin Li CAP_DAC_OVERRIDE
2393*05b00f60SXin Li );
2394*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
2395*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
2396*05b00f60SXin Li if (pdd == NULL)
2397*05b00f60SXin Li error("%s", pcap_geterr(pd));
2398*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2399*05b00f60SXin Li set_dumper_capsicum_rights(pdd);
2400*05b00f60SXin Li #endif
2401*05b00f60SXin Li if (Cflag != 0 || Gflag != 0) {
2402*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2403*05b00f60SXin Li /*
2404*05b00f60SXin Li * basename() and dirname() may modify their input buffer
2405*05b00f60SXin Li * and they do since FreeBSD 12.0, but they didn't before.
2406*05b00f60SXin Li * Hence use the return value only, but always assume the
2407*05b00f60SXin Li * input buffer has been modified and would need to be
2408*05b00f60SXin Li * reset before the next use.
2409*05b00f60SXin Li */
2410*05b00f60SXin Li char *WFileName_copy;
2411*05b00f60SXin Li
2412*05b00f60SXin Li if ((WFileName_copy = strdup(WFileName)) == NULL) {
2413*05b00f60SXin Li error("Unable to allocate memory for file %s",
2414*05b00f60SXin Li WFileName);
2415*05b00f60SXin Li }
2416*05b00f60SXin Li DIAG_OFF_C11_EXTENSIONS
2417*05b00f60SXin Li dumpinfo.WFileName = strdup(basename(WFileName_copy));
2418*05b00f60SXin Li DIAG_ON_C11_EXTENSIONS
2419*05b00f60SXin Li if (dumpinfo.WFileName == NULL) {
2420*05b00f60SXin Li error("Unable to allocate memory for file %s",
2421*05b00f60SXin Li WFileName);
2422*05b00f60SXin Li }
2423*05b00f60SXin Li free(WFileName_copy);
2424*05b00f60SXin Li
2425*05b00f60SXin Li if ((WFileName_copy = strdup(WFileName)) == NULL) {
2426*05b00f60SXin Li error("Unable to allocate memory for file %s",
2427*05b00f60SXin Li WFileName);
2428*05b00f60SXin Li }
2429*05b00f60SXin Li DIAG_OFF_C11_EXTENSIONS
2430*05b00f60SXin Li char *WFileName_dirname = dirname(WFileName_copy);
2431*05b00f60SXin Li DIAG_ON_C11_EXTENSIONS
2432*05b00f60SXin Li dumpinfo.dirfd = open(WFileName_dirname,
2433*05b00f60SXin Li O_DIRECTORY | O_RDONLY);
2434*05b00f60SXin Li if (dumpinfo.dirfd < 0) {
2435*05b00f60SXin Li error("unable to open directory %s",
2436*05b00f60SXin Li WFileName_dirname);
2437*05b00f60SXin Li }
2438*05b00f60SXin Li free(WFileName_dirname);
2439*05b00f60SXin Li free(WFileName_copy);
2440*05b00f60SXin Li
2441*05b00f60SXin Li cap_rights_init(&rights, CAP_CREATE, CAP_FCNTL,
2442*05b00f60SXin Li CAP_FTRUNCATE, CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
2443*05b00f60SXin Li if (cap_rights_limit(dumpinfo.dirfd, &rights) < 0 &&
2444*05b00f60SXin Li errno != ENOSYS) {
2445*05b00f60SXin Li error("unable to limit directory rights");
2446*05b00f60SXin Li }
2447*05b00f60SXin Li if (cap_fcntls_limit(dumpinfo.dirfd, CAP_FCNTL_GETFL) < 0 &&
2448*05b00f60SXin Li errno != ENOSYS) {
2449*05b00f60SXin Li error("unable to limit dump descriptor fcntls");
2450*05b00f60SXin Li }
2451*05b00f60SXin Li #else /* !HAVE_CAPSICUM */
2452*05b00f60SXin Li dumpinfo.WFileName = WFileName;
2453*05b00f60SXin Li #endif
2454*05b00f60SXin Li callback = dump_packet_and_trunc;
2455*05b00f60SXin Li dumpinfo.pd = pd;
2456*05b00f60SXin Li dumpinfo.pdd = pdd;
2457*05b00f60SXin Li pcap_userdata = (u_char *)&dumpinfo;
2458*05b00f60SXin Li } else {
2459*05b00f60SXin Li callback = dump_packet;
2460*05b00f60SXin Li dumpinfo.WFileName = WFileName;
2461*05b00f60SXin Li dumpinfo.pd = pd;
2462*05b00f60SXin Li dumpinfo.pdd = pdd;
2463*05b00f60SXin Li pcap_userdata = (u_char *)&dumpinfo;
2464*05b00f60SXin Li }
2465*05b00f60SXin Li if (print) {
2466*05b00f60SXin Li dlt = pcap_datalink(pd);
2467*05b00f60SXin Li ndo->ndo_if_printer = get_if_printer(dlt);
2468*05b00f60SXin Li dumpinfo.ndo = ndo;
2469*05b00f60SXin Li } else
2470*05b00f60SXin Li dumpinfo.ndo = NULL;
2471*05b00f60SXin Li
2472*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
2473*05b00f60SXin Li if (Uflag)
2474*05b00f60SXin Li pcap_dump_flush(pdd);
2475*05b00f60SXin Li #endif
2476*05b00f60SXin Li } else {
2477*05b00f60SXin Li dlt = pcap_datalink(pd);
2478*05b00f60SXin Li ndo->ndo_if_printer = get_if_printer(dlt);
2479*05b00f60SXin Li callback = print_packet;
2480*05b00f60SXin Li pcap_userdata = (u_char *)ndo;
2481*05b00f60SXin Li }
2482*05b00f60SXin Li
2483*05b00f60SXin Li #ifdef SIGNAL_REQ_INFO
2484*05b00f60SXin Li /*
2485*05b00f60SXin Li * We can't get statistics when reading from a file rather
2486*05b00f60SXin Li * than capturing from a device.
2487*05b00f60SXin Li */
2488*05b00f60SXin Li if (RFileName == NULL)
2489*05b00f60SXin Li (void)setsignal(SIGNAL_REQ_INFO, requestinfo);
2490*05b00f60SXin Li #endif
2491*05b00f60SXin Li #ifdef SIGNAL_FLUSH_PCAP
2492*05b00f60SXin Li (void)setsignal(SIGNAL_FLUSH_PCAP, flushpcap);
2493*05b00f60SXin Li #endif
2494*05b00f60SXin Li
2495*05b00f60SXin Li if (ndo->ndo_vflag > 0 && WFileName && RFileName == NULL && !print) {
2496*05b00f60SXin Li /*
2497*05b00f60SXin Li * When capturing to a file, if "--print" wasn't specified,
2498*05b00f60SXin Li *"-v" means tcpdump should, once per second,
2499*05b00f60SXin Li * "v"erbosely report the number of packets captured.
2500*05b00f60SXin Li * Except when reading from a file, because -r, -w and -v
2501*05b00f60SXin Li * together used to make a corner case, in which pcap_loop()
2502*05b00f60SXin Li * errored due to EINTR (see GH #155 for details).
2503*05b00f60SXin Li */
2504*05b00f60SXin Li #ifdef _WIN32
2505*05b00f60SXin Li /*
2506*05b00f60SXin Li * https://blogs.msdn.microsoft.com/oldnewthing/20151230-00/?p=92741
2507*05b00f60SXin Li *
2508*05b00f60SXin Li * suggests that this dates back to W2K.
2509*05b00f60SXin Li *
2510*05b00f60SXin Li * I don't know what a "long wait" is, but we'll assume
2511*05b00f60SXin Li * that printing the stats could be a "long wait".
2512*05b00f60SXin Li */
2513*05b00f60SXin Li CreateTimerQueueTimer(&timer_handle, NULL,
2514*05b00f60SXin Li verbose_stats_dump, NULL, 1000, 1000,
2515*05b00f60SXin Li WT_EXECUTEDEFAULT|WT_EXECUTELONGFUNCTION);
2516*05b00f60SXin Li setvbuf(stderr, NULL, _IONBF, 0);
2517*05b00f60SXin Li #else /* _WIN32 */
2518*05b00f60SXin Li /*
2519*05b00f60SXin Li * Assume this is UN*X, and that it has setitimer(); that
2520*05b00f60SXin Li * dates back to UNIX 95.
2521*05b00f60SXin Li */
2522*05b00f60SXin Li struct itimerval timer;
2523*05b00f60SXin Li (void)setsignal(SIGALRM, verbose_stats_dump);
2524*05b00f60SXin Li timer.it_interval.tv_sec = 1;
2525*05b00f60SXin Li timer.it_interval.tv_usec = 0;
2526*05b00f60SXin Li timer.it_value.tv_sec = 1;
2527*05b00f60SXin Li timer.it_value.tv_usec = 1;
2528*05b00f60SXin Li setitimer(ITIMER_REAL, &timer, NULL);
2529*05b00f60SXin Li #endif /* _WIN32 */
2530*05b00f60SXin Li }
2531*05b00f60SXin Li
2532*05b00f60SXin Li if (RFileName == NULL) {
2533*05b00f60SXin Li /*
2534*05b00f60SXin Li * Live capture (if -V was specified, we set RFileName
2535*05b00f60SXin Li * to a file from the -V file). Print a message to
2536*05b00f60SXin Li * the standard error on UN*X.
2537*05b00f60SXin Li */
2538*05b00f60SXin Li if (!ndo->ndo_vflag && !WFileName) {
2539*05b00f60SXin Li (void)fprintf(stderr,
2540*05b00f60SXin Li "%s: verbose output suppressed, use -v[v]... for full protocol decode\n",
2541*05b00f60SXin Li program_name);
2542*05b00f60SXin Li } else
2543*05b00f60SXin Li (void)fprintf(stderr, "%s: ", program_name);
2544*05b00f60SXin Li dlt = pcap_datalink(pd);
2545*05b00f60SXin Li dlt_name = pcap_datalink_val_to_name(dlt);
2546*05b00f60SXin Li (void)fprintf(stderr, "listening on %s", device);
2547*05b00f60SXin Li if (dlt_name == NULL) {
2548*05b00f60SXin Li (void)fprintf(stderr, ", link-type %u", dlt);
2549*05b00f60SXin Li } else {
2550*05b00f60SXin Li (void)fprintf(stderr, ", link-type %s (%s)", dlt_name,
2551*05b00f60SXin Li pcap_datalink_val_to_description(dlt));
2552*05b00f60SXin Li }
2553*05b00f60SXin Li (void)fprintf(stderr, ", snapshot length %d bytes\n", ndo->ndo_snaplen);
2554*05b00f60SXin Li (void)fflush(stderr);
2555*05b00f60SXin Li }
2556*05b00f60SXin Li
2557*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2558*05b00f60SXin Li cansandbox = (VFileName == NULL && zflag == NULL);
2559*05b00f60SXin Li #ifdef HAVE_CASPER
2560*05b00f60SXin Li cansandbox = (cansandbox && (ndo->ndo_nflag || capdns != NULL));
2561*05b00f60SXin Li #else
2562*05b00f60SXin Li cansandbox = (cansandbox && ndo->ndo_nflag);
2563*05b00f60SXin Li #endif /* HAVE_CASPER */
2564*05b00f60SXin Li if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
2565*05b00f60SXin Li error("unable to enter the capability mode");
2566*05b00f60SXin Li #endif /* HAVE_CAPSICUM */
2567*05b00f60SXin Li
2568*05b00f60SXin Li do {
2569*05b00f60SXin Li status = pcap_loop(pd, cnt, callback, pcap_userdata);
2570*05b00f60SXin Li if (WFileName == NULL) {
2571*05b00f60SXin Li /*
2572*05b00f60SXin Li * We're printing packets. Flush the printed output,
2573*05b00f60SXin Li * so it doesn't get intermingled with error output.
2574*05b00f60SXin Li */
2575*05b00f60SXin Li if (status == -2) {
2576*05b00f60SXin Li /*
2577*05b00f60SXin Li * We got interrupted, so perhaps we didn't
2578*05b00f60SXin Li * manage to finish a line we were printing.
2579*05b00f60SXin Li * Print an extra newline, just in case.
2580*05b00f60SXin Li */
2581*05b00f60SXin Li putchar('\n');
2582*05b00f60SXin Li }
2583*05b00f60SXin Li (void)fflush(stdout);
2584*05b00f60SXin Li }
2585*05b00f60SXin Li if (status == -2) {
2586*05b00f60SXin Li /*
2587*05b00f60SXin Li * We got interrupted. If we are reading multiple
2588*05b00f60SXin Li * files (via -V) set these so that we stop.
2589*05b00f60SXin Li */
2590*05b00f60SXin Li VFileName = NULL;
2591*05b00f60SXin Li ret = NULL;
2592*05b00f60SXin Li }
2593*05b00f60SXin Li if (status == -1) {
2594*05b00f60SXin Li /*
2595*05b00f60SXin Li * Error. Report it.
2596*05b00f60SXin Li */
2597*05b00f60SXin Li (void)fprintf(stderr, "%s: pcap_loop: %s\n",
2598*05b00f60SXin Li program_name, pcap_geterr(pd));
2599*05b00f60SXin Li }
2600*05b00f60SXin Li if (RFileName == NULL) {
2601*05b00f60SXin Li /*
2602*05b00f60SXin Li * We're doing a live capture. Report the capture
2603*05b00f60SXin Li * statistics.
2604*05b00f60SXin Li */
2605*05b00f60SXin Li info(1);
2606*05b00f60SXin Li }
2607*05b00f60SXin Li pcap_close(pd);
2608*05b00f60SXin Li if (VFileName != NULL) {
2609*05b00f60SXin Li ret = get_next_file(VFile, VFileLine);
2610*05b00f60SXin Li if (ret) {
2611*05b00f60SXin Li int new_dlt;
2612*05b00f60SXin Li
2613*05b00f60SXin Li RFileName = VFileLine;
2614*05b00f60SXin Li pd = pcap_open_offline(RFileName, ebuf);
2615*05b00f60SXin Li if (pd == NULL)
2616*05b00f60SXin Li error("%s", ebuf);
2617*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2618*05b00f60SXin Li cap_rights_init(&rights, CAP_READ);
2619*05b00f60SXin Li if (cap_rights_limit(fileno(pcap_file(pd)),
2620*05b00f60SXin Li &rights) < 0 && errno != ENOSYS) {
2621*05b00f60SXin Li error("unable to limit pcap descriptor");
2622*05b00f60SXin Li }
2623*05b00f60SXin Li #endif
2624*05b00f60SXin Li new_dlt = pcap_datalink(pd);
2625*05b00f60SXin Li if (new_dlt != dlt) {
2626*05b00f60SXin Li /*
2627*05b00f60SXin Li * The new file has a different
2628*05b00f60SXin Li * link-layer header type from the
2629*05b00f60SXin Li * previous one.
2630*05b00f60SXin Li */
2631*05b00f60SXin Li if (WFileName != NULL) {
2632*05b00f60SXin Li /*
2633*05b00f60SXin Li * We're writing raw packets
2634*05b00f60SXin Li * that match the filter to
2635*05b00f60SXin Li * a pcap file. pcap files
2636*05b00f60SXin Li * don't support multiple
2637*05b00f60SXin Li * different link-layer
2638*05b00f60SXin Li * header types, so we fail
2639*05b00f60SXin Li * here.
2640*05b00f60SXin Li */
2641*05b00f60SXin Li error("%s: new dlt does not match original", RFileName);
2642*05b00f60SXin Li }
2643*05b00f60SXin Li
2644*05b00f60SXin Li /*
2645*05b00f60SXin Li * We're printing the decoded packets;
2646*05b00f60SXin Li * switch to the new DLT.
2647*05b00f60SXin Li *
2648*05b00f60SXin Li * To do that, we need to change
2649*05b00f60SXin Li * the printer, change the DLT name,
2650*05b00f60SXin Li * and recompile the filter with
2651*05b00f60SXin Li * the new DLT.
2652*05b00f60SXin Li */
2653*05b00f60SXin Li dlt = new_dlt;
2654*05b00f60SXin Li ndo->ndo_if_printer = get_if_printer(dlt);
2655*05b00f60SXin Li if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
2656*05b00f60SXin Li error("%s", pcap_geterr(pd));
2657*05b00f60SXin Li }
2658*05b00f60SXin Li
2659*05b00f60SXin Li /*
2660*05b00f60SXin Li * Set the filter on the new file.
2661*05b00f60SXin Li */
2662*05b00f60SXin Li if (pcap_setfilter(pd, &fcode) < 0)
2663*05b00f60SXin Li error("%s", pcap_geterr(pd));
2664*05b00f60SXin Li
2665*05b00f60SXin Li /*
2666*05b00f60SXin Li * Report the new file.
2667*05b00f60SXin Li */
2668*05b00f60SXin Li dlt_name = pcap_datalink_val_to_name(dlt);
2669*05b00f60SXin Li fprintf(stderr, "reading from file %s", RFileName);
2670*05b00f60SXin Li if (dlt_name == NULL) {
2671*05b00f60SXin Li fprintf(stderr, ", link-type %u", dlt);
2672*05b00f60SXin Li } else {
2673*05b00f60SXin Li fprintf(stderr, ", link-type %s (%s)",
2674*05b00f60SXin Li dlt_name,
2675*05b00f60SXin Li pcap_datalink_val_to_description(dlt));
2676*05b00f60SXin Li }
2677*05b00f60SXin Li fprintf(stderr, ", snapshot length %d\n", pcap_snapshot(pd));
2678*05b00f60SXin Li }
2679*05b00f60SXin Li }
2680*05b00f60SXin Li }
2681*05b00f60SXin Li while (ret != NULL);
2682*05b00f60SXin Li
2683*05b00f60SXin Li if (count_mode && RFileName != NULL)
2684*05b00f60SXin Li fprintf(stdout, "%u packet%s\n", packets_captured,
2685*05b00f60SXin Li PLURAL_SUFFIX(packets_captured));
2686*05b00f60SXin Li
2687*05b00f60SXin Li free(cmdbuf);
2688*05b00f60SXin Li pcap_freecode(&fcode);
2689*05b00f60SXin Li exit_tcpdump(status == -1 ? S_ERR_HOST_PROGRAM : S_SUCCESS);
2690*05b00f60SXin Li }
2691*05b00f60SXin Li
2692*05b00f60SXin Li /*
2693*05b00f60SXin Li * Catch a signal.
2694*05b00f60SXin Li */
2695*05b00f60SXin Li static void
setsignal(int sig,void (* func)(int))2696*05b00f60SXin Li (*setsignal (int sig, void (*func)(int)))(int)
2697*05b00f60SXin Li {
2698*05b00f60SXin Li #ifdef _WIN32
2699*05b00f60SXin Li return (signal(sig, func));
2700*05b00f60SXin Li #else
2701*05b00f60SXin Li struct sigaction old, new;
2702*05b00f60SXin Li
2703*05b00f60SXin Li memset(&new, 0, sizeof(new));
2704*05b00f60SXin Li new.sa_handler = func;
2705*05b00f60SXin Li if ((sig == SIGCHLD)
2706*05b00f60SXin Li # ifdef SIGNAL_REQ_INFO
2707*05b00f60SXin Li || (sig == SIGNAL_REQ_INFO)
2708*05b00f60SXin Li # endif
2709*05b00f60SXin Li # ifdef SIGNAL_FLUSH_PCAP
2710*05b00f60SXin Li || (sig == SIGNAL_FLUSH_PCAP)
2711*05b00f60SXin Li # endif
2712*05b00f60SXin Li )
2713*05b00f60SXin Li new.sa_flags = SA_RESTART;
2714*05b00f60SXin Li if (sigaction(sig, &new, &old) < 0)
2715*05b00f60SXin Li return (SIG_ERR);
2716*05b00f60SXin Li return (old.sa_handler);
2717*05b00f60SXin Li #endif
2718*05b00f60SXin Li }
2719*05b00f60SXin Li
2720*05b00f60SXin Li /* make a clean exit on interrupts */
2721*05b00f60SXin Li static void
cleanup(int signo _U_)2722*05b00f60SXin Li cleanup(int signo _U_)
2723*05b00f60SXin Li {
2724*05b00f60SXin Li #ifdef _WIN32
2725*05b00f60SXin Li if (timer_handle != INVALID_HANDLE_VALUE) {
2726*05b00f60SXin Li DeleteTimerQueueTimer(NULL, timer_handle, NULL);
2727*05b00f60SXin Li CloseHandle(timer_handle);
2728*05b00f60SXin Li timer_handle = INVALID_HANDLE_VALUE;
2729*05b00f60SXin Li }
2730*05b00f60SXin Li #else /* _WIN32 */
2731*05b00f60SXin Li struct itimerval timer;
2732*05b00f60SXin Li
2733*05b00f60SXin Li timer.it_interval.tv_sec = 0;
2734*05b00f60SXin Li timer.it_interval.tv_usec = 0;
2735*05b00f60SXin Li timer.it_value.tv_sec = 0;
2736*05b00f60SXin Li timer.it_value.tv_usec = 0;
2737*05b00f60SXin Li setitimer(ITIMER_REAL, &timer, NULL);
2738*05b00f60SXin Li #endif /* _WIN32 */
2739*05b00f60SXin Li
2740*05b00f60SXin Li #ifdef HAVE_PCAP_BREAKLOOP
2741*05b00f60SXin Li /*
2742*05b00f60SXin Li * We have "pcap_breakloop()"; use it, so that we do as little
2743*05b00f60SXin Li * as possible in the signal handler (it's probably not safe
2744*05b00f60SXin Li * to do anything with standard I/O streams in a signal handler -
2745*05b00f60SXin Li * the ANSI C standard doesn't say it is).
2746*05b00f60SXin Li */
2747*05b00f60SXin Li pcap_breakloop(pd);
2748*05b00f60SXin Li #else
2749*05b00f60SXin Li /*
2750*05b00f60SXin Li * We don't have "pcap_breakloop()"; this isn't safe, but
2751*05b00f60SXin Li * it's the best we can do. Print the summary if we're
2752*05b00f60SXin Li * not reading from a savefile - i.e., if we're doing a
2753*05b00f60SXin Li * live capture - and exit.
2754*05b00f60SXin Li */
2755*05b00f60SXin Li if (pd != NULL && pcap_file(pd) == NULL) {
2756*05b00f60SXin Li /*
2757*05b00f60SXin Li * We got interrupted, so perhaps we didn't
2758*05b00f60SXin Li * manage to finish a line we were printing.
2759*05b00f60SXin Li * Print an extra newline, just in case.
2760*05b00f60SXin Li */
2761*05b00f60SXin Li putchar('\n');
2762*05b00f60SXin Li (void)fflush(stdout);
2763*05b00f60SXin Li info(1);
2764*05b00f60SXin Li }
2765*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
2766*05b00f60SXin Li #endif
2767*05b00f60SXin Li }
2768*05b00f60SXin Li
2769*05b00f60SXin Li /*
2770*05b00f60SXin Li On windows, we do not use a fork, so we do not care less about
2771*05b00f60SXin Li waiting a child processes to die
2772*05b00f60SXin Li */
2773*05b00f60SXin Li #if defined(HAVE_FORK) || defined(HAVE_VFORK)
2774*05b00f60SXin Li static void
child_cleanup(int signo _U_)2775*05b00f60SXin Li child_cleanup(int signo _U_)
2776*05b00f60SXin Li {
2777*05b00f60SXin Li wait(NULL);
2778*05b00f60SXin Li }
2779*05b00f60SXin Li #endif /* HAVE_FORK && HAVE_VFORK */
2780*05b00f60SXin Li
2781*05b00f60SXin Li static void
info(int verbose)2782*05b00f60SXin Li info(int verbose)
2783*05b00f60SXin Li {
2784*05b00f60SXin Li struct pcap_stat stats;
2785*05b00f60SXin Li
2786*05b00f60SXin Li /*
2787*05b00f60SXin Li * Older versions of libpcap didn't set ps_ifdrop on some
2788*05b00f60SXin Li * platforms; initialize it to 0 to handle that.
2789*05b00f60SXin Li */
2790*05b00f60SXin Li stats.ps_ifdrop = 0;
2791*05b00f60SXin Li if (pcap_stats(pd, &stats) < 0) {
2792*05b00f60SXin Li (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd));
2793*05b00f60SXin Li infoprint = 0;
2794*05b00f60SXin Li return;
2795*05b00f60SXin Li }
2796*05b00f60SXin Li
2797*05b00f60SXin Li if (!verbose)
2798*05b00f60SXin Li fprintf(stderr, "%s: ", program_name);
2799*05b00f60SXin Li
2800*05b00f60SXin Li (void)fprintf(stderr, "%u packet%s captured", packets_captured,
2801*05b00f60SXin Li PLURAL_SUFFIX(packets_captured));
2802*05b00f60SXin Li if (!verbose)
2803*05b00f60SXin Li fputs(", ", stderr);
2804*05b00f60SXin Li else
2805*05b00f60SXin Li putc('\n', stderr);
2806*05b00f60SXin Li (void)fprintf(stderr, "%u packet%s received by filter", stats.ps_recv,
2807*05b00f60SXin Li PLURAL_SUFFIX(stats.ps_recv));
2808*05b00f60SXin Li if (!verbose)
2809*05b00f60SXin Li fputs(", ", stderr);
2810*05b00f60SXin Li else
2811*05b00f60SXin Li putc('\n', stderr);
2812*05b00f60SXin Li (void)fprintf(stderr, "%u packet%s dropped by kernel", stats.ps_drop,
2813*05b00f60SXin Li PLURAL_SUFFIX(stats.ps_drop));
2814*05b00f60SXin Li if (stats.ps_ifdrop != 0) {
2815*05b00f60SXin Li if (!verbose)
2816*05b00f60SXin Li fputs(", ", stderr);
2817*05b00f60SXin Li else
2818*05b00f60SXin Li putc('\n', stderr);
2819*05b00f60SXin Li (void)fprintf(stderr, "%u packet%s dropped by interface\n",
2820*05b00f60SXin Li stats.ps_ifdrop, PLURAL_SUFFIX(stats.ps_ifdrop));
2821*05b00f60SXin Li } else
2822*05b00f60SXin Li putc('\n', stderr);
2823*05b00f60SXin Li infoprint = 0;
2824*05b00f60SXin Li }
2825*05b00f60SXin Li
2826*05b00f60SXin Li #if defined(HAVE_FORK) || defined(HAVE_VFORK)
2827*05b00f60SXin Li #ifdef HAVE_FORK
2828*05b00f60SXin Li #define fork_subprocess() fork()
2829*05b00f60SXin Li #else
2830*05b00f60SXin Li #define fork_subprocess() vfork()
2831*05b00f60SXin Li #endif
2832*05b00f60SXin Li static void
compress_savefile(const char * filename)2833*05b00f60SXin Li compress_savefile(const char *filename)
2834*05b00f60SXin Li {
2835*05b00f60SXin Li pid_t child;
2836*05b00f60SXin Li
2837*05b00f60SXin Li child = fork_subprocess();
2838*05b00f60SXin Li if (child == -1) {
2839*05b00f60SXin Li fprintf(stderr,
2840*05b00f60SXin Li "compress_savefile: fork failed: %s\n",
2841*05b00f60SXin Li pcap_strerror(errno));
2842*05b00f60SXin Li return;
2843*05b00f60SXin Li }
2844*05b00f60SXin Li if (child != 0) {
2845*05b00f60SXin Li /* Parent process. */
2846*05b00f60SXin Li return;
2847*05b00f60SXin Li }
2848*05b00f60SXin Li
2849*05b00f60SXin Li /*
2850*05b00f60SXin Li * Child process.
2851*05b00f60SXin Li * Set to lowest priority so that this doesn't disturb the capture.
2852*05b00f60SXin Li */
2853*05b00f60SXin Li #ifdef NZERO
2854*05b00f60SXin Li setpriority(PRIO_PROCESS, 0, NZERO - 1);
2855*05b00f60SXin Li #else
2856*05b00f60SXin Li setpriority(PRIO_PROCESS, 0, 19);
2857*05b00f60SXin Li #endif
2858*05b00f60SXin Li if (execlp(zflag, zflag, filename, (char *)NULL) == -1)
2859*05b00f60SXin Li fprintf(stderr,
2860*05b00f60SXin Li "compress_savefile: execlp(%s, %s) failed: %s\n",
2861*05b00f60SXin Li zflag,
2862*05b00f60SXin Li filename,
2863*05b00f60SXin Li pcap_strerror(errno));
2864*05b00f60SXin Li #ifdef HAVE_FORK
2865*05b00f60SXin Li exit(S_ERR_HOST_PROGRAM);
2866*05b00f60SXin Li #else
2867*05b00f60SXin Li _exit(S_ERR_HOST_PROGRAM);
2868*05b00f60SXin Li #endif
2869*05b00f60SXin Li }
2870*05b00f60SXin Li #else /* HAVE_FORK && HAVE_VFORK */
2871*05b00f60SXin Li static void
compress_savefile(const char * filename)2872*05b00f60SXin Li compress_savefile(const char *filename)
2873*05b00f60SXin Li {
2874*05b00f60SXin Li fprintf(stderr,
2875*05b00f60SXin Li "compress_savefile failed. Functionality not implemented under your system\n");
2876*05b00f60SXin Li }
2877*05b00f60SXin Li #endif /* HAVE_FORK && HAVE_VFORK */
2878*05b00f60SXin Li
2879*05b00f60SXin Li static void
dump_packet_and_trunc(u_char * user,const struct pcap_pkthdr * h,const u_char * sp)2880*05b00f60SXin Li dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
2881*05b00f60SXin Li {
2882*05b00f60SXin Li struct dump_info *dump_info;
2883*05b00f60SXin Li
2884*05b00f60SXin Li ++packets_captured;
2885*05b00f60SXin Li
2886*05b00f60SXin Li ++infodelay;
2887*05b00f60SXin Li
2888*05b00f60SXin Li dump_info = (struct dump_info *)user;
2889*05b00f60SXin Li
2890*05b00f60SXin Li /*
2891*05b00f60SXin Li * XXX - this won't force the file to rotate on the specified time
2892*05b00f60SXin Li * boundary, but it will rotate on the first packet received after the
2893*05b00f60SXin Li * specified Gflag number of seconds. Note: if a Gflag time boundary
2894*05b00f60SXin Li * and a Cflag size boundary coincide, the time rotation will occur
2895*05b00f60SXin Li * first thereby cancelling the Cflag boundary (since the file should
2896*05b00f60SXin Li * be 0).
2897*05b00f60SXin Li */
2898*05b00f60SXin Li if (Gflag != 0) {
2899*05b00f60SXin Li /* Check if it is time to rotate */
2900*05b00f60SXin Li time_t t;
2901*05b00f60SXin Li
2902*05b00f60SXin Li /* Get the current time */
2903*05b00f60SXin Li if ((t = time(NULL)) == (time_t)-1) {
2904*05b00f60SXin Li error("%s: can't get current_time: %s",
2905*05b00f60SXin Li __func__, pcap_strerror(errno));
2906*05b00f60SXin Li }
2907*05b00f60SXin Li
2908*05b00f60SXin Li
2909*05b00f60SXin Li /* If the time is greater than the specified window, rotate */
2910*05b00f60SXin Li if (t - Gflag_time >= Gflag) {
2911*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2912*05b00f60SXin Li FILE *fp;
2913*05b00f60SXin Li int fd;
2914*05b00f60SXin Li #endif
2915*05b00f60SXin Li
2916*05b00f60SXin Li /* Update the Gflag_time */
2917*05b00f60SXin Li Gflag_time = t;
2918*05b00f60SXin Li /* Update Gflag_count */
2919*05b00f60SXin Li Gflag_count++;
2920*05b00f60SXin Li /*
2921*05b00f60SXin Li * Close the current file and open a new one.
2922*05b00f60SXin Li */
2923*05b00f60SXin Li pcap_dump_close(dump_info->pdd);
2924*05b00f60SXin Li
2925*05b00f60SXin Li /*
2926*05b00f60SXin Li * Compress the file we just closed, if the user asked for it
2927*05b00f60SXin Li */
2928*05b00f60SXin Li if (zflag != NULL)
2929*05b00f60SXin Li compress_savefile(dump_info->CurrentFileName);
2930*05b00f60SXin Li
2931*05b00f60SXin Li /*
2932*05b00f60SXin Li * Check to see if we've exceeded the Wflag (when
2933*05b00f60SXin Li * not using Cflag).
2934*05b00f60SXin Li */
2935*05b00f60SXin Li if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) {
2936*05b00f60SXin Li (void)fprintf(stderr, "Maximum file limit reached: %d\n",
2937*05b00f60SXin Li Wflag);
2938*05b00f60SXin Li info(1);
2939*05b00f60SXin Li exit_tcpdump(S_SUCCESS);
2940*05b00f60SXin Li /* NOTREACHED */
2941*05b00f60SXin Li }
2942*05b00f60SXin Li if (dump_info->CurrentFileName != NULL)
2943*05b00f60SXin Li free(dump_info->CurrentFileName);
2944*05b00f60SXin Li /* Allocate space for max filename + \0. */
2945*05b00f60SXin Li dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
2946*05b00f60SXin Li if (dump_info->CurrentFileName == NULL)
2947*05b00f60SXin Li error("dump_packet_and_trunc: malloc");
2948*05b00f60SXin Li /*
2949*05b00f60SXin Li * Gflag was set otherwise we wouldn't be here. Reset the count
2950*05b00f60SXin Li * so multiple files would end with 1,2,3 in the filename.
2951*05b00f60SXin Li * The counting is handled with the -C flow after this.
2952*05b00f60SXin Li */
2953*05b00f60SXin Li Cflag_count = 0;
2954*05b00f60SXin Li
2955*05b00f60SXin Li /*
2956*05b00f60SXin Li * This is always the first file in the Cflag
2957*05b00f60SXin Li * rotation: e.g. 0
2958*05b00f60SXin Li * We also don't need numbering if Cflag is not set.
2959*05b00f60SXin Li */
2960*05b00f60SXin Li if (Cflag != 0)
2961*05b00f60SXin Li MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0,
2962*05b00f60SXin Li WflagChars);
2963*05b00f60SXin Li else
2964*05b00f60SXin Li MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0);
2965*05b00f60SXin Li
2966*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
2967*05b00f60SXin Li capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
2968*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
2969*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
2970*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2971*05b00f60SXin Li fd = openat(dump_info->dirfd,
2972*05b00f60SXin Li dump_info->CurrentFileName,
2973*05b00f60SXin Li O_CREAT | O_WRONLY | O_TRUNC, 0644);
2974*05b00f60SXin Li if (fd < 0) {
2975*05b00f60SXin Li error("unable to open file %s",
2976*05b00f60SXin Li dump_info->CurrentFileName);
2977*05b00f60SXin Li }
2978*05b00f60SXin Li fp = fdopen(fd, "w");
2979*05b00f60SXin Li if (fp == NULL) {
2980*05b00f60SXin Li error("unable to fdopen file %s",
2981*05b00f60SXin Li dump_info->CurrentFileName);
2982*05b00f60SXin Li }
2983*05b00f60SXin Li dump_info->pdd = pcap_dump_fopen(dump_info->pd, fp);
2984*05b00f60SXin Li #else /* !HAVE_CAPSICUM */
2985*05b00f60SXin Li dump_info->pdd = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
2986*05b00f60SXin Li #endif
2987*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
2988*05b00f60SXin Li capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
2989*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
2990*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
2991*05b00f60SXin Li if (dump_info->pdd == NULL)
2992*05b00f60SXin Li error("%s", pcap_geterr(pd));
2993*05b00f60SXin Li #ifdef HAVE_CAPSICUM
2994*05b00f60SXin Li set_dumper_capsicum_rights(dump_info->pdd);
2995*05b00f60SXin Li #endif
2996*05b00f60SXin Li }
2997*05b00f60SXin Li }
2998*05b00f60SXin Li
2999*05b00f60SXin Li /*
3000*05b00f60SXin Li * XXX - this won't prevent capture files from getting
3001*05b00f60SXin Li * larger than Cflag - the last packet written to the
3002*05b00f60SXin Li * file could put it over Cflag.
3003*05b00f60SXin Li */
3004*05b00f60SXin Li if (Cflag != 0) {
3005*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FTELL64
3006*05b00f60SXin Li int64_t size = pcap_dump_ftell64(dump_info->pdd);
3007*05b00f60SXin Li #else
3008*05b00f60SXin Li /*
3009*05b00f60SXin Li * XXX - this only handles a Cflag value > 2^31-1 on
3010*05b00f60SXin Li * LP64 platforms; to handle ILP32 (32-bit UN*X and
3011*05b00f60SXin Li * Windows) or LLP64 (64-bit Windows) would require
3012*05b00f60SXin Li * a version of libpcap with pcap_dump_ftell64().
3013*05b00f60SXin Li */
3014*05b00f60SXin Li long size = pcap_dump_ftell(dump_info->pdd);
3015*05b00f60SXin Li #endif
3016*05b00f60SXin Li
3017*05b00f60SXin Li if (size == -1)
3018*05b00f60SXin Li error("ftell fails on output file");
3019*05b00f60SXin Li if (size > Cflag) {
3020*05b00f60SXin Li #ifdef HAVE_CAPSICUM
3021*05b00f60SXin Li FILE *fp;
3022*05b00f60SXin Li int fd;
3023*05b00f60SXin Li #endif
3024*05b00f60SXin Li
3025*05b00f60SXin Li /*
3026*05b00f60SXin Li * Close the current file and open a new one.
3027*05b00f60SXin Li */
3028*05b00f60SXin Li pcap_dump_close(dump_info->pdd);
3029*05b00f60SXin Li
3030*05b00f60SXin Li /*
3031*05b00f60SXin Li * Compress the file we just closed, if the user
3032*05b00f60SXin Li * asked for it.
3033*05b00f60SXin Li */
3034*05b00f60SXin Li if (zflag != NULL)
3035*05b00f60SXin Li compress_savefile(dump_info->CurrentFileName);
3036*05b00f60SXin Li
3037*05b00f60SXin Li Cflag_count++;
3038*05b00f60SXin Li if (Wflag > 0) {
3039*05b00f60SXin Li if (Cflag_count >= Wflag)
3040*05b00f60SXin Li Cflag_count = 0;
3041*05b00f60SXin Li }
3042*05b00f60SXin Li if (dump_info->CurrentFileName != NULL)
3043*05b00f60SXin Li free(dump_info->CurrentFileName);
3044*05b00f60SXin Li dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
3045*05b00f60SXin Li if (dump_info->CurrentFileName == NULL)
3046*05b00f60SXin Li error("%s: malloc", __func__);
3047*05b00f60SXin Li MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars);
3048*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
3049*05b00f60SXin Li capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
3050*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
3051*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
3052*05b00f60SXin Li #ifdef HAVE_CAPSICUM
3053*05b00f60SXin Li fd = openat(dump_info->dirfd, dump_info->CurrentFileName,
3054*05b00f60SXin Li O_CREAT | O_WRONLY | O_TRUNC, 0644);
3055*05b00f60SXin Li if (fd < 0) {
3056*05b00f60SXin Li error("unable to open file %s",
3057*05b00f60SXin Li dump_info->CurrentFileName);
3058*05b00f60SXin Li }
3059*05b00f60SXin Li fp = fdopen(fd, "w");
3060*05b00f60SXin Li if (fp == NULL) {
3061*05b00f60SXin Li error("unable to fdopen file %s",
3062*05b00f60SXin Li dump_info->CurrentFileName);
3063*05b00f60SXin Li }
3064*05b00f60SXin Li dump_info->pdd = pcap_dump_fopen(dump_info->pd, fp);
3065*05b00f60SXin Li #else /* !HAVE_CAPSICUM */
3066*05b00f60SXin Li dump_info->pdd = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
3067*05b00f60SXin Li #endif
3068*05b00f60SXin Li #ifdef HAVE_LIBCAP_NG
3069*05b00f60SXin Li capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
3070*05b00f60SXin Li capng_apply(CAPNG_SELECT_BOTH);
3071*05b00f60SXin Li #endif /* HAVE_LIBCAP_NG */
3072*05b00f60SXin Li if (dump_info->pdd == NULL)
3073*05b00f60SXin Li error("%s", pcap_geterr(pd));
3074*05b00f60SXin Li #ifdef HAVE_CAPSICUM
3075*05b00f60SXin Li set_dumper_capsicum_rights(dump_info->pdd);
3076*05b00f60SXin Li #endif
3077*05b00f60SXin Li }
3078*05b00f60SXin Li }
3079*05b00f60SXin Li
3080*05b00f60SXin Li pcap_dump((u_char *)dump_info->pdd, h, sp);
3081*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
3082*05b00f60SXin Li if (Uflag)
3083*05b00f60SXin Li pcap_dump_flush(dump_info->pdd);
3084*05b00f60SXin Li #endif
3085*05b00f60SXin Li
3086*05b00f60SXin Li if (dump_info->ndo != NULL)
3087*05b00f60SXin Li pretty_print_packet(dump_info->ndo, h, sp, packets_captured);
3088*05b00f60SXin Li
3089*05b00f60SXin Li --infodelay;
3090*05b00f60SXin Li if (infoprint)
3091*05b00f60SXin Li info(0);
3092*05b00f60SXin Li }
3093*05b00f60SXin Li
3094*05b00f60SXin Li static void
dump_packet(u_char * user,const struct pcap_pkthdr * h,const u_char * sp)3095*05b00f60SXin Li dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
3096*05b00f60SXin Li {
3097*05b00f60SXin Li struct dump_info *dump_info;
3098*05b00f60SXin Li
3099*05b00f60SXin Li ++packets_captured;
3100*05b00f60SXin Li
3101*05b00f60SXin Li ++infodelay;
3102*05b00f60SXin Li
3103*05b00f60SXin Li dump_info = (struct dump_info *)user;
3104*05b00f60SXin Li
3105*05b00f60SXin Li pcap_dump((u_char *)dump_info->pdd, h, sp);
3106*05b00f60SXin Li #ifdef HAVE_PCAP_DUMP_FLUSH
3107*05b00f60SXin Li if (Uflag)
3108*05b00f60SXin Li pcap_dump_flush(dump_info->pdd);
3109*05b00f60SXin Li #endif
3110*05b00f60SXin Li
3111*05b00f60SXin Li if (dump_info->ndo != NULL)
3112*05b00f60SXin Li pretty_print_packet(dump_info->ndo, h, sp, packets_captured);
3113*05b00f60SXin Li
3114*05b00f60SXin Li --infodelay;
3115*05b00f60SXin Li if (infoprint)
3116*05b00f60SXin Li info(0);
3117*05b00f60SXin Li }
3118*05b00f60SXin Li
3119*05b00f60SXin Li static void
print_packet(u_char * user,const struct pcap_pkthdr * h,const u_char * sp)3120*05b00f60SXin Li print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
3121*05b00f60SXin Li {
3122*05b00f60SXin Li ++packets_captured;
3123*05b00f60SXin Li
3124*05b00f60SXin Li ++infodelay;
3125*05b00f60SXin Li
3126*05b00f60SXin Li if (!count_mode)
3127*05b00f60SXin Li pretty_print_packet((netdissect_options *)user, h, sp, packets_captured);
3128*05b00f60SXin Li
3129*05b00f60SXin Li --infodelay;
3130*05b00f60SXin Li if (infoprint)
3131*05b00f60SXin Li info(0);
3132*05b00f60SXin Li }
3133*05b00f60SXin Li
3134*05b00f60SXin Li #ifdef SIGNAL_REQ_INFO
3135*05b00f60SXin Li static void
requestinfo(int signo _U_)3136*05b00f60SXin Li requestinfo(int signo _U_)
3137*05b00f60SXin Li {
3138*05b00f60SXin Li if (infodelay)
3139*05b00f60SXin Li ++infoprint;
3140*05b00f60SXin Li else
3141*05b00f60SXin Li info(0);
3142*05b00f60SXin Li }
3143*05b00f60SXin Li #endif
3144*05b00f60SXin Li
3145*05b00f60SXin Li #ifdef SIGNAL_FLUSH_PCAP
3146*05b00f60SXin Li static void
flushpcap(int signo _U_)3147*05b00f60SXin Li flushpcap(int signo _U_)
3148*05b00f60SXin Li {
3149*05b00f60SXin Li if (pdd != NULL)
3150*05b00f60SXin Li pcap_dump_flush(pdd);
3151*05b00f60SXin Li }
3152*05b00f60SXin Li #endif
3153*05b00f60SXin Li
3154*05b00f60SXin Li static void
print_packets_captured(void)3155*05b00f60SXin Li print_packets_captured (void)
3156*05b00f60SXin Li {
3157*05b00f60SXin Li static u_int prev_packets_captured, first = 1;
3158*05b00f60SXin Li
3159*05b00f60SXin Li if (infodelay == 0 && (first || packets_captured != prev_packets_captured)) {
3160*05b00f60SXin Li fprintf(stderr, "Got %u\r", packets_captured);
3161*05b00f60SXin Li first = 0;
3162*05b00f60SXin Li prev_packets_captured = packets_captured;
3163*05b00f60SXin Li }
3164*05b00f60SXin Li }
3165*05b00f60SXin Li
3166*05b00f60SXin Li /*
3167*05b00f60SXin Li * Called once each second in verbose mode while dumping to file
3168*05b00f60SXin Li */
3169*05b00f60SXin Li #ifdef _WIN32
verbose_stats_dump(PVOID param _U_,BOOLEAN timer_fired _U_)3170*05b00f60SXin Li static void CALLBACK verbose_stats_dump(PVOID param _U_,
3171*05b00f60SXin Li BOOLEAN timer_fired _U_)
3172*05b00f60SXin Li {
3173*05b00f60SXin Li print_packets_captured();
3174*05b00f60SXin Li }
3175*05b00f60SXin Li #else /* _WIN32 */
verbose_stats_dump(int sig _U_)3176*05b00f60SXin Li static void verbose_stats_dump(int sig _U_)
3177*05b00f60SXin Li {
3178*05b00f60SXin Li print_packets_captured();
3179*05b00f60SXin Li }
3180*05b00f60SXin Li #endif /* _WIN32 */
3181*05b00f60SXin Li
3182*05b00f60SXin Li DIAG_OFF_DEPRECATION
3183*05b00f60SXin Li static void
print_version(FILE * f)3184*05b00f60SXin Li print_version(FILE *f)
3185*05b00f60SXin Li {
3186*05b00f60SXin Li #ifndef HAVE_PCAP_LIB_VERSION
3187*05b00f60SXin Li #ifdef HAVE_PCAP_VERSION
3188*05b00f60SXin Li extern char pcap_version[];
3189*05b00f60SXin Li #else /* HAVE_PCAP_VERSION */
3190*05b00f60SXin Li static char pcap_version[] = "unknown";
3191*05b00f60SXin Li #endif /* HAVE_PCAP_VERSION */
3192*05b00f60SXin Li #endif /* HAVE_PCAP_LIB_VERSION */
3193*05b00f60SXin Li const char *smi_version_string;
3194*05b00f60SXin Li
3195*05b00f60SXin Li (void)fprintf(f, "%s version " PACKAGE_VERSION "\n", program_name);
3196*05b00f60SXin Li #ifdef HAVE_PCAP_LIB_VERSION
3197*05b00f60SXin Li (void)fprintf(f, "%s\n", pcap_lib_version());
3198*05b00f60SXin Li #else /* HAVE_PCAP_LIB_VERSION */
3199*05b00f60SXin Li (void)fprintf(f, "libpcap version %s\n", pcap_version);
3200*05b00f60SXin Li #endif /* HAVE_PCAP_LIB_VERSION */
3201*05b00f60SXin Li
3202*05b00f60SXin Li #if defined(HAVE_LIBCRYPTO) && defined(SSLEAY_VERSION)
3203*05b00f60SXin Li (void)fprintf (f, "%s\n", SSLeay_version(SSLEAY_VERSION));
3204*05b00f60SXin Li #endif
3205*05b00f60SXin Li
3206*05b00f60SXin Li smi_version_string = nd_smi_version_string();
3207*05b00f60SXin Li if (smi_version_string != NULL)
3208*05b00f60SXin Li (void)fprintf (f, "SMI-library: %s\n", smi_version_string);
3209*05b00f60SXin Li
3210*05b00f60SXin Li #if defined(__SANITIZE_ADDRESS__)
3211*05b00f60SXin Li (void)fprintf (f, "Compiled with AddressSanitizer/GCC.\n");
3212*05b00f60SXin Li #elif defined(__has_feature)
3213*05b00f60SXin Li # if __has_feature(address_sanitizer)
3214*05b00f60SXin Li (void)fprintf (f, "Compiled with AddressSanitizer/Clang.\n");
3215*05b00f60SXin Li # elif __has_feature(memory_sanitizer)
3216*05b00f60SXin Li (void)fprintf (f, "Compiled with MemorySanitizer/Clang.\n");
3217*05b00f60SXin Li # endif
3218*05b00f60SXin Li #endif /* __SANITIZE_ADDRESS__ or __has_feature */
3219*05b00f60SXin Li }
3220*05b00f60SXin Li DIAG_ON_DEPRECATION
3221*05b00f60SXin Li
3222*05b00f60SXin Li static void
print_usage(FILE * f)3223*05b00f60SXin Li print_usage(FILE *f)
3224*05b00f60SXin Li {
3225*05b00f60SXin Li print_version(f);
3226*05b00f60SXin Li (void)fprintf(f,
3227*05b00f60SXin Li "Usage: %s [-Abd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqStu" U_FLAG "vxX#]" B_FLAG_USAGE " [ -c count ] [--count]\n", program_name);
3228*05b00f60SXin Li (void)fprintf(f,
3229*05b00f60SXin Li "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n");
3230*05b00f60SXin Li (void)fprintf(f,
3231*05b00f60SXin Li "\t\t[ -i interface ]" IMMEDIATE_MODE_USAGE j_FLAG_USAGE "\n");
3232*05b00f60SXin Li #ifdef HAVE_PCAP_FINDALLDEVS_EX
3233*05b00f60SXin Li (void)fprintf(f,
3234*05b00f60SXin Li "\t\t" LIST_REMOTE_INTERFACES_USAGE "\n");
3235*05b00f60SXin Li #endif
3236*05b00f60SXin Li #ifdef USE_LIBSMI
3237*05b00f60SXin Li (void)fprintf(f,
3238*05b00f60SXin Li "\t\t" m_FLAG_USAGE "\n");
3239*05b00f60SXin Li #endif
3240*05b00f60SXin Li (void)fprintf(f,
3241*05b00f60SXin Li "\t\t[ -M secret ] [ --number ] [ --print ]" Q_FLAG_USAGE "\n");
3242*05b00f60SXin Li (void)fprintf(f,
3243*05b00f60SXin Li "\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ --version ]\n");
3244*05b00f60SXin Li (void)fprintf(f,
3245*05b00f60SXin Li "\t\t[ -V file ] [ -w file ] [ -W filecount ] [ -y datalinktype ]\n");
3246*05b00f60SXin Li #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
3247*05b00f60SXin Li (void)fprintf(f,
3248*05b00f60SXin Li "\t\t[ --time-stamp-precision precision ] [ --micro ] [ --nano ]\n");
3249*05b00f60SXin Li #endif
3250*05b00f60SXin Li (void)fprintf(f,
3251*05b00f60SXin Li "\t\t[ -z postrotate-command ] [ -Z user ] [ expression ]\n");
3252*05b00f60SXin Li }
3253