Home › Forums › Discussions › Support › is MTU decrement just for outbound package
Tagged: MTU decrement
- This topic has 3 replies, 2 voices, and was last updated 3 years, 2 months ago by Vadim Smirnov.
-
AuthorPosts
-
September 8, 2021 at 3:48 pm #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?Thanks.
September 10, 2021 at 2:09 am #11780Yes, 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.
September 12, 2021 at 8:54 am #11781Thanks for answer. How to use TCP MSS option and ICMP fragmentation needed via Windows Packet Filter?
September 12, 2021 at 12:04 pm #11782As 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; }
-
AuthorPosts
- You must be logged in to reply to this topic.