Forum Replies Created
-
AuthorPosts
-
1) In addition to IP address you also have to change the destination MAC address if proxy is located in the same network segment as you are.
2) You have to memorize the connection {source IP, source port, original remote IP, original remote port, new remote IP, new remote port}. When receiving a response on the redirected packet you have to find the connection in your connections table by destination IP/port which in your table should match source IP/port and substitute source IP/port in the packet.Taking into account that WinpkFilter is a development library but not an end user software we don’t find its drivers signing really necessary. When it is used for evaluation or private/non-commercial purposes it can be loaded on Vista x64 by choosing the “Enforce unsigned drivers loading” option in the boot menu. In case of commercial usage WinpkFilter custom build should be signed by the end vendor by its own signature.
Our current point of view may change once Vista x64 becomes more popular when it is now.
it is possible to capture packes from a specific port an re-route it to an other ip?
Can i change the dest. & src IP-Address in the IP-Header?
Which stuff has to be modified?
Yes this is possible and it is as simple as changing IP/TCP/UDP header and recalculating the checksums. Also if this is sort of redirect the reversed operation should be performed in reversed packets.
Internet Gateway sample http://www.ntkernel.com/w&p.php?id=31demonstrates the usage of WinpkFilter for implementing NAT solution.
Looks like your single thread services both winpkfilter and TServerSocket so you got a dead lock. Try to create a dedicated thread for winpkfilter or TServerSocket .
Hmm, I’m not sure that I understand what you have really implemented. Do you use WinpkFilter and Windows Sockets in the same application? If yes then probably your application design has got a synchronization problem (if socket and winpkfilter are used in the same single thread an example).
The general operation flow looks like the following:
Data sent to socket -> Data intercepted by WinpkFilter -> Data indicated back to application -> Application processes and returns data to the stack -> Socket send operation completed
Data sent from local computer to local computer (localhost) even never wrapped with packets and processed inside TCP/IP without passing them to levels below.
This data can be intercepted only with LSP or TDI filter driver.
The code below tracks incoming HTTP packets (port 80) and blocks if finds a particular string pattern in the packet. This is a simple sample for porno filter or URL blocking, you should be able easily adopt it for you needs:
/*************************************************************************/
/* Copyright (c) 2000-2007 NT Kernel Resources. */
/* All Rights Reserved. */
/* http://www.ntkernel.com */
/* [email protected] */
/* */
/* Module Name: wwwcensor.cpp */
/* */
/* Abstract: Defines the entry point for the console application */
/* */
/*************************************************************************/
#include "stdafx.h"
USHORT ntohs( USHORT netshort )
{
PUCHAR pBuffer;
USHORT nResult;
nResult = 0;
pBuffer = (PUCHAR )&netshort;
nResult = ( (pBuffer[ 0 ] << 8) & 0xFF00 )
| ( pBuffer[ 1 ] & 0x00FF );
return( nResult );
}
#define htons ntohs
int main(int argc, char* argv[])
{
TCP_AdapterList AdList;
CNdisApi api;
ETH_REQUEST Request;
INTERMEDIATE_BUFFER PacketBuffer;
ether_header_ptr pEthHeader = NULL;
iphdr_ptr pIpHeader = NULL;
tcphdr_ptr pTcpHeader = NULL;
HANDLE hEvent[256];
DWORD dwAdIndex = 0;
char szTempString[1500];
char szPattern[256];
BOOL bDrop = FALSE;
if (argc < 2)
{
printf ("Command line syntax:ntwwwcensor.exe pattern ntpattern - phrase or word to block HTTP packets with.n");
return 0;
}
if(!api.IsDriverLoaded())
{
printf ("Driver not installed on this system of failed to load.n");
return 0;
}
if ( strlen(argv[1]) > 255 )
{
printf ("Pattern is too,long, please use one with maximum of 255 characters.n");
return 0;
}
//
// Get pattern in upper case
//
ZeroMemory ( szPattern, 256 );
strcpy ( szPattern, argv[1] );
for ( unsigned i = 0; i < strlen (szPattern); ++i )
{
if (isalpha(((UCHAR)szPattern)))
szPattern = (char)toupper((UCHAR)szPattern);
}
//
// Get system installed network interfaces
//
api.GetTcpipBoundAdaptersInfo ( &AdList );
//
// Initialize common ADAPTER_MODE structure (all network interfaces will operate in the same mode)
//
ADAPTER_MODE Mode;
Mode.dwFlags = MSTCP_FLAG_SENT_TUNNEL|MSTCP_FLAG_RECV_TUNNEL;
//
// Create notification events and initialize the driver to pass packets thru us
//
for (dwAdIndex = 0; dwAdIndex < AdList.m_nAdapterCount; ++dwAdIndex)
{
hEvent[dwAdIndex] = CreateEvent(NULL, TRUE, FALSE, NULL);
if (!hEvent[dwAdIndex])
{
printf("Failed to create notification event for network interface n");
return 0;
}
Mode.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[dwAdIndex];
//
// Set MSTCP_FLAG_SENT_TUNNEL|MSTCP_FLAG_RECV_TUNNEL for the network interface
//
api.SetAdapterMode(&Mode);
//
// Set packet notification event for the network interface
//
api.SetPacketEvent((HANDLE)AdList.m_nAdapterHandle[dwAdIndex], hEvent[dwAdIndex]);
}
// Initialize common part of ETH_REQUEST
ZeroMemory ( &Request, sizeof(ETH_REQUEST) );
ZeroMemory ( &PacketBuffer, sizeof(INTERMEDIATE_BUFFER) );
Request.EthPacket.Buffer = &PacketBuffer;
//
// Go into the endless loop (this is just a sample application)
//
while (TRUE)
{
//
// Wait before any of the interfaces is ready to indicate the packet
//
dwAdIndex = WaitForMultipleObjects ( AdList.m_nAdapterCount, hEvent, FALSE, INFINITE ) - WAIT_OBJECT_0;
//
// Reset signalled event
//
ResetEvent(hEvent[dwAdIndex]);
//
// Complete initialization of ETH_REQUEST
//
Request.hAdapterHandle = (HANDLE)AdList.m_nAdapterHandle[dwAdIndex];
//
// Read packet from the interface until there are any
//
while(api.ReadPacket(&Request))
{
//
// Get Ethernet header
//
pEthHeader = (ether_header_ptr)PacketBuffer.m_IBuffer;
//
// Check if Ethernet frame contains IP packet
//
if(ntohs(pEthHeader->h_proto) == ETH_P_IP)
{
//
// Get IP header
//
pIpHeader = (iphdr_ptr)(pEthHeader + 1);
//
// Check if IP packet contains TCP packet
//
if (pIpHeader->ip_p == IPPROTO_TCP)
{
//
// Get TCP header pointer
//
pTcpHeader = (tcphdr_ptr)((PUCHAR)pIpHeader + pIpHeader->ip_hl*4);
//
// Check if this HTTP packet (destined to remote system port 80, or received from it)
//
if (((pTcpHeader->th_dport == htons (80))&&(PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))||
((pTcpHeader->th_sport == htons (80))&&(PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_RECEIVE)))
{
//
// Get data size in the packet and pointer to the data
//
DWORD dwDataLength = PacketBuffer.m_Length - (sizeof(ether_header) + pIpHeader->ip_hl*4 + pTcpHeader->th_off*4);
PCHAR pData = (PCHAR)pEthHeader + (sizeof(ether_header) + pIpHeader->ip_hl*4 + pTcpHeader->th_off*4);
// If packet contains any data - process it
if (dwDataLength)
{
//
// Copy packet payload into the temporary string, replace all 0 bytes with 0x20, convert string to upper case and place at the end
//
memcpy (szTempString, pData, dwDataLength);
for (unsigned t = 0; t < dwDataLength; ++t)
{
if (szTempString[t] == 0)
szTempString[t] = 0x20;
if (isalpha((UCHAR)szTempString[t]))
szTempString[t] = (char)toupper((UCHAR)szTempString[t]);
}
szTempString[dwDataLength] = 0;
//
// Check if this packet payload contains user supplied pattern in ASCII code
//
if (strstr ( szTempString, szPattern ))
bDrop = TRUE;
}
}
}
}
if(bDrop)
{
printf ("TCP %d.%d.%d.%d:%d -> %d.%d.%d.%d:%d pattern found & packet dropped n",
pIpHeader->ip_src.S_un.S_un_b.s_b1, pIpHeader->ip_src.S_un.S_un_b.s_b2, pIpHeader->ip_src.S_un.S_un_b.s_b3, pIpHeader->ip_src.S_un.S_un_b.s_b4, ntohs(pTcpHeader->th_sport),
pIpHeader->ip_dst.S_un.S_un_b.s_b1, pIpHeader->ip_dst.S_un.S_un_b.s_b2, pIpHeader->ip_dst.S_un.S_un_b.s_b3, pIpHeader->ip_dst.S_un.S_un_b.s_b4, ntohs (pTcpHeader->th_dport));
bDrop = FALSE;
}
else
if (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
{
// Place packet on the network interface
api.SendPacketToAdapter(&Request);
}
else
{
// Indicate packet to MSTCP
api.SendPacketToMstcp(&Request);
}
}
}
return 0;
}
Can someone say me which headers are necessary? (where can i download these?)
August 4, 2007 at 11:28 am in reply to: installation NDIS-IM driver failed under winXP 64-bit [rus] #6383Гмм, ничего по идее не изменилось с x64. Как я использовал слегка переделанный вариант snetcfg, так и использую с учетом пеерсборки последнего под x64.
А представленный код собирается под x64? Если нет, то вероятно это просто ограничение 32 битных процессов какое-то.
Well, basically you can use WinpkFilter for parsing packets and blocking once quota exceeded.
Alternatively you can create you own own driver for this. Here depending of the exact requirement you have several options like LSP, TDI filter, NDIS IM, NDIS hooking, WFP…
Using ndisapi.dll from C# is a bit trickier because you can’t pass managed memory to the driver directly. We have got some C# samples to include in the next WinpkFilter release, you can request pre-release preview of these samples by e-mailing support(at)ntkernel.com.
I can’t see any problem with your code and as you may have already noticed you can send ANY packet to the network even filled with all zeros.
There is also a chance that you have a firewall installed which intercepts and blocks your packet.
I do not use a network LAN Ethernet, but a network Wireless WAN, I can use winpkfilter in this case?.
Yes of course.
does winpkfilter recover the packets in the two directions (entering and outgoing)? because my work must recover the packets in the two directions.
Yes, if you set driver filter mode as passthru sample does then you inspect filter both incoming and outgoing packets.
all packets on the network layer (i.e., IP)
May be something like filter hook or firewall hook driver, I’m not sure if they deliver packet with or without Ethernet header . Basically I don’t see any problem with having Ethernet header for the packet like WinpkFilter does for implementing the solution you mentioned. IP packet follows Ethernet header, just make a 14 bytes offset.
or even transport layer (i.e., TCP)
You can create an LSP to operate on the winsock level or TDI level filter.
SerpentFly, не поможешь?
Почитал бы описание, покопался в отладчике, там ничего сложного то нет. Поставь breakpoint, посмотри что где приходит. Я на память не помню, надо тоже лезть смотреть, а на это время все-таки нужно. Если уж совсем никак попробую найти время отписаться.
-
AuthorPosts