From 78b5d7ace619ad57ba6254e770fa76b5b968e6e3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 1 Feb 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-02-01 --- pc/devusb.c | 2 +- pc/etherwavelan.c | 379 +++++++++++++++------------------------------- 2 files changed, 121 insertions(+), 260 deletions(-) diff --git a/pc/devusb.c b/pc/devusb.c index a28ed4ef492d988cede2b62d8fe6699f5ab6b633..869824383b4dbfa105feb39ced136b9a165ae830 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -1312,7 +1312,7 @@ usbreset(void) ub->bwsop = allocqh(ub); ub->bulkq = allocqh(ub); ub->recvq = allocqh(ub); -if(0){ /* DISABLE ERRATA FOR NOW */ +if(0){ t = alloctd(ub); /* inactive TD, looped */ t->link = PADDR(t); ub->bwsop->entries = PADDR(t); diff --git a/pc/etherwavelan.c b/pc/etherwavelan.c index b49a53dac1a08870af40ac143dde60b33fa4dd45..cc338188e7b9c653fc245fd6eb8b2498aff8fec3 100644 --- a/pc/etherwavelan.c +++ b/pc/etherwavelan.c @@ -236,7 +236,7 @@ struct Wltv char name[WNameLen]; }; struct { - WKey key[WNKeys]; + WKey keys[WNKeys]; }; }; }; @@ -284,9 +284,11 @@ struct Ctlr uchar txbuf[1536]; int txlen; - int keyid; // 0 if not using WEP - int xclear; - WKey key[WNKeys]; + int hascrypt; // card has encryption + int crypt; // encryption off/on + int txkey; // transmit key + Wltv keys; // default keys + int xclear; // exclude clear packets off/on Stats; WStats; @@ -314,11 +316,7 @@ w_cmd(Ctlr *ctlr, ushort cmd, ushort arg) int i; int rc; -if(csr_ins(ctlr, WR_Cmd) & WCmdBusy) - print("busy\n"); csr_outs(ctlr, WR_Parm0, arg); - csr_outs(ctlr, WR_Parm1, 0); - csr_outs(ctlr, WR_Parm2, 0); csr_outs(ctlr, WR_Cmd, cmd); for (i = 0; itype,0,1)) return; @@ -406,7 +403,6 @@ static void ltv_outs(Ctlr* ctlr, int type, ushort val) { Wltv l; -delay(100); l.type = type; l.val = val; @@ -431,7 +427,6 @@ ltv_outstr(Ctlr* ctlr, int type, char *val) { Wltv l; int len; -delay(100); len = strlen(val); if(len > sizeof(l.s)) @@ -462,55 +457,6 @@ ltv_inname(Ctlr* ctlr, int type) return l.name+2; } - -static char* -ltv_inkey(Ctlr* ctlr, int id) -{ - static char k[WKeyLen+1]; - Wltv l; - int i, len; - - id--; - memset(&l, 0, sizeof(l)); - l.type = WTyp_Keys; - l.len = sizeof(l.key)/2 + 2; // BUG? - if (w_inltv(ctlr, &l)) - return Unkname; - if (id <0 || id >=WNKeys){ - DEBUG("wavelan: ltv_inkey: bad key id\n"); - return Unkname; - } - for (i=0 ; i WKeyLen) - len = WKeyLen; - memset(k, 0, sizeof(k)); - memmove(k, l.key[id].dat, len); - k[WKeyLen] = 0; - return k; -} - static int w_read(Ctlr* ctlr, int type, int off, void* buf, ulong len) { @@ -589,7 +535,6 @@ w_enable(Ether* ether) { Wltv l; Ctlr* ctlr = (Ctlr*) ether->ctlr; - ushort wep; if (!ctlr) return -1; @@ -597,7 +542,6 @@ w_enable(Ether* ether) w_intdis(ctlr); w_cmd(ctlr, WCmdDis, 0); w_intdis(ctlr); -delay(100); if(w_cmd(ctlr, WCmdIni, 0)) return -1; w_intdis(ctlr); @@ -624,24 +568,12 @@ delay(100); ltv_outs(ctlr, WTyp_Prom, (ether->prom?1:0)); - wep = ltv_ins(ctlr, WTyp_HasCrypt); - if (wep) - if (ctlr->keyid == 0) - ltv_outs(ctlr, WTyp_Crypt, 0); - else { - // BUG? - // I think it's ok, but don't know if - // the card needs a WEPing access point - // just to admit the keys. - ltv_outs(ctlr, WTyp_TxKey, ctlr->keyid); - memset(&l, 0, sizeof(l)); - l.len = sizeof(ctlr->key[0])*WNKeys/2 + 1; - l.type= WTyp_Keys; - memmove(l.key, &ctlr->key[0], sizeof(l.key[0])*WNKeys); - w_outltv(ctlr, &l); - ltv_outs(ctlr, WTyp_Crypt, wep); - ltv_outs(ctlr, WTyp_XClear, ctlr->xclear); - } + if (ctlr->hascrypt){ + ltv_outs(ctlr, WTyp_Crypt, ctlr->crypt); + ltv_outs(ctlr, WTyp_TxKey, ctlr->txkey); + w_outltv(ctlr, &ctlr->keys); + ltv_outs(ctlr, WTyp_XClear, ctlr->xclear); + } // BUG: set multicast addresses @@ -938,18 +870,6 @@ w_timer(void* arg) pexit("terminated",0); } -static void* -emalloc(ulong size) -{ - void *r=malloc(size); - if (!r) - error(Enomem); - memset(r,0,size); - return r; -} - - - static void multicast(void*, uchar*, int) { @@ -1010,18 +930,16 @@ ifstat(Ether* ether, void* a, long n, ulong offset) k = ((ctlr->txbusy)? ", txbusy" : ""); PRINTSTAT("%s\n", k); - if (ctlr->keyid){ + if (ctlr->txkey){ PRINTSTR("Keys: "); - for (i = 0; i < WNKeys; i++) - if (ctlr->key[i].len == 0) + for (i = 0; i < WNKeys; i++){ + if (ctlr->keys.keys[i].len == 0) PRINTSTR("none "); - else { - if (SEEKEYS == 0) - PRINTSTR("set "); - else { - PRINTSTAT("%s ", ctlr->key[i].dat); - } - } + else if (SEEKEYS == 0) + PRINTSTR("set "); + else + PRINTSTAT("%s ", ctlr->keys.keys[i].dat); + } PRINTSTR("\n"); } @@ -1054,11 +972,6 @@ ifstat(Ether* ether, void* a, long n, ulong offset) PRINTSTAT("Clear packets: %s\n", k); txid = ltv_ins(ctlr, WTyp_TxKey); PRINTSTAT("Transmit key id: %d\n", txid); - if (txid >= 1 && txid <= WNKeys){ - k = ltv_inkey(ctlr, txid); - if (SEEKEYS && k != nil) - PRINTSTAT("Transmit key: %s\n", k); - } } } iunlock(&ctlr->Lock); @@ -1092,96 +1005,85 @@ ifstat(Ether* ether, void* a, long n, ulong offset) #undef PRINTSTR #undef PRINTSTAT - -static long -ctl(Ether* ether, void* buf, long n) +static int +option(Ctlr* ctlr, char* buf, long n) { - int i, key; - Ctlr *ctlr; + char *p; + int i, r; + WKey *key; Cmdbuf *cb; - char *nessid; - WKey *kp; - char k[64]; - char *kn= &k[3]; - if((ctlr = ether->ctlr) == nil) - error(Enonexist); - if(ctlr->attached == 0) - error(Eshutdown); + r = 0; cb = parsecmd(buf, n); - if(cb->nf < 2) - error(Ebadctl); - - ilock(&ctlr->Lock); - if(waserror()){ - iunlock(&ctlr->Lock); - free(cb); - nexterror(); - } - - if(strcmp(cb->f[0], "essid") == 0){ - if (strcmp(cb->f[1],"default") == 0) - nessid = ""; + r = -1; + else if(cistrcmp(cb->f[0], "essid") == 0){ + if (cistrcmp(cb->f[1],"default") == 0) + p = ""; else - nessid = cb->f[1]; - if (ctlr->ptype == 3){ + p = cb->f[1]; + if(ctlr->ptype == 3){ memset(ctlr->netname, 0, sizeof(ctlr->netname)); - strncpy(ctlr->netname, nessid, WNameLen); + strncpy(ctlr->netname, p, WNameLen); } - else { + else{ memset(ctlr->wantname, 0, sizeof(ctlr->wantname)); - strncpy(ctlr->wantname, nessid, WNameLen); + strncpy(ctlr->wantname, p, WNameLen); } } - else if(strcmp(cb->f[0], "station_name") == 0){ + else if(cistrcmp(cb->f[0], "station") == 0){ memset(ctlr->nodename, 0, sizeof(ctlr->nodename)); strncpy(ctlr->nodename, cb->f[1], WNameLen); } - else if(strcmp(cb->f[0], "channel") == 0){ + else if(cistrcmp(cb->f[0], "channel") == 0){ i = atoi(cb->f[1]); - if(i < 1 || i > 16 ) - error("channel not in [1-16]\n"); - ctlr->chan = i; + if(i >= 1 && i <= 16 ) + ctlr->chan = i; + else + r = -1; } - else if(strcmp(cb->f[0], "ptype") == 0){ + else if(cistrcmp(cb->f[0], "mode") == 0){ i = atoi(cb->f[1]); - if(i < 1 || i > 3 ) - error("port type not in [1-3]"); - ctlr->ptype = i; + if(i >= 1 && i <= 3 ) + ctlr->ptype = i; + else + r = -1; } - else if(strncmp(cb->f[0], "key", 3) == 0){ - strncpy(k,cb->f[0],64); - if (strcmp(cb->f[1], "off") == 0) - ctlr->keyid = 0; - else if (strcmp(cb->f[1], "exclude") == 0){ - ctlr->xclear = 1; - } - else if (strcmp(cb->f[1], "include") == 0){ + else if(cistrcmp(cb->f[0], "crypt") == 0){ + if(cistrcmp(cb->f[1], "off") == 0) + ctlr->crypt = 0; + else if(cistrcmp(cb->f[1], "on") == 0 && ctlr->hascrypt) + ctlr->crypt = 1; + else + r = -1; + } + else if(cistrcmp(cb->f[0], "clear") == 0){ + if(cistrcmp(cb->f[1], "on") == 0) ctlr->xclear = 0; + else if(cistrcmp(cb->f[1], "off") == 0 && ctlr->hascrypt) + ctlr->xclear = 1; + else + r = -1; + } + else if(cistrncmp(cb->f[0], "key", 3) == 0){ + i = atoi(cb->f[0]+3); + if(i >= 1 && i <= WNKeys){ + ctlr->txkey = i-1; + key = &ctlr->keys.keys[ctlr->txkey]; + key->len = strlen(cb->f[1]); + if (key->len > WKeyLen) + key->len = WKeyLen; + memset(key->dat, 0, sizeof(key->dat)); + memmove(key->dat, cb->f[1], key->len); } - else { - key = atoi(kn); - if (key < 1 || key > WNKeys) - error("key not in [1-4]"); - ctlr->keyid = key; - kp = &ctlr->key[key-1]; - kp->len = strlen(cb->f[1]); -// if (kp->len > WKeyLen) - kp->len = WKeyLen; - memset(kp->dat, 0, sizeof(kp->dat)); - strncpy(kp->dat, cb->f[1], kp->len); -// if (kp->len > WMinKeyLen) -// kp->len = WKeyLen; -// else if (kp->len > 0) -// kp->len = WMinKeyLen; - } + else + r = -1; } - else if(strcmp(cb->f[0], "pm") == 0){ - if(strcmp(cb->f[1], "off") == 0) + else if(cistrcmp(cb->f[0], "pm") == 0){ + if(cistrcmp(cb->f[1], "off") == 0) ctlr->pmena = 0; - else if(strcmp(cb->f[1], "on") == 0){ + else if(cistrcmp(cb->f[1], "on") == 0){ ctlr->pmena = 1; if(cb->nf == 3){ i = atoi(cb->f[2]); @@ -1190,18 +1092,34 @@ ctl(Ether* ether, void* buf, long n) } } else - error(Ebadctl); + r = -1; } else - error(Ebadctl); + r = -2; + free(cb); + return r; +} + +static long +ctl(Ether* ether, void* buf, long n) +{ + Ctlr *ctlr; + + if((ctlr = ether->ctlr) == nil) + error(Enonexist); + if(ctlr->attached == 0) + error(Eshutdown); + + ilock(&ctlr->Lock); + if(option(ctlr, buf, n)){ + iunlock(&ctlr->Lock); + error(Ebadctl); + } if(ctlr->txbusy) w_txdone(ctlr, WTxErrEv|1); // retry tx later. w_enable(ether); - iunlock(&ctlr->Lock); - poperror(); - free(cb); return n; } @@ -1251,91 +1169,22 @@ interrupt(Ureg* ,void* arg) iunlock(&ctlr->Lock); } -static void -setopt(Ctlr* ctlr, char* opt, int no) -{ - int i; - char k[64], *ke, *nessid; - char *kn = &k[3]; - WKey *kp; - int key; - - if (strncmp(opt,"essid=",6) == 0){ - if (strcmp(opt+6, "default") == 0) - nessid = ""; - else - nessid = opt+6; - if (ctlr->ptype == 3){ - memset(ctlr->netname, 0, sizeof(ctlr->netname)); - strncpy(ctlr->netname, nessid, WNameLen); - } - else{ - memset(ctlr->wantname, 0, sizeof(ctlr->wantname)); - strncpy(ctlr->wantname, nessid, WNameLen); - } - } - else if (strncmp(opt,"station_name=",13) == 0){ - // The max. length of an 'opt' is ISAOPTLEN in dat.h. - // It should be > 16 to give reasonable name lengths. - memset(ctlr->nodename, 0, sizeof(ctlr->nodename)); - strncpy(ctlr->nodename, opt+13,WNameLen); - } - else if (strncmp(opt, "channel=",8) == 0){ - i = atoi(opt+8); - if(i < 1 || i > 16 ) - print("#l%d: channel (%d) not in [1-16]\n",no,i); - else - ctlr->chan = i; - } - else if (strncmp(opt, "ptype=",6) == 0){ - i = atoi(opt+6); - if(i < 1 || i > 3 ) - print("#l%d: port type (%d) not in [1-3]\n",no,i); - else - ctlr->ptype = i; - } - else if (strncmp(opt, "key", 3) == 0){ - if (opt[3] == 0 || opt[4] != '='){ - print("#l%d: key option is not keyX=xxxx\n", no); - return; - } - strncpy(k,opt,64); - key = atoi(kn); - if (key < 1 || key > WNKeys){ - print("#l%d: key number (%d) not in [1-%d]\n", - no, key, WNKeys); - return; - } - ctlr->keyid = key; - kp = &ctlr->key[key-1]; - ke = opt+5; - while (*ke && *ke != ' ' && *ke != '\n' && *ke != '\t') - ke++; - kp->len = ke - (opt+5); - if (kp->len > WKeyLen) - kp->len = WKeyLen; - memset(kp->dat, 0, sizeof(kp->dat)); - strncpy(kp->dat, opt+5, kp->len); -// if (kp->len > WMinKeyLen) -// kp->len = WKeyLen; -// else if (kp->len > 0) -// kp->len = WMinKeyLen; - } -} - static int reset(Ether* ether) { - Ctlr* ctlr; - Wltv ltv; int i; + Wltv ltv; + Ctlr* ctlr; + char buf[ISAOPTLEN], *p; if (ether->ctlr){ print("#l%d: only one card supported\n", ether->ctlrno); return -1; } - ether->arg = ctlr = (Ctlr*)emalloc(sizeof(Ctlr)); + if((ctlr = malloc(sizeof(Ctlr))) == nil) + return -1; + ilock(&ctlr->Lock); if (ether->port==0) @@ -1351,13 +1200,23 @@ reset(Ether* ether) ether->ctlrno, ether->port, ether->irq); ctlr->chan = 0; - ctlr->ptype= WDfltPType; - ctlr->keyid= 0; + ctlr->ptype = WDfltPType; + ctlr->txkey = 0; + ctlr->keys.len = sizeof(WKey)*WNKeys/2 + 1; + ctlr->keys.type = WTyp_Keys; *ctlr->netname = *ctlr->wantname = 0; strcpy(ctlr->nodename, "wvlancard"); - for (i=0; i < ether->nopt; i++) - setopt(ctlr, ether->opt[i], ether->ctlrno); + for(i = 0; i < ether->nopt; i++){ + // + // The max. length of an 'opt' is ISAOPTLEN in dat.h. + // It should be > 16 to give reasonable name lengths. + // + strcpy(buf, ether->opt[i]); + if(p = strchr(buf, '=')) + *p = ' '; + option(ctlr, buf, strlen(buf)); + } ctlr->netname[WNameLen-1] = 0; ctlr->wantname[WNameLen-1] = 0; @@ -1370,7 +1229,6 @@ reset(Ether* ether) } w_intdis(ctlr); -delay(500); if (w_cmd(ctlr,WCmdIni,0)){ print("#l%d: init failed\n", ether->ctlrno); goto abort; @@ -1399,6 +1257,9 @@ delay(500); ctlr->maxlen = WMaxLen; ctlr->pmena = 0; ctlr->pmwait= 100; + if(ctlr->hascrypt = ltv_ins(ctlr, WTyp_HasCrypt)) + ctlr->crypt = 1; + // link to ether ether->ctlr = ctlr; ether->mbps = 10;