Vadim Smirnov

Forum Replies Created

Viewing 15 posts - 1,261 through 1,275 (of 1,503 total)
  • Author
    Posts
  • in reply to: Redirection (Gateway) #5969
    Vadim Smirnov
    Keymaster

      Can 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.

      Vadim Smirnov
      Keymaster

        Повторюсь:
        Надо для 6.0 и только!

        DDKBUILD старый продукт, начинался как раз под VC6, сам им не пользуюсь, но думаю и там он еще работает. Если нет ищите старые версии…

        P.S. А вежливости Вас в школе видимо недоучили 🙄

        Vadim Smirnov
        Keymaster
          in reply to: Network bridge && adapter list #6024
          Vadim Smirnov
          Keymaster

            We are your customer and have baught Individual User License only.

            Since Individual license does not include any drivers customization it can be implemented for the extra fee only.

            When we are trying to sniff using WinpkFilter, on the XP Bridge, we don’t see any packets. I mean we can’t sniff.

            Please clarify. Are you trying to use listening mode or tunnel mode? Have you tried PassThru and PacketSniffer samples over the bridge or it was your own code? In general WinpkFilter intercepts all packets between XP bridge and TCP/IP stack, so if there any packets and driver is used correctly then you can’t miss them.

            in reply to: Network bridge && adapter list #6022
            Vadim Smirnov
            Keymaster

              Yes, we require that feature. Can you please tell me how I can get that that?

              This modification is available to WinpkFilter Source Code and Developer (as a custom build) licensees. If you our customer and own one of the licenses mentioned above then please e-mail [email protected] with your order details (license, order ID and approximate date of purchase) in order to get customized WinpkFilter build.

              in reply to: I have some question about winpkfilter buffer. #6027
              Vadim Smirnov
              Keymaster

                where i edit ?

                If you have access to the source code then you should modify the proc.h in line 22

                #define INT_BUF_POOL_SIZE 500

                change to

                #define INT_BUF_POOL_SIZE 1000 //or 1500

                in reply to: Network bridge && adapter list #6020
                Vadim Smirnov
                Keymaster

                  Thats right, when you are not using bridge TCP/IP is bound to your LAN adapters (and you can normally see them), but when using bridge – it is bound to the bridge network adapter (bridge itself is intermediate driver which binds like a protocol to LAN adapters and has network interface on top of it, in this case TCP/IP is bound to this interface and since WinpkFilter driver puts itself between TCP/IP and its adapters then you can see only a bridge).

                  If you require filtering over raw LAN adapters even if XP bridge is used then it is also possible (in general it is just a simple driver modification and we had a customer who requested this feature before).

                  in reply to: ndis-based nat + shaper #6019
                  Vadim Smirnov
                  Keymaster

                    а в “железных” маршрутизаторах типа циски используется такой же алгоритм?

                    Что там в сиске, не знает никто кроме разработчиков сиски.

                    есть ли оценки его эффективности?

                    Тут есть какая-то теория:
                    http://www.lan2net.ru/shaper.shtml

                    in reply to: ndis-based nat + shaper #6017
                    Vadim Smirnov
                    Keymaster

                      Обычно делается очередь пакетов (размер ограничен разумеется), пакеты из очереди выталкиваются в соответствии с установленой скоростью. В случае переполнения очереди пакеты начинают отбрасываться. Цепляться для выталкивания пакетов нужно к таймеру (на случай если долго нет новых пакетов) и событиям прихода новых пакетов (таймер может срабатывать довольно редко по сравнению с приходом пакетов), высчитываем время с последнего события и передаем столько пакетов сколько пролезло бы по установленному каналу за прошедшее время.

                      in reply to: Ethernet frames larger than 1514 bytes #6013
                      Vadim Smirnov
                      Keymaster

                        Is source code license the only way to do that?

                        Developer License is enough, since it already includes custom build it won’t be a problem to change one additional constant.

                        in reply to: Ethernet frames larger than 1514 bytes #6011
                        Vadim Smirnov
                        Keymaster

                          Hi,

                          Standard build of WinpkFilter operates with 1514 bytes frames only. It simply forbids usage of larger frame size by intercepting some requests from the protocls to network card driver.

                          However if there is a requirement to suppport larger frame size then drivers can be easily rebuilded (by changing few constants).

                          in reply to: WinpktFilter hooking vs intermediate driver #5964
                          Vadim Smirnov
                          Keymaster

                            I do understand. But what about Vista?

                            In addition to NDIS hooking and IM drivers Vista is expected to introduce new packet filtering capabilities (Windows Packet Filtering framework). So in general there will be even more options.

                            in reply to: Process ID #6009
                            Vadim Smirnov
                            Keymaster

                              Process context is not available at the NDIS level where WinpkFilter works. In order to determine the packet associated process you should obtain the current connections table on some way (TDI filter, LSP and some other less popular ways) and match packet to the process using address/port information.

                              Usually, firewall is a combination of NDIS level filter (packet firewall) and application level filter (application/desktop firewall).

                              Hope it helps

                              in reply to: Modify TTL of the packets #5993
                              Vadim Smirnov
                              Keymaster

                                Hmm, I don’t see the problem but what is the sense to modify TTL in the incoming packet?

                                You can download some code playing with TTL (and some other fields of the packet) from here http://www.xakep.ru/post/29448/safenat.zip I think it should be a good reference.

                                in reply to: windows XP on top of NT kernel #5989
                                Vadim Smirnov
                                Keymaster

                                  Windows XP belongs to NT family (Windows NT 3.51 – Windows NT 4.0 – Windows 2000 – Windows XP – Windows 2003).

                                  May be your professor meaned Windows ME?

                                Viewing 15 posts - 1,261 through 1,275 (of 1,503 total)