2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
12 #include <sys/types.h>
13 #include <sys/socket.h>
14 #include <arpa/inet.h>
15 #include <linux/if_ether.h>
22 void destroy_rx_ring(int sock
, struct ring
*ring
)
26 munmap(ring
->mm_space
, ring
->mm_len
);
29 fmemset(&ring
->layout
, 0, sizeof(ring
->layout
));
30 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_RX_RING
, &ring
->layout
,
31 sizeof(ring
->layout
));
33 panic("Cannot destroy the RX_RING: %s!\n", strerror(errno
));
38 void setup_rx_ring_layout(int sock
, struct ring
*ring
, unsigned int size
,
39 bool jumbo_support
, bool v3
)
41 fmemset(&ring
->layout
, 0, sizeof(ring
->layout
));
43 ring
->layout
.tp_block_size
= (jumbo_support
?
47 ring
->layout
.tp_frame_size
= (jumbo_support
?
48 TPACKET_ALIGNMENT
<< 12 :
49 TPACKET_ALIGNMENT
<< 7);
51 ring
->layout
.tp_block_nr
= size
/ ring
->layout
.tp_block_size
;
52 ring
->layout
.tp_frame_nr
= ring
->layout
.tp_block_size
/
53 ring
->layout
.tp_frame_size
*
54 ring
->layout
.tp_block_nr
;
56 /* Pass out, if this will ever change and we do crap on it! */
57 build_bug_on(offsetof(struct tpacket_req
, tp_frame_nr
) !=
58 offsetof(struct tpacket_req3
, tp_frame_nr
) &&
59 sizeof(struct tpacket_req
) !=
60 offsetof(struct tpacket_req3
, tp_retire_blk_tov
));
62 ring
->layout3
.tp_retire_blk_tov
= 0;
63 ring
->layout3
.tp_sizeof_priv
= 0;
64 ring
->layout3
.tp_feature_req_word
= 0;
66 set_sockopt_tpacket_v3(sock
);
68 set_sockopt_tpacket_v2(sock
);
71 ring_verify_layout(ring
);
74 void create_rx_ring(int sock
, struct ring
*ring
, int verbose
)
77 bool v3
= get_sockopt_tpacket(sock
) == TPACKET_V3
;
80 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_RX_RING
, &ring
->raw
,
81 v3
? sizeof(ring
->layout3
) : sizeof(ring
->layout
));
83 if (errno
== ENOMEM
&& ring
->layout
.tp_block_nr
> 1) {
84 ring
->layout
.tp_block_nr
>>= 1;
85 ring
->layout
.tp_frame_nr
= ring
->layout
.tp_block_size
/
86 ring
->layout
.tp_frame_size
*
87 ring
->layout
.tp_block_nr
;
91 panic("Cannot allocate RX_RING!\n");
93 ring
->mm_len
= ring
->layout
.tp_block_size
* ring
->layout
.tp_block_nr
;
96 printf("RX: %.2Lf MiB, %u Frames, each %u Byte allocated\n",
97 (long double) ring
->mm_len
/ (1 << 20),
98 ring
->layout
.tp_frame_nr
, ring
->layout
.tp_frame_size
);
102 void mmap_rx_ring(int sock
, struct ring
*ring
)
104 mmap_ring_generic(sock
, ring
);
107 void alloc_rx_ring_frames(struct ring
*ring
)
109 alloc_ring_frames_generic(ring
);
112 void bind_rx_ring(int sock
, struct ring
*ring
, int ifindex
)
114 bind_ring_generic(sock
, ring
, ifindex
);