Ejemplo n.º 1
0
static void enter_mode_rx_only_or_dump(struct mode *mode)
{
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	unsigned long fcnt = 0;
	short ifflags = 0;
	uint8_t *packet;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;

	if (!device_up_and_running(mode->device_in))
		panic("Device not up and running!\n");

	set_memcpy();
	sock = pf_socket();

	if (mode->dump) {
		struct stat tmp;
		memset(&tmp, 0, sizeof(tmp));
		ret = stat(mode->device_out, &tmp);
		if (ret < 0) {
			mode->dump_dir = 0;
			goto try_file;
		}
		mode->dump_dir = !!S_ISDIR(tmp.st_mode);
		if (mode->dump_dir) {
			fd = begin_multi_pcap_file(mode);
		} else {
try_file:
			fd = begin_single_pcap_file(mode);
		}
	}

	memset(&rx_ring, 0, sizeof(rx_ring));
	memset(&rx_poll, 0, sizeof(rx_poll));
	memset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(mode->device_in);
	size = ring_size(mode->device_in, mode->reserve_size);

	enable_kernel_bpf_jit_compiler();
	bpf_parse_rules(mode->filter, &bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
	create_rx_ring(sock, &rx_ring);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(&rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(mode->print_mode);

	if (mode->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(mode->device_in);
		device_bind_irq_to_cpu(mode->cpu, irq);
		printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq, 
		       mode->cpu);
	}

	if (mode->promiscuous == true) {
		ifflags = enter_promiscuous_mode(mode->device_in);
		printf("PROMISC\n");
	}

	printf("BPF:\n");
	bpf_dump_all(&bpf_ops);
	printf("MD: RX %s\n\n", mode->dump ? pcap_ops[mode->pcap]->name : "");

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
			hdr = rx_ring.frames[it].iov_base;
			packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
			fcnt++;

			if (mode->packet_type != PACKET_ALL)
				if (mode->packet_type != hdr->s_ll.sll_pkttype)
					goto next;
			if (unlikely(rx_ring.layout.tp_frame_size <
				     hdr->tp_h.tp_snaplen)) {
				fprintf(stderr, "Skipping too large packet! "
					"No jumbo support selected?\n");
				fflush(stderr);
				goto next;
			}
			if (mode->dump) {
				struct pcap_pkthdr phdr;
				tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
				ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
									   packet, phdr.len);
				if (unlikely(ret != sizeof(phdr) + phdr.len))
					panic("Write error to pcap!\n");
			}

			show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
			dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
					      mode->link_type);

			if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
				sigint = 1;
				break;
			}
