cmake: minor: make whitespaces in cmake files consistent
[netsniff-ng.git] / src / netsniff-ng.c
blob4ed192a5a7f2c446eef5dff78d67607d9e45eb97
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>
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>
75 Output sink. Can be a network device, pcap file or a directory.
77 =item -f|--filter <bpf-file>
79 Use BPF filter file from bpfc.
81 =item -t|--type <type>
83 =over
85 =item Only handle packets of defined type:
87 =over
89 =item - broadcast
91 =item - multicast
93 =item - others
95 =item - outgoing
97 =back
99 =back
101 =item -F|--interval <uint>
103 Dump interval in seconds. if -o is a directory, a new pcap will be created at each interval.
104 The older files are left untouched. (default value: 60 seconds)
106 =item -s|--silent
108 Do not print captured packets to stdout.
110 =item -J|--jumbo-support
112 Support for 64KB Super Jumbo Frames.
114 =item -n|--num <uint>
116 When zerp, capture/replay until SIGINT is received (default).
117 When non-zero, capture/replay the number of packets.
119 =item -r|--rand
121 Randomize packet forwarding order (replay mode only).
123 =item -M|--no-promisc
125 Do not place the interface in promiscuous mode.
127 =item -m|--mmap
129 Mmap pcap file i.e., for replaying. Default: scatter/gather I/O.
131 =item -c|--clrw
133 Instead of using scatter/gather I/O use slower read(2)/write(2) I/O.
135 =item -S|--ring-size <size>
137 Manually set ring size in KB/MB/GB, e.g. '10MB'.
139 =item -k|--kernel-pull <uint>
141 Kernel pull from user interval in microseconds. Default is 10us. (replay mode only).
143 =item -b|--bind-cpu <cpu>
145 Bind to specific CPU (or CPU-range).
147 =item -B|--unbind-cpu <cpu>
149 Forbid to use specific CPU (or CPU-range).
151 =item -H|--prio-high
153 Run the process in high-priority mode.
155 =item -Q|--notouch-irq
157 Do not touch IRQ CPU affinity of NIC.
159 =item -q|--less
161 Print less-verbose packet information.
163 =item -l|--payload
165 Only print human-readable payload.
167 =item -x|--payload-hex
169 Only print payload in hex format.
171 =item -N|--payload-none
173 Only print packet header.
175 =item -X|--all-hex
177 Print packets in hex format.
179 =item -v|--version
181 Print version.
183 =item -h|--help
185 Print help text and lists all options.
187 =back
189 =head1 AUTHOR
191 Written by Daniel Borkmann <daniel@netsniff-ng.org> and Emmanuel Roullit <emmanuel@netsniff-ng.org>
193 =head1 DOCUMENTATION
195 Documentation by Emmanuel Roullit <emmanuel@netsniff-ng.org>
197 =head1 BUGS
199 Please report bugs to <bugs@netsniff-ng.org>
201 =cut
205 #define _GNU_SOURCE
206 #include <stdio.h>
207 #include <stdlib.h>
208 #include <signal.h>
209 #include <getopt.h>
210 #include <ctype.h>
211 #include <time.h>
212 #include <string.h>
213 #include <sys/socket.h>
214 #include <sys/types.h>
215 #include <sys/stat.h>
216 #include <sys/time.h>
217 #include <unistd.h>
218 #include <stdbool.h>
219 #include <pthread.h>
220 #include <fcntl.h>
222 #include "ring_rx.h"
223 #include "ring_tx.h"
224 #include "xsys.h"
225 #include "built_in.h"
226 #include "pcap.h"
227 #include "bpf.h"
228 #include "xio.h"
229 #include "die.h"
230 #include "opt_memcpy.h"
231 #include "tprintf.h"
232 #include "dissector.h"
233 #include "xmalloc.h"
234 #include "mtrand.h"
236 #define CPU_UNKNOWN -1
237 #define CPU_NOTOUCH -2
238 #define PACKET_ALL -1
239 #define DUMP_INTERVAL 60
241 struct mode {
242 char *device_in;
243 char *device_out;
244 char *filter;
245 int cpu;
246 int dump;
247 int link_type;
248 int print_mode;
249 unsigned int reserve_size;
250 int packet_type;
251 bool randomize;
252 bool promiscuous;
253 enum pcap_ops_groups pcap;
254 unsigned long kpull;
255 int jumbo_support;
256 int dump_dir;
257 unsigned long dump_interval;
260 struct tx_stats {
261 unsigned long tx_bytes;
262 unsigned long tx_packets;
265 volatile sig_atomic_t sigint = 0;
267 static int tx_sock;
268 static unsigned long frame_cnt_max = 0;
269 static unsigned long interval = TX_KERNEL_PULL_INT;
270 static struct itimerval itimer;
271 static volatile bool next_dump = false;
273 static const char *short_options = "d:i:o:rf:MJt:S:k:n:b:B:HQmcsqlxXNvhF:";
275 static struct option long_options[] = {
276 {"dev", required_argument, 0, 'd'},
277 {"in", required_argument, 0, 'i'},
278 {"out", required_argument, 0, 'o'},
279 {"rand", no_argument, 0, 'r'},
280 {"mmap", no_argument, 0, 'm'},
281 {"clrw", no_argument, 0, 'c'},
282 {"jumbo-support", no_argument, 0, 'J'},
283 {"filter", required_argument, 0, 'f'},
284 {"no-promisc", no_argument, 0, 'M'},
285 {"num", required_argument, 0, 'n'},
286 {"type", required_argument, 0, 't'},
287 {"interval", required_argument, 0, 'F'},
288 {"ring-size", required_argument, 0, 'S'},
289 {"kernel-pull", required_argument, 0, 'k'},
290 {"bind-cpu", required_argument, 0, 'b'},
291 {"unbind-cpu", required_argument, 0, 'B'},
292 {"prio-high", no_argument, 0, 'H'},
293 {"notouch-irq", no_argument, 0, 'Q'},
294 {"silent", no_argument, 0, 's'},
295 {"less", no_argument, 0, 'q'},
296 {"payload", no_argument, 0, 'l'},
297 {"payload-hex", no_argument, 0, 'x'},
298 {"payload-none", no_argument, 0, 'N'},
299 {"all-hex", no_argument, 0, 'X'},
300 {"version", no_argument, 0, 'v'},
301 {"help", no_argument, 0, 'h'},
302 {0, 0, 0, 0}
305 static void signal_handler(int number)
307 switch (number) {
308 case SIGINT:
309 sigint = 1;
310 break;
311 case SIGHUP:
312 break;
313 default:
314 break;
318 static void timer_elapsed(int number)
320 itimer.it_interval.tv_sec = 0;
321 itimer.it_interval.tv_usec = interval;
322 itimer.it_value.tv_sec = 0;
323 itimer.it_value.tv_usec = interval;
325 pull_and_flush_tx_ring(tx_sock);
326 setitimer(ITIMER_REAL, &itimer, NULL);
329 static void timer_next_dump(int number)
331 itimer.it_interval.tv_sec = interval;
332 itimer.it_interval.tv_usec = 0;
333 itimer.it_value.tv_sec = interval;
334 itimer.it_value.tv_usec = 0;
336 next_dump = true;
337 setitimer(ITIMER_REAL, &itimer, NULL);
340 static void enter_mode_pcap_to_tx(struct mode *mode)
342 int irq, ifindex, fd = 0, ret;
343 unsigned int size, it = 0;
344 struct ring tx_ring;
345 struct frame_map *hdr;
346 struct sock_fprog bpf_ops;
347 struct tx_stats stats;
348 uint8_t *out = NULL;
350 if (!device_up_and_running(mode->device_out))
351 panic("Device not up and running!\n");
353 set_memcpy();
354 tx_sock = pf_socket();
356 if (!pcap_ops[mode->pcap])
357 panic("pcap group not supported!\n");
358 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
359 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
360 if (ret)
361 panic("error reading pcap header!\n");
362 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
363 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
364 if (ret)
365 panic("error prepare reading pcap!\n");
368 memset(&tx_ring, 0, sizeof(tx_ring));
369 memset(&bpf_ops, 0, sizeof(bpf_ops));
370 memset(&stats, 0, sizeof(stats));
372 ifindex = device_ifindex(mode->device_out);
373 size = ring_size(mode->device_out, mode->reserve_size);
375 bpf_parse_rules(mode->filter, &bpf_ops);
377 set_packet_loss_discard(tx_sock);
378 setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
379 create_tx_ring(tx_sock, &tx_ring);
380 mmap_tx_ring(tx_sock, &tx_ring);
381 alloc_tx_ring_frames(&tx_ring);
382 bind_tx_ring(tx_sock, &tx_ring, ifindex);
384 dissector_init_all(mode->print_mode);
386 if (mode->cpu >= 0 && ifindex > 0) {
387 irq = device_irq_number(mode->device_out);
388 device_bind_irq_to_cpu(mode->cpu, irq);
389 printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq,
390 mode->cpu);
393 if (mode->kpull)
394 interval = mode->kpull;
396 itimer.it_interval.tv_sec = 0;
397 itimer.it_interval.tv_usec = interval;
398 itimer.it_value.tv_sec = 0;
399 itimer.it_value.tv_usec = interval;
400 setitimer(ITIMER_REAL, &itimer, NULL);
402 printf("BPF:\n");
403 bpf_dump_all(&bpf_ops);
404 printf("MD: TX %luus %s\n\n", interval, pcap_ops[mode->pcap]->name);
406 while (likely(sigint == 0)) {
407 while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
408 struct pcap_pkthdr phdr;
409 hdr = tx_ring.frames[it].iov_base;
410 /* Kernel assumes: data = ph.raw + po->tp_hdrlen -
411 * sizeof(struct sockaddr_ll); */
412 out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
413 sizeof(struct sockaddr_ll);
415 do {
416 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
417 out, ring_frame_size(&tx_ring));
418 if (unlikely(ret <= 0))
419 goto out;
420 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
421 pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);
423 stats.tx_bytes += hdr->tp_h.tp_len;;
424 stats.tx_packets++;
426 show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
427 dissector_entry_point(out, hdr->tp_h.tp_snaplen,
428 mode->link_type);
430 kernel_may_pull_from_tx(&hdr->tp_h);
431 next_slot(&it, &tx_ring);
433 if (unlikely(sigint == 1))
434 break;
435 if (frame_cnt_max != 0 &&
436 stats.tx_packets >= frame_cnt_max) {
437 sigint = 1;
438 break;
442 out:
443 fflush(stdout);
444 printf("\n");
445 printf("\r%12lu frames outgoing\n", stats.tx_packets);
446 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
448 dissector_cleanup_all();
449 destroy_tx_ring(tx_sock, &tx_ring);
451 close(tx_sock);
452 if (pcap_ops[mode->pcap]->prepare_close_pcap)
453 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
454 close(fd);
457 static void enter_mode_rx_to_tx(struct mode *mode)
459 int rx_sock, ifindex_in, ifindex_out;
460 unsigned int size_in, size_out, it_in = 0, it_out = 0;
461 unsigned long fcnt = 0;
462 uint8_t *in, *out;
463 short ifflags = 0;
464 struct frame_map *hdr_in, *hdr_out;
465 struct ring tx_ring;
466 struct ring rx_ring;
467 struct pollfd rx_poll;
468 struct sock_fprog bpf_ops;
470 if (!strncmp(mode->device_in, mode->device_out,
471 strlen(mode->device_in)))
472 panic("Ingress/egress devices must be different!\n");
473 if (!device_up_and_running(mode->device_out))
474 panic("Egress device not up and running!\n");
475 if (!device_up_and_running(mode->device_in))
476 panic("Ingress device not up and running!\n");
478 set_memcpy();
479 rx_sock = pf_socket();
480 tx_sock = pf_socket();
482 memset(&tx_ring, 0, sizeof(tx_ring));
483 memset(&rx_ring, 0, sizeof(rx_ring));
484 memset(&rx_poll, 0, sizeof(rx_poll));
485 memset(&bpf_ops, 0, sizeof(bpf_ops));
487 ifindex_in = device_ifindex(mode->device_in);
488 size_in = ring_size(mode->device_in, mode->reserve_size);
490 ifindex_out = device_ifindex(mode->device_out);
491 size_out = ring_size(mode->device_out, mode->reserve_size);
493 enable_kernel_bpf_jit_compiler();
494 bpf_parse_rules(mode->filter, &bpf_ops);
495 bpf_attach_to_sock(rx_sock, &bpf_ops);
497 setup_rx_ring_layout(rx_sock, &rx_ring, size_in, mode->jumbo_support);
498 create_rx_ring(rx_sock, &rx_ring);
499 mmap_rx_ring(rx_sock, &rx_ring);
500 alloc_rx_ring_frames(&rx_ring);
501 bind_rx_ring(rx_sock, &rx_ring, ifindex_in);
502 prepare_polling(rx_sock, &rx_poll);
504 set_packet_loss_discard(tx_sock);
505 setup_tx_ring_layout(tx_sock, &tx_ring, size_out, mode->jumbo_support);
506 create_tx_ring(tx_sock, &tx_ring);
507 mmap_tx_ring(tx_sock, &tx_ring);
508 alloc_tx_ring_frames(&tx_ring);
509 bind_tx_ring(tx_sock, &tx_ring, ifindex_out);
511 mt_init_by_seed_time();
512 dissector_init_all(mode->print_mode);
514 if (mode->promiscuous == true) {
515 ifflags = enter_promiscuous_mode(mode->device_in);
516 printf("PROMISC\n");
519 if (mode->kpull)
520 interval = mode->kpull;
522 itimer.it_interval.tv_sec = 0;
523 itimer.it_interval.tv_usec = interval;
524 itimer.it_value.tv_sec = 0;
525 itimer.it_value.tv_usec = interval;
526 setitimer(ITIMER_REAL, &itimer, NULL);
528 printf("BPF:\n");
529 bpf_dump_all(&bpf_ops);
530 printf("MD: RXTX %luus\n\n", interval);
531 printf("Running! Hang up with ^C!\n\n");
533 while (likely(sigint == 0)) {
534 while (user_may_pull_from_rx(rx_ring.frames[it_in].iov_base)) {
535 hdr_in = rx_ring.frames[it_in].iov_base;
536 in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;
537 fcnt++;
538 if (mode->packet_type != PACKET_ALL)
539 if (mode->packet_type != hdr_in->s_ll.sll_pkttype)
540 goto next;
542 hdr_out = tx_ring.frames[it_out].iov_base;
543 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
544 sizeof(struct sockaddr_ll);
546 for (; !user_may_pull_from_tx(tx_ring.frames[it_out].iov_base) &&
547 likely(!sigint);) {
548 if (mode->randomize)
549 next_rnd_slot(&it_out, &tx_ring);
550 else
551 next_slot(&it_out, &tx_ring);
552 hdr_out = tx_ring.frames[it_out].iov_base;
553 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
554 sizeof(struct sockaddr_ll);
557 tpacket_hdr_clone(&hdr_out->tp_h, &hdr_in->tp_h);
558 __memcpy(out, in, hdr_in->tp_h.tp_len);
560 kernel_may_pull_from_tx(&hdr_out->tp_h);
561 if (mode->randomize)
562 next_rnd_slot(&it_out, &tx_ring);
563 else
564 next_slot(&it_out, &tx_ring);
566 show_frame_hdr(hdr_in, mode->print_mode, RING_MODE_INGRESS);
567 dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
568 mode->link_type);
570 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
571 sigint = 1;
572 break;
574 next:
575 kernel_may_pull_from_rx(&hdr_in->tp_h);
576 next_slot(&it_in, &rx_ring);
578 if (unlikely(sigint == 1))
579 goto out;
582 poll(&rx_poll, 1, -1);
583 poll_error_maybe_die(rx_sock, &rx_poll);
585 out:
586 sock_print_net_stats(rx_sock);
588 dissector_cleanup_all();
589 destroy_tx_ring(tx_sock, &tx_ring);
590 destroy_rx_ring(rx_sock, &rx_ring);
592 if (mode->promiscuous == true)
593 leave_promiscuous_mode(mode->device_in, ifflags);
595 close(tx_sock);
596 close(rx_sock);
599 static void enter_mode_read_pcap(struct mode *mode)
601 int ret, fd;
602 struct pcap_pkthdr phdr;
603 struct sock_fprog bpf_ops;
604 struct tx_stats stats;
605 struct frame_map fm;
606 uint8_t *out;
607 size_t out_len;
609 if (!pcap_ops[mode->pcap])
610 panic("pcap group not supported!\n");
611 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
612 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
613 if (ret)
614 panic("error reading pcap header!\n");
615 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
616 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
617 if (ret)
618 panic("error prepare reading pcap!\n");
621 memset(&fm, 0, sizeof(fm));
622 memset(&bpf_ops, 0, sizeof(bpf_ops));
623 memset(&stats, 0, sizeof(stats));
625 bpf_parse_rules(mode->filter, &bpf_ops);
626 dissector_init_all(mode->print_mode);
628 out_len = device_mtu("lo");
629 out = xmalloc_aligned(out_len, 64);
631 printf("BPF:\n");
632 bpf_dump_all(&bpf_ops);
633 printf("MD: RD %s\n\n", pcap_ops[mode->pcap]->name);
635 while (likely(sigint == 0)) {
636 do {
637 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
638 out, out_len);
639 if (unlikely(ret <= 0))
640 goto out;
641 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
642 pcap_pkthdr_to_tpacket_hdr(&phdr, &fm.tp_h);
644 stats.tx_bytes += fm.tp_h.tp_len;;
645 stats.tx_packets++;
647 show_frame_hdr(&fm, mode->print_mode, RING_MODE_EGRESS);
648 dissector_entry_point(out, fm.tp_h.tp_snaplen,
649 mode->link_type);
651 if (frame_cnt_max != 0 &&
652 stats.tx_packets >= frame_cnt_max) {
653 sigint = 1;
654 break;
657 out:
658 fflush(stdout);
659 printf("\n");
660 printf("\r%12lu frames outgoing\n", stats.tx_packets);
661 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
663 xfree(out);
664 dissector_cleanup_all();
665 if (pcap_ops[mode->pcap]->prepare_close_pcap)
666 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
667 close(fd);
670 static void finish_multi_pcap_file(struct mode *mode, int fd)
672 pcap_ops[mode->pcap]->fsync_pcap(fd);
673 if (pcap_ops[mode->pcap]->prepare_close_pcap)
674 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
675 close(fd);
677 memset(&itimer, 0, sizeof(itimer));
678 setitimer(ITIMER_REAL, &itimer, NULL);
681 static int next_multi_pcap_file(struct mode *mode, int fd)
683 int ret;
684 char tmp[512];
686 pcap_ops[mode->pcap]->fsync_pcap(fd);
687 if (pcap_ops[mode->pcap]->prepare_close_pcap)
688 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
689 close(fd);
691 memset(&tmp, 0, sizeof(tmp));
692 snprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
693 tmp[sizeof(tmp) - 1] = 0;
695 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
696 S_IRUSR | S_IWUSR);
697 ret = pcap_ops[mode->pcap]->push_file_header(fd);
698 if (ret)
699 panic("error writing pcap header!\n");
700 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
701 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
702 if (ret)
703 panic("error prepare writing pcap!\n");
706 return fd;
709 static int begin_multi_pcap_file(struct mode *mode)
711 int fd, ret;
712 char tmp[512];
714 if (!pcap_ops[mode->pcap])
715 panic("pcap group not supported!\n");
716 if (mode->device_out[strlen(mode->device_out) - 1] == '/')
717 mode->device_out[strlen(mode->device_out) - 1] = 0;
719 memset(&tmp, 0, sizeof(tmp));
720 snprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
721 tmp[sizeof(tmp) - 1] = 0;
723 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
724 S_IRUSR | S_IWUSR);
725 ret = pcap_ops[mode->pcap]->push_file_header(fd);
726 if (ret)
727 panic("error writing pcap header!\n");
728 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
729 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
730 if (ret)
731 panic("error prepare writing pcap!\n");
734 interval = mode->dump_interval;
735 itimer.it_interval.tv_sec = interval;
736 itimer.it_interval.tv_usec = 0;
737 itimer.it_value.tv_sec = interval;
738 itimer.it_value.tv_usec = 0;
739 setitimer(ITIMER_REAL, &itimer, NULL);
741 return fd;
744 static void finish_single_pcap_file(struct mode *mode, int fd)
746 pcap_ops[mode->pcap]->fsync_pcap(fd);
747 if (pcap_ops[mode->pcap]->prepare_close_pcap)
748 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
749 close(fd);
752 static int begin_single_pcap_file(struct mode *mode)
754 int fd, ret;
756 if (!pcap_ops[mode->pcap])
757 panic("pcap group not supported!\n");
758 fd = open_or_die_m(mode->device_out,
759 O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
760 S_IRUSR | S_IWUSR);
761 ret = pcap_ops[mode->pcap]->push_file_header(fd);
762 if (ret)
763 panic("error writing pcap header!\n");
764 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
765 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
766 if (ret)
767 panic("error prepare writing pcap!\n");
770 return fd;
773 static void enter_mode_rx_only_or_dump(struct mode *mode)
775 int sock, irq, ifindex, fd = 0, ret;
776 unsigned int size, it = 0;
777 unsigned long fcnt = 0;
778 short ifflags = 0;
779 uint8_t *packet;
780 struct ring rx_ring;
781 struct pollfd rx_poll;
782 struct frame_map *hdr;
783 struct sock_fprog bpf_ops;
785 if (!device_up_and_running(mode->device_in))
786 panic("Device not up and running!\n");
788 set_memcpy();
789 sock = pf_socket();
791 if (mode->dump) {
792 struct stat tmp;
793 memset(&tmp, 0, sizeof(tmp));
794 ret = stat(mode->device_out, &tmp);
795 if (ret < 0) {
796 mode->dump_dir = 0;
797 goto try_file;
799 mode->dump_dir = !!S_ISDIR(tmp.st_mode);
800 if (mode->dump_dir) {
801 fd = begin_multi_pcap_file(mode);
802 } else {
803 try_file:
804 fd = begin_single_pcap_file(mode);
808 memset(&rx_ring, 0, sizeof(rx_ring));
809 memset(&rx_poll, 0, sizeof(rx_poll));
810 memset(&bpf_ops, 0, sizeof(bpf_ops));
812 ifindex = device_ifindex(mode->device_in);
813 size = ring_size(mode->device_in, mode->reserve_size);
815 enable_kernel_bpf_jit_compiler();
816 bpf_parse_rules(mode->filter, &bpf_ops);
817 bpf_attach_to_sock(sock, &bpf_ops);
819 setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
820 create_rx_ring(sock, &rx_ring);
821 mmap_rx_ring(sock, &rx_ring);
822 alloc_rx_ring_frames(&rx_ring);
823 bind_rx_ring(sock, &rx_ring, ifindex);
825 prepare_polling(sock, &rx_poll);
826 dissector_init_all(mode->print_mode);
828 if (mode->cpu >= 0 && ifindex > 0) {
829 irq = device_irq_number(mode->device_in);
830 device_bind_irq_to_cpu(mode->cpu, irq);
831 printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq,
832 mode->cpu);
835 if (mode->promiscuous == true) {
836 ifflags = enter_promiscuous_mode(mode->device_in);
837 printf("PROMISC\n");
840 printf("BPF:\n");
841 bpf_dump_all(&bpf_ops);
842 printf("MD: RX %s\n\n", mode->dump ? pcap_ops[mode->pcap]->name : "");
844 while (likely(sigint == 0)) {
845 while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
846 hdr = rx_ring.frames[it].iov_base;
847 packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
848 fcnt++;
850 if (mode->packet_type != PACKET_ALL)
851 if (mode->packet_type != hdr->s_ll.sll_pkttype)
852 goto next;
853 if (unlikely(rx_ring.layout.tp_frame_size <
854 hdr->tp_h.tp_snaplen)) {
855 fprintf(stderr, "Skipping too large packet! "
856 "No jumbo support selected?\n");
857 fflush(stderr);
858 goto next;
860 if (mode->dump) {
861 struct pcap_pkthdr phdr;
862 tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
863 ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
864 packet, phdr.len);
865 if (unlikely(ret != sizeof(phdr) + phdr.len))
866 panic("Write error to pcap!\n");
869 show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
870 dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
871 mode->link_type);
873 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
874 sigint = 1;
875 break;
877 next:
878 kernel_may_pull_from_rx(&hdr->tp_h);
879 next_slot(&it, &rx_ring);
881 if (unlikely(sigint == 1))
882 break;
883 if (mode->dump && next_dump) {
884 struct tpacket_stats kstats;
885 socklen_t slen = sizeof(kstats);
886 memset(&kstats, 0, sizeof(kstats));
887 getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
888 &kstats, &slen);
889 fd = next_multi_pcap_file(mode, fd);
890 next_dump = false;
891 if (mode->print_mode == FNTTYPE_PRINT_NONE) {
892 printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
893 kstats.tp_drops);
894 fflush(stdout);
899 poll(&rx_poll, 1, -1);
900 poll_error_maybe_die(sock, &rx_poll);
903 if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE))
904 sock_print_net_stats(sock);
905 else {
906 printf("\n\n");
907 fflush(stdout);
909 dissector_cleanup_all();
910 destroy_rx_ring(sock, &rx_ring);
911 if (mode->promiscuous == true)
912 leave_promiscuous_mode(mode->device_in, ifflags);
913 close(sock);
914 if (mode->dump) {
915 if (mode->dump_dir)
916 finish_multi_pcap_file(mode, fd);
917 else
918 finish_single_pcap_file(mode, fd);
922 static void help(void)
924 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
925 VERSION_STRING);
926 printf("http://www.netsniff-ng.org\n\n");
927 printf("Usage: netsniff-ng [options]\n");
928 printf("Options:\n");
929 printf(" -i|-d|--dev|--in <dev|pcap> Input source as netdev or pcap\n");
930 printf(" -o|--out <dev|pcap|dir> Output sink as netdev or pcap or directory\n");
931 printf(" -f|--filter <bpf-file> Use BPF filter file from bpfc\n");
932 printf(" -t|--type <type> Only handle packets of defined type:\n");
933 printf(" host|broadcast|multicast|others|outgoing\n");
934 printf(" -F|--interval <uint> Dump interval in sec if -o is a directory where\n");
935 printf(" pcap files should be stored (default: 60)\n");
936 printf(" -s|--silent Do not print captured packets\n");
937 printf(" -J|--jumbo-support Support for 64KB Super Jumbo Frames\n");
938 printf(" Default RX/TX slot: 2048Byte\n");
939 printf(" -n|--num <uint> Number of packets until exit\n");
940 printf(" `-- 0 Loop until interrupt (default)\n");
941 printf(" `- n Send n packets and done\n");
942 printf(" -r|--rand Randomize packet forwarding order\n");
943 printf(" -M|--no-promisc No promiscuous mode for netdev\n");
944 printf(" -m|--mmap Mmap pcap file i.e., for replaying\n");
945 printf(" Default: scatter/gather I/O\n");
946 printf(" -c|--clrw Instead s/g I/O use slower read(2)/write(2) I/O\n");
947 printf(" -S|--ring-size <size> Manually set ring size to <size>:\n");
948 printf(" mmap space in KB/MB/GB, e.g. \'10MB\'\n");
949 printf(" -k|--kernel-pull <uint> Kernel pull from user interval in us\n");
950 printf(" Default is 10us where the TX_RING\n");
951 printf(" is populated with payload from uspace\n");
952 printf(" -b|--bind-cpu <cpu> Bind to specific CPU (or CPU-range)\n");
953 printf(" -B|--unbind-cpu <cpu> Forbid to use specific CPU (or CPU-range)\n");
954 printf(" -H|--prio-high Make this high priority process\n");
955 printf(" -Q|--notouch-irq Do not touch IRQ CPU affinity of NIC\n");
956 printf(" -q|--less Print less-verbose packet information\n");
957 printf(" -l|--payload Only print human-readable payload\n");
958 printf(" -x|--payload-hex Only print payload in hex format\n");
959 printf(" -N|--payload-none Only print packet header\n");
960 printf(" -X|--all-hex Print packets in hex format\n");
961 printf(" -v|--version Show version\n");
962 printf(" -h|--help Guess what?!\n");
963 printf("\n");
964 printf("Examples:\n");
965 printf(" netsniff-ng --in eth0 --out dump.pcap --silent --bind-cpu 0\n");
966 printf(" netsniff-ng --in dump.pcap --mmap --out eth0 --silent --bind-cpu 0\n");
967 printf(" netsniff-ng --in any --filter icmp.bpf --all-hex\n");
968 printf(" netsniff-ng --in eth0 --out eth1 --silent --bind-cpu 0 --type host --filter http.bpf\n");
969 printf(" netsniff-ng --in any --filter http.bpf --payload\n");
970 printf(" netsniff-ng --in wlan0 --out /opt/probe1/ --silent --interval 30 --bind-cpu 0 --jumbo-support\n");
971 printf("\n");
972 printf("Note:\n");
973 printf(" This tool is targeted for network developers! You should\n");
974 printf(" be aware of what you are doing and what these options above\n");
975 printf(" mean! Use netsniff-ng's bpfc compiler for generating filter files.\n");
976 printf(" Further, netsniff-ng automatically enables the kernel BPF JIT\n");
977 printf(" if present.\n");
978 printf("\n");
979 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
980 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
981 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
982 printf("License: GNU GPL version 2\n");
983 printf("This is free software: you are free to change and redistribute it.\n");
984 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
985 die();
988 static void version(void)
990 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
991 VERSION_STRING);
992 printf("http://www.netsniff-ng.org\n\n");
993 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
994 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
995 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
996 printf("License: GNU GPL version 2\n");
997 printf("This is free software: you are free to change and redistribute it.\n");
998 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
999 die();
1002 static void header(void)
1004 printf("%s%s%s\n", colorize_start(bold), PROGNAME_STRING " "
1005 VERSION_STRING, colorize_end());
1008 int main(int argc, char **argv)
1010 int c, i, j, opt_index;
1011 char *ptr;
1012 bool prio_high = false;
1013 struct mode mode;
1014 void (*enter_mode)(struct mode *mode) = NULL;
1016 check_for_root_maybe_die();
1018 memset(&mode, 0, sizeof(mode));
1019 mode.link_type = LINKTYPE_EN10MB;
1020 mode.print_mode = FNTTYPE_PRINT_NORM;
1021 mode.cpu = CPU_UNKNOWN;
1022 mode.packet_type = PACKET_ALL;
1023 mode.promiscuous = true;
1024 mode.randomize = false;
1025 mode.pcap = PCAP_OPS_SG;
1026 mode.dump_interval = DUMP_INTERVAL;
1028 while ((c = getopt_long(argc, argv, short_options, long_options,
1029 &opt_index)) != EOF) {
1030 switch (c) {
1031 case 'd':
1032 case 'i':
1033 mode.device_in = xstrdup(optarg);
1034 break;
1035 case 'o':
1036 mode.device_out = xstrdup(optarg);
1037 break;
1038 case 'r':
1039 mode.randomize = true;
1040 break;
1041 case 'J':
1042 mode.jumbo_support = 1;
1043 break;
1044 case 'f':
1045 mode.filter = xstrdup(optarg);
1046 break;
1047 case 'M':
1048 mode.promiscuous = false;
1049 break;
1050 case 't':
1051 if (!strncmp(optarg, "host", strlen("host")))
1052 mode.packet_type = PACKET_HOST;
1053 else if (!strncmp(optarg, "broadcast", strlen("broadcast")))
1054 mode.packet_type = PACKET_BROADCAST;
1055 else if (!strncmp(optarg, "multicast", strlen("multicast")))
1056 mode.packet_type = PACKET_MULTICAST;
1057 else if (!strncmp(optarg, "others", strlen("others")))
1058 mode.packet_type = PACKET_OTHERHOST;
1059 else if (!strncmp(optarg, "outgoing", strlen("outgoing")))
1060 mode.packet_type = PACKET_OUTGOING;
1061 else
1062 mode.packet_type = PACKET_ALL;
1063 break;
1064 case 'S':
1065 ptr = optarg;
1066 mode.reserve_size = 0;
1068 for (j = i = strlen(optarg); i > 0; --i) {
1069 if (!isdigit(optarg[j - i]))
1070 break;
1071 ptr++;
1074 if (!strncmp(ptr, "KB", strlen("KB")))
1075 mode.reserve_size = 1 << 10;
1076 else if (!strncmp(ptr, "MB", strlen("MB")))
1077 mode.reserve_size = 1 << 20;
1078 else if (!strncmp(ptr, "GB", strlen("GB")))
1079 mode.reserve_size = 1 << 30;
1080 else
1081 panic("Syntax error in ring size param!\n");
1083 *ptr = 0;
1084 mode.reserve_size *= atoi(optarg);
1085 break;
1086 case 'b':
1087 set_cpu_affinity(optarg, 0);
1088 if (mode.cpu != CPU_NOTOUCH)
1089 mode.cpu = atoi(optarg);
1090 break;
1091 case 'B':
1092 set_cpu_affinity(optarg, 1);
1093 break;
1094 case 'H':
1095 prio_high = true;
1096 break;
1097 case 'c':
1098 mode.pcap = PCAP_OPS_RW;
1099 break;
1100 case 'm':
1101 mode.pcap = PCAP_OPS_MMAP;
1102 break;
1103 case 'Q':
1104 mode.cpu = CPU_NOTOUCH;
1105 break;
1106 case 's':
1107 mode.print_mode = FNTTYPE_PRINT_NONE;
1108 break;
1109 case 'q':
1110 mode.print_mode = FNTTYPE_PRINT_LESS;
1111 break;
1112 case 'x':
1113 mode.print_mode = FNTTYPE_PRINT_PAY_HEX;
1114 break;
1115 case 'l':
1116 mode.print_mode = FNTTYPE_PRINT_PAY_ASCII;
1117 break;
1118 case 'X':
1119 mode.print_mode = FNTTYPE_PRINT_ALL_HEX;
1120 break;
1121 case 'N':
1122 mode.print_mode = FNTTYPE_PRINT_NO_PAY;
1123 break;
1124 case 'k':
1125 mode.kpull = (unsigned long) atol(optarg);
1126 break;
1127 case 'n':
1128 frame_cnt_max = (unsigned long) atol(optarg);
1129 break;
1130 case 'F':
1131 mode.dump_interval = (unsigned long) atol(optarg);
1132 break;
1133 case 'v':
1134 version();
1135 break;
1136 case 'h':
1137 help();
1138 break;
1139 case '?':
1140 switch (optopt) {
1141 case 'd':
1142 case 'i':
1143 case 'o':
1144 case 'f':
1145 case 't':
1146 case 'F':
1147 case 'n':
1148 case 'S':
1149 case 'b':
1150 case 'k':
1151 case 'B':
1152 case 'e':
1153 panic("Option -%c requires an argument!\n",
1154 optopt);
1155 default:
1156 if (isprint(optopt))
1157 whine("Unknown option character "
1158 "`0x%X\'!\n", optopt);
1159 die();
1161 default:
1162 break;
1166 if (!mode.device_in)
1167 mode.device_in = xstrdup("any");
1169 register_signal(SIGINT, signal_handler);
1170 register_signal(SIGHUP, signal_handler);
1172 init_pcap(mode.jumbo_support);
1173 tprintf_init();
1174 header();
1176 if (prio_high == true) {
1177 set_proc_prio(get_default_proc_prio());
1178 set_sched_status(get_default_sched_policy(),
1179 get_default_sched_prio());
1182 if (mode.device_in && (device_mtu(mode.device_in) ||
1183 !strncmp("any", mode.device_in, strlen(mode.device_in)))) {
1184 if (!mode.device_out) {
1185 mode.dump = 0;
1186 enter_mode = enter_mode_rx_only_or_dump;
1187 } else if (device_mtu(mode.device_out)) {
1188 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1189 enter_mode = enter_mode_rx_to_tx;
1190 } else {
1191 mode.dump = 1;
1192 register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
1193 enter_mode = enter_mode_rx_only_or_dump;
1195 } else {
1196 if (mode.device_out && device_mtu(mode.device_out)) {
1197 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1198 enter_mode = enter_mode_pcap_to_tx;
1199 } else {
1200 enter_mode = enter_mode_read_pcap;
1204 if (!enter_mode)
1205 panic("Selection not supported!\n");
1206 enter_mode(&mode);
1208 tprintf_cleanup();
1209 cleanup_pcap();
1211 if (mode.device_in)
1212 xfree(mode.device_in);
1213 if (mode.device_out)
1214 xfree(mode.device_out);
1215 return 0;