view · edit · print · history

Mac OS X Network Location Scripts

Note: This hack is known to work with Mac OS X Panther (10.3.8 and 10.3.9) and Tiger (10.4.1 and 10.4.2)

Introduction

Mac OS X allows you to setup multiple network locations each with their own configuration. You can configure and select your network locations from the Apple -> Location menu or Network panel in System Preferences. It is possible to have your own scripts run when you change network locations. This solution will run scripts within subdirectories of /etc/networklocations. Each subdirectory name will match the name of a network location (Ex: Switching to a network location named Home-wifi would run the scripts within /etc/networklocations/Home-wifi.).

System Configuration framework

The System Configuration framework brings dynamic network configurations to Mac OS X and allows applications to interact with network services. The framework has four main components:

  • Persistant store
  • Dynamic store
  • Schema
  • Configuration agents

The persistant store contains all network configuration preferences for interfaces, services, and other network location information. The dynamic store is the current network configuration. The schema provides a hierarchical layout for the persistant and dynamic stores. The configd daemon manages configuration agents which are responsible for configuring various network components.

configd

The configd service regularly looks for changes in the network configuration by monitoring /Library/Preferences/SystemConfiguration/preferences.plist. A configuration agent called the Kernel Event Monitor can also trigger configd to inspect the preferences.plist file. This file is modified whenever the network configuration changes. When a modification is detected, configd will note the changes and call upon various configuration agents to modify network interfaces, routing tables, and many other networking elements. These configuration agents are located in /System/Library/SystemConfiguration/.

Kicker.bundle

Kicker.bundle is the configuration agent where most of the magic of this solution happens. Kicker.bundle stores dictionaries in an XML file, called Kicker.xml, which can be found in the Contents/Resources/ subdirectory of Kicker.bundle.

Kicker.xml

Inside the Kicker.xml file, you will see lines like:

 
        <dict>
                <key>execCommand</key>
                <string>$BUNDLE/Contents/Resources/enable-network</string>
                <key>execUID</key>
                <integer>0</integer>
                <key>keys</key>
                <array>
                        <string>State:/Network/Global/DNS</string>
                        <string>State:/Network/Global/IPv4</string>
                        <string>State:/Network/Global/NetInfo</string>
                </array>
                <key>name</key>
                <string>network_change</string>
                <key>postName</key>
                <string>com.apple.system.config.network_change</string>
        </dict>
 

Everything between the <dict> and </dict> lines is a dictionary. There are keys with string, integer, and array values. The execCommand key's value is basically the location of the program to run. $BUNDLE is replaced with the location of Kicker.bundle. You can run programs as specific users by putting their UID in <integer> </integer> value tags for the execUID key. Next, you have an array for keys which tell Kicker.bundle what network configuration changes should kick your program.

Network location script dictionary

This dictionary will run the networklocation.sh shell script from within Kicker.bundle's Content/Resrouces/ directory. You can download the current version of this dictionary.

 
        <dict>
                <key>name</key>
                <string>location-change</string>
                <key>execCommand</key>
                <string>$BUNDLE/Contents/Resources/networklocation.sh</string>
                <key>execUID</key>
                <integer>0</integer>
                <key>keys</key>
                <array>
                        <string>State:/Network/Global/IPv4</string>
                </array>
                <key>changedKeysAsArguments</key>
                <true/>
        </dict>
 

IP Monitor configuration agent publishes the State:/Network/Global/IPv4 key whenever the primary network service changes. After you modify Kicker.xml, you will have to restart configd or reboot the computer for the changes to take effect.

networklocation.sh

First, you will need to create the directory /etc/networklocations. A subdirectory must be created for each network location name you would want to run scripts. networklocation.sh is the script that Kicker.xml will run when a network location changes. You can download the most current version of networklocation.sh. You must place this script in the location provided by your dictionary.

References

Nixes changes · ALL changes
Page last modified on August 04, 2005, at 06:47 PM