diff --git a/cmd/xdpcap/flags.go b/cmd/xdpcap/flags.go index a5e21d6..8a61267 100644 --- a/cmd/xdpcap/flags.go +++ b/cmd/xdpcap/flags.go @@ -181,6 +181,8 @@ type flags struct { // Filter provided as input. Not in any particular format, for metadata / debugging only. filterExpr string filterOpts filterOpts + + maxPackets uint64 } // parseFlags creates the flags, and attempts to parse args. @@ -196,6 +198,7 @@ func parseFlags(name string, args []string) (flags, error) { flags.IntVar(&flags.filterOpts.perfPerCPUBuffer, "buffer", 8192, "Per CPU perf buffer size to create (`bytes`)") flags.IntVar(&flags.filterOpts.perfWatermark, "watermark", 1, "Perf watermark (`bytes`). Must be < buffer.") + flags.Uint64Var(&flags.maxPackets, "c", 0, "Maximum number of packets to capture across all `actions`. 0 indicates unlimited") flags.BoolVar(&flags.quiet, "q", false, "Don't print statistics") flags.BoolVar(&flags.flush, "flush", false, "Flush pcap data written to for every packet received") diff --git a/cmd/xdpcap/flags_test.go b/cmd/xdpcap/flags_test.go index 93dcb61..d949d05 100644 --- a/cmd/xdpcap/flags_test.go +++ b/cmd/xdpcap/flags_test.go @@ -136,7 +136,7 @@ func TestFilterRawInvalid(t *testing.T) { func TestOptions(t *testing.T) { output := tempOutput(t) - flags, err := parseFlags("", []string{"-buffer", "1234", "-watermark", "5678", "-q", "-flush", "-actions", "pass,drop", "-linktype", "802.11", "foo", output}) + flags, err := parseFlags("", []string{"-buffer", "1234", "-watermark", "5678", "-q", "-flush", "-actions", "pass,drop", "-linktype", "802.11", "-c", "1000", "foo", output}) if err != nil { t.Fatal(err) } @@ -148,6 +148,7 @@ func TestOptions(t *testing.T) { expected.flush = true expected.filterOpts.actions = []xdpAction{xdpPass, xdpDrop} expected.linkType = layers.LinkTypeIEEE802_11 + expected.maxPackets = 1000 requireFlags(t, output, expected, flags) } diff --git a/cmd/xdpcap/main.go b/cmd/xdpcap/main.go index 364d282..caaf0ce 100644 --- a/cmd/xdpcap/main.go +++ b/cmd/xdpcap/main.go @@ -106,6 +106,8 @@ func capture(flags flags) error { // Write out a pcap file from aggregated packets go func() { + totalPackets := uint64(0) + for { pkt, err := filter.read() switch { @@ -134,6 +136,13 @@ func capture(flags flags) error { fmt.Fprintln(os.Stderr, "Error flushing data:", err) } } + + if flags.maxPackets != 0 { + totalPackets++ + if totalPackets >= flags.maxPackets { + sigs <- syscall.SIGTERM + } + } } }()