summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--astraceroute/Makefile1
-rw-r--r--netsniff-ng/Makefile1
-rw-r--r--ring.c64
-rw-r--r--ring.h4
-rw-r--r--ring_rx.c43
-rw-r--r--ring_tx.c43
-rw-r--r--trafgen/Makefile1
7 files changed, 85 insertions, 72 deletions
diff --git a/astraceroute/Makefile b/astraceroute/Makefile
index 91f0a9e..36e37f0 100644
--- a/astraceroute/Makefile
+++ b/astraceroute/Makefile
@@ -10,4 +10,5 @@ astraceroute-objs = xmalloc.o \
bpf.o \
geoip.o \
ring_rx.o \
+ ring.o \
astraceroute.o
diff --git a/netsniff-ng/Makefile b/netsniff-ng/Makefile
index b50778f..211c726 100644
--- a/netsniff-ng/Makefile
+++ b/netsniff-ng/Makefile
@@ -44,6 +44,7 @@ netsniff-ng-objs = dissector.o \
pcap_mm.o \
ring_rx.o \
ring_tx.o \
+ ring.o \
tprintf.o \
tstamping.o \
geoip.o \
diff --git a/ring.c b/ring.c
new file mode 100644
index 0000000..2899df3
--- /dev/null
+++ b/ring.c
@@ -0,0 +1,64 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2009, 2010 Daniel Borkmann.
+ * Subject to the GPL, version 2.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <linux/if_ether.h>
+
+#include "xmalloc.h"
+#include "die.h"
+#include "ring.h"
+#include "built_in.h"
+
+void mmap_ring_generic(int sock, struct ring *ring)
+{
+ ring->mm_space = mmap(0, ring->mm_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED | MAP_LOCKED | MAP_POPULATE, sock, 0);
+ if (ring->mm_space == MAP_FAILED)
+ panic("Cannot mmap {TX,RX}_RING!\n");
+}
+
+void alloc_ring_frames_generic(struct ring *ring)
+{
+ int i;
+ size_t len = ring->layout.tp_frame_nr * sizeof(*ring->frames);
+
+ ring->frames = xmalloc_aligned(len, CO_CACHE_LINE_SIZE);
+ fmemset(ring->frames, 0, len);
+
+ for (i = 0; i < ring->layout.tp_frame_nr; ++i) {
+ ring->frames[i].iov_len = ring->layout.tp_frame_size;
+ ring->frames[i].iov_base = ring->mm_space +
+ (i * ring->layout.tp_frame_size);
+ }
+}
+
+void bind_ring_generic(int sock, struct ring *ring, int ifindex)
+{
+ int ret;
+ /* The {TX,RX}_RING registers itself to the networking stack with
+ * dev_add_pack(), so we have one single RX_RING for all devs
+ * otherwise you'll get the packet twice.
+ */
+ fmemset(&ring->s_ll, 0, sizeof(ring->s_ll));
+
+ ring->s_ll.sll_family = AF_PACKET;
+ ring->s_ll.sll_protocol = htons(ETH_P_ALL);
+ ring->s_ll.sll_ifindex = ifindex;
+ ring->s_ll.sll_hatype = 0;
+ ring->s_ll.sll_halen = 0;
+ ring->s_ll.sll_pkttype = 0;
+
+ ret = bind(sock, (struct sockaddr *) &ring->s_ll, sizeof(ring->s_ll));
+ if (ret < 0)
+ panic("Cannot bind {TX,RX}_RING!\n");
+}
diff --git a/ring.h b/ring.h
index 1074e8d..93edb01 100644
--- a/ring.h
+++ b/ring.h
@@ -141,4 +141,8 @@ static inline int get_sockopt_tpacket(int sock)
return __get_sockopt_tpacket(sock);
}
+extern void mmap_ring_generic(int sock, struct ring *ring);
+extern void alloc_ring_frames_generic(struct ring *ring);
+extern void bind_ring_generic(int sock, struct ring *ring, int ifindex);
+
#endif /* RING_H */
diff --git a/ring_rx.c b/ring_rx.c
index a3d8e4d..de19568 100644
--- a/ring_rx.c
+++ b/ring_rx.c
@@ -43,9 +43,11 @@ void setup_rx_ring_layout(int sock, struct ring *ring, unsigned int size,
ring->layout.tp_block_size = (jumbo_support ?
getpagesize() << 4 :
getpagesize() << 2);
+
ring->layout.tp_frame_size = (jumbo_support ?
TPACKET_ALIGNMENT << 12 :
TPACKET_ALIGNMENT << 7);
+
ring->layout.tp_block_nr = size / ring->layout.tp_block_size;
ring->layout.tp_frame_nr = ring->layout.tp_block_size /
ring->layout.tp_frame_size *
@@ -77,6 +79,7 @@ void create_rx_ring(int sock, struct ring *ring, int verbose)
retry:
ret = setsockopt(sock, SOL_PACKET, PACKET_RX_RING, &ring->raw,
v3 ? sizeof(ring->layout3) : sizeof(ring->layout));
+
if (errno == ENOMEM && ring->layout.tp_block_nr > 1) {
ring->layout.tp_block_nr >>= 1;
ring->layout.tp_frame_nr = ring->layout.tp_block_size /
@@ -98,49 +101,15 @@ retry:
void mmap_rx_ring(int sock, struct ring *ring)
{
- ring->mm_space = mmap(0, ring->mm_len, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_LOCKED | MAP_POPULATE, sock, 0);
- if (ring->mm_space == MAP_FAILED) {
- destroy_rx_ring(sock, ring);
- panic("Cannot mmap RX_RING!\n");
- }
+ mmap_ring_generic(sock, ring);
}
void alloc_rx_ring_frames(struct ring *ring)
{
- int i;
- size_t len = ring->layout.tp_frame_nr * sizeof(*ring->frames);
-
- ring->frames = xmalloc_aligned(len, CO_CACHE_LINE_SIZE);
- fmemset(ring->frames, 0, len);
-
- for (i = 0; i < ring->layout.tp_frame_nr; ++i) {
- ring->frames[i].iov_len = ring->layout.tp_frame_size;
- ring->frames[i].iov_base = ring->mm_space +
- (i * ring->layout.tp_frame_size);
- }
+ alloc_ring_frames_generic(ring);
}
void bind_rx_ring(int sock, struct ring *ring, int ifindex)
{
- int ret;
- /*
- * The RX_RING registers itself to the networking stack with
- * dev_add_pack(), so we have one single RX_RING for all devs
- * otherwise you'll get the packet twice.
- */
- fmemset(&ring->s_ll, 0, sizeof(ring->s_ll));
-
- ring->s_ll.sll_family = AF_PACKET;
- ring->s_ll.sll_protocol = htons(ETH_P_ALL);
- ring->s_ll.sll_ifindex = ifindex;
- ring->s_ll.sll_hatype = 0;
- ring->s_ll.sll_halen = 0;
- ring->s_ll.sll_pkttype = 0;
-
- ret = bind(sock, (struct sockaddr *) &ring->s_ll, sizeof(ring->s_ll));
- if (ret < 0) {
- destroy_rx_ring(sock, ring);
- panic("Cannot bind RX_RING!\n");
- }
+ bind_ring_generic(sock, ring, ifindex);
}
diff --git a/ring_tx.c b/ring_tx.c
index f4f06a1..18216ac 100644
--- a/ring_tx.c
+++ b/ring_tx.c
@@ -53,25 +53,28 @@ void setup_tx_ring_layout(int sock, struct ring *ring, unsigned int size,
ring->layout.tp_block_size = (jumbo_support ?
getpagesize() << 4 :
getpagesize() << 2);
+
ring->layout.tp_frame_size = (jumbo_support ?
TPACKET_ALIGNMENT << 12 :
TPACKET_ALIGNMENT << 7);
+
ring->layout.tp_block_nr = size / ring->layout.tp_block_size;
ring->layout.tp_frame_nr = ring->layout.tp_block_size /
ring->layout.tp_frame_size *
ring->layout.tp_block_nr;
+ set_sockopt_tpacket_v2(sock);
+
ring_verify_layout(ring);
}
void create_tx_ring(int sock, struct ring *ring, int verbose)
{
int ret;
-
- set_sockopt_tpacket_v2(sock);
retry:
ret = setsockopt(sock, SOL_PACKET, PACKET_TX_RING, &ring->layout,
sizeof(ring->layout));
+
if (errno == ENOMEM && ring->layout.tp_block_nr > 1) {
ring->layout.tp_block_nr >>= 1;
ring->layout.tp_frame_nr = ring->layout.tp_block_size /
@@ -94,45 +97,15 @@ retry:
void mmap_tx_ring(int sock, struct ring *ring)
{
- ring->mm_space = mmap(0, ring->mm_len, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_LOCKED | MAP_POPULATE, sock, 0);
- if (ring->mm_space == MAP_FAILED) {
- destroy_tx_ring(sock, ring);
- panic("Cannot mmap TX_RING!\n");
- }
+ mmap_ring_generic(sock, ring);
}
void alloc_tx_ring_frames(struct ring *ring)
{
- int i;
- size_t len = ring->layout.tp_frame_nr * sizeof(*ring->frames);
-
- ring->frames = xmalloc_aligned(len, CO_CACHE_LINE_SIZE);
- fmemset(ring->frames, 0, len);
-
- for (i = 0; i < ring->layout.tp_frame_nr; ++i) {
- ring->frames[i].iov_len = ring->layout.tp_frame_size;
- ring->frames[i].iov_base = ring->mm_space +
- (i * ring->layout.tp_frame_size);
- }
+ alloc_ring_frames_generic(ring);
}
void bind_tx_ring(int sock, struct ring *ring, int ifindex)
{
- int ret;
-
- fmemset(&ring->s_ll, 0, sizeof(ring->s_ll));
-
- ring->s_ll.sll_family = AF_PACKET;
- ring->s_ll.sll_protocol = htons(ETH_P_ALL);
- ring->s_ll.sll_ifindex = ifindex;
- ring->s_ll.sll_hatype = 0;
- ring->s_ll.sll_halen = 0;
- ring->s_ll.sll_pkttype = 0;
-
- ret = bind(sock, (struct sockaddr *) &ring->s_ll, sizeof(ring->s_ll));
- if (ret < 0) {
- destroy_tx_ring(sock, ring);
- panic("Cannot bind TX_RING!\n");
- }
+ bind_ring_generic(sock, ring, ifindex);
}
diff --git a/trafgen/Makefile b/trafgen/Makefile
index b34b98c..8257ad1 100644
--- a/trafgen/Makefile
+++ b/trafgen/Makefile
@@ -7,6 +7,7 @@ trafgen-objs = xmalloc.o \
xutils.o \
mac80211.o \
ring_tx.o \
+ ring.o \
trafgen_lexer.yy.o \
trafgen_parser.tab.o \
trafgen.o