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; irxkey); 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];