xio: removed misc.{c,h}, placed function into xio.c
[netsniff-ng.git] / src / netsniff-ng.c
blob1eb36f7306f27e039b1a45eedd66a1b9e4b6e27c
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'.
23 #define _GNU_SOURCE
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <signal.h>
27 #include <getopt.h>
28 #include <ctype.h>
29 #include <time.h>
30 #include <string.h>
31 #include <sys/socket.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/time.h>
35 #include <unistd.h>
36 #include <stdbool.h>
37 #include <pthread.h>
38 #include <fcntl.h>
40 #include "ring_rx.h"
41 #include "ring_tx.h"
42 #include "netdev.h"
43 #include "compiler.h"
44 #include "pcap.h"
45 #include "poll.h"
46 #include "bpf.h"
47 #include "signals.h"
48 #include "xio.h"
49 #include "die.h"
50 #include "tty.h"
51 #include "opt_memcpy.h"
52 #include "tprintf.h"
53 #include "dissector.h"
54 #include "xmalloc.h"
55 #include "psched.h"
56 #include "mtrand.h"
58 #define CPU_UNKNOWN -1
59 #define CPU_NOTOUCH -2
60 #define PACKET_ALL -1
61 #define DUMP_INTERVAL 60
63 struct mode {
64 char *device_in;
65 char *device_out;
66 char *filter;
67 int cpu;
68 int dump;
69 int link_type;
70 int print_mode;
71 unsigned int reserve_size;
72 int packet_type;
73 bool randomize;
74 bool promiscuous;
75 enum pcap_ops_groups pcap;
76 unsigned long kpull;
77 int jumbo_support;
78 int dump_dir;
79 unsigned long dump_interval;
82 struct tx_stats {
83 unsigned long tx_bytes;
84 unsigned long tx_packets;
87 sig_atomic_t sigint = 0;
89 static int tx_sock;
90 static unsigned long frame_cnt_max = 0;
91 static unsigned long interval = TX_KERNEL_PULL_INT;
92 static struct itimerval itimer;
93 static volatile bool next_dump = false;
95 static const char *short_options = "d:i:o:rf:MJt:S:k:n:b:B:HQmcsqlxCXNvhF:";
97 static struct option long_options[] = {
98 {"dev", required_argument, 0, 'd'},
99 {"in", required_argument, 0, 'i'},
100 {"out", required_argument, 0, 'o'},
101 {"rand", no_argument, 0, 'r'},
102 {"mmap", no_argument, 0, 'm'},
103 {"clrw", no_argument, 0, 'c'},
104 {"jumbo-support", no_argument, 0, 'J'},
105 {"filter", required_argument, 0, 'f'},
106 {"no-promisc", no_argument, 0, 'M'},
107 {"num", required_argument, 0, 'n'},
108 {"type", required_argument, 0, 't'},
109 {"interval", required_argument, 0, 'F'},
110 {"ring-size", required_argument, 0, 'S'},
111 {"kernel-pull", required_argument, 0, 'k'},
112 {"bind-cpu", required_argument, 0, 'b'},
113 {"unbind-cpu", required_argument, 0, 'B'},
114 {"prio-high", no_argument, 0, 'H'},
115 {"notouch-irq", no_argument, 0, 'Q'},
116 {"silent", no_argument, 0, 's'},
117 {"less", no_argument, 0, 'q'},
118 {"payload", no_argument, 0, 'l'},
119 {"payload-hex", no_argument, 0, 'x'},
120 {"c-style", no_argument, 0, 'C'},
121 {"all-hex", no_argument, 0, 'X'},
122 {"no-payload", no_argument, 0, 'N'},
123 {"version", no_argument, 0, 'v'},
124 {"help", no_argument, 0, 'h'},
125 {0, 0, 0, 0}
128 static void signal_handler(int number)
130 switch (number) {
131 case SIGINT:
132 sigint = 1;
133 break;
134 case SIGHUP:
135 break;
136 default:
137 break;
141 static void timer_elapsed(int number)
143 itimer.it_interval.tv_sec = 0;
144 itimer.it_interval.tv_usec = interval;
145 itimer.it_value.tv_sec = 0;
146 itimer.it_value.tv_usec = interval;
148 pull_and_flush_tx_ring(tx_sock);
149 setitimer(ITIMER_REAL, &itimer, NULL);
152 static void timer_next_dump(int number)
154 itimer.it_interval.tv_sec = interval;
155 itimer.it_interval.tv_usec = 0;
156 itimer.it_value.tv_sec = interval;
157 itimer.it_value.tv_usec = 0;
159 next_dump = true;
160 setitimer(ITIMER_REAL, &itimer, NULL);
163 static void enter_mode_pcap_to_tx(struct mode *mode)
165 int irq, ifindex, fd = 0, ret;
166 unsigned int size, it = 0;
167 struct ring tx_ring;
168 struct frame_map *hdr;
169 struct sock_fprog bpf_ops;
170 struct tx_stats stats;
171 uint8_t *out = NULL;
173 if (!device_up_and_running(mode->device_out))
174 panic("Device not up and running!\n");
176 set_memcpy();
177 tx_sock = pf_socket();
179 if (!pcap_ops[mode->pcap])
180 panic("pcap group not supported!\n");
181 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
182 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
183 if (ret)
184 panic("error reading pcap header!\n");
185 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
186 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
187 if (ret)
188 panic("error prepare reading pcap!\n");
191 memset(&tx_ring, 0, sizeof(tx_ring));
192 memset(&bpf_ops, 0, sizeof(bpf_ops));
193 memset(&stats, 0, sizeof(stats));
195 ifindex = device_ifindex(mode->device_out);
196 size = ring_size(mode->device_out, mode->reserve_size);
198 bpf_parse_rules(mode->filter, &bpf_ops);
200 set_packet_loss_discard(tx_sock);
201 setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
202 create_tx_ring(tx_sock, &tx_ring);
203 mmap_tx_ring(tx_sock, &tx_ring);
204 alloc_tx_ring_frames(&tx_ring);
205 bind_tx_ring(tx_sock, &tx_ring, ifindex);
207 dissector_init_all(mode->print_mode);
209 if (mode->cpu >= 0 && ifindex > 0) {
210 irq = device_irq_number(mode->device_out);
211 device_bind_irq_to_cpu(mode->cpu, irq);
212 printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq,
213 mode->cpu);
216 if (mode->kpull)
217 interval = mode->kpull;
219 itimer.it_interval.tv_sec = 0;
220 itimer.it_interval.tv_usec = interval;
221 itimer.it_value.tv_sec = 0;
222 itimer.it_value.tv_usec = interval;
223 setitimer(ITIMER_REAL, &itimer, NULL);
225 printf("BPF:\n");
226 bpf_dump_all(&bpf_ops);
227 printf("MD: TX %luus %s\n\n", interval, pcap_ops[mode->pcap]->name);
229 while (likely(sigint == 0)) {
230 while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
231 struct pcap_pkthdr phdr;
232 hdr = tx_ring.frames[it].iov_base;
233 /* Kernel assumes: data = ph.raw + po->tp_hdrlen -
234 * sizeof(struct sockaddr_ll); */
235 out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
236 sizeof(struct sockaddr_ll);
238 do {
239 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
240 out, ring_frame_size(&tx_ring));
241 if (unlikely(ret <= 0))
242 goto out;
243 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
244 pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);
246 stats.tx_bytes += hdr->tp_h.tp_len;;
247 stats.tx_packets++;
249 show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
250 dissector_entry_point(out, hdr->tp_h.tp_snaplen,
251 mode->link_type);
253 kernel_may_pull_from_tx(&hdr->tp_h);
254 next_slot(&it, &tx_ring);
256 if (unlikely(sigint == 1))
257 break;
258 if (frame_cnt_max != 0 &&
259 stats.tx_packets >= frame_cnt_max) {
260 sigint = 1;
261 break;
265 out:
266 fflush(stdout);
267 printf("\n");
268 printf("\r%12lu frames outgoing\n", stats.tx_packets);
269 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
271 dissector_cleanup_all();
272 destroy_tx_ring(tx_sock, &tx_ring);
274 close(tx_sock);
275 if (pcap_ops[mode->pcap]->prepare_close_pcap)
276 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
277 close(fd);
280 /* If netsniff-ngs in device is on a tap, it can efficiently filter out
281 * some interesting packets and give them to the out device for testing
282 * or debugging for instance. */
283 static void enter_mode_rx_to_tx(struct mode *mode)
285 int rx_sock, ifindex_in, ifindex_out;
286 unsigned int size_in, size_out, it_in = 0, it_out = 0;
287 unsigned long fcnt = 0;
288 uint8_t *in, *out;
289 short ifflags = 0;
290 struct frame_map *hdr_in, *hdr_out;
291 struct ring tx_ring;
292 struct ring rx_ring;
293 struct pollfd rx_poll;
294 struct sock_fprog bpf_ops;
296 if (!strncmp(mode->device_in, mode->device_out,
297 strlen(mode->device_in)))
298 panic("Ingress/egress devices must be different!\n");
299 if (!device_up_and_running(mode->device_out))
300 panic("Egress device not up and running!\n");
301 if (!device_up_and_running(mode->device_in))
302 panic("Ingress device not up and running!\n");
304 set_memcpy();
305 rx_sock = pf_socket();
306 tx_sock = pf_socket();
308 memset(&tx_ring, 0, sizeof(tx_ring));
309 memset(&rx_ring, 0, sizeof(rx_ring));
310 memset(&rx_poll, 0, sizeof(rx_poll));
311 memset(&bpf_ops, 0, sizeof(bpf_ops));
313 ifindex_in = device_ifindex(mode->device_in);
314 size_in = ring_size(mode->device_in, mode->reserve_size);
316 ifindex_out = device_ifindex(mode->device_out);
317 size_out = ring_size(mode->device_out, mode->reserve_size);
319 enable_kernel_bpf_jit_compiler();
320 bpf_parse_rules(mode->filter, &bpf_ops);
321 bpf_attach_to_sock(rx_sock, &bpf_ops);
323 setup_rx_ring_layout(rx_sock, &rx_ring, size_in, mode->jumbo_support);
324 create_rx_ring(rx_sock, &rx_ring);
325 mmap_rx_ring(rx_sock, &rx_ring);
326 alloc_rx_ring_frames(&rx_ring);
327 bind_rx_ring(rx_sock, &rx_ring, ifindex_in);
328 prepare_polling(rx_sock, &rx_poll);
330 set_packet_loss_discard(tx_sock);
331 setup_tx_ring_layout(tx_sock, &tx_ring, size_out, mode->jumbo_support);
332 create_tx_ring(tx_sock, &tx_ring);
333 mmap_tx_ring(tx_sock, &tx_ring);
334 alloc_tx_ring_frames(&tx_ring);
335 bind_tx_ring(tx_sock, &tx_ring, ifindex_out);
337 mt_init_by_seed_time();
338 dissector_init_all(mode->print_mode);
340 if (mode->promiscuous == true) {
341 ifflags = enter_promiscuous_mode(mode->device_in);
342 printf("PROMISC\n");
345 if (mode->kpull)
346 interval = mode->kpull;
348 itimer.it_interval.tv_sec = 0;
349 itimer.it_interval.tv_usec = interval;
350 itimer.it_value.tv_sec = 0;
351 itimer.it_value.tv_usec = interval;
352 setitimer(ITIMER_REAL, &itimer, NULL);
354 printf("BPF:\n");
355 bpf_dump_all(&bpf_ops);
356 printf("MD: RXTX %luus\n\n", interval);
357 printf("Running! Hang up with ^C!\n\n");
359 while (likely(sigint == 0)) {
360 while (user_may_pull_from_rx(rx_ring.frames[it_in].iov_base)) {
361 hdr_in = rx_ring.frames[it_in].iov_base;
362 in = ((uint8_t *) hdr_in) + hdr_in->tp_h.tp_mac;
363 fcnt++;
364 if (mode->packet_type != PACKET_ALL)
365 if (mode->packet_type != hdr_in->s_ll.sll_pkttype)
366 goto next;
368 hdr_out = tx_ring.frames[it_out].iov_base;
369 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
370 sizeof(struct sockaddr_ll);
372 /* If we cannot pull, look for a different slot. */
373 for (; !user_may_pull_from_tx(tx_ring.frames[it_out].iov_base) &&
374 likely(!sigint);) {
375 if (mode->randomize)
376 next_rnd_slot(&it_out, &tx_ring);
377 else
378 next_slot(&it_out, &tx_ring);
379 hdr_out = tx_ring.frames[it_out].iov_base;
380 out = ((uint8_t *) hdr_out) + TPACKET_HDRLEN -
381 sizeof(struct sockaddr_ll);
384 tpacket_hdr_clone(&hdr_out->tp_h, &hdr_in->tp_h);
385 __memcpy(out, in, hdr_in->tp_h.tp_len);
387 kernel_may_pull_from_tx(&hdr_out->tp_h);
388 if (mode->randomize)
389 next_rnd_slot(&it_out, &tx_ring);
390 else
391 next_slot(&it_out, &tx_ring);
393 /* Should actually be avoided ... */
394 show_frame_hdr(hdr_in, mode->print_mode, RING_MODE_INGRESS);
395 dissector_entry_point(in, hdr_in->tp_h.tp_snaplen,
396 mode->link_type);
398 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
399 sigint = 1;
400 break;
402 next:
403 kernel_may_pull_from_rx(&hdr_in->tp_h);
404 next_slot(&it_in, &rx_ring);
406 if (unlikely(sigint == 1))
407 goto out;
410 poll(&rx_poll, 1, -1);
411 poll_error_maybe_die(rx_sock, &rx_poll);
413 out:
414 sock_print_net_stats(rx_sock);
416 dissector_cleanup_all();
417 destroy_tx_ring(tx_sock, &tx_ring);
418 destroy_rx_ring(rx_sock, &rx_ring);
420 if (mode->promiscuous == true)
421 leave_promiscuous_mode(mode->device_in, ifflags);
423 close(tx_sock);
424 close(rx_sock);
427 static void enter_mode_read_pcap(struct mode *mode)
429 int ret, fd;
430 struct pcap_pkthdr phdr;
431 struct sock_fprog bpf_ops;
432 struct tx_stats stats;
433 struct frame_map fm;
434 uint8_t *out;
435 size_t out_len;
437 if (!pcap_ops[mode->pcap])
438 panic("pcap group not supported!\n");
439 fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
440 ret = pcap_ops[mode->pcap]->pull_file_header(fd);
441 if (ret)
442 panic("error reading pcap header!\n");
443 if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
444 ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
445 if (ret)
446 panic("error prepare reading pcap!\n");
449 memset(&fm, 0, sizeof(fm));
450 memset(&bpf_ops, 0, sizeof(bpf_ops));
451 memset(&stats, 0, sizeof(stats));
453 bpf_parse_rules(mode->filter, &bpf_ops);
454 dissector_init_all(mode->print_mode);
456 out_len = device_mtu("lo");
457 out = xmalloc_aligned(out_len, 64);
459 printf("BPF:\n");
460 bpf_dump_all(&bpf_ops);
461 printf("MD: RD %s\n\n", pcap_ops[mode->pcap]->name);
463 while (likely(sigint == 0)) {
464 do {
465 ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
466 out, out_len);
467 if (unlikely(ret <= 0))
468 goto out;
469 } while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
470 pcap_pkthdr_to_tpacket_hdr(&phdr, &fm.tp_h);
472 stats.tx_bytes += fm.tp_h.tp_len;;
473 stats.tx_packets++;
475 show_frame_hdr(&fm, mode->print_mode, RING_MODE_EGRESS);
476 dissector_entry_point(out, fm.tp_h.tp_snaplen,
477 mode->link_type);
479 if (frame_cnt_max != 0 &&
480 stats.tx_packets >= frame_cnt_max) {
481 sigint = 1;
482 break;
485 out:
486 fflush(stdout);
487 printf("\n");
488 printf("\r%12lu frames outgoing\n", stats.tx_packets);
489 printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
491 xfree(out);
492 dissector_cleanup_all();
493 if (pcap_ops[mode->pcap]->prepare_close_pcap)
494 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
495 close(fd);
498 static void finish_multi_pcap_file(struct mode *mode, int fd)
500 pcap_ops[mode->pcap]->fsync_pcap(fd);
501 if (pcap_ops[mode->pcap]->prepare_close_pcap)
502 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
503 close(fd);
505 memset(&itimer, 0, sizeof(itimer));
506 setitimer(ITIMER_REAL, &itimer, NULL);
509 static int next_multi_pcap_file(struct mode *mode, int fd)
511 int ret;
512 char tmp[512];
514 pcap_ops[mode->pcap]->fsync_pcap(fd);
515 if (pcap_ops[mode->pcap]->prepare_close_pcap)
516 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
517 close(fd);
519 memset(&tmp, 0, sizeof(tmp));
520 snprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
521 tmp[sizeof(tmp) - 1] = 0;
523 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
524 S_IRUSR | S_IWUSR);
525 ret = pcap_ops[mode->pcap]->push_file_header(fd);
526 if (ret)
527 panic("error writing pcap header!\n");
528 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
529 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
530 if (ret)
531 panic("error prepare writing pcap!\n");
534 return fd;
537 static int begin_multi_pcap_file(struct mode *mode)
539 int fd, ret;
540 char tmp[512];
542 if (!pcap_ops[mode->pcap])
543 panic("pcap group not supported!\n");
544 if (mode->device_out[strlen(mode->device_out) - 1] == '/')
545 mode->device_out[strlen(mode->device_out) - 1] = 0;
547 memset(&tmp, 0, sizeof(tmp));
548 snprintf(tmp, sizeof(tmp), "%s/%lu.pcap", mode->device_out, time(0));
549 tmp[sizeof(tmp) - 1] = 0;
551 fd = open_or_die_m(tmp, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
552 S_IRUSR | S_IWUSR);
553 ret = pcap_ops[mode->pcap]->push_file_header(fd);
554 if (ret)
555 panic("error writing pcap header!\n");
556 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
557 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
558 if (ret)
559 panic("error prepare writing pcap!\n");
562 interval = mode->dump_interval;
563 itimer.it_interval.tv_sec = interval;
564 itimer.it_interval.tv_usec = 0;
565 itimer.it_value.tv_sec = interval;
566 itimer.it_value.tv_usec = 0;
567 setitimer(ITIMER_REAL, &itimer, NULL);
569 return fd;
572 static void finish_single_pcap_file(struct mode *mode, int fd)
574 pcap_ops[mode->pcap]->fsync_pcap(fd);
575 if (pcap_ops[mode->pcap]->prepare_close_pcap)
576 pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_WRITE);
577 close(fd);
580 static int begin_single_pcap_file(struct mode *mode)
582 int fd, ret;
584 if (!pcap_ops[mode->pcap])
585 panic("pcap group not supported!\n");
586 fd = open_or_die_m(mode->device_out,
587 O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE,
588 S_IRUSR | S_IWUSR);
589 ret = pcap_ops[mode->pcap]->push_file_header(fd);
590 if (ret)
591 panic("error writing pcap header!\n");
592 if (pcap_ops[mode->pcap]->prepare_writing_pcap) {
593 ret = pcap_ops[mode->pcap]->prepare_writing_pcap(fd);
594 if (ret)
595 panic("error prepare writing pcap!\n");
598 return fd;
601 static void enter_mode_rx_only_or_dump(struct mode *mode)
603 int sock, irq, ifindex, fd = 0, ret;
604 unsigned int size, it = 0;
605 unsigned long fcnt = 0;
606 short ifflags = 0;
607 uint8_t *packet;
608 struct ring rx_ring;
609 struct pollfd rx_poll;
610 struct frame_map *hdr;
611 struct sock_fprog bpf_ops;
613 if (!device_up_and_running(mode->device_in))
614 panic("Device not up and running!\n");
616 set_memcpy();
617 sock = pf_socket();
619 if (mode->dump) {
620 struct stat tmp;
621 memset(&tmp, 0, sizeof(tmp));
622 ret = stat(mode->device_out, &tmp);
623 if (ret < 0) {
624 mode->dump_dir = 0;
625 goto try_file;
627 mode->dump_dir = !!S_ISDIR(tmp.st_mode);
628 if (mode->dump_dir) {
629 fd = begin_multi_pcap_file(mode);
630 } else {
631 try_file:
632 fd = begin_single_pcap_file(mode);
636 memset(&rx_ring, 0, sizeof(rx_ring));
637 memset(&rx_poll, 0, sizeof(rx_poll));
638 memset(&bpf_ops, 0, sizeof(bpf_ops));
640 ifindex = device_ifindex(mode->device_in);
641 size = ring_size(mode->device_in, mode->reserve_size);
643 enable_kernel_bpf_jit_compiler();
644 bpf_parse_rules(mode->filter, &bpf_ops);
645 bpf_attach_to_sock(sock, &bpf_ops);
647 setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
648 create_rx_ring(sock, &rx_ring);
649 mmap_rx_ring(sock, &rx_ring);
650 alloc_rx_ring_frames(&rx_ring);
651 bind_rx_ring(sock, &rx_ring, ifindex);
653 prepare_polling(sock, &rx_poll);
654 dissector_init_all(mode->print_mode);
656 if (mode->cpu >= 0 && ifindex > 0) {
657 irq = device_irq_number(mode->device_in);
658 device_bind_irq_to_cpu(mode->cpu, irq);
659 printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq,
660 mode->cpu);
663 if (mode->promiscuous == true) {
664 ifflags = enter_promiscuous_mode(mode->device_in);
665 printf("PROMISC\n");
668 printf("BPF:\n");
669 bpf_dump_all(&bpf_ops);
670 printf("MD: RX %s\n\n", mode->dump ? pcap_ops[mode->pcap]->name : "");
672 while (likely(sigint == 0)) {
673 while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
674 hdr = rx_ring.frames[it].iov_base;
675 packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
676 fcnt++;
678 if (mode->packet_type != PACKET_ALL)
679 if (mode->packet_type != hdr->s_ll.sll_pkttype)
680 goto next;
681 if (unlikely(rx_ring.layout.tp_frame_size <
682 hdr->tp_h.tp_snaplen)) {
683 fprintf(stderr, "Skipping too large packet! "
684 "No jumbo support selected?\n");
685 fflush(stderr);
686 goto next;
688 if (mode->dump) {
689 struct pcap_pkthdr phdr;
690 tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
691 ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
692 packet, phdr.len);
693 if (unlikely(ret != sizeof(phdr) + phdr.len))
694 panic("Write error to pcap!\n");
697 show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
698 dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
699 mode->link_type);
701 if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
702 sigint = 1;
703 break;
705 next:
706 kernel_may_pull_from_rx(&hdr->tp_h);
707 next_slot(&it, &rx_ring);
709 if (unlikely(sigint == 1))
710 break;
711 if (mode->dump && next_dump) {
712 struct tpacket_stats kstats;
713 socklen_t slen = sizeof(kstats);
714 memset(&kstats, 0, sizeof(kstats));
715 getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
716 &kstats, &slen);
717 fd = next_multi_pcap_file(mode, fd);
718 next_dump = false;
719 if (mode->print_mode == FNTTYPE_PRINT_NONE) {
720 printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
721 kstats.tp_drops);
722 fflush(stdout);
727 poll(&rx_poll, 1, -1);
728 poll_error_maybe_die(sock, &rx_poll);
731 if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE))
732 sock_print_net_stats(sock);
733 else {
734 printf("\n\n");
735 fflush(stdout);
737 dissector_cleanup_all();
738 destroy_rx_ring(sock, &rx_ring);
739 if (mode->promiscuous == true)
740 leave_promiscuous_mode(mode->device_in, ifflags);
741 close(sock);
742 if (mode->dump) {
743 if (mode->dump_dir)
744 finish_multi_pcap_file(mode, fd);
745 else
746 finish_single_pcap_file(mode, fd);
750 static void help(void)
752 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
753 VERSION_STRING);
754 printf("http://www.netsniff-ng.org\n\n");
755 printf("Usage: netsniff-ng [options]\n");
756 printf("Options:\n");
757 printf(" -i|-d|--dev|--in <dev|pcap> Input source as netdev or pcap\n");
758 printf(" -o|--out <dev|pcap|dir> Output sink as netdev or pcap or directory\n");
759 printf(" -f|--filter <bpf-file> Use BPF filter file from bpfc\n");
760 printf(" -t|--type <type> Only handle packets of defined type:\n");
761 printf(" host|broadcast|multicast|others|outgoing\n");
762 printf(" -F|--interval <int> Dump interval in sec if -o is a directory where\n");
763 printf(" pcap files should be stored (default: 60)\n");
764 printf(" -s|--silent Do not print captured packets\n");
765 printf(" -J|--jumbo-support Support for 64KB Super Jumbo Frames\n");
766 printf(" Default RX/TX slot: 2048Byte\n");
767 printf(" -n|--num <uint> Number of packets until exit\n");
768 printf(" `-- 0 Loop until interrupt (default)\n");
769 printf(" `- n Send n packets and done\n");
770 printf(" -r|--rand Randomize packet forwarding order\n");
771 printf(" -M|--no-promisc No promiscuous mode for netdev\n");
772 printf(" -m|--mmap Mmap pcap file i.e., for replaying\n");
773 printf(" Default: scatter/gather I/O\n");
774 printf(" -c|--clrw Instead s/g I/O use slower read/write I/O\n");
775 printf(" -S|--ring-size <size> Manually set ring size to <size>:\n");
776 printf(" mmap space in KB/MB/GB, e.g. \'10MB\'\n");
777 printf(" -k|--kernel-pull <int> Kernel pull from user interval in us\n");
778 printf(" Default is 10us where the TX_RING\n");
779 printf(" is populated with payload from uspace\n");
780 printf(" -b|--bind-cpu <cpu> Bind to specific CPU (or CPU-range)\n");
781 printf(" -B|--unbind-cpu <cpu> Forbid to use specific CPU (or CPU-range)\n");
782 printf(" -H|--prio-high Make this high priority process\n");
783 printf(" -Q|--notouch-irq Do not touch IRQ CPU affinity of NIC\n");
784 printf(" -q|--less Print less-verbose packet information\n");
785 printf(" -l|--payload Only print human-readable payload\n");
786 printf(" -x|--payload-hex Only print payload in hex format\n");
787 printf(" -C|--c-style Print full packet in trafgen/C style hex format\n");
788 printf(" -X|--all-hex Print packets in hex format\n");
789 printf(" -N|--no-payload Only print packet header\n");
790 printf(" -v|--version Show version\n");
791 printf(" -h|--help Guess what?!\n");
792 printf("\n");
793 printf("Examples:\n");
794 printf(" netsniff-ng --in eth0 --out dump.pcap --silent --bind-cpu 0\n");
795 printf(" netsniff-ng --in dump.pcap --mmap --out eth0 --silent --bind-cpu 0\n");
796 printf(" netsniff-ng --in any --filter icmp.bpf --all-hex\n");
797 printf(" netsniff-ng --in eth0 --out eth1 --silent --bind-cpu 0 --type host --filter http.bpf\n");
798 printf(" netsniff-ng --in any --filter http.bpf --payload\n");
799 printf(" netsniff-ng --in wlan0 --out /opt/probe1/ --silent --interval 30 --bind-cpu 0 --jumbo-support\n");
800 printf("\n");
801 printf("Note:\n");
802 printf(" This tool is targeted for network developers! You should\n");
803 printf(" be aware of what you are doing and what these options above\n");
804 printf(" mean! Use netsniff-ng's bpfc compiler for generating filter files.\n");
805 printf(" Further, netsniff-ng automatically enables the kernel BPF JIT\n");
806 printf(" if present.\n");
807 printf("\n");
808 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
809 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
810 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
811 printf("License: GNU GPL version 2\n");
812 printf("This is free software: you are free to change and redistribute it.\n");
813 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
814 die();
817 static void version(void)
819 printf("\n%s %s, the packet sniffing beast\n", PROGNAME_STRING,
820 VERSION_STRING);
821 printf("http://www.netsniff-ng.org\n\n");
822 printf("Please report bugs to <bugs@netsniff-ng.org>\n");
823 printf("Copyright (C) 2009-2012 Daniel Borkmann <daniel@netsniff-ng.org>\n");
824 printf("Copyright (C) 2009-2012 Emmanuel Roullit <emmanuel@netsniff-ng.org>\n");
825 printf("License: GNU GPL version 2\n");
826 printf("This is free software: you are free to change and redistribute it.\n");
827 printf("There is NO WARRANTY, to the extent permitted by law.\n\n");
828 die();
831 static void header(void)
833 printf("%s%s%s\n", colorize_start(bold), PROGNAME_STRING " "
834 VERSION_STRING, colorize_end());
837 int main(int argc, char **argv)
839 int c, i, j, opt_index;
840 char *ptr;
841 bool prio_high = false;
842 struct mode mode;
843 void (*enter_mode)(struct mode *mode) = NULL;
845 check_for_root_maybe_die();
847 memset(&mode, 0, sizeof(mode));
848 mode.link_type = LINKTYPE_EN10MB;
849 mode.print_mode = FNTTYPE_PRINT_NORM;
850 mode.cpu = CPU_UNKNOWN;
851 mode.packet_type = PACKET_ALL;
852 mode.promiscuous = true;
853 mode.randomize = false;
854 mode.pcap = PCAP_OPS_SG;
855 mode.dump_interval = DUMP_INTERVAL;
857 while ((c = getopt_long(argc, argv, short_options, long_options,
858 &opt_index)) != EOF) {
859 switch (c) {
860 case 'd':
861 case 'i':
862 mode.device_in = xstrdup(optarg);
863 break;
864 case 'o':
865 mode.device_out = xstrdup(optarg);
866 break;
867 case 'r':
868 mode.randomize = true;
869 break;
870 case 'J':
871 mode.jumbo_support = 1;
872 break;
873 case 'f':
874 mode.filter = xstrdup(optarg);
875 break;
876 case 'M':
877 mode.promiscuous = false;
878 break;
879 case 't':
880 if (!strncmp(optarg, "host", strlen("host")))
881 mode.packet_type = PACKET_HOST;
882 else if (!strncmp(optarg, "broadcast", strlen("broadcast")))
883 mode.packet_type = PACKET_BROADCAST;
884 else if (!strncmp(optarg, "multicast", strlen("multicast")))
885 mode.packet_type = PACKET_MULTICAST;
886 else if (!strncmp(optarg, "others", strlen("others")))
887 mode.packet_type = PACKET_OTHERHOST;
888 else if (!strncmp(optarg, "outgoing", strlen("outgoing")))
889 mode.packet_type = PACKET_OUTGOING;
890 else
891 mode.packet_type = PACKET_ALL;
892 break;
893 case 'S':
894 ptr = optarg;
895 mode.reserve_size = 0;
897 for (j = i = strlen(optarg); i > 0; --i) {
898 if (!isdigit(optarg[j - i]))
899 break;
900 ptr++;
903 if (!strncmp(ptr, "KB", strlen("KB")))
904 mode.reserve_size = 1 << 10;
905 else if (!strncmp(ptr, "MB", strlen("MB")))
906 mode.reserve_size = 1 << 20;
907 else if (!strncmp(ptr, "GB", strlen("GB")))
908 mode.reserve_size = 1 << 30;
909 else
910 panic("Syntax error in ring size param!\n");
912 *ptr = 0;
913 mode.reserve_size *= atoi(optarg);
914 break;
915 case 'b':
916 set_cpu_affinity(optarg, 0);
917 if (mode.cpu != CPU_NOTOUCH)
918 mode.cpu = atoi(optarg);
919 break;
920 case 'B':
921 set_cpu_affinity(optarg, 1);
922 break;
923 case 'H':
924 prio_high = true;
925 break;
926 case 'c':
927 mode.pcap = PCAP_OPS_RW;
928 break;
929 case 'm':
930 mode.pcap = PCAP_OPS_MMAP;
931 break;
932 case 'Q':
933 mode.cpu = CPU_NOTOUCH;
934 break;
935 case 's':
936 mode.print_mode = FNTTYPE_PRINT_NONE;
937 break;
938 case 'q':
939 mode.print_mode = FNTTYPE_PRINT_LESS;
940 break;
941 case 'l':
942 mode.print_mode = FNTTYPE_PRINT_CHR1;
943 break;
944 case 'x':
945 mode.print_mode = FNTTYPE_PRINT_HEX1;
946 break;
947 case 'C':
948 mode.print_mode = FNTTYPE_PRINT_PAAC;
949 break;
950 case 'X':
951 mode.print_mode = FNTTYPE_PRINT_HEX2;
952 break;
953 case 'N':
954 mode.print_mode = FNTTYPE_PRINT_NOPA;
955 break;
956 case 'k':
957 mode.kpull = (unsigned long) atol(optarg);
958 break;
959 case 'n':
960 frame_cnt_max = (unsigned long) atol(optarg);
961 break;
962 case 'F':
963 mode.dump_interval = (unsigned long) atol(optarg);
964 break;
965 case 'v':
966 version();
967 break;
968 case 'h':
969 help();
970 break;
971 case '?':
972 switch (optopt) {
973 case 'd':
974 case 'i':
975 case 'o':
976 case 'f':
977 case 't':
978 case 'F':
979 case 'n':
980 case 'S':
981 case 'b':
982 case 'k':
983 case 'B':
984 case 'e':
985 panic("Option -%c requires an argument!\n",
986 optopt);
987 default:
988 if (isprint(optopt))
989 whine("Unknown option character "
990 "`0x%X\'!\n", optopt);
991 die();
993 default:
994 break;
998 if (!mode.device_in)
999 mode.device_in = xstrdup("any");
1001 register_signal(SIGINT, signal_handler);
1002 register_signal(SIGHUP, signal_handler);
1004 init_pcap(mode.jumbo_support);
1005 tprintf_init();
1006 header();
1008 if (prio_high == true) {
1009 set_proc_prio(get_default_proc_prio());
1010 set_sched_status(get_default_sched_policy(),
1011 get_default_sched_prio());
1014 if (mode.device_in && (device_mtu(mode.device_in) ||
1015 !strncmp("any", mode.device_in, strlen(mode.device_in)))) {
1016 if (!mode.device_out) {
1017 mode.dump = 0;
1018 enter_mode = enter_mode_rx_only_or_dump;
1019 } else if (device_mtu(mode.device_out)) {
1020 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1021 enter_mode = enter_mode_rx_to_tx;
1022 } else {
1023 mode.dump = 1;
1024 register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
1025 enter_mode = enter_mode_rx_only_or_dump;
1027 } else {
1028 if (mode.device_out && device_mtu(mode.device_out)) {
1029 register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
1030 enter_mode = enter_mode_pcap_to_tx;
1031 } else {
1032 enter_mode = enter_mode_read_pcap;
1036 if (!enter_mode)
1037 panic("Selection not supported!\n");
1038 enter_mode(&mode);
1040 tprintf_cleanup();
1041 cleanup_pcap();
1043 if (mode.device_in)
1044 xfree(mode.device_in);
1045 if (mode.device_out)
1046 xfree(mode.device_out);
1047 return 0;