Personal tools
You are here: Home Tips and Tricks (old) Wireless Auto-configuration for FreeBSD, Version 0.2
Document Actions

Wireless Auto-configuration for FreeBSD, Version 0.2

by xenophon — last modified 2005-09-15 18:48

This hack will automatically configure a wireless network card at interface startup time provided a list of possible networks and their WEP keys in /etc/rc.conf. The attached scripts are covered by the same license as FreeBSD.

I wanted a feature similar to Wireless Zero Configuration in Windows XP. The attached scripts approximate this for FreeBSD. After you've unpacked the shell archive, you'll need to compile wi-assoc-p.c with the following command:

 cc -static -o /sbin/wi-assoc-p wi-assoc-p.c

Then copy the script start_if.wiface to /etc and create symlinks to the appropriate file names with the following commands:

 cp start_if.wiface /etc
 chmod a+x /etc/start_if.wiface
 ln -sf /etc/start_if.wiface /etc/start_if.ath0
 ln -sf /etc/start_if.wiface /etc/start_if.wi0

Configuration data goes into /etc/rc.conf in the following format:

 wiconfig_${interface}_ssid${index}="${arguments_to_ifconfig}"

For example:

 wiconfig_wi0_ssid0="ssid foobar wepmode on wepkey 0xdeadbeef"
 wiconfig_wi0_ssid1="ssid bazqux wepmode off"
 wiconfig_ath0_ssid0="media DS11 ${wiconfig_wi0_ssid0}"

The start_if.wiface script will exit as soon as it associates, so use lower indicies for preferred configurations.

This is a shell archive. Save it in a file, remove anything before this line, and then unpack it by entering "sh file". Note, it may create directories; files and directories will be owned by you and have default permissions:

 #
 # This archive contains:

 #
 #        start_if.wiface
 #        wi-assoc-p.c

 #
 echo x - start_if.wiface

 sed 's/^X//' >start_if.wiface << 'END-of-start_if.wiface'
 X#!/bin/sh

 X#### START_IF.WIFACE --- Automagically configure wireless interfaces
 X

 X## The "start_if.<interface>" script is called by ifscript_up() in
 X## /etc/network.subr. We get the variable "$1" from that subroutine
 X## because it uses the Bourne shell operator "." to run this script.
 X## This has the happy side effect of allowing you to call this
 X## script from the command-line with the interface as an argument
 X## and have the script Do the Right Thing.
 Xwiface=$1
 X
 Xindex=0
 Xwhile : ; do

 X    eval wiconfig_args=\$wiconfig_${wiface}_args${index}
 X    if [ -n "${wiconfig_args}" ]; then
 X        ifconfig ${wiface} ${wiconfig_args}
 X    else
 X        break;
 X    fi

 X    ifconfig ${wiface} up && sleep 5
 X    if wi-assoc-p ${wiface}; then
 X        ifconfig ${wiface} down

 X        eval showstat_${wiface}=1
 X        break;
 X    fi

 X    index=$((${index} + 1))
 Xdone
 X

 X#### START_IF.WIFACE ends here.
 END-of-start_if.wiface
 echo x - wi-assoc-p.c

 sed 's/^X//' >wi-assoc-p.c << 'END-of-wi-assoc-p.c'
 X/* WI-ASSOC-P.C --- Test true if wireless card associated with AP/peers */
 X
 X#include <sys/param.h>
 X#include <sys/ioctl.h>
 X#include <sys/socket.h>
 X#include <sys/sysctl.h>
 X#include <sys/time.h>
 X#include <sys/module.h>
 X#include <sys/linker.h>
 X
 X#include <net/ethernet.h>
 X#include <net/if.h>

 X#include <net/if_var.h>
 X#include <net/if_dl.h>
 X#include <net/if_types.h>
 X#include <net/if_media.h>
 X#include <net/route.h>
 X#include <net80211/ieee80211.h>

 X#include <net80211/ieee80211_ioctl.h>
 X
 X#include <netinet/in.h>

 X#include <netinet/in_var.h>
 X#include <arpa/inet.h>
 X#include <netdb.h>
 X
 X#include <ctype.h>
 X#include <err.h>
 X#include <errno.h>
 X#include <fcntl.h>
 X#include <stdio.h>
 X#include <stdlib.h>
 X#include <string.h>
 X#include <unistd.h>
 X#include <ifaddrs.h>
 X
 Xint
 Xmain (int argc, char *argv[])
 X{
 X  char ifname[32];              /* the name of the interface,
 X                                   e.g. "wi0" */
 X  int ifindex = 0;              /* the index of the interface */
 X  int s;                        /* datagram socket, a handle for the
 X                                   interface in calls to ioctl(2) */

 X  u_int8_t data[32];            /* ioctl return values */
 X struct ifreq ifr;
 X struct ifmediareq ifmr;
 X struct ieee80211req ireq;
 X

 X  argc--; argv++;
 X if (argc < 1)
 X    errx (EXIT_FAILURE, "no interface specified");
 X
 X strncpy (ifname, *argv, sizeof (ifname));

 X  if ((ifindex = if_nametoindex (ifname)) == 0)
 X    errx (EXIT_FAILURE, "interface %s does not exist", ifname);
 X

 X  ifr.ifr_addr.sa_family = AF_INET;
 X strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name));
 X

 X  if ((s = socket (ifr.ifr_addr.sa_family, SOCK_DGRAM, 0)) < 0) {
 X    err (EXIT_FAILURE, "socket");
 X }
 X
 X (void) memset (&ireq, 0, sizeof (ireq));
 X (void) strncpy (ireq.i_name, ifname, sizeof (ireq.i_name));

 X  ireq.i_data = &data;
 X

 X  ireq.i_type = IEEE80211_IOC_SSID;
 X ireq.i_val = -1;
 X if (ioctl (s, SIOCG80211, &ireq) < 0) {
 X    /* If we can't get the SSID, then this isn't an 802.11 device. */
 X    exit (EXIT_FAILURE);
 X }
 X
 X (void) memset (&ifmr, 0, sizeof (ifmr));
 X (void) strncpy (ifmr.ifm_name, ifname, sizeof (ifmr.ifm_name));
 X

 X  if (ioctl (s, SIOCGIFMEDIA, (caddr_t) &ifmr) < 0) {
 X    exit (EXIT_FAILURE);        /* interface doesn't support SIOC{G,S}IFMEDIA
 */
 X }
 X
 X if (ifmr.ifm_status & IFM_ACTIVE)
 X    exit (EXIT_SUCCESS);        /* associated */
 X else
 X    exit (EXIT_FAILURE);        /* no carrier */
 X}
 X
 X/* WI-ASSOC-P.C ends here. */
 END-of-wi-assoc-p.c
 exit

« November 2008 »
Su Mo Tu We Th Fr Sa
1
2345678
9101112131415
16171819202122
23242526272829
30
 

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: