jguinch

_Multiping : ping multiples hosts simultaneously

3 posts in this topic

Here are 4 small function that I use for a tool in my job to launch several ping simultaneously. It also offers the possibility to run in background
 - _Multiping
 - _MultiPingCancel
 - _MultipingGetInfo
 - _MultiPingGetResult

_Multiping requires the use of the #pragma compile(AutoItExecuteAllowed, True) directive.

 

#pragma compile(AutoItExecuteAllowed, True)

#include <ProcessConstants.au3>
#include <WinAPI.au3>
#include <WinAPIProc.au3>


; #EXAMPLE# =====================================================================================================================
#include <Array.au3>
ConsoleWrite("Downloading hosts list, please wait...")
Local $aDomains = StringRegExp(BinaryToString(InetRead("https://github.com/opendns/public-domain-lists/blob/master/opendns-random-domains.txt")), 'js-file-line">([^<]+)</td>', 3)
Redim $aDomains[25]

Local $iProgress = 0, $iCount = UBound($aDomains), $aMPInfos, $iPercent
Local $aPings = _Multiping($aDomains, 1000, 5, 1)
ProgressOn("PING HOSTS", "Please wait while _Multiping is running")

While 1
    $aMPInfos = _MultipingGetInfo(1)
    If Not $aMPInfos[0] Then ExitLoop
    $iPercent = Floor($aMPInfos[1]* 100 / $iCount)
    ProgressSet($iPercent, $aMPInfos[1] & " / " & $iCount & " done")
    Sleep(100)
WEnd
ProgressOff()
MsgBox(0, "_Multiping example", "Result :" & @CRLF & $aMPInfos[2] & " hosts are online")
Local $aRes = _MultiPingGetResult()
_ArrayDisplay($aRes)
; ===============================================================================================================================





; #FUNCTION# ====================================================================================================================
; Name ..........: _Multiping
; Description ...: Pings a list of hosts using simultaneous pings to increase the speed.
; Syntax ........: _Multiping($aHosts[, $iTimeout = 4000[, $iMaxPing = 5[, $iBackground = 0]]])
; Parameters ....: $aHosts              - 1D array containing the list of the hosts to ping.
;                  $iTimeout            - [optional] Time to wait for an answer in milliseconds (default is 4000).
;                  $iMaxPing            - [optional] Maximum number of simultaneous ping to launch (defaut is 5).
;                  $iBackground         - [optional] 0 - Waits until the ping process is conplete before continuing (defaut)
;                                                    1 - Returns immediately and launch the ping process in the background (see remarks)
; Return values .: 1 on success, 0 on error and sets @error to a non-zero value. See remarks.
; Rermarks ......: Use _MultipingGetInfo to determine if the _Multiping process is finish.
;                  Use _MultiPingGetResult to get the result of the previous _Multiping call.
;                  Use _MultiPingCancel to cancel a _Multiping process running in background.
;                  The function requires the use of the #pragma compile(AutoItExecuteAllowed, True) directive.
; ===============================================================================================================================
Func _Multiping($aHosts, $iTimeout = 4000, $iMaxPing = 5, $iBackground = 0)
    If Not IsDeclared("_iMultipingState") Then
        Global $g__aMPHosts, $g__iMPMaxPing, $g__iMPTimeout, $g__iMPState, $g__iMPFinished, $g__aMPRet, $g__iMPCount, $g__iMPCancel, $g__iMPCountOnline
    EndIf

    If $g__iMPState Then Return SetError(2, 0, 0)
    $g__aMPHosts = $aHosts
    $g__iMPMaxPing = $iMaxPing
    $g__iMPTimeout = $iTimeout
    $g__iMPCount = 0
    $g__iMPState = 1
    $g__iMPFinished = 0
    $g__iMPCountOnline = 0

    Local $aRet[UBound($aHosts)][2]
    $g__aMPRet = $aRet

    AdlibRegister("__MultipingAdlib", 100)

    If Not $iBackground Then
        While $g__iMPState
            Sleep(10)
        WEnd
    EndIf
    Return 1
EndFunc ; ==> _Multiping

; #FUNCTION# ====================================================================================================================
; Name ..........: _MultiPingCancel
; Description ...: Cancels a _Multiping porocess running in backgorund.
; Syntax ........: _MultiPingCancel()
; Parameters ....: None
; Return values .: 1 on success, 0 on error.
; ===============================================================================================================================
Func _MultiPingCancel()
    If Not IsDeclared("g__iMPCancel") Then Return 0
    $g__iMPCancel = 1
    Return 1
EndFunc ; ==> _MultiPingCancel

; #FUNCTION# ====================================================================================================================
; Name ..........: _MultipingGetInfo
; Description ...: Returns information for the previous _Multiping call
; Syntax ........: _MultipingGetInfo([$iFlag = 0])
; Parameters ....: $iFlag               - [optional] argument that determines what the return value will be. See Return Value.
; Return values .: The return value depends of the $iFlag value :
;                   $iFlag = 0 (default) : 1 if the _Multiping process is running, or 0 if finish
;                   $iFlag = 1 : a 1D array containing the following informations :
;                       array[0] : 1 if the _Multiping process is running, or 0 if finish
;                       array[1] : number of hosts processed by _Multiping
;                       array[1] : number of online hosts processed by _Multiping
; Remarks .......: _MultipingGetInfo is useful to retrieve the progress of a _Multiping running in background
; ===============================================================================================================================
Func _MultipingGetInfo($iFlag = 0)
    Local $iState = Execute("$g__iMPState")
    If Not $iFlag Then Return $iState

    Local $aRet = [$iState, Execute("$g__iMPFinished"), Execute("$g__iMPCountOnline") ]
    Return $aRet
EndFunc ; ==> _MultipingGetInfo

