Scripting Airport Toggle

I want to make a button on my iKeys that toggles my wireless connection on and off via AppleScript. Only thread I found dealing with that was this one…

http://macscripter.net/viewtopic.php?pid=35687

…and in my instance it doesn’t quite help. Mostly because I can’t figure out from ifconfig -a if en0 is truly my Airport connection.

I have a desktop Mac Pro with wireless and wired Ethernet. I use the wired Ethernet 99.99% of the time, but in order to bypass certain issues with it, I have to hop on the wireless for brief periods. Due to security concerns, I want to be able to switch the Airport on when I need it, and off when I’m done.

I also want to switch all routing of web traffic to the Airport when it’s on and back to Ethernet when Aiport is off (and this last part befuddles me since how does Firefox and Parallels know which interface to use?).

I current have 7 available interfaces:

Ethernet 1 (always on)
Parallels Shared (always on)
Paralles Host-Only (always on)
Bluetooth (always off)
Ethernet 2 (always off)
Firewire (always off)
AirPort (want to toggle on/off)

I did an ifconfig -a but since the output doesn’t include the English-language name it’s confusing. For starts, en0 is showing as being active when Airport is off, so I’m guessing en0 is not the Airport in my case (per thread link provided above).

So the questions:

–How do I toggle on/off the Airport connection via AppleScript?

–How do I toggle all internet traffic (Firefox, Safari, and if possible Parallels) to the Airport (i.e. “when Airport is active, route all internet traffic through the wireless” and “when Airport is off, route all internet traffic through Ethernet”)

Thanks in advance for the help…:slight_smile:

Got part of my answer…have to switch-off the Ethernet while turning on the wireless…can’t have both on (in my particular case anyway).

So the “toggle” I am requesting literally is “turn on wireless, turn off Ethernet” and “turn off wireless, turn on Ethernet.”

I think I would setup two “Locations” and switch between them with scselect through do shell script (or just do it with a shell script if iKeys can run those directly).

Hopefully that will not interrupt your Parallels virtual networks since they are enabled in both. Though I would not be surprised if there is a momentary glitch whenever you switch.

chrys…

I tried your idea, but turning on the Airport is global to all Locations. Each location happily memorized the state of the Ethernet though.

So Locations apparently is not a solution (though I was really jazzed about the idea…very clever…), or I’m doing something wrong.

Unfortunately, for anyone following this thread, I’m not a command-line guru so I need fairly explicit syntax for any “do script” advice.

I haven’t tested the side-effects it all has on Parallel’s two interfaces yet…focusing mostly on getting the interfaces swapped reliably. I can always script re-launching Parallels, just as I have to script re-mounting servers.

I’m using ControllerMate to allow my iKeys Button Panel (or iKeys Desktop) toggle the swap. It can run stored or external AppleScripts (among other things), but not terminal commands directly. I’m also having issues with it not liking “do script” via AppleScript, but one problem at a time.

I may need to do this “interface swap” regularly, and manually it’s alot of steps. Seems an ideal candidate for scripting. :smiley:

Hmm, on my system (10.4), in the Network preference pane, I pick a location and pick “Network Port Configurations” (from “Show:”) to check and uncheck (enable and disable) individual ports. My AirPort connection is one of them and I can enable or disable independently in each location.

I created two locations: “test Normal” with only the built-in Ethernet enabled, and “test AirPort” with only AirPort enabled. When I switch between them, the corresponding interface is enabled (as shown by ifconfig -a; en0 is the built-in Ethernet and en1 is the AirPort on my system). I do not have anything connected to my Ethernet port, but I am pretty sure that it would work normally if I had an Ethernet connection there.

The AirPort is definitely enabled and disabled when I switch locations (via the Network pref pane, via the Location submenu of the  (Apple) menu, or via scselect). I can see that AirPort is disabled based on the AirPort menu extra (the signal ˜wedge’ is empied, clicking on it give a grayed out menu item “AirPort: Not configured”) and in Internet Connect application (the AirPort toolbar entry disappears).

It works for me.?

set locationName to "test AirPort"
--set locationName to "test Normal"
do shell script "scselect " & quoted form of locationName

