summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-06-23 23:54:15 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-06-23 23:54:15 +0200
commita8cc5cff0eb4ed57164045e53cb6773ba9258e65 (patch)
tree4f10c5981e0f7e4c8f15122129a1daeadc6907d3
parent43323512f08b671e391685c601e78645b15ee681 (diff)
wifi: allow selecting specific access point with bssid= parameter and wifictl command
-rw-r--r--sys/man/8/plan9.ini14
-rw-r--r--sys/src/9/pc/etheriwl.c4
-rw-r--r--sys/src/9/pc/wifi.c42
-rw-r--r--sys/src/9/pc/wifi.h4
4 files changed, 53 insertions, 11 deletions
diff --git a/sys/man/8/plan9.ini b/sys/man/8/plan9.ini
index 61115f7fd..9e82444f6 100644
--- a/sys/man/8/plan9.ini
+++ b/sys/man/8/plan9.ini
@@ -392,18 +392,28 @@ or
.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:
.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
diff --git a/sys/src/9/pc/etheriwl.c b/sys/src/9/pc/etheriwl.c
index 51c80933e..8930a10d2 100644
--- a/sys/src/9/pc/etheriwl.c
+++ b/sys/src/9/pc/etheriwl.c
@@ -1953,7 +1953,9 @@ setoptions(Ether *edev)
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()){
diff --git a/sys/src/9/pc/wifi.c b/sys/src/9/pc/wifi.c
index ec16f7477..127a5efb8 100644
--- a/sys/src/9/pc/wifi.c
+++ b/sys/src/9/pc/wifi.c
@@ -32,7 +32,7 @@ enum {
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 @@ wifiproc(void *arg)
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 @@ wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
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 @@ enum {
CMdebug,
CMessid,
CMauth,
+ CMbssid,
CMrxkey0,
CMrxkey1,
CMrxkey2,
@@ -580,6 +591,7 @@ static Cmdtab wifictlmsg[] =
CMdebug, "debug", 0,
CMessid, "essid", 0,
CMauth, "auth", 0,
+ CMbssid, "bssid", 0,
CMrxkey0, "rxkey0", 0, /* group keys */
CMrxkey1, "rxkey1", 0,
@@ -595,6 +607,7 @@ static Cmdtab wifictlmsg[] =
long
wifictl(Wifi *wifi, void *buf, long n)
{
+ uchar addr[Eaddrlen];
Cmdbuf *cb;
Cmdtab *ct;
Wnode *wn;
@@ -607,20 +620,19 @@ wifictl(Wifi *wifi, void *buf, long n)
}
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--;
wn = nodelookup(wifi, addr, 0);
}
}
- if(wn == nil)
+ if(wn == nil && ct->index != CMbssid)
error("missing node");
}
switch(ct->index){
@@ -647,6 +659,17 @@ wifictl(Wifi *wifi, void *buf, long n)
}
}
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 @@ wifistat(Wifi *wifi, void *buf, long n, ulong off)
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 @@ wifistat(Wifi *wifi, void *buf, long n, ulong off)
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;
diff --git a/sys/src/9/pc/wifi.h b/sys/src/9/pc/wifi.h
index 39e35f14a..8f67324eb 100644
--- a/sys/src/9/pc/wifi.h
+++ b/sys/src/9/pc/wifi.h
@@ -52,7 +52,11 @@ struct Wifi
Ref txseq;
void (*transmit)(Wifi*, Wnode*, Block*);
+ /* for searching */
+ uchar bssid[Eaddrlen];
char essid[Essidlen+2];
+
+ /* effective base station */
Wnode *bss;
Wnode node[32];