; #FUNCTION# ====================================================================================================================
; Name ..........: _MultiPingGetResult
; Description ...: Returns the result of the previous _Multiping call
; Syntax ........: _MultiPingGetResult([$iFlag = 0])
; Parameters ....: $iFlag               - [optional] Specifies whether to return pingable, not pinbable or all hosts. Default is 0.
;                                          - 0 : returns all results
;                                          - 1 : returns only pingable hosts
;                                          - 2 : returns only not pingable hosts
; Return values .: ;  On success, a 2D array containing results :
;                       array[0][0] : first hosts
;                       array[0][1] : result for the first host (see remarks)
;                       array[1][0] : second hosts
;                       array[1][1] : result for the second host
;                     On error, 0 and sets @error to a nonzero value.
; Remarks .......: A result can be a one of the following :
;                     - a positive value for the roundtrip-time in milliseconds.
;                     - one of theses negative values if the host is not pingable :
;                         -1 : Hosts is offline
;                         -2 : Host is unreachable
;                         -3 : Bad destination
;                         -4 : Other error
;                     -  0 if the ping process was cancelled before the host was pinged (only when using _MultiPing in background
; ===============================================================================================================================
Func _MultiPingGetResult($iFlag = 0)
    Local $aRes = Execute("$g__aMPRet")
    If Not IsArray($aRes) Then Return SetError(1, 0, 0)

    If $iFlag <> 0 And $iFlag <> 1 And $iFlag <> 2 Then Return SetError(2, 0, 0)

    Local $aRet[UBound($aRes)][2], $n = 0
    For $i = 0 To UBound($aRes) - 1
        If $aRes[$i][1] = "" Or StringInStr($aRes[$i][1], "PING:") Then $aRes[$i][1] = 0

        If $iFlag = 0 Or ($iFlag = 1 And $aRes[$i][1] > 0) Or ($iFlag = 2 And $aRes[$i][1] < 0) Then
            $aRet[$n][0] = $aRes[$i][0]
            $aRet[$n][1] = $aRes[$i][1]
            $n += 1
        EndIf
    Next
    Redim $aRet[$n][2]
    Return $aRet
EndFunc ; ==> _MultiPingGetResult

; #INTERNAL USE ONLY#============================================================================================================
Func __MultipingAdlib()
    Local $iPid, $iRet, $aResult
    Local Const $STILL_ACTIVE = 259

    For $i = 0 To UBound($g__aMPRet) - 1
        $g__aMPRet[$i][0] = $g__aMPHosts[$i]
    Next

    For $i = 0 To UBound($g__aMPRet) - 1
        If $g__aMPRet[$i][1] = "" Then
            If $g__iMPCount < $g__iMPMaxPing Then
                If $g__aMPHosts[$i] = "" Then Return SetError(1, 0, 0)
                $iPid = Run(@AutoItExe & ' /AutoIt3ExecuteLine "Exit Ping(""' & $g__aMPHosts[$i] & '"", ' & $g__iMPTimeout & ') & @error"')
                $g__aMPRet[$i][1] = "PING:" & _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, 0, $iPID)
                $g__iMPCount +=1
            Else
                ExitLoop
            EndIf
        Else
            If StringInStr($g__aMPRet[$i][1], "PING:") Then
                $hProcess = StringReplace($g__aMPRet[$i][1], "PING:", "")
                $iRet = _WinAPI_GetExitCodeProcess($hProcess)
                If $iRet <> $STILL_ACTIVE Then
                    $aResult = StringRegExp($iRet, "(\d*)(\d)$", 1)
                    $g__aMPRet[$i][1] = ($aResult[0] ? $aResult[0] : (-1 * $aResult[1]))
                    $g__iMPFinished += 1
                    If $g__aMPRet[$i][1] > 0 Then $g__iMPCountOnline += 1
                    $g__iMPCount -= 1
                EndIf
            EndIf
            If $g__iMPCancel Then ExitLoop
        EndIf
    Next
    If $g__iMPFinished = UBound($g__aMPHosts) Or $g__iMPCancel Then
        AdlibUnRegister("__MultipingAdlib")
        $g__aMPHosts = 0
        $g__iMPMaxPing = 0
        $g__iMPTimeout = 0
        $g__iMPState = 0
        $g__iMPCancel = 0
    EndIf
EndFunc ; ==> __MultipingAdlib

 

Share this post


Link to post
Share on other sites



On 9/8/2016 at 5:16 AM, jguinch said:

$iPid = Run(@AutoItExe & ' /AutoIt3ExecuteLine "Exit Ping(""' & $g__aMPHosts[$i] & '"", ' & $g__iMPTimeout & ') & @error"')

