wifi: move scanning/probe into wifi layer, avoid associating with wpa network until rsne is setup
This commit is contained in:
parent
82ccf5b26a
commit
3fbf35112f
3 changed files with 102 additions and 102 deletions
|
@ -1745,6 +1745,13 @@ rxon(Ether *edev, Wnode *bss)
|
|||
}
|
||||
flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto;
|
||||
|
||||
if(ctlr->aid != 0)
|
||||
setled(ctlr, 2, 0, 1); /* on when associated */
|
||||
else if(memcmp(ctlr->bssid, edev->bcast, Eaddrlen) != 0)
|
||||
setled(ctlr, 2, 10, 10); /* slow blink when connecting */
|
||||
else
|
||||
setled(ctlr, 2, 5, 5); /* fast blink when scanning */
|
||||
|
||||
if(ctlr->wifi->debug)
|
||||
print("#l%d: rxon: bssid %E, aid %x, channel %d, filter %x, flags %x\n",
|
||||
edev->ctlrno, ctlr->bssid, ctlr->aid, ctlr->channel, filter, flags);
|
||||
|
@ -1846,7 +1853,6 @@ transmit(Wifi *wifi, Wnode *wn, Block *b)
|
|||
return;
|
||||
}
|
||||
|
||||
if(wn != nil)
|
||||
if((wn->channel != ctlr->channel)
|
||||
|| (!ctlr->prom && (wn->aid != ctlr->aid || memcmp(wn->bssid, ctlr->bssid, Eaddrlen) != 0)))
|
||||
rxon(edev, wn);
|
||||
|
@ -1988,62 +1994,9 @@ iwlpromiscuous(void *arg, int on)
|
|||
qunlock(ctlr);
|
||||
}
|
||||
|
||||
static void
|
||||
iwlproc(void *arg)
|
||||
{
|
||||
Ether *edev;
|
||||
Ctlr *ctlr;
|
||||
Wifi *wifi;
|
||||
Wnode *bss;
|
||||
|
||||
edev = arg;
|
||||
ctlr = edev->ctlr;
|
||||
wifi = ctlr->wifi;
|
||||
|
||||
for(;;){
|
||||
/* hop channels for catching beacons */
|
||||
setled(ctlr, 2, 5, 5);
|
||||
while(wifi->bss == nil){
|
||||
qlock(ctlr);
|
||||
if(wifi->bss != nil){
|
||||
qunlock(ctlr);
|
||||
break;
|
||||
}
|
||||
ctlr->channel = 1 + ctlr->channel % 11;
|
||||
ctlr->aid = 0;
|
||||
rxon(edev, nil);
|
||||
qunlock(ctlr);
|
||||
wifiprobe(ctlr->wifi, ctlr->channel);
|
||||
tsleep(&up->sleep, return0, 0, 1000);
|
||||
}
|
||||
|
||||
/* wait for association */
|
||||
setled(ctlr, 2, 10, 10);
|
||||
while(wifichecklink(wifi) && (bss = wifi->bss) != nil){
|
||||
if(bss->aid != 0)
|
||||
break;
|
||||
tsleep(&up->sleep, return0, 0, 1000);
|
||||
}
|
||||
|
||||
if(wifi->bss == nil)
|
||||
continue;
|
||||
|
||||
/* wait for disassociation */
|
||||
edev->link = 1;
|
||||
setled(ctlr, 2, 0, 1);
|
||||
while(wifichecklink(wifi) && (bss = wifi->bss) != nil){
|
||||
if(bss->aid == 0)
|
||||
break;
|
||||
tsleep(&up->sleep, return0, 0, 1000);
|
||||
}
|
||||
edev->link = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwlattach(Ether *edev)
|
||||
{
|
||||
char name[32];
|
||||
FWImage *fw;
|
||||
Ctlr *ctlr;
|
||||
char *err;
|
||||
|
@ -2088,9 +2041,6 @@ iwlattach(Ether *edev)
|
|||
|
||||
setoptions(edev);
|
||||
|
||||
snprint(name, sizeof(name), "#l%diwl", edev->ctlrno);
|
||||
kproc(name, iwlproc, edev);
|
||||
|
||||
ctlr->attached = 1;
|
||||
}
|
||||
qunlock(ctlr);
|
||||
|
|
|
@ -31,6 +31,7 @@ enum {
|
|||
|
||||
static char Sconn[] = "connecting";
|
||||
static char Sauth[] = "authenticated";
|
||||
static char Sneedauth[] = "need authentication";
|
||||
static char Sunauth[] = "unauthenticated";
|
||||
|
||||
static char Sassoc[] = "associated";
|
||||
|
@ -132,8 +133,8 @@ wifitx(Wifi *wifi, Wnode *wn, Block *b)
|
|||
Wifipkt *w;
|
||||
uint seq;
|
||||
|
||||
if(wn != nil)
|
||||
wn->lastsend = MACHP(0)->ticks;
|
||||
wn->lastsend = MACHP(0)->ticks;
|
||||
|
||||
seq = incref(&wifi->txseq);
|
||||
seq <<= 4;
|
||||
|
||||
|
@ -143,7 +144,7 @@ wifitx(Wifi *wifi, Wnode *wn, Block *b)
|
|||
w->seq[0] = seq;
|
||||
w->seq[1] = seq>>8;
|
||||
|
||||
if((w->fc[0] & 0x0c) != 0x00 && wn != nil)
|
||||
if((w->fc[0] & 0x0c) != 0x00)
|
||||
b = wifiencrypt(wifi, wn, b);
|
||||
|
||||
if(b != nil)
|
||||
|
@ -183,8 +184,8 @@ nodelookup(Wifi *wifi, uchar *bssid, int new)
|
|||
return nn;
|
||||
}
|
||||
|
||||
void
|
||||
wifiprobe(Wifi *wifi, int channel)
|
||||
static void
|
||||
wifiprobe(Wifi *wifi, Wnode *wn)
|
||||
{
|
||||
Wifipkt *w;
|
||||
Block *b;
|
||||
|
@ -192,8 +193,11 @@ wifiprobe(Wifi *wifi, int channel)
|
|||
int n;
|
||||
|
||||
n = strlen(wifi->essid);
|
||||
if(n == 0)
|
||||
if(n == 0){
|
||||
/* no specific essid, just tell driver to tune channel */
|
||||
(*wifi->transmit)(wifi, wn, nil);
|
||||
return;
|
||||
}
|
||||
|
||||
b = allocb(WIFIHDRSIZE + 512);
|
||||
w = (Wifipkt*)b->wp;
|
||||
|
@ -217,14 +221,12 @@ wifiprobe(Wifi *wifi, int channel)
|
|||
*p++ = 0x8b;
|
||||
*p++ = 0x96;
|
||||
|
||||
if(channel > 0){
|
||||
*p++ = 0x03; /* ds parameter set */
|
||||
*p++ = 1;
|
||||
*p++ = channel;
|
||||
}
|
||||
*p++ = 0x03; /* ds parameter set */
|
||||
*p++ = 1;
|
||||
*p++ = wn->channel;
|
||||
|
||||
b->wp = p;
|
||||
wifitx(wifi, nil, b);
|
||||
wifitx(wifi, wn, b);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -250,6 +252,9 @@ sendauth(Wifi *wifi, Wnode *bss)
|
|||
*p++ = 0; /* status */
|
||||
*p++ = 0;
|
||||
b->wp = p;
|
||||
|
||||
bss->aid = 0;
|
||||
|
||||
wifitx(wifi, bss, b);
|
||||
}
|
||||
|
||||
|
@ -408,7 +413,8 @@ wifideauth(Wifi *wifi, Wnode *wn)
|
|||
wn->aid = 0;
|
||||
|
||||
if(wn == wifi->bss){
|
||||
wifi->bss = nil;
|
||||
/* notify driver about node aid association */
|
||||
(*wifi->transmit)(wifi, wn, nil);
|
||||
|
||||
/* notify aux/wpa with a zero length write that we got deassociated from the ap */
|
||||
ether = wifi->ether;
|
||||
|
@ -478,10 +484,9 @@ wifiproc(void *arg)
|
|||
continue;
|
||||
b->rp += wifihdrlen(w);
|
||||
recvbeacon(wifi, wn, b->rp, BLEN(b));
|
||||
if(wifi->bss != nil)
|
||||
continue;
|
||||
if(((wn->status == nil || wn->status == Sunauth)
|
||||
|| (wn->status == Sconn && TK2SEC(wn->lastseen - wn->lastsend) > 2))
|
||||
|
||||
if(wifi->bss == nil
|
||||
&& TK2MS(MACHP(0)->ticks - wn->lastsend) > 1000
|
||||
&& goodbss(wifi, wn)){
|
||||
setstatus(wifi, wn, Sconn);
|
||||
sendauth(wifi, wn);
|
||||
|
@ -503,15 +508,21 @@ wifiproc(void *arg)
|
|||
(*wifi->transmit)(wifi, wn, nil);
|
||||
break;
|
||||
case 0xb0: /* auth */
|
||||
setstatus(wifi, wn, Sauth);
|
||||
if(wifi->debug)
|
||||
print("#l%d: got auth from %E\n", wifi->ether->ctlrno, wn->bssid);
|
||||
if(wn->brsnelen > 0 && wn->rsnelen == 0)
|
||||
setstatus(wifi, wn, Sneedauth);
|
||||
else
|
||||
setstatus(wifi, wn, Sauth);
|
||||
if(wifi->bss == nil && goodbss(wifi, wn)){
|
||||
wifi->bss = wn;
|
||||
sendassoc(wifi, wn);
|
||||
if(wn->status == Sauth)
|
||||
sendassoc(wifi, wn);
|
||||
}
|
||||
break;
|
||||
case 0xc0: /* deauth */
|
||||
if(wifi->debug)
|
||||
print("#l%d: got deauth\n", wifi->ether->ctlrno);
|
||||
print("#l%d: got deauth from %E\n", wifi->ether->ctlrno, wn->bssid);
|
||||
wifideauth(wifi, wn);
|
||||
break;
|
||||
}
|
||||
|
@ -579,6 +590,56 @@ wifoproc(void *arg)
|
|||
pexit("ether out queue closed", 0);
|
||||
}
|
||||
|
||||
static void
|
||||
wifsproc(void *arg)
|
||||
{
|
||||
Ether *ether;
|
||||
Wifi *wifi;
|
||||
Wnode wnscan;
|
||||
Wnode *wn;
|
||||
ulong now, tmout;
|
||||
|
||||
wifi = arg;
|
||||
ether = wifi->ether;
|
||||
|
||||
wn = &wnscan;
|
||||
memset(wn, 0, sizeof(*wn));
|
||||
memmove(wn->bssid, ether->bcast, Eaddrlen);
|
||||
|
||||
while(waserror())
|
||||
;
|
||||
Scan:
|
||||
/* scan for access point */
|
||||
while(wifi->bss == nil){
|
||||
ether->link = 0;
|
||||
wnscan.channel = 1 + wnscan.channel % 11;
|
||||
wifiprobe(wifi, &wnscan);
|
||||
tsleep(&up->sleep, return0, 0, 1000);
|
||||
}
|
||||
|
||||
/* maintain access point */
|
||||
tmout = 0;
|
||||
while((wn = wifi->bss) != nil){
|
||||
ether->link = (wn->status == Sassoc) || (wn->status == Sblocked);
|
||||
now = MACHP(0)->ticks;
|
||||
if(wn->status != Sneedauth && TK2SEC(now - wn->lastseen) > 60 || goodbss(wifi, wn) == 0){
|
||||
wifideauth(wifi, wn);
|
||||
wifi->bss = nil;
|
||||
break;
|
||||
}
|
||||
if(TK2MS(now - wn->lastsend) > 1000){
|
||||
if(wn->status == Sauth && (++tmout & 7) == 0)
|
||||
wifideauth(wifi, wn); /* stuck in auth, start over */
|
||||
if(wn->status == Sconn || wn->status == Sunauth)
|
||||
sendauth(wifi, wn);
|
||||
if(wn->status == Sauth)
|
||||
sendassoc(wifi, wn);
|
||||
}
|
||||
tsleep(&up->sleep, return0, 0, 500);
|
||||
}
|
||||
goto Scan;
|
||||
}
|
||||
|
||||
Wifi*
|
||||
wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
|
||||
{
|
||||
|
@ -603,28 +664,12 @@ wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
|
|||
kproc(name, wifiproc, wifi);
|
||||
snprint(name, sizeof(name), "#l%dwifo", ether->ctlrno);
|
||||
kproc(name, wifoproc, wifi);
|
||||
snprint(name, sizeof(name), "#l%dwifs", ether->ctlrno);
|
||||
kproc(name, wifsproc, wifi);
|
||||
|
||||
return wifi;
|
||||
}
|
||||
|
||||
int
|
||||
wifichecklink(Wifi *wifi)
|
||||
{
|
||||
Wnode *wn;
|
||||
|
||||
wn = wifi->bss;
|
||||
if(wn == nil)
|
||||
return 0;
|
||||
if((TK2SEC(MACHP(0)->ticks - wn->lastseen) > 60)
|
||||
|| (TK2SEC(wn->lastseen - wn->lastsend) > 5) && (wn->status == Sauth || wn->status == Sblocked)){
|
||||
if(wifi->debug)
|
||||
print("#l%d: link broken\n", wifi->ether->ctlrno);
|
||||
wifideauth(wifi, wn);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
hextob(char *s, char **sp, uchar *b, int n)
|
||||
{
|
||||
|
@ -760,8 +805,11 @@ wifictl(Wifi *wifi, void *buf, long n)
|
|||
wifi->essid[0] = 0;
|
||||
Findbss:
|
||||
wn = wifi->bss;
|
||||
if(wn != nil && goodbss(wifi, wn))
|
||||
break;
|
||||
if(wn != nil){
|
||||
if(goodbss(wifi, wn))
|
||||
break;
|
||||
wifideauth(wifi, wn);
|
||||
}
|
||||
wifi->bss = nil;
|
||||
if(wifi->essid[0] == 0 && memcmp(wifi->bssid, wifi->ether->bcast, Eaddrlen) == 0)
|
||||
break;
|
||||
|
@ -791,8 +839,13 @@ wifictl(Wifi *wifi, void *buf, long n)
|
|||
wn->rsnelen = 0;
|
||||
else
|
||||
wn->rsnelen = hextob(cb->f[1], nil, wn->rsne, sizeof(wn->rsne));
|
||||
setstatus(wifi, wn, Sauth);
|
||||
sendassoc(wifi, wn);
|
||||
if(wn->aid == 0){
|
||||
setstatus(wifi, wn, Sconn);
|
||||
sendauth(wifi, wn);
|
||||
} else {
|
||||
setstatus(wifi, wn, Sauth);
|
||||
sendassoc(wifi, wn);
|
||||
}
|
||||
break;
|
||||
case CMrxkey0: case CMrxkey1: case CMrxkey2: case CMrxkey3: case CMrxkey4:
|
||||
case CMtxkey0:
|
||||
|
|
|
@ -81,6 +81,3 @@ void wifiiq(Wifi*, Block*);
|
|||
|
||||
long wifistat(Wifi*, void*, long, ulong);
|
||||
long wifictl(Wifi*, void*, long);
|
||||
|
||||
int wifichecklink(Wifi*);
|
||||
void wifiprobe(Wifi*, int);
|
||||
|
|
Loading…
Reference in a new issue