ref: 17357cd71f36d19b3cf2f3f9656a1505ed318efb
parent: 4ccbd5042434734c09f171e47ca0b78682dc2c36
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sun Jun 23 19:54:15 EDT 2013
wifi: allow selecting specific access point with bssid= parameter and wifictl command
--- a/sys/man/8/plan9.ini
+++ b/sys/man/8/plan9.ini
@@ -392,11 +392,18 @@
.B /boot.
To select the access point, the
.B essid=
-parameter can be specified at boot or set during runtime
+and
+.B bssid=
+parameters can be specified at boot or set during runtime
like:
.EX
echo essid left-armpit >/net/ether1/clone
.EE
+If both
+.B essid=
+and
+.B bssid=
+are spcified, both must match.
Scan results appear in the
.B ifstats
file and can be read out like:
@@ -403,7 +410,10 @@
.EX
cat /net/ether1/ifstats
.EE
-Ad-hoc mode or encryption is currently not supported.
+Ad-hoc mode or WEP encryption is currently not supported.
+To enable WPA/WPA2 encryption, see
+.IR wpa (8)
+for details.
.SS DISKS, TAPES
(S)ATA controllers are autodetected.
.SS \fL*nodma=\fP
--- a/sys/src/9/pc/etheriwl.c
+++ b/sys/src/9/pc/etheriwl.c
@@ -1953,7 +1953,9 @@
p = strchr(buf, '=');
if(p != nil)
*p = 0;
- if(strcmp(buf, "debug") == 0 || strcmp(buf, "essid") == 0){+ if(strcmp(buf, "debug") == 0
+ || strcmp(buf, "essid") == 0
+ || strcmp(buf, "bssid") == 0){if(p != nil)
*p = ' ';
if(!waserror()){--- a/sys/src/9/pc/wifi.c
+++ b/sys/src/9/pc/wifi.c
@@ -32,7 +32,7 @@
static char Snone[] = "new";
static char Sconn[] = "connecting";
static char Sauth[] = "authenticated";
-static char Sunauth[] = "unauthentictaed";
+static char Sunauth[] = "unauthenticated";
static char Sassoc[] = "associated";
static char Sunassoc[] = "unassociated";
static char Sblocked[] = "blocked"; /* no keys negotiated. only pass EAPOL frames */
@@ -385,7 +385,14 @@
continue;
b->rp += wifihdrlen(w);
recvbeacon(wifi, wn, b->rp, BLEN(b));
- if(wifi->bss == nil && wifi->essid[0] != 0 && strcmp(wifi->essid, wn->ssid) == 0){+ if(wifi->bss == nil){+ if(memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) != 0){+ if(memcmp(wifi->bssid, wn->bssid, Eaddrlen) != 0)
+ continue; /* bssid doesnt match */
+ } else if(wifi->essid[0] == 0)
+ continue; /* both bssid and essid unspecified */
+ if(wifi->essid[0] != 0 && strcmp(wifi->essid, wn->ssid) != 0)
+ continue; /* essid doesnt match */
wifi->bss = wn;
setstatus(wifi, Sconn);
sendauth(wifi, wn);
@@ -498,6 +505,9 @@
wifi->transmit = transmit;
wifi->status = Snone;
+ wifi->essid[0] = 0;
+ memmove(wifi->bssid, ether->bcast, Eaddrlen);
+
snprint(name, sizeof(name), "#l%dwifi", ether->ctlrno);
kproc(name, wifiproc, wifi);
snprint(name, sizeof(name), "#l%dwifo", ether->ctlrno);
@@ -567,6 +577,7 @@
CMdebug,
CMessid,
CMauth,
+ CMbssid,
CMrxkey0,
CMrxkey1,
CMrxkey2,
@@ -580,6 +591,7 @@
CMdebug, "debug", 0,
CMessid, "essid", 0,
CMauth, "auth", 0,
+ CMbssid, "bssid", 0,
CMrxkey0, "rxkey0", 0, /* group keys */
CMrxkey1, "rxkey1", 0,
@@ -595,6 +607,7 @@
long
wifictl(Wifi *wifi, void *buf, long n)
{+ uchar addr[Eaddrlen];
Cmdbuf *cb;
Cmdtab *ct;
Wnode *wn;
@@ -607,13 +620,12 @@
}
if(wifi->debug)
print("#l%d: wifictl: %.*s\n", wifi->ether->ctlrno, (int)n, buf);+ memmove(addr, wifi->ether->bcast, Eaddrlen);
wn = wifi->bss;
cb = parsecmd(buf, n);
ct = lookupcmd(cb, wifictlmsg, nelem(wifictlmsg));
if(ct->index >= CMauth){- if(ct->index >= CMrxkey0 && cb->nf > 1){- uchar addr[Eaddrlen];
-
+ if(cb->nf > 1 && (ct->index == CMbssid || ct->index >= CMrxkey0)){ if(parseether(addr, cb->f[1]) == 0){cb->f++;
cb->nf--;
@@ -620,7 +632,7 @@
wn = nodelookup(wifi, addr, 0);
}
}
- if(wn == nil)
+ if(wn == nil && ct->index != CMbssid)
error("missing node");}
switch(ct->index){@@ -647,6 +659,17 @@
}
}
break;
+ case CMbssid:
+ memmove(wifi->bssid, addr, Eaddrlen);
+ if(wn == nil){+ wifi->bss = nil;
+ setstatus(wifi, Snone);
+ } else {+ wifi->bss = wn;
+ setstatus(wifi, Sconn);
+ sendauth(wifi, wn);
+ }
+ break;
case CMauth:
setstatus(wifi, Sauth);
memset(wn->rxkey, 0, sizeof(wn->rxkey));
@@ -687,11 +710,12 @@
e = s + 4096;
p = seprint(p, e, "status: %s\n", wifi->status);
- p = seprint(p, e, "essid: %s\n", wifi->essid);
wn = wifi->bss;
if(wn != nil){+ p = seprint(p, e, "essid: %s\n", wn->ssid);
p = seprint(p, e, "bssid: %E\n", wn->bssid);
+ p = seprint(p, e, "channel: %.2d\n", wn->channel);
/* only print key ciphers and key length */
for(i = 0; i<nelem(wn->rxkey); i++)
@@ -707,7 +731,9 @@
p = seprint(p, e, "%.2X", wn->brsne[i]);
p = seprint(p, e, "\n");
}
- p = seprint(p, e, "channel: %.2d\n", wn->channel);
+ } else {+ p = seprint(p, e, "essid: %s\n", wifi->essid);
+ p = seprint(p, e, "bssid: %E\n", wifi->bssid);
}
now = MACHP(0)->ticks;
--- a/sys/src/9/pc/wifi.h
+++ b/sys/src/9/pc/wifi.h
@@ -52,7 +52,11 @@
Ref txseq;
void (*transmit)(Wifi*, Wnode*, Block*);
+ /* for searching */
+ uchar bssid[Eaddrlen];
char essid[Essidlen+2];
+
+ /* effective base station */
Wnode *bss;
Wnode node[32];
--
⑨