is MTU decrement just for outbound package

Home Forums Discussions Support is MTU decrement just for outbound package

Tagged: 

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #11779
    liujia
    Participant

      It said:

      Supports MTU decrement (allows you to set system-wide MTU decrement). This option is required if you plan to add additional headers to IP packets (implement IP in IP packet tunneling, IPSEC based VPN and so on)

      Target Windows system(A) installed Winpckagefilter, and ‘Current system wide MTU decrement = 1388’, then system #A IP package will be < 1500-1388 size. If ping system #A from another system(B) as command ‘ping B-ip -l 85 -f’ will retrun ‘Pinging with 85 bytes of data:
      Packet needs to be fragmented but DF set’. But ping system #B from system #A with the same command is okay. So ‘MTU decrement’ is work only on outbound package? If I need to set ‘MTU decrement’ for inbound package(only), how to do?

      Thanks.

      #11780
      Vadim Smirnov
      Keymaster

        Yes, this option modifies the MTU for local network adapters. You can’t affect the remote system MTU value directly but you can use the TCP MSS option or/and ICMP fragmentation needed to affect the effective MTU between hosts.

        #11781
        liujia
        Participant

          Thanks for answer. How to use TCP MSS option and ICMP fragmentation needed via Windows Packet Filter?

          #11782
          Vadim Smirnov
          Keymaster

            As for the TCP MSS option you can check CsnatDlg::CheckMTUCorrelation in snatDlg.cpp

            I don’t have an open source sample using ICMP fragmentation needed option, but if packet size exceeds MTU and DF flag is set then you can use the function below to convert it to ICMP type 3 code 4 (“fragmentation needed but don’t fragment set”) and forward back to the host.

            void convert_to_icmp_unreachable(INTERMEDIATE_BUFFER& buffer) const
            {
            	auto* eth_header = reinterpret_cast<ether_header_ptr>(buffer.m_IBuffer);
            	auto* ip_header = reinterpret_cast<iphdr_ptr>(buffer.m_IBuffer + ETHER_HEADER_LENGTH);
            
            	// 1. Copy IP header and 8 bytes of payload after icmp header
            	auto* const next_header = reinterpret_cast<PCHAR>(ip_header) + sizeof(DWORD) * ip_header->ip_hl;
            	const auto payload_length = static_cast<unsigned short>(next_header - reinterpret_cast<char*>(ip_header) + 8);
            	memmove(
            		reinterpret_cast<char*>(eth_header) + ETHER_HEADER_LENGTH + sizeof(iphdr) + sizeof(icmphdr),
            		ip_header,
            		payload_length
            	);
            
            	// 2. Swap MAC addresses
            	std::swap(eth_header->h_dest, eth_header->h_source);
            
            	// 3. Swap IP addresses
            	std::swap(ip_header->ip_dst, ip_header->ip_src);
            
            	// 4. Initialize IP header
            	ip_header->ip_hl = 5;
            	ip_header->ip_v = 4;
            	ip_header->ip_tos = 0;
            	ip_header->ip_len = htons(sizeof(iphdr) + sizeof(icmphdr) + payload_length);
            	ip_header->ip_off = htons(IP_DF);
            	ip_header->ip_ttl = 30;
            	ip_header->ip_p = IPPROTO_ICMP;
            
            	// 5. Initialize ICMP header
            	auto* const icmp_header = reinterpret_cast<icmphdr_ptr>(ip_header + 1);
            	icmp_header->type = 3;
            	icmp_header->code = 4;
            	icmp_header->seq = htons(config_.default_adapter->get_mtu());
            
            	// Recalculate checksum
            	RecalculateICMPChecksum(&buffer);
            	RecalculateIPChecksum(&buffer);
            
            	buffer.m_Length = ETHER_HEADER_LENGTH + sizeof(iphdr) + sizeof(icmphdr) + payload_length;
            }
          Viewing 4 posts - 1 through 4 (of 4 total)
          • You must be logged in to reply to this topic.