Sign in to follow this  
Followers 0
Confuzzled

Ping takes way too long

4 posts in this topic

I'm trying to find all devices on the local LAN segment. I figure if I ping all 256 addresses on the local segment, then this should be a fair indicator of devices that are currently active on it.

I loop through all addresses and ping them. Traditionally they should respond with a microsecond or two, and ping times should be brief.

I'm finding that each ping is taking about a third of a second, making a 256 pass loop take a few minutes.

Sample (working) code extracted from a larger program I have written is attached. I've taken to putting up a Splashbox to show progress so users don't think that the process has stopped or frozen. Even with feedback removed, it is still taking way too long.

;GetIP.inc
; get IP addresses

;Note: should compare the public IP address with the others extracted and check for following:
; 1 - Are they the same - if not then are behind a router of some kind
; 2 - Private IP range: 10.0.0.0-10.255.255.255 or 172.16.0.0 - 172.31.255.255 or 192.168.0.0 - 192.168.255.255
; 3 - Automatic Private addressing 169.254.0.0 169.254.255.255
; If any of the above are valid, further information should be given regarding configuration of firewalls and routers

;Ping rest of LAN segment if local address found to search for other devices present - should identify any shared Internet connections

Dim $IP_Add ;Temporary IP Address
Dim $IP_Add_Masked[3] ; Variable to split IP address into octets
$bd_Behind_Router = "NO" ; Set to known value
$bd_Out = $bd_Out & "Internet "

; get public IP address from site [url="http://www.dslreports.com/whois"]http://www.dslreports.com/whois[/url]
$bd_Current_IP_Address_Full = GetIP()
$bd_Current_IP_Address_Masked = CheckIPAddress($bd_Current_IP_Address_Full)
;Get the IP addresses of the first four network adapters on the system
If @IPAddress1 = $bd_Current_IP_Address_Full Then
 $bd_Current_IP_Adapter_1 = $bd_Current_IP_Address_Full
Else
 $bd_Current_IP_Adapter_1 = CheckIPAddress(@IPAddress1)
 $bd_Behind_Router = "YES"
EndIf
$bd_Current_IP_Adapter_2 = CheckIPAddress(@IPAddress2)
$bd_Current_IP_Adapter_3 = CheckIPAddress(@IPAddress3)
$bd_Current_IP_Adapter_4 = CheckIPAddress(@IPAddress4)

If $bd_Diag_Mode = 1 Then
 MsgBox(0, "IP Addresses", "Your public IP Address is: " & @TAB & $bd_Current_IP_Address_Full & @CRLF & _
 "Masked (Privacy): " & @TAB & @TAB & $bd_Current_IP_Address_Masked & @CRLF & @CRLF & _
 "Network adapter 1 address: " & @TAB & $bd_Current_IP_Adapter_1 & ", " & @CRLF & _
 "Network adapter 2 address: " & @TAB & $bd_Current_IP_Adapter_2 & ", " & @CRLF & _
 "Network adapter 3 address: " & @TAB & $bd_Current_IP_Adapter_3 & ", " & @CRLF & _
 "Network adapter 4 address: " & @TAB & $bd_Current_IP_Adapter_4 & ", " & @CRLF & @CRLF & _
 "Behind NAT Firewall/Router? "  & @TAB & $bd_Behind_Router)
EndIf

If $bd_Behind_Router = "YES" Then
 $bd_Out = $bd_Out & " You are behind a NAT firewall and/or router." & @CRLF
EndIf

$bd_Out = $bd_Out & @CRLF
ClipPut ($bd_Out)

Func CheckIPAddress($IP_Add)
Select
 Case $IP_Add = "NOT CONNECTED"
  Return $IP_Add
    Case $IP_Add = "0.0.0.0"
        Return $IP_Add
    Case StringLeft($IP_Add, 3) = "10."
  $bd_Out = $bd_Out & "Local IP Address " & $IP_Add & " "
        $bd_Behind_Router = "YES"
  PingCheck($IP_Add) ;Check by pinging all addresses in local range to see if other devices on LAN are reachable
  Return $IP_Add
 Case StringLeft($IP_Add, 8) = "192.168."
  $bd_Out = $bd_Out & "Local IP Address " & $IP_Add & " "
  $bd_Behind_Router = "YES"
  PingCheck($IP_Add) ;Check by pinging all addresses in local range to see if other devices on LAN are reachable
  Return $IP_Add
 Case StringLeft($IP_Add, 8) = "169.254."
  $bd_Out = $bd_Out & "Automatic Local IP Address " & $IP_Add & " "
  $bd_Behind_Router = "YES"
  PingCheck($IP_Add) ;Check by pinging all addresses in local range to see if other devices on LAN are reachable
  Return $IP_Add
 Case (StringLeft($IP_Add, 4) = "172.") AND (Number(StringMid ($IP_Add, 5,3)) > 15) AND (Number(StringMid ($IP_Add, 5,3)) < 32)
  $bd_Out = $bd_Out & "Local IP Address " & $IP_Add & " "
  $bd_Behind_Router = "YES"
  PingCheck($IP_Add) ;Check by pinging all addresses in local range to see if other devices on LAN are reachable
  Return $IP_Add
 Case Else
        ; This is where we mask off the last two octets
  ; Concatenate the first and second only and mask the third and fourth octet
  $IP_Add_Masked = StringSplit($IP_Add,".")
  ; Check that StringSplit actually found an IP octet
  If $IP_Add_Masked[0] > 2 Then
   $IP_Add = $IP_Add_Masked[1] & "." & $IP_Add_Masked[2] & ".xxx.xxx"
  EndIf
  $bd_Out = $bd_Out & "IP Address " & $IP_Add & " "
  Return $IP_Add
 EndSelect
