2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
11 * "I love the smell of 10GbE in the morning. Smells like ... victory."
12 * - W. Richard Stevens, "Secret Teachings of the UNIX Environment"
17 #include <linux/if_packet.h>
18 #include <linux/socket.h>
19 #include <linux/sockios.h>
20 #include <sys/ioctl.h>
30 struct tpacket_hdr
*h1
;
31 struct tpacket2_hdr
*h2
;
32 struct tpacket3_hdr
*h3
;
37 struct tpacket2_hdr tp_h __aligned_tpacket
;
38 struct sockaddr_ll s_ll
__align_tpacket(sizeof(struct tpacket2_hdr
));
43 uint32_t offset_to_priv
;
44 struct tpacket_hdr_v1 h1
;
51 struct sockaddr_ll s_ll
;
53 struct tpacket_req layout
;
54 struct tpacket_req3 layout3
;
59 static inline void next_rnd_slot(unsigned int *it
, struct ring
*ring
)
61 *it
= rand() % ring
->layout
.tp_frame_nr
;
64 static inline unsigned int ring_size(char *ifname
, unsigned int size
)
70 * Device bitrate in bytes times two as ring size.
71 * Fallback => ~ 64,00 MB
72 * 10 MBit => ~ 2,38 MB
73 * 54 MBit => ~ 12,88 MB
74 * 100 MBit => ~ 23,84 MB
75 * 300 MBit => ~ 71,52 MB
76 * 1.000 MBit => ~ 238,42 MB
77 * 10.000 MBit => ~ 2.384.18 MB
79 size
= device_bitrate(ifname
);
80 size
= (size
* 1000000) / 8;
85 return round_up_cacheline(size
);
88 static inline unsigned int ring_frame_size(struct ring
*ring
)
90 return ring
->layout
.tp_frame_size
;
93 static inline void ring_verify_layout(struct ring
*ring
)
95 bug_on(ring
->layout
.tp_block_size
< ring
->layout
.tp_frame_size
);
96 bug_on((ring
->layout
.tp_block_size
% ring
->layout
.tp_frame_size
) != 0);
97 bug_on((ring
->layout
.tp_block_size
% getpagesize()) != 0);
100 static inline void tpacket_hdr_clone(struct tpacket2_hdr
*thdrd
,
101 struct tpacket2_hdr
*thdrs
)
103 thdrd
->tp_sec
= thdrs
->tp_sec
;
104 thdrd
->tp_nsec
= thdrs
->tp_nsec
;
105 thdrd
->tp_snaplen
= thdrs
->tp_snaplen
;
106 thdrd
->tp_len
= thdrs
->tp_len
;
109 static inline void prepare_polling(int sock
, struct pollfd
*pfd
)
111 memset(pfd
, 0, sizeof(*pfd
));
114 pfd
->events
= POLLIN
| POLLRDNORM
| POLLERR
;
117 static inline void __set_sockopt_tpacket(int sock
, int val
)
119 int ret
= setsockopt(sock
, SOL_PACKET
, PACKET_VERSION
, &val
, sizeof(val
));
121 panic("Cannot set tpacketv2!\n");
124 static inline int __get_sockopt_tpacket(int sock
)
127 socklen_t len
= sizeof(val
);
129 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_VERSION
, &val
, &len
);
131 panic("Cannot get tpacket version!\n");
136 static inline void set_sockopt_tpacket_v2(int sock
)
138 __set_sockopt_tpacket(sock
, TPACKET_V2
);
141 static inline void set_sockopt_tpacket_v3(int sock
)
143 __set_sockopt_tpacket(sock
, TPACKET_V3
);
146 static inline int get_sockopt_tpacket(int sock
)
148 return __get_sockopt_tpacket(sock
);
151 extern void mmap_ring_generic(int sock
, struct ring
*ring
);
152 extern void alloc_ring_frames_generic(struct ring
*ring
, int num
, size_t size
);
153 extern void bind_ring_generic(int sock
, struct ring
*ring
, int ifindex
);