]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
added -C option to rotate save file every optarg * 1,000,000 bytes.
[tcpdump] / tcpdump.c
index b59a15212d697357aa969fdf8fd5411d7dc3797d..f19c54d43b344ec3b799c58198f9fcec7baab0b9 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
  *     The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 #ifndef lint
 static const char copyright[] =
-    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\
+    "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
 The Regents of the University of California.  All rights reserved.\n";
 static const char rcsid[] =
-    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.165 2001-06-24 20:38:52 itojun Exp $ (LBL)";
+    "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.167 2001-10-01 01:12:01 mcr Exp $ (LBL)";
 #endif
 
 /*
@@ -76,13 +76,17 @@ int uflag = 0;                      /* Print undecoded NFS handles */
 int vflag;                     /* verbose */
 int xflag;                     /* print packet in hex */
 int Xflag;                     /* print packet in ascii as well as hex */
+off_t Cflag = 0;                /* rotate dump files after this many bytes */
 
 char *espsecret = NULL;                /* ESP secret key */
 
 int packettype;
 
+int infodelay;
+int infoprint;
 
 char *program_name;
+char *WFileName;
 
 int32_t thiszone;              /* seconds offset from gmt to local time */
 
@@ -90,6 +94,12 @@ int32_t thiszone;            /* seconds offset from gmt to local time */
 static RETSIGTYPE cleanup(int);
 static void usage(void) __attribute__((noreturn));
 
+extern void dump_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp);
+
+#ifdef SIGINFO
+RETSIGTYPE requestinfo(int);
+#endif
+
 /* Length of saved portion of packet. */
 int snaplen = DEFAULT_SNAPLEN;
 
@@ -159,7 +169,7 @@ lookup_printer(int type)
        /* NOTREACHED */
 }
 
-static pcap_t *pd;
+pcap_t *pd;
 
 extern int optind;
 extern int opterr;
@@ -170,7 +180,8 @@ main(int argc, char **argv)
 {
        register int cnt, op, i;
        bpf_u_int32 localnet, netmask;
-       register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
+       register char *cp, *infile, *cmdbuf, *device, *RFileName;
+       extern char *WFileName;
        pcap_handler printer;
        struct bpf_program fcode;
        RETSIGTYPE (*oldhandler)(int);
@@ -196,7 +207,7 @@ main(int argc, char **argv)
        
        opterr = 0;
        while (
-           (op = getopt(argc, argv, "ac:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1)
+           (op = getopt(argc, argv, "ac:C:deE:fF:i:lm:nNOpqr:Rs:StT:uvw:xXY")) != -1)
                switch (op) {
 
                case 'a':
@@ -209,6 +220,12 @@ main(int argc, char **argv)
                                error("invalid packet count %s", optarg);
                        break;
 
+               case 'C':
+                       Cflag = atoi(optarg) * 1000000;
+                       if (Cflag < 0) 
+                               error("invalid file size %s", optarg);
+                       break;
+
                case 'd':
                        ++dflag;
                        break;
@@ -431,12 +448,16 @@ main(int argc, char **argv)
                pcap_dumper_t *p = pcap_dump_open(pd, WFileName);
                if (p == NULL)
                        error("%s", pcap_geterr(pd));
-               printer = pcap_dump;
+               printer = dump_and_trunc;
                pcap_userdata = (u_char *)p;
        } else {
                printer = lookup_printer(pcap_datalink(pd));
                pcap_userdata = 0;
+#ifdef SIGINFO
+               (void)setsignal(SIGINFO, requestinfo);
+#endif
        }
+
        if (RFileName == NULL) {
                (void)fprintf(stderr, "%s: listening on %s\n",
                    program_name, device);
@@ -455,25 +476,36 @@ main(int argc, char **argv)
 static RETSIGTYPE
 cleanup(int signo)
 {
-       struct pcap_stat stat;
 
        /* Can't print the summary if reading from a savefile */
        if (pd != NULL && pcap_file(pd) == NULL) {
                (void)fflush(stdout);
                putc('\n', stderr);
-               if (pcap_stats(pd, &stat) < 0)
-                       (void)fprintf(stderr, "pcap_stats: %s\n",
-                           pcap_geterr(pd));
-               else {
-                       (void)fprintf(stderr, "%d packets received by filter\n",
-                           stat.ps_recv);
-                       (void)fprintf(stderr, "%d packets dropped by kernel\n",
-                           stat.ps_drop);
-               }
+               info(1);
        }
        exit(0);
 }
 
+void
+info(register int verbose)
+{
+       struct pcap_stat stat;
+
+       if (pcap_stats(pd, &stat) < 0) {
+               (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd));
+               return;
+       }
+       if (!verbose)
+               fprintf(stderr, "%s: ", program_name);
+       (void)fprintf(stderr, "%d packets received by filter", stat.ps_recv);
+       if (!verbose)
+               fputs(", ", stderr);
+       else
+               putc('\n', stderr);
+       (void)fprintf(stderr, "%d packets dropped by kernel\n", stat.ps_drop);
+       infoprint = 0;
+}
+
 /* Like default_print() but data need not be aligned */
 void
 default_print_unaligned(register const u_char *cp, register u_int length)
@@ -509,6 +541,16 @@ default_print(register const u_char *bp, register u_int length)
        default_print_unaligned(bp, length);
 }
 
+#ifdef SIGINFO
+RETSIGTYPE requestinfo(int signo)
+{
+       if (infodelay)
+               ++infoprint;
+       else
+               info(0);
+}
+#endif
+
 static void
 usage(void)
 {