You must download and install the signed network filter driver from https://www.ntkernel.com/downloads/Wind ... %20x64.msi
You must also put the dll/lib files in the same folder as the PB source code. I have compiled them for you download from https://1drv.ms/u/s!AufD7SJtv9Nuj5Ukx6v ... w?e=pIXRMy
I have posted this in the hope that someone can modify it to use the Fast I/O functions included in the lib. Fast I/O can improve performance a lot.
Api docs can be found here https://www.ntkernel.com/docs/windows-p ... mentation/
You will need at least 2 Ethernet Adapters. You must also set the correct adapter index in the source for each adapter.
I have tested this with a dual 10Gbit Intel Nic and I can pass 5.5Gb/sec in one direction limited by the routers CPU. The PC CPU usage is 80% per thread but that's with HT enabled on the CPU. Multithreading is possible but packets have to be queued in the correct order before being sent.
The Library is free for non commercial use.
Have fun
**** UPDATE ****
ENABLE THREADSAFE!!
Code: Select all
EnableExplicit
SetPriorityClass_(GetCurrentProcess_(),#HIGH_PRIORITY_CLASS)
#NDIS_PACKET_TYPE_PROMISCUOUS = $00000020
#MSTCP_FLAG_RECV_TUNNEL = $00000002; // Receive packets instead MSTCP
#MSTCP_FLAG_FILTER_DIRECT = $00000010; // In promiscuous mode TCP/IP stack receives all
#MSTCP_FLAG_LOOPBACK_BLOCK = $00000040; // Silently drop loopback packets, this flag
#PACKET_FLAG_ON_SEND = $00000001
#PACKET_FLAG_ON_RECEIVE = $00000002
Structure _ADAPTER_MODE Align 1
*hAdapterHandle
dwFlags.l
EndStructure
Structure LIST_ENTRY Align 1
*Flink
*Blink
EndStructure
Structure _INTERMEDIATE_BUFFER Align 1
m_qLink.LIST_ENTRY
m_dwDeviceFlags.l
m_Length.l
m_Flags.l; // NDIS_PACKET flags
m_8021q.l; // 802.1q info
m_FilterID.l
m_Reserved.l[4]
m_IBuffer.a[1514]
EndStructure
Structure _ETH_M_REQUEST Align 1
*hAdapterHandle
dwPacketsNumber.l
dwPacketsSuccess.l
*EthPacket._INTERMEDIATE_BUFFER[256]
EndStructure
Structure eal Align 1
mac_char.b[6]
EndStructure
Structure names Align 1
name.b[256]
EndStructure
Structure TCP_AdapterList Align 1
m_nAdapterCount.l; // Number of adapters
m_szAdapterNameList.names[32]; // Array of adapter names
*m_nAdapterHandle[32] ; // Array of adapter handles, this are key handles for any adapter relative operation
m_nAdapterMediumList.l[32] ; // List of adapter mediums
m_czCurrentAddress.eal[32] ; // current (configured) ethernet address
m_usMTU.u ; // current adapter MTU
EndStructure
Structure params
*filter
*hEvent
*pkt._ETH_M_REQUEST
*spkt._ETH_M_REQUEST
*TCP_AdapterList.TCP_AdapterList
EndStructure
Import "ndisapi.lib"
OpenFilterDriver(driver_name.s)
IsDriverLoaded(hOpen.l)
GetTcpipBoundAdaptersInfo(hOpen.l, *pAdapters)
ConvertWindows2000AdapterName(szAdapterName.p-Ascii, *szUserFriendlyName, dwUserFriendlyNameLength.l)
SetAdapterMode(hOpen.l, *pMode)
ReadPackets(hOpen.l, *pPacket)
SetPacketEvent(hOpen.l, *hAdapter, *hEvent)
GetHwPacketFilter(hOpen.l, *hAdapter, *pFilter)
SetHwPacketFilter(hOpen.l, *hAdapter, filter.l)
SendPacketsToAdapter(hOpen.l, *pPacket)
SendPacketToMstcp(hOpen.l, *pPacket)
SetHwPacketFilterEvent(hOpen.l, *hAdapter, *hEvent)
FlushAdapterPacketQueue(hOpen.l, *hAdapter)
EndImport
Procedure wan(*val.params)
Protected packets, i, length
Debug "ADAPTER1 Thread Started"
Repeat
WaitForSingleObject_(*val\hEvent, #INFINITE)
While ReadPackets(*val\filter, *val\pkt)
packets = *val\pkt\dwPacketsSuccess
For i = 0 To packets - 1
If *val\pkt\EthPacket[i]\m_dwDeviceFlags = #PACKET_FLAG_ON_RECEIVE
length = *val\pkt\EthPacket[i]\m_Length
CopyMemory(@*val\pkt\EthPacket[i]\m_IBuffer, @*val\spkt\EthPacket[i]\m_IBuffer, *val\pkt\EthPacket[i]\m_Length)
*val\spkt\EthPacket[i]\m_Length = *val\pkt\EthPacket[i]\m_Length
EndIf
Next
*val\spkt\dwPacketsNumber = i
SendPacketsToAdapter(*val\filter, *val\spkt)
*val\pkt\dwPacketsSuccess = 0
i = 0
Wend
ResetEvent_(*val\hEvent)
ForEver
EndProcedure
Procedure lan(*val.params)
Protected packets, i, length
Debug "ADAPTER2 Thread Started"
Repeat
WaitForSingleObject_(*val\hEvent, #INFINITE)
While ReadPackets(*val\filter, *val\pkt)
packets = *val\pkt\dwPacketsSuccess
For i = 0 To packets - 1
If *val\pkt\EthPacket[i]\m_dwDeviceFlags = #PACKET_FLAG_ON_RECEIVE
length = *val\pkt\EthPacket[i]\m_Length
CopyMemory(@*val\pkt\EthPacket[i]\m_IBuffer, @*val\spkt\EthPacket[i]\m_IBuffer, *val\pkt\EthPacket[i]\m_Length)
*val\spkt\EthPacket[i]\m_Length = *val\pkt\EthPacket[i]\m_Length
EndIf
Next
*val\spkt\dwPacketsNumber = i
SendPacketsToAdapter(*val\filter, *val\spkt)
*val\pkt\dwPacketsSuccess = 0
i = 0
Wend
ResetEvent_(*val\hEvent)
ForEver
EndProcedure
Define *TCP_AdapterList.TCP_AdapterList = AllocateStructure(TCP_AdapterList)
Define *wan_mode._ADAPTER_MODE = AllocateStructure(_ADAPTER_MODE)
Define *lan_mode._ADAPTER_MODE = AllocateStructure(_ADAPTER_MODE)
Define *pkt._ETH_M_REQUEST = AllocateStructure(_ETH_M_REQUEST)
Define *spkt._ETH_M_REQUEST = AllocateStructure(_ETH_M_REQUEST)
Define *lpkt._ETH_M_REQUEST = AllocateStructure(_ETH_M_REQUEST)
Define *lspkt._ETH_M_REQUEST = AllocateStructure(_ETH_M_REQUEST)
Define *wan_param.params = AllocateStructure(params)
Define *lan_param.params = AllocateStructure(params)
Define *buff = AllocateMemory(256)
Define i, filter, recv_adap, send_adap, wan_recv_internal.s, lan_recv_internal.s, wan_hEvent, lan_hEvent, k, recv_mac.s, lan_recv_mac.s
For i = 0 To 255
*pkt\EthPacket[i] = AllocateStructure(_INTERMEDIATE_BUFFER)
*spkt\EthPacket[i] = AllocateStructure(_INTERMEDIATE_BUFFER)
*lpkt\EthPacket[i] = AllocateStructure(_INTERMEDIATE_BUFFER)
*lspkt\EthPacket[i] = AllocateStructure(_INTERMEDIATE_BUFFER)
Next
filter = OpenFilterDriver("NDISRD")
If IsDriverLoaded(filter)
recv_adap = 4 ;<-- Adapter 1
send_adap = 8 ;<-- Adapter 2
If GetTcpipBoundAdaptersInfo(filter, *TCP_AdapterList)
Debug "Adapter Count: " + *TCP_AdapterList\m_nAdapterCount
Debug #CR$
wan_recv_internal = PeekS(*TCP_AdapterList\m_szAdapterNameList[recv_adap], -1, #PB_Ascii)
Debug "Adapter Internal Name: " + wan_recv_internal
ConvertWindows2000AdapterName(wan_recv_internal, *buff, 256)
Debug "Adapter Friendly Name: " + PeekS(*buff, -1, #PB_Ascii)
Debug "Adapter Handle: " + *TCP_AdapterList\m_nAdapterHandle[recv_adap]
Debug "Adapter Medium: " + *TCP_AdapterList\m_nAdapterMediumList[recv_adap]
For k = 0 To 5
recv_mac.s + Hex(*TCP_AdapterList\m_czCurrentAddress[recv_adap]\mac_char[k], #PB_Byte) + ":"
Next
recv_mac = Left(recv_mac, Len(recv_mac) - 1)
Debug "Adapter MAC Address: " + recv_mac
Debug "Adapter MTU: " + *TCP_AdapterList\m_usMTU
Debug #CR$
lan_recv_internal.s = PeekS(*TCP_AdapterList\m_szAdapterNameList[send_adap], -1, #PB_Ascii)
Debug "Adapter Internal Name: " + lan_recv_internal
ConvertWindows2000AdapterName(lan_recv_internal, *buff, 256)
Debug "Adapter Friendly Name: " + PeekS(*buff, -1, #PB_Ascii)
Debug "Adapter Handle: " + *TCP_AdapterList\m_nAdapterHandle[send_adap]
Debug "Adapter Medium: " + *TCP_AdapterList\m_nAdapterMediumList[send_adap]
For k = 0 To 5
lan_recv_mac.s + Hex(*TCP_AdapterList\m_czCurrentAddress[send_adap]\mac_char[k], #PB_Byte) + ":"
Next
lan_recv_mac = Left(lan_recv_mac, Len(lan_recv_mac) - 1)
Debug "Adapter MAC Address: " + lan_recv_mac
Debug "Adapter MTU: " + *TCP_AdapterList\m_usMTU
Debug #CR$
If SetHwPacketFilter(filter, *TCP_AdapterList\m_nAdapterHandle[recv_adap], #NDIS_PACKET_TYPE_PROMISCUOUS)
Debug "ADAPTER1 Set Hardware Pascket Filter SUCCESS"
*wan_mode\hAdapterHandle = *TCP_AdapterList\m_nAdapterHandle[recv_adap]
*wan_mode\dwFlags = #MSTCP_FLAG_RECV_TUNNEL | #MSTCP_FLAG_FILTER_DIRECT | #MSTCP_FLAG_LOOPBACK_BLOCK
If SetAdapterMode(filter, *wan_mode)
Debug "ADAPTER1 Set Adapter Mode SUCCESS"
*pkt\hAdapterHandle = *TCP_AdapterList\m_nAdapterHandle[recv_adap]
*pkt\dwPacketsNumber = 512
*spkt\hAdapterHandle = *TCP_AdapterList\m_nAdapterHandle[send_adap]
wan_hEvent = CreateEvent_(#Null, #True, #False, #Null)
If wan_hEvent
If SetPacketEvent(filter, *TCP_AdapterList\m_nAdapterHandle[recv_adap], wan_hEvent)
Debug "ADAPTER1 Created Adapter Event SUCCESS"
*wan_param\filter = filter
*wan_param\hEvent = wan_hEvent
*wan_param\TCP_AdapterList = *TCP_AdapterList
*wan_param\pkt = *pkt
*wan_param\spkt = *spkt
CreateThread(@wan(), *wan_param)
EndIf
EndIf
EndIf
EndIf
If SetHwPacketFilter(filter, *TCP_AdapterList\m_nAdapterHandle[send_adap], #NDIS_PACKET_TYPE_PROMISCUOUS)
Debug "ADAPTER2 Set Hardware Pascket Filter SUCCESS"
*lan_mode\hAdapterHandle = *TCP_AdapterList\m_nAdapterHandle[send_adap]
*lan_mode\dwFlags = #MSTCP_FLAG_RECV_TUNNEL | #MSTCP_FLAG_FILTER_DIRECT | #MSTCP_FLAG_LOOPBACK_BLOCK
If SetAdapterMode(filter, *lan_mode)
Debug "ADAPTER2 Set Adapter Mode SUCCESS"
*lpkt\hAdapterHandle = *TCP_AdapterList\m_nAdapterHandle[send_adap]
*lpkt\dwPacketsNumber = 512
*lspkt\hAdapterHandle = *TCP_AdapterList\m_nAdapterHandle[recv_adap]
lan_hEvent = CreateEvent_(#Null, #True, #False, #Null)
If lan_hEvent
If SetPacketEvent(filter, *TCP_AdapterList\m_nAdapterHandle[send_adap], lan_hEvent)
Debug "ADAPTER2 Created Adapter Event SUCCESS"
*lan_param\filter = filter
*lan_param\hEvent = lan_hEvent
*lan_param\TCP_AdapterList = *TCP_AdapterList
*lan_param\pkt = *lpkt
*lan_param\spkt = *lspkt
CreateThread(@lan(), *lan_param)
EndIf
EndIf
EndIf
EndIf
Repeat
Delay(1000)
ForEver
EndIf
EndIf