- This topic has 5 replies, 3 voices, and was last updated 19 years, 6 months ago by Vadim Smirnov. 
- 
		AuthorPosts
- 
		
			
				
February 17, 2006 at 2:23 am #4993Hi, 
 if I use a Windows computer as an internet-gateway (Internet Connection Sharing), is it possible to redirect some users (with a specific IP) to another Website than the requested?
 Is it possible in Visual Basic ?
 Please add some relevant source-code.
 Thanks a lot in advance.
 EdFebruary 17, 2006 at 9:22 am #5965Yes, this is possible to implement in Visual basic using WinpkFilter library, however I can’t provide you with ready to use code in VB (as I’m not a VB coder). If you can use the C code I think I can provide some. Also you can use port/protocol mapping avalable in NeT Firewall (set up redirector rules on the internal LAN interface). February 17, 2006 at 9:52 am #5966Hi Serpent, 
 first of all, thanks for the information.
 But I have a few further questions:The WinpkFilter library you mentioned, is it free or do I have to purchase it? Is it the free downloadable ndisapi.dll ? Can you provide some code samples for the redirection in C or another programming language? Thanks in advance. 
 EdFebruary 17, 2006 at 11:44 am #5967The WinpkFilter library you mentioned, is it free or do I have to purchase it? Is it the free downloadable ndisapi.dll ? WinpkFilter is free for non-commercial use and available for download from here (http://www.ntkernel.com/w&p.php?id=7). Package includes drivers(ndisrd.sys/ndisrd.vxd), API DLL (ndisapi.dll) and several simple samples. If you register WinpkFilter (any type of subscription starting from 95$) you also get access to the Internet Gateway source code (http://www.ntkernel.com/w&p.php?id=31) which implements NAT and gives a good clue to how to redirect packets. Some code samples can be also found by looking through this forum. I can also C&P a redirect relative portion of code from NeT Firewall source, but it may appear a bit difficult to understand. April 16, 2006 at 12:01 pm #5968@SerpentFly wrote: Yes, this is possible to implement in Visual basic using WinpkFilter library, however I can’t provide you with ready to use code in VB (as I’m not a VB coder). If you can use the C code I think I can provide some. Also you can use port/protocol mapping avalable in NeT Firewall (set up redirector rules on the internal LAN interface). Can you provide some C code for this purpose ? April 17, 2006 at 11:22 am #5969Can you provide some C code for this purpose ? The routine below is taken from the Internet Gateway source and implements NAT processing: unsigned __stdcall CsnatDlg::StartNAT ( void* pArguments )
 {
 CsnatDlg* pDlg = (CsnatDlg*)pArguments;
 HANDLE hEvents[ADAPTER_LIST_SIZE + 1];
 CNetworkInterface* hAdapters [ADAPTER_LIST_SIZE + 1];
 CNetworkInterface *pNetCard, *pProviderCard;
 unsigned dwActiveAdaptersCount = 1;
 ADAPTER_MODE Mode;
 ETH_REQUEST Request;
 INTERMEDIATE_BUFFER PacketBuffer;
 DWORD dwWait, dwIndex;
 ether_header* pEthHeader;
 iphdr* pIpHeader;
 tcphdr* pTcpHeader;
 udphdr* pUdpHeader;
 
 Mode.dwFlags = MSTCP_FLAG_SENT_TUNNEL|MSTCP_FLAG_RECV_TUNNEL;
 
 hEvents[0] = pDlg->m_hNATTerminateEvent;
 
 // Walk adapters list and initialize provider and clients interfaces
 POSITION pos = pDlg->m_NetCardsList.GetHeadPosition();
 
 for (unsigned i = 0; i < pDlg->m_dwAdapterCount; ++i)
 {
 pNetCard = (CNetworkInterface*)pDlg->m_NetCardsList.GetNext(pos);
 
 if ((pNetCard->m_NATState == CLIENT) || (pNetCard->m_NATState == PROVIDER))
 {
 hAdapters[dwActiveAdaptersCount] = pNetCard;
 hEvents[dwActiveAdaptersCount] = ::CreateEvent(NULL, TRUE, FALSE, NULL);
 pDlg->m_NdisApi.SetPacketEvent(pNetCard->m_hAdapter, hEvents[dwActiveAdaptersCount]);
 Mode.hAdapterHandle = pNetCard->m_hAdapter;
 pDlg->m_NdisApi.SetAdapterMode(&Mode);
 dwActiveAdaptersCount++;
 
 if(pNetCard->m_NATState == PROVIDER)
 pProviderCard = pNetCard;
 }
 }
 
 // Initialize Request
 ZeroMemory ( &Request, sizeof(ETH_REQUEST) );
 ZeroMemory ( &PacketBuffer, sizeof(INTERMEDIATE_BUFFER) );
 Request.EthPacket.Buffer = &PacketBuffer;
 
 do
 {
 dwWait = ::WaitForMultipleObjects(
 dwActiveAdaptersCount,
 hEvents,
 FALSE,
 INFINITE
 );
 
 dwIndex = dwWait - WAIT_OBJECT_0;
 
 if (!dwIndex)
 continue;
 
 ::ResetEvent(hEvents[dwIndex]);
 
 Request.hAdapterHandle = hAdapters[dwIndex]->m_hAdapter;
 
 // Read all queued packets from the specified interface
 while(pDlg->m_NdisApi.ReadPacket(&Request))
 {
 pEthHeader = (ether_header*)PacketBuffer.m_IBuffer;
 if ( ntohs(pEthHeader->h_proto) == ETH_P_IP )
 {
 pIpHeader = (iphdr*)(PacketBuffer.m_IBuffer + ETHER_HEADER_LENGTH);
 
 // Check if connection is established from local system (we don't do NAT processing
 // for local system)
 BOOL bIsLocalAddress = hAdapters[dwIndex]->IsLocalAddress(&pIpHeader->ip_src);
 
 if (bIsLocalAddress && (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))
 {
 // Place packet on the network interface
 pDlg->m_NdisApi.SendPacketToAdapter(&Request);
 
 continue;
 }
 
 // TCP packet processing
 if (pIpHeader->ip_p == IPPROTO_TCP)
 {
 // This is TCP packet, get TCP header pointer
 pTcpHeader = (tcphdr*)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
 
 // Outgoing TCP packets processing
 if ((hAdapters[dwIndex]->m_NATState == PROVIDER)&&
 (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))
 {
 CPortNATEntry* pTcpNE = NULL;
 
 if (pTcpHeader->th_flags == TH_SYN)
 {
 // New TCP connnection established, allocate dynamic NAT entry
 pTcpNE = pDlg->m_TcpNatTable.Allocate(pIpHeader->ip_src, pTcpHeader->th_sport, pIpHeader->ip_dst, pTcpHeader->th_dport);
 
 if(pTcpNE)
 {
 pTcpNE->m_IpNAT = hAdapters[dwIndex]->m_NATIp;
 }
 }
 else
 {
 // Try to locate xisting NAT entry
 pTcpNE = pDlg->m_TcpNatTable.Find(pIpHeader->ip_src, pTcpHeader->th_sport, pIpHeader->ip_dst, pTcpHeader->th_dport);
 }
 
 if (pTcpNE)
 {
 // If NAT entry is found perform NAT processing
 pIpHeader->ip_src.S_un.S_addr = htonl(pTcpNE->m_IpNAT.S_un.S_addr);
 pTcpHeader->th_sport = htons(pTcpNE->m_usNATPort);
 // Recalculate checksums
 RecalculateTCPChecksum (&PacketBuffer);
 RecalculateIPChecksum(pIpHeader);
 }
 }
 
 // Incoming TCP packets processing
 if ((hAdapters[dwIndex]->m_NATState == PROVIDER)&&
 (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_RECEIVE))
 {
 // Map connection to the NAT entry if the one exists
 CPortNATEntry* pTcpNE = pDlg->m_TcpNatTable.Map(pTcpHeader->th_dport);
 if (pTcpNE)
 {
 // NAT entry exists, make NAT processing
 if (htonl(pTcpNE->m_IpDst.S_un.S_addr) == pIpHeader->ip_src.S_un.S_addr)
 {
 pIpHeader->ip_dst.S_un.S_addr = htonl(pTcpNE->m_IpSrc.S_un.S_addr);
 pTcpHeader->th_dport = htons(pTcpNE->m_usSrcPort);
 RecalculateTCPChecksum (&PacketBuffer);
 RecalculateIPChecksum(pIpHeader);
 }
 }
 
 }
 }
 // UDP packets processing
 if (pIpHeader->ip_p == IPPROTO_UDP)
 {
 // This is UDP packet, get UDP header pointer
 pUdpHeader = (udphdr*)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
 
 // DNS hook
 // If we receive DNS packet on the NAT client adapter then we redirect it
 // to this system configured DNS server
 if ((hAdapters[dwIndex]->m_NATState == CLIENT)&&
 (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_RECEIVE))
 {
 if (ntohs(pUdpHeader->th_dport) == 53/*DNS port*/)
 {
 // Save the DNS IP used by the NAT client system
 hAdapters[dwIndex]->m_LocalDNS.S_un.S_addr = ntohl(pIpHeader->ip_dst.S_un.S_addr);
 pIpHeader->ip_dst.S_un.S_addr = pDlg->m_DNSIp.S_un.S_addr;
 RecalculateIPChecksum(pIpHeader);
 }
 }
 // DNS reply came, substitute source IP back to the original DNS address
 if ((hAdapters[dwIndex]->m_NATState == CLIENT)&&
 (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))
 {
 if (ntohs(pUdpHeader->th_sport) == 53/*DNS port*/)
 {
 pIpHeader->ip_src.S_un.S_addr = htonl(hAdapters[dwIndex]->m_LocalDNS.S_un.S_addr);
 RecalculateIPChecksum(pIpHeader);
 }
 }
 // Outgoing UDP NAT processing
 if ((hAdapters[dwIndex]->m_NATState == PROVIDER)&&
 (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND))
 {
 CPortNATEntry* pUdpNE = NULL;
 // Try to find existing entry
 pUdpNE = pDlg->m_UdpNatTable.Find(pIpHeader->ip_src, pUdpHeader->th_sport, pIpHeader->ip_dst, pUdpHeader->th_dport);
 // If not found -> allocate a new one
 if (!pUdpNE)
 {
 pUdpNE = pDlg->m_UdpNatTable.Allocate(pIpHeader->ip_src, pUdpHeader->th_sport, pIpHeader->ip_dst, pUdpHeader->th_dport);
 
 if(pUdpNE)
 {
 pUdpNE->m_IpNAT = hAdapters[dwIndex]->m_NATIp;
 }
 }
 // NAT processing
 if (pUdpNE)
 {
 pIpHeader->ip_src.S_un.S_addr = htonl(pUdpNE->m_IpNAT.S_un.S_addr);
 pUdpHeader->th_sport = htons(pUdpNE->m_usNATPort);
 RecalculateUDPChecksum (&PacketBuffer);
 RecalculateIPChecksum(pIpHeader);
 }
 }
 // Incoming UDP packets processing
 if ((hAdapters[dwIndex]->m_NATState == PROVIDER)&&
 (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_RECEIVE))
 {
 CPortNATEntry* pUdpNE = pDlg->m_UdpNatTable.Map(pUdpHeader->th_dport);
 if (pUdpNE)
 {
 if (htonl(pUdpNE->m_IpDst.S_un.S_addr) == pIpHeader->ip_src.S_un.S_addr)
 {
 pIpHeader->ip_dst.S_un.S_addr = htonl(pUdpNE->m_IpSrc.S_un.S_addr);
 pUdpHeader->th_dport = htons(pUdpNE->m_usSrcPort);
 RecalculateUDPChecksum (&PacketBuffer);
 RecalculateIPChecksum(pIpHeader);
 }
 }
 
 }
 }
 
 }
 
 // Reinject packet into the stack
 if (PacketBuffer.m_dwDeviceFlags == PACKET_FLAG_ON_SEND)
 {
 // Place packet on the network interface
 pDlg->m_NdisApi.SendPacketToAdapter(&Request);
 }
 else
 {
 // Indicate packet to MSTCP
 pDlg->m_NdisApi.SendPacketToMstcp(&Request);
 }
 }
 
 }while (dwIndex);
 
 // Free all NAT entries
 pDlg->m_TcpNatTable.RemoveAll();
 pDlg->m_UdpNatTable.RemoveAll();
 
 for (unsigned i = 1; i < dwActiveAdaptersCount; ++i)
 {
 Mode.dwFlags = 0;
 Mode.hAdapterHandle = hAdapters->m_hAdapter;
 
 // Set NULL event to release previously set event object
 pDlg->m_NdisApi.SetPacketEvent(hAdapters->m_hAdapter, NULL);
 
 // Close Event
 if (hEvents)
 CloseHandle ( hEvents );
 
 // Set default adapter mode
 pDlg->m_NdisApi.SetAdapterMode(&Mode);
 
 // Empty adapter packets queue
 pDlg->m_NdisApi.FlushAdapterPacketQueue (hAdapters->m_hAdapter);
 }
 
 _endthreadex( 0 );
 return 0;
 }Complete source code for the Internet Gateway is available to registered WinpkFilter customers. 
- 
		AuthorPosts
- You must be logged in to reply to this topic.
