2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Copyright 2014, 2015 Tobias Klauser
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 void setup_ring_layout_generic(struct ring
*ring
, size_t size
,
26 memset(&ring
->layout
, 0, sizeof(ring
->layout
));
28 ring
->layout
.tp_block_size
= (jumbo_support
?
29 RUNTIME_PAGE_SIZE
<< 4 :
30 RUNTIME_PAGE_SIZE
<< 2);
32 ring
->layout
.tp_frame_size
= (jumbo_support
?
33 TPACKET_ALIGNMENT
<< 12 :
34 TPACKET_ALIGNMENT
<< 7);
36 ring
->layout
.tp_block_nr
= size
/ ring
->layout
.tp_block_size
;
37 ring
->layout
.tp_frame_nr
= ring
->layout
.tp_block_size
/
38 ring
->layout
.tp_frame_size
*
39 ring
->layout
.tp_block_nr
;
42 void mmap_ring_generic(int sock
, struct ring
*ring
)
44 ring
->mm_space
= mmap(NULL
, ring
->mm_len
, PROT_READ
| PROT_WRITE
,
45 MAP_SHARED
| MAP_LOCKED
| MAP_POPULATE
, sock
, 0);
46 if (ring
->mm_space
== MAP_FAILED
)
47 panic("Cannot mmap {TX,RX}_RING!\n");
50 void alloc_ring_frames_generic(struct ring
*ring
, size_t num
, size_t size
)
52 size_t i
, len
= num
* sizeof(*ring
->frames
);
54 ring
->frames
= xzmalloc_aligned(len
, CO_CACHE_LINE_SIZE
);
56 for (i
= 0; i
< num
; ++i
) {
57 ring
->frames
[i
].iov_len
= size
;
58 ring
->frames
[i
].iov_base
= ring
->mm_space
+ (i
* size
);
62 void bind_ring_generic(int sock
, struct ring
*ring
, int ifindex
, bool tx_only
)
66 /* The {TX,RX}_RING registers itself to the networking stack with
67 * dev_add_pack(), so we have one single RX_RING for all devs
68 * otherwise you'll get the packet twice.
70 memset(&ring
->s_ll
, 0, sizeof(ring
->s_ll
));
72 ring
->s_ll
.sll_family
= AF_PACKET
;
73 ring
->s_ll
.sll_ifindex
= ifindex
;
74 ring
->s_ll
.sll_protocol
= tx_only
? 0 : htons(ETH_P_ALL
);
76 ret
= bind(sock
, (struct sockaddr
*) &ring
->s_ll
, sizeof(ring
->s_ll
));
78 panic("Cannot bind {TX,RX}_RING!\n");