[WinPcap-users] capture delay based on timestamps increases?
maffa
Wed, 20 Apr 2005 15:26:46 -0700
Hello,
Below is a sample program adapted from
the print packets sample in the documentation.
Instead of printing the packets, for
each packet it calculates the difference between the current
time and the timestamp in the pcap packet
header and puts those deltas into 500ms buckets.
It prints those buckets and the maximum
delay value after so many samples to a file. My problem
is that when capturing, for example,
from a constant bitrate 4Mbps stream, over time that maximum
delta value keeps getting larger and
larger but the program is keeping up with the input data.
If I restart the application, the delay
goes back to the minimum value.
Can anyone help explain this increased
delay in timestamps, please?
Thanks very much.
Mike Maffa
[EMAIL PROTECTED]
The sample was built using VS.NET 2003
using WinPcap3.1-Beta4
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
#include
"stdafx.h"
#define
HAVE_REMOTE
#include
"pcap.h"
__int64
m_i64_500OrLess = 0;
__int64
m_i64_500To1000 = 0;
__int64
m_i64_1000To1500 = 0;
__int64
m_i64_1500To2000 = 0;
__int64
m_i64_2000To2500 = 0;
__int64
m_i64_2500To3000 = 0;
__int64
m_i64_3000OrMore = 0;
__int64
m_i64TotalSamples = 0;
__int64
m_i64Max = 0;
__int64
m_i64Min = 0;
void
AddDeltaTimeStat(struct
timeval ts);
int
_tmain(int
argc, _TCHAR* argv[])
{
pcap_if_t *alldevs;
pcap_if_t *d;
int
inum;
int
i=0;
pcap_t *adhandle;
int
res;
char
errbuf[PCAP_ERRBUF_SIZE];
// struct tm *ltime;
// char timestr[16];
struct
pcap_pkthdr *header;
const
u_char *pkt_data;
/*
Retrieve the device list on the local machine */
if
(pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) ==
-1)
{
fprintf(stderr,"Error
in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/*
Print the list */
for(d=alldevs;
d; d=d->next)
{
printf("%d.
%s", ++i, d->name);
if
(d->description)
printf(" (%s)\n", d->description);
else
printf(" (No description available)\n");
}
if(i==0)
{
printf("\nNo
interfaces found! Make sure WinPcap is installed.\n");
return
-1;
}
printf("Enter
the interface number (1-%d):",i);
scanf("%d",
&inum);
if(inum
< 1 || inum > i)
{
printf("\nInterface
number out of range.\n");
/*
Free the device list */
pcap_freealldevs(alldevs);
return
-1;
}
/*
Jump to the selected adapter */
for(d=alldevs,
i=0; i< inum-1 ;d=d->next, i++);
/*
Open the device */
if
( (adhandle= pcap_open(d->name, //
name of the device
65536,
//
portion of the packet to capture.
//
65536 guarantees that the whole packet will be captured on all the link
layers
PCAP_OPENFLAG_PROMISCUOUS,
// promiscuous
mode
1000,
//
read timeout
NULL,
//
authentication on the remote machine
errbuf
//
error buffer
)
) == NULL)
{
fprintf(stderr,"\nUnable
to open the adapter. %s is not supported by WinPcap\n", d->name);
/*
Free the device list */
pcap_freealldevs(alldevs);
return
-1;
}
//
compile the filter
struct
bpf_program fcode;
unsigned
int
uiNetMask = 0xffffff;
char
szFilter[] = "ip and udp and dst host 238.5.5.21 and dst port 258";
if(pcap_compile(adhandle,
&fcode, szFilter, 1, uiNetMask) < 0)
{
_tprintf(_T("Unable
to compile the packet filter. Check the syntax.\n"));
}
//
set the filter
if(pcap_setfilter(adhandle,
&fcode) < 0)
{
_tprintf(_T("Unable
to set the packet filter, error from pcap_setfilter()."));
}
printf("\nlistening
on %s...\n", d->description);
/*
At this point, we don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
/*
Retrieve the packets */
while((res
= pcap_next_ex( adhandle, &header, &pkt_data)) >= 0){
if(res
== 0)
/* Timeout
elapsed */
continue;
AddDeltaTimeStat(header->ts);
/*
convert the timestamp to readable format */
//ltime=localtime(&header->ts.tv_sec);
//strftime(
timestr, sizeof timestr, "%H:%M:%S", ltime);
//printf("%s,%.6d
len:%d\n", timestr, header->ts.tv_usec, header->len);
}
if(res
== -1){
printf("Error
reading the packets: %s\n", pcap_geterr(adhandle));
return
-1;
}
return
0;
}
void
AddDeltaTimeStat(struct
timeval ts)
{
#define
EPOCHFILETIME (116444736000000000i64)
LARGE_INTEGER liNow;
FILETIME ftNow;
__int64
i64Now;
struct
timeval tvNow;
GetSystemTimeAsFileTime(&ftNow);
liNow.LowPart =
ftNow.dwLowDateTime;
liNow.HighPart = ftNow.dwHighDateTime;
i64Now = liNow.QuadPart;
/*
In 100-nanosecond intervals */
i64Now -= EPOCHFILETIME;
/*
Offset to the Epoch time */
i64Now /= 10;
/*
In microseconds */
tvNow.tv_sec =
(long)(i64Now
/ 1000000);
tvNow.tv_usec = (long)(i64Now
% 1000000);
__int64
i64TsInusec = 0;
i64TsInusec = Int32x32To64(ts.tv_sec,
1000000) + ts.tv_usec;
__int64
i64DiffInusec = 0;
if
((i64Now - i64TsInusec) > 0)
{
i64DiffInusec
= i64Now - i64TsInusec; //
in microseconds
}
__int64
i64DiffInms = i64DiffInusec / 1000; //
in milliseconds
if
(i64DiffInms <= m_i64Min)
{
m_i64Min
= i64DiffInms;
}
if
(i64DiffInms >= m_i64Max)
{
m_i64Max
= i64DiffInms;
}
//
bucketize
if
(i64DiffInms <= 500)
{
++m_i64_500OrLess;
}
else
if
((i64DiffInms > 500) && (i64DiffInms <= 1000))
{
++m_i64_500To1000;
}
else
if
((i64DiffInms > 1000) && (i64DiffInms <= 1500))
{
++m_i64_1000To1500;
}
else
if
((i64DiffInms > 1500) && (i64DiffInms <= 2000))
{
++m_i64_1500To2000;
}
else
if
((i64DiffInms > 2000) && (i64DiffInms <= 2500))
{
++m_i64_2000To2500;
}
else
if
((i64DiffInms > 2500) && (i64DiffInms <= 3000))
{
++m_i64_2500To3000;
}
else
{
++m_i64_3000OrMore;
}
++m_i64TotalSamples;
if
((m_i64TotalSamples % 200000) == 0)
{
FILE *fp
= _tfopen(_T("c:\\stats.log"), _T("a+"));
if
(fp != NULL)
{
TCHAR szTimeBuf[MAX_PATH];
FILETIME LocalFileTime;
SYSTEMTIME LocalTime;
FileTimeToLocalFileTime(&ftNow, &LocalFileTime);
FileTimeToSystemTime(&LocalFileTime, &LocalTime);
_stprintf(szTimeBuf, _T("%02d/%02d/%04d %02d:%02d:%02d.%03d"),
LocalTime.wMonth, LocalTime.wDay, LocalTime.wYear, LocalTime.wHour, LocalTime.wMinute,
LocalTime.wSecond, LocalTime.wMilliseconds);
_ftprintf(fp, _T("\n%s\n"), szTimeBuf);
_ftprintf(fp, _T("\t 500ms or less : %I64d\n"),
m_i64_500OrLess);
_ftprintf(fp, _T("\t 500ms to 1000ms : %I64d\n"),
m_i64_500To1000);
_ftprintf(fp, _T("\t 1000ms to 1500ms : %I64d\n"), m_i64_1000To1500);
_ftprintf(fp, _T("\t 1500ms to 2000ms : %I64d\n"), m_i64_1500To2000);
_ftprintf(fp, _T("\t 2000ms to 2500ms : %I64d\n"), m_i64_2000To2500);
_ftprintf(fp, _T("\t 2500ms to 3000ms : %I64d\n"), m_i64_2500To3000);
_ftprintf(fp, _T("\t 3000ms or more : %I64d\n"),
m_i64_3000OrMore);
_ftprintf(fp, _T("\t Min = %I64d, Max = %I64d\n"), m_i64Min,
m_i64Max);
fflush(fp);
fclose(fp);
}
}
return;
}
-
[WinPcap-users] capture delay based on timestamps increases?
maffa