EndFunc ; <<= CheckIPAddress

Func GetIP()
 ; GetIP
 ; get public IP address from site [url="http://www.dslreports.com/whois"]http://www.dslreports.com/whois[/url]
 Local $ip
 If InetGet("[url="http://www.dslreports.com/whois"]http://www.dslreports.com/whois[/url]", @TempDir & "\~ip.tmp",1,0) Then
  $ip = FileRead(@TempDir & "\~ip.tmp")
  FileDelete(@TempDir & "\~ip.tmp")
  $ip = StringTrimLeft($ip, StringInStr($ip, "The IP that just fetched this page is<br>") + 40)
  $ip = StringLeft($ip, StringInStr($ip, "<br>") - 1)      
  Return $ip
 Else
  SetError(1)
  $ip = "NOT CONNECTED"
  Return $ip
 EndIf
EndFunc ; <<= GetIP

Func PingCheck($IP_Add)
 ;Ping all addresses in local network segment (count = 256)
 Local $Count ; Iteration counter
 Local $IP_Address ; IP Address being pinged
 Local $IP_Address_Masked[3] ; Variable to split IP address into octets
 Local $IP_Address_3  ;First three octets of $IP_Address_Masked
 Local $IP_Range ; Range to be tested
 $IP_Address_Masked = StringSplit($IP_Add,".") ; Split it up into four octets
 $IP_Address_3 = $IP_Address_Masked[1] & "." & $IP_Address_Masked[2] & "." & $IP_Address_Masked[3] & "." ; Build first three octets
 $IP_Range = "Range " & $IP_Address_3 & "0 - " & $IP_Address_3 & "255"
 ConsoleWrite("IP Address segment being pinged is " & $IP_Add & @CRLF)
 SplashTextOn("   Checking local network connections", @LF & "Checking IP address" & @LF & $IP_Add,300,100)
 
 For $Count = 0 to 255 Step 1 ;Do for all 256 addresses in fourth octet
  $IP_Address = $IP_Address_3 & $Count ; Build IP address to ping
  If Ping($IP_Address, 5) > 0 Then ; only report successful pings
   If $IP_Address <> $IP_Add Then ; skip for actual IP address - only do for all others in segment
    $bd_Out = $bd_Out & " Another device found at " & $IP_Address
   EndIf
  EndIf
 ControlSetText("   Checking local network connections", "", "Static1", @LF & "Looking for IP address " & $IP_Address & @LF & @LF & $IP_Range)
 TrayTip("Checking local connections","        IP address: " & $IP_Address , 10, 17)
 Next
TrayTip ("", "", 0,0) ; Turn off traytip
SplashOff() ; Turn off splash text
EndFunc ; <<= PingCheck

Is there some alternate way of doing this that somebody can recommend?

Share this post


Link to post
Share on other sites



Before you ping, why not ask your name server if it's heard of the IP in question? Like so:

#include <Constants.au3> ; required for StderrRead

; include this little function I wrote...
Func NsKnowsIp($ip)
    $foo = Run("nslookup "&$ip, @SystemDir, @SW_HIDE, $STDERR_CHILD)
    $output = ""
    While 1
        $output &= StderrRead($foo)
        If @error Then ExitLoop
    Wend
    if stringinstr($output,"can't find " & $ip) Then
        return false
    Else
        return True
    EndIf
endfunc


; example usage

if NsKnowsIp("127.0.0.1") then
    msgbox(0,"","127.0.0.1 is known")
Else
    msgbox(0,"","127.0.0.1 is unknown")
EndIf

if NsKnowsIp("127.0.0.2") then
    msgbox(0,"","127.0.0.2 is known")
Else
    msgbox(0,"","127.0.0.2 is unknown")
EndIf

[font="Fixedsys"][list][*]All of my AutoIt Example Scripts[*]http://saneasylum.com[/list][/font]

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I did this a while ago on a local netsend messenger for my home network :P

This is the function to check the machine status.

Func CheckMachineStatus($sMachine)
    Local $pPing = Run("ping -w 50 -n 1 -l 8 " & $sMachine, "", @SW_HIDE, $STDOUT_CHILD)
    Local $pPingTimer = TimerInit()
    Local $pFinalRead = ""
    While ProcessExists($pPing) And TimerDiff($pPingTimer) < 2000
        If Mod(Floor(TimerDiff($pPingTimer)), 50) = 0 Then
            Switch GUICtrlRead($Status)
                Case "|"
                    GUICtrlSetData($Status, "/")
                Case "\"
                    GUICtrlSetData($Status, "|")
                Case "--"
                    GUICtrlSetData($Status, "\")
                Case "/"
                    GUICtrlSetData($Status, "--")
            EndSwitch
        EndIf
        $pPingRead = StdoutRead($pPing, -1, True)
        If $pPingRead <> "" Then
            $pFinalRead &= $pPingRead
        EndIf
    WEnd
    TimerStop($pPingTimer)
    If StringLen($pFinalRead) > 200 Then $pFinalRead = StringRight($pFinalRead, 200)
    If IsArray(StringRegExp($pFinalRead, "(\d+)%", 1)) Then
        Return 1
    Else
        Return 0
    EndIf
EndFunc

OBS: the -n 1 in the ping line means "just ping it once", when the default is 4, that's why it takes too

long. This one is faster.

Edited by CoePSX

[quote name='Valik' post='301213' date='Jan 31 2007, 10:36 PM']You seem to have a habit of putting things in the wrong place. I feel sorry for any female you attempt to have sex with.[/quote][font="Lucida Sans Unicode"][/font]

Share this post


Link to post
Share on other sites

Thanks for the input from both of you. I'll investigate the DOS commands further.

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  
Followers 0