PCcard location-dependent configuration stuff Copyright 2001, 2002, David H. Wolfskill . Free use for any purpose is granted; please retain attribution. See Larry Wall's "Artistic License" for additional detail on the intent, should that appear appropriate. As the comments in the script (pccard_hook) indicate, the files here are an outgrowth of my efforts to get FreeBSD (on my laptop) to adjust to different locations as automatically as possible. Some folks use scripts that interact with the user; I didn't see how that was useful for me, because I fire up xdm during the multi-user boot process, and besides, this is the kind of thing where a computer should be able to to the work. Others use scripts that try to use network services (ARP & DHCP, for example) to determine information... but in my case, the catalyst for this work was 802.11b (wireless Ethernet) cards to work, and there are things that need to be configured, such as BSS vs. ad-hoc mode, SSID & WEP, before the card can use network services. (Recent changes from Doug Ambrisko to the an driver to permit promiscuous mode may change that. This work was done around the time those changes were written, and one of the other changes that went in in the same batch allowed "ancontrol" to affect the card's configuration without doing an "ifconfig up" first: early versions of the script did the "ifconfig up".) I have been running with this script since about 10 March, 2001, both on FreeBSD 4-STABLE and 5-CURRENT, on a laptop that has been tracking both of those on a daily basis. I have applied the above-mentioned "an" patches to the -STABLE side, and I also have Brokks Davis' "ifconfig" patches applied on both sides. Without the former patch, the code needed an "ifconfig up" in order to get the Aironet cards to respond to configuration change requests; without the latter, "ifconfig" won't do the configuration; you need to use the driver-specific "XXcontrol" program. Here's a list of the files: * README This file. * dhclient-exit-hooks A bit of code that gets executed when dhclient has had a chance to do something, if it is put in /etc. I use it to do a "reverse lookup" on my IP address (if I was just assigned one), and thus determine my hostname. It also fires up ntpdate and ntpd, if an NTP server is found. * kwd.db The RDB "database" that defines how to get a card (defined basically by its driver) to change its configuration, and how to find out what the result was. The "an" and "an-exp" entries work, at least for the BSS, non-WEP case. I don't have any other kinds of cards; I put the "wi" entry in as an example of what such a thing might look like (and to illustrate how different things are handled). * loc.db The RDB "database" that defines the characteristics of the different "locations". The entries -- modulo WEP keys and SSID changes -- work for me. I had a "work" entry, but work is no longer there, so that's moot. * pccard_hook The (Perl) script itself. I placed it in /usr/local/sbin/pccard_hook, but the only concerns I know of regarding that are that it be on a filesystem that is mounted when you want to invoke it, and that you point to it correctly from wherever you invoke it (more on that below). It has quite a few flags & options, which I'll describe below. Not all of them are implemented yet.... * start_if.an0 A 1-line invocation of pccard_hook for the an0 interface. * stop_if.an0 Clean things up a little: revert the hostname to "localhost" and kill off ntpd (if it's running). Note that there are a couple of RDB-style "databases" mentioned above. These are just flat files of a particular format; there are no actual "database routines" used, and this is pretty much self-contained. Nevertheless, the is a "port" (/usr/ports/databases/rdb), and what is in it will define the format, as well as provide examples of its use and scripts to manipulate the "databases" in various ways -- in particular, the "etbl" script is useful for editing these files that have rather long lines. The biggest challenge I faced in doing this is figuring out at what point to get pccard_hook invoked. Before I cobbled up the script, I had been hacking /etc/pccard.conf to issue the "ancontrol" commands directly. This meant that if I went from work to home, I needed to be sure and edit that file... and that was gross. Still, that experience led me to place the following line in /etc/pccard.conf: insert /usr/local/sbin/pccard_hook -x -i $device for the stanza of the device in question. And this has the benefit of working. The problems are twofold: * It doesn't scale. I'd need to do this for every different kind of card I'd want to use. :-( * It's ugly. Except for this, I wouldn't need to have /etc/pccard.conf at all -- the content of /etc/defaults/pccard.conf works just fine (thanks, Warner!). So I prowled around to find out where some code was that gets control around the same place -- before we actually try to sned or receive any traffic. And it was thus that I found /etc/pccard_ether. I didn't see anything that jumped out at me as an already-existing point to customize the behavior, so I applied the following patch: --- /etc/pccard_ether.orig Wed Apr 4 08:10:22 2001 +++ /etc/pccard_ether Sat Mar 31 00:57:04 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 And that's what I used until Ambrisko pointed out the existence of /etc/st{art,op}_if.*. Since using those doesn't mess with files that FreeBSD updates, that's a win. On the other hand, a pair of these is needed for each instantiation of each interface that one might want to use. Still, it seems to be the least of the evils, so I'm using it. OK; here's a discussion of the command-line flags & options for pccard_hook: * -d Debug flag. Writes to a file (/var/log/pccard_hook) unless -T is specified, in which case, it writes to /dev/tty. (Thought here is that if you're testing, it's probably manual, and you might want to see what's happening; if you're not testing, there's a reasonable probability this is happening rather automatically, and the amount of debug information might be enough that something useful will scroll by, unrecoverably.) * -D database directory (default: /usr/local/etc/pccard). For me, it made sense to keep the files together, though that's not necessarily optimal in retrospect. In particular, the per-driver database (kwd.db) has nothing that could imaginably be "secret" in it, while the location database (loc.db) could well have things in it that one would rather were not disclosed to random folks. * -f file for tracking the usage patterns, as a hint to the ordering This is not (yet) implemented... at all. The thought was that it might be interesting to maintain some sort of "connection history", so the code could be set up to base ordering heuristics on that history. And it might be interesting to do that... someday. Meanwhile, I haven't noticed much slowness in configuring for work or home, so it's not been a problem (for me). * -i interface on whose behalf we're doing this Uh... yeah. We know this already, so we might as well mention it. That way, we have some hope of coping with multi-homed machines. And besides, we need to know the device so we can know what the commads to issue to it are. * -l override the searching heuristics and just use the specified loc Mostly for the impatient, or as a fail-safe, so it can be invoked manually. * -n number of times to go through the list (default 5) After the code stabilized, I have yet to see it actually go all the way through the list, but the idea is that if it tries all of the defined locations for a given interface-type, and still doesn't get a connection, it will go through the list again, up to this many times -- before reverting to using the "*" location (if one is defined for this interface type). * -T test -- merely report what would (otherwise) have been done I used this during development, and for testing new kwd.db entries. For example, after I applied Brooks Davis' ifconfig patches (so that the bulk, if not all, of this configuration can be done with "ifconfig" vs. "ancontrol"), I tested the new "an-exp" entry with the -T flag. This may be used independently of the -d (debug) flag. * -x if specified, use the "experimental" (-exp) entry This is a hack. I did it so I could distinguish between the "an driver; use ancontrol" entry, vs. the "an driver; use ifconfig" one. It would probably be slightly less obnoxious to make this an option that takes an argument that would be appended to the driver name.... Maybe I'll do that....