Saturday, January 07, 2006


The Holidays are over, Happy New Year and let's get back to werk :)

This week I have decided to give a make-over to my ancient Dell Inspiron 8000. I upgraded from RedHat 7.2 (yes, I know, I know...) to Fedora Core 4, and bought a Linksys WPC 54G v3 wireless card.

After downloading and installing ndiswrapper 1.7, I proceeded to configure the wireless connection.

The Windows NT driver that came with the card was installed properly by ndiswrapper, and the "iwlist scan" command promptly discovered my home network; then I tried using iwconfig to set the ESSID.

And I got into a problem here: iwconfig would report success, yet the SSID remained unchanged (off/any), and the address of the access point was all zeroed.

I tried setting the address point address by hand, no dice.

I googled the matter until 3 AM, when I decided to write my own C program for resetting the network ID on the card.

And, guess what? After running the code, the card auto-magically connected to my access point!
I have not tried using encryption yet. Our house is far enough from the street, and the closest neighbor is out of range for the Apple AirPort that we use... so no need to be paranoid.

Anyway, here's the program that made it all work:


/* -*- tab-width: 4; indent-tabs-mode: nil; -*-
vim: tabstop=4:softtabstop=4:expandtab:shiftwidth=4
*/
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <wireless.h>


static const char* default_dev[] = { "wlan0", NULL };


int main(int argc, const char* argv[])
{
int result = 0;
const char* device = NULL;

int s = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
if (s == -1)
{
fprintf(stderr, "socket: %s\n", strerror(errno));
result = -1;
}
else
{
struct iwreq req;

/* Reset the SSID for all devices given
as command line arguments; if no device
specified, reset the default device
*/
if (!(++argv, --argc))
{
argc = 1, argv = default_dev;
}

for (; argc; --argc, ++argv)
{
device = *argv;

/* init request structure */
memset(&req, 0, sizeof req);
strncpy(req.ifr_ifrn.ifrn_name,
device, sizeof req.ifr_ifrn.ifrn_name);

memset(&req.u.essid, 0, sizeof req.u.essid);

if (ioctl(s, SIOCSIWESSID, &req) < 0)
{
fprintf(stderr,
"ioctl: %s: %s\n", device, strerror(errno));

result = -2;
}
}

close(s);
}
return result;
}

After compiling it with the command
gcc -static essid.c -o /sbin/essid-reset ,
I have added to my system the following scripts:

/etc/sysconfig/network-scripts/ifcfg-wlan0

DEVICE=wlan0
BOOTPROTO=dhcp
ONBOOT=yes
TYPE=Ethernet

USERCTL=no
PEERDNS=yes
IPV6INIT=no


and:
/etc/init.d/wlan

#!/bin/sh

case "$action" in
start)
/sbin/essid-reset;;
stop)
ifdown wlan0;
rmmod ndiswrapper;;
esac

No comments: