Post

LAN MTU Scanner

LAN MTU Scanner

A simple script to discover the maximum MTU supported by every device on your LAN — so you can confidently enable jumbo frames without breaking connectivity.

Why

Most home and lab networks run at the default MTU of 1500 bytes. But if your switch and NICs support jumbo frames (up to 9000 bytes), you’re leaving throughput on the table — especially for large file transfers, NAS backups, and VM traffic. The problem is that every device in the path must support the same MTU. One misconfigured device and packets get silently dropped or fragmented.

This script removes the guesswork. It scans your LAN, finds live hosts, and tests each one to determine the largest packet it will accept without fragmentation.

How It Works

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Scan LAN for active hosts
        |
        v
  For each host:
        |
        v
  Send ping with DF (Don't Fragment) bit set
  Starting at 9000 bytes, step down
        |
        ├── Ping succeeds
        |     -> Report max MTU for this host
        |
        └── Ping fails
              -> Reduce size and retry
              -> Floor at 1500 (standard MTU)

The key flag is ping -M do which sets the Don’t Fragment bit. If the packet is too large for any link in the path, ICMP will reject it instead of silently fragmenting — giving us an exact measurement.

The Script

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/bin/bash
# mtu-scan.sh — Discover max MTU for each device on your LAN

SUBNET="${1:-192.168.1}"
MTU_START=9000
MTU_STEP=500
MTU_MIN=1500

echo "Scanning ${SUBNET}.0/24 for max MTU support..."
echo "=============================================="

for host in $(seq 1 254); do
    ip="${SUBNET}.${host}"

    # skip hosts that aren't alive
    ping -c 1 -W 1 "$ip" &>/dev/null || continue

    mtu=$MTU_START
    max_mtu=$MTU_MIN

    while [ $mtu -ge $MTU_MIN ]; do
        payload=$((mtu - 28))  # subtract IP + ICMP headers
        if ping -M do -c 1 -W 1 -s "$payload" "$ip" &>/dev/null; then
            max_mtu=$mtu
            break
        fi
        mtu=$((mtu - MTU_STEP))
    done

    if [ $max_mtu -gt $MTU_MIN ]; then
        echo "$ip — max MTU: $max_mtu (jumbo frames supported)"
    else
        echo "$ip — max MTU: $MTU_MIN (standard)"
    fi
done

echo ""
echo "Done. The lowest value above is your safe network-wide MTU."

Usage

1
2
3
4
5
6
7
chmod +x mtu-scan.sh

# Scan default subnet (192.168.1.x)
./mtu-scan.sh

# Scan a different subnet
./mtu-scan.sh 10.0.0

Example Output

1
2
3
4
5
6
7
8
9
Scanning 192.168.1.0/24 for max MTU support...
==============================================
192.168.1.1   — max MTU: 1500 (standard)
192.168.1.10  — max MTU: 9000 (jumbo frames supported)
192.168.1.15  — max MTU: 9000 (jumbo frames supported)
192.168.1.20  — max MTU: 1500 (standard)
192.168.1.100 — max MTU: 9000 (jumbo frames supported)

Done. The lowest value above is your safe network-wide MTU.

In this example, the router (.1) and one device (.20) only support 1500 — so enabling 9000 network-wide would break connectivity to those devices. You could either upgrade those devices or set jumbo frames only between the hosts that support it.

Fine-Tuning

The default MTU_STEP of 500 gives a fast scan. For an exact measurement, you can do a second pass:

1
2
# Binary search between 1500 and the value found above
MTU_STEP=1

Or modify the script to do a binary search between the last failure and last success for each host.

What is MTU

MTUNameUse Case
1500Standard EthernetDefault for most networks
9000Jumbo FramesNAS, iSCSI, VM migration, bulk transfers
1280IPv6 MinimumSmallest allowed for IPv6

Things to Know

  • All devices in the path matter — your NIC, switch, router, and destination all need to support the MTU you set
  • Switches don’t respond to ping — this script tests end-to-end path MTU, not individual switch capability
  • VPN and tunnels reduce MTU — WireGuard typically needs ~1420, OpenVPN ~1400 due to encapsulation overhead
  • Setting MTU too high causes silent failures — packets get dropped with no obvious error, making it hard to debug without a tool like this
This post is licensed under CC BY 4.0 by the author.