Each location also has a UUID (ex: my “test AirPort” is 9A8775A7-10DF-40B5-8034-10340D42D79F; yours will be different, they are Univerally Unique IDentifiers) that you can use in place of the descriptive name in the locationName variable above. Run scselect without arguments to get a list of the configured locations.

In the past, I have used UI scripted Internet Connect to switch the AirPort power on and off (the dictionary based AppleEvent interface to Internet Connect seems useless on my system), but that would not help you with disabling your Ethernet connection. The last time I needed to script AirPort power, I used XNetwork OSAX, but it also only handles the AirPort interface.

10.5.8 (Leopard) here.

Network pane has a left column list of “services” and the right side shows the attributes of the service highlighted. Under AirPort there is “Status” (on or off) and a button next to it “Turn AirPort On” (or “Off”). Clicking that button changes it’s state for all Locations near as I can tell (Locations is a pop-down listing at the top of the Network pane that defaults to “Automatic” and has “Edit Locations” to save/name setups.

In other words, even despite saving Locations where the Ethernet definitely can be turned on or off, if I activate AirPort in one location, it activates in all of them. Quite annoying.

I do recall the Leopard pane is different than the Tiger pane in some way, but I don’t have a Tiger system to verify.

So perhaps a two-part solution?

Would it be possible to separately switch the Ethernet on and off via Locations, and the AirPort on and off via some other means like the OSAX you mentioned?

I took a quick peak at XNetwork but the impression is that it’s not compatible with Intel-based Macs past 10.4.x, could be wrong.

P.S. Appreciate all your help!

Hmm, that’s unfortunate. In Tiger, there are actually two levels of “enabled”, the checkbox along with the other interfaces and the actual power setting (settable via the menu extra, or through Internet Connection). It sounds like maybe they merged these two types of enabling into a single On/Off.

It might not be compatible, but if it is, you could just leave AirPort enabled in the Network pref pane and use the OSAX to toggle the power (start airport and stop airport).

Another approach might be to leave both Ethernet 1 and AirPort enabled in the pref pane and use ipconfig to switch between them at a lower level. Note that none of the changes made via ipconfig will be persistent. Any operations done at a higher level (pref pane changes, switching locations, etc.) will reset the changes done by ipconfig.

You will have to know the device names for your Ethernet 1 and AirPort interfaces (I would guess en0 and en2, respectively). It should be possible to determine these experimentally by enabling/disabling them in the pref pane and checking which one changes in ifconfig -a output (look for the presence or absence of UP in the flags section).

property ethernet_ifname : "en0"
property airport_ifname : "en1"

useOnlyAirPort()
--useOnlyEthernet()

to useOnlyEthernet()
	enableDHCPInterface(ethernet_ifname)
	disableInterface(airport_ifname)
end useOnlyEthernet
to useOnlyAirPort()
	enableDHCPInterface(airport_ifname)
	disableInterface(ethernet_ifname)
end useOnlyAirPort

to enableDHCPInterface(ifname)
	do shell script "ipconfig set " & quoted form of ifname & " DHCP" with administrator privileges
end enableDHCPInterface
to disableInterface(ifname)
	do shell script "ipconfig set " & quoted form of ifname & " NONE && ifconfig " & quoted form of ifname & " down" with administrator privileges
end disableInterface

Edit history: Fixed typo. Added ifconfig down to script.

I found this script online to toggle the Airport, but I can’t figure out if it will work and seem to be missing two components used by the original author:

Internet Connect.app
GrowlHelperApp.app

Anyone know about the above apps? I looked around, but got a bit lost in the Growl discussions and it seemed like both are Tiger-centric.

Wish this was easier than it’s turning out to be…

--Turn Apple Airport card on/off

--USER SETTINGS:
--Display a dialog asking what to do
property display_dialog : false --Yes (True) or No (False)
--Always turn Internet Connect off or default
property always_off : false --Yes (True) or No (false)
--Set the amount of time before dialogs auto-answer
property dialog_timeout : 60 --Seconds

--SCRIPT SETTINGS, DO NOT CHANGE
property ic_on : false

try
	--Dialog set up
	if display_dialog is true then
		set alert_message to ("Airport:" & return & return)
		set alert_message to alert_message & ("Would you like to turn the Airport card on or off?")
		display dialog alert_message buttons {"Cancel", "On", "Off"} default button 2 with icon 1 giving up after dialog_timeout
		copy the result as list to {buttonpressed}
	end if
	
	--Check if Internet Connect is running
	tell application "System Events"
		set process_list to name of every process
		if process_list does not contain "Internet Connect" then
			try
				tell application "Internet Connect.app" to activate
			end try
			set ic_on to true
		end if
	end tell
	
	tell application "System Events"
		tell process "Internet Connect"
			if not (exists window 1) then
				keystroke "n" using command down
			end if
			
			if not (exists window "Airport") then
				click button "airport" of tool bar 1 of window 1
			end if
			
			--If display_dialog is set to false
			if display_dialog is false then
				--Turn Airport On
				if exists button "Turn Airport On" of window "Airport" then
					click button "Turn Airport On" of window "Airport"
					set airport to "on"
				else if exists button "Turn Airport Off" of window "Airport" then
					click button "Turn Airport Off" of window "Airport"
					set airport to "off"
				end if
			end if
			
			--If display_dialog is set to true
			if display_dialog is true then
				--Turn Airport On, if buttonpressed is "On"
				if buttonpressed is "On" then
					if exists button "Turn Airport On" of window "Airport" then
						click button "Turn Airport On" of window "Airport"
						set airport to "on"
					end if
				else if buttonpressed is "Off" then
				else if exists button "Turn Airport Off" of window "Airport" then
					click button "Turn Airport Off" of window "Airport"
					set airport to "off"
				end if
			end if
		end tell
	end tell
	
	--Tell Internet Connect to Quit
	if always_off is true then
		tell application "Internet Connect.app" to quit
	else if ic_on is true then
		tell application "Internet Connect.app" to quit
	end if
	
	
	set appName to "Airport"
	--Growl Notify
	if exists application "GrowlHelperApp.app" then
		tell application "GrowlHelperApp.app"
			set the allNotificationsList to ¬
				{"Airport On", "Airport Off"}
			set the enabledNotificationsList to ¬
				{"Airport On", "Airport Off"}
			«event register» given «class appl»:¬
				appName, «class anot»:allNotificationsList ¬
				, «class dnot»:enabledNotificationsList ¬
				, «class iapp»:"AirPort Admin Utility"
			
			if airport is "off" then
				--	Send a Notification...
				«event notifygr» given «class name»:¬
					"Airport Off", «class titl»:¬
					appName, «class desc»:¬
					"Airpot Turned Off", «class appl»:appName
			else if airport is "on" then
				--	Send a Notification...
				«event notifygr» given «class name»:¬
					"Airport On", «class titl»:¬
					appName, «class desc»:¬
					"Airport Turned On", «class appl»:appName
			end if
		end tell
	end if
end try

Hi,

in 10.5 or higher this toggles Airport, it requires an admin password


set isOn to (last word of (do shell script "networksetup getairportpower") is "On") as integer
do shell script "networksetup setairportpower " & item (isOn + 1) of {"On", "Off"} password "¢¢¢¢¢¢¢" with administrator privileges

StefanK…

Not sure whether to LOL or just bow my head…worked like a charm.

Now to figure out how to not just toggle, but intregate it with turing Ethernet on/off opposite the Airport, which I hope I can figure out from chrys’ posts.

Closer!

EDIT: One question though…the Network pane does not register the change in the AirPort status, but the menu bar icon does. Is there a reason for this behavior?

Well, StefanK’s toggle works, but unfortunately I still have to manually join the network (it doesn’t auto-rejoin the same network).

I think the AirPort is on en4, near as I can tell from ifconfig. Shows “UP” whether up or down, but that entry changes when I toggle AirPort on or off.

Also, near as I can tell, en1 is the Ethernet–despite it showing an “UP” flag whether it’s on or not (it’s the only entry that changes in ifconfig when I toggle it).

So my next puzzle is probably: how do I script joining a specific network with the Airport?

You can also control the Ethernet port with networksetup

sudo networksetup -setnetworkserviceenabled 'Built-In Ethernet' on

In a non-English system Built-In Ethernet could have a localized name. You can list the services with

sudo networksetup -listallnetworkservices

The displayed status in System Preferences doesn’t matter after calling networksetup.
After relaunching System Preferences the status should be correct