#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_icon=..\..\..\Windows\Installer\{B268E9A1-04A9-40D0-9866-846BE2B74BA7}\Icon_app.ico #AutoIt3Wrapper_outfile=nping.exe #AutoIt3Wrapper_Compression=3 #AutoIt3Wrapper_Change2CUI=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #NoTrayIcon #include #include Global Const $MAX_PROCESS = 25 ; A maximum number of processes Local $networkRange = "google.com" If @Compiled Then If $CmdLine[0] > 0 Then For $n = 1 to UBound($CmdLine)-1 Switch $CmdLine[$n] Case "/?", "?", "/help", "/info" _showHelp() Exit 0 Case Else $networkRange = $CmdLine[1] EndSwitch Next Else _showHelp() Exit 0 EndIf EndIf $aArray = _GetIpAddressList($networkRange) If @error Then ConsoleWrite("Error: There are no addresses to be scanned in this range. Check the syntax." & @CRLF & @CRLF) _showHelp() Exit 1 EndIf Local $aProcess[$MAX_PROCESS] ; An array to keep a reference to spawned processes, in the next loop we fill it with value 0 for reference For $i = 0 To UBound($aProcess) - 1 $aProcess[$i] = 0 Next Local $i = 0 ; which IP are we currently trying to ping ( based on array ) Local $iFinished = 0 ; how many processes have finished pinging While 1 ; We check all the currently running processes For $n = 0 To UBound($aProcess) - 1 ; Check if we need a spot, and there is an existing spot here If ($i <> UBound($aArray) And $aProcess[$n] == 0) Then $aProcess[$n] = _MSPing($aArray[$i]) ; Spawn a new process in the available spot $i += 1 ; Increment $i so we can do the next process the next time around Else ; Check if this process has been spawned and the process is ready If ($aProcess[$n] <> 0 And _MSPingIsReady($aProcess[$n])) Then ; Get results from the command $sHostname = _MSPingGetHostname($aProcess[$n]) $sResult = _MSPingGetResult($aProcess[$n]) ; If the result is not a failure If ($sResult <> -1) Then ; Write the output to console ConsoleWrite($sHostname & " has a roundtrip of " & $sResult & " ms" & @CRLF) EndIf ; Free up an empty space for the next address to Ping $aProcess[$n] = 0 ; Increment the total of processes that have finished $iFinished += 1 ; If the total number of finished processes If ($iFinished == UBound($aArray)) Then ExitLoop 2 ; Return EndIf EndIf Next Sleep(50) ; Give existing ping commands some time to process the request WEnd Func _showHelp() ConsoleWrite("nping.exe scans a network based on a supplied network address." & @CRLF & @CRLF & _ "Usage: nping.exe ipaddress" & @CRLF & @CRLF & _ "Examples: " & @CRLF & " nping.exe 192.168.0.0-1" & @CRLF & " will ping these addresses: 192.168.0.0 and 192.168.0.1" & @CRLF & _ " nping.exe 192.168.0.100-150" & @CRLF & " will ping everything in the range from 192.168.0.100 to 192.168.0.150" & @CRLF & _ " nping.exe 0-255.0-255.0-255.0-255" & @CRLF & " will ping the entire internet. Note that this will take a very long time." & @CRLF) EndFunc Func _GetIpAddressList($ipFormat) $ipFormat = StringReplace($ipFormat, "*", "1-255") $ipSplit = StringSplit($ipFormat, ".") If $ipSplit[0] <> 4 Then TCPStartup() Local $ret[1] = [TCPNameToIP($ipFormat)] If @error Then Return SetError(1) Return $ret EndIf For $i = 1 To 4 If Not StringRegExp($ipSplit[$i], "[0-9\-]*") Then TCPStartup() Local $ret[1] = [TCPNameToIP($ipFormat)] If @error Then Return SetError(1) Return $ret EndIf Next Local $ipRange[4][2], $totalPermu = 1 For $i = 0 To 3 If StringInStr($ipSplit[$i + 1], "-") Then $m = StringSplit($ipSplit[$i + 1], "-") $ipRange[$i][0] = $m[1] $ipRange[$i][1] = $m[2] Else $n = Number($ipSplit[$i + 1]) $ipRange[$i][0] = $n $ipRange[$i][1] = $n EndIf $totalPermu *= $ipRange[$i][1] - $ipRange[$i][0] + 1 Next Local $result[$totalPermu], $i = 0 For $a = $ipRange[0][0] To $ipRange[0][1] For $b = $ipRange[1][0] To $ipRange[1][1] For $c = $ipRange[2][0] To $ipRange[2][1] For $d = $ipRange[3][0] To $ipRange[3][1] $result[$i] = $a & "." & $b & "." & $c & "." & $d $i += 1 Next Next Next Next Return $result EndFunc ;==>_GetIpAddressList Func _Exit() Exit EndFunc ;==>_Exit Func _MSPing($sHostname, $timeout = 50) Local $return_struc[4] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) $return_struc[1] = $sHostname $return_struc[2] = Run("ping " & $sHostname & " -n 1 -w " & $timeout, "", @SW_HIDE, $STDOUT_CHILD) Return $return_struc EndFunc ;==>_MSPing Func _MSPingIsReady(ByRef $return_struc) Return ___MSPingReadOutput($return_struc) EndFunc ;==>_MSPingIsReady Func _MSPingGetResult($return_struc) Return $return_struc[0] EndFunc ;==>_MSPingGetResult Func _MSPingGetHostname($return_struc) Return $return_struc[1] EndFunc ;==>_MSPingGetHostname ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) $data = StdoutRead($return_struc[2]) If (@error) Then ___MSPingParseResult($return_struc) Return 1 Else $return_struc[3] &= $data Return 0 EndIf EndFunc ;==>___MSPingReadOutput ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3) If @error Then $return_struc[0] = -1 Else $return_struc[0] = $result[0] EndIf EndFunc ;==>___MSPingParseResult