link: fixed to include <sys/types.h> for caddr_t
[netsniff-ng.git] / ring.h
blob55d5e963385576e5e9c09cb8b490d34b788a9322
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2009, 2010 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #ifndef RING_H
8 #define RING_H
11 * "I love the smell of 10GbE in the morning. Smells like ... victory."
12 * - W. Richard Stevens, "Secret Teachings of the UNIX Environment"
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <linux/if_packet.h>
18 #include <linux/socket.h>
19 #include <linux/sockios.h>
20 #include <sys/ioctl.h>
21 #include <string.h>
22 #include <poll.h>
23 #include <sys/poll.h>
25 #include "built_in.h"
26 #include "die.h"
27 #include "dev.h"
28 #include "config.h"
30 union tpacket_uhdr {
31 struct tpacket_hdr *h1;
32 struct tpacket2_hdr *h2;
33 #ifdef HAVE_TPACKET3
34 struct tpacket3_hdr *h3;
35 #endif
36 void *raw;
39 struct frame_map {
40 struct tpacket2_hdr tp_h __aligned_tpacket;
41 struct sockaddr_ll s_ll __align_tpacket(sizeof(struct tpacket2_hdr));
44 #ifdef HAVE_TPACKET3
45 struct block_desc {
46 uint32_t version;
47 uint32_t offset_to_priv;
48 struct tpacket_hdr_v1 h1;
50 #endif
52 struct ring {
53 struct iovec *frames;
54 uint8_t *mm_space;
55 size_t mm_len;
56 struct sockaddr_ll s_ll;
57 union {
58 struct tpacket_req layout;
59 #ifdef HAVE_TPACKET3
60 struct tpacket_req3 layout3;
61 #endif
62 uint8_t raw;
66 static inline void next_rnd_slot(unsigned int *it, struct ring *ring)
68 *it = rand() % ring->layout.tp_frame_nr;
71 static inline unsigned int ring_size(char *ifname, unsigned int size)
73 if (size > 0)
74 return size;
77 * Device bitrate in bytes times two as ring size.
78 * Fallback => ~ 64,00 MB
79 * 10 MBit => ~ 2,38 MB
80 * 54 MBit => ~ 12,88 MB
81 * 100 MBit => ~ 23,84 MB
82 * 300 MBit => ~ 71,52 MB
83 * 1.000 MBit => ~ 238,42 MB
84 * 10.000 MBit => ~ 2.384.18 MB
86 size = device_bitrate(ifname);
87 size = (size * 1000000) / 8;
88 size = size * 2;
89 if (size == 0)
90 size = 1 << 26;
92 return round_up_cacheline(size);
95 static inline unsigned int ring_frame_size(struct ring *ring)
97 return ring->layout.tp_frame_size;
100 static inline void ring_verify_layout(struct ring *ring)
102 bug_on(ring->layout.tp_block_size < ring->layout.tp_frame_size);
103 bug_on((ring->layout.tp_block_size % ring->layout.tp_frame_size) != 0);
104 bug_on((ring->layout.tp_block_size % getpagesize()) != 0);
107 static inline void tpacket_hdr_clone(struct tpacket2_hdr *thdrd,
108 struct tpacket2_hdr *thdrs)
110 thdrd->tp_sec = thdrs->tp_sec;
111 thdrd->tp_nsec = thdrs->tp_nsec;
112 thdrd->tp_snaplen = thdrs->tp_snaplen;
113 thdrd->tp_len = thdrs->tp_len;
116 static inline void prepare_polling(int sock, struct pollfd *pfd)
118 memset(pfd, 0, sizeof(*pfd));
119 pfd->fd = sock;
120 pfd->revents = 0;
121 pfd->events = POLLIN | POLLRDNORM | POLLERR;
124 static inline void __set_sockopt_tpacket(int sock, int val)
126 int ret = setsockopt(sock, SOL_PACKET, PACKET_VERSION, &val, sizeof(val));
127 if (ret)
128 panic("Cannot set tpacketv2!\n");
131 static inline void set_sockopt_tpacket_v2(int sock)
133 __set_sockopt_tpacket(sock, TPACKET_V2);
136 static inline void set_sockopt_tpacket_v3(int sock)
138 #ifdef HAVE_TPACKET3
139 __set_sockopt_tpacket(sock, TPACKET_V3);
140 #endif
143 static inline int get_sockopt_tpacket(int sock)
145 int val, ret;
146 socklen_t len = sizeof(val);
148 ret = getsockopt(sock, SOL_PACKET, PACKET_VERSION, &val, &len);
149 if (ret)
150 panic("Cannot get tpacket version!\n");
152 return val;
155 extern void mmap_ring_generic(int sock, struct ring *ring);
156 extern void alloc_ring_frames_generic(struct ring *ring, int num, size_t size);
157 extern void bind_ring_generic(int sock, struct ring *ring, int ifindex, bool tx_only);
159 #endif /* RING_H */