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

4.1155-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 59bc7c1 was c31922b, checked in by Chris Johns <chrisj@…>, on 06/19/15 at 05:32:13

Fix RTEMS ifdef labelling.

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