proto_ipv6_mobility_hdr.h: Headerfixing
[netsniff-ng.git] / src / netsniff-ng.c
blob3bc21b3a5e27c3d2f3143a9729fb46c45b2290f6
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][-v|--version][-h|--help]
38 =head1 DESCRIPTION
40 The first sniffer that invoked both, the zero-copy RX_RING as well as
41 the zero-copy TX_RING for high-performance network I/O and scatter/gather
42 or mmaped PCAP I/O.
44 =head1 EXAMPLES
46 =over
48 =item netsniff-ng --in eth0 --out dump.pcap
50 Capture traffic from interface 'eth0' and save it pcap file 'dump.pcap'
52 =item netsniff-ng --in any --filter http.bpf --payload
54 Capture HTTP traffic from any interface and print its payload on stdout
56 =item netsniff-ng --in wlan0 --bind-cpu 0,1
58 Capture all traffic from wlan0 interface.
59 Schedule process on CPU 0 and 1.
61 =back
63 =head1 OPTIONS
65 =over
67 =item -i|-d|--dev|--in <dev|pcap>
69 Input source. Can be a network device or pcap file.
71 =item -o|--out <dev|pcap|dir|txf>
73 Output sink. Can be a network device, pcap file, a trafgen txf file or a
74 directory. (There's only pcap to txf translation possible.)
76 =item -f|--filter <bpf-file>
78 Use BPF filter file from bpfc.
80 =item -t|--type <type>
82 =over
84 =item Only handle packets of defined type:
86 =over
88 =item - broadcast
90 =item - multicast
92 =item - others
94 =item - outgoing
96 =back
98 =back
100 =item -F|--interval <uint>
102 Dump interval in seconds. if -o is a directory, a new pcap will be created at each interval.
103 The older files are left untouched. (default value: 60 seconds)
105 =item -s|--silent
107 Do not print captured packets to stdout.
109 =item -J|--jumbo-support
111 Support for 64KB Super Jumbo Frames.
113 =item -n|--num <uint>
115 When zerp, capture/replay until SIGINT is received (default).
116 When non-zero, capture/replay the number of packets.
118 =item -r|--rand
120 Randomize packet forwarding order (replay mode only).
122 =item -M|--no-promisc
124 Do not place the interface in promiscuous mode.
126 =item -m|--mmap
128 Mmap pcap file i.e., for replaying. Default: scatter/gather I/O.
130 =item -c|--clrw
132 Instead of using scatter/gather I/O use slower read(2)/write(2) I/O.
134 =item -S|--ring-size <size>
136 Manually set ring size in KB/MB/GB, e.g. '10MB'.
138 =item -k|--kernel-pull <uint>
140 Kernel pull from user interval in microseconds. Default is 10us. (replay mode only).
142 =item -b|--bind-cpu <cpu>
144 Bind to specific CPU (or CPU-range).
146 =item -B|--unbind-cpu <cpu>
148 Forbid to use specific CPU (or CPU-range).
150 =item -H|--prio-high
152 Run the process in high-priority mode.
154 =item -Q|--notouch-irq
156 Do not touch IRQ CPU affinity of NIC.
158 =item -q|--less
160 Print less-verbose packet information.
162 =item -v|--version
164 Print version.
166 =item -h|--help
168 Print help text and lists all options.
170 =back
172 =head1 AUTHOR
174 Written by Daniel Borkmann <daniel@netsniff-ng.org> and Emmanuel Roullit <emmanuel@netsniff-ng.org>
176 =head1 DOCUMENTATION
178 Documentation by Emmanuel Roullit <emmanuel@netsniff-ng.org>
180 =head1 BUGS
182 Please report bugs to <bugs@netsniff-ng.org>
184 =cut
188 #define _GNU_SOURCE
189 #include <stdio.h>
190 #include <stdlib.h>
191 #include <signal.h>
192 #include <getopt.h>
193 #include <ctype.h>
194 #include <time.h>
195 #include <string.h>
196 #include <sys/socket.h>
197 #include <sys/types.h>
198 #include <sys/stat.h>
199 #include <sys/time.h>
200 #include <unistd.h>
201 #include <stdbool.h>
202 #include <pthread.h>
203 #include <fcntl.h>
205 #include "ring_rx.h"
206 #include "ring_tx.h"
207 #include "xsys.h"
208 #include "built_in.h"
209 #include "pcap.h"
210 #include "bpf.h"
211 #include "xio.h"
212 #include "xstring.h"
213 #include "die.h"
214 #include "tprintf.h"
215 #include "dissector.h"
216 #include "xmalloc.h"
217 #include "mtrand.h"
219 #define CPU_UNKNOWN -1
220 #define CPU_NOTOUCH -2
221 #define PACKET_ALL -1
222 #define DUMP_INTERVAL 60
224 struct mode {
225 char *device_in;
226 char *device_out;
227 char *filter;
228 int cpu;
229 int dump;
230 int link_type;
231 int print_mode;
232 unsigned int reserve_size;
233 int packet_type;
234 bool randomize;
235 bool promiscuous;
236 enum pcap_ops_groups pcap;
237 unsigned long kpull;
238 int jumbo_support;
239 int dump_dir;
240 unsigned long dump_interval;
243 struct tx_stats {
244 unsigned long tx_bytes;
245 unsigned long tx_packets;
248 volatile sig_atomic_t sigint = 0;
250 static int tx_sock;
251 static unsigned long frame_cnt_max = 0;
252 static unsigned long interval = TX_KERNEL_PULL_INT;
253 static struct itimerval itimer;
254 static volatile bool next_dump = false;
256 static const char *short_options = "d:i:o:rf:MJt:S:k:n:b:B:HQmcsqvhF:";
258 static struct option long_options[] = {
259 {"dev", required_argument, 0, 'd'},
260 {"in", required_argument, 0, 'i'},
261 {"out", required_argument, 0, 'o'},
262 {"rand", no_argument, 0, 'r'},
263 {"mmap", no_argument, 0, 'm'},
264 {"clrw", no_argument, 0, 'c'},
265 {"jumbo-support", no_argument, 0, 'J'},
266 {"filter", required_argument, 0, 'f'},
267 {"no-promisc", no_argument, 0, 'M'},
268 {"num", required_argument, 0, 'n'},
269 {"type", required_argument, 0, 't'},
270 {"interval", required_argument, 0, 'F'},
271 {"ring-size", required_argument, 0, 'S'},
272 {"kernel-pull", required_argument, 0, 'k'},
273 {"bind-cpu", required_argument, 0, 'b'},
274 {"unbind-cpu", required_argument, 0, 'B'},
275 {"prio-high", no_argument, 0, 'H'},
276 {"notouch-irq", no_argument, 0, 'Q'},
277 {"silent", no_argument, 0, 's'},
278 {"less", no_argument, 0, 'q'},
279 {"version", no_argument, 0, 'v'},
280 {"help", no_argument, 0, 'h'},
281 {0, 0, 0, 0}
284 static void signal_handler(int number)
286 switch (number) {
287 case SIGINT:
288 sigint = 1;
289 break;
290 case SIGHUP:
291 break;
292 default:
293 break;
297 static void timer_elapsed(int number)
299 itimer.it_interval.tv_sec = 0;
300 itimer.it_interval.tv_usec = interval;
301 itimer.it_value.tv_sec = 0;
302 itimer.it_value.tv_usec = interval;
304 pull_and_flush_tx_ring(tx_sock);
305 setitimer(ITIMER_REAL, &itimer, NULL);
308 static void timer_next_dump(int number)
310 itimer.it_interval.tv_sec = interval;
311 itimer.it_interval.tv_usec = 0;
312 itimer.it_value.tv_sec = interval;
313 itimer.it_value.tv_usec = 0;
315 next_dump = true;
316 setitimer(ITIMER_REAL, &itimer, NULL);
319 static void enter_mode_pcap_to_tx(struct mode *mode)
321 int irq, ifindex, fd = 0, ret;
322 unsigned int size, it = 0;
323 struct ring tx_ring;
324 struct frame_map *hdr;
325 struct sock_fprog bpf_ops;
326 struct tx_stats stats;
327 uint8_t *out = NULL;
329 if (!device_up_and_running(mode->device_out))
330 panic("Device not up and running!\n");
332 tx_sock = pf_socket();
334 if (!pcap_ops[mode->pcap])
335 panic("pcap group not supported!\n");
336 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
337 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
338 if (ret)
339 panic("error reading pcap header!\n");
340 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
341 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
342 if (ret)
343 panic("error prepare reading pcap!\n");
346 fmemset(&tx_ring, 0, sizeof(tx_ring));
347 fmemset(&bpf_ops, 0, sizeof(bpf_ops));
348 fmemset(&stats, 0, sizeof(stats));
350 ifindex = device_ifindex(mode->device_out);
351 size = ring_size(mode->device_out, mode->reserve_size);
353 bpf_parse_rules(mode->filter, &bpf_ops);
355 set_packet_loss_discard(tx_sock);
356 setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
357 create_tx_ring(tx_sock, &tx_ring);
358 mmap_tx_ring(tx_sock, &tx_ring);
359 alloc_tx_ring_frames(&tx_ring);
360 bind_tx_ring(tx_sock, &tx_ring, ifindex);
362 dissector_init_all(mode->print_mode);
364 if (mode->cpu >= 0 && ifindex > 0) {
365 irq = device_irq_number(mode->device_out);
366 device_bind_irq_to_cpu(mode->cpu, irq);
367 printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq,
368 mode->cpu);
371 if (mode->kpull)
372 interval = mode->kpull;
374 itimer.it_interval.tv_sec = 0;
375 itimer.it_interval.tv_usec = interval;
376 itimer.it_value.tv_sec = 0;
377 itimer.it_value.tv_usec = interval;
378 setitimer(ITIMER_REAL, &itimer, NULL);
380 printf("BPF:\n");
381 bpf_dump_all(&bpf_ops);
382 printf("MD: TX %luus %s\n\n", interval, pcap_ops[mode->pcap]->name);
384 while (likely(sigint == 0)) {
385 while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
386 struct pcap_pkthdr phdr;
387 hdr = tx_ring.frames[it].iov_base;
388 /* Kernel assumes: data = ph.raw + po->tp_hdrlen -
389 * sizeof(struct sockaddr_ll); */
390 out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
391 sizeof(struct sockaddr_ll);
393 do {
394 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
395 out, ring_frame_size(&tx_ring));
396 if (unlikely(ret <= 0))
397 goto out;
398 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
399 pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);
401 stats.tx_bytes += hdr->tp_h.tp_len;;
402 stats.tx_packets++;
404 show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
405 dissector_entry_point(out, hdr->tp_h.tp_snaplen,
406 mode->link_type);
408 kernel_may_pull_from_tx(&hdr->tp_h);
409 next_slot_prewr(&it, &tx_ring);
411 if (unlikely(sigint == 1))
412 break;
413 if (frame_cnt_max != 0 &&
414 stats.tx_packets >= frame_cnt_max) {
415 sigint = 1;
416 break;
420 out:
421 fflush(stdout);
422 printf("\n");
423 printf("\r%12lu frames outgoing\n", stats.tx_packets);
424 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
426 dissector_cleanup_all();
427 destroy_tx_ring(tx_sock, &tx_ring);
429 close(tx_sock);
430 if (pcap_ops[mode->pcap]->prepare_close_pcap)
431 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
432 close(fd);
435 static void enter_mode_rx_to_tx(struct mode *mode)
437 int rx_sock, ifindex_in, ifindex_out;
438 unsigned int size_in, size_out, it_in = 0, it_out = 0;
439 unsigned long fcnt = 0;
440 uint8_t *in, *out;
441 short ifflags = 0;
442 struct frame_map *hdr_in, *hdr_out;
443 struct ring tx_ring;
444 struct ring rx_ring;
445 struct pollfd rx_poll;
446 struct sock_fprog bpf_ops;
448 if (!strncmp(mode->device_in, mode->device_out,
449 strlen(mode->device_in)))
450 panic("Ingress/egress devices must be different!\n");
451 if (!device_up_and_running(mode->device_out))
452 panic("Egress device not up and running!\n");
453 if (!device_up_and_running(mode->device_in))
454 panic("Ingress device not up and running!\n");
456 rx_sock = pf_socket();
457 tx_sock = pf_socket();
459 fmemset(&tx_ring, 0, sizeof(tx_ring));
460 fmemset(&rx_ring, 0, sizeof(rx_ring));
461 fmemset(&rx_poll, 0, sizeof(rx_poll));
462 fmemset(&bpf_ops, 0, sizeof(bpf_ops));
464 ifindex_in = device_ifindex(mode->device_in);
465 size_in = ring_size(mode->device_in, mode->reserve_size);
467 ifindex_out = device_ifindex(mode->device_out);
468 size_out = ring_size(mode->device_out, mode->reserve_size);
470 enable_kernel_bpf_jit_compiler();
471 bpf_parse_rules(mode->filter, &bpf_ops);
472 bpf_attach_to_sock(rx_sock, &bpf_ops);
474 setup_rx_ring_layout(rx_sock, &rx_ring, size_in, mode->jumbo_support);
475 create_rx_ring(rx_sock, &rx_ring);
476 mmap_rx_ring(rx_sock, &rx_ring);
477 alloc_rx_ring_frames(&rx_ring);
478 bind_rx_ring(rx_sock, &rx_ring, ifindex_in);
479 prepare_polling(rx_sock, &rx_poll);
481 set_packet_loss_discard(tx_sock);
482 setup_tx_ring_layout(tx_sock, &tx_ring, size_out, mode->jumbo_support);
483 create_tx_ring(tx_sock, &tx_ring);
484 mmap_tx_ring(tx_sock, &tx_ring);
485 alloc_tx_ring_frames(&tx_ring);
486 bind_tx_ring(tx_sock, &tx_ring, ifindex_out);
488 mt_init_by_seed_time();
489 dissector_init_all(mode->print_mode);
491 if (mode->promiscuous == true) {
492 ifflags = enter_promiscuous_mode(mode->device_in);
493 printf("PROMISC\n");
496 if (mode->kpull)
497 interval = mode->kpull;
499 itimer.it_interval.tv_sec = 0;
500 itimer.it_interval.tv_usec = interval;
501 itimer.it_value.tv_sec = 0;
502 itimer.it_value.tv_usec = interval;
503 setitimer(ITIMER_REAL, &itimer, NULL);
505 printf("BPF:\n");
506 bpf_dump_all(&bpf_ops);
507 printf("MD: RXTX %luus\n\n", interval);
508 printf("Running! Hang up with ^C!\n\n");
510 while (likely(sigint == 0)) {
511 while (user_may_pull_from_rx(rx_ring.frames[it_in].iov_base)) {
512 hdr_in = rx_ring.frames[it_in].iov_base;
513 in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;
514 fcnt++;
515 if (mode->packet_type != PACKET_ALL)
516 if (mode->packet_type != hdr_in->s_ll.sll_pkttype)
517 goto next;
519 hdr_out = tx_ring.frames[it_out].iov_base;
520 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
521 sizeof(struct sockaddr_ll);
523 for (; !user_may_pull_from_tx(tx_ring.frames[it_out].iov_base) &&
524 likely(!sigint);) {
525 if (mode->randomize)
526 next_rnd_slot(&it_out, &tx_ring);
527 else
528 next_slot(&it_out, &tx_ring);
529 hdr_out = tx_ring.frames[it_out].iov_base;
530 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
531 sizeof(struct sockaddr_ll);
534 tpacket_hdr_clone(&hdr_out->tp_h, &hdr_in->tp_h);
535 fmemcpy(out, in, hdr_in->tp_h.tp_len);
537 kernel_may_pull_from_tx(&hdr_out->tp_h);
538 if (mode->randomize)
539 next_rnd_slot(&it_out, &tx_ring);
540 else
541 next_slot(&it_out, &tx_ring);
543 show_frame_hdr(hdr_in, mode->print_mode, RING_MODE_INGRESS);
544 dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
545 mode->link_type);
547 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
548 sigint = 1;
549 break;
551 next:
552 kernel_may_pull_from_rx(&hdr_in->tp_h);
553 next_slot(&it_in, &rx_ring);
555 if (unlikely(sigint == 1))
556 goto out;
559 poll(&rx_poll, 1, -1);
560 poll_error_maybe_die(rx_sock, &rx_poll);
562 out:
563 sock_print_net_stats(rx_sock);
565 dissector_cleanup_all();
566 destroy_tx_ring(tx_sock, &tx_ring);
567 destroy_rx_ring(rx_sock, &rx_ring);
569 if (mode->promiscuous == true)
570 leave_promiscuous_mode(mode->device_in, ifflags);
572 close(tx_sock);
573 close(rx_sock);
576 static void enter_mode_read_pcap(struct mode *mode)
578 int ret, fd, fdo = 0;
579 struct pcap_pkthdr phdr;
580 struct sock_fprog bpf_ops;
581 struct tx_stats stats;
582 struct frame_map fm;
583 uint8_t *out;
584 size_t out_len;
586 if (!pcap_ops[mode->pcap])
587 panic("pcap group not supported!\n");
588 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
589 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
590 if (ret)
591 panic("error reading pcap header!\n");
592 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
593 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
594 if (ret)
595 panic("error prepare reading pcap!\n");
598 fmemset(&fm, 0, sizeof(fm));
599 fmemset(&bpf_ops, 0, sizeof(bpf_ops));
600 fmemset(&stats, 0, sizeof(stats));
602 bpf_parse_rules(mode->filter, &bpf_ops);
603 dissector_init_all(mode->print_mode);
605 out_len = device_mtu("lo");
606 out = xmalloc_aligned(out_len, 64);
608 printf("BPF:\n");
609 bpf_dump_all(&bpf_ops);
610 printf("MD: RD %s\n\n", pcap_ops[mode->pcap]->name);
612 if (mode->device_out) {
613 fdo = open_or_die_m(mode->device_out, O_RDWR | O_CREAT |
614 O_TRUNC | O_LARGEFILE, S_IRUSR | S_IWUSR);
617 while (likely(sigint == 0)) {
618 do {
619 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
620 out, out_len);
621 if (unlikely(ret <= 0))
622 goto out;
623 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
624 pcap_pkthdr_to_tpacket_hdr(&phdr, &fm.tp_h);
626 stats.tx_bytes += fm.tp_h.tp_len;
627 stats.tx_packets++;
629 show_frame_hdr(&fm, mode->print_mode, RING_MODE_EGRESS);
630 dissector_entry_point(out, fm.tp_h.tp_snaplen,
631 mode->link_type);
633 if (mode->device_out) {
634 int i = 0;
635 char bout[80];
636 slprintf(bout, sizeof(bout), "$P%u {\n ", stats.tx_packets);
637 write_or_die(fdo, bout, strlen(bout));
639 while (i < fm.tp_h.tp_snaplen) {
640 slprintf(bout, sizeof(bout), "0x%02x, ", out[i]);
641 write_or_die(fdo, bout, strlen(bout));
642 i++;
643 if (i % 10 == 0) {
644 slprintf(bout, sizeof(bout), "\n", out[i]);
645 write_or_die(fdo, bout, strlen(bout));
646 if (i < fm.tp_h.tp_snaplen) {
647 slprintf(bout, sizeof(bout), " ", out[i]);
648 write_or_die(fdo, bout, strlen(bout));
652 if (i % 10 != 0) {
653 slprintf(bout, sizeof(bout), "\n");
654 write_or_die(fdo, bout, strlen(bout));
656 slprintf(bout, sizeof(bout), "}\n\n");
657 write_or_die(fdo, bout, strlen(bout));
660 if (frame_cnt_max != 0 &&
661 stats.tx_packets >= frame_cnt_max) {
662 sigint = 1;
663 break;
666 out:
667 fflush(stdout);
668 printf("\n");
669 printf("\r%12lu frames outgoing\n", stats.tx_packets);
670 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
672 xfree(out);
673 dissector_cleanup_all();
674 if (pcap_ops[mode->pcap]->prepare_close_pcap)
675 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
676 close(fd);
678 if (mode->device_out)
679 close(fdo);
682 static void finish_multi_pcap_file(struct mode *mode, int fd)
684 pcap_ops[mode->pcap]->fsync_pcap(fd);
685 if (pcap_ops[mode->pcap]->prepare_close_pcap)
686 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
687 close(fd);
689 fmemset(&itimer, 0, sizeof(itimer));
690 setitimer(ITIMER_REAL, &itimer, NULL);
693 static int next_multi_pcap_file(struct mode *mode, int fd)
695 int ret;
696 char tmp[512];
698 pcap_ops[mode->pcap]->fsync_pcap(fd);
699 if (pcap_ops[mode->pcap]->prepare_close_pcap)
700 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
701 close(fd);
703 slprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
705 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
706 S_IRUSR | S_IWUSR);
707 ret = pcap_ops[mode->pcap]->push_file_header(fd);
708 if (ret)
709 panic("error writing pcap header!\n");
710 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
711 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
712 if (ret)
713 panic("error prepare writing pcap!\n");
716 return fd;
719 static int begin_multi_pcap_file(struct mode *mode)
721 int fd, ret;
722 char tmp[512];
724 if (!pcap_ops[mode->pcap])
725 panic("pcap group not supported!\n");
726 if (mode->device_out[strlen(mode->device_out) - 1] == '/')
727 mode->device_out[strlen(mode->device_out) - 1] = 0;
729 slprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
731 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
732 S_IRUSR | S_IWUSR);
733 ret = pcap_ops[mode->pcap]->push_file_header(fd);
734 if (ret)
735 panic("error writing pcap header!\n");
736 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
737 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
738 if (ret)
739 panic("error prepare writing pcap!\n");
742 interval = mode->dump_interval;
743 itimer.it_interval.tv_sec = interval;
744 itimer.it_interval.tv_usec = 0;
745 itimer.it_value.tv_sec = interval;
746 itimer.it_value.tv_usec = 0;
747 setitimer(ITIMER_REAL, &itimer, NULL);
749 return fd;
752 static void finish_single_pcap_file(struct mode *mode, int fd)
754 pcap_ops[mode->pcap]->fsync_pcap(fd);
755 if (pcap_ops[mode->pcap]->prepare_close_pcap)
756 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
757 close(fd);
760 static int begin_single_pcap_file(struct mode *mode)
762 int fd, ret;
764 if (!pcap_ops[mode->pcap])
765 panic("pcap group not supported!\n");
766 fd = open_or_die_m(mode->device_out,
767 O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
768 S_IRUSR | S_IWUSR);
769 ret = pcap_ops[mode->pcap]->push_file_header(fd);
770 if (ret)
771 panic("error writing pcap header!\n");
772 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
773 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
774 if (ret)
775 panic("error prepare writing pcap!\n");
778 return fd;
781 static void enter_mode_rx_only_or_dump(struct mode *mode)
783 int sock, irq, ifindex, fd = 0, ret;
784 unsigned int size, it = 0;
785 unsigned long fcnt = 0;
786 short ifflags = 0;
787 uint8_t *packet;
788 struct ring rx_ring;
789 struct pollfd rx_poll;
790 struct frame_map *hdr;
791 struct sock_fprog bpf_ops;
793 if (!device_up_and_running(mode->device_in))
794 panic("Device not up and running!\n");
796 sock = pf_socket();
798 if (mode->dump) {
799 struct stat tmp;
800 fmemset(&tmp, 0, sizeof(tmp));
801 ret = stat(mode->device_out, &tmp);
802 if (ret < 0) {
803 mode->dump_dir = 0;
804 goto try_file;
806 mode->dump_dir = !!S_ISDIR(tmp.st_mode);
807 if (mode->dump_dir) {
808 fd = begin_multi_pcap_file(mode);
809 } else {
810 try_file:
811 fd = begin_single_pcap_file(mode);
815 fmemset(&rx_ring, 0, sizeof(rx_ring));
816 fmemset(&rx_poll, 0, sizeof(rx_poll));
817 fmemset(&bpf_ops, 0, sizeof(bpf_ops));
819 ifindex = device_ifindex(mode->device_in);
820 size = ring_size(mode->device_in, mode->reserve_size);
822 enable_kernel_bpf_jit_compiler();
823 bpf_parse_rules(mode->filter, &bpf_ops);
824 bpf_attach_to_sock(sock, &bpf_ops);
826 setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
827 create_rx_ring(sock, &rx_ring);
828 mmap_rx_ring(sock, &rx_ring);
829 alloc_rx_ring_frames(&rx_ring);
830 bind_rx_ring(sock, &rx_ring, ifindex);
832 prepare_polling(sock, &rx_poll);
833 dissector_init_all(mode->print_mode);
835 if (mode->cpu >= 0 && ifindex > 0) {
836 irq = device_irq_number(mode->device_in);
837 device_bind_irq_to_cpu(mode->cpu, irq);
838 printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq,
839 mode->cpu);
842 if (mode->promiscuous == true) {
843 ifflags = enter_promiscuous_mode(mode->device_in);
844 printf("PROMISC\n");
847 printf("BPF:\n");
848 bpf_dump_all(&bpf_ops);
849 printf("MD: RX %s\n\n", mode->dump ? pcap_ops[mode->pcap]->name : "");
851 while (likely(sigint == 0)) {
852 while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
853 hdr = rx_ring.frames[it].iov_base;
854 packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
855 fcnt++;
857 if (mode->packet_type != PACKET_ALL)
858 if (mode->packet_type != hdr->s_ll.sll_pkttype)
859 goto next;
860 if (unlikely(rx_ring.layout.tp_frame_size <
861 hdr->tp_h.tp_snaplen)) {
862 fprintf(stderr, "Skipping too large packet! "
863 "No jumbo support selected?\n");
864 fflush(stderr);
865 goto next;
867 if (mode->dump) {
868 struct pcap_pkthdr phdr;
869 tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
870 ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
871 packet, phdr.len);
872 if (unlikely(ret != sizeof(phdr) + phdr.len))
873 panic("Write error to pcap!\n");
876 show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
877 dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
878 mode->link_type);
880 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
881 sigint = 1;
882 break;
884 next:
885 kernel_may_pull_from_rx(&hdr->tp_h);
886 next_slot_prerd(&it, &rx_ring);
888 if (unlikely(sigint == 1))
889 break;
890 if (mode->dump && next_dump) {
891 struct tpacket_stats kstats;
892 socklen_t slen = sizeof(kstats);
893 fmemset(&kstats, 0, sizeof(kstats));
894 getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
895 &kstats, &slen);
896 fd = next_multi_pcap_file(mode, fd);
897 next_dump = false;
898 if (mode->print_mode == FNTTYPE_PRINT_NONE) {
899 printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
900 kstats.tp_drops);
901 fflush(stdout);
906 poll(&rx_poll, 1, -1);
907 poll_error_maybe_die(sock, &rx_poll);
910 if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE))
911 sock_print_net_stats(sock);
912 else {
913 printf("\n\n");
914 fflush(stdout);
916 dissector_cleanup_all();
917 destroy_rx_ring(sock, &rx_ring);
918 if (mode->promiscuous == true)
919 leave_promiscuous_mode(mode->device_in, ifflags);
920 close(sock);
921 if (mode->dump) {
922 if (mode->dump_dir)
923 finish_multi_pcap_file(mode, fd);
924 else
925 finish_single_pcap_file(mode, fd);
929 static void help(void)
931 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
932 VERSION_STRING);
933 printf("http://www.netsniff-ng.org\n\n");
934 printf("Usage: netsniff-ng [options]\n");
935 printf("Options:\n");
936 printf(" -i|-d|--dev|--in <dev|pcap> Input source as netdev or pcap\n");
937 printf(" -o|--out <dev|pcap|dir|txf> Output sink as netdev, pcap, directory, txf file\n");
938 printf(" -f|--filter <bpf-file> Use BPF filter file from bpfc\n");
939 printf(" -t|--type <type> Only handle packets of defined type:\n");
940 printf(" host|broadcast|multicast|others|outgoing\n");
941 printf(" -F|--interval <uint> Dump interval in sec if -o is a directory where\n");
942 printf(" pcap files should be stored (default: 60)\n");
943 printf(" -J|--jumbo-support Support for 64KB Super Jumbo Frames\n");
944 printf(" Default RX/TX slot: 2048Byte\n");
945 printf(" -n|--num <uint> Number of packets until exit\n");
946 printf(" `-- 0 Loop until interrupted (default)\n");
947 printf(" `- n Send n packets and done\n");
948 printf("Options for printing:\n");
949 printf(" -s|--silent Do not print captured packets\n");
950 printf(" -q|--less Print less-verbose packet information\n");
951 printf(" -X|--hex Print packet data in hex format\n");
952 printf(" -l|--ascii Print human-readable packet data\n");
953 printf("Options, advanced:\n");
954 printf(" -r|--rand Randomize packet forwarding order\n");
955 printf(" -M|--no-promisc No promiscuous mode for netdev\n");
956 printf(" -m|--mmap Mmap pcap file i.e., for replaying\n");
957 printf(" Default: scatter-gather I/O\n");
958 printf(" -c|--clrw Use slower read(2)/write(2) I/O\n");
959 printf(" -S|--ring-size <size> Manually set ring size to <size>:\n");
960 printf(" mmap space in KB/MB/GB, e.g. \'10MB\'\n");
961 printf(" -k|--kernel-pull <uint> Kernel pull from user interval in us\n");
962 printf(" Default is 10us where the TX_RING\n");
963 printf(" is populated with payload from uspace\n");
964 printf(" -b|--bind-cpu <cpu> Bind to specific CPU (or CPU-range)\n");
965 printf(" -B|--unbind-cpu <cpu> Forbid to use specific CPU (or CPU-range)\n");
966 printf(" -H|--prio-high Make this high priority process\n");
967 printf(" -Q|--notouch-irq Do not touch IRQ CPU affinity of NIC\n");
968 printf(" -v|--version Show version\n");
969 printf(" -h|--help Guess what?!\n");
970 printf("\n");
971 printf("Examples:\n");
972 printf(" netsniff-ng --in eth0 --out dump.pcap --silent --bind-cpu 0\n");
973 printf(" netsniff-ng --in dump.pcap --mmap --out eth0 --silent --bind-cpu 0\n");
974 printf(" netsniff-ng --in dump.pcap --out dump.txf --silent --bind-cpu 0\n");
975 printf(" netsniff-ng --in eth0 --out eth1 --silent --bind-cpu 0 --type host\n");
976 printf(" netsniff-ng --in eth1 --out /opt/probe1/ -s -m -J --interval 30 -b 0\n");
977 printf(" netsniff-ng --in any --filter http.bpf --jumbo-support --ascii\n");
978 printf("\n");
979 printf("Note:\n");
980 printf(" This tool is targeted for network developers! You should\n");
981 printf(" be aware of what you are doing and what these options above\n");
982 printf(" mean! Use netsniff-ng's bpfc compiler for generating filter files.\n");
983 printf(" Further, netsniff-ng automatically enables the kernel BPF JIT\n");
984 printf(" if present. Txf file output is only possible if the input source\n");
985 printf(" is a pcap file.\n");
986 printf("\n");
987 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
988 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
989 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
990 printf("License: GNU GPL version 2\n");
991 printf("This is free software: you are free to change and redistribute it.\n");
992 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
993 die();
996 static void version(void)
998 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
999 VERSION_STRING);
1000 printf("http://www.netsniff-ng.org\n\n");
1001 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
1002 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
1003 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
1004 printf("License: GNU GPL version 2\n");
1005 printf("This is free software: you are free to change and redistribute it.\n");
1006 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
1007 die();
1010 static void header(void)
1012 printf("%s%s%s\n", colorize_start(bold), PROGNAME_STRING " "
1013 VERSION_STRING, colorize_end());
1016 int main(int argc, char **argv)
1018 int c, i, j, opt_index;
1019 char *ptr;
1020 bool prio_high = false;
1021 struct mode mode;
1022 void (*enter_mode)(struct mode *mode) = NULL;
1024 check_for_root_maybe_die();
1026 fmemset(&mode, 0, sizeof(mode));
1027 mode.link_type = LINKTYPE_EN10MB;
1028 mode.print_mode = FNTTYPE_PRINT_NORM;
1029 mode.cpu = CPU_UNKNOWN;
1030 mode.packet_type = PACKET_ALL;
1031 mode.promiscuous = true;
1032 mode.randomize = false;
1033 mode.pcap = PCAP_OPS_SG;
1034 mode.dump_interval = DUMP_INTERVAL;
1036 while ((c = getopt_long(argc, argv, short_options, long_options,
1037 &opt_index)) != EOF) {
1038 switch (c) {
1039 case 'd':
1040 case 'i':
1041 mode.device_in = xstrdup(optarg);
1042 break;
1043 case 'o':
1044 mode.device_out = xstrdup(optarg);
1045 break;
1046 case 'r':
1047 mode.randomize = true;
1048 break;
1049 case 'J':
1050 mode.jumbo_support = 1;
1051 break;
1052 case 'f':
1053 mode.filter = xstrdup(optarg);
1054 break;
1055 case 'M':
1056 mode.promiscuous = false;
1057 break;
1058 case 't':
1059 if (!strncmp(optarg, "host", strlen("host")))
1060 mode.packet_type = PACKET_HOST;
1061 else if (!strncmp(optarg, "broadcast", strlen("broadcast")))
1062 mode.packet_type = PACKET_BROADCAST;
1063 else if (!strncmp(optarg, "multicast", strlen("multicast")))
1064 mode.packet_type = PACKET_MULTICAST;
1065 else if (!strncmp(optarg, "others", strlen("others")))
1066 mode.packet_type = PACKET_OTHERHOST;
1067 else if (!strncmp(optarg, "outgoing", strlen("outgoing")))
1068 mode.packet_type = PACKET_OUTGOING;
1069 else
1070 mode.packet_type = PACKET_ALL;
1071 break;
1072 case 'S':
1073 ptr = optarg;
1074 mode.reserve_size = 0;
1076 for (j = i = strlen(optarg); i > 0; --i) {
1077 if (!isdigit(optarg[j - i]))
1078 break;
1079 ptr++;
1082 if (!strncmp(ptr, "KB", strlen("KB")))
1083 mode.reserve_size = 1 << 10;
1084 else if (!strncmp(ptr, "MB", strlen("MB")))
1085 mode.reserve_size = 1 << 20;
1086 else if (!strncmp(ptr, "GB", strlen("GB")))
1087 mode.reserve_size = 1 << 30;
1088 else
1089 panic("Syntax error in ring size param!\n");
1091 *ptr = 0;
1092 mode.reserve_size *= atoi(optarg);
1093 break;
1094 case 'b':
1095 set_cpu_affinity(optarg, 0);
1096 if (mode.cpu != CPU_NOTOUCH)
1097 mode.cpu = atoi(optarg);
1098 break;
1099 case 'B':
1100 set_cpu_affinity(optarg, 1);
1101 break;
1102 case 'H':
1103 prio_high = true;
1104 break;
1105 case 'c':
1106 mode.pcap = PCAP_OPS_RW;
1107 break;
1108 case 'm':
1109 mode.pcap = PCAP_OPS_MMAP;
1110 break;
1111 case 'Q':
1112 mode.cpu = CPU_NOTOUCH;
1113 break;
1114 case 's':
1115 mode.print_mode = FNTTYPE_PRINT_NONE;
1116 break;
1117 case 'q':
1118 mode.print_mode = FNTTYPE_PRINT_LESS;
1119 break;
1120 case 'k':
1121 mode.kpull = (unsigned long) atol(optarg);
1122 break;
1123 case 'n':
1124 frame_cnt_max = (unsigned long) atol(optarg);
1125 break;
1126 case 'F':
1127 mode.dump_interval = (unsigned long) atol(optarg);
1128 break;
1129 case 'v':
1130 version();
1131 break;
1132 case 'h':
1133 help();
1134 break;
1135 case '?':
1136 switch (optopt) {
1137 case 'd':
1138 case 'i':
1139 case 'o':
1140 case 'f':
1141 case 't':
1142 case 'F':
1143 case 'n':
1144 case 'S':
1145 case 'b':
1146 case 'k':
1147 case 'B':
1148 case 'e':
1149 panic("Option -%c requires an argument!\n",
1150 optopt);
1151 default:
1152 if (isprint(optopt))
1153 whine("Unknown option character "
1154 "`0x%X\'!\n", optopt);
1155 die();
1157 default:
1158 break;
1162 if (!mode.device_in)
1163 mode.device_in = xstrdup("any");
1165 register_signal(SIGINT, signal_handler);
1166 register_signal(SIGHUP, signal_handler);
1168 init_pcap(mode.jumbo_support);
1169 tprintf_init();
1170 header();
1172 if (prio_high == true) {
1173 set_proc_prio(get_default_proc_prio());
1174 set_sched_status(get_default_sched_policy(),
1175 get_default_sched_prio());
1178 if (mode.device_in && (device_mtu(mode.device_in) ||
1179 !strncmp("any", mode.device_in, strlen(mode.device_in)))) {
1180 if (!mode.device_out) {
1181 mode.dump = 0;
1182 enter_mode = enter_mode_rx_only_or_dump;
1183 } else if (device_mtu(mode.device_out)) {
1184 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1185 enter_mode = enter_mode_rx_to_tx;
1186 } else {
1187 mode.dump = 1;
1188 register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
1189 enter_mode = enter_mode_rx_only_or_dump;
1191 } else {
1192 if (mode.device_out && device_mtu(mode.device_out)) {
1193 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1194 enter_mode = enter_mode_pcap_to_tx;
1195 } else {
1196 enter_mode = enter_mode_read_pcap;
1200 if (!enter_mode)
1201 panic("Selection not supported!\n");
1202 enter_mode(&mode);
1204 tprintf_cleanup();
1205 cleanup_pcap();
1207 if (mode.device_in)
1208 xfree(mode.device_in);
1209 if (mode.device_out)
1210 xfree(mode.device_out);
1211 return 0;