]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Add --print-sampling option to print every Nth packet
authorNathan O'Sullivan <[email protected]>
Mon, 17 Jan 2022 00:05:15 +0000 (10:05 +1000)
committerDenis Ovsienko <[email protected]>
Mon, 17 Jan 2022 19:43:59 +0000 (19:43 +0000)
New option `--print-sampling=NTH` will parse and print every NTH packet,
with all other packets producing no output. This option enables
`--print` and `-S` flags.

Print sampling is useful for real-time inspection of an interface with
a high packet rate, or initial inspection of large capture files.

CHANGES
netdissect.h
print.c
tcpdump.1.in
tcpdump.c
tests/TESTLIST
tests/print-sampling.out [new file with mode: 0644]

diff --git a/CHANGES b/CHANGES
index 05ab4f3527af108eb8ebf3974a0ae8b77d193d94..97fdb08833b30b441d37ed609bedbd9c8dbe6e23 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -10,6 +10,8 @@ Monthday, Month DD, YYYY by gharris and denis
       VQP: Do not print unknown error codes twice.
       ZMTP: Replace custom code with bittok2str().
       BFD: Add support for S-BFD and spell LAG in uppercase.
       VQP: Do not print unknown error codes twice.
       ZMTP: Replace custom code with bittok2str().
       BFD: Add support for S-BFD and spell LAG in uppercase.
+    User interface:
+      Add --print-sampling to print every Nth packet instead of all.
     Source code:
       Use %zu when printing a sizeof to squelch compiler warnings
       (FIXME: somebody please wrap the line below just before the release)
     Source code:
       Use %zu when printing a sizeof to squelch compiler warnings
       (FIXME: somebody please wrap the line below just before the release)
