Confuzzled Posted August 17, 2006 Posted August 17, 2006 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.expandcollapse popup;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 ; <<= PingCheckIs there some alternate way of doing this that somebody can recommend?
lod3n Posted August 17, 2006 Posted August 17, 2006 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]
CoePSX Posted August 17, 2006 Posted August 17, 2006 (edited) I did this a while ago on a local netsend messenger for my home network 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 August 17, 2006 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]
Confuzzled Posted August 18, 2006 Author Posted August 18, 2006 Thanks for the input from both of you. I'll investigate the DOS commands further.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now