Vadim Smirnov

Forum Replies Created

Viewing 15 posts - 571 through 585 (of 1,476 total)
  • Author
    Posts
  • in reply to: Ethernet Bridge #9691
    Vadim Smirnov
    Keymaster

      И еще один момент, любое другое приложение обращающееся к драйверу может поставить свои события на пакеты и мост перестанет их получать. Например, достаточно запустить стандартный passthru на одном из интерфейсов моста, чтобы последний перестал нормально работать. В целом для production стоит ограничить доступ к драйверу (для демо версии это неудобно).

      in reply to: Ethernet Bridge #9690
      Vadim Smirnov
      Keymaster

        Маловато конечно информации, чтобы делать какие-то выводы. Во-первых, какие интерфейсы включены в мост? Два обычных Ethernet 802.3?

        Для начала стоит посмотреть в отладчике чем заняты рабочие потоки после того как мост перестает работать. Для наглядности я бы добавил консольный вывод в рабочие потоки (получил пакеты -> переслал пакеты). Сразу будет понятно какой поток заснул или вообще вышел.

        Например, если мост перестал функционировать, но при этом потоки продолжают получать и перекладывать пакеты и оба сетевых интерфейса сами по себе работают нормально (пингают хосты в подключенных сетях), то возможно что-то сбрасывает promiscuous фильтр на одном или на обоих интерфейсах. Это несложно проверить, прочитав текущий фильтр, как, впрочем, несложно и поправить, восстановив promiscuous.

        in reply to: SEND PACKET TO DESIRED ADAPTER #9686
        Vadim Smirnov
        Keymaster

          If I’m not mistaken Internet Gateway uses single thread to send/receive packets from both adapters (LAN and WAN) waiting with WaitForMultipleObjects an adapter associated event objects.

          So, in order to implement bandwidth management I’d advise launching two threads instead, one per network interface, each waiting with WaitForSingleObject on associated event. This way you should be able to delay packets for the selected network adapter without affecting the second one. Just note to take care about threads synchronization when accessing shared data. You can use Ethernet Bridge source for the reference for thread per network adapter model.

          in reply to: Ethernet Bridge #9682
          Vadim Smirnov
          Keymaster

            В общем да, рестартовать мост имеет смысл если произошли изменения в используемых интерфейсах, остальные изменения можно игнорировать. Внутренне HANDLE сетевого адаптера – это указатель на структуру в ядре, она удаляется только при удалении адаптера из системы, то есть HANDLE может изменится только если адаптер был удален и снова добавлен.

            Единственно, если 32-битное приложение работает с драйвером на 64-битной системе, то NDISAPI включает дополнительный уровень трансляции для хэндлов (из 32 в 64 битные) и на постоянство хэндлов полагаться нельзя, 32-битные хэндлы в этом случае – индексы в массиве 64-битных.

            in reply to: Ethernet Bridge #9679
            Vadim Smirnov
            Keymaster

              Судя по симптомам, скорей всего дело в том, что один из интерфейсов переподключается в процессе работы. Это поведением можно симитировать сделав disable/enable одной из сетевых карт моста в процессе работы.

              Простоты ради Ethernet Bridge не обрабатывает изменения сетевой конфигурации. Нужно бы добавить мониторинг изменений доступных интерфейсов (SetAdapterListChangeEvent) и останавливать/перезапускать мост когда один из адаптеров “уходит”/”возвращается”.

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

              in reply to: [C#]Get the process a packet was sent by #9644
              Vadim Smirnov
              Keymaster

                Normally I’d use IP Helper API for this purpose. For the TCP protocol it can be done with the following steps:
                1) Use GetExtendedTcpTable and GetOwnerModuleFromTcpEntry to build the mapping from the local (IP address, TCP port) to process executable.
                2) Extract IP and port information from the packet and use the mapping built on previous step to look up the process executable.
                3) Update the mapping periodically or when you can’t lookup process for the certain packet.

                For the UDP just use GetExtendedUdpTable and GetOwnerModuleFromUdpEntry instead.

                in reply to: PassThru #9630
                Vadim Smirnov
                Keymaster

                  2) а вот тут я мало что понял.

                  Вместо моста делаем шлюз, где одна сетевая карта раздает интернет на другую. Как еще проще обьяснить – не знаю. В такой конфигурации можно фильтровать как внешний, так и внутренний интерфейс и отбирать/модифицировать нужный траффик.

                  in reply to: PassThru #9627
                  Vadim Smirnov
                  Keymaster

                    Согласен, есть нюансы…

                    С другой стороны, против использования встроенного моста и Windows 7 есть один серьезный аргумент – нет гарантированной возможности забиндиться на интерфейсы под мостом (причем непонятно от чего это зависит), а это в свою очередь означает, что нет возможности фильтровать транзитный трафик (он обработается внутри моста).

                    Таким образом, видится два варианта:
                    1) Перенести функционал моста непосредственно в драйвер.
                    2) Использовать routing/NAT. Опять же можно использовать как самописный NAT, так и встроенный в Windows Internet Connection Sharing (ICS). Тогда будет достаточно запустить приложение только на одном интерефейсе (внешнем или внутреннем в данном случае роли не играет) и отбирать только нужный трафик.

                    in reply to: PassThru #9625
                    Vadim Smirnov
                    Keymaster

                      На компе я удалил мост, а из устройств – сетевые карты; перезагрузился, установил драйверы для сетевых карт, создал мост. После этого WinpkFilter стал видеть сетевые интерфейсы правильно: мост видит, а сетевые карты нет.

                      Тем не менее, я бы на это не полагался и организовал бы мост средствами WinpkFilter.

                      in reply to: PassThru #9623
                      Vadim Smirnov
                      Keymaster

                        Еще один возможный вариант – использовать не мост, а маршрутизацию. Несколько лет назад делал нечто подобное для NetTalk DUO при подключении через USB (RNDIS). В такой конфигурации в системе появляется дополнительный сетевой интерфейс, а NetTalk DUO выглядел как сетевое устройство подключенное к той же сети. Приложение на winpkfilter обеспечивало выдачу адресов в этой сети по DHCP и организовывало NAT из этой сети на внешний интерфейс, таким образом NetTalk DUO получал доступ к интернету от подключенного лэптопа.

                        in reply to: PassThru #9619
                        Vadim Smirnov
                        Keymaster

                          Да, любопытно, я такой список интерфейсов наблюдаю, только если сначала сбриджить два адаптера, а затем в свойствах моста отключить их от моста. Похоже не все так гладко с этой конфигурацией на Windows 7…

                          Тем не менее, в качестве основы для решения поставленой задачи, я бы рекомендовал взять мост построеный на WinpkFilter:
                          https://www.ntkernel.com/bridging-networks-with-windows-packet-filter/
                          Код на GitHub:
                          https://github.com/wiresock/ndisapi/tree/master/examples/ethernet_bridge
                          и в нем отдельно обработать SIP трафик. Мне кажется так и проще и надежней с учетом не до конца предсказуемого поведения встроенного моста Windows.

                          in reply to: PassThru #9615
                          Vadim Smirnov
                          Keymaster

                            Если я правильно понимаю, то имеем две сетевые карты обьединенные Windows Bridge? Или мост организован чем-то еще, например построен на этом примере https://github.com/wiresock/ndisapi/tree/master/examples/ethernet_bridge?

                            Я только что попробовал обьединить две сетевые карты на Win7 32bit с помощью Windows Bridge и дело в том что после обьединения WinpkFilter больше не видит адаптеры “под” мостом, поэтому мне непонятно как получилось запустить passthru на одном из них. Ниже вывод listadapters без моста и с включенным мостом:

                            C:\Program Files\WinpkFilter\bin\i386>listadapters
                            The following network interfaces are available to MSTCP:
                            1) WAN Network Interface (BH).
                                    Internal Name:   \DEVICE\NDISWANBH
                                    Current MAC:     C23720524153
                                    Medium:  0x00000003
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            2) WAN Network Interface (IP).
                                    Internal Name:   \DEVICE\NDISWANIP
                                    Current MAC:     C23720524153
                                    Medium:  0x00000003
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            Number of active WAN links: 0
                            3) WAN Network Interface (IPv6).
                                    Internal Name:   \DEVICE\NDISWANIPV6
                                    Current MAC:     C23720524153
                                    Medium:  0x00000003
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            Number of active WAN links: 0
                            4) Local Area Connection 2.
                                    Internal Name:   \DEVICE\{952D0F1E-B3CE-4BEF-9DFE-515F24CA8A0E}
                                    Current MAC:     02004C4F4F50
                                    Medium:  0x00000000
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            5) Local Area Connection.
                                    Internal Name:   \DEVICE\{C06C019F-D330-41DB-A35B-0B27382DE884}
                                    Current MAC:     00155D01780A
                                    Medium:  0x00000000
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            
                            Current system wide MTU decrement = 0
                            
                            Default adapter startup mode = 0x0
                            C:\Program Files\WinpkFilter\bin\i386>listadapters
                            The following network interfaces are available to MSTCP:
                            1) Network Bridge.
                                    Internal Name:   \DEVICE\{F66FC5CF-6953-47C8-86F6-1A3B5771E620}
                                    Current MAC:     02004C4F4F50
                                    Medium:  0x00000000
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            2) WAN Network Interface (BH).
                                    Internal Name:   \DEVICE\NDISWANBH
                                    Current MAC:     C23720524153
                                    Current MAC:     C23720524153
                                    Medium:  0x00000003
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            3) WAN Network Interface (IP).
                                    Internal Name:   \DEVICE\NDISWANIP
                                    Current MAC:     C23720524153
                                    Medium:  0x00000003
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            Number of active WAN links: 0
                            4) WAN Network Interface (IPv6).
                                    Internal Name:   \DEVICE\NDISWANIPV6
                                    Current MAC:     C23720524153
                                    Medium:  0x00000003
                                    Current MTU:     1500
                                    Current adapter mode = 0x0
                            Number of active WAN links: 0
                            
                            Current system wide MTU decrement = 0
                            
                            Default adapter startup mode = 0x0
                            C:\Program Files\WinpkFilter\bin\i386>

                            К слову, в отличии от Windows 7, на Windows 10 это возможно…

                            Так что пожалуйста побольше деталей и желательно описать задачу, а то сложно советовать, не зная, что хочется в итоге получить.

                            in reply to: WinpkFilter news/updates. #9610
                            Vadim Smirnov
                            Keymaster

                              WinpkFilter 3.2.8.1 update:

                              1. Windows 10 HLK tests passed
                              2. RAS_LINK ProtocolBuffer size extended to 2048 bytes (Windows Vista had 600 bytes buffer, while Windows 10 has 1200 bytes)
                              3. Fixed task offload issue specific to certain 10 Gbps network interfaces which could cause packet loss and thus network performance degradation
                              4. Updated and slightly extended NDISAPI.DLL
                              5. Added Bluetooth media type for NDIS Lightweight Filter driver type

                              If you are eligible for a free update, please send the following details to support@ntkernel.com tо receive an update instruction:

                              Your order ID.
                              An approximate date of purchasing.

                              Vadim Smirnov
                              Keymaster

                                Александр,

                                Если программа упадет и процесс завершится, то драйвер перейдет в режим “пропускать все” и сессия продолжится (возможна потеря некоторого числа пакетов). Хуже если программа намертво зависнет, тогда сеть может оказаться заблокированной, так что для обеспечения надежности стоит предусмотреть механизм самоконтороля и аварийного завершения.

                                Примеры для Delphi в целом несколько простоваты, для начала можно взять passthru, но при этом сразу рекомендую его немного изменить для работы с блоками пакетов (аналогичный пример на С называется packthru), это существенно улучшит производительность. В остальном каких то больших трудностей я не вижу, добавить дополнительные пакеты в UDP сессию относительно несложно.

                                in reply to: Изменение пакета #9600
                                Vadim Smirnov
                                Keymaster

                                  Примера для C#, к сожалению нет, в следующих версиях соответствующие функции будут добавлены к ndisapi.dll, но ничего не мешает сделать сейчас:

                                  //
                                  // Function recalculates IP checksum
                                  //
                                  void
                                  CNdisApi::RecalculateIPChecksum(
                                  	PINTERMEDIATE_BUFFER pPacket
                                  )
                                  {
                                  	unsigned short word16;
                                  	unsigned int sum = 0;
                                  	unsigned int i = 0;
                                  	PUCHAR buff;
                                  
                                  	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
                                  
                                  	// Initialize checksum to zero
                                  	pIpHeader->ip_sum = 0;
                                  	buff = (PUCHAR)pIpHeader;
                                  
                                  	// Calculate IP header checksum
                                  	for (i = 0; i < pIpHeader->ip_hl * sizeof(DWORD); i = i + 2)
                                  	{
                                  		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
                                  		sum = sum + word16;
                                  	}
                                  
                                  	// 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;
                                  
                                  	pIpHeader->ip_sum = htons((unsigned short)sum);
                                  }
                                  
                                  //
                                  // Function recalculates ICMP checksum
                                  //
                                  void
                                  CNdisApi::RecalculateICMPChecksum(
                                  	PINTERMEDIATE_BUFFER pPacket
                                  )
                                  {
                                  	unsigned short word16, padd = 0;
                                  	unsigned int i, sum = 0;
                                  	PUCHAR buff;
                                  	DWORD dwIcmpLen;
                                  	icmphdr_ptr pIcmpHeader = NULL;
                                  	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
                                  
                                  	// Sanity check
                                  	if (pIpHeader->ip_p == IPPROTO_ICMP)
                                  	{
                                  		pIcmpHeader = (icmphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
                                  	}
                                  	else
                                  		return;
                                  
                                  	dwIcmpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;
                                  
                                  	if ((dwIcmpLen / 2) * 2 != dwIcmpLen)
                                  	{
                                  		padd = 1;
                                  		pPacket->m_IBuffer[dwIcmpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
                                  	}
                                  
                                  	buff = (PUCHAR)pIcmpHeader;
                                  	pIcmpHeader->checksum = 0;
                                  
                                  	// make 16 bit words out of every two adjacent 8 bit words and 
                                  	// calculate the sum of all 16 bit words
                                  	for (i = 0; i< dwIcmpLen + padd; i = i + 2) {
                                  		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
                                  		sum = sum + (unsigned long)word16;
                                  	}
                                  
                                  	// 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;
                                  
                                  	pIcmpHeader->checksum = ntohs((unsigned short)sum);
                                  }
                                  
                                  //
                                  // Function recalculates TCP checksum
                                  //
                                  void
                                  CNdisApi::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[i] << 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);
                                  }
                                  
                                  //
                                  // Function recalculates UDP checksum
                                  //
                                  void
                                  CNdisApi::RecalculateUDPChecksum(
                                  	PINTERMEDIATE_BUFFER pPacket
                                  )
                                  {
                                  	udphdr_ptr pUdpHeader = NULL;
                                  	unsigned short word16, padd = 0;
                                  	unsigned int i, sum = 0;
                                  	PUCHAR buff;
                                  	DWORD dwUdpLen;
                                  
                                  	iphdr_ptr pIpHeader = (iphdr_ptr)&pPacket->m_IBuffer[sizeof(ether_header)];
                                  
                                  	// Sanity check
                                  	if (pIpHeader->ip_p == IPPROTO_UDP)
                                  	{
                                  		pUdpHeader = (udphdr_ptr)(((PUCHAR)pIpHeader) + sizeof(DWORD)*pIpHeader->ip_hl);
                                  	}
                                  	else
                                  		return;
                                  
                                  	dwUdpLen = ntohs(pIpHeader->ip_len) - pIpHeader->ip_hl * 4;//pPacket->m_Length - ((PUCHAR)(pTcpHeader) - pPacket->m_IBuffer);
                                  
                                  	if ((dwUdpLen / 2) * 2 != dwUdpLen)
                                  	{
                                  		padd = 1;
                                  		pPacket->m_IBuffer[dwUdpLen + pIpHeader->ip_hl * 4 + sizeof(ether_header)] = 0;
                                  	}
                                  
                                  	buff = (PUCHAR)pUdpHeader;
                                  	pUdpHeader->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< dwUdpLen + padd; i = i + 2) {
                                  		word16 = ((buff[i] << 8) & 0xFF00) + (buff[i + 1] & 0xFF);
                                  		sum = sum + (unsigned long)word16;
                                  	}
                                  
                                  	// add the UDP 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 UDP packet
                                  	sum = sum + IPPROTO_UDP + (unsigned short)dwUdpLen;
                                  
                                  	// 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;
                                  
                                  	pUdpHeader->th_sum = ntohs((unsigned short)sum);
                                  }
                                  
                                Viewing 15 posts - 571 through 585 (of 1,476 total)