Jump to content
Sign in to follow this  
cdtoews

Check MTU size without ICMP

Recommended Posts

cdtoews

I'm looking for a way to test MTU without ICMP.

I have made the following script to check for MTU size end-to-end. My problem currently is that I need to check MTU size in an environment where ICMP is blocked. I'm mostly trying to check connectivity to devices that I manage, and that will accept HTTP requests. I'm hoping someone can help me send HTTP request packets of a certain size, and see if I get a request. One of the requirements is that I will need to be able to specify the port number that it uses.

Any help will be appreciated.

Here is my code for testing MTU using ICMP

#include <Array.au3>
#include <GUIConstants.au3>

Opt("GUICoordMode",2)
Opt("GUIOnEventMode", 1)
dim $sAddress , $sResult , $NF_blocked , $NF_works , $IPaddress , $RET , $PID , $test_mtusize , $jumpsize , $blocked , $lastblocked , $mtu , $currentmtu
dim $RET2 , $PID2 , $rawhostlist , $hostlist , $temp , $pre , $post , $temp1  , $row , $testaddress , $displaylist , $extraline , $maxrow , $mainwindow
dim $na = "****"
dim $hoplist[30][5]

dim $hopcell = 50
dim $widthcell = 100
dim $hostcell = 200
dim $nextline = (-1 * $hostcell) + (-3 * $widthcell) + (-1 * $hopcell)



;put back next line after testing
$sAddress = InputBox("Test MTU size to where?","What IP to test to: ")


;check for connectivity
$pResult = _PingTest($sAddress)

if StringInStr($pResult,"Reply") Then
;continue with script
Else
    MsgBox(0,"D'Oh", "Can't even ping " & $sAddress)
    Exit
EndIf


$mainwindow = GUICreate("Testing MTU",650,650) ; will create a dialog box that when displayed is centered
GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked")
$okbutton = GUICtrlCreateButton("OK", 300, 620, 50)
GUICtrlSetOnEvent($okbutton, "OKButton")

GUICtrlCreateLabel ("Testing MTU to each hop, visit http://help.toews.us", -340, -620, 500)

GUICtrlCreateLabel ("Hop",  -500, 0, $hopcell)
GUICtrlCreateLabel ("DNS Name",  0, -1, $hostcell)
GUICtrlCreateLabel ("IP Address",  0, -1, $widthCell)
GUICtrlCreateLabel ("MTU",  0, -1, $widthCell)
GUICtrlCreateLabel ("Ping Max MTU +1",  0, -1, $widthCell)
GUISetState ()   ; will display an empty dialog box


;running pathping to find route to host
$rawhostlist = _Pathping($sAddress)
;msgBox(0,"pathping results",$rawhostlist)

$temp = StringReplace($rawhostlist, @cr & @cr, @cr)
$rawhostlist = $temp
$temp = StringReplace($rawhostlist, @LF , "")
$rawhostlist = $temp
$hostlist = StringSplit($rawhostlist, @cr)
;_ArrayDisplay($hostlist, "hostlist")

;loop to populate $hoplist
for $x = 0 to $hostlist[0]
    $maxrow = $row
;MsgBox(0,'','inside loop')
    if StringInStr($hostlist[$x],"Computing") Then
        ExitLoop
    Elseif $hostlist[$x] = "" Then 
        if $pre = 1 and $extraline =0 Then
        ;this is to check, sometimes there is an empty space before
            $extraline = 1
        Else
            $post = 1
        EndIf
    Elseif $pre = 1 and $post = 0 Then;hoplist array population
    ;MsgBox(0,'','inside host if')
        $temp1 = StringSplit(StringStripWS($hostlist[$x],4), " ",1);$temp1[0] = 4(no reverse dns)  5(reverse dns)
    ;_ArrayDisplay($temp1,$hostlist[$x])
    ;MsgBox(0,'tem1[4] is',$temp1[4])
        if $temp1[0] = 5 Then
            $hoplist[$row][1] = $temp1[2]
            $hoplist[$row][2] = $temp1[3]
            $hoplist[$row][3] = cleantext($temp1[4])
        ElseIf $temp1[0] = 4 Then
            $hoplist[$row][1] = $temp1[2]
            $hoplist[$row][2] = $temp1[3]
            $hoplist[$row][3] = $temp1[3]
                    
        EndIf
            GUICtrlCreateLabel ($hoplist[$row][1],  $nextline,0 , $hopcell)
            GUICtrlCreateLabel ($hoplist[$row][2],  0, -1, $hostcell)
            GUICtrlCreateLabel ($hoplist[$row][3],  0, -1, $widthCell)
                
    ;MsgBox(0,'$hoplist[$row][3] is',$hoplist[$row][3])
        MsgBox(0,'','going to test ' & $hoplist[$row][3])
        $hoplist[$row][4] = _maxmtu($hoplist[$row][3])
        GUICtrlCreateLabel ($hoplist[$row][4],  0, -1, $widthCell)
        GUICtrlCreateLabel (_fragtest($hoplist[$row][3],$hoplist[$row][4])  ,  0, -1, $widthCell)
            
        
        $row += 1
    EndIf;end of hoplist array population
    
    if StringInStr($hostlist[$x],"maximum") Then
    ;MsgBox(0,'','found maximum')
        $pre = 1
        $post = 0
    EndIf
    
        
    
Next

GUICtrlCreateLabel (" Script  Done",  $nextline,0 , $hopcell)
            



#cs
              ##########################################
              #         display hoplist          #
              ##########################################
              

for $y = 1 to $maxrow
    for $z = 1 to 4
        $displaylist &= $hoplist[$y][$z] & @TAB
    Next
    $displaylist &= @CRLF
