Skip to content

Commit

Permalink
Calculate timestamp at retrieval, not capture. Fixes nmap#666
Browse files Browse the repository at this point in the history
  • Loading branch information
bonsaiviking committed Apr 12, 2023
1 parent 38f91c5 commit d5a38b6
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 27 deletions.
2 changes: 1 addition & 1 deletion packetWin7/npf/npf/Packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
#endif // ALLOC_PRAGMA

PNPCAP_DRIVER_EXTENSION g_pDriverExtension = NULL;

LARGE_INTEGER TimeFreq = {0};

UNICODE_STRING deviceSymLink = RTL_CONSTANT_STRING(L"\\DosDevices\\" NPF_DRIVER_NAME_WIDECHAR);

Expand Down
3 changes: 2 additions & 1 deletion packetWin7/npf/npf/Packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,8 @@ typedef struct _NPF_NBL_COPY
{
SINGLE_LIST_ENTRY NBCopiesHead;
SINGLE_LIST_ENTRY NBLCopyEntry;
struct timeval tstamp;
LARGE_INTEGER PerfCount;
LARGE_INTEGER SystemTime;
#ifdef HAVE_DOT11_SUPPORT
PUCHAR Dot11RadiotapHeader;
#endif
Expand Down
24 changes: 11 additions & 13 deletions packetWin7/npf/npf/Read.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ NPF_Read(
}

header = (struct bpf_hdr *) (packp + copied);
header->bh_tstamp = pCapData->pNBCopy->pNBLCopy->tstamp;
GET_TIMEVAL(&header->bh_tstamp, &Open->start, Open->TimestampMode, pCapData->pNBCopy->pNBLCopy);
header->bh_caplen = 0;
header->bh_datalen = pCapData->pNBCopy->ulPacketSize;
header->bh_hdrlen = sizeof(struct bpf_hdr);
Expand Down Expand Up @@ -372,7 +372,8 @@ NPF_TapExForEachOpen(
_Inout_ POPEN_INSTANCE Open,
_In_ const PNET_BUFFER_LIST pNetBufferLists,
_Inout_ PSINGLE_LIST_ENTRY NBLCopyHead,
_Inout_ struct timeval *tstamp,
_In_ LARGE_INTEGER SystemTime,
_In_ LARGE_INTEGER PerfCount,
_In_ BOOLEAN AtDispatchLevel
);

Expand All @@ -390,11 +391,13 @@ NPF_DoTap(
LOCK_STATE_EX lockState;
PNPF_NBL_COPY pNBLCopy = NULL;
SINGLE_LIST_ENTRY NBLCopiesHead;
struct timeval tstamp = {0, 0};
NBLCopiesHead.Next = NULL;
PNPF_SRC_NB pSrcNB = NULL;
PSINGLE_LIST_ENTRY pNBCopiesEntry = NULL;
LARGE_INTEGER SystemTime, PerfCount;

// TODO: Keep track of which of these is needed and what precision
GET_TIMESTAMPS(&SystemTime, &PerfCount);
/* Lock the group */
// Read-only lock since list is not being modified.
NdisAcquireRWLockRead(pFiltMod->OpenInstancesLock, &lockState,
Expand All @@ -409,7 +412,7 @@ NPF_DoTap(
if (!(TempOpen == pOpenOriginating && TempOpen->SkipSentPackets))
{
// NdisAcquireRWLockRead above raised to DISPATCH_LEVEL
NPF_TapExForEachOpen(TempOpen, NetBufferLists, &NBLCopiesHead, &tstamp, TRUE);
NPF_TapExForEachOpen(TempOpen, NetBufferLists, &NBLCopiesHead, SystemTime, PerfCount, TRUE);
}
}
}
Expand Down Expand Up @@ -697,7 +700,8 @@ NPF_TapExForEachOpen(
POPEN_INSTANCE Open,
PNET_BUFFER_LIST pNetBufferLists,
PSINGLE_LIST_ENTRY NBLCopyHead,
struct timeval *tstamp,
LARGE_INTEGER SystemTime,
LARGE_INTEGER PerfCount,
BOOLEAN AtDispatchLevel
)
{
Expand All @@ -712,7 +716,6 @@ NPF_TapExForEachOpen(
PNPF_NBL_COPY pNBLCopy = NULL;
PSINGLE_LIST_ENTRY pNBLCopyPrev = NULL;
PSINGLE_LIST_ENTRY pSrcNBPrev = NULL;
NT_ASSERT(tstamp != NULL);

//TRACE_ENTER();

Expand Down Expand Up @@ -750,13 +753,8 @@ NPF_TapExForEachOpen(
pNBLCopy->refcount = 1;
NT_ASSERT(pNBLCopy->NBLCopyEntry.Next == NULL);
pNBLCopyPrev->Next = &pNBLCopy->NBLCopyEntry;
if (tstamp->tv_sec == 0)
{
// We only get the timestamp once for all packets in this set of NBLs
// since they were all delivered at the same time.
GET_TIME(tstamp, &Open->start, Open->TimestampMode);
}
pNBLCopy->tstamp = *tstamp;
pNBLCopy->SystemTime = SystemTime;
pNBLCopy->PerfCount = PerfCount;
}
else
{
Expand Down
68 changes: 56 additions & 12 deletions packetWin7/npf/npf/time_calls.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@
#define TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE 4
#define /* DEPRECATED */ TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP 99

extern LARGE_INTEGER TimeFreq;

inline BOOLEAN NPF_TimestampModeSupported(_In_ ULONG mode)
{
return mode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION
Expand Down Expand Up @@ -156,7 +158,7 @@ inline void TIME_SYNCHRONIZE(
LARGE_INTEGER SystemTime;
//LARGE_INTEGER i;
//ULONG tmp2;
LARGE_INTEGER TimeFreq, PTime;
LARGE_INTEGER PTime;

// get the absolute value of the system boot time.
PTime = KeQueryPerformanceCounter(&TimeFreq);
Expand All @@ -177,15 +179,13 @@ inline void TIME_SYNCHRONIZE(
}
}

inline void GetTimeKQPC(
inline void GetTimevalFromPerfCount(
_Out_ struct timeval* dst,
_In_ struct timeval* start)
_In_ struct timeval* start,
_In_ LARGE_INTEGER PTime)
{
LARGE_INTEGER PTime, TimeFreq;
LONG tmp;

PTime = KeQueryPerformanceCounter(&TimeFreq);
tmp = (LONG)(PTime.QuadPart / TimeFreq.QuadPart);
NT_ASSERT(TimeFreq.QuadPart != 0);
LONG tmp = (LONG)(PTime.QuadPart / TimeFreq.QuadPart);

//it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION
dst->tv_sec = start->tv_sec + tmp;
Expand All @@ -198,15 +198,32 @@ inline void GetTimeKQPC(
}
}

inline void GetTimeKQPC(
_Out_ struct timeval* dst,
_In_ struct timeval* start)
{
LARGE_INTEGER PTime;

PTime = KeQueryPerformanceCounter(NULL);
GetTimevalFromPerfCount(dst, start, PTime);
}

inline void GetTimevalFromSystemTime(
_Out_ struct timeval* dst,
_In_ LARGE_INTEGER SystemTime)
{
dst->tv_sec = (LONG)(SystemTime.QuadPart / 10000000 - 11644473600);
dst->tv_usec = (LONG)((SystemTime.QuadPart % 10000000) / 10);
}

inline void GetTimeQST(
_Out_ struct timeval* dst)
{
LARGE_INTEGER SystemTime;

KeQuerySystemTime(&SystemTime);

dst->tv_sec = (LONG)(SystemTime.QuadPart / 10000000 - 11644473600);
dst->tv_usec = (LONG)((SystemTime.QuadPart % 10000000) / 10);
GetTimevalFromSystemTime(dst, SystemTime);
}

inline void GetTimeQST_precise(
Expand All @@ -216,8 +233,7 @@ inline void GetTimeQST_precise(

BestQuerySystemTime(&SystemTime);

dst->tv_sec = (LONG)(SystemTime.QuadPart / 10000000 - 11644473600);
dst->tv_usec = (LONG)((SystemTime.QuadPart % 10000000) / 10);
GetTimevalFromSystemTime(dst, SystemTime);
}


Expand All @@ -240,5 +256,33 @@ inline void GET_TIME(
}
}

inline void GET_TIMESTAMPS(
_Out_opt_ PLARGE_INTEGER pSystemTime,
_Out_opt_ PLARGE_INTEGER pPerfCount)
{
if (pSystemTime)
BestQuerySystemTime(pSystemTime);
if (pPerfCount)
*pPerfCount = KeQueryPerformanceCounter(NULL);
}

inline void GET_TIMEVAL(
_Out_ struct timeval *tstamp,
_In_ struct timeval* start,
_In_ ULONG TimestampMode,
_In_ PNPF_NBL_COPY pNBLCopy)
{
switch (TimestampMode)
{
case TIMESTAMPMODE_QUERYSYSTEMTIME:
case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE:
GetTimevalFromSystemTime(tstamp, pNBLCopy->SystemTime);
break;
default:
GetTimevalFromPerfCount(tstamp, start, pNBLCopy->PerfCount);
break;
}
}


#endif /*_time_calls*/

0 comments on commit d5a38b6

Please sign in to comment.