From: Vadim Kochan
Allow to collect rx stats for multiple pcap mode, by storing
them in separated variables before switch to the next pcap file.
It allows to have the one approach when dump for single or multiple
pcap(s) mode.
Signed-off-by: Vadim Kochan
---
RFC -> PATCH:
1) Fixed alignments
2) Returned maybe_unused
3) Check ret value of get rx stats func before dump it
4) Returned considering PRINT_MODE
netsniff-ng.c | 118 --
ring_rx.c | 23 ++--
ring_rx.h | 2 +-
3 files changed, 77 insertions(+), 66 deletions(-)
diff --git a/netsniff-ng.c b/netsniff-ng.c
index 57edc43..3b69c8f 100644
--- a/netsniff-ng.c
+++ b/netsniff-ng.c
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include "ring_rx.h"
#include "ring_tx.h"
@@ -64,6 +65,8 @@ struct ctx {
gid_t gid;
uint32_t link_type, magic;
uint32_t fanout_group, fanout_type;
+ uint64_t pkts_seen, pkts_recvd, pkts_drops;
+ uint64_t pkts_recvd_last, pkts_drops_last;
};
static volatile sig_atomic_t sigint = 0, sighup = 0;
@@ -203,6 +206,41 @@ static inline void setup_rfmon_mac80211_dev(struct ctx
*ctx, char **rfmon_dev)
panic_handler_add(on_panic_del_rfmon, *rfmon_dev);
}
+static int update_rx_stats(struct ctx *ctx, int sock, bool is_v3)
+{
+ uint64_t packets, drops;
+ int ret;
+
+ ret = get_rx_net_stats(sock, &packets, &drops, is_v3);
+ if (ret)
+ return ret;
+
+ ctx->pkts_recvd += packets;
+ ctx->pkts_drops += drops;
+ ctx->pkts_recvd_last = packets;
+ ctx->pkts_drops_last = drops;
+
+ return 0;
+}
+
+static void dump_rx_stats(struct ctx *ctx, int sock, bool is_v3)
+{
+ if (update_rx_stats(ctx, sock, is_v3))
+ return;
+
+ printf("\r%12"PRIu64" packets incoming (%"PRIu64" unread on exit)\n",
+ is_v3 ? ctx->pkts_seen : ctx->pkts_recvd,
+ is_v3 ? ctx->pkts_recvd - ctx->pkts_seen : 0);
+ printf("\r%12"PRIu64" packets passed filter\n",
+ ctx->pkts_recvd - ctx->pkts_drops);
+ printf("\r%12"PRIu64" packets failed filter (out of space)\n",
+ ctx->pkts_drops);
+
+ if (ctx->pkts_recvd > 0)
+ printf("\r%12.4lf%% packet droprate\n",
+ (1.0 * ctx->pkts_drops / ctx->pkts_recvd) * 100.0);
+}
+
static void pcap_to_xmit(struct ctx *ctx)
{
uint8_t *out = NULL;
@@ -376,7 +414,6 @@ static void receive_to_xmit(struct ctx *ctx)
int rx_sock, ifindex_in, ifindex_out, ret;
size_t size_in, size_out;
unsigned int it_in = 0, it_out = 0;
- unsigned long frame_count = 0;
struct frame_map *hdr_in, *hdr_out;
struct ring tx_ring, rx_ring;
struct pollfd rx_poll;
@@ -428,7 +465,7 @@ static void receive_to_xmit(struct ctx *ctx)
hdr_in = rx_ring.frames[it_in].iov_base;
in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;
- frame_count++;
+ ctx->pkts_seen++;
if (ctx->packet_type != -1)
if (ctx->packet_type !=
hdr_in->s_ll.sll_pkttype)
@@ -465,14 +502,14 @@ static void receive_to_xmit(struct ctx *ctx)
show_frame_hdr(in, hdr_in->tp_h.tp_snaplen,
ctx->link_type, hdr_in, ctx->print_mode,
- frame_count);
+ ctx->pkts_seen);
dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
ctx->link_type, ctx->print_mode,
&hdr_in->s_ll);
if (frame_count_max != 0) {
- if (frame_count >= frame_count_max) {
+ if (ctx->pkts_seen >= frame_count_max) {
sigint = 1;
break;
}
@@ -499,7 +536,7 @@ next:
out:
timer_purge();
- sock_rx_net_stats(rx_sock, 0);
+ dump_rx_stats(ctx, rx_sock, false);
bpf_release(&bpf_ops);
@@ -844,26 +881,8 @@ static int begin_single_pcap_file(struct ctx *ctx)
return fd;
}
-static void print_pcap_file_stats(int sock, struct ctx *ctx)
-{
- int ret;
- struct tpacket_stats kstats;
- socklen_t slen = sizeof(kstats);
-
- fmemset(&kstats, 0, sizeof(kstats));
-
- ret = getsockopt(sock, SOL_PACKET, PACKET_STATISTICS, &kstats, &slen);
- if (unlikely(ret))
- panic("Cannot get packet statistics!\n");
-
- if (ctx->print_mode == PRINT_NONE) {
- printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
- kstats.tp_drops);
- fflush(stdout)