Turn off Airport when Ethernet is plugged in on OSX

Thursday, January 10, 2013 08:12 PM

I like to move from my desk, to a conference room, and/or just other more comfortable places (ex. couches, arm chairs, floor) when I'm working. The problem with that is when I'm done for the day I leave my laptop at my desk and connect it to wired ethernet. Where this all falls apart is when I go home and need to use the VPN. If my laptop is connected to the network, and in this scenario both wired and wireless networks are enabled the VPN fails to work.

I don't want to have to remember everyday before I leave that I need to disable the Airport on my laptop. When this happens in most things computer related, I usually turn to automating said repetitive task.

Luckily in OSX (when writing this blog post I'm running Mountain Lion) there's this great daemon called launchd (which was introduced in Tiger) that does many things one of them is it can be used to trigger an event when watching a path on the filesystem (in this case we want to watch /Library/Preferences/SystemConfiguration), which is precisely what we need in this circumstance.

First let's create a file called com.heatxsink.jackedin.plist under the directory /Library/LaunchDaemons.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>
        <string>com.heatxsink.jackedin</string>
        <key>ProgramArguments</key>
        <array>
        <string>/Library/Scripts/heatxsink/jackedin.sh</string>
        </array>
        <key>StandardOutPath</key>
        <string>/var/log/jackedin.log</string>
        <key>StandardErrorPath</key>
        <string>/var/log/jackedin.log</string>
        <key>Debug</key>
        <true/>
        <key>WatchPaths</key>
        <array>
        <string>/Library/Preferences/SystemConfiguration</string>
        </array>
    </dict>
</plist>

Next, we're going to create another file called jackedin.sh under the directory /Library/Scripts/heatxsink, unfortunately the directory /Library/Scripts/heatxsink doesn't exist so type the following to create the directory...

$ sudo mkdir -p /Library/Scripts/heatxsink

The contents of the jackedin.sh needs to be the following ...

#!/bin/sh
ETHERNET_INTERFACE="en0"
AIRPORT_INTERFACE="en1"
DETECT_INET=`ifconfig $ETHERNET_INTERFACE | grep inet6 | tr -d '\t' | cut -d ' ' -f 1 | tr -d '\n'`

if [ "$DETECT_INET" = "inet6" ] ; then
        /usr/sbin/networksetup -setairportpower $AIRPORT_INTERFACE off
        echo "Wired ethernet detected, turning off Airport."
        exit 0
else
        /usr/sbin/networksetup -setairportpower $AIRPORT_INTERFACE on
        echo "No wired ethernet, turning on Airport."
        exit 1
fi

After saving this file you'll need to make sure the permissions have been set correctly, to do that type the following ...

$ sudo chmod 755 /Library/Scripts/heatxsink/jackedin.sh

Now that we have our com.heatxsink.jackedin.plist and jackedin.sh files properly added to the filesystem we will just need to load the com.heatxsink.jackedin.plist into launchd. You can do that by typing the following ...

$ sudo launchctl load /Library/LaunchDaemons/com.heatxsink.jackedin.plist

Wrapping it up

Unfortunately this is tied very closely to a workflow that requires using one network interface at a time (either wired or wireless). For example when I took my laptop home and I was wired in I kept flipping out why I couldn't swap over to wireless! In this case you should just "unload" com.heatxsink.jackedin.plist from launchd by doing the following ...

$ sudo launchctl unload /Library/LaunchDaemons/com.heatxsink.jackedin.plist

Happy Hacking!