Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!


Click here to return to the 'Change location automatically based on network' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Change location automatically based on network
Authored by: BobHarris on Aug 16, '05 10:44:01PM
Here is my SleepWatcher based automatic network location switching script.

Bob Harris


#!/bin/sh
#-----------------------------------------------------------
# MacAutoNetDetective.sh - Script to automatically set my
#                          Mac OS X Network Location after
#                          waking up from sleep.
#
#   If you are going to try and use this script then you
#   will need to customize it, so see the 
#   "CUSTOMIZE THIS SECTION" below.  You should read the
#   following comments.
#
#   This script is intended to be run by SleepWatcher
#   whenever my iBook wakes up from sleep.
#     http://www.versiontracker.com/dyn/moreinfo/macosx/17579
#     http://www.bernhard-baehr.de/
#   SleepWatcher looks for the executable script
#   $HOME/.wakeup where you should put a call to a modified
#   copy of MacAutoNetDetective.sh:
#
#       #--------------------------------------------
#       # .wakeup - SleepWatcher wakeup action script
#       #--------------------------------------------
#       # Bob Harris
#       #--------------------------------------------
#         sh $HOME/bin/MacAutoNetDetective.sh
#       #--------------------------------------------
#
#   .wakeup and MacAutoNetDetective.sh need to be made
#   executable:
#
#       chmod +x $HOME/.wakeup
#       chmod +x $HOME/bin/MacAutoNetDetective.sh
#
#       NOTE:  I had to modify the SleepWatcher 2.0.1
#              /etc/rc.wakeup script to add >/dev/null to
#              grep command:
#
#                if grep -q $shell /etc/shells >/dev/null; then
#
#              to get it to stop saying:
#
#                ...
#                if grep -q $shell /etc/shells; then
#                grep: writing output: Bad file descriptor
#                ...
#
#   I use this script because at work I need a Network
#   Location that includes proxy information configured on
#   the ethernet port, at home I use WiFi with fixed IP
#   addresses to router 10.0.1.1, and at Mom's the WiFi uses
#   a different SSID/password with the router at
#   192.168.1.1.  There is no limit to the number of Network
#   Locations this script could support as long as you can
#   find enough unique network information to determine
#   where you are waking up.
#
#   This is a very customized script, but the basic idea
#   should be usable by anyone that can figure out some
#   unique network identification while connected using
#   DHCP, and then switch to the desired Network Location.
#
#   /usr/sbin/scselect
#      Will display all the available Network Locations.
#      Mine looks something like this:
#
#      % /usr/sbin/scselect
#      Defined sets include: (* == current set)
#       96078368-4301-11D8-B301-000A95DAE736	(Automatic)
#     * 0	(at Home DSL)
#       628CF6AE-2102-11D8-ADDA-000A95DAE736	(Mom's)
#       86E16997-6E3A-11D9-B31F-000A95DAE736	(at Work)
#
#   /usr/sbin/scselect "desired location"
#      Will set a new Network Location.
#
#   /usr/sbin/netstat -nr | awk '/^default/{print $2}'
#      Will tell you your current default router IP address
#
#   /usr/sbin/arp -a
#      Seems to give the local router as well as other
#      recent IP to ethernet MAC translations.  It also
#      includes names, which can be very useful.  For
#      example Home says: AirportExtreme, Mom's says:
#      dslrouter, and work stays:
#      usa-swi-1-rtr-1.xyzcompany.net.  This could be very
#      useful in determining which network I'm attached to.
#
#   /usr/sbin/system_profiler SPAirPortDataType |\
#         awk -F": " '/Current Wireless Network/{print $2}'
#      Can find your Airport SSID.
#                          
#   /usr/bin/grep nameserver /etc/resolv.conf
#      Will tell you your current DNS servers
#
#   /sbin/ifconfig -a
#      Will tell you your current IP address
#
#   /usr/sbin/traceroute -m 5 whatisyourip.com
#      Might show you the names of some of your ISP's
#      routers, however, if any of the routers along the way
#      block tracerouter probes, you will get nothing, and
#      depending on the value of -m, suffer through a long
#      timeout.  -w 2 -q 2 can cut down on this a little.
#
# logger information can be viewed in /var/log/system.log,
#        or via Applications -> Utilities -> Console -> Logs
#        -> system.log
#                          
#-----------------------------------------------------------
# Bob Harris
#-----------------------------------------------------------
logger "${0##*/}: Start -----------------------------------"

