Exemplo n.º 1
0
static void enter_mode_pcap_to_tx(struct mode *mode)
{
	int irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	struct ring tx_ring;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;
	struct tx_stats stats;
	uint8_t *out = NULL;
	unsigned long trunced = 0;
	struct timeval start, end, diff;

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

	tx_sock = pf_socket();

	if (!pcap_ops[mode->pcap])
		panic("pcap group not supported!\n");
	fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);
	ret = pcap_ops[mode->pcap]->pull_file_header(fd, &mode->link_type);
	if (ret)
		panic("error reading pcap header!\n");
	if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
		ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
		if (ret)
			panic("error prepare reading pcap!\n");
	}

	fmemset(&tx_ring, 0, sizeof(tx_ring));
	fmemset(&bpf_ops, 0, sizeof(bpf_ops));
	fmemset(&stats, 0, sizeof(stats));

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

		enter_rfmon_mac80211(mode->device_trans, &mode->device_out);
		if (mode->link_type != LINKTYPE_IEEE802_11)
			panic("Wrong linktype of pcap!\n");
	}

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

	bpf_parse_rules(mode->filter, &bpf_ops);

	set_packet_loss_discard(tx_sock);
	set_sockopt_hwtimestamp(tx_sock, mode->device_out);
	setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
	create_tx_ring(tx_sock, &tx_ring);
	mmap_tx_ring(tx_sock, &tx_ring);
	alloc_tx_ring_frames(&tx_ring);
	bind_tx_ring(tx_sock, &tx_ring, ifindex);

	dissector_init_all(mode->print_mode);

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

	if (mode->kpull)
		interval = mode->kpull;

	itimer.it_interval.tv_sec = 0;
	itimer.it_interval.tv_usec = interval;
	itimer.it_value.tv_sec = 0;
	itimer.it_value.tv_usec = interval;
	setitimer(ITIMER_REAL, &itimer, NULL); 

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

	gettimeofday(&start, NULL);

	while (likely(sigint == 0)) {
		while (user_may_pull_from_tx(tx_ring.frames[it].iov_base)) {
			struct pcap_pkthdr phdr;
			hdr = tx_ring.frames[it].iov_base;
			/* Kernel assumes: data = ph.raw + po->tp_hdrlen -
			 * sizeof(struct sockaddr_ll); */
			out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
			      sizeof(struct sockaddr_ll);

			do {
				memset(&phdr, 0, sizeof(phdr));
				ret = pcap_ops[mode->pcap]->read_pcap_pkt(fd, &phdr,
						out, ring_frame_size(&tx_ring));
				if (unlikely(ret <= 0))
					goto out;
				if (ring_frame_size(&tx_ring) < phdr.len) {
					phdr.len = ring_frame_size(&tx_ring);
					trunced++;
				}
			} while (mode->filter && !bpf_run_filter(&bpf_ops, out, phdr.len));
			pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);

			stats.tx_bytes += hdr->tp_h.tp_len;;
			stats.tx_packets++;

			show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
			dissector_entry_point(out, hdr->tp_h.tp_snaplen,
					      mode->link_type, mode->print_mode);

			kernel_may_pull_from_tx(&hdr->tp_h);
			next_slot_prewr(&it, &tx_ring);

			if (unlikely(sigint == 1))
				break;
			if (frame_cnt_max != 0 &&
			    stats.tx_packets >= frame_cnt_max) {
				sigint = 1;
				break;
			}
		}
	}
