etheriwl: automatic channel scanning, transmission handling, promisc mode
the channel= plan9.ini parameter isnt needed anymore as we now hop the channels to scan for beacons. the status is also indicated with the link led :-) handle all these flags on packet transmission like RTS for big packets and sending data packets to the AP instead of broadcasting everything. properly setup bss hardware node table and filtering. now promisc mode is only used when requested. handle deauth message from ap. increase node table to 32 entries.
This commit is contained in:
parent
c2f5d36d7f
commit
ffb3ded366
4 changed files with 284 additions and 63 deletions
|
@ -222,6 +222,28 @@ enum {
|
|||
SchedTransTblOff5000 = 0x7e0,
|
||||
};
|
||||
|
||||
enum {
|
||||
FilterPromisc = 1<<0,
|
||||
FilterCtl = 1<<1,
|
||||
FilterMulticast = 1<<2,
|
||||
FilterNoDecrypt = 1<<3,
|
||||
FilterBSS = 1<<5,
|
||||
FilterBeacon = 1<<6,
|
||||
};
|
||||
|
||||
enum {
|
||||
RFlag24Ghz = 1<<0,
|
||||
RFlagCCK = 1<<1,
|
||||
RFlagAuto = 1<<2,
|
||||
RFlagShSlot = 1<<4,
|
||||
RFlagShPreamble = 1<<5,
|
||||
RFlagNoDiversity = 1<<7,
|
||||
RFlagAntennaA = 1<<8,
|
||||
RFlagAntennaB = 1<<9,
|
||||
RFlagTSF = 1<<15,
|
||||
RFlagCTSToSelf = 1<<30,
|
||||
};
|
||||
|
||||
typedef struct FWInfo FWInfo;
|
||||
typedef struct FWImage FWImage;
|
||||
typedef struct FWSect FWSect;
|
||||
|
@ -303,7 +325,14 @@ struct Ctlr {
|
|||
u32int *nic;
|
||||
uchar *kwpage;
|
||||
|
||||
/* assigned node ids in hardware node table or -1 if unassigned */
|
||||
int bcastnodeid;
|
||||
int bssnodeid;
|
||||
|
||||
/* current receiver settings */
|
||||
int channel;
|
||||
int prom;
|
||||
int aid;
|
||||
|
||||
RXQ rx;
|
||||
TXQ tx[20];
|
||||
|
@ -1019,12 +1048,11 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
|
|||
q = &ctlr->tx[qid];
|
||||
while(q->n >= Ntx){
|
||||
iunlock(ctlr);
|
||||
eqlock(q);
|
||||
if(waserror()){
|
||||
qunlock(q);
|
||||
nexterror();
|
||||
qlock(q);
|
||||
if(!waserror()){
|
||||
tsleep(q, txqready, q, 10);
|
||||
poperror();
|
||||
}
|
||||
tsleep(q, txqready, q, 10);
|
||||
qunlock(q);
|
||||
ilock(ctlr);
|
||||
}
|
||||
|
@ -1067,12 +1095,42 @@ qcmd(Ctlr *ctlr, uint qid, uint code, uchar *data, int size, Block *block)
|
|||
iunlock(ctlr);
|
||||
}
|
||||
|
||||
static int
|
||||
txqempty(void *arg)
|
||||
{
|
||||
TXQ *q = arg;
|
||||
return q->n == 0;
|
||||
}
|
||||
|
||||
static void
|
||||
flushq(Ctlr *ctlr, uint qid)
|
||||
{
|
||||
TXQ *q;
|
||||
|
||||
q = &ctlr->tx[qid];
|
||||
while(q->n > 0){
|
||||
qlock(q);
|
||||
if(!waserror()){
|
||||
tsleep(q, txqempty, q, 10);
|
||||
poperror();
|
||||
}
|
||||
qunlock(q);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cmd(Ctlr *ctlr, uint code, uchar *data, int size)
|
||||
{
|
||||
qcmd(ctlr, 4, code, data, size, nil);
|
||||
}
|
||||
|
||||
static void
|
||||
flushcmd(Ctlr *ctlr)
|
||||
{
|
||||
flushq(ctlr, 4);
|
||||
}
|
||||
|
||||
static void
|
||||
setled(Ctlr *ctlr, int which, int on, int off)
|
||||
{
|
||||
|
@ -1099,9 +1157,6 @@ postboot(Ctlr *ctlr)
|
|||
char *err;
|
||||
int i, q;
|
||||
|
||||
/* main led turn on! (verify that firmware processes commands) */
|
||||
setled(ctlr, 2, 0, 1);
|
||||
|
||||
if((err = niclock(ctlr)) != nil)
|
||||
error(err);
|
||||
|
||||
|
@ -1228,12 +1283,42 @@ rxon(Ether *edev, Wnode *bss)
|
|||
{
|
||||
uchar c[Tcmdsize], *p;
|
||||
Ctlr *ctlr;
|
||||
uchar *bssid;
|
||||
int filter, flags;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
bssid = edev->bcast;
|
||||
filter = FilterMulticast | FilterBeacon;
|
||||
if(ctlr->prom)
|
||||
filter |= FilterPromisc;
|
||||
if(bss != nil){
|
||||
ctlr->channel = bss->channel;
|
||||
if(bss->aid != 0){
|
||||
bssid = bss->bssid;
|
||||
filter |= FilterBSS;
|
||||
filter &= ~FilterBeacon;
|
||||
ctlr->aid = bss->aid;
|
||||
|
||||
ctlr->bssnodeid = -1;
|
||||
} else {
|
||||
filter &= ~FilterBSS;
|
||||
filter |= FilterBeacon;
|
||||
ctlr->aid = 0;
|
||||
|
||||
ctlr->bcastnodeid = -1;
|
||||
}
|
||||
} else {
|
||||
ctlr->bcastnodeid = -1;
|
||||
ctlr->bssnodeid = -1;
|
||||
}
|
||||
flags = RFlagTSF | RFlagCTSToSelf | RFlag24Ghz | RFlagAuto;
|
||||
|
||||
if(0) print("rxon: bssid %E, aid %x, channel %d, filter %x, flags %x\n",
|
||||
bssid, ctlr->aid, ctlr->channel, filter, flags);
|
||||
|
||||
memset(p = c, 0, sizeof(c));
|
||||
memmove(p, edev->ea, 6); p += 8; /* myaddr */
|
||||
memmove(p, (bss != nil) ? bss->bssid : edev->bcast, 6);
|
||||
p += 8; /* bssid */
|
||||
memmove(p, bssid, 6); p += 8; /* bssid */
|
||||
memmove(p, edev->ea, 6); p += 8; /* wlap */
|
||||
*p++ = 3; /* mode (STA) */
|
||||
*p++ = 0; /* air (?) */
|
||||
|
@ -1242,14 +1327,13 @@ rxon(Ether *edev, Wnode *bss)
|
|||
p += 2;
|
||||
*p++ = 0xff; /* ofdm mask (not yet negotiated) */
|
||||
*p++ = 0x0f; /* cck mask (not yet negotiated) */
|
||||
if(bss != nil)
|
||||
put16(p, bss->aid & ~0xc000);
|
||||
put16(p, ctlr->aid & 0x3fff);
|
||||
p += 2; /* aid */
|
||||
put32(p, (1<<15)|(1<<30)|(1<<0)); /* flags (TSF | CTS_TO_SELF | 24GHZ) */
|
||||
put32(p, flags);
|
||||
p += 4;
|
||||
put32(p, 8|4|1); /* filter (NODECRYPT|MULTICAST|PROMISC) */
|
||||
put32(p, filter);
|
||||
p += 4;
|
||||
*p++ = bss != nil ? bss->channel : ctlr->channel;
|
||||
*p++ = ctlr->channel;
|
||||
p++; /* reserved */
|
||||
*p++ = 0xff; /* ht single mask */
|
||||
*p++ = 0xff; /* ht dual mask */
|
||||
|
@ -1260,10 +1344,14 @@ rxon(Ether *edev, Wnode *bss)
|
|||
p += 2; /* reserved */
|
||||
}
|
||||
cmd(ctlr, 16, c, p - c);
|
||||
|
||||
addnode(ctlr, (ctlr->type != Type4965) ? 15 : 31, edev->bcast);
|
||||
if(bss != nil)
|
||||
addnode(ctlr, 0, bss->bssid);
|
||||
if(ctlr->bcastnodeid == -1){
|
||||
ctlr->bcastnodeid = (ctlr->type != Type4965) ? 15 : 31;
|
||||
addnode(ctlr, ctlr->bcastnodeid, edev->bcast);
|
||||
}
|
||||
if(ctlr->bssnodeid == -1 && bss != nil && ctlr->aid != 0){
|
||||
ctlr->bssnodeid = 0;
|
||||
addnode(ctlr, ctlr->bssnodeid, bss->bssid);
|
||||
}
|
||||
}
|
||||
|
||||
static struct ratetab {
|
||||
|
@ -1271,10 +1359,10 @@ static struct ratetab {
|
|||
uchar plcp;
|
||||
uchar flags;
|
||||
} ratetab[] = {
|
||||
{ 2, 10, 1<<1 },
|
||||
{ 4, 20, 1<<1 },
|
||||
{ 11, 55, 1<<1 },
|
||||
{ 22, 110, 1<<1 },
|
||||
{ 2, 10, RFlagCCK },
|
||||
{ 4, 20, RFlagCCK },
|
||||
{ 11, 55, RFlagCCK },
|
||||
{ 22, 110, RFlagCCK },
|
||||
{ 12, 0xd, 0 },
|
||||
{ 18, 0xf, 0 },
|
||||
{ 24, 0x5, 0 },
|
||||
|
@ -1286,32 +1374,76 @@ static struct ratetab {
|
|||
{ 120, 0x3, 0 }
|
||||
};
|
||||
|
||||
enum {
|
||||
TFlagNeedProtection = 1<<0,
|
||||
TFlagNeedRTS = 1<<1,
|
||||
TFlagNeedCTS = 1<<2,
|
||||
TFlagNeedACK = 1<<3,
|
||||
TFlagLinkq = 1<<4,
|
||||
TFlagImmBa = 1<<6,
|
||||
TFlagFullTxOp = 1<<7,
|
||||
TFlagBtDis = 1<<12,
|
||||
TFlagAutoSeq = 1<<13,
|
||||
TFlagMoreFrag = 1<<14,
|
||||
TFlagInsertTs = 1<<16,
|
||||
TFlagNeedPadding = 1<<20,
|
||||
};
|
||||
|
||||
static void
|
||||
transmit(Wifi *wifi, Wnode *, Block *b)
|
||||
transmit(Wifi *wifi, Wnode *wn, Block *b)
|
||||
{
|
||||
uchar c[Tcmdsize], *p;
|
||||
Ether *edev;
|
||||
Ctlr *ctlr;
|
||||
Wifipkt *w;
|
||||
int flags, nodeid, rate;
|
||||
|
||||
ctlr = wifi->ether->ctlr;
|
||||
w = (Wifipkt*)b->rp;
|
||||
edev = wifi->ether;
|
||||
ctlr = edev->ctlr;
|
||||
|
||||
qlock(ctlr);
|
||||
if(wn != nil && (wn->aid != ctlr->aid || wn->channel != ctlr->channel))
|
||||
rxon(edev, wn);
|
||||
|
||||
rate = 0;
|
||||
flags = 0;
|
||||
nodeid = ctlr->bcastnodeid;
|
||||
if((w->a1[0] & 1) == 0){
|
||||
flags |= TFlagNeedACK;
|
||||
|
||||
if(BLEN(b) > 512-4)
|
||||
flags |= TFlagNeedRTS;
|
||||
|
||||
if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
|
||||
nodeid = ctlr->bssnodeid;
|
||||
rate = 2; /* BUG: hardcode 11Mbit */
|
||||
}
|
||||
|
||||
if(flags & (TFlagNeedRTS|TFlagNeedCTS)){
|
||||
if(ctlr->type != Type4965){
|
||||
flags &= ~(TFlagNeedRTS|TFlagNeedCTS);
|
||||
flags |= TFlagNeedProtection;
|
||||
} else
|
||||
flags |= TFlagFullTxOp;
|
||||
}
|
||||
}
|
||||
qunlock(ctlr);
|
||||
|
||||
memset(p = c, 0, sizeof(c));
|
||||
put16(p, BLEN(b));
|
||||
p += 2;
|
||||
p += 2; /* lnext */
|
||||
put32(p, 0); /* flags */
|
||||
put32(p, flags);
|
||||
p += 4;
|
||||
put32(p, 0);
|
||||
p += 4; /* scratch */
|
||||
|
||||
/* BUG: hardcode 11Mbit */
|
||||
*p++ = ratetab[2].plcp; /* plcp */
|
||||
*p++ = ratetab[2].flags | (1<<6); /* rflags */
|
||||
*p++ = ratetab[rate].plcp;
|
||||
*p++ = ratetab[rate].flags | (1<<6);
|
||||
|
||||
p += 2; /* xflags */
|
||||
|
||||
/* BUG: we always use broadcast node! */
|
||||
*p++ = (ctlr->type != Type4965) ? 15 : 31;
|
||||
|
||||
*p++ = nodeid;
|
||||
*p++ = 0; /* security */
|
||||
*p++ = 0; /* linkq */
|
||||
p++; /* reserved */
|
||||
|
@ -1379,11 +1511,7 @@ setoptions(Ether *edev)
|
|||
int i;
|
||||
|
||||
ctlr = edev->ctlr;
|
||||
ctlr->channel = 3;
|
||||
for(i = 0; i < edev->nopt; i++){
|
||||
if(strncmp(edev->opt[i], "channel=", 8) == 0)
|
||||
ctlr->channel = atoi(edev->opt[i]+8);
|
||||
else
|
||||
if(strncmp(edev->opt[i], "essid=", 6) == 0){
|
||||
snprint(buf, sizeof(buf), "essid %s", edev->opt[i]+6);
|
||||
if(!waserror()){
|
||||
|
@ -1394,9 +1522,78 @@ setoptions(Ether *edev)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
iwlpromiscuous(void *arg, int on)
|
||||
{
|
||||
Ether *edev;
|
||||
Ctlr *ctlr;
|
||||
|
||||
edev = arg;
|
||||
ctlr = edev->ctlr;
|
||||
qlock(ctlr);
|
||||
ctlr->prom = on;
|
||||
if(ctlr->prom)
|
||||
rxon(edev, nil);
|
||||
else
|
||||
rxon(edev, ctlr->wifi->bss);
|
||||
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);
|
||||
tsleep(&up->sleep, return0, 0, 1000);
|
||||
}
|
||||
|
||||
/* wait for association */
|
||||
setled(ctlr, 2, 10, 10);
|
||||
while((bss = wifi->bss) != nil){
|
||||
if(bss->aid != 0)
|
||||
break;
|
||||
tsleep(&up->sleep, return0, 0, 1000);
|
||||
}
|
||||
|
||||
if(bss == nil)
|
||||
continue;
|
||||
|
||||
/* wait for disassociation */
|
||||
edev->link = 1;
|
||||
setled(ctlr, 2, 0, 1);
|
||||
while((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;
|
||||
|
@ -1528,12 +1725,16 @@ iwlattach(Ether *edev)
|
|||
bootfirmware(ctlr);
|
||||
postboot(ctlr);
|
||||
|
||||
ctlr->bcastnodeid = -1;
|
||||
ctlr->bssnodeid = -1;
|
||||
ctlr->channel = 1;
|
||||
ctlr->aid = 0;
|
||||
|
||||
setoptions(edev);
|
||||
|
||||
rxon(edev, nil);
|
||||
snprint(name, sizeof(name), "#l%diwl", edev->ctlrno);
|
||||
kproc(name, iwlproc, edev);
|
||||
|
||||
edev->prom = 1;
|
||||
edev->link = 1;
|
||||
ctlr->attached = 1;
|
||||
}
|
||||
qunlock(ctlr);
|
||||
|
@ -1783,7 +1984,7 @@ again:
|
|||
edev->attach = iwlattach;
|
||||
edev->ifstat = iwlifstat;
|
||||
edev->ctl = iwlctl;
|
||||
edev->promiscuous = nil;
|
||||
edev->promiscuous = iwlpromiscuous;
|
||||
edev->multicast = nil;
|
||||
edev->mbps = 10;
|
||||
|
||||
|
|
|
@ -121,6 +121,7 @@ trap.$O: /sys/include/tos.h
|
|||
uartaxp.$O: uartaxp.i
|
||||
etherm10g.$O: etherm10g2k.i etherm10g4k.i
|
||||
etheriwl.$O: wifi.h
|
||||
wifi.$O: wifi.h
|
||||
|
||||
init.h:D: ../port/initcode.c init9.c
|
||||
$CC ../port/initcode.c
|
||||
|
|
|
@ -93,12 +93,12 @@ drop:
|
|||
}
|
||||
|
||||
static void
|
||||
wifitx(Wifi *wifi, Block *b)
|
||||
wifitx(Wifi *wifi, Wnode *wn, Block *b)
|
||||
{
|
||||
Wifipkt *w;
|
||||
uint seq;
|
||||
|
||||
seq = wifi->txseq++;
|
||||
seq = incref(&wifi->txseq);
|
||||
seq <<= 4;
|
||||
|
||||
w = (Wifipkt*)b->rp;
|
||||
|
@ -107,7 +107,7 @@ wifitx(Wifi *wifi, Block *b)
|
|||
w->seq[0] = seq;
|
||||
w->seq[1] = seq>>8;
|
||||
|
||||
(*wifi->transmit)(wifi, wifi->bss, b);
|
||||
(*wifi->transmit)(wifi, wn, b);
|
||||
}
|
||||
|
||||
|
||||
|
@ -118,18 +118,29 @@ nodelookup(Wifi *wifi, uchar *bssid, int new)
|
|||
|
||||
if(memcmp(bssid, wifi->ether->bcast, Eaddrlen) == 0)
|
||||
return nil;
|
||||
for(wn = nn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
|
||||
if((wn = wifi->bss) != nil){
|
||||
if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){
|
||||
wn->lastseen = MACHP(0)->ticks;
|
||||
return wn;
|
||||
}
|
||||
if(wn != wifi->bss && wn->lastseen < nn->lastseen)
|
||||
}
|
||||
for(wn = nn = wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
|
||||
if(wn == wifi->bss)
|
||||
continue;
|
||||
if(memcmp(wn->bssid, bssid, Eaddrlen) == 0){
|
||||
wn->lastseen = MACHP(0)->ticks;
|
||||
return wn;
|
||||
}
|
||||
if(wn->lastseen < nn->lastseen)
|
||||
nn = wn;
|
||||
}
|
||||
if(!new)
|
||||
return nil;
|
||||
memmove(nn->bssid, bssid, Eaddrlen);
|
||||
nn->lastseen = MACHP(0)->ticks;
|
||||
nn->channel = 0;
|
||||
nn->cap = 0;
|
||||
nn->aid = 0;
|
||||
return nn;
|
||||
}
|
||||
|
||||
|
@ -156,7 +167,7 @@ sendauth(Wifi *wifi, Wnode *bss)
|
|||
*p++ = 0; /* status */
|
||||
*p++ = 0;
|
||||
b->wp = p;
|
||||
wifitx(wifi, b);
|
||||
wifitx(wifi, bss, b);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -190,7 +201,7 @@ sendassoc(Wifi *wifi, Wnode *bss)
|
|||
*p++ = 0x8b;
|
||||
*p++ = 0x96;
|
||||
b->wp = p;
|
||||
wifitx(wifi, b);
|
||||
wifitx(wifi, bss, b);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -210,13 +221,14 @@ recvassoc(Wifi *wifi, Wnode *wn, uchar *d, int len)
|
|||
wifi->status = Sassoc;
|
||||
break;
|
||||
default:
|
||||
wn->aid = 0;
|
||||
wifi->status = Sunassoc;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len)
|
||||
recvbeacon(Wifi *, Wnode *wn, uchar *d, int len)
|
||||
{
|
||||
uchar *e, *x;
|
||||
uchar t, m[256/8];
|
||||
|
@ -251,11 +263,6 @@ recvbeacon(Wifi *wifi, Wnode *wn, uchar *d, int len)
|
|||
if(len != strlen(wn->ssid) || strncmp(wn->ssid, (char*)d, len) != 0){
|
||||
strncpy(wn->ssid, (char*)d, len);
|
||||
wn->ssid[len] = 0;
|
||||
if(wifi->bss == nil && strcmp(wifi->essid, wn->ssid) == 0){
|
||||
wifi->bss = wn;
|
||||
wifi->status = Sconn;
|
||||
sendauth(wifi, wn);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3: /* DSPARAMS */
|
||||
|
@ -289,6 +296,11 @@ wifiproc(void *arg)
|
|||
continue;
|
||||
b->rp += WIFIHDRSIZE;
|
||||
recvbeacon(wifi, wn, b->rp, BLEN(b));
|
||||
if(wifi->bss == nil && wifi->essid[0] != 0 && strcmp(wifi->essid, wn->ssid) == 0){
|
||||
wifi->bss = wn;
|
||||
wifi->status = Sconn;
|
||||
sendauth(wifi, wn);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if((wn = nodelookup(wifi, w->a3, 0)) == nil)
|
||||
|
@ -306,7 +318,9 @@ wifiproc(void *arg)
|
|||
sendassoc(wifi, wn);
|
||||
break;
|
||||
case 0xc0: /* deauth */
|
||||
wn->aid = 0;
|
||||
wifi->status = Sunauth;
|
||||
sendauth(wifi, wn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -318,6 +332,7 @@ wifietheroq(Wifi *wifi, Block *b)
|
|||
{
|
||||
Etherpkt e;
|
||||
Wifipkt *w;
|
||||
Wnode *bss;
|
||||
SNAP *s;
|
||||
|
||||
if(BLEN(b) < ETHERHDRSIZE){
|
||||
|
@ -332,7 +347,8 @@ wifietheroq(Wifi *wifi, Block *b)
|
|||
w = (Wifipkt*)b->rp;
|
||||
w->fc[0] = 0x08; /* data */
|
||||
w->fc[1] = 0x01; /* STA->AP */
|
||||
memmove(w->a1, wifi->bss ? wifi->bss->bssid : wifi->ether->bcast, Eaddrlen);
|
||||
bss = wifi->bss;
|
||||
memmove(w->a1, bss != nil ? bss->bssid : wifi->ether->bcast, Eaddrlen);
|
||||
memmove(w->a2, e.s, Eaddrlen);
|
||||
memmove(w->a3, e.d, Eaddrlen);
|
||||
|
||||
|
@ -344,7 +360,7 @@ wifietheroq(Wifi *wifi, Block *b)
|
|||
s->orgcode[2] = 0;
|
||||
memmove(s->type, e.type, 2);
|
||||
|
||||
wifitx(wifi, b);
|
||||
wifitx(wifi, bss, b);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -364,6 +380,7 @@ wifoproc(void *arg)
|
|||
Wifi*
|
||||
wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
|
||||
{
|
||||
char name[32];
|
||||
Wifi *wifi;
|
||||
|
||||
wifi = malloc(sizeof(Wifi));
|
||||
|
@ -372,8 +389,10 @@ wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*))
|
|||
wifi->transmit = transmit;
|
||||
wifi->status = Snone;
|
||||
|
||||
kproc("wifi", wifiproc, wifi);
|
||||
kproc("wifo", wifoproc, wifi);
|
||||
snprint(name, sizeof(name), "#l%dwifi", ether->ctlrno);
|
||||
kproc(name, wifiproc, wifi);
|
||||
snprint(name, sizeof(name), "#l%dwifo", ether->ctlrno);
|
||||
kproc(name, wifoproc, wifi);
|
||||
|
||||
return wifi;
|
||||
}
|
||||
|
@ -392,7 +411,6 @@ wifictl(Wifi *wifi, void *buf, long n)
|
|||
cb = parsecmd(buf, n);
|
||||
if(cb->f[0] && strcmp(cb->f[0], "essid") == 0){
|
||||
if(cb->f[1] == nil){
|
||||
/* TODO senddeauth(wifi); */
|
||||
wifi->essid[0] = 0;
|
||||
wifi->bss = nil;
|
||||
} else {
|
||||
|
@ -425,7 +443,8 @@ wifistat(Wifi *wifi, void *buf, long n, ulong off)
|
|||
|
||||
p = seprint(p, e, "status: %s\n", wifi->status);
|
||||
p = seprint(p, e, "essid: %s\n", wifi->essid);
|
||||
p = seprint(p, e, "bssid: %E\n", wifi->bss ? wifi->bss->bssid : zeros);
|
||||
wn = wifi->bss;
|
||||
p = seprint(p, e, "bssid: %E\n", wn != nil ? wn->bssid : zeros);
|
||||
|
||||
now = MACHP(0)->ticks;
|
||||
for(wn=wifi->node; wn != &wifi->node[nelem(wifi->node)]; wn++){
|
||||
|
|
|
@ -34,13 +34,13 @@ struct Wifi
|
|||
|
||||
Queue *iq;
|
||||
char *status;
|
||||
Ref txseq;
|
||||
void (*transmit)(Wifi*, Wnode*, Block*);
|
||||
|
||||
Wnode node[16];
|
||||
char essid[32+2];
|
||||
Wnode *bss;
|
||||
|
||||
uint txseq;
|
||||
char essid[32+2];
|
||||
Wnode node[32];
|
||||
};
|
||||
|
||||
Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*));
|
||||
|
|
Loading…
Reference in a new issue