From 02c7610c3543e9190539efe944e1c90c3ebb5623 Mon Sep 17 00:00:00 2001
Message-Id: <02c7610c3543e9190539efe944e1c90c3ebb5623.1469118440.git.pabeni@redhat.com>
From: Paolo Abeni <pabeni@redhat.com>
Date: Thu, 21 Jul 2016 18:25:49 +0200
Subject: [PATCH] netsniff-ng: Skip duplicated packets on loopback device
Upstream commit: 81f8c546d90b7615e0e6a6777445b10b4263d598
---
netsniff-ng.c | 28 +++++++++++++++++++++-------
1 file changed, 21 insertions(+), 7 deletions(-)
diff --git a/netsniff-ng.c b/netsniff-ng.c
index b238979..75b5ca0 100644
--- a/netsniff-ng.c
+++ b/netsniff-ng.c
@@ -54,7 +54,8 @@ enum dump_mode {
struct ctx {
char *device_in, *device_out, *device_trans, *filter, *prefix;
- int cpu, rfraw, dump, print_mode, dump_dir, packet_type, verbose;
+ int cpu, rfraw, dump, print_mode, dump_dir, packet_type, verbose,
+ lo_ifindex;
unsigned long kpull, dump_interval, reserve_size, tx_bytes, tx_packets;
bool randomize, promiscuous, enforce, jumbo, dump_bpf;
enum pcap_ops_groups pcap;
@@ -346,6 +347,18 @@ static void pcap_to_xmit(struct ctx *ctx)
printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec);
}
+static inline bool skip_packet(struct ctx *ctx, struct sockaddr_ll *sll)
+{
+ if (ctx->packet_type != -1)
+ return ctx->packet_type != sll->sll_pkttype;
+
+ /* when receving from the loopback device, each packet is seen twice,
+ * so drop the outgoing ones to avoid duplicates
+ */
+ return (sll->sll_ifindex == ctx->lo_ifindex) &&
+ (sll->sll_pkttype == PACKET_OUTGOING);
+}
+
static void receive_to_xmit(struct ctx *ctx)
{
short ifflags = 0;
@@ -424,9 +437,8 @@ static void receive_to_xmit(struct ctx *ctx)
frame_count++;
- if (ctx->packet_type != -1)
- if (ctx->packet_type != hdr_in->s_ll.sll_pkttype)
- goto next;
+ if (skip_packet(ctx, &hdr_in->s_ll))
+ goto next;
hdr_out = tx_ring.frames[it_out].iov_base;
out = ((uint8_t *) hdr_out) + TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);
@@ -835,9 +847,8 @@ static void walk_t3_block(struct block_desc *pbd, struct ctx *ctx,
__label__ next;
packet = ((uint8_t *) hdr + hdr->tp_mac);
- if (ctx->packet_type != -1)
- if (ctx->packet_type != sll->sll_pkttype)
- goto next;
+ if (skip_packet(ctx, sll))
+ goto next;
(*frame_count)++;
@@ -1414,6 +1425,9 @@ int main(int argc, char **argv)
if (!ctx.device_in)
ctx.device_in = xstrdup("any");
+ if (!strcmp(ctx.device_in, "any") || !strcmp(ctx.device_in, "lo"))
+ ctx.lo_ifindex = device_ifindex("lo");
+
register_signal(SIGINT, signal_handler);
register_signal(SIGHUP, signal_handler);
--
1.8.3.1