index b509b432d41f20e4976c8e1776eb578c46d51ae8..89da451ebb84e7da2c907983bbe21c94e3849153 100644 (file)
@@ -220,6 +220,7 @@ struct netdissect_options {
   jmp_buf ndo_early_end;       /* jmp_buf for setjmp()/longjmp() */
   void *ndo_last_mem_p;                /* pointer to the last allocated memory chunk */
   int ndo_packet_number;       /* print a packet number in the beginning of line */
   jmp_buf ndo_early_end;       /* jmp_buf for setjmp()/longjmp() */
   void *ndo_last_mem_p;                /* pointer to the last allocated memory chunk */
   int ndo_packet_number;       /* print a packet number in the beginning of line */
+  int ndo_print_sampling;      /* print every Nth packet */
   int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */
   int ndo_tstamp_precision;    /* requested time stamp precision */
   const char *program_name;    /* Name of the program using the library */
   int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */
   int ndo_tstamp_precision;    /* requested time stamp precision */
   const char *program_name;    /* Name of the program using the library */
diff --git a/print.c b/print.c
index 265eee7b8a4cd15b0f5c27a7242a6bfc90d50a58..2e827f71fccc7ca8b06a36fce207c6230c8731a8 100644 (file)
--- a/print.c
+++ b/print.c
@@ -315,6 +315,9 @@ pretty_print_packet(netdissect_options *ndo, const struct pcap_pkthdr *h,
        u_int hdrlen = 0;
        int invalid_header = 0;
 
        u_int hdrlen = 0;
        int invalid_header = 0;
 
+       if (ndo->ndo_print_sampling && packets_captured % ndo->ndo_print_sampling != 0)
+               return;
+
        if (ndo->ndo_packet_number)
                ND_PRINT("%5u  ", packets_captured);
 
        if (ndo->ndo_packet_number)
                ND_PRINT("%5u  ", packets_captured);
 
index 2bc13e5367c64aac67a24134e31ecd67657aa487..1e05d0bd2dfeb9ffc5d75d4647adae561d94dc0b 100644 (file)
@@ -20,7 +20,7 @@
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
 .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 .\"
-.TH TCPDUMP 1  "29 November 2021"
+.TH TCPDUMP 1  "17 January 2022"
 .SH NAME
 tcpdump \- dump traffic on a network
 .SH SYNOPSIS
 .SH NAME
 tcpdump \- dump traffic on a network
 .SH SYNOPSIS
@@ -86,15 +86,20 @@ tcpdump \- dump traffic on a network
 [
 .B \-\-print
 ]
 [
 .B \-\-print
 ]
+.ti +8
+[
+.B \-\-print\-sampling
+.I nth
+]
 [
 .B \-Q
 .I in|out|inout
 ]
 [
 .B \-Q
 .I in|out|inout
 ]
-.ti +8
 [
 .B \-r
 .I file
 ]
 [
 .B \-r
 .I file
 ]
+.ti +8
 [
 .B \-s
 .I snaplen
 [
 .B \-s
 .I snaplen
@@ -106,11 +111,11 @@ tcpdump \- dump traffic on a network
 [
 .B \-\-version
 ]
 [
 .B \-\-version
 ]
-.ti +8
 [
 .B \-V
 .I file
 ]
 [
 .B \-V
 .I file
 ]
+.ti +8
 [
 .B \-w
 .I file
 [
 .B \-w
 .I file
@@ -653,6 +658,17 @@ file with the
 .B \-w
 flag.
 .TP
 .B \-w
 flag.
 .TP
+.BI \-\-print\-sampling= nth
+.PD
+Print every \fInth\fP packet. This option enables the \fB--print\fP flag.
+.IP
+Unprinted packets are not parsed, which decreases processing time. Setting
+\fInth\fP to \fB100\fP for example, will (counting from 1) parse and print the
+100th packet, 200th patcket, 300th packet, and so on.
+.IP
+This option also enables the \fB-S\fP flag, as relative TCP sequence
+numbers are not tracked for unprinted packets.
+.TP
 .BI \-Q " direction"
 .PD 0
 .TP
 .BI \-Q " direction"
 .PD 0
 .TP
index a4403370e715b4c5b91e90bcd750f5a9565724a0..73e097196d85ef1c961e5581de28aa72dddbcd50 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -691,6 +691,7 @@ show_remote_devices_and_exit(void)
 #define OPTION_TSTAMP_NANO             134
 #define OPTION_FP_TYPE                 135
 #define OPTION_COUNT                   136
 #define OPTION_TSTAMP_NANO             134
 #define OPTION_FP_TYPE                 135
 #define OPTION_COUNT                   136
+#define OPTION_PRINT_SAMPLING          137
 
 static const struct option longopts[] = {
 #if defined(HAVE_PCAP_CREATE) || defined(_WIN32)
 
 static const struct option longopts[] = {
 #if defined(HAVE_PCAP_CREATE) || defined(_WIN32)
@@ -738,6 +739,7 @@ static const struct option longopts[] = {
        { "fp-type", no_argument, NULL, OPTION_FP_TYPE },
        { "number", no_argument, NULL, '#' },
        { "print", no_argument, NULL, OPTION_PRINT },
        { "fp-type", no_argument, NULL, OPTION_FP_TYPE },
        { "number", no_argument, NULL, '#' },
        { "print", no_argument, NULL, OPTION_PRINT },
+       { "print-sampling", required_argument, NULL, OPTION_PRINT_SAMPLING },
        { "version", no_argument, NULL, OPTION_VERSION },
        { NULL, 0, NULL, 0 }
 };
        { "version", no_argument, NULL, OPTION_VERSION },
        { NULL, 0, NULL, 0 }
 };
@@ -1960,6 +1962,14 @@ main(int argc, char **argv)
                        print = 1;
                        break;
 
                        print = 1;
                        break;
 
+               case OPTION_PRINT_SAMPLING:
+                       print = 1;
+                       ++ndo->ndo_Sflag;
+                       ndo->ndo_print_sampling = atoi(optarg);
+                       if (ndo->ndo_print_sampling <= 0)
+                               error("invalid print sampling %s", optarg);
+                       break;
+
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
                case OPTION_TSTAMP_MICRO:
                        ndo->ndo_tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
                case OPTION_TSTAMP_MICRO:
                        ndo->ndo_tstamp_precision = PCAP_TSTAMP_PRECISION_MICRO;
@@ -3262,9 +3272,11 @@ print_usage(FILE *f)
 "\t\t" m_FLAG_USAGE "\n");
 #endif
        (void)fprintf(f,
 "\t\t" m_FLAG_USAGE "\n");
 #endif
        (void)fprintf(f,
-"\t\t[ -M secret ] [ --number ] [ --print ]" Q_FLAG_USAGE "\n");
+"\t\t[ -M secret ] [ --number ] [ --print ]\n");
+       (void)fprintf(f,
+"\t\t[ --print-sampling nth ]" Q_FLAG_USAGE " [ -r file ]\n");
        (void)fprintf(f,
        (void)fprintf(f,
-"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ --version ]\n");
+"\t\t[ -s snaplen ] [ -T type ] [ --version ]\n");
        (void)fprintf(f,
 "\t\t[ -V file ] [ -w file ] [ -W filecount ] [ -y datalinktype ]\n");
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
        (void)fprintf(f,
 "\t\t[ -V file ] [ -w file ] [ -W filecount ] [ -y datalinktype ]\n");
 #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION
index 96045f82b979a66ffaed6a60e6dac9bc49d70fa2..1ca9bbbf2becb8a8ac72e01df63d45e66caf2d64 100644 (file)
@@ -18,6 +18,7 @@ print-X               print-flags.pcap        print-capX.out  -X
 print-XX       print-flags.pcap        print-capXX.out -XX
 print-A                print-flags.pcap        print-A.out     -A
 print-AA       print-flags.pcap        print-AA.out    -AA
 print-XX       print-flags.pcap        print-capXX.out -XX
 print-A                print-flags.pcap        print-A.out     -A
 print-AA       print-flags.pcap        print-AA.out    -AA
+print-sampling print-flags.pcap print-sampling.out --print-sampling=3
 
 # TCP 3-Way Handshake test, nano precision
 # Use "no -t", -t, -tt, -ttt, -tttt, -ttttt options for more code coverage
 
 # TCP 3-Way Handshake test, nano precision
 # Use "no -t", -t, -tt, -ttt, -tttt, -ttttt options for more code coverage
diff --git a/tests/print-sampling.out b/tests/print-sampling.out
new file mode 100644 (file)
index 0000000..839becc
--- /dev/null
@@ -0,0 +1,3 @@
+    3  03:57:35.938167 IP 127.0.0.1.55920 > 127.0.0.1.80: Flags [.], ack 930778610, win 8192, options [nop,nop,TS val 1306300950 ecr 1306300950], length 0
+    6  03:57:35.941232 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [P.], seq 930778610:930784169, ack 928549449, win 8192, options [nop,nop,TS val 1306300953 ecr 1306300951], length 5559: HTTP: HTTP/1.1 200 OK
+    9  03:57:37.230839 IP 127.0.0.1.80 > 127.0.0.1.55920: Flags [F.], seq 930784169, ack 928549450, win 8192, options [nop,nop,TS val 1306302243 ecr 1306302241], length 0