man: trafgen: Add example program, rewritten using the trafgen functions
[netsniff-ng-new.git] / ring_tx.c
blobb8ce4461577178130cbbf1b9bb9e5101a0224556
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2009, 2010 Emmanuel Roullit.
5 * Copyright 2014, 2015 Tobias Klauser.
6 * Subject to the GPL, version 2.
7 */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <unistd.h>
13 #include <sys/mman.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <arpa/inet.h>
17 #include <linux/if_ether.h>
19 #include "die.h"
20 #include "xmalloc.h"
21 #include "ring_tx.h"
22 #include "built_in.h"
24 static void set_packet_loss_discard(int sock)
26 int ret, discard = 1;
27 ret = setsockopt(sock, SOL_PACKET, PACKET_LOSS, (void *) &discard,
28 sizeof(discard));
29 if (ret < 0)
30 panic("setsockopt: cannot set packet loss");
33 void destroy_tx_ring(int sock, struct ring *ring)
35 int ret;
37 munmap(ring->mm_space, ring->mm_len);
38 ring->mm_len = 0;
40 fmemset(&ring->layout, 0, sizeof(ring->layout));
41 ret = setsockopt(sock, SOL_PACKET, PACKET_TX_RING, &ring->layout,
42 sizeof(ring->layout));
43 if (unlikely(ret))
44 panic("Cannot destroy the TX_RING: %s!\n", strerror(errno));
46 xfree(ring->frames);
49 static void setup_tx_ring_layout(int sock, struct ring *ring, size_t size,
50 bool jumbo_support)
52 setup_ring_layout_generic(sock, ring, size, jumbo_support);
54 set_sockopt_tpacket_v2(sock);
56 ring_verify_layout(ring);
59 static void create_tx_ring(int sock, struct ring *ring, bool verbose)
61 int ret;
62 retry:
63 ret = setsockopt(sock, SOL_PACKET, PACKET_TX_RING, &ring->layout,
64 sizeof(ring->layout));
66 if (errno == ENOMEM && ring->layout.tp_block_nr > 1) {
67 shrink_ring_layout_generic(ring);
68 goto retry;
71 if (ret < 0)
72 panic("Cannot allocate TX_RING!\n");
74 ring->mm_len = (size_t) ring->layout.tp_block_size * ring->layout.tp_block_nr;
76 if (verbose) {
77 printf("TX,V2: %.2Lf MiB, %u Frames, each %u Byte allocated\n",
78 (long double) ring->mm_len / (1 << 20),
79 ring->layout.tp_frame_nr, ring->layout.tp_frame_size);
83 static void alloc_tx_ring_frames(int sock __maybe_unused, struct ring *ring)
85 alloc_ring_frames_generic(ring, ring->layout.tp_frame_nr,
86 ring->layout.tp_frame_size);
89 void ring_tx_setup(struct ring *ring, int sock, size_t size, int ifindex,
90 bool jumbo_support, bool verbose)
92 fmemset(ring, 0, sizeof(*ring));
93 set_packet_loss_discard(sock);
94 setup_tx_ring_layout(sock, ring, size, jumbo_support);
95 create_tx_ring(sock, ring, verbose);
96 mmap_ring_generic(sock, ring);
97 alloc_tx_ring_frames(sock, ring);
98 bind_ring_generic(sock, ring, ifindex, true);