source: rtems-libbsd/freebsd/contrib/tcpdump/tcpdump.c @ 8440506

4.115-freebsd-12freebsd-9.3
Last change on this file since 8440506 was 8440506, checked in by Chris Johns <chrisj@…>, on Jun 15, 2015 at 7:42:23 AM

Add tcpdump and libpcap.

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