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>
19 #include <linux/socket.h>
20 #include <linux/sockios.h>
21 #include <sys/ioctl.h>
31 # define PACKET_FANOUT 18
32 # define PACKET_FANOUT_POLICY_HASH 0
33 # define PACKET_FANOUT_POLICY_LB 1
34 # define PACKET_FANOUT_POLICY_DEFAULT PACKET_FANOUT_HASH
38 struct tpacket2_hdr tp_h __aligned_tpacket
;
39 struct sockaddr_ll s_ll
__align_tpacket(sizeof(struct tpacket2_hdr
));
43 struct iovec
*frames __cacheline_aligned
;
46 struct tpacket_req layout
;
47 struct sockaddr_ll s_ll
;
50 static inline void next_slot(unsigned int *it
, struct ring
*ring
)
53 atomic_cmp_swp(it
, ring
->layout
.tp_frame_nr
, 0);
56 static inline void next_rnd_slot(unsigned int *it
, struct ring
*ring
)
58 *it
= rand() % ring
->layout
.tp_frame_nr
;
61 #define RING_SIZE_FALLBACK (1 << 26)
63 static inline unsigned int ring_size(char *ifname
, unsigned int size
)
69 * Device bitrate in bytes times two as ring size.
70 * Fallback => ~ 64,00 MB
71 * 10 MBit => ~ 2,38 MB
72 * 54 MBit => ~ 12,88 MB
73 * 100 MBit => ~ 23,84 MB
74 * 300 MBit => ~ 71,52 MB
75 * 1.000 MBit => ~ 238,42 MB
76 * 10.000 MBit => ~ 2.384.18 MB
78 size
= device_bitrate(ifname
);
79 size
= (size
* 1000000) / 8;
82 size
= RING_SIZE_FALLBACK
;
84 return round_up_cacheline(size
);
92 static inline unsigned int ring_frame_size(struct ring
*ring
)
94 return ring
->layout
.tp_frame_size
;
97 static inline void tpacket_hdr_clone(struct tpacket2_hdr
*thdrd
,
98 struct tpacket2_hdr
*thdrs
)
100 thdrd
->tp_sec
= thdrs
->tp_sec
;
101 thdrd
->tp_nsec
= thdrs
->tp_nsec
;
102 thdrd
->tp_snaplen
= thdrs
->tp_snaplen
;
103 thdrd
->tp_len
= thdrs
->tp_len
;
107 # define POLLRDNORM 0x0040
110 # define POLLWRNORM 0x0100
113 # define POLLRDHUP 0x2000
116 #define POLL_NEXT_PKT 0
117 #define POLL_MOVE_OUT 1
119 static inline void prepare_polling(int sock
, struct pollfd
*pfd
)
121 memset(pfd
, 0, sizeof(*pfd
));
124 pfd
->events
= POLLIN
| POLLRDNORM
| POLLERR
;
127 static inline void set_sockopt_fanout(int sock
, unsigned int fanout_id
,
128 unsigned int fanout_type
)
130 unsigned int fanout_arg
= (fanout_id
| (fanout_type
<< 16));
131 int ret
= setsockopt(sock
, SOL_PACKET
, PACKET_FANOUT
, &fanout_arg
,
134 panic("No packet fanout support!\n");
137 static inline void set_sockopt_tpacket(int sock
)
139 int ret
, val
= TPACKET_V2
;
141 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_VERSION
, &val
, sizeof(val
));
143 panic("Cannot set tpacketv2!\n");
146 #if defined(__WITH_HARDWARE_TIMESTAMPING)
147 # include <linux/net_tstamp.h>
149 static inline void set_sockopt_hwtimestamp(int sock
, const char *dev
)
152 struct hwtstamp_config hwconfig
;
155 memset(&hwconfig
, 0, sizeof(hwconfig
));
156 hwconfig
.tx_type
= HWTSTAMP_TX_ON
;
157 hwconfig
.rx_filter
= HWTSTAMP_FILTER_ALL
;
159 memset(&ifr
, 0, sizeof(ifr
));
160 strlcpy(ifr
.ifr_name
, dev
, sizeof(ifr
.ifr_name
));
161 ifr
.ifr_data
= &hwconfig
;
163 ret
= ioctl(sock
, SIOCSHWTSTAMP
, &ifr
);
167 timesource
= SOF_TIMESTAMPING_RAW_HARDWARE
;
169 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_TIMESTAMP
, ×ource
,
172 panic("Cannot set timestamping!\n");
175 static inline void set_sockopt_hwtimestamp(int sock
, const char *dev
)
179 #endif /* defined(__WITH_HARDWARE_TIMESTAMPING) */