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/[email protected]/
To unsubscribe use
mailto: [EMAIL PROTECTED]
=================================================================