Skip to content

Commit

Permalink
Loopback capture support with new device organization
Browse files Browse the repository at this point in the history
  • Loading branch information
bonsaiviking committed Aug 22, 2019
1 parent 545c677 commit 1a9f318
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 142 deletions.
11 changes: 8 additions & 3 deletions Common/WpcapNames.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,17 @@
// Used in packetWin7\Dll and the driver
#define NPF_DEVICE_NAMES_PREFIX NPF_DRIVER_NAME "\\" ///< (AAA) packet.dll
#define NPF_DEVICE_NAMES_PREFIX_WIDECHAR NPF_DRIVER_NAME_WIDECHAR L"\\" ///< (AAA) used by the NPF driver, that does not accept the TEXT(a) macro correctly.
#define NPF_DEVICE_NAMES_PREFIX_WIFI NPF_DEVICE_NAMES_PREFIX "\\WIFI_"
#define NPF_DEVICE_NAMES_PREFIX_WIDECHAR_WIFI NPF_DEVICE_NAMES_PREFIX_WIDECHAR L"\\WIFI_"
#define NPF_DEVICE_NAMES_TAG_WIFI "WIFI_"
#define NPF_DEVICE_NAMES_TAG_WIDECHAR_WIFI L"WIFI_"
#define NPF_DEVICE_NAMES_PREFIX_WIFI NPF_DEVICE_NAMES_PREFIX NPF_DEVICE_NAMES_TAG_WIFI
#define NPF_DEVICE_NAMES_PREFIX_WIDECHAR_WIFI NPF_DEVICE_NAMES_PREFIX_WIDECHAR NPF_DEVICE_NAMES_TAG_WIDECHAR_WIFI

// Used in packetWin7\Dll
#define FAKE_NDISWAN_ADAPTER_NAME "\\Device\\" NPF_DRIVER_NAME "_GenericDialupAdapter" ///< (CCC) Name of a fake ndiswan adapter that is always available on 2000/XP/2003, used to capture NCP/LCP packets
#define FAKE_NDISWAN_ADAPTER_NAME "\\Device\\" NPF_DRIVER_NAME "\\GenericDialupAdapter" ///< (CCC) Name of a fake ndiswan adapter that is always available on 2000/XP/2003, used to capture NCP/LCP packets
#define FAKE_NDISWAN_ADAPTER_DESCRIPTION "Adapter for generic dialup and VPN capture" ///< (DDD) Description of a fake ndiswan adapter that is always available on 2000/XP/2003, used to capture NCP/LCP packets
// Used in packetWin7\Dll
#define FAKE_LOOPBACK_ADAPTER_NAME "\\Device\\" NPF_DRIVER_NAME "\\Loopback" ///< (CCC) Name of a fake loopback adapter
#define FAKE_LOOPBACK_ADAPTER_DESCRIPTION "Adapter for loopback traffic capture" ///< (DDD) Description of a fake loopback adapter that is always available

// Used in packetWin7\Dll, NPFInstall and the driver
#define NPF_SERVICE_DESC NPF_DRIVER_NAME_NORMAL " Packet Driver (" NPF_DRIVER_NAME ")" ///< (FFF) packet.dll
Expand Down
58 changes: 57 additions & 1 deletion packetWin7/Dll/AdInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@


static BOOLEAN PacketAddFakeNdisWanAdapter();
static BOOLEAN PacketAddFakeLoopbackAdapter();

#ifdef HAVE_IPHELPER_API
static BOOLEAN IsIPv4Enabled(LPCSTR AdapterNameA);
Expand Down Expand Up @@ -2187,6 +2188,8 @@ BOOLEAN PacketUpdateAdInfo(PCHAR AdapterName)
PacketAddFakeNdisWanAdapter();
#endif //HAVE_WANPACKET_API

PacketAddFakeLoopbackAdapter();

#ifdef HAVE_DAG_API
if(g_p_dagc_open != NULL)
{
Expand Down Expand Up @@ -2266,6 +2269,11 @@ void PacketPopulateAdaptersInfoList()
}
#endif // HAVE_WANPACKET_API

if (!PacketAddFakeLoopbackAdapter())
{
TRACE_PRINT("PacketPopulateAdaptersInfoList: adding fake Loopback adapter failed.");
}

#ifdef HAVE_AIRPCAP_API
if(g_PAirpcapGetDeviceList) // Ensure that the airpcap dll is present
{
Expand Down Expand Up @@ -2301,6 +2309,54 @@ void PacketPopulateAdaptersInfoList()
TRACE_EXIT();
}

static BOOLEAN PacketAddFakeLoopbackAdapter()
{
//this function should acquire the g_AdaptersInfoMutex, since it's NOT called with an ADAPTER_INFO as parameter
PADAPTER_INFO TmpAdInfo, SAdInfo;
CHAR LoopbackName[MAX_WINPCAP_KEY_CHARS] = FAKE_LOOPBACK_ADAPTER_NAME;
CHAR LoopbackDesc[MAX_WINPCAP_KEY_CHARS] = FAKE_LOOPBACK_ADAPTER_DESCRIPTION;

TRACE_ENTER();


WaitForSingleObject(g_AdaptersInfoMutex, INFINITE);

for(SAdInfo = g_AdaptersInfoList; SAdInfo != NULL; SAdInfo = SAdInfo->Next)
{
if(strcmp(LoopbackName, SAdInfo->Name) == 0)
{
TRACE_PRINT("PacketAddFakeLoopbackAdapter: Adapter already present in the list");
ReleaseMutex(g_AdaptersInfoMutex);
TRACE_EXIT();
return TRUE;
}
}

TmpAdInfo = (PADAPTER_INFO) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
if (TmpAdInfo == NULL)
{
TRACE_PRINT("PacketAddFakeLoopbackAdapter: GlobalAlloc Failed allocating memory for the AdInfo structure");
ReleaseMutex(g_AdaptersInfoMutex);
TRACE_EXIT();
return FALSE;
}

strncpy(TmpAdInfo->Name, LoopbackName, sizeof(TmpAdInfo->Name) - 1);
strncpy(TmpAdInfo->Description, LoopbackDesc, sizeof(TmpAdInfo->Description) - 1);
TmpAdInfo->LinkLayer.LinkType = NdisMediumNull;
TmpAdInfo->LinkLayer.LinkSpeed = 10 * 1000 * 1000; //we emulate a fake 10MBit Ethernet
TmpAdInfo->Flags = 0;
memset(TmpAdInfo->MacAddress,'0',6);
TmpAdInfo->MacAddressLen = 6;
TmpAdInfo->pNetworkAddresses = NULL;

TmpAdInfo->Next = g_AdaptersInfoList;
g_AdaptersInfoList = TmpAdInfo;
ReleaseMutex(g_AdaptersInfoMutex);

TRACE_EXIT();
return TRUE;
}
#ifdef HAVE_WANPACKET_API

static BOOLEAN PacketAddFakeNdisWanAdapter()
Expand Down Expand Up @@ -2354,7 +2410,7 @@ static BOOLEAN PacketAddFakeNdisWanAdapter()
}
}