Next
MsgBox(0,'display list',$displaylist)
#ce

While 1
  Sleep(1000) ; Idle around
WEnd

#cs
_maxmtu($sAddress)
MsgBox(64, "Results", "Largest Unfragmented Packet to " & $sAddress & @crlf & "is " & $NF_works)

#ce
Func _fragtest($testaddress, $mtu)
    local $output
    local $fragmtu
    $fragmtu = $mtu + 1
    Local $PID = Run(@ComSpec & " /c ping  " & $testaddress & " -n 1  -l " & $fragmtu, @TempDir, @SW_HIDE, 2); 2 = $STDOUT_CHILD
    While 1
        $output &= StdoutRead($PID)
        If @error Then ExitLoop
    WEnd
    if StringInStr($output,"Reply") Then
        Return "Pass"
    Else
        Return "Fail"
    EndIf
    
    
    
    
    
EndFunc


func _maxmtu($testaddress)
    
    local $bogusIP
    $bogusIP = 0
;check to see if this is an IP  

;check to see if number($hostIP) is obove 0 and below 255
    If Number($testaddress) <= 0 Then
        Return $na
        $bogusIP =1
    ElseIf Number($testaddress) > 255 Then
        Return $na
        $bogusIP = 1
    EndIf
    SetError(0)
;pings host and checks for errors
    ping($testaddress, 1)
    if @error = 3 Then
        Return $na
        $bogusIP = 1
    ElseIf @error = 4 Then
        Return $na
        $bogusIP = 1
    EndIf

    
    if $bogusIP = 0 Then
            
        ;MsgBox(0,'going out',$testaddress)
            $jumpsize = 200
            $test_mtusize = 1500
        do 
            
            $sResult = _MtuTest($testaddress , $test_mtusize);ping with "do no fragment" set
            $currentmtu = $test_mtusize
            if StringInStr($sResult,"fragmented") Then;packet too large
                $NF_blocked = $test_mtusize
                $test_mtusize -= $jumpsize
                $blocked = 1
            Else;packet under threshold
                $NF_works = $test_mtusize
                $test_mtusize += $jumpsize
                $blocked = 0
            EndIf
            
            if $blocked = $lastblocked Then
            Else
                $jumpsize = int($jumpsize/2)
                if $jumpsize <1 Then
                    $jumpsize = 1
                EndIf
                
            EndIf
            $lastblocked = $blocked
                
            ;MsgBox(0,'wassup',"$currentmtusize: " & $currentmtu & @crlf & @crlf & "$jumpsize: " & $jumpsize  & @crlf & @crlf & "$blocked: " & $blocked & @crlf & @crlf & "Blocked: " & $NF_blocked & @crlf & @crlf &  "$NF_works: " & $NF_works)
            
        until $NF_blocked = $NF_works+1
        Return $NF_works
    EndIf
EndFunc


Func _MtuTest($IPaddress, $mtu)
    
    Local $RET = ""
    Local $PID = Run(@ComSpec & " /c ping  " & $IPaddress & " -n 1 -f -l " & $mtu, @TempDir, @SW_HIDE, 2); 2 = $STDOUT_CHILD
   ;Local $PID = Run(@ComSpec & " /c ping  " & $IPaddress & " -n 1 -f -l " & $mtu, @TempDir,@SW_SHOW, 2); 2 = $STDOUT_CHILD
    While 1
        $RET &= StdoutRead($PID)
        If @error Then Return $RET
    WEnd
EndFunc  ;==>_NSLookup 

Func cleantext($toclean)
    local $replacewith = ""
    local $badtext =  "[]"
    for $cleanloop = 1 to stringlen($badtext)
        $temp = StringReplace($toclean,StringMid($badtext,$cleanloop,1),$replacewith)
    ;MsgBox(0,'inside cleantext loop',"clearing: " & StringMid($badtext,$cleanloop,1) & @crlf & $toclean)
        $toclean = $temp
    Next
    
    Return $toclean
EndFunc



func _Pathping($IPaddress)
    Local $RET3 = ""
    Local $PID3 = Run(@ComSpec & " /c pathping  " & $IPaddress , @TempDir, @SW_HIDE, 2); 2 = $STDOUT_CHILD
    While 1
        $RET3 &= StdoutRead($PID3)
        if StringInStr($ret3,"Computing statistics") then 
            return $RET3
            ExitLoop
        EndIf
        
        If @error Then Return $RET3
    WEnd    
    


EndFunc




Func _PingTest($IPaddress)
    Local $RET2 = ""
    Local $PID2 = Run(@ComSpec & " /c ping  " & $IPaddress & " -n 1 ", @TempDir, @SW_HIDE, 2); 2 = $STDOUT_CHILD
    While 1
        $RET2 &= StdoutRead($PID2)
        If @error Then Return $RET2
    WEnd
EndFunc  ;==>_NSLookup 


Func    CLOSEClicked()
    ;nuthin
EndFunc     
Func OKButton()
   Exit
EndFunc

Share this post


Link to post
Share on other sites
ptrex

@cdtoews

You can read out the MTU size from the REGISTRY

System Key: [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\

Interfaces\[Adapter ID]]

Value Name: MTU

Data Type: REG_DWORD (DWORD Value)

Value Data: Default = 0xffffffff

Regards

ptrex

Share this post


Link to post
Share on other sites
cdtoews

@cdtoews

You can read out the MTU size from the REGISTRY

Regards

ptrex

Reading the MTU size will tell me what size the packets are leaving at, not the end-to-end MTU size. A router along the way may be fragmenting the packets. I want to send packets with the "do not fragment" flag set, just like when you ping with the -f flag.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×