ring: built_in: fix if cacheline_aligned is not defined
[netsniff-ng.git] / src / netsniff-ng.c
blob275417e8d0f14bb215e2aa651aa67c05dac856f7
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2009-2011 Daniel Borkmann.
5 * Copyright 2010 Emmanuel Roullit.
6 * Subject to the GPL, version 2.
8 * The first sniffer that invoked both, the zero-copy RX_RING as well as
9 * the zero-copy TX_RING for high-performance network I/O and scatter/gather
10 * or mmaped PCAP I/O.
12 * "I knew that danger lay ahead, of course; but I did not expect to
13 * meet it in our own Shire. Can't a hobbit walk from the Water to the
14 * River in peace?" "But it is not your own Shire," said Gildor. "Others
15 * dwelt here before hobbits were; and others will dwell here again when
16 * hobbits are no more. The wide world is all about you: you can fence
17 * yourselves in, but you cannot for ever fence it out."
19 * -- The Lord of the Rings, Gildor to Frodo,
20 * Chapter 'Three is Company'.
25 =head1 NAME
27 netsniff-ng - the packet sniffing beast
29 =head1 SYNOPSIS
31 netsniff-ng -i|-d|--dev|--in <dev|pcap> -o|--out <dev|pcap|dir|txf>
32 [-f|--filter <bpf-file>][-t|--type <type>][-F|--interval <uint>]
33 [-s|--silent][-J|--jumbo-support][-n|--num <uint>][-r|--rand]
34 [-M|--no-promisc][-m|--mmap | -c|--clrw][-S|--ring-size <size>]
35 [-k|--kernel-pull <uint>][-b|--bind-cpu <cpu> | -B|--unbind-cpu <cpu>]
36 [-H|--prio-high][-Q|--notouch-irq][-q|--less | -l|--payload |
37 -x|--payload-hex | -C|--c-style | -X|--all-hex | -N|--no-payload]
38 [-v|--version][-h|--help]
40 =head1 DESCRIPTION
42 The first sniffer that invoked both, the zero-copy RX_RING as well as
43 the zero-copy TX_RING for high-performance network I/O and scatter/gather
44 or mmaped PCAP I/O.
46 =head1 EXAMPLES
48 =over
50 =item netsniff-ng --in eth0 --out dump.pcap
52 Capture traffic from interface 'eth0' and save it pcap file 'dump.pcap'
54 =item netsniff-ng --in any --filter http.bpf --payload
56 Capture HTTP traffic from any interface and print its payload on stdout
58 =item netsniff-ng --in wlan0 --bind-cpu 0,1
60 Capture all traffic from wlan0 interface.
61 Schedule process on CPU 0 and 1.
63 =back
65 =head1 OPTIONS
67 =over
69 =item -i|-d|--dev|--in <dev|pcap>
71 Input source. Can be a network device or pcap file.
73 =item -o|--out <dev|pcap|dir|txf>
75 Output sink. Can be a network device, pcap file, a trafgen txf file or a
76 directory. (There's only pcap to txf translation possible.)
78 =item -f|--filter <bpf-file>
80 Use BPF filter file from bpfc.
82 =item -t|--type <type>
84 =over
86 =item Only handle packets of defined type:
88 =over
90 =item - broadcast
92 =item - multicast
94 =item - others
96 =item - outgoing
98 =back
100 =back
102 =item -F|--interval <uint>
104 Dump interval in seconds. if -o is a directory, a new pcap will be created at each interval.
105 The older files are left untouched. (default value: 60 seconds)
107 =item -s|--silent
109 Do not print captured packets to stdout.
111 =item -J|--jumbo-support
113 Support for 64KB Super Jumbo Frames.
115 =item -n|--num <uint>
117 When zerp, capture/replay until SIGINT is received (default).
118 When non-zero, capture/replay the number of packets.
120 =item -r|--rand
122 Randomize packet forwarding order (replay mode only).
124 =item -M|--no-promisc
126 Do not place the interface in promiscuous mode.
128 =item -m|--mmap
130 Mmap pcap file i.e., for replaying. Default: scatter/gather I/O.
132 =item -c|--clrw
134 Instead of using scatter/gather I/O use slower read(2)/write(2) I/O.
136 =item -S|--ring-size <size>
138 Manually set ring size in KB/MB/GB, e.g. '10MB'.
140 =item -k|--kernel-pull <uint>
142 Kernel pull from user interval in microseconds. Default is 10us. (replay mode only).
144 =item -b|--bind-cpu <cpu>
146 Bind to specific CPU (or CPU-range).
148 =item -B|--unbind-cpu <cpu>
150 Forbid to use specific CPU (or CPU-range).
152 =item -H|--prio-high
154 Run the process in high-priority mode.
156 =item -Q|--notouch-irq
158 Do not touch IRQ CPU affinity of NIC.
160 =item -q|--less
162 Print less-verbose packet information.
164 =item -l|--payload
166 Only print human-readable payload.
168 =item -x|--payload-hex
170 Only print payload in hex format.
172 =item -N|--payload-none
174 Only print packet header.
176 =item -X|--all-hex
178 Print packets in hex format.
180 =item -v|--version
182 Print version.
184 =item -h|--help
186 Print help text and lists all options.
188 =back
190 =head1 AUTHOR
192 Written by Daniel Borkmann <daniel@netsniff-ng.org> and Emmanuel Roullit <emmanuel@netsniff-ng.org>
194 =head1 DOCUMENTATION
196 Documentation by Emmanuel Roullit <emmanuel@netsniff-ng.org>
198 =head1 BUGS
200 Please report bugs to <bugs@netsniff-ng.org>
202 =cut
206 #define _GNU_SOURCE
207 #include <stdio.h>
208 #include <stdlib.h>
209 #include <signal.h>
210 #include <getopt.h>
211 #include <ctype.h>
212 #include <time.h>
213 #include <string.h>
214 #include <sys/socket.h>
215 #include <sys/types.h>
216 #include <sys/stat.h>
217 #include <sys/time.h>
218 #include <unistd.h>
219 #include <stdbool.h>
220 #include <pthread.h>
221 #include <fcntl.h>
223 #include "ring_rx.h"
224 #include "ring_tx.h"
225 #include "xsys.h"
226 #include "built_in.h"
227 #include "pcap.h"
228 #include "bpf.h"
229 #include "xio.h"
230 #include "xstring.h"
231 #include "die.h"
232 #include "opt_memcpy.h"
233 #include "tprintf.h"
234 #include "dissector.h"
235 #include "xmalloc.h"
236 #include "mtrand.h"
238 #define CPU_UNKNOWN -1
239 #define CPU_NOTOUCH -2
240 #define PACKET_ALL -1
241 #define DUMP_INTERVAL 60
243 struct mode {
244 char *device_in;
245 char *device_out;
246 char *filter;
247 int cpu;
248 int dump;
249 int link_type;
250 int print_mode;
251 unsigned int reserve_size;
252 int packet_type;
253 bool randomize;
254 bool promiscuous;
255 enum pcap_ops_groups pcap;
256 unsigned long kpull;
257 int jumbo_support;
258 int dump_dir;
259 unsigned long dump_interval;
262 struct tx_stats {
263 unsigned long tx_bytes;
264 unsigned long tx_packets;
267 volatile sig_atomic_t sigint = 0;
269 static int tx_sock;
270 static unsigned long frame_cnt_max = 0;
271 static unsigned long interval = TX_KERNEL_PULL_INT;
272 static struct itimerval itimer;
273 static volatile bool next_dump = false;
275 static const char *short_options = "d:i:o:rf:MJt:S:k:n:b:B:HQmcsqlxXNvhF:";
277 static struct option long_options[] = {
278 {"dev", required_argument, 0, 'd'},
279 {"in", required_argument, 0, 'i'},
280 {"out", required_argument, 0, 'o'},
281 {"rand", no_argument, 0, 'r'},
282 {"mmap", no_argument, 0, 'm'},
283 {"clrw", no_argument, 0, 'c'},
284 {"jumbo-support", no_argument, 0, 'J'},
285 {"filter", required_argument, 0, 'f'},
286 {"no-promisc", no_argument, 0, 'M'},
287 {"num", required_argument, 0, 'n'},
288 {"type", required_argument, 0, 't'},
289 {"interval", required_argument, 0, 'F'},
290 {"ring-size", required_argument, 0, 'S'},
291 {"kernel-pull", required_argument, 0, 'k'},
292 {"bind-cpu", required_argument, 0, 'b'},
293 {"unbind-cpu", required_argument, 0, 'B'},
294 {"prio-high", no_argument, 0, 'H'},
295 {"notouch-irq", no_argument, 0, 'Q'},
296 {"silent", no_argument, 0, 's'},
297 {"less", no_argument, 0, 'q'},
298 {"payload", no_argument, 0, 'l'},
299 {"payload-hex", no_argument, 0, 'x'},
300 {"payload-none", no_argument, 0, 'N'},
301 {"all-hex", no_argument, 0, 'X'},
302 {"version", no_argument, 0, 'v'},
303 {"help", no_argument, 0, 'h'},
304 {0, 0, 0, 0}
307 static void signal_handler(int number)
309 switch (number) {
310 case SIGINT:
311 sigint = 1;
312 break;
313 case SIGHUP:
314 break;
315 default:
316 break;
320 static void timer_elapsed(int number)
322 itimer.it_interval.tv_sec = 0;
323 itimer.it_interval.tv_usec = interval;
324 itimer.it_value.tv_sec = 0;
325 itimer.it_value.tv_usec = interval;
327 pull_and_flush_tx_ring(tx_sock);
328 setitimer(ITIMER_REAL, &itimer, NULL);
331 static void timer_next_dump(int number)
333 itimer.it_interval.tv_sec = interval;
334 itimer.it_interval.tv_usec = 0;
335 itimer.it_value.tv_sec = interval;
336 itimer.it_value.tv_usec = 0;
338 next_dump = true;
339 setitimer(ITIMER_REAL, &itimer, NULL);
342 static void enter_mode_pcap_to_tx(struct mode *mode)
344 int irq, ifindex, fd = 0, ret;
345 unsigned int size, it = 0;
346 struct ring tx_ring;
347 struct frame_map *hdr;
348 struct sock_fprog bpf_ops;
349 struct tx_stats stats;
350 uint8_t *out = NULL;
352 if (!device_up_and_running(mode->device_out))
353 panic("Device not up and running!\n");
355 set_memcpy();
356 tx_sock = pf_socket();
358 if (!pcap_ops[mode->pcap])
359 panic("pcap group not supported!\n");
360 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
361 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
362 if (ret)
363 panic("error reading pcap header!\n");
364 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
365 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
366 if (ret)
367 panic("error prepare reading pcap!\n");
370 memset(&tx_ring, 0, sizeof(tx_ring));
371 memset(&bpf_ops, 0, sizeof(bpf_ops));
372 memset(&stats, 0, sizeof(stats));
374 ifindex = device_ifindex(mode->device_out);
375 size = ring_size(mode->device_out, mode->reserve_size);
377 bpf_parse_rules(mode->filter, &bpf_ops);
379 set_packet_loss_discard(tx_sock);
380 setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
381 create_tx_ring(tx_sock, &tx_ring);
382 mmap_tx_ring(tx_sock, &tx_ring);
383 alloc_tx_ring_frames(&tx_ring);
384 bind_tx_ring(tx_sock, &tx_ring, ifindex);
386 dissector_init_all(mode->print_mode);
388 if (mode->cpu >= 0 && ifindex > 0) {
389 irq = device_irq_number(mode->device_out);
390 device_bind_irq_to_cpu(mode->cpu, irq);
391 printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq,
392 mode->cpu);
395 if (mode->kpull)
396 interval = mode->kpull;
398 itimer.it_interval.tv_sec = 0;
399 itimer.it_interval.tv_usec = interval;
400 itimer.it_value.tv_sec = 0;
401 itimer.it_value.tv_usec = interval;
402 setitimer(ITIMER_REAL, &itimer, NULL);
404 printf("BPF:\n");
405 bpf_dump_all(&bpf_ops);
406 printf("MD: TX %luus %s\n\n", interval, pcap_ops[mode->pcap]->name);
408 while (likely(sigint == 0)) {
409 while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
410 struct pcap_pkthdr phdr;
411 hdr = tx_ring.frames[it].iov_base;
412 /* Kernel assumes: data = ph.raw + po->tp_hdrlen -
413 * sizeof(struct sockaddr_ll); */
414 out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
415 sizeof(struct sockaddr_ll);
417 do {
418 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
419 out, ring_frame_size(&tx_ring));
420 if (unlikely(ret <= 0))
421 goto out;
422 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
423 pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);
425 stats.tx_bytes += hdr->tp_h.tp_len;;
426 stats.tx_packets++;
428 show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
429 dissector_entry_point(out, hdr->tp_h.tp_snaplen,
430 mode->link_type);
432 kernel_may_pull_from_tx(&hdr->tp_h);
433 next_slot(&it, &tx_ring);
435 if (unlikely(sigint == 1))
436 break;
437 if (frame_cnt_max != 0 &&
438 stats.tx_packets >= frame_cnt_max) {
439 sigint = 1;
440 break;
444 out:
445 fflush(stdout);
446 printf("\n");
447 printf("\r%12lu frames outgoing\n", stats.tx_packets);
448 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
450 dissector_cleanup_all();
451 destroy_tx_ring(tx_sock, &tx_ring);
453 close(tx_sock);
454 if (pcap_ops[mode->pcap]->prepare_close_pcap)
455 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
456 close(fd);
459 static void enter_mode_rx_to_tx(struct mode *mode)
461 int rx_sock, ifindex_in, ifindex_out;
462 unsigned int size_in, size_out, it_in = 0, it_out = 0;
463 unsigned long fcnt = 0;
464 uint8_t *in, *out;
465 short ifflags = 0;
466 struct frame_map *hdr_in, *hdr_out;
467 struct ring tx_ring;
468 struct ring rx_ring;
469 struct pollfd rx_poll;
470 struct sock_fprog bpf_ops;
472 if (!strncmp(mode->device_in, mode->device_out,
473 strlen(mode->device_in)))
474 panic("Ingress/egress devices must be different!\n");
475 if (!device_up_and_running(mode->device_out))
476 panic("Egress device not up and running!\n");
477 if (!device_up_and_running(mode->device_in))
478 panic("Ingress device not up and running!\n");
480 set_memcpy();
481 rx_sock = pf_socket();
482 tx_sock = pf_socket();
484 memset(&tx_ring, 0, sizeof(tx_ring));
485 memset(&rx_ring, 0, sizeof(rx_ring));
486 memset(&rx_poll, 0, sizeof(rx_poll));
487 memset(&bpf_ops, 0, sizeof(bpf_ops));
489 ifindex_in = device_ifindex(mode->device_in);
490 size_in = ring_size(mode->device_in, mode->reserve_size);
492 ifindex_out = device_ifindex(mode->device_out);
493 size_out = ring_size(mode->device_out, mode->reserve_size);
495 enable_kernel_bpf_jit_compiler();
496 bpf_parse_rules(mode->filter, &bpf_ops);
497 bpf_attach_to_sock(rx_sock, &bpf_ops);
499 setup_rx_ring_layout(rx_sock, &rx_ring, size_in, mode->jumbo_support);
500 create_rx_ring(rx_sock, &rx_ring);
501 mmap_rx_ring(rx_sock, &rx_ring);
502 alloc_rx_ring_frames(&rx_ring);
503 bind_rx_ring(rx_sock, &rx_ring, ifindex_in);
504 prepare_polling(rx_sock, &rx_poll);
506 set_packet_loss_discard(tx_sock);
507 setup_tx_ring_layout(tx_sock, &tx_ring, size_out, mode->jumbo_support);
508 create_tx_ring(tx_sock, &tx_ring);
509 mmap_tx_ring(tx_sock, &tx_ring);
510 alloc_tx_ring_frames(&tx_ring);
511 bind_tx_ring(tx_sock, &tx_ring, ifindex_out);
513 mt_init_by_seed_time();
514 dissector_init_all(mode->print_mode);
516 if (mode->promiscuous == true) {
517 ifflags = enter_promiscuous_mode(mode->device_in);
518 printf("PROMISC\n");
521 if (mode->kpull)
522 interval = mode->kpull;
524 itimer.it_interval.tv_sec = 0;
525 itimer.it_interval.tv_usec = interval;
526 itimer.it_value.tv_sec = 0;
527 itimer.it_value.tv_usec = interval;
528 setitimer(ITIMER_REAL, &itimer, NULL);
530 printf("BPF:\n");
531 bpf_dump_all(&bpf_ops);
532 printf("MD: RXTX %luus\n\n", interval);
533 printf("Running! Hang up with ^C!\n\n");
535 while (likely(sigint == 0)) {
536 while (user_may_pull_from_rx(rx_ring.frames[it_in].iov_base)) {
537 hdr_in = rx_ring.frames[it_in].iov_base;
538 in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;
539 fcnt++;
540 if (mode->packet_type != PACKET_ALL)
541 if (mode->packet_type != hdr_in->s_ll.sll_pkttype)
542 goto next;
544 hdr_out = tx_ring.frames[it_out].iov_base;
545 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
546 sizeof(struct sockaddr_ll);
548 for (; !user_may_pull_from_tx(tx_ring.frames[it_out].iov_base) &&
549 likely(!sigint);) {
550 if (mode->randomize)
551 next_rnd_slot(&it_out, &tx_ring);
552 else
553 next_slot(&it_out, &tx_ring);
554 hdr_out = tx_ring.frames[it_out].iov_base;
555 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
556 sizeof(struct sockaddr_ll);
559 tpacket_hdr_clone(&hdr_out->tp_h, &hdr_in->tp_h);
560 __memcpy(out, in, hdr_in->tp_h.tp_len);
562 kernel_may_pull_from_tx(&hdr_out->tp_h);
563 if (mode->randomize)
564 next_rnd_slot(&it_out, &tx_ring);
565 else
566 next_slot(&it_out, &tx_ring);
568 show_frame_hdr(hdr_in, mode->print_mode, RING_MODE_INGRESS);
569 dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
570 mode->link_type);
572 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
573 sigint = 1;
574 break;
576 next:
577 kernel_may_pull_from_rx(&hdr_in->tp_h);
578 next_slot(&it_in, &rx_ring);
580 if (unlikely(sigint == 1))
581 goto out;
584 poll(&rx_poll, 1, -1);
585 poll_error_maybe_die(rx_sock, &rx_poll);
587 out:
588 sock_print_net_stats(rx_sock);
590 dissector_cleanup_all();
591 destroy_tx_ring(tx_sock, &tx_ring);
592 destroy_rx_ring(rx_sock, &rx_ring);
594 if (mode->promiscuous == true)
595 leave_promiscuous_mode(mode->device_in, ifflags);
597 close(tx_sock);
598 close(rx_sock);
601 static void enter_mode_read_pcap(struct mode *mode)
603 int ret, fd, fdo = 0;
604 struct pcap_pkthdr phdr;
605 struct sock_fprog bpf_ops;
606 struct tx_stats stats;
607 struct frame_map fm;
608 uint8_t *out;
609 size_t out_len;
611 if (!pcap_ops[mode->pcap])
612 panic("pcap group not supported!\n");
613 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
614 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
615 if (ret)
616 panic("error reading pcap header!\n");
617 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
618 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
619 if (ret)
620 panic("error prepare reading pcap!\n");
623 memset(&fm, 0, sizeof(fm));
624 memset(&bpf_ops, 0, sizeof(bpf_ops));
625 memset(&stats, 0, sizeof(stats));
627 bpf_parse_rules(mode->filter, &bpf_ops);
628 dissector_init_all(mode->print_mode);
630 out_len = device_mtu("lo");
631 out = xmalloc_aligned(out_len, 64);
633 printf("BPF:\n");
634 bpf_dump_all(&bpf_ops);
635 printf("MD: RD %s\n\n", pcap_ops[mode->pcap]->name);
637 if (mode->device_out) {
638 fdo = open_or_die_m(mode->device_out, O_RDWR | O_CREAT |
639 O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR);
642 while (likely(sigint == 0)) {
643 do {
644 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
645 out, out_len);
646 if (unlikely(ret <= 0))
647 goto out;
648 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
649 pcap_pkthdr_to_tpacket_hdr(&phdr, &fm.tp_h);
651 stats.tx_bytes += fm.tp_h.tp_len;
652 stats.tx_packets++;
654 show_frame_hdr(&fm, mode->print_mode, RING_MODE_EGRESS);
655 dissector_entry_point(out, fm.tp_h.tp_snaplen,
656 mode->link_type);
658 if (mode->device_out) {
659 int i = 0;
660 char bout[80];
661 slprintf(bout, sizeof(bout), "$P%u {\n ", stats.tx_packets);
662 write_or_die(fdo, bout, strlen(bout));
664 while (i < fm.tp_h.tp_snaplen) {
665 slprintf(bout, sizeof(bout), "0x%02x, ", out[i]);
666 write_or_die(fdo, bout, strlen(bout));
667 i++;
668 if (i % 10 == 0) {
669 slprintf(bout, sizeof(bout), "\n", out[i]);
670 write_or_die(fdo, bout, strlen(bout));
671 if (i < fm.tp_h.tp_snaplen) {
672 slprintf(bout, sizeof(bout), " ", out[i]);
673 write_or_die(fdo, bout, strlen(bout));
677 if (i % 10 != 0) {
678 slprintf(bout, sizeof(bout), "\n");
679 write_or_die(fdo, bout, strlen(bout));
681 slprintf(bout, sizeof(bout), "}\n\n");
682 write_or_die(fdo, bout, strlen(bout));
685 if (frame_cnt_max != 0 &&
686 stats.tx_packets >= frame_cnt_max) {
687 sigint = 1;
688 break;
691 out:
692 fflush(stdout);
693 printf("\n");
694 printf("\r%12lu frames outgoing\n", stats.tx_packets);
695 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
697 xfree(out);
698 dissector_cleanup_all();
699 if (pcap_ops[mode->pcap]->prepare_close_pcap)
700 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
701 close(fd);
703 if (mode->device_out)
704 close(fdo);
707 static void finish_multi_pcap_file(struct mode *mode, int fd)
709 pcap_ops[mode->pcap]->fsync_pcap(fd);
710 if (pcap_ops[mode->pcap]->prepare_close_pcap)
711 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
712 close(fd);
714 memset(&itimer, 0, sizeof(itimer));
715 setitimer(ITIMER_REAL, &itimer, NULL);
718 static int next_multi_pcap_file(struct mode *mode, int fd)
720 int ret;
721 char tmp[512];
723 pcap_ops[mode->pcap]->fsync_pcap(fd);
724 if (pcap_ops[mode->pcap]->prepare_close_pcap)
725 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
726 close(fd);
728 memset(&tmp, 0, sizeof(tmp));
729 snprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
730 tmp[sizeof(tmp) - 1] = 0;
732 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
733 S_IRUSR | S_IWUSR);
734 ret = pcap_ops[mode->pcap]->push_file_header(fd);
735 if (ret)
736 panic("error writing pcap header!\n");
737 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
738 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
739 if (ret)
740 panic("error prepare writing pcap!\n");
743 return fd;
746 static int begin_multi_pcap_file(struct mode *mode)
748 int fd, ret;
749 char tmp[512];
751 if (!pcap_ops[mode->pcap])
752 panic("pcap group not supported!\n");
753 if (mode->device_out[strlen(mode->device_out) - 1] == '/')
754 mode->device_out[strlen(mode->device_out) - 1] = 0;
756 memset(&tmp, 0, sizeof(tmp));
757 snprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
758 tmp[sizeof(tmp) - 1] = 0;
760 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
761 S_IRUSR | S_IWUSR);
762 ret = pcap_ops[mode->pcap]->push_file_header(fd);
763 if (ret)
764 panic("error writing pcap header!\n");
765 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
766 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
767 if (ret)
768 panic("error prepare writing pcap!\n");
771 interval = mode->dump_interval;
772 itimer.it_interval.tv_sec = interval;
773 itimer.it_interval.tv_usec = 0;
774 itimer.it_value.tv_sec = interval;
775 itimer.it_value.tv_usec = 0;
776 setitimer(ITIMER_REAL, &itimer, NULL);
778 return fd;
781 static void finish_single_pcap_file(struct mode *mode, int fd)
783 pcap_ops[mode->pcap]->fsync_pcap(fd);
784 if (pcap_ops[mode->pcap]->prepare_close_pcap)
785 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
786 close(fd);
789 static int begin_single_pcap_file(struct mode *mode)
791 int fd, ret;
793 if (!pcap_ops[mode->pcap])
794 panic("pcap group not supported!\n");
795 fd = open_or_die_m(mode->device_out,
796 O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
797 S_IRUSR | S_IWUSR);
798 ret = pcap_ops[mode->pcap]->push_file_header(fd);
799 if (ret)
800 panic("error writing pcap header!\n");
801 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
802 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
803 if (ret)
804 panic("error prepare writing pcap!\n");
807 return fd;
810 static void enter_mode_rx_only_or_dump(struct mode *mode)
812 int sock, irq, ifindex, fd = 0, ret;
813 unsigned int size, it = 0;
814 unsigned long fcnt = 0;
815 short ifflags = 0;
816 uint8_t *packet;
817 struct ring rx_ring;
818 struct pollfd rx_poll;
819 struct frame_map *hdr;
820 struct sock_fprog bpf_ops;
822 if (!device_up_and_running(mode->device_in))
823 panic("Device not up and running!\n");
825 set_memcpy();
826 sock = pf_socket();
828 if (mode->dump) {
829 struct stat tmp;
830 memset(&tmp, 0, sizeof(tmp));
831 ret = stat(mode->device_out, &tmp);
832 if (ret < 0) {
833 mode->dump_dir = 0;
834 goto try_file;
836 mode->dump_dir = !!S_ISDIR(tmp.st_mode);
837 if (mode->dump_dir) {
838 fd = begin_multi_pcap_file(mode);
839 } else {
840 try_file:
841 fd = begin_single_pcap_file(mode);
845 memset(&rx_ring, 0, sizeof(rx_ring));
846 memset(&rx_poll, 0, sizeof(rx_poll));
847 memset(&bpf_ops, 0, sizeof(bpf_ops));
849 ifindex = device_ifindex(mode->device_in);
850 size = ring_size(mode->device_in, mode->reserve_size);
852 enable_kernel_bpf_jit_compiler();
853 bpf_parse_rules(mode->filter, &bpf_ops);
854 bpf_attach_to_sock(sock, &bpf_ops);
856 setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
857 create_rx_ring(sock, &rx_ring);
858 mmap_rx_ring(sock, &rx_ring);
859 alloc_rx_ring_frames(&rx_ring);
860 bind_rx_ring(sock, &rx_ring, ifindex);
862 prepare_polling(sock, &rx_poll);
863 dissector_init_all(mode->print_mode);
865 if (mode->cpu >= 0 && ifindex > 0) {
866 irq = device_irq_number(mode->device_in);
867 device_bind_irq_to_cpu(mode->cpu, irq);
868 printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq,
869 mode->cpu);
872 if (mode->promiscuous == true) {
873 ifflags = enter_promiscuous_mode(mode->device_in);
874 printf("PROMISC\n");
877 printf("BPF:\n");
878 bpf_dump_all(&bpf_ops);
879 printf("MD: RX %s\n\n", mode->dump ? pcap_ops[mode->pcap]->name : "");
881 while (likely(sigint == 0)) {
882 while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
883 hdr = rx_ring.frames[it].iov_base;
884 packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
885 fcnt++;
887 if (mode->packet_type != PACKET_ALL)
888 if (mode->packet_type != hdr->s_ll.sll_pkttype)
889 goto next;
890 if (unlikely(rx_ring.layout.tp_frame_size <
891 hdr->tp_h.tp_snaplen)) {
892 fprintf(stderr, "Skipping too large packet! "
893 "No jumbo support selected?\n");
894 fflush(stderr);
895 goto next;
897 if (mode->dump) {
898 struct pcap_pkthdr phdr;
899 tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
900 ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
901 packet, phdr.len);
902 if (unlikely(ret != sizeof(phdr) + phdr.len))
903 panic("Write error to pcap!\n");
906 show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
907 dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
908 mode->link_type);
910 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
911 sigint = 1;
912 break;
914 next:
915 kernel_may_pull_from_rx(&hdr->tp_h);
916 next_slot(&it, &rx_ring);
918 if (unlikely(sigint == 1))
919 break;
920 if (mode->dump && next_dump) {
921 struct tpacket_stats kstats;
922 socklen_t slen = sizeof(kstats);
923 memset(&kstats, 0, sizeof(kstats));
924 getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
925 &kstats, &slen);
926 fd = next_multi_pcap_file(mode, fd);
927 next_dump = false;
928 if (mode->print_mode == FNTTYPE_PRINT_NONE) {
929 printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
930 kstats.tp_drops);
931 fflush(stdout);
936 poll(&rx_poll, 1, -1);
937 poll_error_maybe_die(sock, &rx_poll);
940 if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE))
941 sock_print_net_stats(sock);
942 else {
943 printf("\n\n");
944 fflush(stdout);
946 dissector_cleanup_all();
947 destroy_rx_ring(sock, &rx_ring);
948 if (mode->promiscuous == true)
949 leave_promiscuous_mode(mode->device_in, ifflags);
950 close(sock);
951 if (mode->dump) {
952 if (mode->dump_dir)
953 finish_multi_pcap_file(mode, fd);
954 else
955 finish_single_pcap_file(mode, fd);
959 static void help(void)
961 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
962 VERSION_STRING);
963 printf("http://www.netsniff-ng.org\n\n");
964 printf("Usage: netsniff-ng [options]\n");
965 printf("Options:\n");
966 printf(" -i|-d|--dev|--in <dev|pcap> Input source as netdev or pcap\n");
967 printf(" -o|--out <dev|pcap|dir|txf> Output sink as netdev, pcap, directory, txf file\n");
968 printf(" -f|--filter <bpf-file> Use BPF filter file from bpfc\n");
969 printf(" -t|--type <type> Only handle packets of defined type:\n");
970 printf(" host|broadcast|multicast|others|outgoing\n");
971 printf(" -F|--interval <uint> Dump interval in sec if -o is a directory where\n");
972 printf(" pcap files should be stored (default: 60)\n");
973 printf(" -s|--silent Do not print captured packets\n");
974 printf(" -J|--jumbo-support Support for 64KB Super Jumbo Frames\n");
975 printf(" Default RX/TX slot: 2048Byte\n");
976 printf(" -n|--num <uint> Number of packets until exit\n");
977 printf(" `-- 0 Loop until interrupt (default)\n");
978 printf(" `- n Send n packets and done\n");
979 printf(" -r|--rand Randomize packet forwarding order\n");
980 printf(" -M|--no-promisc No promiscuous mode for netdev\n");
981 printf(" -m|--mmap Mmap pcap file i.e., for replaying\n");
982 printf(" Default: scatter/gather I/O\n");
983 printf(" -c|--clrw Instead s/g I/O use slower read(2)/write(2) I/O\n");
984 printf(" -S|--ring-size <size> Manually set ring size to <size>:\n");
985 printf(" mmap space in KB/MB/GB, e.g. \'10MB\'\n");
986 printf(" -k|--kernel-pull <uint> Kernel pull from user interval in us\n");
987 printf(" Default is 10us where the TX_RING\n");
988 printf(" is populated with payload from uspace\n");
989 printf(" -b|--bind-cpu <cpu> Bind to specific CPU (or CPU-range)\n");
990 printf(" -B|--unbind-cpu <cpu> Forbid to use specific CPU (or CPU-range)\n");
991 printf(" -H|--prio-high Make this high priority process\n");
992 printf(" -Q|--notouch-irq Do not touch IRQ CPU affinity of NIC\n");
993 printf(" -q|--less Print less-verbose packet information\n");
994 printf(" -l|--payload Only print human-readable payload\n");
995 printf(" -x|--payload-hex Only print payload in hex format\n");
996 printf(" -N|--payload-none Only print packet header\n");
997 printf(" -X|--all-hex Print packets in hex format\n");
998 printf(" -v|--version Show version\n");
999 printf(" -h|--help Guess what?!\n");
1000 printf("\n");
1001 printf("Examples:\n");
1002 printf(" netsniff-ng --in eth0 --out dump.pcap --silent --bind-cpu 0\n");
1003 printf(" netsniff-ng --in dump.pcap --mmap --out eth0 --silent --bind-cpu 0\n");
1004 printf(" netsniff-ng --in dump.pcap --out dump.txf --silent --bind-cpu 0\n");
1005 printf(" netsniff-ng --in any --filter icmp.bpf --all-hex\n");
1006 printf(" netsniff-ng --in eth0 --out eth1 --silent --bind-cpu 0 --type host\n");
1007 printf(" netsniff-ng --in wlan0 --out /opt/probe1/ --silent --interval 30 --bind-cpu 0\n");
1008 printf("\n");
1009 printf("Note:\n");
1010 printf(" This tool is targeted for network developers! You should\n");
1011 printf(" be aware of what you are doing and what these options above\n");
1012 printf(" mean! Use netsniff-ng's bpfc compiler for generating filter files.\n");
1013 printf(" Further, netsniff-ng automatically enables the kernel BPF JIT\n");
1014 printf(" if present. Txf file output is only possible if the input source\n");
1015 printf(" is a pcap file.\n");
1016 printf("\n");
1017 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
1018 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
1019 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
1020 printf("License: GNU GPL version 2\n");
1021 printf("This is free software: you are free to change and redistribute it.\n");
1022 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
1023 die();
1026 static void version(void)
1028 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
1029 VERSION_STRING);
1030 printf("http://www.netsniff-ng.org\n\n");
1031 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
1032 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
1033 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
1034 printf("License: GNU GPL version 2\n");
1035 printf("This is free software: you are free to change and redistribute it.\n");
1036 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
1037 die();
1040 static void header(void)
1042 printf("%s%s%s\n", colorize_start(bold), PROGNAME_STRING " "
1043 VERSION_STRING, colorize_end());
1046 int main(int argc, char **argv)
1048 int c, i, j, opt_index;
1049 char *ptr;
1050 bool prio_high = false;
1051 struct mode mode;
1052 void (*enter_mode)(struct mode *mode) = NULL;
1054 check_for_root_maybe_die();
1056 memset(&mode, 0, sizeof(mode));
1057 mode.link_type = LINKTYPE_EN10MB;
1058 mode.print_mode = FNTTYPE_PRINT_NORM;
1059 mode.cpu = CPU_UNKNOWN;
1060 mode.packet_type = PACKET_ALL;
1061 mode.promiscuous = true;
1062 mode.randomize = false;
1063 mode.pcap = PCAP_OPS_SG;
1064 mode.dump_interval = DUMP_INTERVAL;
1066 while ((c = getopt_long(argc, argv, short_options, long_options,
1067 &opt_index)) != EOF) {
1068 switch (c) {
1069 case 'd':
1070 case 'i':
1071 mode.device_in = xstrdup(optarg);
1072 break;
1073 case 'o':
1074 mode.device_out = xstrdup(optarg);
1075 break;
1076 case 'r':
1077 mode.randomize = true;
1078 break;
1079 case 'J':
1080 mode.jumbo_support = 1;
1081 break;
1082 case 'f':
1083 mode.filter = xstrdup(optarg);
1084 break;
1085 case 'M':
1086 mode.promiscuous = false;
1087 break;
1088 case 't':
1089 if (!strncmp(optarg, "host", strlen("host")))
1090 mode.packet_type = PACKET_HOST;
1091 else if (!strncmp(optarg, "broadcast", strlen("broadcast")))
1092 mode.packet_type = PACKET_BROADCAST;
1093 else if (!strncmp(optarg, "multicast", strlen("multicast")))
1094 mode.packet_type = PACKET_MULTICAST;
1095 else if (!strncmp(optarg, "others", strlen("others")))
1096 mode.packet_type = PACKET_OTHERHOST;
1097 else if (!strncmp(optarg, "outgoing", strlen("outgoing")))
1098 mode.packet_type = PACKET_OUTGOING;
1099 else
1100 mode.packet_type = PACKET_ALL;
1101 break;
1102 case 'S':
1103 ptr = optarg;
1104 mode.reserve_size = 0;
1106 for (j = i = strlen(optarg); i > 0; --i) {
1107 if (!isdigit(optarg[j - i]))
1108 break;
1109 ptr++;
1112 if (!strncmp(ptr, "KB", strlen("KB")))
1113 mode.reserve_size = 1 << 10;
1114 else if (!strncmp(ptr, "MB", strlen("MB")))
1115 mode.reserve_size = 1 << 20;
1116 else if (!strncmp(ptr, "GB", strlen("GB")))
1117 mode.reserve_size = 1 << 30;
1118 else
1119 panic("Syntax error in ring size param!\n");
1121 *ptr = 0;
1122 mode.reserve_size *= atoi(optarg);
1123 break;
1124 case 'b':
1125 set_cpu_affinity(optarg, 0);
1126 if (mode.cpu != CPU_NOTOUCH)
1127 mode.cpu = atoi(optarg);
1128 break;
1129 case 'B':
1130 set_cpu_affinity(optarg, 1);
1131 break;
1132 case 'H':
1133 prio_high = true;
1134 break;
1135 case 'c':
1136 mode.pcap = PCAP_OPS_RW;
1137 break;
1138 case 'm':
1139 mode.pcap = PCAP_OPS_MMAP;
1140 break;
1141 case 'Q':
1142 mode.cpu = CPU_NOTOUCH;
1143 break;
1144 case 's':
1145 mode.print_mode = FNTTYPE_PRINT_NONE;
1146 break;
1147 case 'q':
1148 mode.print_mode = FNTTYPE_PRINT_LESS;
1149 break;
1150 case 'x':
1151 mode.print_mode = FNTTYPE_PRINT_PAY_HEX;
1152 break;
1153 case 'l':
1154 mode.print_mode = FNTTYPE_PRINT_PAY_ASCII;
1155 break;
1156 case 'X':
1157 mode.print_mode = FNTTYPE_PRINT_ALL_HEX;
1158 break;
1159 case 'N':
1160 mode.print_mode = FNTTYPE_PRINT_NO_PAY;
1161 break;
1162 case 'k':
1163 mode.kpull = (unsigned long) atol(optarg);
1164 break;
1165 case 'n':
1166 frame_cnt_max = (unsigned long) atol(optarg);
1167 break;
1168 case 'F':
1169 mode.dump_interval = (unsigned long) atol(optarg);
1170 break;
1171 case 'v':
1172 version();
1173 break;
1174 case 'h':
1175 help();
1176 break;
1177 case '?':
1178 switch (optopt) {
1179 case 'd':
1180 case 'i':
1181 case 'o':
1182 case 'f':
1183 case 't':
1184 case 'F':
1185 case 'n':
1186 case 'S':
1187 case 'b':
1188 case 'k':
1189 case 'B':
1190 case 'e':
1191 panic("Option -%c requires an argument!\n",
1192 optopt);
1193 default:
1194 if (isprint(optopt))
1195 whine("Unknown option character "
1196 "`0x%X\'!\n", optopt);
1197 die();
1199 default:
1200 break;
1204 if (!mode.device_in)
1205 mode.device_in = xstrdup("any");
1207 register_signal(SIGINT, signal_handler);
1208 register_signal(SIGHUP, signal_handler);
1210 init_pcap(mode.jumbo_support);
1211 tprintf_init();
1212 header();
1214 if (prio_high == true) {
1215 set_proc_prio(get_default_proc_prio());
1216 set_sched_status(get_default_sched_policy(),
1217 get_default_sched_prio());
1220 if (mode.device_in && (device_mtu(mode.device_in) ||
1221 !strncmp("any", mode.device_in, strlen(mode.device_in)))) {
1222 if (!mode.device_out) {
1223 mode.dump = 0;
1224 enter_mode = enter_mode_rx_only_or_dump;
1225 } else if (device_mtu(mode.device_out)) {
1226 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1227 enter_mode = enter_mode_rx_to_tx;
1228 } else {
1229 mode.dump = 1;
1230 register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
1231 enter_mode = enter_mode_rx_only_or_dump;
1233 } else {
1234 if (mode.device_out && device_mtu(mode.device_out)) {
1235 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1236 enter_mode = enter_mode_pcap_to_tx;
1237 } else {
1238 enter_mode = enter_mode_read_pcap;
1242 if (!enter_mode)
1243 panic("Selection not supported!\n");
1244 enter_mode(&mode);
1246 tprintf_cleanup();
1247 cleanup_pcap();
1249 if (mode.device_in)
1250 xfree(mode.device_in);
1251 if (mode.device_out)
1252 xfree(mode.device_out);
1253 return 0;