Tweaking NICs before dhclient does

pccardd & 802.11b PCMCIA cards

I had been using FreeBSD on laptops for a while, but I used an old one from work (strictly) at home, and used a newer one (strictly) at work. (Well, except when I took a laptop to the USENIX conference in San Diego.)

Basically, I thus avoided the issue of coping with environmental changes, such as switching between ``BSS'' and ``ad-hoc'' modes, or changing SSIDs, or selecting different WEP keys... and to the extent that it was still necessary, it was infrequent enough that I could just hack /etc/pccard.conf directly to put ``ancontrol'' commands directly in the ``an'' stanza (for example).

Well, now that I have my very own laptop, I'm actually taking it with me, with the expectation that it will be able to be useful in different environments. And this experience provided the requisite catalyst for me to finally try to do something constructive about it.

One of my colleagues had mentioned putting together a script that would try different settings for the Cisco/Aironet card until it found one that worked. This seemed like a fairly promising direction, though I got the impression that his script was rather dependent on the particular capabilities of the Cisco/Aironet cards, and would need to be tweaked to cope with the Lucent/WaveLan/Orinoco cards (for example). Another colleague put together a script that would ask him to select a location, and it would go off and ``do the right thing'' for that location. I found this approach rather more problematical, since I fire up xdm from /usr/local/etc/rc.d, and although it would have been possible to call such a script from withing the xdm initialization script, that wouldn't necessarily handle an environment change without a re-boot.

So I put together a script to be invoked from within the appropriate stanza(s) in /etc/pccard.conf. Its sole required argument is the one that identifies with interface is being used, and that is known at the time that the stanza is being parsed, so that should be easy. Here's a sample:

########## an ########## # Aironet 340/342 Series 11Mbps 802.11 wireless NIC card "Cisco Systems" "340 Series Wireless LAN Adapter" config auto "an" ? insert /usr/local/sbin/pccard_hook -i $device insert /etc/pccard_ether $device start remove /etc/pccard_ether $device stop
(The line in boldface is the one I added. The rest of the stanza is copied directly from /etc/defaults/pccard.conf.)

So, as I was writing this page, the thought occurred to me that the above approach -- copying stanzas from /etc/defaults/pccard.conf to /etc/pccard.conf, with the addition of the above bold-faced line -- is really ugly.

So I started looking at other ways to accomplish this. I see that in /etc/pccard_ether, there is provision to source /etc/start_if.${interface} if it exists. That would be OK, except that I'd need to create one of these for each possible device. And each of them would look like all the others (which leads to the question ``why can't we just invoke a single one?'').

Given that, I tried hacking /etc/pccard_ether directly:

--- /usr/src/etc/pccard_ether Sat Feb 3 20:41:34 2001 +++ /etc/pccard_ether Thu Mar 15 11:48:08 2001 @@ -58,6 +58,9 @@ case ${startstop} in [Ss][Tt][Aa][Rr][Tt] | '') + if [ -x /usr/local/sbin/pccard_hook ]; then + /usr/local/sbin/pccard_hook -i ${interface} + fi if [ -r /etc/start_if.${interface} ]; then . /etc/start_if.${interface} fi

I'm not real happy with that, either... but it does seem to work, with a minimum of hassle.

Postscript: Adapting a suggestion from Doug Ambrisko, I ditched the above, and created:


dhcp-135[1] ls /etc/st*_if.*
/etc/start_if.an0       /etc/start_if.wi1       /etc/stop_if.ed1
/etc/start_if.an1       /etc/stop_if.an0        /etc/stop_if.wi0
/etc/start_if.wi0       /etc/stop_if.an1        /etc/stop_if.wi1

They contain:


dhcp-135[2] more !$
/usr/local/sbin/pccard_hook -i an0
...skipping...
/usr/local/sbin/pccard_hook -i an1
...skipping...
/usr/local/sbin/pccard_hook -i wi0
...skipping...
/usr/local/sbin/pccard_hook -i wi1
...skipping...
hostname localhost
[ -f /var/run/ntpd.pid ] && kill `cat /var/run/ntpd.pid`
/bin/rm -f /etc/ntp.conf /var/run/ntpd.pid
...skipping...
hostname localhost
[ -f /var/run/ntpd.pid ] && kill `cat /var/run/ntpd.pid`
/bin/rm -f /etc/ntp.conf /var/run/ntpd.pid
...skipping...
hostname localhost
[ -f /var/run/ntpd.pid ] && kill `cat /var/run/ntpd.pid`
/bin/rm -f /etc/ntp.conf /var/run/ntpd.pid
...skipping...
hostname localhost
[ -f /var/run/ntpd.pid ] && kill `cat /var/run/ntpd.pid`
/bin/rm -f /etc/ntp.conf /var/run/ntpd.pid
...skipping...
hostname localhost
[ -f /var/run/ntpd.pid ] && kill `cat /var/run/ntpd.pid`
/bin/rm -f /etc/ntp.conf /var/run/ntpd.pid
which is arguably rather clumsy, at best. But it does work, without hacking existing system files.

Anyway, here's a directory where copies of the files involved (except for the /etc/st*_if.* files; you see those above) may be found; alternatively, here's a gzipped tarball of the set.


Firewalls for mobile devices

Once the BayLISA meetings started being held at Apple's Cupertino campus, where Apple provides wireless Net access and a DHCP server providing routable (17/8) addresses, I had some incentive to take advantage of the Net access while taking some steps to protect my laptop.

The approach I took was to implement ipfw in the laptop's kernel, using a set of rules that blocks everything except DHCP. Then, once a lease is granted, I already have a bit of code (/etc/dhclient-exit-hooks) that gets control, so I use that point to invoke a script that replaces the firewall rules with ones that

The relevant lines from /etc/rc.conf are


firewall_enable="YES"
firewall_script="/etc/rc.firewall-pre-dhcp"
firewall_quiet="NO"
firewall_logging="YES"

As you can see, I am not using the supplied /etc/rc.firewall, though I did use it as a starting-point. One note, should you choose to do this on your own: placing an exit 0 (or any other form of ``exit'' statement) in your firewall rule-generation script is very unlikely to generate results that you want: there is quite a bit of network (and other) initialization that takes place after the firewall rules are set up, and the ``exit'' statement will prevent that.

In any case, a copy of the above-referenced /etc/rc.firewall-pre-dhcp script may be found here. And here is another link to the /etc/dhclient-exit-hooks script.

Finally, here is a link to the /etc/rc.firewall-post-dhcp script.


Comments? Please send them to David Wolfskill -- thanks!
$Id: dyn_net.html,v 1.3 2004/09/09 01:09:10 david Exp $