1 /* XXX: Coding Style - use the tool indent with the following (Linux kernel
4 * indent -nbad -bap -nbc -bbo -hnl -br -brs -c33 -cd33 -ncdb -ce -ci4 \
5 * -cli0 -d0 -di1 -nfc1 -i8 -ip0 -l80 -lp -npcs -nprs -npsl -sai \
6 * -saf -saw -ncs -nsc -sob -nfca -cp33 -ss -ts8 -il1
11 * High performance network sniffer for packet inspection
13 * Copyright (C) 2009, 2010 Daniel Borkmann <danborkmann@googlemail.com>
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or (at
18 * your option) any later version.
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
22 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
25 * You should have received a copy of the GNU General Public License along
26 * with this program; if not, write to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
29 * Note: Your kernel has to be compiled with CONFIG_PACKET_MMAP=y option in
35 * Mostly RX_RING related stuff and other networking code
47 #include <arpa/inet.h>
49 #include <sys/ioctl.h>
52 #include <linux/if_ether.h>
53 #include <linux/if_packet.h>
54 #include <linux/filter.h>
56 #include <netsniff-ng/macros.h>
57 #include <netsniff-ng/types.h>
58 #include <netsniff-ng/rx_ring.h>
61 * destroy_virt_ring - Destroys virtual RX_RING buffer
65 void destroy_virt_ring(int sock
, ring_buff_t
* rb
)
69 memset(&(rb
->layout
), 0, sizeof(rb
->layout
));
70 setsockopt(sock
, SOL_PACKET
, PACKET_RX_RING
, (void *)&(rb
->layout
),
83 * create_virt_ring - Creates virtual RX_RING buffer
87 void create_virt_ring(int sock
, ring_buff_t
* rb
)
93 memset(&(rb
->layout
), 0, sizeof(rb
->layout
));
95 /* max: getpagesize() << 11 for i386 */
96 rb
->layout
.tp_block_size
= getpagesize() << 2;
97 rb
->layout
.tp_frame_size
= TPACKET_ALIGNMENT
<< 7;
99 /* max: 15 for i386 */
100 rb
->layout
.tp_block_nr
= 1 << 13;
101 rb
->layout
.tp_frame_nr
=
102 rb
->layout
.tp_block_size
/ rb
->layout
.tp_frame_size
*
103 rb
->layout
.tp_block_nr
;
106 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_RX_RING
,
107 (void *)&(rb
->layout
), sizeof(rb
->layout
));
109 if (errno
== ENOMEM
&& rb
->layout
.tp_block_nr
> 1) {
110 rb
->layout
.tp_block_nr
>>= 1;
111 rb
->layout
.tp_frame_nr
=
112 rb
->layout
.tp_block_size
/ rb
->layout
.tp_frame_size
*
113 rb
->layout
.tp_block_nr
;
119 perr("setsockopt: creation of rx ring failed: %d - ", errno
);
125 rb
->len
= rb
->layout
.tp_block_size
* rb
->layout
.tp_block_nr
;
127 dbg("%.2f MB allocated for rx ring \n", 1.f
* rb
->len
/ (1024 * 1024));
128 dbg(" [ %d blocks, %d frames ] \n", rb
->layout
.tp_block_nr
,
129 rb
->layout
.tp_frame_nr
);
130 dbg(" [ %d frames per block ]\n",
131 rb
->layout
.tp_block_size
/ rb
->layout
.tp_frame_size
);
132 dbg(" [ framesize: %d bytes, blocksize: %d bytes ]\n\n",
133 rb
->layout
.tp_frame_size
, rb
->layout
.tp_block_size
);
137 * mmap_virt_ring - Memory maps virtual RX_RING kernel buffer into userspace
138 * in order to avoid syscalls for fetching packet buffers
142 void mmap_virt_ring(int sock
, ring_buff_t
* rb
)
146 rb
->buffer
= mmap(0, rb
->len
, PROT_READ
| PROT_WRITE
, MAP_SHARED
, sock
,
148 if (rb
->buffer
== MAP_FAILED
) {
149 perr("mmap: cannot mmap the rx ring: %d - ", errno
);
151 destroy_virt_ring(sock
, rb
);
159 * bind_dev_to_ring - Binds virtual RX_RING to network device
161 * @ifindex: device number
164 void bind_dev_to_ring(int sock
, int ifindex
, ring_buff_t
* rb
)
170 memset(&(rb
->params
), 0, sizeof(rb
->params
));
172 rb
->params
.sll_family
= AF_PACKET
;
173 rb
->params
.sll_protocol
= htons(ETH_P_ALL
);
174 rb
->params
.sll_ifindex
= ifindex
;
175 rb
->params
.sll_hatype
= 0;
176 rb
->params
.sll_halen
= 0;
177 rb
->params
.sll_pkttype
= 0;
179 ret
= bind(sock
, (struct sockaddr
*)&(rb
->params
),
180 sizeof(struct sockaddr_ll
));
182 perr("bind: cannot bind device: %d - ", errno
);
190 * put_dev_into_promisc_mode - Puts network device into promiscuous mode
192 * @ifindex: device number
194 void put_dev_into_promisc_mode(int sock
, int ifindex
)
197 struct packet_mreq mr
;
199 memset(&mr
, 0, sizeof(mr
));
201 mr
.mr_ifindex
= ifindex
;
202 mr
.mr_type
= PACKET_MR_PROMISC
;
204 /* This is better than ioctl(), because the kernel now manages the
205 promisc flag for itself via internal counters. If the socket will
206 be closed the kernel decrements the counters automatically which
207 will not work with ioctl(). There, you have to manage things
210 ret
= setsockopt(sock
, SOL_PACKET
, PACKET_ADD_MEMBERSHIP
,
213 perr("setsockopt: cannot set dev %d to promisc mode: %d - ",
222 * inject_kernel_bpf - Binds filter code to socket
224 * @bpf: Berkeley Packet Filter code
225 * @len: length of bpf
227 void inject_kernel_bpf(int sock
, struct sock_filter
*bpf
, int len
)
230 struct sock_fprog filter
;
234 memset(&filter
, 0, sizeof(filter
));
236 filter
.len
= len
/ sizeof(struct sock_filter
);
239 ret
= setsockopt(sock
, SOL_SOCKET
, SO_ATTACH_FILTER
,
240 &filter
, sizeof(filter
));
242 perr("setsockopt: filter cannot be injected: %d - ", errno
);
250 * ethdev_to_ifindex - Translates device name into device number
254 int ethdev_to_ifindex(int sock
, char *dev
)
259 memset(ðreq
, 0, sizeof(ethreq
));
260 strncpy(ethreq
.ifr_name
, dev
, IFNAMSIZ
);
262 ret
= ioctl(sock
, SIOCGIFINDEX
, ðreq
);
264 perr("ioctl: cannot determine dev number for %s: %d - ",
265 ethreq
.ifr_name
, errno
);
271 return (ethreq
.ifr_ifindex
);
275 * net_stat - Grabs and prints current socket statistics
278 void net_stat(int sock
)
281 struct tpacket_stats kstats
;
282 socklen_t slen
= sizeof(kstats
);
284 memset(&kstats
, 0, sizeof(kstats
));
286 ret
= getsockopt(sock
, SOL_PACKET
, PACKET_STATISTICS
, &kstats
, &slen
);
288 dbg("%d frames incoming\n", kstats
.tp_packets
);
289 dbg("%d frames passed filter\n",
290 kstats
.tp_packets
- kstats
.tp_drops
);
291 dbg("%d frames failed filter (due to out of space)\n",
297 * alloc_pf_sock - Allocates a raw PF_PACKET socket
299 int alloc_pf_sock(void)
301 int sock
= socket(PF_PACKET
, SOCK_RAW
, 0);
303 perr("alloc pf socket");
311 * parse_rules - Parses a BPF rulefile
312 * @rulefile: path to rulefile
316 void parse_rules(char *rulefile
, struct sock_filter
**bpf
, int *len
)
320 char buff
[128] = { 0 };
322 struct sock_filter sf_single
;
326 FILE *fp
= fopen(rulefile
, "r");
328 perr("cannot read rulefile - ");
332 dbg("parsing rulefile %s\n", rulefile
);
335 while (fgets(buff
, sizeof(buff
), fp
) != NULL
) {
336 buff
[sizeof(buff
) - 1] = 0;
337 memset(&sf_single
, 0, sizeof(sf_single
));
339 ret
= sscanf(buff
, "{ 0x%x, %d, %d, 0x%08x },",
340 (unsigned int *)((void *)&(sf_single
.code
)),
341 (int *)((void *)&(sf_single
.jt
)),
342 (int *)((void *)&(sf_single
.jf
)), &(sf_single
.k
));
344 /* No valid bpf opcode format, might be a comment or
350 *bpf
= (struct sock_filter
*)realloc(*bpf
,
351 *len
* sizeof(sf_single
));
353 memcpy(&(*bpf
)[*len
- 1], &sf_single
, sizeof(sf_single
));
355 dbg("line %d: { 0x%x, %d, %d, 0x%08x }\n", count
++,
356 (*bpf
)[*len
- 1].code
,
358 (*bpf
)[*len
- 1].jf
, (*bpf
)[*len
- 1].k
);