is MTU decrement just for outbound package

Home Forums Discussions Support Portal is MTU decrement just for outbound package


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

    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?


    Vadim Smirnov

    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.


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

    Vadim Smirnov

    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);
    		reinterpret_cast<char*>(eth_header) + ETHER_HEADER_LENGTH + sizeof(iphdr) + sizeof(icmphdr),
    	// 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
    	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.