next:
			kernel_may_pull_from_rx(&hdr->tp_h);
			next_slot(&it, &rx_ring);

			if (unlikely(sigint == 1))
				break;
			if (mode->dump && next_dump) {
				struct tpacket_stats kstats;
				socklen_t slen = sizeof(kstats);
				memset(&kstats, 0, sizeof(kstats));
				getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
					   &kstats, &slen);
				fd = next_multi_pcap_file(mode, fd);
				next_dump = false;
				if (mode->print_mode == FNTTYPE_PRINT_NONE) {
					printf(".(+%u/-%u)", kstats.tp_packets - kstats.tp_drops,
					       kstats.tp_drops);
					fflush(stdout);
				}
			}
		}

		poll(&rx_poll, 1, -1);
		poll_error_maybe_die(sock, &rx_poll);
	}

	if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE))
		sock_print_net_stats(sock);
	else {
		printf("\n\n");
		fflush(stdout);
	}
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);
	if (mode->promiscuous == true)
		leave_promiscuous_mode(mode->device_in, ifflags);
	close(sock);
	if (mode->dump) {
		if (mode->dump_dir)
			finish_multi_pcap_file(mode, fd);
		else
			finish_single_pcap_file(mode, fd);
	}
}
Ejemplo n.º 2
0
static void recv_only_or_dump(struct ctx *ctx)
{
	short ifflags = 0;
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct sock_fprog bpf_ops;
	struct timeval start, end, diff;
	struct block_desc *pbd;
	unsigned long frame_count = 0;

	sock = pf_socket();

	if (ctx->rfraw) {
		ctx->device_trans = xstrdup(ctx->device_in);
		xfree(ctx->device_in);

		enter_rfmon_mac80211(ctx->device_trans, &ctx->device_in);
		ctx->link_type = LINKTYPE_IEEE802_11;
	}

	fmemset(&rx_ring, 0, sizeof(rx_ring));
	fmemset(&rx_poll, 0, sizeof(rx_poll));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(ctx->device_in);

	size = ring_size(ctx->device_in, ctx->reserve_size);

	enable_kernel_bpf_jit_compiler();

	bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type);
	if (ctx->dump_bpf)
		bpf_dump_all(&bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	ret = set_sockopt_hwtimestamp(sock, ctx->device_in);
	if (ret == 0 && ctx->verbose)
		printf("HW timestamping enabled\n");

	setup_rx_ring_layout(sock, &rx_ring, size, true, true);
	create_rx_ring(sock, &rx_ring, ctx->verbose);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(sock, &rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(ctx->print_mode);

	if (ctx->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(ctx->device_in);
		device_set_irq_affinity(irq, ctx->cpu);

		if (ctx->verbose)
			printf("IRQ: %s:%d > CPU%d\n",
			       ctx->device_in, irq, ctx->cpu);
	}

	if (ctx->promiscuous)
		ifflags = enter_promiscuous_mode(ctx->device_in);

	if (dump_to_pcap(ctx) && __pcap_io->init_once_pcap)
		__pcap_io->init_once_pcap();

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (dump_to_pcap(ctx)) {
		__label__ try_file;
		struct stat stats;

		fmemset(&stats, 0, sizeof(stats));
		ret = stat(ctx->device_out, &stats);
		if (ret < 0) {
			ctx->dump_dir = 0;
			goto try_file;
		}

		ctx->dump_dir = S_ISDIR(stats.st_mode);
		if (ctx->dump_dir) {
			fd = begin_multi_pcap_file(ctx);
		} else {
		try_file:
			fd = begin_single_pcap_file(ctx);
		}
	}

	printf("Running! Hang up with ^C!\n\n");
	fflush(stdout);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx_block((pbd = (void *)
				rx_ring.frames[it].iov_base))) {
			walk_t3_block(pbd, ctx, sock, &fd, &frame_count);

			kernel_may_pull_from_rx_block(pbd);
			it = (it + 1) % rx_ring.layout3.tp_block_nr;

			if (unlikely(sigint == 1))
				break;
		}

		poll(&rx_poll, 1, -1);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (!(ctx->dump_dir && ctx->print_mode == PRINT_NONE)) {
		sock_rx_net_stats(sock, frame_count);

		printf("\r%12lu  sec, %lu usec in total\n",
		       diff.tv_sec, diff.tv_usec);
	} else {
		printf("\n\n");
		fflush(stdout);
	}

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);

	if (ctx->promiscuous)
		leave_promiscuous_mode(ctx->device_in, ifflags);

	if (ctx->rfraw)
		leave_rfmon_mac80211(ctx->device_trans, ctx->device_in);

	if (dump_to_pcap(ctx)) {
		if (ctx->dump_dir)
			finish_multi_pcap_file(ctx, fd);
		else
			finish_single_pcap_file(ctx, fd);
	}

	close(sock);
}
Ejemplo n.º 3
0
static void enter_mode_rx_only_or_dump(struct mode *mode)
{
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	unsigned long fcnt = 0, skipped = 0;
	short ifflags = 0;
	uint8_t *packet;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;
	struct timeval start, end, diff;

	if (!device_up_and_running(mode->device_in))
		panic("Device not up and running!\n");

	sock = pf_socket();

	if (mode->rfraw) {
		mode->device_trans = xstrdup(mode->device_in);
		xfree(mode->device_in);

		enter_rfmon_mac80211(mode->device_trans, &mode->device_in);
		mode->link_type = LINKTYPE_IEEE802_11;
	}

	if (mode->dump) {
		struct stat tmp;
		fmemset(&tmp, 0, sizeof(tmp));
		ret = stat(mode->device_out, &tmp);
		if (ret < 0) {
			mode->dump_dir = 0;
			goto try_file;
		}
		mode->dump_dir = !!S_ISDIR(tmp.st_mode);
		if (mode->dump_dir) {
			fd = begin_multi_pcap_file(mode);
		} else {
try_file:
			fd = begin_single_pcap_file(mode);
		}
	}

	fmemset(&rx_ring, 0, sizeof(rx_ring));
	fmemset(&rx_poll, 0, sizeof(rx_poll));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(mode->device_in);
	size = ring_size(mode->device_in, mode->reserve_size);

	enable_kernel_bpf_jit_compiler();
	bpf_parse_rules(mode->filter, &bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	set_sockopt_hwtimestamp(sock, mode->device_in);
	setup_rx_ring_layout(sock, &rx_ring, size, mode->jumbo_support);
	create_rx_ring(sock, &rx_ring);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(&rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(mode->print_mode);

	if (mode->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(mode->device_in);
		device_bind_irq_to_cpu(mode->cpu, irq);
		printf("IRQ: %s:%d > CPU%d\n", mode->device_in, irq, 
		       mode->cpu);
	}

	if (mode->promiscuous == true) {
		ifflags = enter_promiscuous_mode(mode->device_in);
		printf("PROMISC\n");
	}

	printf("BPF:\n");
	bpf_dump_all(&bpf_ops);
	printf("MD: RX %s ", mode->dump ? pcap_ops[mode->pcap]->name : "");
	if (mode->rfraw)
		printf("802.11 raw via %s ", mode->device_in);
#ifdef _LARGEFILE64_SOURCE
	printf("lf64 ");
#endif 
	ioprio_print();
	printf("\n");

	gettimeofday(&start, NULL);

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
			hdr = rx_ring.frames[it].iov_base;
			packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
			fcnt++;

			if (mode->packet_type != PACKET_ALL)
				if (mode->packet_type != hdr->s_ll.sll_pkttype)
					goto next;
			if (unlikely(ring_frame_size(&rx_ring) <
				     hdr->tp_h.tp_snaplen)) {
				skipped++;
				goto next;
			}
			if (mode->dump) {
				struct pcap_pkthdr phdr;
				tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &phdr);
				ret = pcap_ops[mode->pcap]->write_pcap_pkt(fd, &phdr,
									   packet, phdr.len);
				if (unlikely(ret != sizeof(phdr) + phdr.len))
					panic("Write error to pcap!\n");
			}

			show_frame_hdr(hdr, mode->print_mode, RING_MODE_INGRESS);
			dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
					      mode->link_type, mode->print_mode);

			if (frame_cnt_max != 0 && fcnt >= frame_cnt_max) {
				sigint = 1;
				break;
			}
next:
			kernel_may_pull_from_rx(&hdr->tp_h);
			next_slot_prerd(&it, &rx_ring);

			if (unlikely(sigint == 1))
				break;
			if (mode->dump && next_dump) {
				struct tpacket_stats kstats;
				socklen_t slen = sizeof(kstats);
				fmemset(&kstats, 0, sizeof(kstats));
				getsockopt(sock, SOL_PACKET, PACKET_STATISTICS,
					   &kstats, &slen);
				fd = next_multi_pcap_file(mode, fd);
				next_dump = false;
				if (mode->print_mode == FNTTYPE_PRINT_NONE) {
					printf(".(+%lu/-%lu)",
					       1UL * kstats.tp_packets -
					       kstats.tp_drops -
					       skipped, 1UL * kstats.tp_drops +
					       skipped);
					fflush(stdout);
				}
			}
		}

		poll(&rx_poll, 1, -1);
		poll_error_maybe_die(sock, &rx_poll);
	}

	gettimeofday(&end, NULL);
	diff = tv_subtract(end, start);

	if (!(mode->dump_dir && mode->print_mode == FNTTYPE_PRINT_NONE)) {
		sock_print_net_stats(sock, skipped);
		printf("\r%12lu  sec, %lu usec in total\n", diff.tv_sec,
		       diff.tv_usec);
	} else {
		printf("\n\n");
		fflush(stdout);
	}

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);

	if (mode->promiscuous == true)
		leave_promiscuous_mode(mode->device_in, ifflags);

	if (mode->rfraw)
		leave_rfmon_mac80211(mode->device_trans, mode->device_in);

	close(sock);

	if (mode->dump) {
		if (mode->dump_dir)
			finish_multi_pcap_file(mode, fd);
		else
			finish_single_pcap_file(mode, fd);
	}
}
Ejemplo n.º 4
0
static void recv_only_or_dump(struct ctx *ctx)
{
	short ifflags = 0;
	int sock, ifindex, fd = 0, ret;
	size_t size;
	unsigned int it = 0;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct sock_fprog bpf_ops;
	struct timeval start, end, diff;
	bool is_v3 = is_defined(HAVE_TPACKET3);

	sock = pf_socket_type(ctx->link_type);

	ifindex = device_ifindex(ctx->device_in);
	size = ring_size(ctx->device_in, ctx->reserve_size);

	enable_kernel_bpf_jit_compiler();

	bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type);
	if (ctx->dump_bpf)
		bpf_dump_all(&bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	if (ctx->hwtimestamp) {
		ret = set_sockopt_hwtimestamp(sock, ctx->device_in);
		if (ret == 0 && ctx->verbose)
			printf("HW timestamping enabled\n");
	}

	ring_rx_setup(&rx_ring, sock, size, ifindex, &rx_poll, is_v3, true,
		      ctx->verbose, ctx->fanout_group, ctx->fanout_type);

	dissector_init_all(ctx->print_mode);

	if (ctx->cpu >= 0 && ifindex > 0) {
		int irq = device_irq_number(ctx->device_in);
		device_set_irq_affinity(irq, ctx->cpu);

		if (ctx->verbose)
			printf("IRQ: %s:%d > CPU%d\n",
			       ctx->device_in, irq, ctx->cpu);
	}

	if (ctx->promiscuous)
		ifflags = device_enter_promiscuous_mode(ctx->device_in);

	if (dump_to_pcap(ctx) && __pcap_io->init_once_pcap)
		__pcap_io->init_once_pcap(true);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (dump_to_pcap(ctx)) {
		struct stat stats;

		ret = stat(ctx->device_out, &stats);
		if (ret < 0)
			ctx->dump_dir = 0;
		else
			ctx->dump_dir = S_ISDIR(stats.st_mode);

		if (ctx->dump_dir)
			fd = begin_multi_pcap_file(ctx);
		else
			fd = begin_single_pcap_file(ctx);
	}

	printf("Running! Hang up with ^C!\n\n");
	fflush(stdout);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0)) {
#ifdef HAVE_TPACKET3
		struct block_desc *pbd;

		while (user_may_pull_from_rx_block((pbd = rx_ring.frames[it].iov_base))) {
			walk_t3_block(pbd, ctx, sock, &fd);

			kernel_may_pull_from_rx_block(pbd);
			it = (it + 1) % rx_ring.layout3.tp_block_nr;

			if (unlikely(sigint == 1))
				break;
		}
#else
		while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
			struct frame_map *hdr = rx_ring.frames[it].iov_base;
			uint8_t *packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
			pcap_pkthdr_t phdr;

			if (ctx->packet_type != -1)
				if (ctx->packet_type != hdr->s_ll.sll_pkttype)
					goto next;

			ctx->pkts_seen++;

			if (unlikely(ring_frame_size(&rx_ring) < hdr->tp_h.tp_snaplen)) {
				/* XXX: silently ignore for now. We used to
				 * report them with dump_rx_stats()  */
				goto next;
			}

			if (dump_to_pcap(ctx)) {
				tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &hdr->s_ll, &phdr, ctx->magic);

				ret = __pcap_io->write_pcap(fd, &phdr, ctx->magic, packet,
							    pcap_get_length(&phdr, ctx->magic));
				if (unlikely(ret != (int) pcap_get_total_length(&phdr, ctx->magic)))
					panic("Write error to pcap!\n");
			}

			show_frame_hdr(packet, hdr->tp_h.tp_snaplen,
				       ctx->link_type, hdr, ctx->print_mode,
				       ctx->pkts_seen);

			dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
					      ctx->link_type, ctx->print_mode,
					      &hdr->s_ll);

			if (frame_count_max != 0) {
				if (unlikely(ctx->pkts_seen >= frame_count_max)) {
					sigint = 1;
					break;
				}
			}

