diff options
author | Paolo Abeni <pabeni@redhat.com> | 2016-07-21 15:25:27 +0200 |
---|---|---|
committer | Tobias Klauser <tklauser@distanz.ch> | 2016-07-21 15:39:05 +0200 |
commit | 81f8c546d90b7615e0e6a6777445b10b4263d598 (patch) | |
tree | 41b697375caac65a0312cb662bc6f147716d46c0 | |
parent | 20f72d2b68969f75b0a116e49b133363d4b6fb9a (diff) |
netsniff-ng: Skip duplicated packets on loopback device
When sniffing on the loopback device, each packet will be seen
twice, once per direction. To avoid duplicates, explicitly
skip OUTGOING packets received from loopback, if no packet_type
filter is explicitly set.
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r-- | netsniff-ng.c | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/netsniff-ng.c b/netsniff-ng.c index 8d22151..4cfabc1 100644 --- a/netsniff-ng.c +++ b/netsniff-ng.c @@ -55,7 +55,7 @@ enum dump_mode { struct ctx { char *device_in, *device_out, *device_trans, *filter, *prefix; - int cpu, rfraw, dump, print_mode, dump_dir, packet_type; + int cpu, rfraw, dump, print_mode, dump_dir, packet_type, lo_ifindex; unsigned long kpull, dump_interval, tx_bytes, tx_packets; size_t reserve_size; bool randomize, promiscuous, enforce, jumbo, dump_bpf, hwtimestamp, verbose; @@ -410,6 +410,18 @@ out: 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; @@ -470,9 +482,8 @@ static void receive_to_xmit(struct ctx *ctx) ctx->pkts_seen++; - 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); @@ -942,9 +953,8 @@ static void walk_t3_block(struct block_desc *pbd, struct ctx *ctx, uint8_t *packet = ((uint8_t *) hdr + hdr->tp_mac); pcap_pkthdr_t phdr; - if (ctx->packet_type != -1) - if (ctx->packet_type != sll->sll_pkttype) - goto next; + if (skip_packet(ctx, sll)) + goto next; ctx->pkts_seen++; @@ -1071,9 +1081,8 @@ static void recv_only_or_dump(struct ctx *ctx) uint8_t *packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac; pcap_pkthdr_t phdr; - if (ctx->packet_type != -1) - if (ctx->packet_type != hdr->s_ll.sll_pkttype) - goto next; + if (skip_packet(ctx, &hdr->s_ll)) + goto next; ctx->pkts_seen++; @@ -1523,6 +1532,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(SIGQUIT, signal_handler); register_signal(SIGTERM, signal_handler); |