Pinging your subnet

One way to discover which of several machines on a subnet is actually on line (if you can’t see them all) is to do a broadcast ping to the entire subnet (everything inside your router with the same three first numbers in its IP Address). This is how I do it:


set tid to AppleScript's text item delimiters
set myIP to getInternalIP()
if myIP is " unknown " then
	display dialog "You do not seem to be connected"
	return
end if
set AppleScript's text item delimiters to "."
set subNet to text items 1 thru 3 of myIP as text
set MM to text item -1 of myIP as text
set AppleScript's text item delimiters to tid
set P to (do shell script "ping -c3 " & subNet & ".255")
set AppleScript's text item delimiters to return & "64 bytes from " & subNet & "."
set Nup to text items 2 thru -1 of P
set IPisUp to {}
set AppleScript's text item delimiters to ":"
repeat with aLine in Nup
	tell (text item 1 of contents of aLine) to if it is not MM and it is not in IPisUp then set end of IPisUp to it
end repeat
set AppleScript's text item delimiters to tid
set tellMe to "The following IP's (excluding this machine, " & myIP & ") are now answering broadcast pings on your subnet." & return & return
repeat with anIP in IPisUp
	set tellMe to tellMe & subNet & "." & contents of anIP & return
end repeat
display dialog tellMe with icon 1

(*Note: SP2 for WinXP automatically disables answering broadcast pings unless the instruction "set multicastbroadcastresponse ENABLE" is entered in each by an administrator of the machine.*)

to getInternalIP()
	set the_interface to 0
	repeat
		set ip_internal to ""
		try
			set ip_internal to do shell script ("ipconfig getifaddr en" & the_interface)
		end try
		if ip_internal is not "" then exit repeat
		set the_interface to the_interface + 1
		if the_interface = 5 then
			set ip_internal to " unknown "
			exit repeat
		end if
	end repeat
	return ip_internal
end getInternalIP


hi adam,

i like your script. i’ve added a repeat block that makes it take more time, but i think the result is very useful. when we find a good ip address, we look it up with ‘arp’ and get the name of the machine. if the machine does not have a ‘name’ in the arp table, we still list the ip. i’ve added a lookup of the MAC address of the machine (for potential Wake On Lan) but don’t actually use it. here is the code:


property theArp : "#!/bin/sh
/usr/sbin/arp"

set tid to AppleScript's text item delimiters
set myIp to getInternalIP()
if myIp is " unknown " then
	display dialog "You do not seem to be connected"
	return
end if
set AppleScript's text item delimiters to "."
set subNet to text items 1 thru 3 of myIp as text
set MM to text item -1 of myIp as text
set AppleScript's text item delimiters to tid
set P to (do shell script "ping -c3 " & subNet & ".255")
set AppleScript's text item delimiters to return & "64 bytes from " & subNet & "."
set Nup to text items 2 thru -1 of P
set IPisUp to {}
set AppleScript's text item delimiters to ":"
repeat with aLine in Nup
	tell (text item 1 of contents of aLine) to if it is not MM and it is not in IPisUp then set end of IPisUp to it
end repeat
set AppleScript's text item delimiters to tid
set tellMe to "The following IP's (excluding this machine, " & myIp & ") are now answering broadcast pings on your subnet." & return & return
repeat with anIP in IPisUp
	set preTellMe to {}
	set preTellMe to subNet & "." & contents of anIP
	do shell script "sh -c " & quoted form of (theArp & space & preTellMe)
	set res to the result as string
	set resArp to {}
	repeat with w from 1 to number of words in res
		set text item delimiters to space
		try
			set this_item to text item w of res
			-- log this_item
		end try
		set end of resArp to this_item
		if this_item = "at" then
			set prev_word to (w - 2)
			set myHost to text item prev_word in res as text
			--log myHost
			set next_word to (w + 1)
			set theMac to text item next_word in res as text --if you wanted MAC addresses, say for Wake On Lan
			if myHost = "?" then
				set tellMe to tellMe & preTellMe & return
			else
				set tellMe to tellMe & preTellMe & space & myHost & return
			end if
		end if
		set AppleScript's text item delimiters to tid
	end repeat
end repeat
display dialog tellMe --with icon 1

(*Note: SP2 for WinXP automatically disables answering broadcast pings unless the instruction "set multicastbroadcastresponse ENABLE" is entered in each by an administrator of the machine.*)

to getInternalIP()
	set the_interface to 0
	repeat
		set ip_internal to ""
		try
			set ip_internal to do shell script ("ipconfig getifaddr en" & the_interface)
		end try
		if ip_internal is not "" then exit repeat
		set the_interface to the_interface + 1
		if the_interface = 5 then
			set ip_internal to " unknown "
			exit repeat
		end if
	end repeat
	return ip_internal
end getInternalIP

it might also be a good idea to reorganize the ip addresses numerically (i think they are currently in the order of response time) but i haven’t got time for that now.

cheers.