2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009, 2010 Daniel Borkmann.
5 * Subject to the GPL, version 2.
12 * "I love the smell of 10GbE in the morning. Smells like ... victory."
13 * - W. Richard Stevens, "Secret Teachings of the UNIX Environment"
18 #include <linux/if_packet.h>
29 # define PACKET_FANOUT 18
30 # define PACKET_FANOUT_POLICY_HASH 0
31 # define PACKET_FANOUT_POLICY_LB 1
32 # define PACKET_FANOUT_POLICY_DEFAULT PACKET_FANOUT_HASH
36 struct tpacket_hdr tp_h __aligned_tpacket
;
37 struct sockaddr_ll s_ll __aligned_tpacket
;
41 struct iovec
*frames __cacheline_aligned
;
42 uint8_t *mm_space __cacheline_aligned
;
44 struct tpacket_req layout
;
45 struct sockaddr_ll s_ll
;
48 static inline void next_slot(unsigned int *it
, struct ring
*ring
)
51 atomic_cmp_swp(it
, ring
->layout
.tp_frame_nr
, 0);
54 static inline void next_slot_prerd(unsigned int *it
, struct ring
*ring
)
57 atomic_cmp_swp(it
, ring
->layout
.tp_frame_nr
, 0);
58 prefetch_rd_hi(ring
->frames
[*it
].iov_base
);
61 static inline void next_slot_prewr(unsigned int *it
, struct ring
*ring
)
64 atomic_cmp_swp(it
, ring
->layout
.tp_frame_nr
, 0);
65 prefetch_wr_hi(ring
->frames
[*it
].iov_base
);
68 static inline void next_rnd_slot(unsigned int *it
, struct ring
*ring
)
70 *it
= mt_rand_int32() % ring
->layout
.tp_frame_nr
;
73 #define RING_SIZE_FALLBACK (1 << 26)
75 static inline unsigned int ring_size(char *ifname
, unsigned int size
)
81 * Device bitrate in bytes times two as ring size.
82 * Fallback => ~ 64,00 MB
83 * 10 MBit => ~ 2,38 MB
84 * 54 MBit => ~ 12,88 MB
85 * 100 MBit => ~ 23,84 MB
86 * 300 MBit => ~ 71,52 MB
87 * 1.000 MBit => ~ 238,42 MB
88 * 10.000 MBit => ~ 2.384.18 MB
90 size
= device_bitrate(ifname
);
91 size
= (size
* 1000000) / 8;
94 size
= RING_SIZE_FALLBACK
;
95 return round_up_cacheline(size
);
103 static inline unsigned int ring_frame_size(struct ring
*ring
)
105 return ring
->layout
.tp_frame_size
;
108 static inline void tpacket_hdr_clone(struct tpacket_hdr
*thdrd
,
109 struct tpacket_hdr
*thdrs
)
111 thdrd
->tp_sec
= thdrs
->tp_sec
;
112 thdrd
->tp_usec
= thdrs
->tp_usec
;
113 thdrd
->tp_snaplen
= thdrs
->tp_snaplen
;
114 thdrd
->tp_len
= thdrs
->tp_len
;
118 # define POLLRDNORM 0x0040
121 # define POLLWRNORM 0x0100
124 # define POLLRDHUP 0x2000
127 #define POLL_NEXT_PKT 0
128 #define POLL_MOVE_OUT 1
130 static inline void prepare_polling(int sock
, struct pollfd
*pfd
)
132 memset(pfd
, 0, sizeof(*pfd
));
135 pfd
->events
= POLLIN
| POLLRDNORM
| POLLERR
;
138 static inline void set_sockopt_fanout(int sock
, unsigned int fanout_id
,
139 unsigned int fanout_type
)
141 unsigned int fanout_arg
= (fanout_id
| (fanout_type
<< 16));
142 int ret
= setsockopt(sock
, SOL_PACKET
, PACKET_FANOUT
, &fanout_arg
,
145 panic("No packet fanout support!\n");