Example #1
0
bool cPcapNet::sendFile (const char* file, bool sync, int loops)
{
	struct pcap_pkthdr *header;
	const u_char *pkt_data;
	bpf_u_int32 len = 0;
	bool error = false;

 // FIXME close interface on error
	uint32_t count = getFileSize(file);

	if (!openInterface ())
		return false;

	pcap_send_queue* q = pcap_sendqueue_alloc (count);
	if (!q)
	{
		fprintf (stderr, "can't allocate sendqueue\n");
		return false;
	}

	cPcapFileIO pcapfile;

	if (!pcapfile.open (file))
		return false;

	// Retrieve the packets from the file
	while (pcapfile.read (&header, &pkt_data))
	{
		int r = pcap_sendqueue_queue (q, header, pkt_data);
		// pcap_sendqueue_queue can only fail, if we have'n allocated enough memory
		assert (!r);

		len += (header->len + sizeof (*header));
	}

	error = pcapfile.error ();
	if (error)
		fprintf (stderr, "File error while reading %s\n", file);

	pcapfile.close ();

	while (!error && loops--)
	{
		error = pcap_sendqueue_transmit (ifcHandle, q, sync) != len;
		if (error)
			fprintf (stderr, "PCAP could not send transmit buffer\n");
	}
	pcap_sendqueue_destroy (q);
	pcap_close(ifcHandle);

	return !error;
}
Example #2
0
/***************************************************************************
 * Some methods of transmit queue multiple packets in a buffer then
 * send all queued packets at once. At the end of a scan, we might have
 * some pending packets that haven't been transmitted yet. Therefore,
 * we'll have to flush them.
 ***************************************************************************/
void
rawsock_flush(struct Adapter *adapter)
{
    if (adapter->sendq) {
        pcap_sendqueue_transmit(adapter->pcap, adapter->sendq, 0);

        /* Dude, I totally forget why this step is necessary. I vaguely
         * remember there's a good reason for it though */
        pcap_sendqueue_destroy(adapter->sendq);
        adapter->sendq =  pcap_sendqueue_alloc(SENDQ_SIZE);
    }

}
Example #3
0
static void
rawsock_close_adapter(struct Adapter *adapter)
{
    if (adapter->ring) {
        PFRING.close(adapter->ring);
    }
    if (adapter->pcap) {
        pcap_close(adapter->pcap);
    }
    if (adapter->sendq) {
        pcap_sendqueue_destroy(adapter->sendq);
    }

    free(adapter);
}
Example #4
0
/***************************************************************************
 * wrapper for libpcap's sendpacket
 *
 * PORTABILITY: WINDOWS and PF_RING
 * For performance, Windows and PF_RING can queue up multiple packets, then
 * transmit them all in a chunk. If we stop and wait for a bit, we need
 * to flush the queue to force packets to be transmitted immediately.
 ***************************************************************************/
