~kris/9p

9hist

78b5d7ace619ad57ba6254e770fa76b5b968e6e3 — David du Colombier 25 years ago 3438ed0
Plan 9 from Bell Labs 2001-02-01
2 files changed, 121 insertions(+), 260 deletions(-)

M pc/devusb.c
M pc/etherwavelan.c
M pc/devusb.c => pc/devusb.c +1 -1
@@ 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);

M pc/etherwavelan.c => pc/etherwavelan.c +120 -259
@@ 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; i<WTmOut; i++){
		rc = csr_ins(ctlr, WR_EvSts);


@@ 389,7 387,6 @@ w_outltv(Ctlr* ctlr, Wltv* l)
{
	int i,len;
	ushort *p;
delay(100);

	if (w_seek(ctlr,l->type,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 <WNKeys; i++){
		// BUG: despite the checks, this seems to get nothing;
		// although it could be that the card
		// does not allow reading keys for security.
		if (l.key[id].len != 0){
			DEBUG("len=%d ", l.key[id].len);
		}
		if (l.key[id].dat[1] != 0){
			DEBUG("dat1=%s ", l.key[id].dat+1);
		} 
		if (l.key[id].dat[2] != 0){
			DEBUG("dat2=%s ", l.key[id].dat+2);
		} 
		if (l.key[id].dat[0] != 0){
			DEBUG("%s ", l.key[id].dat);
		} 
//		else 
//			DEBUG("none ");
	}
	DEBUG("\n");
	if (l.key[id].dat[0] == 0)
		return Nilname;
	len = l.key[id].len;
	if (len > 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;