]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
Give more information on -l, and note that -U works without -w.
[tcpdump] / tcpdump.c
index c8da36baa92592284844e58af56b537a647b3f55..587ed32170ac925df013cd2d8cb8473737e71003 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -87,6 +87,12 @@ extern int SIZE_BUF;
 #define NAME_MAX 255
 #endif
 
+#ifdef SIGINFO
+#define SIGNAL_REQ_INFO SIGINFO
+#elif SIGUSR1
+#define SIGNAL_REQ_INFO SIGUSR1
+#endif
+
 netdissect_options Gndo;
 netdissect_options *gndo = &Gndo;
 
@@ -115,10 +121,11 @@ static void ndo_default_print(netdissect_options *, const u_char *, u_int);
 static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
 static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
 static void droproot(const char *, const char *);
-static void ndo_error(netdissect_options *ndo, const char *fmt, ...);
+static void ndo_error(netdissect_options *ndo, const char *fmt, ...)
+     __attribute__ ((noreturn, format (printf, 2, 3)));
 static void ndo_warning(netdissect_options *ndo, const char *fmt, ...);
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
 RETSIGTYPE requestinfo(int);
 #endif
 
@@ -133,10 +140,6 @@ RETSIGTYPE requestinfo(int);
 static void info(int);
 static u_int packets_captured;
 
-typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *);
-typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo,
-                                const struct pcap_pkthdr *, const u_char *);
-
 struct printer {
         if_printer f;
        int type;
@@ -314,11 +317,20 @@ static struct ndo_printer ndo_printers[] = {
 #endif
 #ifdef DLT_IEEE802_15_4_NOFCS
        { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
+#endif
+#ifdef DLT_PPI
+       { ppi_if_print,         DLT_PPI },
+#endif
+#ifdef DLT_NETANALYZER
+       { netanalyzer_if_print, DLT_NETANALYZER },
+#endif
+#ifdef DLT_NETANALYZER_TRANSPARENT
+       { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
 #endif
        { NULL,                 0 },
 };
 
-static if_printer
+if_printer
 lookup_printer(int type)
 {
        struct printer *p;
@@ -331,7 +343,7 @@ lookup_printer(int type)
        /* NOTREACHED */
 }
 
-static if_ndo_printer
+if_ndo_printer
 lookup_ndo_printer(int type)
 {
        struct ndo_printer *p;
@@ -652,9 +664,8 @@ main(int argc, char **argv)
        smiInit("tcpdump");
 #endif
 
-       opterr = 0;
        while (
-           (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1)
+           (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 "vw:W:xXy:Yz:Z:")) != -1)
                switch (op) {
 
                case 'a':
@@ -748,7 +759,11 @@ main(int argc, char **argv)
                        break;
 
                case 'h':
-                       ++hflag;
+                       usage();
+                       break;
+
+               case 'H':
+                       ++Hflag;
                        break;
 
                case 'i':
@@ -924,6 +939,8 @@ main(int argc, char **argv)
                                packettype = PT_TFTP;
                        else if (strcasecmp(optarg, "aodv") == 0)
                                packettype = PT_AODV;
+                       else if (strcasecmp(optarg, "carp") == 0)
+                               packettype = PT_CARP;
                        else
                                error("unknown packet type `%s'", optarg);
                        break;
@@ -1250,8 +1267,10 @@ main(int argc, char **argv)
        (void)setsignal(SIGPIPE, cleanup);
        (void)setsignal(SIGTERM, cleanup);
        (void)setsignal(SIGINT, cleanup);
-       (void)setsignal(SIGCHLD, child_cleanup);
 #endif /* WIN32 */
+#if defined(HAVE_FORK) || defined(HAVE_VFORK)
+       (void)setsignal(SIGCHLD, child_cleanup);
+#endif
        /* Cooperate with nohup(1) */
 #ifndef WIN32  
        if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
@@ -1336,13 +1355,13 @@ main(int argc, char **argv)
                pcap_userdata = (u_char *)&printinfo;
        }
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
        /*
         * We can't get statistics when reading from a file rather
         * than capturing from a device.
         */
        if (RFileName == NULL)
-               (void)setsignal(SIGINFO, requestinfo);
+               (void)setsignal(SIGNAL_REQ_INFO, requestinfo);
 #endif
 
        if (vflag > 0 && WFileName) {
@@ -1464,13 +1483,13 @@ cleanup(int signo _U_)
   On windows, we do not use a fork, so we do not care less about
   waiting a child processes to die
  */
-#ifndef WIN32
+#if defined(HAVE_FORK) || defined(HAVE_VFORK)
 static RETSIGTYPE
 child_cleanup(int signo _U_)
 {
   wait(NULL);
 }
-#endif /* WIN32 */
+#endif /* HAVE_FORK && HAVE_VFORK */
 
 static void
 info(register int verbose)
@@ -1491,34 +1510,41 @@ info(register int verbose)
        if (!verbose)
                fprintf(stderr, "%s: ", program_name);
 
-       (void)fprintf(stderr, "%u packets captured", packets_captured);
+       (void)fprintf(stderr, "%u packet%s captured", packets_captured,
+           PLURAL_SUFFIX(packets_captured));
        if (!verbose)
                fputs(", ", stderr);
        else
                putc('\n', stderr);
-       (void)fprintf(stderr, "%u packets received by filter", stat.ps_recv);
+       (void)fprintf(stderr, "%u packet%s received by filter", stat.ps_recv,
+           PLURAL_SUFFIX(stat.ps_recv));
        if (!verbose)
                fputs(", ", stderr);
        else
                putc('\n', stderr);
-       (void)fprintf(stderr, "%u packets dropped by kernel", stat.ps_drop);
+       (void)fprintf(stderr, "%u packet%s dropped by kernel", stat.ps_drop,
+           PLURAL_SUFFIX(stat.ps_drop));
        if (stat.ps_ifdrop != 0) {
                if (!verbose)
                        fputs(", ", stderr);
                else
                        putc('\n', stderr);
-               (void)fprintf(stderr, "%u packets dropped by interface\n",
-                   stat.ps_ifdrop);
+               (void)fprintf(stderr, "%u packet%s dropped by interface\n",
+                   stat.ps_ifdrop, PLURAL_SUFFIX(stat.ps_ifdrop));
        } else
                putc('\n', stderr);
        infoprint = 0;
 }
 
-#ifndef WIN32
+#if defined(HAVE_FORK) || defined(HAVE_VFORK)
 static void
 compress_savefile(const char *filename)
 {
+# ifdef HAVE_FORK
        if (fork())
+# else
+       if (vfork())
+# endif
                return;
        /*
         * Set to lowest priority so that this doesn't disturb the capture
@@ -1534,15 +1560,20 @@ compress_savefile(const char *filename)
                        zflag,
                        filename,
                        strerror(errno));
+# ifdef HAVE_FORK
+       exit(1);
+# else
+       _exit(1);
+# endif
 }
-#else  /* WIN32 */
+#else  /* HAVE_FORK && HAVE_VFORK */
 static void
 compress_savefile(const char *filename)
 {
        fprintf(stderr,
-               "compress_savefile failed. Functionality not implemented under windows\n");
+               "compress_savefile failed. Functionality not implemented under your system\n");
 }
-#endif /* WIN32 */
+#endif /* HAVE_FORK && HAVE_VFORK */
 
 static void
 dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
@@ -1819,7 +1850,7 @@ default_print(const u_char *bp, u_int length)
        ndo_default_print(gndo, bp, length);
 }
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
 RETSIGTYPE requestinfo(int signo _U_)
 {
        if (infodelay)
@@ -1881,7 +1912,7 @@ usage(void)
 #endif /* WIN32 */
 #endif /* HAVE_PCAP_LIB_VERSION */
        (void)fprintf(stderr,
-"Usage: %s [-aAbd" D_FLAG "efh" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
+"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
        (void)fprintf(stderr,
 "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n");
        (void)fprintf(stderr,