TmpAdInfo = GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
TmpAdInfo = (PADAPTER_INFO) GlobalAllocPtr(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(ADAPTER_INFO));
if (TmpAdInfo == NULL)
{
TRACE_PRINT("PacketAddFakeNdisWanAdapter: GlobalAlloc Failed allocating memory for the AdInfo structure");
Expand Down
33 changes: 16 additions & 17 deletions packetWin7/Dll/Packet32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ HANDLE g_hNpcapHelperPipe = INVALID_HANDLE_VALUE; // Handle for NpcapHelper n
HANDLE g_hDllHandle = NULL; // The handle to this DLL.

CHAR g_strLoopbackAdapterName[BUFSIZE] = ""; // The name of "Npcap Loopback Adapter".
#define NPCAP_LOOPBACK_ADAPTER_BUILTIN "NPF_Loopback"

map<string, int> g_nbAdapterMonitorModes; // The states for all the wireless adapters that show whether it is in the monitor mode.

Expand Down Expand Up @@ -954,28 +955,17 @@ PCHAR NpcapTranslateAdapterName_Standard2Wifi(PCHAR AdapterName)
{
TRACE_ENTER();
TRACE_EXIT();
return NpcapReplaceString(AdapterName, "_{", "_WIFI_{");
return NpcapReplaceString(AdapterName, "{", NPF_DEVICE_NAMES_TAG_WIFI "{");
}

PCHAR NpcapTranslateAdapterName_Npf2Npcap(PCHAR AdapterName)
{
#ifdef NPF_NPCAP_RUN_IN_WINPCAP_MODE
UNREFERENCED_PARAMETER(AdapterName);
return NULL;
#else
return NpcapReplaceString(AdapterName, "NPF", "NPCAP");
#endif
return NpcapReplaceString(AdapterName, "NPF_", NPF_DEVICE_NAMES_PREFIX);
}

PCHAR NpcapTranslateMemory_Npcap2Npf(PCHAR pStr, int iBufSize)
{
#ifdef NPF_NPCAP_RUN_IN_WINPCAP_MODE
UNREFERENCED_PARAMETER(pStr);
UNREFERENCED_PARAMETER(iBufSize);
return NULL;
#else
return NpcapReplaceMemory(pStr, iBufSize, "NPCAP", "NPF");
#endif
return NpcapReplaceMemory(pStr, iBufSize, NPF_DEVICE_NAMES_PREFIX, "NPF_");
}

/*!
Expand Down Expand Up @@ -4865,9 +4855,18 @@ BOOLEAN PacketIsLoopbackAdapter(PCHAR AdapterName)

TRACE_ENTER();

// Set the return value to TRUE for "Npcap Loopback Adapter".
if (strcmp(g_strLoopbackAdapterName + sizeof(DEVICE_PREFIX) - 1,
AdapterName + sizeof(DEVICE_PREFIX) - 1 + sizeof(NPF_DEVICE_NAMES_PREFIX) - 1) == 0)
if (strlen(AdapterName) < sizeof(DEVICE_PREFIX)) {
// The adapter name is too short.
ret = FALSE;
}
// Compare to NPF_Loopback
else if (strcmp(AdapterName + sizeof(DEVICE_PREFIX) - 1, NPCAP_LOOPBACK_ADAPTER_BUILTIN) == 0 ||
// or compare to value in Registry, if it's found and long enough.
(strlen(g_strLoopbackAdapterName) > sizeof(DEVICE_PREFIX) &&
strlen(AdapterName) > sizeof(DEVICE_PREFIX) - 1 + sizeof(NPF_DEVICE_NAMES_PREFIX) &&
strcmp(g_strLoopbackAdapterName + sizeof(DEVICE_PREFIX) - 1,
AdapterName + sizeof(DEVICE_PREFIX) - 1 + sizeof(NPF_DEVICE_NAMES_PREFIX) - 1) == 0)
)
{
ret = TRUE;
}
Expand Down
66 changes: 49 additions & 17 deletions packetWin7/npf/npf/Openclos.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ extern ULONG g_Dot11SupportMode;

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
extern HANDLE g_WFPEngineHandle;
extern PDEVICE_OBJECT g_LoopbackDevObj;
#endif

static
Expand Down Expand Up @@ -299,7 +298,7 @@ NPF_OpenAdapter(
{
if (g_WFPEngineHandle == INVALID_HANDLE_VALUE)
{
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "g_LoopbackDevObj=%p, init WSK injection handles and register callouts", g_LoopbackDevObj);
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "init WSK injection handles and register callouts");
// Use Windows Filtering Platform (WFP) to capture loopback packets, also help WSK take care of loopback packet sending.
Status = NPF_InitInjectionHandles();
if (!NT_SUCCESS(Status))
Expand All @@ -321,7 +320,7 @@ NPF_OpenAdapter(
else

{
TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "g_LoopbackDevObj=%p, NO need to init WSK code", g_LoopbackDevObj);
TRACE_MESSAGE(PACKET_DEBUG_LOUD, "g_WFPEngineHandle invalid, not initializing WSK handles");
}

TRACE_MESSAGE1(PACKET_DEBUG_LOUD, "This is loopback adapter, set MTU to: %u", NPF_LOOPBACK_INTERFACR_MTU + ETHER_HDR_LEN);
Expand Down Expand Up @@ -1302,9 +1301,30 @@ NPF_GetFilterModuleByAdapterName(
size_t i = 0;
size_t shrink_by = 0;
BOOLEAN Dot11 = FALSE;
NDIS_STRING BaseName;
BOOLEAN Loopback = FALSE;
NDIS_STRING BaseName = NDIS_STRING_CONST("Loopback");
WCHAR *pName = NULL;
TRACE_ENTER();

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
// If this is *not* the legacy loopback name, we'll have to set up BaseName to be the real name of the buffer.
if (g_LoopbackAdapterName.Buffer != NULL) {
// strip off leading backslashes
while (shrink_by < pAdapterName->Length && pAdapterName->Buffer[shrink_by] == L'\\') {
shrink_by++;
}
if (RtlCompareMemory(g_LoopbackAdapterName.Buffer + devicePrefix.Length / 2, pAdapterName->Buffer + shrink_by,
pAdapterName->Length - shrink_by / 2) == pAdapterName->Length - shrink_by / 2)
{
Loopback = TRUE;
}
// Restore shrink_by in case this wasn't a match.
shrink_by = 0;
}

if (!Loopback) {
#endif

BaseName.MaximumLength = pAdapterName->MaximumLength;
BaseName.Buffer = ExAllocatePoolWithTag(NonPagedPool, BaseName.MaximumLength, 'GFBN');
if (BaseName.Buffer == NULL) {
Expand All @@ -1331,6 +1351,10 @@ NPF_GetFilterModuleByAdapterName(
}
BaseName.Length = BaseName.Length - shrink_by*sizeof(WCHAR);

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
} //end if !Loopback
#endif

NdisAcquireSpinLock(&g_FilterArrayLock);
for (Curr = g_arrFiltMod.Next; Curr != NULL; Curr = Curr->Next)
{
Expand All @@ -1344,7 +1368,9 @@ NPF_GetFilterModuleByAdapterName(
{
NPF_StopUsingBinding(pFiltMod);
NdisReleaseSpinLock(&g_FilterArrayLock);
ExFreePoolWithTag(BaseName.Buffer, 'GFBN');
if (!Loopback) {
ExFreePoolWithTag(BaseName.Buffer, 'GFBN');
}
return pFiltMod;
}
else
Expand All @@ -1353,7 +1379,9 @@ NPF_GetFilterModuleByAdapterName(
}
}
NdisReleaseSpinLock(&g_FilterArrayLock);
ExFreePoolWithTag(BaseName.Buffer, 'GFBN');
if (!Loopback) {
ExFreePoolWithTag(BaseName.Buffer, 'GFBN');
}

TRACE_EXIT();
return NULL;
Expand Down Expand Up @@ -1732,27 +1760,31 @@ NPF_AttachAdapter(
// break;
// }

// create the adapter object
pFiltMod = NPF_CreateFilterModule(AttachParameters->BaseMiniportName, AttachParameters->MiniportMediaType);
if (pFiltMod == NULL)
{
returnStatus = NDIS_STATUS_RESOURCES;
TRACE_EXIT();
return returnStatus;
}

#ifdef HAVE_WFP_LOOPBACK_SUPPORT
// Determine whether this is our loopback adapter
// Determine whether this is the legacy loopback adapter
if (g_LoopbackAdapterName.Buffer != NULL)
{
if (RtlCompareMemory(g_LoopbackAdapterName.Buffer + devicePrefix.Length / 2, AttachParameters->BaseMiniportName->Buffer + devicePrefix.Length / 2,
AttachParameters->BaseMiniportName->Length - devicePrefix.Length) == AttachParameters->BaseMiniportName->Length - devicePrefix.Length)
{
pFiltMod->Loopback = TRUE;
// This request is for the legacy loopback adapter listed in the Registry.
// Since we now have a fake filter module for this, deny the binding.
// We'll intercept open requests for this name elsewhere and redirect to the fake one.
returnStatus = NDIS_STATUS_NOT_SUPPORTED;
break;
}
}
#endif

// create the adapter object
pFiltMod = NPF_CreateFilterModule(AttachParameters->BaseMiniportName, AttachParameters->MiniportMediaType);
if (pFiltMod == NULL)
{
returnStatus = NDIS_STATUS_RESOURCES;
TRACE_EXIT();
return returnStatus;
}

#ifdef HAVE_RX_SUPPORT
// Determine whether this is our send-to-Rx adapter for the open_instance.
if (g_SendToRxAdapterName.Buffer != NULL)
Expand Down
Loading

0 comments on commit 1a9f318

Please sign in to comment.