#
# We start by setting the network to the "Automatic"
# Location, assuming this is the original default MacOSX
# setup.  It should allow us to automatically detect a
# network via Airport or ethernet, and get an IP address via
# DHCP.  That should be enough to probe for information that
# tells us were we are.
#
/usr/sbin/scselect "Automatic"
logger "${0##*/}: scselect: Automatic: status=$?"
sleep 5

#
# Get my current default router IP address.  If there is no
# default router assigned yet, wait until one appears.
#
tries=0
delay=5
announce=1
def_router=""
while [[ -z "$def_router" ]]
do
    def_router=$(/usr/sbin/netstat -nr | awk '/^default/{print $2}')
    tries=$(( $tries + 1 ))
    if [[ -z "$def_router" ]]; then
        if [[ $tries -gt $announce ]]; then
            logger "${0##*/}: netstat: no default router: tries=$tries"
            announce=$(( ( $announce + 1 ) + ( $announce / 2 ) ))
        fi
        sleep $delay
        tries=$(( $tries + 1 ))
    fi
done
logger "${0##*/}: netstat: $def_router"

#
# Get my current arp information.
#
my_arp=$(/usr/sbin/arp -a)
logger "${0##*/}: arp: $my_arp"

#==========================
# CUSTOMIZE THIS SECTION
#==========================
#
# Based on my router and arp information, choose one of my
# Network Locations.
#
# See above suggestions for other ways to find out where you
# might be, especially if your default router is not unique
# in all locations you might be roaming (for example
# 10.0.1.1 and 192.168.1.1 are very common home Cable/DSL
# router IP addresses.
#
atHOME=0
atWORK=0
atMOMS=0
MINIMUM=5
[[ "$def_router" = 10.0.1.1        ]] && atHOME=$(( $atHOME + 1 ))
[[ "$my_arp" = *AirportExtreme*    ]] && atHOME=$(( $atHOME + 1 ))
[[ "$my_arp" = *11:22:33:44:55:66* ]] && atHOME=$(( $atHOME + 10 ))

[[ "$def_router" = 10.37.151.1     ]] && atWORK=$(( $atWORK + 10 ))
[[ "$my_arp" = *mycompany.com*     ]] && atWORK=$(( $atWORK + 10 ))

[[ "$def_router" = 192.168.1.1     ]] && atMOMS=$(( $atMOMS + 1 ))
[[ "$my_arp" = *dslrouter*         ]] && atMOMS=$(( $atMOMS + 1 ))
[[ "$my_arp" = *aa:bb:cc:dd:ee:ff* ]] && atMOMS=$(( $atMOMS + 10 ))

SCORE=$MINIMUM && Location=""
[[ $SCORE -lt $atHOME  ]] && SCORE=$atHOME && Location="at Home DSL"
[[ $SCORE -lt $atWORK  ]] && SCORE=$atWORK && Location="at Work"
[[ $SCORE -lt $atMOMS  ]] && SCORE=$atMOMS && Location="Mom's"

logger "${0##*/}: Location='$Location'"

#==========================
# END CUSTOMIZATION
#==========================

#
# If we have figured out which Location we are at, then use
# scselect to set our new Network Location, otherwise, leave
# the system set to Automatic under the assumption that we
# are in a strange new place.
#
if [[ ! -z "$Location" ]]; then
    /usr/sbin/scselect "$Location"
    sts=$?
    logger "${0##*/}: scselect: $Location: status=$sts"
else
    #
    # can not figure out which location this is, so 
    # leave it set to "Automatic".
    #
    logger "${0##*/}: Could not resolve the location"
fi

logger "${0##*/}: End -------------------------------------"
exit


[ Reply to This | # ]