Bash script to determine max MTU

An area of the forum to discuss router binaries (utilities and applications that run on routers) etc.
Post Reply
mstombs
RouterTech Team
RouterTech Team
Posts: 3753
Joined: Wed Jan 10, 2007 11:54 pm

Bash script to determine max MTU

Post by mstombs » Sat Jan 19, 2008 12:13 pm

Unchanged script from:- "V1.02.09 - DGTeam Rev. 0743" for Netgear 834GT

viewtopic.php?p=25585

Code: Select all

#! /bin/sh
#edit by stev-o - find the MTU available for current network

#Usage: $0 <exthost>
#
#$0 = Me
#<exthost> = custom host used for test, different from built-in ones, needed if they go down or close: this is optional
#
#P.S.:due to a limitation of busybox "ping" command, make sure the hosts passed reject fragmented packet, otherwise the test will be compromized...

export PATH=$PATH:"/usr/sbin:/bin:/usr/bin:/sbin"

MTU="32"
STEP="750"
STROKES_LIMIT="30"
PACKETS_HEADER="28"
HOST_1="www.grc.com"  #Hosts MUSTN'T reply packets greater than effective MTU so not all hosts are GOOD for test...
HOST_2="dns.it.net"
HOST_3="www.libero.it"
HOST_EXT="$1"

probe() {  #ping host with one icmp-echo packet of variable size: the output is passed through various shell filters
    if [ "$HOST" != "" ]; then  #avoid processing NULL, if exthost is not given
    echo "Sending $MTU bytes to $HOST"
    ping -s $MTU -c "1" $HOST > /dev/null 2>&1
    RESULT=$?
    #recursive output message
        if [ "$RESULT" = "0" ]; then
        echo "----> Contiguous"
        else
        echo "----> Fragmented"
        fi
    echo
    fi
}

answer() {
    echo
    echo "It's reasonable to say that $MTU_LASTGOOD bytes is the largest contiguous packet size ($MTU includes $PACKETS_HEADER ICMP/IP Headers)"
    echo
    echo "MTU should be set to $MTU"
    echo
}

#Let's start testing, with a small echo-packet, if the host is at least reachable
for HOST in "$HOST_EXT" "$HOST_1" "$HOST_2" "$HOST_3"
do
    probe
    if [ "$RESULT" = "0" ]; then  #If the 1st host fails, try the others
    HOSTGOOD="1"
    break
    else
    HOSTGOOD="0"
    fi
done

#No valid hosts founded: exit...
if [ "$HOSTGOOD" != "1" ]; then
echo "No reachable hosts"
exit 1
fi

#The host is pingable, so let's go on with larger packets....    
MTU="$STEP"
STROKES="0"
while [ "$STROKES" -lt "$STROKES_LIMIT" ]
do
    STEP=`expr "$STEP" / 2 + "$STEP" % 2`
    probe
        if [ "$RESULT" = "0" ]; then
            if [ "$MTU" = "$MTU_LASTGOOD" ]; then
            break
            else
            MTU_LASTGOOD="$MTU"
            MTU=`expr "$MTU" + "$STEP"`
            fi
        else
        MTU=`expr "$MTU" - "$STEP"`
        fi
    STROKES=`expr "$STROKES" + 1`  #limit the max loop retries in case of successive host failures
done

#Maximum retries value reached: exit...
if [ "$STROKES" = "$STROKES_LIMIT" ]; then
echo
echo "Test limit exceeded"
exit 2
fi

#Add ICMP default header to the found value
MTU=`expr "$MTU" + "$PACKETS_HEADER"`
answer
User avatar
thechief
RouterTech Team
RouterTech Team
Posts: 12064
Joined: Wed Feb 01, 2006 10:22 pm
Location: England, the Centre of Africa
Contact:

Post by thechief » Sat Jan 19, 2008 5:20 pm

Cool :) Tells me that my mtu "should" be set to 1452 - but it was already set at 1452. And when I set it to 1500, it tells me that it "should" be set to 1500.

Is there another meaning to "should" in this case? :?
The Chief: :afro: Be sure to read the Firmware FAQ and do a Forum Search before posting!
No support via PM. Ask all questions on the open forum.
mstombs
RouterTech Team
RouterTech Team
Posts: 3753
Joined: Wed Jan 10, 2007 11:54 pm

Post by mstombs » Sat Jan 19, 2008 7:09 pm

