Vadim Smirnov

Forum Replies Created

Viewing 15 posts - 1,246 through 1,260 (of 1,502 total)
  • Author
    Posts
  • in reply to: SERVICE_SYSTEM_START vs SERVICE_DEMAND_START #6054
    Vadim Smirnov
    Keymaster

      А эти данные из перехваченных send’ов у тебя каким-то образом обрабатываются или ждут до лучших времен пока стартанет ответственное за их обработку приложение?

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

      in reply to: port redirection #6051
      Vadim Smirnov
      Keymaster

        is it possible to get that port redirect dynamically upon startup of “my_app”?

        WinpkFilter driver should be installed on the system before hand. But in any case you start filtering/redirecting packets only when your application is active and stop this when your application is terminated. So the answer is YES.

        in reply to: port redirection #6049
        Vadim Smirnov
        Keymaster

          is there a chance to configure windows’ firewall to redirect data sent from an external interface to port 25 to our port 10025?

          Windows built-in firewall does not support port redirecting services.

          does anyone have an idea how to solve this EXCEPT using custom LSP/TDI/NDIS drivers?

          Regretfully there is no other way. You can use WinpkFilter library (http://www.ntkernel.com/w&p.php?id=7) to implement port redirector solution though.

          in reply to: Simple tiny Firewall #6047
          Vadim Smirnov
          Keymaster

            can I paste a link here that would be for a Simple Stupid Firewall that I made using winpkfilter example (PacketSniffer and PassThru)

            Sure, you can.

            Vadim Smirnov
            Keymaster

              SmartFirewall is an earlier version of NeT Firewall.

              in reply to: OID_802_3_XMIT_ONE_COLLISION #5973
              Vadim Smirnov
              Keymaster

                Проблема в том, что это драйвер-фильтр

                В смысле Intermediate?

                Где можно выполнять запросы OID, в OnSend, OnReceive, OnInitialize, OnHalt?

                В общем случае запросы можно делать как только нижележащий драйвер готов их обрабатывать и до того как он перестает это делать (то есть OnInitialize и OnHalt использовать пожалуй не очень разумно).

                В общем случае нужно следить только за IRQL “Callers of NdisRequest can be running at IRQL <= DISPATCH_LEVEL" и руководстоваться тем когда эта самая статистика нужна.

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

                  Anyway, is it ok to have an Article on the subject we treat here with my Application as a solution and a link to the WinpkFilter run-time libraries that are presented on

                  http://www.ntkernel.com/w&p.php?id=7

                  or it is in violation of the license agreement?

                  It is OK to do so. Good luck with your article and hope you will post a link to it here. If you are interested we can also publish it on this web-site.

                  in reply to: I have some question about web redirection. #6040
                  Vadim Smirnov
                  Keymaster

                    This is TCP checksum in C, I suppose you should be able to translate to Delphi


                    //
                    // Function recalculates TCP checksum
                    //
                    VOID
                    RecalculateTCPChecksum (
                    PINTERMEDIATE_BUFFER pPacket
                    )
                    {
                    tcphdr_ptr pTcpHeader = NULL;
                    unsigned short word16, padd = 0;
                    unsigned int i, sum = 0;
                    PUCHAR buff;
                    DWORD dwTcpLen;

                    iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];

                    // Sanity check
                    if (pIpHeader->ip_p == IPPROTO_TCP)
                    {
                    pTcpHeader = (tcphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
                    }
                    else
                    return;

                    dwTcpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl*4;//pPacket->m_Length - ((PUCHAR)(pTcpHeader) - pPacket->m_IBuffer);

                    if ( (dwTcpLen/2)*2 != dwTcpLen )
                    {
                    padd=1;
                    pPacket->m_IBuffer[dwTcpLen + pIpHeader->ip_hl*4 + sizeof(ether_header)] = 0;
                    }

                    buff = (PUCHAR)pTcpHeader;
                    pTcpHeader->th_sum = 0;

                    // make 16 bit words out of every two adjacent 8 bit words and
                    // calculate the sum of all 16 vit words
                    for (i=0; i< dwTcpLen+padd; i=i+2){
                    word16 =((buff<<8)&0xFF00)+(buff[i+1]&0xFF);
                    sum = sum + (unsigned long)word16;
                    }

                    // add the TCP pseudo header which contains:
                    // the IP source and destination addresses,

                    sum = sum + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_src.S_un.S_un_w.s_w2);
                    sum = sum + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w1) + ntohs(pIpHeader->ip_dst.S_un.S_un_w.s_w2);

                    // the protocol number and the length of the TCP packet
                    sum = sum + IPPROTO_TCP + (unsigned short)dwTcpLen;

                    // keep only the last 16 bits of the 32 bit calculated sum and add the carries
                    while (sum>>16)
                    sum = (sum & 0xFFFF)+(sum >> 16);

                    // Take the one's complement of sum
                    sum = ~sum;

                    pTcpHeader->th_sum = htons((unsigned short)sum);
                    }
                    in reply to: I have some question about web redirection. #6038
                    Vadim Smirnov
                    Keymaster

                      i’ve tried to change destination ip of ipheader, then recalculate checksum but it didn’t work

                      You should modify destination IP address in the potgoing packet to redirect address and recalculate packet checksums (both IP and TCP). You should do the reverse operation in the incoming packet associated with the connection you modify.

                      in reply to: Question about WinpkFilter #6041
                      Vadim Smirnov
                      Keymaster

                        Is it possible to unaccept a certain kind of packet(e.g. packets with the same source IP addr) just using the use-mode APIs provided in WinpkFilter?

                        You mean drop these packets? If so then yes you can just skip reinjecting into the stack API calls (SendPacketToMstcp, SendPacketToAdapter) for these packets.

                        in reply to: NET Firewall supporting Outging NAT ??? #6034
                        Vadim Smirnov
                        Keymaster

                          I wonder if the Net Firewall supports a simple one to many NAT.

                          One to many NAT is not implemented in the current version of NeT Firewall.

                          in reply to: I have some question about web redirection. #6036
                          Vadim Smirnov
                          Keymaster

                            if we detect some harmful site(http packet) in winpkfilter we redirect alert site.

                            Since connection to the harmful site already established it can’t be easily redirected (normally redirection should occure during connection establishment). However, you can terminate connection to the harmful site and drop all packet to/from it, alert user about harmful site, redirect all newly established HTTP user sessions from the registered harmful site to the alert site and etc…

                            in reply to: HTTP message identification #6032
                            Vadim Smirnov
                            Keymaster

                              Пишу TDI-фильтр для устройства TCP. Задача фильтра — определять и собирать в буфер сообщения HTTP с последующей выдачей наверх приложению Win32. Через обработчик TDI_SEND может проходить как полноформатное HTTP сообщение, так и отдельные куски, вплоть до отдельных байтов. Интересует вопрос, есть ли способы корректно определить, что передаваемое побайтно сообщение именно HTTP, а не что-то другое.

                              На уровне TDI все выглядит точно так же как и в обычном сокете, так что есть ли способ по куску данных случайно выхваченого из потока данных сокета достоверно определить HTTP протокол? Маловероятно, если только этот кусок не достаточно велик чтобы содержать достоверные сигнатуры HTTP (заголовки запросов/ответов например). Можно еще смотреть на порты, но вообще говоря HTTP сервер не обязан работать на 80 порту. Единственный достоверный способ – это анализировать весь поток данных, выбирать и опознавать HTTP заголовки.

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

                                I am just running the examples, PassThru and PacketSniffer only.

                                but its not sniffing in the XP-bridge mode.

                                Well it works OK in test environment and you are the first one who reported problems like this. Could you provide the complete details about it? It would be good if you provide ipconfig output, listadapters output and how do you start passthru sample (with it’s output compared to some other tool which shows you packets). Some broken functionality can be alo caused by installed firewall or some sort of other low level network software.

                                Also, which version of WinpkFilter are you using?

                                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.

                                Viewing 15 posts - 1,246 through 1,260 (of 1,502 total)