checking for internet access


I switch on my machine and the first page which I visit teach me something.
This sunday starts very well.

Yvan KOENIG (VALLAURIS, France) dimanche 4 novembre 2012 08:51:45

That is true, and that suffices for me, if the car is running, and I can reach the destination (By the handler StefanK posted and Kai Edwards originally made), if say the interface is running and I then don’t get a hit on a second site. Say I then tried both google and yahoo (finding it very unlikely that they both be down for maintainance or being hacked at the same time), then I know for sure the problem must be looked into).

But that problem is rather something I’d deal with manually, as it can be so much, it can be my routing tables, it can be dns, it can be isp, it can just be that net is more or less flooded at the moment (though unlikely).

Traceroute is best used interactively, but I really start by using the network assistant, that I find that little app to be nice and reliable. But if it was scriptable, we’d be in heaven, where you just could perform the tests by AppleScript, as it is such a little conscious app, checking your problems thoroughly.


tell application "Network Assitant" to check "network-connection" with private router at "xxxx.xxxx.xxxx.xxxx" using "en0"


tell application "Network Assitant" to check "dns-speed" using "en1"

This is not a challenge for you StefanK, as they won’t pay you, if you make it, I think. IMHO you didn’t write an extension, when you wrote the Bonjour Printer listener, but a missing part!


This is really a tricky business, to place the error as I said above.

But, if any of my interfaces are up and running, and I can get at Nasa’s time server or some other known non-http service in Europe, then I think I have a connection. If the ping at that server fails, then something is probably wrong at my end, and it is time to fire up Network Assistant or something (traceroute/ping).

The next step is to check the dns, if dns is working. If it isn’t the error is also probably at my end.

(Both the two previous steps may point at some problem inside the domain between me and my isp-really).

If there was success so far, and if the host I am trying to connect to doesn’t give a result, but Google and Yahoo does, then I’ll say the host is down. If my connection is up, (interface/connect to ntp, by ip and dns), but I can’t get at those sites, then I’ll say it is a general Network problem at the moment.

set a to internetAvailable()
on internetAvailable()
	-- Assumes at least one interface to be checked for active status before running.
	local inetStatus
	set inetStatus to false
		set inetStatus to (do shell script "ping -t 1 -c 1 >/dev/null && echo \"true\" || echo \"false\"")
	end try
	-- Nasa's time server, that should give a low lookup time to everyone.
	-- One should really choose a know non-http service physically close.
	return inetStatus
end internetAvailable

This handler checks that dns is working, the site should really be picked somewhere closer to you.

set a to dnsworks()

on dnsworks()
– Assumes at least one interface to be up
– and that the server was reachable by ip-address
local dnsStatus
set dnsStatus to false
set dnsStatus to (do shell script “ping -t 1 -c 1 >/dev/null && echo "true" || echo "false"”) as boolean
end try
return dnsStatus
end dnsworks