It also tells me that my mtu "should" be set to whatever it currently is and pppoa can support 1500 - but last week something downstream was not working above 1492 (the pppoe limit) for me - determined manually from DOS!
mstombs
RouterTech Team
RouterTech Team
Posts: 3753
Joined: Wed Jan 10, 2007 11:54 pm

Post by mstombs » Wed Jan 14, 2009 12:28 am

I'm sure I had one before, but couldn't find it - so here's a dos bat version of the above script, save as "mtu.bat" and run it

Code: Select all

rem #! /bin/sh
rem edit by stev-o - find the MTU available for current network
rem convert to DOS bat 20090113 mstombs
rem Usage: $0 <exthost>
rem $0 = Me
rem <exthost> = custom host used for test, different from built-in ones, needed if they go down or close: this is optional

@echo off
rem .-- Prepare the Command Processor --
setlocal ENABLEEXTENSIONS
setlocal ENABLEDELAYEDEXPANSION
rem -- Set the title
set version=01.000
set title=%~nx0 - version %version%
title %title%

::: -- Set the window size --
MODE CON: COLS=50 LINES=60

set /a MTU=32
set /a STEP=750
set /a STROKES_LIMIT=30
set /a PACKETS_HEADER=28
set HOST_1=www.grc.com
set HOST_2=dns.it.net
set HOST_3=www.libero.it
set HOST_EXT=%1%

rem Let's start testing, with a small echo-packet, if the host is at least reachable
for %%H in (%HOST_EXT% %HOST_1% %HOST_2% %HOST_3%) do (
	set host=%%H
	call:probe
	if !RESULT! == "0" (
	rem  If the 1st host fails, try the others
		set HOSTGOOD="1"
		echo Good, !host! is pingable
		echo.
		goto got
	) else (
		set HOSTGOOD="0"
	)
)
:got
rem No valid hosts founded: exit...
if %HOSTGOOD% NEQ "1" (
	echo "No reachable hosts"
	pause
	exit
)

rem The host is pingable, so let's go on with larger packets....
set /a MTU=STEP
set /a STROKES=0
:do
	set /a STEP=STEP-STEP/2
	call:probe
	if %RESULT% == "0" (
		if  "%MTU%" == "%MTU_LASTGOOD%" (
			goto done
		) else (
			set /a MTU_LASTGOOD=MTU
			set /a MTU=MTU+STEP
		)
	) else (
		set /a MTU=MTU-STEP
	)
	set /a STROKES=STROKES+1
rem limit the max loop retries in case of successive host failures
if %STROKES% LSS %STROKES_LIMIT% (
	goto do
) else (
rem Maximum retries value reached: exit...
	echo.
	echo "Test limit exceeded"
	pause
	exit
)
:done
rem Add ICMP default header to the found value
set /a MTU=MTU+PACKETS_HEADER
echo.
echo %MTU_LASTGOOD% bytes is the largest contiguous packet size
echo %MTU% including %PACKETS_HEADER% ICMP/IP Headers
echo.
echo MTU should be set to %MTU%
echo.
pause
exit 0

:probe
:: ping host with one icmp-echo packet of variable size
if %host% NEQ "" (
	rem #avoid processing NULL, if exthost is not given
	echo Sending %MTU% bytes to %host%
	ping -f -l %MTU% -n "1" %host% >NUL
	rem recursive output message
		if errorlevel 1 (
			echo ....... Fragmented
			set RESULT="1"
		) else (
			echo ....... Contiguous
			set RESULT="0"
		)
echo.
)
goto:eof
Example output

Code: Select all

Sending 32 bytes to example.com
....... Contiguous

Good, example.com is pingable

Sending 750 bytes to example.com
....... Contiguous

Sending 1125 bytes to example.com
....... Contiguous

Sending 1313 bytes to example.com
....... Contiguous

Sending 1407 bytes to example.com
....... Contiguous

Sending 1454 bytes to example.com
....... Fragmented

Sending 1430 bytes to example.com
....... Fragmented

Sending 1418 bytes to example.com
....... Contiguous

Sending 1424 bytes to example.com
....... Fragmented

Sending 1421 bytes to example.com
....... Contiguous

Sending 1423 bytes to example.com
....... Fragmented

Sending 1422 bytes to example.com
....... Contiguous

1422 bytes is the largest contiguous packet size
1450 including 28 ICMP/IP Headers

MTU should be set to 1450

Press any key to continue . . .
If your router is not the limiting size - consider making it so!
Post Reply