Every now and again, I come across some kind of connectivity issue relating to misconfigured MTUs somewhere along the connection path. This can manifest itself through any number of symptoms. A common problem I have seen is with VPN connectivity to Checkpoint; all other basic connectivity tests are successful, but the VPN still won't connect. So once you figure that the issue may be relating to MTUs, how do you go about testing that?

There are a number of ways to do so, but as the article title suggests, we will be doing so with the ping command. While my primary focus will be from a Linux perspective, you can certainly run this test from a Windows host as well.

First up, let's take a look at the Linux command we will be using, and break it down a bit:

ping -c 2 -M do -s <size> <IP Address>

Let's take a look at the flags:

-c 2 : send only 2 pings. By default, Linux will continuously ping, this way we limit how long the MTU test will take. Theoretically, this would work with just 1 ping, but I am sending 2 to be sure.

-M do : This one may be a bit backwards for some... But it means DO set the DF (Do Not Fragment) option on the packet.

-s <size> - we will manually set the ping packet sizes to determine the MTU.

STRATEGY

The strategy is simple... Ping a series of diffent sizes, and this will help narrow down the MTU size. A ping is 28 bytes on it's own. A typical LAN connection has an MTU of 1500 bytes. So we need to remember to subtract 28 from the MTU we really want to test. For example, if we want to test an MTU of 1500, first ping and set the size to 1473, this should fail as we are sending a ping that is 1501 bytes in size, with the Do Not Fragment option set. you should get an output similar to the following:

jon@JonM-LabPC:/$ ping -c 2 -M do 8.8.8.8 -s 1473
PING 8.8.8.8 (8.8.8.8) 1473(1501) bytes of data.
ping: local error: Message too long, mtu=1500
ping: local error: Message too long, mtu=1500

--- 8.8.8.8 ping statistics ---
2 packets transmitted, 0 received, +2 errors, 100% packet loss, time 1006ms

We can see the error "Message too long", followed by the actual MTU size. Please be aware that not all Linux distros will have this same output... For Checkpoint's Gaia, you will get something similar to this:

[Expert@R7730StandAlone:0]# ping -c 2 -M do -s 1473 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 1473(1501) bytes of data.
From 172.26.176.150 icmp_seq=1 Frag needed and DF set (mtu = 1500)
From 172.26.176.150 icmp_seq=1 Frag needed and DF set (mtu = 1500)

--- 8.8.8.8 ping statistics ---
0 packets transmitted, 0 received, +2 errors

So, depending on the output you get, you can further validate that the MTU is 1500 by sending a ping that is exactly 1500 bytes in size, rather than 1501. You would just set the size to 1472. This will be the MTU for 99% of internal LAN connections, and most residential cable modems.

If, however, this 1500 byte ping fails, you may be dealing with a PPPoE (or similar) kind of connection. Due to the protocol overhead, the MTU for these connections actually works out to be 1492 bytes. This also includes most residential DSL modems. To test this you would set your ping sizes to 1465 (1493 bytes total, too big), and 1464 (1494 bytes total, just perfect). I specifically mention residential DSL connections here, because that typically works out to be the issue with the Checkpoint VPN connectivity issues. The solution, in these cases, is to set the LARGER side to match the SMALLER side. So despite the fact that the CP VPN Gateway is on a 1500 MTU connection, the residential DSL connection cannot be made larger, so we set the MTU to 1492 on the Gateway.

Please keep in mind that DSL and PPPoE are NOT the only protocols that add overhead to the packets. Other things like IPv6-in-IPv4 (and reverse), GRE, IPSec encrytion, and any number of other protocols may add to that overhead. So you may need to do a series of ping tests to finally nail down the MTU. Also keep in mind that there are some security products that will drop a p[ing for size violations. Checkpoint's IPS has this kind of protection, and others do as well. In Checkpoint, this protection can be tuned, disabled, and/or excepted. Most other security products worth their money will have similar options.

Lastly, here is the Windows command you would use to perform this test from that client side:

ping -f -l <size> <IP Address>

-f : set the Do Not Fragment option
-l <size> : set the length (size) of the ping

Note: We do not need to set a count in Windows, as it will only send 4 pings by default anyways.

Fail output:

c:\>ping -f -l 1473 8.8.8.8

Pinging 8.8.8.8 with 1473 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.

Ping statistics for 8.8.8.8:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

As we can see, the Windows output isn't quite as helpful. But a ping size 1472 will just succeed as expected:

c:\>ping -f -l 1472 8.8.8.8

Pinging 8.8.8.8 with 1472 bytes of data:
Reply from 8.8.8.8: bytes=1472 time=22ms TTL=55
Reply from 8.8.8.8: bytes=1472 time=20ms TTL=55
Reply from 8.8.8.8: bytes=1472 time=21ms TTL=55
Reply from 8.8.8.8: bytes=1472 time=28ms TTL=55

Ping statistics for 8.8.8.8:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 20ms, Maximum = 28ms, Average = 22ms

Go ahead and let me know how you test your MTUs, and what kind of situations you've used this kind of test in the comments section below.