Hi,

I want to design a program, which can send packets from a libpcap format file 
to an Ethernet network. As the example in the WinPcap manual "sendcap.c", I use 
the following function of WinPcap(3.0) with Windows Net4.0 : 
"pcap_open_offline" to open the capture,
"pcap_open_live" to open the output adaptater,
"pcap_sendqueue_queue" to fill the queue,
"pcap_sendqueue_transmit" to transmit the queue.

This example work correctly. However I want to change the timestamp in order to 
send the packets faster or slower to test the performance of a receiver. After 
the program has extracted the packet with the command "res = pcap_next_ex( 
indesc, &pktheader, &pktdata))", I have add 2 lines in order to modify the 
timeval in the packet header before the packet are sent in the queue : 
"       (*pktheader).ts.tv_usec = timeusec[j];
        (*pktheader).ts.tv_sec = timesec[j++];
"
timeusec and timesec are tables which contain the new timestamp values. I use 
Ethereal (Version 0.10.9) to sniff the network. And here comes the problems. 
The "sync" value is TRUE. And the timestamps I measure are different to the 
value that I have entered in the tables (for example: long timeusec[10] = 
{258155,  258185,  258215,  258315,  258415,  258515,  259015,  259515,  
260015, 260035};. long timesec[10] = {1108287570, 1108287570, 1108287570, 
1108287570, 1108287570, 1108287570, 1108287570, 1108287570, 1108287570, 
1108287570};). I obtain the same timestamp than if the sync = FALSE.
But when I enter in the table the origin timestamps of the file, that work 
correctly with a good precision. 
Whereas when I entered timestamps above 100000usec (long timeusec[10] = 
{0,100000,200000,300000,400000,500000,600000,700000,800000,900000};) that also 
work correctly. Nevertheless the timestamp monitored are not as accurate than 
with the origin timestamps.
I noticed that when I send 10 packets with timestamp below to 100000usec, the 
program call the function DeviceIoControl (in the function PacketSendPackets 
[packet.dll]) only one time. If I put timestamp equal 1 sec, he call 10 times 
this functions. 

How can I do to change the timestamp with a quite good accuracy (about 100usec) 
of a libpcap file that I send? What is the issue with my program (I give you a 
copy)?   

François


/*----------------------------------------------*/
/*                sendcap.c                     */
/*----------------------------------------------*/


#include <stdlib.h>
#include <stdio.h>

#include <pcap.h>


void find_device(pcap_if_t **all_devices);


void main(int argc, char **argv) {
        int j;
        pcap_if_t *all_devices;
        pcap_t *indesc,*outdesc;
        char error[PCAP_ERRBUF_SIZE];
        FILE *capfile;
        char *capture_file;
        int caplen,
        sync = TRUE; 
        int nb=0;
        u_int res;
        pcap_send_queue *squeue;
        struct pcap_pkthdr *pktheader;
        struct pcap_pkthdr nextpkt;
        u_char *pktdata;

        long timeusec[10] = {258155,      258185,     258215,     258315,     
258415,     258515,      259015,    259515,     260015,     260035};
        long timesec[10] = {1108287570, 1108287570, 1108287570, 1108287570, 
1108287570, 1108287570, 1108287570, 1108287570, 1108287570, 1108287570};

        capture_file = "capturefile.pcp";

        find_device(&all_devices);
        printf("Device name : %s\n", all_devices->name);
        printf("sync = %d\n",sync);
        
        capfile=fopen(capture_file,"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);
                        

        /* Open the capture */
        if((indesc = pcap_open_offline(capture_file, error)) == NULL){
                fprintf(stderr,"\nError opening the input file: %s\n", error);
                return; 
        }

        /* Open the output adapter */
        if((outdesc = pcap_open_live(all_devices->name, 1000, 1, 1000, error) ) 
== NULL)
        {
                fprintf(stderr,"\nError opening adapter: %s\n", error);
                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);
        j = 0;
        /* Fill the queue with the packets from the file */
        while((res = pcap_next_ex( indesc, &pktheader, &pktdata)) == 1){
        
        (*pktheader).ts.tv_usec = timeusec[j++];
        (*pktheader).ts.tv_sec = timesec[j];

        printf("tv_sec %ld |tv_usec %ld | len:%d | timestamp : %ld\n", 
pktheader->ts.tv_sec, pktheader->ts.tv_usec, pktheader->len, 
pktheader->ts.tv_usec - nextpkt.ts.tv_usec);
        nextpkt.ts.tv_usec = (*pktheader).ts.tv_usec;   


                if(pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1){
                        printf("Warning: packet buffer too small, not all the 
packets will be sent.\n");
                        break;
                }
        }
        if(res == -1){

                printf("Corrupted input file.\n");
                pcap_sendqueue_destroy(squeue);
                return;
        }

        /* Transmit the queue */
        
        if((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) < squeue->len)
        {
                printf("An error occurred sending the packets: %s. Only %d 
bytes were sent\n", error, res);
        }
        
        /* free the send queue */
        pcap_sendqueue_destroy(squeue);

        return;
}


/*-------------------------------------------------------------------------------*/

void find_device(pcap_if_t **all_devices)
{


    int i=0;
    char errbuf[PCAP_ERRBUF_SIZE];
    
    /* Retrieve the device list */
    if (pcap_findalldevs(&(*all_devices), errbuf) == -1)
    {
        fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
        exit(1);
    }
    


}


================================================================= This is the 
WinPcap users list. It is archived at
 http://www.mail-archive.com/winpcap-users@winpcap.polito.it/

 To unsubscribe use
 mailto: [EMAIL PROTECTED]
=================================================================

Reply via email to