I have created forged destination unreachable ICMP with type 3 and code 4 (fragmentation needed and DF bit is set). My setup has Server, Client, and a switch between them. Ideally this ICMP gets generated by router/gateway but I'm generating this at client. I'm creating this ICMP using Scapy tool. Here is how I'm creating:
ip = IP()
icmp = ICMP()
# IP Packet sent to client
ip.dst = ip_server
ip.src = ip_client
ip.protocol = 1 #shows that ip header contains icmp as data
# icmp type 3 + code 4
icmp.type = 3
icmp.code = 4
mtu =1300
icmp.unused = mtu
#
# build original packet for ICMP ping request
#
ip_orig = IP()
ip_orig.src = ip_server
ip_orig.dst = ip_client
icmp_orig = TCP()
tcp_orig.sport = 50000
tcp_orig.dport = 50000
tcp_orig.seq= original sequence number
#
# send the packet
#
send (ip/icmp/ip_orig/tcp_orig)
Steps I'm following to demonstrate the effect of this ICMP: 1> Server and client are talking to each other using sockets 2> As soon as server accepts the connection, I'm giving a 60 seconds pause in the machine during which I disable all the TCP ACKs going out of client machine (because if server receives ACKs for the message it sent then it wouldn't respond to ICMP). 3> Server sends it first message to client but won't receive any ACKs and server keeps re-transmitting the message, meanwhile I inject an ICMP message as mentioned in the above scapy code: send (ip/icmp/ip_orig/tcp/orig). I'm reporting MTU 1300 in the icmp i'm sending. 4> Ideally Server should reduce it's MTU and sends message back to client with MTU size of 1300.
But Server keeps re-transmitting the message with MTU size 1500. Kindly help me with this. Why is server not reducing its MTU? Am I doing something wrong in my demonstration? Any help would be greatly appreciated.
There are a few pointers I outlined in this answer and in its comments:
ip_orig
) is exactly identical to the one received. Therefore, setting just its source IP address and destination IP addresses (i.e.ip_orig.src
andip_orig.dst
, respectively) is probably not enough.tcp_orig.seq
) should be set as well, since the specification requires that at least 8 bytes of the problematic packet's IP layer payload are included in the ICMP error message.DF
bit is set. You can enable path MTU discovery withsysctl -w net.ipv4.ip_no_pmtu_disc=0
.