why not just have a function return the the ping ?. That way the pragma declaration is not needed.
Am I wrong ?

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

  • Similar Content

    • MrBeatnik
      Ping() doesn't send packet?
      By MrBeatnik
      I have a rather strange issue on some machines.
      If I attempt to use the inbuilt PING function, no ICMP packet is sent out.
       
      Ping("internal.fqdn.com") is returning "Host Unreachable"
      If I ping using the command prompt, it's all fine.
       
      Using wireshark I can see that it hasn't even attempted an ICMP request. I can see it has looked up DNS to check for the correct IP address (I can see reply packet returns 10 different IP address as round robin - which is expected), but then it simply doesn't send the request.
       
      Any ideas?
    • MuffinMan
      Logging dropped pings using AutoIT not matching DOS' ping -t
      By MuffinMan
      We seem to be having some connectivity problems with a hosted application vendor.  Doing a "ping -t" to the vendor's host reveals that we are dropping packets here and there.  I was asked if I could write a script that could run and log these dropped packets.

      i put together the code below and initially it was logging a lot of dropped packets - too many really, so I put in Google.com and was still getting a lot of dropped packets.  I figured that maybe I was ping flooding and so I added in a Sleep between pings.  Now if I run my logger with a ping it running at the same time the command prompt is catching more drops than the app. The only requirement is to date/time stamp these dropped pings.  Does anyone have any suggestions on making AutoIT's ping function more like the Windows version?
      If $cmdLine[0] <> 2 Then MsgBox(0, "Error", "Script must have 2 parameters to run - Suspect Address & Known Good Address") Exit EndIf $Site1 = $CmdLine[1] ;--> This should be your suspect addr $Site2 = $CmdLine[2] ;--> This should be your known good addr Logfile("STARTING PING SCAN") While 1 $var = Ping($Site1,600) If @error <> 0 Then $var2 = Ping($Site2,600) If $var2 Then; also possible: If @error = 0 Then ... $errstr = $Site1 & " failed to ping, " & $Site2 & " pinged in " & $var2 & " ms" Else $errstr = $Site1 & " failed to ping, " & $Site2 & " also failed to ping" EndIf Logfile($errstr) EndIf Sleep(1500) ;--> Added sleep function in case I was flooding, but now ping -t catches lots of drops that this app doesn't Wend Func LogFile($msg) $file = FileOpen($Site1 & "_log.txt", 1+8) ; Check if file opened for writing OK If $file = -1 Then MsgBox(0, "Error", "Unable to open file. Script will close") Exit EndIf $time = @MON & "-" & @MDAY & "-" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC FileWrite($file, $time & " - " & $msg & @CRLF) FileClose($file) EndFunc
    • pilky1986
      Internet Connection Tester
      By pilky1986
      Hello,
      I was looking around the net for a simple protable program to test whether you have an internet connection.. in short i couldnt find what i wanted so i wrote one.
      After looking on the forum i found some code snippets from others who had started to this kind of thing, but no completed project.
      Credits:
      Autoit Team / Autoit Program!
      ISN AutoIt Studio - '?do=embed' frameborder='0' data-embedContent>>
      Post: '?do=embed' frameborder='0' data-embedContent>>
      Autoitsnippet: http://www.autoitscript.com/wiki/AutoIt_Snippets#IsInternetConnected
      Function (by Guiness): '?do=embed' frameborder='0' data-embedContent>>
      I have attached the full code and compilied executable.
      All constructive comments / improvement ideas / actual coded example imporovements, welcome.
      Screenshots
      Version 2


      Version 1




      Update:
      09/03/2014 - v1.3 - Added a sleep() to the program loop to prevent high constant cpu usage - credit: wakillon
      09/03/2014 - v1.2 - Added in another test (Microsoft Windows Test #2) using a function written by auto it forum member Guiness
      09/03/2014 - v1.1 - Removed unnecessary includes, moved global variables to the top of the code - Credit: wakillon / water
      Internet Connection Tester v1.3.zip
    • Chimp
      versatile multi ping
      By Chimp
      I needed a function to ping many computers, and get the results of the pings in an array so to manage it easily in a script.
      Searching in the forum I found some interesting sw with a nice graphical interface, but not a generic function that simply return an array.
      a very powerful pinger I found is >nPing by Manadar,  but it is designed as a command line tool, so I decided to use the entire engine  of nPing adapting it a bit, so that it can be used as an udf.
      This code is a first attempt (beta) and it can be used to:
      Ping all computers (IP addresses) belonging to the (local) LAN
      just call the _nPing() without any parameter

      Ping a predefined list of IP
      just pass the list of host (IP or hastnames) to the function in an 1D zero based array or in a 2D array indicating the column containing the addresses

      Ping all computers (IP addresses) of a remote LAN
      just pass an IP of that lan and his subnet mask

      Ping range of computers (IP addresses)
      just pass a string rappresenting the range of IP to ping (as accepted by the nPing program by Manadar),
      for example:
      192.168.0.0-1        will ping these addresses: 192.168.0.0 and 192.168.0.1
      192.168.20.*           will ping everything in the range from 192.168.20.1 to 192.168.20.255
      192.168.0-1.1-254    will ping everything in the range from 192.168.0.1 to 192.168.1.254



      I have not done extensive testing on it, so I would be grateful if someone that tries it, can report any error
      thanks
      EDIT:
      After some testing, I have seen that sometime some IP are reported as dead, while are alive instead.
      This occurs when a device is not so fast to answer to the ping, and so it's marked as dead while instead is only too slow to answer to the ping.
       I  came to the conclusion that for a more accurate result about the not responding devices, is better to use a $timeout parameter of 4000 ms as default value in the _MSPing() function (the same default timeout value as in the standard ping command)
      So I have "calibrated" the multiping.au3 by modifying the line 349 and incrementing the value of the $Timeout variable from 100 ms to 4000 ms.
      This should be a better choice  for a general purpose utilization that gives more stable and accurate results about the not responding devices.
      This should not slow down the overall performances, but will only give some more time  to respond to the slower devices.
      MultiPing.au3
      #include <iNet.au3> ; #INDEX# ======================================================================================================================= ; Title .........: _nPing ; AutoIt Version : ; Language ......: English ; Description ...: Function to perform multi Ping. ; Author(s) .....: core engine is Manadar's "nping" retrieved at the following post ; http://www.autoitscript.com/forum/topic/108060-nping-console-network-pinger-network-sweeper-network-scanner ; adapted to this UDF by PincoPanco ; =============================================================================================================================== ; #CURRENT# ===================================================================================================================== ; _nPing multi IP pinger ; =============================================================================================================================== ; #INTERNAL_USE ================================================================================================================= ; _LanParameters given IP and mask generate [and display] various lan parameters ; _CIDR_To_Mask transform a CIDR number (1 - 32) to the corresponding 4 digit mask ; _Mask_To_CIDR transform a 4 digit mask to the corresponding CIDR number (1 - 32) ; _GetSubnetMask given the local IP returns the related subnet mask (thanks to dragan) ; _Convert_To_Binary from decimal to binary ; _Bin_To_Dec from binary to decimal ; _FileReadToArray_mod read a file of IP in a 1D array, if is a csv and a separator is passed a 2D array is returned ; _GetIpAddressList Generate the IP list to Ping ; _Make_Range Given an IP and his mask, this function return the full LAN "range" for _nPing ; _GetLanParameters calculate all IP/subnet related parameters ; _isIPaddr check if passed IP is a plausible IP ; _isSNmask check if passed mask is a plausible mask ; _Progress shows a progress bar for the current scan ; =============================================================================================================================== ; #FUNCTION# ==================================================================================================================== ; Name...........: _nPing ; Description ...: returns an array containing: clients responding to ping or clients not responding or both. See $ReturnFlag ; Syntax.........: _nPing([[$IP]|[$IPArray]|[$IPrange]],[[$NetMask]|[$column]], [$ReturnFlag], [$Resolve], [$MyFunction]) ; Parameters ....: [[$IP]|[$IPArray]|[$IPrange]] - An IP address or an 1D or 2D array (0 based) or an IPrange(*) ; $NetMask - An 4 digit Net Mask or a CIDR notation value (numbers of bit from 1 to 32) ; if previous parameter is an 2D array then this parameter contains the ; nr. of the column that contains the addresses to be pinged ; $ReturnFlag - 0|1|2, what to return: 0=all cliensts; 1=responding clients; 2= not responding clients(**) ; $Resolve - O or 1, if IP lookup name resolution must be performed; 1 = yes, 0 = no ; $MyFunction - an User Defined Function to be called each time a PING complete (default is progress bar) ; the called function receives 1 parameter that is an array containing the following 6 parameters: ; [0] nr. of total addresses under process ; [1] nr. of ping already finished ; [2] IP just processed ; [3] resolved Host name or -1 if IP is down ; [4] roundtrip of this ping or -1 if IP is down ; [5] Index of this IP within the caller's passed array ; by default is called the _Progress() function that will display the progress bar ; Return values .: Success - an 2D array containing: ; first row ($array[0][x]) contains: [0][0]= nr. of returned host; [0][1]= total roundtrip ; other rows: [n][0]=Address; [n][1]=lookup name; [n][2]=roundtrip; [n][3]=index in the passed array*** ; Failure - -1, sets @error ; |1 - too many IP, max 16777216 ($MAX_HOSTS) ; |2 - wrong array dimensions or wrong column number ; |3 - wrong IP ; |4 - wrong subnet mask ; |5 - bad "range" or wrong IP error ; |6 - Windows Sockets Error ; |7 - (not used) ; |8 - DLL call error (reading local subnet mask) ; ; (*) IPrange is a string as below ; "192.168.0.0-1" will ping these addresses: 192.168.0.0 and 192.168.0.1 ; "192.168.20.*" will ping everything in the range from 192.168.20.1 to 192.168.20.255 ; "192.168.0-1.1-254" will ping everything in the range from 192.168.0.1 to 192.168.1.254 ; ; (**) returnead 2D array has the following 4 columns: ; first row contains: [0][0]= nr. of returned host; [0][1]= total roundtrip ; following rows contains fields as below ; +-------------------------+-------------------------+ ; | nr of elements in array | total roundtrip | ; +-------------------------+-------------------------+-------------------------+-------------------------+ ; | IP address | [hostname] ( -1) | roundtrip (or -1) | index *** | ; +-------------------------+-------------------------+-------------------------+-------------------------+ ; ; (***) since the returned array has not the same nr. of rows and also has not the same order of the array in input, ; this index is a reference to "bind" both arrays. ; It is more useful if the input array is a 2D array and you have to bind the rows containing results ; with related fields (array elements) in the "source" array ; Author ........: ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _nPing($networkRange = "", $MyMask = "", $ReturnFlag = 1, $Resolve = 0, $MyFunction = "_Progress") Static $TCP = TCPStartup() ; this should be used at the beginning of the main program instead of inside the Func() Static $dig = FileExists(".\dig\dig.exe") ; this is for IP to hostname resolution. if dig.exe exists will be used. (faster than _TCPIpToName) Local $MAX_PROCESS = 20 ; A maximum number of processes (25) ; Global $MAX_HOSTS = 16777216 ; A maximum number of hosts to ping due to AutoIt's array limit size Local $_IPup[1][4] ; will contain results of PINGs [IP][roundrip or -1] ; check what has been required from caller If $networkRange = "" Then ; no parameters passed, so scan local network ; ConsoleWrite("debug: no IP/range provided, I will scan the local LAN" & @CRLF) $networkRange = _Make_Range(TCPNameToIP(@ComputerName), _GetSubnetMask(TCPNameToIP(@ComputerName))) ; retrieve local LAN and Subnet Mask values If @error Then Return SetError(@error, @extended, -1) ; ConsoleWrite("debug: network range=" & $networkRange & @CRLF) ElseIf IsArray($networkRange) Then ; ----- is an array -----------------------------+ ; if is an 2D array then $MyMask contains the column else is ignored | If UBound($networkRange) > 16777216 Then Return SetError(1, 0, -1) ; | too many IP > $MAX_HOSTS ; If UBound($networkRange, 0) <> 1 Then Return SetError(2, 0, -1) ; | If UBound($networkRange, 0) > 2 Then Return SetError(2, 0, -1) ; | max 2D array If UBound($networkRange, 0) = 1 Then ; | $aArray = $networkRange ; $aArray = all IP to scan | Else ; ----- it is a 2D array ----- | ; the number of the column with addresses is in $MyMask parameter | If $MyMask > UBound($networkRange, 2) - 1 Then Return SetError(2, 0, -1) ; | wrong column Local $aArray[UBound($networkRange)] ; | For $i = 0 To UBound($networkRange) - 1 ; | $aArray[$i] = $networkRange[$i][$MyMask] ; | Next ; | EndIf ; | ; ------------------------------------------------------------------------------+ ElseIf _isIPaddr($networkRange) Then ; single IP ; ConsoleWrite("debug: single IP value received" & @CRLF) If $MyMask <> "" Then ; is there a subnet? If Not _isSNmask($MyMask) Then ; wrong 4 digit mask If $MyMask > 0 And $MyMask < 33 Then ; is it a CIDR notation number? (nr. of bits of mask (1 to 32)) $MyMask = _CIDR_To_Mask($MyMask) Else Return SetError(4, 0, -1) ; wrong mask provided EndIf EndIf $networkRange = _Make_Range($networkRange, $MyMask) ; generate the "range" of all IP belonging to that subnet mask EndIf EndIf If Not IsArray($networkRange) Then ; ConsoleWrite("debug: Is not an Array" & @CRLF) ; if $networkRange is NOT an array then it is a "range" ; either passed as parameter by caller or generated by above checks $aArray = _GetIpAddressList($networkRange) ; Generate the list of IP to be pinged If @error Then Return SetError(5, 0, -1) ; IP range error EndIf ; ; _ArrayDisplay($aArray,"debug") ; $aArray should contain the IP to be pinged by _nPing ; ; *********************************************************************************************************** ; here start of nping core by Manadar (slightly modified) ; http://www.autoitscript.com/forum/topic/108060-nping-console-network-pinger-network-sweeper-network-scanner ; *********************************************************************************************************** If $ReturnFlag = 0 Then ; make room for all clients ReDim $_IPup[UBound($aArray) + 1][4] ; $_IPup will contain results 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 Local $iUp = 0 ; Total hosts that are UP Local $iDown = 0 ; Total hosts that are DOWN Local $iTotalRoundTrip = 0 ; Total roundtrip (all the +ms added together) 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($i, $aArray[$i]) ; Start a new Ping process $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 ; has finished to ping ; results of endings pings. (Get results from the various Pimg commands) $sHostname = _MSPingGetHostname($aProcess[$n]) $sResult = _MSPingGetResult($aProcess[$n]) $sIndex = ___MSPingGetIndex($aProcess[$n]) ; new, added by me (zero based) ; ConsoleWrite("debug: " & $sIndex & " : " & $sHostname & " : " & $sResult & @CRLF) ; -------------------------------------------------------------------------------------------------------------------------------------------------------------- If ($sResult <> -1) Then ; current IP is UP ; ConsoleWrite("debug: " & $sHostname & " has a roundtrip of " & $sResult & " ms" & @CRLF) $iUp += 1 If $ReturnFlag < 2 Then ; if return all(0) or responding only(1) If $ReturnFlag = 1 Then ; 1 = return back only responding IP ReDim $_IPup[$iUp + 1][4] $_IPup[$iUp][3] = $sIndex ; the index of the passed array that contains this IP $sIndex = $iUp Else ; $ReturnFlag = 0 Then keep all clients $sIndex += 1 $_IPup[$sIndex][3] = $sIndex - 1 EndIf $_IPup[$sIndex][0] = $sHostname If $Resolve Then ; ------------ resolve IP to hostname ------------ If _isIPaddr($_IPup[$sIndex][0]) Then ; is it an IP ? (or an hostname) If $dig Then ; resolve with dig if is present (much faster especially on passive devices without a host name) Local $digID = Run(".\dig\dig.exe -x " & $_IPup[$sIndex][0] & " +short", "", @SW_HIDE, 0x2) Do $_IPup[$sIndex][1] &= StdoutRead($digID) ; resolved IP to name (if resolvable else empty) Until @error Else ; _TCPIpToName is very slow to return if the remote IP do not belongs to a windows client (example a printer or a router) $_IPup[$sIndex][1] = _TCPIpToName($_IPup[$sIndex][0]) EndIf Else $_IPup[$sIndex][1] = $_IPup[$sIndex][0] EndIf EndIf ; End of name resolution ------------------------------------- $_IPup[$sIndex][2] = $sResult ; roundtrip of the ping $iTotalRoundTrip += $sResult EndIf Else ; current IP is down ---------------------------------------------------------------------------------------------------------------------------------------- $iDown += 1 If $ReturnFlag = 0 Then ; 0 return back all IP, responding and not responding $sIndex += 1 $_IPup[$sIndex][0] = $sHostname $_IPup[$sIndex][1] = -1 ; loockup name $_IPup[$sIndex][2] = -1 ; roundtrip $_IPup[$sIndex][3] = $sIndex - 1 ; ElseIf $ReturnFlag = 1 Then ; $ReturnFlag = 1 return only responding ; nothing to store ElseIf $ReturnFlag = 2 Then ; $ReturnFlag = 2 return only not responding ReDim $_IPup[$iDown + 1][4] $_IPup[$iDown][0] = $sHostname $_IPup[$iDown][1] = -1 $_IPup[$iDown][2] = -1 $_IPup[$iDown][3] = $sIndex $sIndex = $iDown EndIf 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 ($sResult <> -1 And $ReturnFlag <> 2) Or ($sResult = -1 And $ReturnFlag <> 1) Then ; call an UDF to track and manage what's going on during the scan; ; an array is passed to the called function with the following 6 parameters: ; 0) nr. of total addresses under process ; 1) nr. of ping already finished ; 2) IP just processed ; 3) resolved Host name or -1 if IP is down ; 4) roundtrip of this ping or -1 if IP is down ; 5) Index of this IP within the caller's passed array ; by default is called the _Progress() function that will display the progress bar Local $aPass_Args[6] = [UBound($aArray), $iFinished, $_IPup[$sIndex][0], $_IPup[$sIndex][1], $_IPup[$sIndex][2], $_IPup[$sIndex][3]] Local $aArgs[2] = ["CallArgArray", $aPass_Args] Call($MyFunction, $aArgs) Else Local $aPass_Args[6] = [UBound($aArray), $iFinished, $sHostname, -1, -1, $sIndex] Local $aArgs[2] = ["CallArgArray", $aPass_Args] Call($MyFunction, $aArgs) EndIf ; If the total number of finished processes If ($iFinished == UBound($aArray)) Then ExitLoop 2 ; Exit -----+ EndIf ; | EndIf ; | Next ; | Sleep(50) ; Give existing ping commands some time to process the request | WEnd ; | ; <-------------------+ ; fill record [0] If $ReturnFlag = 0 Then ; return all $_IPup[0][0] = $iUp + $iDown $_IPup[0][1] = $iUp ; $iTotalRoundTrip ; $_IPup[0][2] = $iDown ElseIf $ReturnFlag = 1 Then ; return only up $_IPup[0][0] = $iUp $_IPup[0][1] = $iTotalRoundTrip ; $_IPup[0][2] = $iDown ElseIf $ReturnFlag = 2 Then ; return only down $_IPup[0][0] = $iDown $_IPup[0][1] = -1 ; $_IPup[0][2] = $iUp EndIf Return $_IPup ; - - - The end of scan - - - EndFunc ;==>_nPing Func _GetIpAddressList($ipFormat) ; Generate the IP list to Ping If $ipFormat = "" Then Return SetError(5, 0, -1) ; no IP to ping EndIf $ipFormat = StringReplace($ipFormat, "*", "1-255") ; change * with "1-255" $ipSplit = StringSplit($ipFormat, ".") If $ipSplit[0] <> 4 Then ; if it is not an IP address then check if it is an hostname Static $TCP = TCPStartup() Local $ret[1] = [TCPNameToIP($ipFormat)] ; from hostname to IP If @error Then Return SetError(6, @error, -1) ; windows API WSAGetError Windows Sockets Error in @extended Return $ret ; -----> return EndIf For $i = 1 To 4 ; controls once again If Not StringRegExp($ipSplit[$i], "[0-9\-]*") Then ; are 4 octets numbers Static $TCP = TCPStartup() Local $ret[1] = [TCPNameToIP($ipFormat)] ; if not number try to decode from host to IP If @error Then Return SetError(6, @error, -1) ; windows API WSAGetError. Windows Sockets Error in @extended Return $ret ; -----> return EndIf Next ; $ipFormat is not an hostname Local $ipRange[4][2], $totalPermu = 1 For $i = 0 To 3 If StringInStr($ipSplit[$i + 1], "-") Then ; control the presence of the "-" sign $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 ; total number of IP to check If ($ipRange[$i][0] < 0 Or $ipRange[$i][0] > 255) Or ($ipRange[$i][1] < 0 Or $ipRange[$i][1] > 255) Then Return SetError(3, 0, -1) ; wrong IP Next If $totalPermu > 16777216 Then ; > $MAX_HOSTS Return SetError(1, String($totalPermu), -1) ; too many IP EndIf 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 ; $result contains the IP addresses to ping $i += 1 Next Next Next Next Return $result EndFunc ;==>_GetIpAddressList Func _Exit() Exit EndFunc ;==>_Exit Func _MSPing($Array_ndx, $sHostname, $timeout = 4000) ;$timeout = 50) ; start a new Ping Local $return_struc[5] ; [0] = Result (in ms) ; [1] = The hostname originally used ; [2] = Process handle (for internal use only) ; [3] = Buffer (for internal use only) ; [4] = Index of IP in source array **new** $return_struc[1] = $sHostname $return_struc[2] = Run("ping " & $sHostname & " -n 1 -w " & $timeout, "", @SW_HIDE, 0x2) ; 0x2 -> $STDOUT_CHILD) $return_struc[4] = $Array_ndx Return $return_struc EndFunc ;==>_MSPing Func _MSPingIsReady(ByRef $return_struc) ; check if Ping has finished Return ___MSPingReadOutput($return_struc) EndFunc ;==>_MSPingIsReady Func _MSPingGetResult($return_struc) Return $return_struc[0]; [0] = Result (in ms) EndFunc ;==>_MSPingGetResult Func _MSPingGetHostname($return_struc) ; returns the hostname Return $return_struc[1]; [1] = The hostname originally used EndFunc ;==>_MSPingGetHostname ; Internal use only Func ___MSPingReadOutput(ByRef $return_struc) ; peek result of DOS Ping command $data = StdoutRead($return_struc[2]) ; [2] = Process handle (for internal use only) If (@error) Then ; if ping has finished ___MSPingParseResult($return_struc) ; extract time taken by ping Return 1 ; 1 = finished Else $return_struc[3] &= $data ; [3] = Buffer (for internal use only) ; contains DOS output Return 0 ; 0 = not yet finished EndIf EndFunc ;==>___MSPingReadOutput ; Internal use only Func ___MSPingParseResult(ByRef $return_struc) ; extract from Ping command the millisecond value $result = StringRegExp($return_struc[3], "([0-9]*)ms", 3); [3] = DOS command output is here If @error Then $return_struc[0] = -1 ; [0] = Result (in ms) -1 if error Else $return_struc[0] = $result[0] ; returns the first millisecond value retrieved from Ping EndIf EndFunc ;==>___MSPingParseResult ; Internal use only - new (added by me) Func ___MSPingGetIndex(ByRef $return_struc) ; Index of the current IP in passed array Return $return_struc[4] EndFunc ;==>___MSPingGetIndex ; = = = = = net related functions = = = = = Func _Make_Range($ipLan, $sMask) ; Given an IP and his mask, this function return the full LAN "range" for _nPing Local $aLan = _GetLanParameters($ipLan, $sMask) If @error Then Return SetError(@error, @extended, -1) Return $aLan[7][0] EndFunc ;==>_Make_Range Func _GetLanParameters($theIP1, $sSubNet) ; ------------------------------------------ ; calculate all IP/subnet related parameters ; ------------------------------------------ If Not _isIPaddr($theIP1) Then Return SetError(3, 0, -1) ; wrong IP address ;check on subnet If Not _isSNmask($sSubNet) Then ; it is not a valid 4 digit subnet If $sSubNet > 0 And $sSubNet < 33 Then ; is it a CIDR notation number? nr. of bits 1 to 32 $sSubNet = _CIDR_To_Mask($sSubNet) Else Return SetError(4, 0, -1) ; wrong Mask provided EndIf EndIf Local $aLan[8][5] ; net parameters container Local $sDot[2] = ['', '.'] ; used as IP octets separator Local $aIP = StringSplit($theIP1, '.'), $aSubNet = StringSplit($sSubNet, '.') ; split IP address in single octets and calculate related parameters For $i = 1 To 4 $aLan[0][$i] = $aIP[$i] ; IP $aLan[1][$i] = $aSubNet[$i] ; NetMask $aLan[2][$i] = BitNOT($aLan[1][$i] - 256) ; Wildcard, is the inverse of subnet: BitNot($NetMask - 256) $aLan[3][$i] = BitAND($aLan[0][$i], $aLan[1][$i]) ; LanAddress BitAnd(IP, netmask) $aLan[4][$i] = BitOR($aLan[0][$i], $aLan[2][$i]) ; Broadcast address $aLan[5][$i] = $aLan[3][$i] ; preset First host ; will be $NetAddress + 1 $aLan[6][$i] = $aLan[4][$i] ; preset Last host ; will be $Broadcast -1 Next If $sSubNet <> "255.255.255.255" Then $aLan[5][4] = BitOR($aLan[5][4], 1) ; First host $NetAddress + 1 (Turn last bit ON) $aLan[6][4] = BitAND($aLan[6][4], 254) ; Last host $Broadcast -1 (Turn last bit OFF) EndIf For $i = 1 To 4 $aLan[0][0] &= $aLan[0][$i] & $sDot[$i < 4] ; [0] IP $aLan[1][0] &= $aLan[1][$i] & $sDot[$i < 4] ; [1] NetMask $aLan[2][0] &= $aLan[2][$i] & $sDot[$i < 4] ; [2] Wildcard $aLan[3][0] &= $aLan[3][$i] & $sDot[$i < 4] ; [3] Network $aLan[4][0] &= $aLan[4][$i] & $sDot[$i < 4] ; [4] Broadcast $aLan[5][0] &= $aLan[5][$i] & $sDot[$i < 4] ; [5] First host $aLan[6][0] &= $aLan[6][$i] & $sDot[$i < 4] ; [6] Last host ; [7][0] Range for _nPing If $aLan[5][$i] = $aLan[6][$i] Then $aLan[7][0] &= $aLan[5][$i] & $sDot[$i < 4] Else $aLan[7][0] &= $aLan[5][$i] & "-" & $aLan[6][$i] & $sDot[$i < 4] EndIf Next ; MsgBox(0, "net", "IP address: " & @TAB & $aLan[0][0] & @CRLF & "Subnet: " & @TAB & $aLan[1][0] & @CRLF & "Wildcard: " & @TAB & $aLan[2][0] & @CRLF & "Network: " & @TAB & $aLan[3][0] & @CRLF & "Broadcast: " & @TAB & $aLan[4][0] & @CRLF & "First host: " & @TAB & $aLan[5][0] & @CRLF & "Last host: " & @TAB & $aLan[6][0]) ; _ArrayDisplay($aLan, "IP/subnet related parameters") Return $aLan EndFunc ;==>_GetLanParameters ; #FUNCTION# ==================================================================================================================== ; Name...........: _LanParameters ; Description ...: given an IP and his subnet returns [and displays] the following values in dec and binary format: ; |IP Address ; |Netmask ; |Wildcard ; |Network Address ; |Broadcast Address ; |First host ; |Last host ; Syntax.........: _LanParameters([$IP, $Subnet]) ; Parameters ....: ; ; Return values .: ; Author ........: ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: ; =============================================================================================================================== Func _LanParameters($theIP1 = "", $sSubNet = "255.255.255.255", $Msg = 0) Static $TCP = TCPStartup() If $theIP1 = "" Then $theIP1 = TCPNameToIP(@ComputerName) $sSubNet = _GetSubnetMask($theIP1) ElseIf $sSubNet = "" Then $sSubNet = "255.255.255.255" EndIf If Not _isSNmask($sSubNet) Then ; it is not a 4 digit subnet If $sSubNet > 0 And $sSubNet < 33 Then ; is it a CIDR notation number? nr. of bits 1 to 32 $sSubNet = _CIDR_To_Mask($sSubNet) Else Return SetError(4, 0, False) ; wrong mask EndIf EndIf Local $aLan = _GetLanParameters($theIP1, $sSubNet) Local $LanID[7][3] $LanID[0][0] = "IP Address " $LanID[1][0] = "Netmask " $LanID[2][0] = "Wildcard " $LanID[3][0] = "Network Address " $LanID[4][0] = "Broadcast Address" $LanID[5][0] = "First host " $LanID[6][0] = "Last host " For $i = 0 To 6 $LanID[$i][1] = $aLan[$i][0] $LanID[$i][2] = _Convert_To_Binary($aLan[$i][1]) & "." & _Convert_To_Binary($aLan[$i][2]) & "." & _Convert_To_Binary($aLan[$i][3]) & "." & _Convert_To_Binary($aLan[$i][4]) Next If $Msg Then MsgBox(0, "Lan IDs", $LanID[0][0] & @TAB & $LanID[0][2] & @TAB & $LanID[0][1] & @CRLF & _ $LanID[1][0] & "( " & _Mask_To_CIDR($LanID[1][1]) & " ) " & @TAB & $LanID[1][2] & @TAB & $LanID[1][1] & @CRLF & _ $LanID[2][0] & @TAB & $LanID[2][2] & @TAB & $LanID[2][1] & @CRLF & _ $LanID[3][0] & @TAB & $LanID[3][2] & @TAB & $LanID[3][1] & @CRLF & _ $LanID[4][0] & @TAB & $LanID[4][2] & @TAB & $LanID[4][1] & @CRLF & _ $LanID[5][0] & @TAB & $LanID[5][2] & @TAB & $LanID[5][1] & @CRLF & _ $LanID[6][0] & @TAB & $LanID[6][2] & @TAB & $LanID[6][1] & @CRLF) Return $LanID EndFunc ;==>_LanParameters ; #FUNCTION# ==================================================================================================================== ; Name...........: _CIDR_To_Mask ; Description ...: transform a CIDR number (1 - 32) to the corresponding 4 digit mask ; Syntax.........: _CIDR_To_Mask($CIDR) ; Parameters ....: $CIDR a number from 1 to 32 ; Return values .: a 4 bite corresponding subnet mask ; =============================================================================================================================== Func _CIDR_To_Mask($sSubNet) ; From nr. of bit to 4 digit mask $sSubNet = StringLeft(StringLeft("11111111111111111111111111111111", $sSubNet) & "0000000000000000000000000000000", 32) $sSubNet = _Bin_To_Dec(StringLeft($sSubNet, 8)) & "." & _Bin_To_Dec(StringMid($sSubNet, 9, 8)) & "." & _Bin_To_Dec(StringMid($sSubNet, 17, 8)) & "." & _Bin_To_Dec(StringRight($sSubNet, 8)) Return $sSubNet EndFunc ;==>_CIDR_To_Mask ; #FUNCTION# ==================================================================================================================== ; Name...........: _Mask_To_CIDR ; Description ...: transform a 4 digit mask to the corresponding CIDR number (1 - 32) ; Syntax.........: _Mask_To_CIDR($SubnetMask) ; Parameters ....: $SubnetMask a 4 bite subnet mask ; Return values .: the corresponding CIDR ; =============================================================================================================================== Func _Mask_To_CIDR($sSubNet) ; from 4 digit mask to nr. of bits If _isSNmask($sSubNet) Then Local $Digit = StringSplit($sSubNet, ".", 2) Return StringInStr(_Convert_To_Binary($Digit[0]) & _Convert_To_Binary($Digit[1]) & _Convert_To_Binary($Digit[2]) & _Convert_To_Binary($Digit[3]), "1", 0, -1) Else Return SetError(4, 0, False) ; wrong mask EndIf EndFunc ;==>_Mask_To_CIDR ; _GetSubnetMask ; #FUNCTION# ==================================================================================================================== ; Name...........: _GetSubnetMask ; Description ...: given the local IP returns the related subnet mask (thanks to dragan) ; http://www.autoitscript.com/forum/topic/155078-how-to-easily-get-the-subnet-mask/?p=1120929 ; Syntax.........: _GetSubnetMask($LocalIP) ; Parameters ....: $LocalIP IP of the local computer ; Return values .: the corresponding subnet mask ; =============================================================================================================================== Func _GetSubnetMask($theIP) ; given the local IP returns the related subnet mask Local Const $tagIP_ADDRESS_STRING = "char IPAddress[16];" Local Const $tagIP_MASK_STRING = "char IPMask[16];" Local Const $tagIP_ADDR_STRING = "ptr Next;" & $tagIP_ADDRESS_STRING & $tagIP_MASK_STRING & "DWORD Context;" Local Const $tagIP_ADAPTER_INFO = "ptr Next; DWORD ComboIndex; char AdapterName[260];char Description[132]; UINT AddressLength; BYTE Address[8]; dword Index; UINT Type;" & _ " UINT DhcpEnabled; ptr CurrentIpAddress; ptr IpAddressListNext; char IpAddressListADDRESS[16]; char IpAddressListMASK[16]; DWORD IpAddressListContext; " & _ "ptr GatewayListNext; char GatewayListADDRESS[16]; char GatewayListMASK[16]; DWORD GatewayListContext; " & _ "ptr DhcpServerNext; char DhcpServerADDRESS[16]; char DhcpServerMASK[16]; DWORD DhcpServerContext; " & _ "int HaveWins; " & _ "ptr PrimaryWinsServerNext; char PrimaryWinsServerADDRESS[16]; char PrimaryWinsServerMASK[16]; DWORD PrimaryWinsServerContext; " & _ "ptr SecondaryWinsServerNext; char SecondaryWinsServerADDRESS[16]; char SecondaryWinsServerMASK[16]; DWORD SecondaryWinsServerContext; " & _ "DWORD LeaseObtained; DWORD LeaseExpires;" Local $dll = DllOpen("Iphlpapi.dll") If @error Then Return SetError(8, @error, 0); <----------- error 'dll open: Iphlpapi.dll' Local $ret = DllCall($dll, "dword", "GetAdaptersInfo", "ptr", 0, "dword*", 0) If @error Then DllClose($dll) Return SetError(8, @error, 0); <----------- error 'dll call function: GetAdaptersInfo' EndIf Local $adapterBuffer = DllStructCreate("byte[" & $ret[2] & "]") Local $adapterBuffer_pointer = DllStructGetPtr($adapterBuffer) DllCall($dll, "dword", "GetAdaptersInfo", "ptr", $adapterBuffer_pointer, "dword*", $ret[2]) If @error Then $adapterBuffer = "" $adapterBuffer_pointer = "" DllClose($dll) Return SetError(8, @error, 0); <----------- error 'dll call function: GetAdaptersInfo with adapter buffer pointer' EndIf Local $adapter = DllStructCreate($tagIP_ADAPTER_INFO, $adapterBuffer_pointer) Local $IPType = -1 Local $FoundIt = False Local $retVal = "" Do ; -------------------- IP search -------------------- $Ptr = DllStructGetPtr($adapter, "IpAddressListNext") Local $IPStruct, $Index = 0 Local $allArray[1][3] Do ReDim $allArray[$Index + 1][3] $IPStruct = DllStructCreate($tagIP_ADDR_STRING, $Ptr) $allArray[$Index][0] = DllStructGetData($IPStruct, "IPAddress") $allArray[$Index][1] = DllStructGetData($IPStruct, "IPMask") $allArray[$Index][2] = DllStructGetData($IPStruct, "Context") $Ptr = DllStructGetData($IPStruct, "Next") $Index += 1 Until $Ptr = 0 For $i = 0 To UBound($allArray) - 1 If $allArray[$i][0] <> $theIP Then ContinueLoop ; >-+ $retVal = $allArray[$i][1] ; | $IPType = 0 ; | $FoundIt = True ; | ExitLoop ; if found do not search over | Next ; <-------+ If $FoundIt Then ExitLoop ; >---------------------------+ $Ptr = DllStructGetData($adapter, "Next") ; | $adapter = DllStructCreate($tagIP_ADAPTER_INFO, $Ptr); | Until @error ; | ; <---------------------------+ $adapterBuffer = "" $adapterBuffer_pointer = "" DllClose($dll) If Not $FoundIt Then Return SetError(3, 0, 0) ; IP not found <----------- error Return SetError(0, $IPType, $retVal) ; OK Return mask EndFunc ;==>_GetSubnetMask Func _isIPaddr($sIPAddr) ; returns true if argument is a plausible IP address If Not StringRegExp($sIPAddr, "^((25[0-5]|2[0-4]\d|[01]?\d?\d)\.){3}(25[0-5]|2[0-4]\d|[01]?\d?\d)$") Then Return SetError(1, 0, False) Return True EndFunc ;==>_isIPaddr Func _isSNmask($sSNmask) ; returns true if argument is a correct 4 digit network mask If Not StringRegExp($sSNmask, "^(((255\.){3}(255|254|252|248|240|224|192|128|0+))|((255\.){2}(255|254|252|248|240|224|192|128|0+)\.0)|((255\.)(255|254|252|248|240|224|192|128|0+)(\.0+){2})|((255|254|252|248|240|224|192|128|0+)(\.0+){3}))$") Then Return SetError(1, 0, False) Return True EndFunc ;==>_isSNmask Func _Progress($aArgs) ; Func _Progress($ToDo, $Done, $Dummy1, $Dummy2, $Dummy3, $Dummy4) ; this will show the progress bar while scanning ; $_Percent = Int($Done / $ToDo * 100) $_Percent = Int($aArgs[1] / $aArgs[0] * 100) Static $_Progress = 0 If Not $_Progress Then ProgressOn("Progress Meter", "Pinged address ", $aArgs[1] & "/" & $aArgs[0] & " ( 0 %)", -1, -1, 16) $_Progress = 1 EndIf ProgressSet($_Percent, $aArgs[1] & "/" & $aArgs[0] & " ( " & $_Percent & " %)", "Pinged address " & $aArgs[2]) If $_Percent = 100 Then ProgressSet(100, "Done", "Complete") Sleep(500) ProgressOff() $_Progress = 0 EndIf EndFunc ;==>_Progress Func _Convert_To_Binary($iNumber) ; from decimal to binary ; http://www.autoitscript.com/forum/topic/90056-decimal-to-binary-number-converter/?p=647505 Local $sBinString = "" While $iNumber $sBinString = BitAND($iNumber, 1) & $sBinString $iNumber = BitShift($iNumber, 1) WEnd ; limit returned value to 8 bit 0 - 255 Return StringRight("00000000" & $sBinString, 8) EndFunc ;==>_Convert_To_Binary Func _Bin_To_Dec($BinNum) ; from binary to decimal Local $dec = 0 For $i = 0 To StringLen($BinNum) - 1 $dec += 2 ^ $i * StringMid($BinNum, StringLen($BinNum) - $i, 1) Next Return $dec EndFunc ;==>_Bin_To_Dec ; #FUNCTION# ==================================================================================================================== ; Name...........: _FileReadToArray_mod ; Description ...: read a file to an array and if is passed a separator and a column number extract only that column (from a csv) ; Syntax.........: _FileReadToArray_mod($sFilePath, $delim = ";") ; Parameters ....: |$sFilePath - path and filename of the file to read ; |$delim - the character separator of the values in the csv ; Remarks .......: if the file is not a csv and contains only one IP per line then $delim is ignored ; Return values .: an 1D array containing the "IP" extracted from the $col column. First column is nr.0 ; =============================================================================================================================== ; Func _FileReadColumnToArray($sFilePath, $delim = ";", $col = 0) Func _FileReadToArray_mod($sFilePath, $delim = ";") ; this function is extracted, adapted and slightly modified from the _FileReadToArray() function in file.au3 Local $aArray Local $hFile = FileOpen($sFilePath, 0); $FO_READ) If $hFile = -1 Then Return SetError(1, 0, 0);; unable to open the file ;; Read the file and remove any trailing white spaces Local $aFile = FileRead($hFile, FileGetSize($sFilePath)) FileClose($hFile) ;~ $aFile = StringStripWS($aFile, 2) ; remove last line separator if any at the end of the file If StringRight($aFile, 1) = @LF Then $aFile = StringTrimRight($aFile, 1) If StringRight($aFile, 1) = @CR Then $aFile = StringTrimRight($aFile, 1) If StringInStr($aFile, @LF) Then $aArray = StringSplit(StringStripCR($aFile), @LF) ElseIf StringInStr($aFile, @CR) Then ;; @LF does not exist so split on the @CR $aArray = StringSplit($aFile, @CR) Else ;; unable to split the file If StringLen($aFile) Then Dim $aArray[2] = [1, $aFile] ; returns the whole file in one element Else Return SetError(2, 0, 0) ; File is empty EndIf EndIf ; now split 1D $aArray to 2D $aColumns according to delimiter Local $aColumns[$aArray[0]][1] ; create a new [2D] array with same nr. of lines of $aArray For $i = 1 To $aArray[0] ; scan all lines of the array $TempRow = StringSplit($aArray[$i], $delim, 2) ; split the line If UBound($TempRow) > UBound($aColumns, 2) Then ReDim $aColumns[$aArray[0]][UBound($TempRow)] For $ii = 0 To UBound($TempRow) - 1 $aColumns[$i - 1][$ii] = $TempRow[$ii] Next Next Return $aColumns EndFunc ;==>_FileReadToArray_mod Func _ExtractColumnFromArray($aArray, $col = 0) If 1 = UBound($aArray, 0) Then If $col = 0 Then Return $aArray ; already a single column array, send it back as is Else Return SetError(2, 0, -1) ; wrong column number EndIf EndIf If $col >= UBound($aArray, 2) Then Return SetError(2, 0, -1) ; wrong column number Local $aColumn[UBound($aArray)] ; create a new [1D] array For $i = 0 To UBound($aArray) - 1 ; scan all lines of the array $aColumn[$i] = $aArray[$i][$col] Next Return $aColumn EndFunc ;==>_ExtractColumnFromArray Basic Example of use:
      #include 'MultiPing.au3' #include <array.au3> MsgBox(0, "Hello", "The _nPing() function will ping ranges of IP addresses" & @CRLF & @CRLF & _         "if called without arguments, it will try to detect your LAN parameters" & @CRLF & _         "and then will ping all your LAN addresses, returninig a list of responding IP." & @CRLF & @CRLF & _         "First  a detection of the LAN is performed and result displayed" & @CRLF & @CRLF & _         "Press OK to detect:") $lan = _LanParameters("", "", 1) ; with the first 2 argument blank, will detect local LAN ;                                     the third parameter 1 means show results MsgBox(0, "Hello", "OK, now the full IP range will be pinged." & @CRLF & "In this example only the addresses of responding devices" & @CRLF & _         "will be returned in the array (default)," & @CRLF & _         "but the function can also return:" & @CRLF & _         " 0 the whole list of IPs" & @CRLF & _         " 1 only responding IPs" & @CRLF & _         " 2 only not responding IPs" & @CRLF & @CRLF & _         "Press OK to ping from IP " & $lan[5][1] & " to IP " & $lan[6][1]) ; simplest way to use: without parameters ; will scan all your local LAN ; and display only responding IP Local $Result = _nPing() If @error Then MsgBox(0, "", "@error " & @error) _ArrayDisplay($Result) MsgBox(0, "", "Another way to use is to read a list of IP from a file (csv or single column)" & @CRLF & _         "into an array and pass the array to the function" & @CRLF & _         "if the array is 1D then is passed as is" & @CRLF & _         "if the array is 2D (because a csv was read) the first column is passed," & @CRLF & _         "but if you want to pass another column of the 2D array then" & @CRLF & _         "just pass the column number (zero based) as second parameter (first column is 0)" & @CRLF & _         "In this example the IP are in column 1" & @CRLF & @CRLF & _         "Press OK to read the file") ; read the file in an array ; use the ";" as fields separator $IPlist = _FileReadToArray_mod(".\IP_List.txt", ";") If Not @error Then     _ArrayDisplay($IPlist, "Data read from file") ; show array content     $Result = _nPing($IPlist, 1); pass the second column to the function     If @error Then MsgBox(0, "", "@error " & @error)     _ArrayDisplay($Result) ; display the result of the pings Else     MsgBox(0, "", "@error " & @error) EndIf IP_List.txt
      Google;173.194.36.50 AutoIT;87.106.181.57 YouTube;74.125.228.65 Google.com;74.125.224.72 Gmail.com;74.125.224.181 Bing.com;131.253.13.32 Hotmail.com;65.55.72.135 Yahoo.com;98.139.183.24 Amazon.com;72.21.211.176 Facebook.com;69.171.234.21 Facebook.com;69.63.176.13 Facebook.com;69.63.181.15 Facebook.com;69.63.184.142 Facebook.com;69.63.187.17 Facebook.com;69.63.187.18 Facebook.com;69.63.187.19 Facebook.com;69.63.181.11 Facebook.com;69.63.181.12 Twitter.com;199.59.148.10 Twitter.com;199.59.149.230 LinkedIn.com;216.52.242.86 WordPress.com;76.74.254.126 WordPress.org;72.233.56.138 Tumblr.com;174.121.194.34 Livejournal.com;209.200.154.225 Reddit.com;64.208.126.67 Imgur.com;173.231.140.219 Pinterest.com;23.21.142.179 Instagram.com;23.23.130.59 Stickam.com;67.201.54.151 Blogtv.com;84.22.170.149 Justin.tv;199.9.249.21 ChatRoulette.com;184.173.141.231 Newegg.com;216.52.208.187 ThePirateBay.org;194.71.107.50 Movie2k.com;109.163.226.240 PayPal.com;173.0.84.3 Botcrawl.com;174.132.77.244