A similar handler could be made with ping to check if your gateway is up. this is the first ip-address outside your domain, whether your domain consists of your machine, or your router. (Then you'd use the ip-address of your gateway.)

It looks like one of kai’s, with its knotted one-line syntax and clever use of ‘or’ to get it to try again if the result’s ‘false’ the first time. :slight_smile:

I’ve added some alternative “sed” scripts to my own post above (#15) and a muse about the status possibly being something other than “active” or “inactive”.

If anybody knows about a better way to get the ip-address of the isp’s current gateway, then I’d be happy.

But I suspect it not to be easy, and not totally useful. But if you can get it, then you have it! :slight_smile:

The Router address in Network preferences is a good start, but if you have a router, then you are kind of in the dark.

So if you do a traceroute, and exclude the addresses in your domain, then the first one would be your gateway.

I can’t check how this works with airport at the moment, but I guess it should return the correct ip-address, as the access point, should really give the ip-address of the “gateway”

# set mgwarddr to gatewayAddr with havingRouter
set mgwarddr to gatewayAddr without havingRouter
on gatewayAddr given havingRouter:havingRouter
” This will of course break if you have a switch inside, maybe another router and so on, just adjust the hopcount, and add a parameter for the situation.

	local gwAddr, hops
	if havingRouter then
		set hops to 2
		set hops to 1
	end if
	set gwAddr to null
		set gwAddr to (do shell script "traceroute -q 1 -w 1 -m " & hops & " 2>/dev/null |sed -n '" & hops & " {;s/^[^(]*[(]\\([^)]*\\)[)].*$/\\1/p ;}'")
	end try
	return gwAddr
end gatewayAddr

Communication with my router is via a Web browser (URL = “http://” & the router address), so I can parse the connection status from the router’s main Web page in Safari. In theory ” if I knew how to pass the password ” I could “curl” the router directly for the information.

So is mine really, but only when I’m home. Can’t do that elsewhere. And my usage pattern in all of this is due to the fact, that I pull out the cable the second I am done with being online. I may let people have a go at my box when I am watching anything flash, but at least I throw them out at my own leisure! :slight_smile: ( A NAT only helps for whats outside the NAT. )

I think this should work:

 curl --user name:password

I found it on this nice page.


And if that doesn’t work out, then maybe you are having a https connection to your router, then, I believe you can go in and have a look at the connection inspector in Safari, provided the debug menu of Safari is enabled, to see what certificate are being used.

Then there should be another option for curl to establish an ssl connection.

For my E4200 linksys router at home, it uses http basic authentication:

do shell script "curl --user admin:****** [url=http://x.x.x.x/Status_Router.asp]http://x.x.x.x/Status_Router.asp"[/url]

Hi, let me star by saying thank you all for making this topic so interesting and so complete!. I have a second question witch is related and I am sure you guy will love to comment about it. How can I check the internet speed ? can this be done via Applescript or shell Script ?

Then you for your time!


Hello. I am not sure how I’d script the clicking of the start button on this page.

You’d also have to check that the page has loaded before you can script that click.

do shell script "open [url=]"[/url]

Thank you!!! I will start making test! :slight_smile:

(do shell script "ifconfig | sed -En '/^en0:/,/status/ { /^[^s]+status: / { /inactive/ { c\\'$'\\n''false'$'\\n'' ; q ; } ; c\\'$'\\n''true'$'\\n'' ; } ; }'") as boolean

I am do understand that the ‘$’ here are either signalling the start or end of line, but I am just guessing their significance, and purpose. (I am sure it breaks without them, and I hope it was easy to figure out. :D)

But I don’t have the exact information. I wonder if this is some weird way of signalling the end of line, or something that is necessary to signal a line break.


I am equally interested in the rationale (and everything) behind the ‘’ (literal null string) behind the \n.
I think both are ways to signal end of line though.

I really can’t guess what the dollar does, as you wouldn’t signal end of line bufffer before the newline or?
The literal null string is better, I think it is easy to see that it signals the end of a line after the newline. :smiley:

Where do you take it from? :slight_smile:

The ‘$‘s here are for the shell, not for “sed”. “sed” needs literal linefeeds in those positions, not escaped "n"s. The sequence ‘$’\n’’ interrupts the quoted command text being sent to “sed”, gets the shell to interpret $‘\n’ and insert the result, then resumes the quoted text. You could do exactly the same thing with an AppleScript concatenation instead: " & linefeed & ". Or of course you could simply rely on your script editor inserting a linefeed when you hit the ‘Return’ key.

(do shell script "ifconfig | sed -En '/^en0:/,/status/ { /^[^s]+status: / { /inactive/ { c\\" & linefeed & "false" & linefeed & " ; q ; } ; c\\" & linefeed & "true" & linefeed & " ; } ; }'") as boolean

-- Or:
(do shell script "ifconfig | sed -En '/^en0:/,/status/ { /^[^s]+status: / { /inactive/ { c\\
; q ; } ; c\\
; } ; }'") as boolean


I got it, if I do echo $\\n
in the terminal then I get a newline. I didn’t know that!

Thanks for your explanation, I got lost in the hyphens! :smiley:

By the way, DJ Bazzie Wazzie made me realize that we can actually format do shell scripts like this: (this particular example with the indentation of the change lines* works because the whitespace is ignored later on I think.
*The lines that are arguments to the change c command.

(do shell script "
    ifconfig | sed -En '
        /^en0:/,/status/ {
             /^[^s]+status: / { 
                 /inactive/ { 
") as boolean

Just for the hell of it! :slight_smile:

I have wanted to use here documents within do shell scripts for a long time now, it turns out it is easy to achieve:

The point with here documents is that you feed the script between the sentinels as standard input to a tool, and that you can indeed pass variables, or the result of a function within that “input stream”.

set i to "McUsr"
set mresult to (do shell script "
	me=" & i & "
	cat <<%
	I am $me

The reason for this here, is of course to make sed scripts more reusable, in that you can change the search patterns and such with variables, you can of course also substitute them directly within the do shell script command. :slight_smile:

set because to "because it is interesting!"
set theRest to (do shell script "(
	# commenting works, but not in the middle of streams \\
	cat <<<" & "'Another concept 
I have wondered about!'" & " \\
   |nl \\
   |sed -n 's/^[[:space:]]\\{1,\\}//p' 
   # I can even comment inline some places but not in the middle of a stream \\
   echo " & because & " \\
   # line after line with comments \\ 
   echo )

Yes, it worked for me, because I had set linefeeds as the line terminator in Script Debugger. Sorry about that.