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

How to perform an action on change of network System
I have a PowerBook that I move between various networks. Some of these networks have different proxy settings -- see this hint for how that can be handled.

I also had the problem that I wanted NTP to be working, and some of these networks were filtering the ntp packets. It is possible to set /etc/ntp.conf, just like a standard unix ntp daemon. Unfortunately, ntpd will decide that a bunch of the time servers are unreachable, and will stop trying. When you wake your Mac on another network, ntp will lose contact with its last servers, decide it can't do anything, and shut itself down. So I wanted to kick ntpd when I connected to a new network.

The first step was to add iburst commands to the ntp setup, and to decide that SystemStarter restart "Network Time", when run as root, would restart ntpd. I then needed a way to get ntp to be kicked when my network config changed. I found the solution to that in this blog posting: Apple's System Configuration framework keeps track of network connections and when they change. This can be accessed through the scutil command.

Initially I found scutil difficult to use. The man page is horrible, but if you run scuti and then type help at its prompt, then you get a better list of commands.

In particular, you can try this:
  1. Run scutil
  2. Type list for a list of things you can watch
  3. Type get State:/Network/Global/IPv4 and then d.show to see the current IPv4 state
  4. Type n.add State:/Network/Global/IPv4 and then n.watch to set a watch on the IPv4 state
  5. Now unplug and re-plug your network cable and watch it tell you all about it
So, how do I make my script run when this changes? It turns out that there is a daemon already there that watches these events and does stuff as needed. It's called kicker, and you can see it's config file here: /System » Library » SystemConfiguration » Kicker.bundle » Contents » Resources » Kicker.xml. Note that it already has a script that it runs on network change: /System » Library » SystemConfiguration » Kicker.bundle » Contents » Resources » enable-network. Note that this script has changed names with different versions of Mac OS X.

Interestingly, there is already something there to start NetworkTime:
/System/Library/StartupItems/NetworkTime/NetworkTime start
The problem is that it tries to start network time and not restart network time. So if the ntp daemon is already running, it won't be touched. Changing the command to restart ntpd solved my problem:
/System/Library/StartupItems/NetworkTime/NetworkTime restart
This works in both cases, because restart will also start a daemon if it's not presently running. But the general method of running a script on network change looked useful for others, so I thought I'd post in the information.
    •    
  • Currently 3.25 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (4 votes cast)
 
[25,352 views]  

How to perform an action on change of network | 7 comments | Create New Account
Click here to return to the 'How to perform an action on change of network' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
How to perform an action on change of network
Authored by: sapporo on May 18, '07 08:53:07AM

I'd rather not touch anything in /System .

There's a nice Cocoa class called IXSCNotificationManager, which makes it trivial to get notified about stuff like location changes. Someone should probably write a utility based on that and make it available via Fink or DarwinPorts.



[ Reply to This | # ]
Or an Applescript that launches on login or runs in the background
Authored by: designr on May 18, '07 10:05:24AM
property last_ip : ""
set my_IP to (do shell script "/sbin/ifconfig en0 | head -3 | grep 'inet ' | cut -d' ' -f 2") as string
if my_IP ≠ last_ip then
	set last_ip to my_IP
	if my_IP contains "192.168.0." then
		beep
		delay 2
		beep
	end if
else
	beep
end if


[ Reply to This | # ]
Make a launchd agent instead
Authored by: Krioni on May 20, '07 08:21:38PM
Use Lingon to make a launchd agent that watches the system.log file. Have a shell script that sees if the change includes the phrase "posting notification com.apple.system.config.network_change"

If it does, the shell script can do whatever else you want, including run osascript to do some AppleScript commands.

Here's an example system.log watcher shell script:


#!/bin/sh

SEARCHSTRING="posting notification com.apple.system.config.network_change"
RECENTCHANGE=`tail -2 /var/log/system.log|grep "$SEARCHSTRING"`

LOGHEADER=`date +"%Y-%m-%d %H:%M:%S"`
HOSTNAME_SCRIPT=`hostname -s`
PROCESSNAME="NetworkChange"

if [ -z "$RECENTCHANGE" ] ; then 
# do nothing
else
   echo "$LOGHEADER $HOSTNAME_SCRIPT $PROCESSNAME: Network Changed">> /dev/console

fi

exit 0
On the line after the "echo...Network Changed" line, include the commands you want. The easiest way to do that if you know AppleScript is to make a script file and just call it like this:

osascript /PATH/TO/YOUR/SCRIPT.scpt 
Post here if you need more help getting that to work.

---
http://www.danshockley.com

[ Reply to This | # ]

How to perform an action on change of network
Authored by: DylanMuir on May 20, '07 10:50:55PM

This is an awesome and informative hint. It's great when someone documents how to do useful things properly, without resorting to hacks and workarounds!



[ Reply to This | # ]
How to perform an action on change of network
Authored by: deviantintegral on May 21, '07 12:37:42PM
Or just use LocationChanger to fire off scripts as needed.

http://www.ghoselab.cmrr.umn.edu/software.html

[ Reply to This | # ]
I'm not embarrased...
Authored by: Lliwynd on May 21, '07 10:42:32PM
at all.

It turns out there is a bug in my hint :). At the bottom of the standard enable-network script there is an exit 1. That causes the enable-network script to only be called once (I had commented out that line in testing and didn't try it with it back in). Hence things still will not restart.

I ended up opening up the Kicker.xml file I referred to, and duplicating the section for "enable-network" to make a new section, "restart-network". It calls a new "restart-network" script that is similar to the enable-network script. The changes are the lack of the "exit 1" at the end, and I only have it restart ntp, and not touch the other stuff.



[ Reply to This | # ]
How to perform an action on change of network
Authored by: encro on May 22, '07 08:31:41AM
This might be a good place to reference ncutil as perhaps part of a solution for setting parameter of the System Configuration framework:

ncutil
http://deaddog.duch.udel.edu/ncutil/

---
Steve

[ Reply to This | # ]