out:
	gettimeofday(&end, NULL);
	diff = tv_subtract(end, start);

	fflush(stdout);
	printf("\n");
	printf("\r%12lu frames outgoing\n", stats.tx_packets);
	printf("\r%12lu frames truncated (larger than frame)\n", trunced);
	printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
	printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec, diff.tv_usec);

	bpf_release(&bpf_ops);
	dissector_cleanup_all();
	destroy_tx_ring(tx_sock, &tx_ring);

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

	close(tx_sock);
	if (pcap_ops[mode->pcap]->prepare_close_pcap)
		pcap_ops[mode->pcap]->prepare_close_pcap(fd, PCAP_MODE_READ);
	close(fd);
}
Exemplo n.º 2
0
static void enter_mode_pcap_to_tx(struct mode *mode)
{
	int irq, ifindex, fd = 0, ret;
	unsigned int size, it = 0;
	struct ring tx_ring;
	struct frame_map *hdr;
	struct sock_fprog bpf_ops;
	struct tx_stats stats;
	uint8_t *out = NULL;
	unsigned long trunced = 0;
	struct timeval start, end, diff;
	int filen = 0;
	struct pcap_timeval *pcap_time;

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

	if (!pcap_ops[mode->pcap])
		panic("pcap group not supported!\n");

	//Moved here
	/*
	   ifindex = device_ifindex(mode->device_out);  //Make n devices out of it. From here
	   size = ring_size(mode->device_out, mode->reserve_size);

	   bpf_parse_rules(mode->filter, &bpf_ops);

	   set_packet_loss_discard(tx_sock);
	   set_sockopt_hwtimestamp(tx_sock, mode->device_out);
	   setup_tx_ring_layout(tx_sock, &tx_ring, size, mode->jumbo_support);
	   create_tx_ring(tx_sock, &tx_ring);
	   mmap_tx_ring(tx_sock, &tx_ring);
	   alloc_tx_ring_frames(&tx_ring);
	   bind_tx_ring(tx_sock, &tx_ring, ifindex);  

	   dissector_init_all(mode->print_mode);

	   if (mode->cpu >= 0 && ifindex > 0) {
	   irq = device_irq_number(mode->device_out);
	   device_bind_irq_to_cpu(mode->cpu, irq);
	   printf("IRQ: %s:%d > CPU%d\n", mode->device_out, irq, 
	   mode->cpu);
	   } //Till here. Make n TXRings. One for each NIC.
	 */
	//Moved to here end

	int x = 0;


	for (filen = 0; filen < num_of_pcaps; filen++) {

		tx_sock = pf_socket();

		mode->device_in = pcaplist[filen];
		printf("\n \n File selected is: %s \n", mode->device_in);

		fd = open_or_die(mode->device_in, O_RDONLY | O_LARGEFILE | O_NOATIME);	//Need to do for each file
		ret =
		    pcap_ops[mode->pcap]->pull_file_header(fd,
							   &mode->link_type);
		if (ret) {
			panic("error reading pcap header!\n");
			continue;
		}
		if (pcap_ops[mode->pcap]->prepare_reading_pcap) {
			ret = pcap_ops[mode->pcap]->prepare_reading_pcap(fd);
			if (ret) {
				panic("error prepare reading pcap!\n");
				continue;
			}
		}

		fmemset(&tx_ring, 0, sizeof(tx_ring));
		fmemset(&bpf_ops, 0, sizeof(bpf_ops));
		fmemset(&stats, 0, sizeof(stats));

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

			enter_rfmon_mac80211(mode->device_trans,
					     &mode->device_out);
			if (mode->link_type != LINKTYPE_IEEE802_11)
				panic("Wrong linktype of pcap!\n");
			continue;
		}

		ifindex = device_ifindex(mode->device_out);	//Make n devices out of it. From here
		size = ring_size(mode->device_out, mode->reserve_size);

		bpf_parse_rules(mode->filter, &bpf_ops);

		set_packet_loss_discard(tx_sock);
		set_sockopt_hwtimestamp(tx_sock, mode->device_out);
		setup_tx_ring_layout(tx_sock, &tx_ring, size,
				     mode->jumbo_support);
		create_tx_ring(tx_sock, &tx_ring);
		mmap_tx_ring(tx_sock, &tx_ring);
		alloc_tx_ring_frames(&tx_ring);
		bind_tx_ring(tx_sock, &tx_ring, ifindex);	//Till here. Make n TXRings. One for each NIC.

		dissector_init_all(mode->print_mode);

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

		if (mode->kpull)
			interval = mode->kpull;

		itimer.it_interval.tv_sec = 0;
		itimer.it_interval.tv_usec = interval;
		itimer.it_value.tv_sec = 0;
		itimer.it_value.tv_usec = interval;	//for fixed delay need to SET this

		setitimer(ITIMER_REAL, &itimer, NULL);

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

		gettimeofday(&start, NULL);

		sigint = 0;

		while (likely(sigint == 0)) {
			while (user_may_pull_from_tx
			       (tx_ring.frames[it].iov_base)) {
				struct pcap_pkthdr phdr;
				hdr = tx_ring.frames[it].iov_base;
				/* Kernel assumes: data = ph.raw + po->tp_hdrlen -
				 * sizeof(struct sockaddr_ll); */
				out = ((uint8_t *) hdr) + TPACKET_HDRLEN -
				    sizeof(struct sockaddr_ll);

				do {
					memset(&phdr, 0, sizeof(phdr));
					ret =
					    pcap_ops[mode->pcap]->
					    read_pcap_pkt(fd, &phdr, out,
							  ring_frame_size
							  (&tx_ring));
					if (unlikely(ret <= 0))
						goto out;
					if (ring_frame_size(&tx_ring) <
					    phdr.len) {
						phdr.len =
						    ring_frame_size(&tx_ring);
						trunced++;
					}
				} while (mode->filter
					 && !bpf_run_filter(&bpf_ops, out,
							    phdr.len));
				pcap_pkthdr_to_tpacket_hdr(&phdr, &hdr->tp_h);

				if (stats.tx_packets == 0) {
					pcap_time = &phdr.ts;
					beginning_tv_sec = pcap_time->tv_sec;
					beginning_tv_usec = pcap_time->tv_usec;
				}

				/*
				 * START OF BLOCK
				 The below routines are only if Speed or PPS is set else they won't execute
				 *
				 */

				if (gbit_s > 0) {
					/* computing max rate */
					pps =
					    ((gbit_s * 1000000000) /
					     8 /*byte */ ) / (8 /*Preamble */  +
							      avg_send_len +
							      4 /*CRC*/ +
							      12 /*IFG*/);

					td = (double)(hz / pps);
					tick_delta = (ticks) td;

					//printf("Number of %d-byte Packet Per Second at %.2f Gbit/s: %.2f\n", (avg_send_len + 4 /*CRC*/), gbit_s, pps);
				}

				else if (pps > 0) {
					td = (double)(hz / pps);
					tick_delta = (ticks) td;
				}
				//END OF BLOCK
/*
			show_frame_hdr(hdr, mode->print_mode, RING_MODE_EGRESS);
			
dissector_entry_point(out, hdr->tp_h.tp_snaplen,
					      mode->link_type, mode->print_mode);
*/

				//x++;

				kernel_may_pull_from_tx(&hdr->tp_h);
				next_slot_prewr(&it, &tx_ring);

				stats.tx_bytes += hdr->tp_h.tp_len;;
				stats.tx_packets++;
				send_len += hdr->tp_h.tp_len;
				avg_send_len = send_len / stats.tx_packets;

				if (unlikely(sigint == 1))
					break;
				if (frame_cnt_max != 0 &&
				    stats.tx_packets >= frame_cnt_max) {

					//sigint = 1;
					break;
				}
//START OF BLOCK
				if (gbit_s != 0 || pps > 0)
					tick_start = getticks();

				if (gbit_s > 0 || pps > 0) {
					/* rate set */
					while ((getticks() - tick_start) <
					       (num_pkt_good_sent *
						tick_delta)) ;
				} else if (gbit_s < 0) {
					/* real pcap rate --FULL SYNC MODE */

					pcap_time = &phdr.ts;

					ticks ticks_from_beginning = (((pcap_time->tv_sec - beginning_tv_sec) * 1000000) + (pcap_time->tv_usec - beginning_tv_usec)) * hz / 1000000;	//delta time of this pkt from beginning of pcap
					/* h-> is this packet header and beginning is 1st packet's header */

					if (ticks_from_beginning == 0)
						tick_start = getticks();	/* first packet, resetting time */
					while ((getticks() - tick_start) <
					       ticks_from_beginning) ;
				}
				//pps routine end
//END OF BLOCK

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

		fflush(stdout);
		printf("\n");
		printf("\r%12lu frames outgoing\n", stats.tx_packets);
		printf("\r%12lu frames truncated (larger than frame)\n",
		       trunced);
		printf("\r%12lu bytes outgoing\n", stats.tx_bytes);
		printf("\r%12lu sec, %lu usec in total\n", diff.tv_sec,
		       diff.tv_usec);

		bpf_release(&bpf_ops);
		dissector_cleanup_all();
		destroy_tx_ring(tx_sock, &tx_ring);

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

		close(tx_sock);
		if (pcap_ops[mode->pcap]->prepare_close_pcap)
			pcap_ops[mode->pcap]->prepare_close_pcap(fd,
								 PCAP_MODE_READ);
		close(fd);

	}
}