int
rawsock_send_packet(
    struct Adapter *adapter,
    const unsigned char *packet,
    unsigned length,
    unsigned flush)
{
    if (adapter == 0)
        return 0;
    
    /* Print --packet-trace if debugging */
    if (adapter->is_packet_trace) {
        packet_trace(stdout, packet, length, 1);
    }

    /* PF_RING */
    if (adapter->ring) {
        int err = PF_RING_ERROR_NO_TX_SLOT_AVAILABLE;

        while (err == PF_RING_ERROR_NO_TX_SLOT_AVAILABLE) {
            err = PFRING.send(adapter->ring, packet, length, (unsigned char)flush);
        }
        if (err < 0)
            LOG(1, "pfring:xmit: ERROR %d\n", err);
        return err;
    }

    /* WINDOWS PCAP */
    if (adapter->sendq) {
        int err;
        struct pcap_pkthdr hdr;
        hdr.len = length;
        hdr.caplen = length;

        err = pcap_sendqueue_queue(adapter->sendq, &hdr, packet);
        if (err) {
            //printf("sendpacket() failed %d\n", x);
            //for (;;)
            pcap_sendqueue_transmit(adapter->pcap, adapter->sendq, 0);
            //printf("pcap_send_queue)() returned %u\n", x);
            pcap_sendqueue_destroy(adapter->sendq);
            adapter->sendq =  pcap_sendqueue_alloc(SENDQ_SIZE);
            pcap_sendqueue_queue(adapter->sendq, &hdr, packet);
            //("sendpacket() returned %d\n", x);
            //exit(1);
        } else
            ; //printf("+%u\n", count++);
        if (flush) {
            pcap_sendqueue_transmit(adapter->pcap, adapter->sendq, 0);

            /* Dude, I totally forget why this step is necessary. I vaguely
             * remember there's a good reason for it though */
            pcap_sendqueue_destroy(adapter->sendq);
            adapter->sendq =  pcap_sendqueue_alloc(SENDQ_SIZE);
        }
        return 0;
    }

    /* LIBPCAP */
    if (adapter->pcap)
        return pcap_sendpacket(adapter->pcap, packet, length);

    return 0;
}
Example #5
0
void main(int argc, char **argv)
{
	pcap_t *indesc,*outdesc;
	char errbuf[PCAP_ERRBUF_SIZE];
	char source[PCAP_BUF_SIZE];
	FILE *capfile;
	int caplen, sync;
	u_int res;
	pcap_send_queue *squeue;
	struct pcap_pkthdr *pktheader;
	u_char *pktdata;
	float cpu_time;
	u_int npacks = 0;
	
	/* Check the validity of the command line */
	if (argc <= 2 || argc >= 5)
	{
		usage();
		return;
	}
		
	/* Retrieve the length of the capture file */
	capfile=fopen(argv[1],"rb");
	if(!capfile){
		printf("Capture file not found!\n");
		return;
	}
	
	fseek(capfile , 0, SEEK_END);
	caplen= ftell(capfile)- sizeof(struct pcap_file_header);
	fclose(capfile);
			
	/* Chek if the timestamps must be respected */
	if(argc == 4 && argv[3][0] == 's')
		sync = TRUE;
	else
		sync = FALSE;

	/* Open the capture */
	/* Create the source string according to the new WinPcap syntax */
	if ( pcap_createsrcstr(	source,			// variable that will keep the source string
							PCAP_SRC_FILE,	// we want to open a file
							NULL,			// remote host
							NULL,			// port on the remote host
							argv[1],		// name of the file we want to open
							errbuf			// error buffer
							) != 0)
	{
		fprintf(stderr,"\nError creating a source string\n");
		return;
	}
	
	/* Open the capture file */
	if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
	{
		fprintf(stderr,"\nUnable to open the file %s.\n", source);
		return;
	}

	/* Open the output adapter */
	if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, errbuf) ) == NULL)
	{
		fprintf(stderr,"\nUnable to open adapter %s.\n", source);
		return;
	}

	/* Check the MAC type */
	if (pcap_datalink(indesc) != pcap_datalink(outdesc))
	{
		printf("Warning: the datalink of the capture differs from the one of the selected interface.\n");
		printf("Press a key to continue, or CTRL+C to stop.\n");
		getchar();
	}

	/* Allocate a send queue */
	squeue = pcap_sendqueue_alloc(caplen);

	/* Fill the queue with the packets from the file */
	while ((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1)
	{
		if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1)
		{
			printf("Warning: packet buffer too small, not all the packets will be sent.\n");
			break;
		}

		npacks++;
	}

	if (res == -1)
	{
		printf("Corrupted input file.\n");
		pcap_sendqueue_destroy(squeue);
		return;
	}

	/* Transmit the queue */
	
	cpu_time = (float)clock ();

	if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)
	{
		printf("An error occurred sending the packets: %s. Only %d bytes were sent\n", pcap_geterr(outdesc), res);
	}
	
	cpu_time = (clock() - cpu_time)/CLK_TCK;
	
	printf ("\n\nElapsed time: %5.3f\n", cpu_time);
	printf ("\nTotal packets generated = %d", npacks);
	printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time));
	printf ("\n");

	/* free the send queue */
	pcap_sendqueue_destroy(squeue);

	/* Close the input file */
	pcap_close(indesc);

	/* 
	 * lose the output adapter 
	 * IMPORTANT: remember to close the adapter, otherwise there will be no guarantee that all the 
	 * packets will be sent!
	 */
	pcap_close(outdesc);


	return;
}