diff --git a/packetWin7/npf/npf/Openclos.c b/packetWin7/npf/npf/Openclos.c index 34341b5e..010f0591 100644 --- a/packetWin7/npf/npf/Openclos.c +++ b/packetWin7/npf/npf/Openclos.c @@ -691,7 +691,20 @@ NPF_StartUsingOpenInstance( { // Get the absolute value of the system boot time. // This is used for timestamp conversion. - TIME_SYNCHRONIZE(&pOpen->start); + if (pOpen->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE) + { + // When using relative QPC timestamps, we skip system clock + // synchronisation and just set the start time to 0. + pOpen->start.tv_sec = 0; + pOpen->start.tv_usec = 0; + + // But, we must make sure the performance counter frequency is still initialised. + KeQueryPerformanceCounter(&TimeFreq); + } + else + { + TIME_SYNCHRONIZE(&pOpen->start); + } NPF_UpdateTimestampModeCounts(pOpen->pFiltMod, pOpen->TimestampMode, TIMESTAMPMODE_UNSET); // Insert a null filter (accept all) @@ -2260,7 +2273,7 @@ NPF_AttachAdapter( pFiltMod->AdapterBindingStatus = FilterPaused; NPF_AddToFilterModuleArray(pFiltMod); // If any handles are running, enable ops again. - if (pFiltMod->nTimestampQPC > 0 || pFiltMod->nTimestampQST > 0 || pFiltMod->nTimestampQST_Precise > 0) + if (pFiltMod->nTimestampQPC > 0 || pFiltMod->nTimestampQST > 0 || pFiltMod->nTimestampQST_Precise > 0 || pFiltMod->nTimestampQPC_Relative > 0) { NPF_EnableOps(pFiltMod); } @@ -2496,7 +2509,7 @@ NOTE: Called at PASSIVE_LEVEL and the filter is in paused state Curr = PopEntryList(&pFiltMod->OpenInstances); } NdisReleaseRWLock(pFiltMod->OpenInstancesLock, &lockState); - NT_ASSERT(pFiltMod->nTimestampQPC == 0 && pFiltMod->nTimestampQST == 0 && pFiltMod->nTimestampQST_Precise == 0); + NT_ASSERT(pFiltMod->nTimestampQPC == 0 && pFiltMod->nTimestampQST == 0 && pFiltMod->nTimestampQST_Precise == 0 && pFiltMod->nTimestampQPC_Relative == 0); // Restore original filter and lookahead value NPF_SetPacketFilter(pFiltMod, 0); @@ -3479,6 +3492,9 @@ VOID NPF_UpdateTimestampModeCounts( case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE: result = InterlockedIncrement(&pFiltMod->nTimestampQST_Precise); break; + case TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE: + result = InterlockedIncrement(&pFiltMod->nTimestampQPC_Relative); + break; default: NT_ASSERT(FALSE); break; @@ -3498,6 +3514,9 @@ VOID NPF_UpdateTimestampModeCounts( case TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE: result = InterlockedDecrement(&pFiltMod->nTimestampQST_Precise); break; + case TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE: + result = InterlockedDecrement(&pFiltMod->nTimestampQPC_Relative); + break; default: NT_ASSERT(FALSE); break; diff --git a/packetWin7/npf/npf/Packet.c b/packetWin7/npf/npf/Packet.c index d0e233aa..320ec734 100644 --- a/packetWin7/npf/npf/Packet.c +++ b/packetWin7/npf/npf/Packet.c @@ -1864,13 +1864,14 @@ static NTSTATUS funcBIOCGTIMESTAMPMODES(_In_ POPEN_INSTANCE pOpen, // Need to at least deliver the number of modes ULONG uNeeded = sizeof(ULONG); static ULONG SupportedModes[] = { - 0, // count of modes, 0 means not initialized yet - TIMESTAMPMODE_SINGLE_SYNCHRONIZATION, - TIMESTAMPMODE_QUERYSYSTEMTIME, + 0 // count of modes, 0 means not initialized yet + , TIMESTAMPMODE_SINGLE_SYNCHRONIZATION + , TIMESTAMPMODE_QUERYSYSTEMTIME #if (NTDDI_VERSION >= NTDDI_WIN8) // This is last and is not reported if not different than QST - TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE + , TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE #endif + , TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE }; // Initialize the count if not already done. diff --git a/packetWin7/npf/npf/Packet.h b/packetWin7/npf/npf/Packet.h index 7f35599b..42f3678f 100644 --- a/packetWin7/npf/npf/Packet.h +++ b/packetWin7/npf/npf/Packet.h @@ -348,6 +348,7 @@ typedef struct _NPCAP_FILTER_MODULE LONG nTimestampQPC; // Opens wanting TIMESTAMPMODE_SINGLE_SYNCHRONIZATION LONG nTimestampQST; // Opens wanting TIMESTAMPMODE_QUERYSYSTEMTIME LONG nTimestampQST_Precise; // Opens wanting TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE + LONG nTimestampQPC_Relative; // Opens wanting TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE ULONG SupportedPacketFilters; ULONG MyPacketFilter; diff --git a/packetWin7/npf/npf/Read.c b/packetWin7/npf/npf/Read.c index d2cc47b6..5e28dfd7 100644 --- a/packetWin7/npf/npf/Read.c +++ b/packetWin7/npf/npf/Read.c @@ -300,7 +300,7 @@ NPF_Read( GetTimevalFromSystemTime(&header->bh_tstamp, pCapData->pNBCopy->pNBLCopy->SystemTime); break; default: - NT_ASSERT(Open->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION); + NT_ASSERT(Open->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION || Open->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE); NT_ASSERT(pCapData->pNBCopy->pNBLCopy->PerfCount.QuadPart > 0); GetTimevalFromPerfCount(&header->bh_tstamp, &Open->start, pCapData->pNBCopy->pNBLCopy->PerfCount); break; @@ -740,13 +740,13 @@ NPF_DoTap( PNPF_CAP_DATA pCaptures = NULL; /* Get relevant timestamps */ - if (pFiltMod->nTimestampQPC == 0 && pFiltMod->nTimestampQST == 0 && pFiltMod->nTimestampQST_Precise == 0) + if (pFiltMod->nTimestampQPC == 0 && pFiltMod->nTimestampQST == 0 && pFiltMod->nTimestampQST_Precise == 0 && pFiltMod->nTimestampQPC_Relative == 0) { // No instances at OpenRunning return; } // Any instances need performance counter? - if (pFiltMod->nTimestampQPC > 0) + if (pFiltMod->nTimestampQPC > 0 || pFiltMod->nTimestampQPC_Relative > 0) { PerfCount = KeQueryPerformanceCounter(NULL); } @@ -1115,10 +1115,13 @@ NPF_TapExForEachOpen( ULONG TotalPacketSize = pNBCopy->ulPacketSize; BOOLEAN bEnqueued = FALSE; - NT_ASSERT((Open->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION && pNBLCopy->PerfCount.QuadPart > 0) - || ((Open->TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME - || Open->TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE) - && pNBLCopy->SystemTime.QuadPart > 0)); + NT_ASSERT( + ((Open->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION + || Open->TimestampMode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE) + && pNBLCopy->PerfCount.QuadPart > 0) + || ((Open->TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME + || Open->TimestampMode == TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE) + && pNBLCopy->SystemTime.QuadPart > 0)); if (!Open->bModeCapt) { diff --git a/packetWin7/npf/npf/time_calls.h b/packetWin7/npf/npf/time_calls.h index 36e30f30..b8a4ec71 100644 --- a/packetWin7/npf/npf/time_calls.h +++ b/packetWin7/npf/npf/time_calls.h @@ -112,6 +112,7 @@ #define TIMESTAMPMODE_QUERYSYSTEMTIME 2 #define /* DEPRECATED */ TIMESTAMPMODE_RDTSC 3 #define TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE 4 +#define TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE 5 #define /* DEPRECATED */ TIMESTAMPMODE_SYNCHRONIZATION_ON_CPU_NO_FIXUP 99 #define TIMESTAMPMODE_UNSET ((ULONG) -1) @@ -122,7 +123,8 @@ inline BOOLEAN NPF_TimestampModeSupported(_In_ ULONG mode) { return mode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION || mode == TIMESTAMPMODE_QUERYSYSTEMTIME - || mode == TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE; + || mode == TIMESTAMPMODE_QUERYSYSTEMTIME_PRECISE + || mode == TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE; } inline void BestQuerySystemTime( @@ -189,7 +191,7 @@ inline void GetTimevalFromPerfCount( NT_ASSERT(TimeFreq.QuadPart != 0); LONG tmp = (LONG)(PTime.QuadPart / TimeFreq.QuadPart); - //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION + //it should be only the normal case i.e. TIMESTAMPMODE_SINGLESYNCHRONIZATION (or TIMESTAMPMODE_SINGLE_SYNCHRONIZATION_RELATIVE) dst->tv_sec = start->tv_sec + tmp; dst->tv_usec = start->tv_usec + (LONG)((PTime.QuadPart % TimeFreq.QuadPart) * 1000000 / TimeFreq.QuadPart);