next:
			kernel_may_pull_from_rx(&hdr->tp_h);
			it = (it + 1) % rx_ring.layout.tp_frame_nr;

			if (unlikely(sigint == 1))
				break;

			update_pcap_next_dump(ctx, hdr->tp_h.tp_snaplen, &fd,
					      sock, is_v3);
		}
#endif /* HAVE_TPACKET3 */

		ret = poll(&rx_poll, 1, -1);
		if (unlikely(ret < 0)) {
			if (errno != EINTR)
				panic("Poll failed!\n");
		}
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	dump_rx_stats(ctx, sock, is_v3);
	printf("\r%12lu  sec, %lu usec in total\n",
			diff.tv_sec, diff.tv_usec);

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);

	if (ctx->promiscuous)
		device_leave_promiscuous_mode(ctx->device_in, ifflags);

	if (ctx->rfraw)
		leave_rfmon_mac80211(ctx->device_in);

	if (dump_to_pcap(ctx)) {
		if (ctx->dump_dir)
			finish_multi_pcap_file(ctx, fd);
		else
			finish_single_pcap_file(ctx, fd);
	}

	close(sock);
}
Ejemplo n.º 5
0
static void recv_only_or_dump(struct ctx *ctx)
{
	uint8_t *packet;
	short ifflags = 0;
	int sock, irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	unsigned long frame_count = 0, skipped = 0;
	struct ring rx_ring;
	struct pollfd rx_poll;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;
	struct timeval start, end, diff;
	pcap_pkthdr_t phdr;

	if (!device_up_and_running(ctx->device_in) && !ctx->rfraw)
		panic("Device not up and running!\n");

	sock = pf_socket();

	if (ctx->rfraw) {
		ctx->device_trans = xstrdup(ctx->device_in);
		xfree(ctx->device_in);

		enter_rfmon_mac80211(ctx->device_trans, &ctx->device_in);
		ctx->link_type = LINKTYPE_IEEE802_11;
	}

	fmemset(&rx_ring, 0, sizeof(rx_ring));
	fmemset(&rx_poll, 0, sizeof(rx_poll));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));

	ifindex = device_ifindex(ctx->device_in);

	size = ring_size(ctx->device_in, ctx->reserve_size);

	enable_kernel_bpf_jit_compiler();

	bpf_parse_rules(ctx->filter, &bpf_ops, ctx->link_type);
	if (ctx->dump_bpf)
		bpf_dump_all(&bpf_ops);
	bpf_attach_to_sock(sock, &bpf_ops);

	set_sockopt_hwtimestamp(sock, ctx->device_in);

	setup_rx_ring_layout(sock, &rx_ring, size, ctx->jumbo);
	create_rx_ring(sock, &rx_ring, ctx->verbose);
	mmap_rx_ring(sock, &rx_ring);
	alloc_rx_ring_frames(&rx_ring);
	bind_rx_ring(sock, &rx_ring, ifindex);

	prepare_polling(sock, &rx_poll);
	dissector_init_all(ctx->print_mode);

	if (ctx->cpu >= 0 && ifindex > 0) {
		irq = device_irq_number(ctx->device_in);
		device_bind_irq_to_cpu(irq, ctx->cpu);

		if (ctx->verbose)
			printf("IRQ: %s:%d > CPU%d\n",
			       ctx->device_in, irq, ctx->cpu);
	}

	if (ctx->promiscuous)
		ifflags = enter_promiscuous_mode(ctx->device_in);

	drop_privileges(ctx->enforce, ctx->uid, ctx->gid);

	if (dump_to_pcap(ctx)) {
		__label__ try_file;
		struct stat stats;

		fmemset(&stats, 0, sizeof(stats));
		ret = stat(ctx->device_out, &stats);
		if (ret < 0) {
			ctx->dump_dir = 0;
			goto try_file;
		}

		ctx->dump_dir = S_ISDIR(stats.st_mode);
		if (ctx->dump_dir) {
			fd = begin_multi_pcap_file(ctx);
		} else {
		try_file:
			fd = begin_single_pcap_file(ctx);
		}
	}

	printf("Running! Hang up with ^C!\n\n");
	fflush(stdout);

	bug_on(gettimeofday(&start, NULL));

	while (likely(sigint == 0)) {
		while (user_may_pull_from_rx(rx_ring.frames[it].iov_base)) {
			__label__ next;

			hdr = rx_ring.frames[it].iov_base;
			packet = ((uint8_t *) hdr) + hdr->tp_h.tp_mac;
			frame_count++;

			if (ctx->packet_type != -1)
				if (ctx->packet_type != hdr->s_ll.sll_pkttype)
					goto next;

			if (unlikely(ring_frame_size(&rx_ring) < hdr->tp_h.tp_snaplen)) {
				skipped++;
				goto next;
			}

			if (dump_to_pcap(ctx)) {
				tpacket_hdr_to_pcap_pkthdr(&hdr->tp_h, &hdr->s_ll, &phdr, ctx->magic);

				ret = __pcap_io->write_pcap(fd, &phdr, ctx->magic, packet,
							    pcap_get_length(&phdr, ctx->magic));
				if (unlikely(ret != pcap_get_total_length(&phdr, ctx->magic)))
					panic("Write error to pcap!\n");
			}

			show_frame_hdr(hdr, ctx->print_mode);

			dissector_entry_point(packet, hdr->tp_h.tp_snaplen,
					      ctx->link_type, ctx->print_mode);

			if (frame_count_max != 0) {
				if (frame_count >= frame_count_max) {
					sigint = 1;
					break;
				}
			}

			next:

			kernel_may_pull_from_rx(&hdr->tp_h);

			it++;
			if (it >= rx_ring.layout.tp_frame_nr)
				it = 0;

			if (unlikely(sigint == 1))
				break;

			if (dump_to_pcap(ctx)) {
				if (ctx->dump_mode == DUMP_INTERVAL_SIZE) {
					interval += hdr->tp_h.tp_snaplen;

					if (interval > ctx->dump_interval) {
						next_dump = true;
						interval = 0;
					}
				}

				if (next_dump) {
					fd = next_multi_pcap_file(ctx, fd);
					next_dump = false;

					if (ctx->verbose)
						print_pcap_file_stats(sock, ctx, skipped);
				}
			}
		}

		poll(&rx_poll, 1, -1);
	}

	bug_on(gettimeofday(&end, NULL));
	timersub(&end, &start, &diff);

	if (!(ctx->dump_dir && ctx->print_mode == PRINT_NONE)) {
		sock_print_net_stats(sock, skipped);

		printf("\r%12lu  sec, %lu usec in total\n",
		       diff.tv_sec, diff.tv_usec);
	} else {
		printf("\n\n");
		fflush(stdout);
	}

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_rx_ring(sock, &rx_ring);

	if (ctx->promiscuous)
		leave_promiscuous_mode(ctx->device_in, ifflags);

	if (ctx->rfraw)
		leave_rfmon_mac80211(ctx->device_trans, ctx->device_in);

	if (dump_to_pcap(ctx)) {
		if (ctx->dump_dir)
			finish_multi_pcap_file(ctx, fd);
		else
			finish_single_pcap_file(ctx, fd);
	}

	close(sock);
}