2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2009, 2010 Emmanuel Roullit.
5 * Subject to the GPL, version 2.
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <arpa/inet.h>
16 #include <linux/if_ether.h>
23 static void set_packet_loss_discard(int sock
)
26 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_LOSS
, (void *) &discard
,
29 panic("setsockopt: cannot set packet loss");
32 void destroy_tx_ring(int sock
, struct ring
*ring
)
36 munmap(ring
->mm_space
, ring
->mm_len
);
39 fmemset(&ring
->layout
, 0, sizeof(ring
->layout
));
40 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_TX_RING
, &ring
->layout
,
41 sizeof(ring
->layout
));
43 panic("Cannot destroy the TX_RING: %s!\n", strerror(errno
));
48 static void setup_tx_ring_layout(int sock
, struct ring
*ring
, size_t size
,
51 fmemset(&ring
->layout
, 0, sizeof(ring
->layout
));
53 ring
->layout
.tp_block_size
= (jumbo_support
?
54 RUNTIME_PAGE_SIZE
<< 4 :
55 RUNTIME_PAGE_SIZE
<< 2);
57 ring
->layout
.tp_frame_size
= (jumbo_support
?
58 TPACKET_ALIGNMENT
<< 12 :
59 TPACKET_ALIGNMENT
<< 7);
61 ring
->layout
.tp_block_nr
= size
/ ring
->layout
.tp_block_size
;
62 ring
->layout
.tp_frame_nr
= ring
->layout
.tp_block_size
/
63 ring
->layout
.tp_frame_size
*
64 ring
->layout
.tp_block_nr
;
66 set_sockopt_tpacket_v2(sock
);
68 ring_verify_layout(ring
);
71 static void create_tx_ring(int sock
, struct ring
*ring
, bool verbose
)
75 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_TX_RING
, &ring
->layout
,
76 sizeof(ring
->layout
));
78 if (errno
== ENOMEM
&& ring
->layout
.tp_block_nr
> 1) {
79 ring
->layout
.tp_block_nr
>>= 1;
80 ring
->layout
.tp_frame_nr
= ring
->layout
.tp_block_size
/
81 ring
->layout
.tp_frame_size
*
82 ring
->layout
.tp_block_nr
;
87 panic("Cannot allocate TX_RING!\n");
89 ring
->mm_len
= (size_t) ring
->layout
.tp_block_size
* ring
->layout
.tp_block_nr
;
92 printf("TX,V2: %.2Lf MiB, %u Frames, each %u Byte allocated\n",
93 (long double) ring
->mm_len
/ (1 << 20),
94 ring
->layout
.tp_frame_nr
, ring
->layout
.tp_frame_size
);
98 static void alloc_tx_ring_frames(int sock __maybe_unused
, struct ring
*ring
)
100 alloc_ring_frames_generic(ring
, ring
->layout
.tp_frame_nr
,
101 ring
->layout
.tp_frame_size
);
104 void ring_tx_setup(struct ring
*ring
, int sock
, size_t size
, int ifindex
,
105 bool jumbo_support
, bool verbose
)
107 fmemset(ring
, 0, sizeof(*ring
));
108 set_packet_loss_discard(sock
);
109 setup_tx_ring_layout(sock
, ring
, size
, jumbo_support
);
110 create_tx_ring(sock
, ring
, verbose
);
111 mmap_ring_generic(sock
, ring
);
112 alloc_tx_ring_frames(sock
, ring
);
113 bind_ring_generic(sock
, ring
, ifindex
, true);