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