OK, turing.

<- leave blank

Wed Jun 7 17:39:17 EDT 2023

diff 46bac13b16df5cbd92ea1da12cfef168201f0dad uncommitted
--- a/sys/src/9/pc/etherrt2860.c
+++ b/sys/src/9/pc/etherrt2860.c
@@ -1251,23 +1251,7 @@
 static void selchangroup(Ctlr*, int);
 static void setleds(Ctlr*, u16int);

-static uint
-get16(uchar *p){
- return *((u16int*)p);
-}
-static uint
-get32(uchar *p){
- return *((u32int*)p);
-}
 static void
-put32(uchar *p, uint v){
- *((u32int*)p) = v;
-}
-static void
-put16(uchar *p, uint v){
- *((u16int*)p) = v;
-};
-static void
 memwrite(Ctlr *ctlr, u32int off, uchar *data, uint size){
	memmove((uchar*)ctlr->nic + off, data, size);
 }
@@ -2562,7 +2546,7 @@
 {
	Ether *edev;
	Ctlr *ctlr;
- Wifipkt *w;
+ Wframe w;
	u8int mcs, qid;
	int ridx, /*ctl_ridx,*/ hdrlen;
	uchar *p;
@@ -2596,17 +2580,15 @@
	tx = &ctlr->tx[qid];

	nodeid = ctlr->bcastnodeid;
- w = (Wifipkt*)b->rp;
- hdrlen = wifihdrlen(w);
-
+ hdrlen = wifiunpack(&w, b->rp);
	p = pool->p + pool->i * TxwiDmaSz;
- if((w->a1[0] & 1) == 0){
+ if((w.a1[0] & 1) == 0){
		*(p+4) = TxAck; /* xflags */

		if(BLEN(b) > 512-4)
			*(p+1) = TxTxopBackoff; /* txop */

- if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
+ if((w.fc[0] & Wfc0typemask) == Wfc0typedat && ctlr->bssnodeid != -1){
			nodeid = ctlr->bssnodeid;
			ridx = 2; /* BUG: hardcode 11Mbit */
		}
@@ -2652,11 +2634,8 @@
	/* setup payload segments */
	put32(p + 8, PCIWADDR(outb->rp)); /* sdp1 */
	put16(p + 4, BLEN(outb) | TxLs1); /* sdl1 */
-
- p = pool->p + pool->i * TxwiDmaSz;
- w = (Wifipkt*)(p + Txwisize);
	if(ctlr->wifi->debug){
- print("transmit: %E->%E,%E nodeid=%x txq[%d]=%d size=%zd\n", w->a2,
w->a1, w->a3, nodeid, qid, ctlr->tx[qid].i, BLEN(outb));
+ print("transmit: %E->%E,%E nodeid=%x txq[%d]=%d size=%zd\n", w.a2, w.a1,
w.a3, nodeid, qid, ctlr->tx[qid].i, BLEN(outb));
	}

	tx->i = (tx->i + 1) % Ntx;
@@ -2730,7 +2709,7 @@
		u16int sdl0, len;
		u32int flags;
		uchar *p;
- Wifipkt *w;
+ Wframe w;
		int hdrlen;

		p = (uchar*)rx->p + Rdscsize * rx->i;
@@ -2761,16 +2740,15 @@
		len = get16(b->rp + 2 /* wcid, keyidx */) & 0xfff;
		b->rp = d + Rxwisize;
		b->wp = b->rp + len;
- w = (Wifipkt*)b->rp;
- hdrlen = wifihdrlen(w);
+ hdrlen = wifiunpack(&w, b->rp);
		/* HW may insert 2 padding bytes after 802.11 header */
		if(flags & RxL2pad){
			memmove(b->rp + 2, b->rp, hdrlen);
			b->rp += 2;
		}
- w = (Wifipkt*)b->rp;
+ wifiunpack(&w, b->rp);
		if(ctlr->wifi->debug)
- print("receive: %E->%E,%E wcid 0x%x \n", w->a2, w->a1, w->a3,
ctlr->wcid);
+ print("receive: %E->%E,%E wcid 0x%x \n", w.a2, w.a1, w.a3, ctlr->wcid);
		wifiiq(ctlr->wifi, b);
 skip:
		put16(p + 4 /* sdp0 */ + 2 /* sdl1 */, sdl0 & ~RxDdone);
--- a/sys/src/9/pc/etherwpi.c
+++ b/sys/src/9/pc/etherwpi.c
@@ -290,24 +290,6 @@
 #define csr32r(c, r) (*((c)->nic+((r)/4)))
 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))

-static uint
-get32(uchar *p){
- return *((u32int*)p);
-}
-static uint
-get16(uchar *p)
-{
- return *((u16int*)p);
-}
-static void
-put32(uchar *p, uint v){
- *((u32int*)p) = v;
-}
-static void
-put16(uchar *p, uint v){
- *((u16int*)p) = v;
-};
-
 static char*
 niclock(Ctlr *ctlr)
 {
@@ -1402,7 +1384,7 @@
	uchar c[Tcmdsize], *p;
	Ether *edev;
	Ctlr *ctlr;
- Wifipkt *w;
+ Wframe w;
	int flags, nodeid, rate, timeout;
	char *err;

@@ -1430,14 +1412,15 @@
	timeout = 3;
	nodeid = ctlr->bcastnodeid;
	p = wn->minrate;
- w = (Wifipkt*)b->rp;
- if((w->a1[0] & 1) == 0){
+
+ wifiunpack(&w, b->rp);
+ if((w.a1[0] & 1) == 0){
		flags |= TFlagNeedACK;

		if(BLEN(b) > 512-4)
			flags |= TFlagNeedRTS|TFlagFullTxOp;

- if((w->fc[0] & 0x0c) == 0x08 && ctlr->bssnodeid != -1){
+ if((w.fc[0] & Wfc0typemask) == Wfc0typedat && ctlr->bssnodeid != -1){
			timeout = 0;
			nodeid = ctlr->bssnodeid;
			p = wn->actrate;
--- a/sys/src/9/port/etheriwl.c
+++ b/sys/src/9/port/etheriwl.c
@@ -722,28 +722,6 @@
 #define csr32r(c, r) (*((c)->nic+((r)/4)))
 #define csr32w(c, r, v) (*((c)->nic+((r)/4)) = (v))

-static uint
-get16(uchar *p){
- return *((u16int*)p);
-}
-static uint
-get32(uchar *p){
- return *((u32int*)p);
-}
-static void
-put32(uchar *p, uint v){
- *((u32int*)p) = v;
-}
-static void
-put64(uchar *p, uvlong v)
-{
- *((u64int*)p) = v;
-}
-static void
-put16(uchar *p, uint v){
- *((u16int*)p) = v;
-};
-
 static char*
 niclock(Ctlr *ctlr)
 {
@@ -1692,12 +1670,13 @@
	coherence();
	ctlr->rx.b[i] = b;

- if(ctlr->mqrx)
+ if(ctlr->mqrx) {
		put64(ctlr->rx.p + (i<<3), PCIWADDR(b->rp));
- else
+ } else {
		put32(ctlr->rx.p + (i<<2), PCIWADDR(b->rp) >>
		8);
- dmaflush(1, ctlr->rx.p + i*ctlr->rx.psz, ctlr->rx.psz);
+ }

+ dmaflush(1, ctlr->rx.p + i*ctlr->rx.psz, ctlr->rx.psz);
	return 0;
 }

@@ -3839,7 +3818,7 @@
	Ether *edev;
	Station *sta;
	Ctlr *ctlr;
- Wifipkt *w;
+ Wframe w;
	char *err;

	edev = wifi->ether;
@@ -3876,14 +3855,15 @@
	flags = 0;
	sta = &ctlr->bcast;
	p = wn->minrate;
- w = (Wifipkt*)b->rp;
- if((w->a1[0] & 1) == 0){
+
+ wifiunpack(&w, b->rp);
+ if((w.a1[0] & 1) == 0){
		flags |= TFlagNeedACK;

		if(BLEN(b) > 512-4)
			flags |= TFlagNeedRTS;

- if((w->fc[0] & 0x0c) == 0x08 && ctlr->bss.id != -1){
+ if((w.fc[0] & 0x0c) == 0x08 && ctlr->bss.id != -1){
			sta = &ctlr->bss;
			p = wn->actrate;
		}
--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -135,12 +135,13 @@
 /* flag values */
 enum
 {
- BINTR = (1<<0),
- BFREE = (1<<1),
- Bipck = (1<<2), /* ip checksum */
- Budpck = (1<<3), /* udp checksum */
- Btcpck = (1<<4), /* tcp checksum */
- Bpktck = (1<<5), /* packet checksum */
+ BINTR = (1<<0),
+ BFREE = (1<<1),
+ Bipck = (1<<2), /* ip checksum */
+ Budpck = (1<<3), /* udp checksum */
+ Btcpck = (1<<4), /* tcp checksum */
+ Bpktck = (1<<5), /* packet checksum */
+ Btimestamp = (1<<6), /* timestamp prefix */
 };

 struct Block
--- a/sys/src/9/port/wifi.c
+++ b/sys/src/9/port/wifi.c
@@ -45,46 +45,133 @@
	0
 };

-static Block* wifidecrypt(Wifi *, Wnode *, Block *);
-static Block* wifiencrypt(Wifi *, Wnode *, Block *);
+static Block* wifidecrypt(Wifi *, Wnode *, Wframe *, Block *);
+static Block* wifiencrypt(Wifi *, Wnode *, Wframe *, Block *);
 static void freewifikeys(Wifi *, Wnode *);

 static void dmatproxy(Block *bp, int upstream, uchar proxy[Eaddrlen], DMAT *t);

 static uchar*
-srcaddr(Wifipkt *w)
+srcaddr(Wframe *f)
 {
- if((w->fc[1] & 0x02) == 0)
- return w->a2;
- if((w->fc[1] & 0x01) == 0)
- return w->a3;
- return w->a4;
+ if((f->fc[1] & 0x02) == 0)
+ return f->a2;
+ if((f->fc[1] & 0x01) == 0)
+ return f->a3;
+
+ return f->a4;
 }
+
 static uchar*
-dstaddr(Wifipkt *w)
+dstaddr(Wframe *f)
 {
- if((w->fc[1] & 0x01) != 0)
- return w->a3;
- return w->a1;
+ if((f->fc[1] & 0x01) != 0)
+ return f->a3;
+
+ return f->a1;
 }

 int
-wifihdrlen(Wifipkt *w)
+wifilen(Wframe *w)
 {
- int n;
+ int l = WIFIHDRSIZE;

- n = WIFIHDRSIZE;
- if((w->fc[0] & 0x0c) == 0x08)
- if((w->fc[0] & 0xf0) == 0x80){ /* QOS */
- n += 2;
- if(w->fc[1] & 0x80)
- n += 4;
+ /* got a4?  */
+ if((w->fc[1] & Wfc1dirmask) == Wfc1diraptoap)
+ l += Eaddrlen;
+
+ /* got qos?  */
+ if((w->fc[0] & Wfc0typemask) == Wfc0typedat) {
+ if((w->fc[0] & Wfc0submask) == Wfc0subqos) {
+ l += 2;
+
+ /* got ht?  */
+ if(w->fc[1] & Wfc1order)
+ l += 4;
		}
- if((w->fc[1] & 3) == 0x03)
- n += Eaddrlen;
- return n;
+ }
+
+ return l;
 }

+int
+wifipack(Wframe *w, uchar *p)
+{
+ uchar *s = p;
+
+ *p++ = w->fc[0];
+ *p++ = w->fc[1];
+ *p++ = w->dur;
+ *p++ = w->dur >> 8;
+
+ memmove(p, w->a1, Eaddrlen); p += Eaddrlen;
+ memmove(p, w->a2, Eaddrlen); p += Eaddrlen;
+ memmove(p, w->a3, Eaddrlen); p += Eaddrlen;
+
+ *p = w->seq;
+ *p = w->seq >> 8;
+
+ /* got a4?  */
+ if((w->fc[1] & Wfc1dirmask) == Wfc1diraptoap) {
+ memmove(p, w->a4, Eaddrlen);
+ p += Eaddrlen;
+ }
+
+ /* got qos?  */
+ if((w->fc[0] & Wfc0typemask) == Wfc0typedat) {
+ if((w->fc[0] & Wfc0submask) == Wfc0subqos) {
+ *p++ = w->qos;
+ *p++ = w->qos >> 8;
+
+ /* got ht?  */
+ if(w->fc[1] & Wfc1order)
+ p += 4;
+ }
+ }
+
+ return p - s;
+}
+
+int
+wifiunpack(Wframe *w, uchar *p)
+{
+ uchar *s = p;
+
+ w->fc[0] = *p++;
+ w->fc[1] = *p++;
+
+ w->dur = *p++;
+ w->dur |= *p++ << 8;
+
+ memmove(w->a1, p, Eaddrlen); p += Eaddrlen;
+ memmove(w->a2, p, Eaddrlen); p += Eaddrlen;
+ memmove(w->a3, p, Eaddrlen); p += Eaddrlen;
+
+ w->seq = *p++;
+ w->seq |= *p++ << 8;
+
+ /* got a4?  */
+ if((w->fc[1] & Wfc1dirmask) == Wfc1diraptoap) {
+ memmove(w->a4, p, Eaddrlen);
+ p += Eaddrlen;
+ }
+
+ /* got qos?  */
+ if((w->fc[0] & Wfc0typemask) == Wfc0typedat) {
+ if((w->fc[0] & Wfc0submask) == Wfc0subqos) {
+ w->qos = *p++;
+ w->qos |= *p++ << 8;
+
+ /* got ht?  */
+ if(w->fc[1] & Wfc1order)
+ p += 4;
+ }
+ }
+
+ return p - s;
+}
+
+
 static uvlong
 getts(uchar *d)
 {
@@ -102,7 +189,7 @@
 wifiiq(Wifi *wifi, Block *b)
 {
	SNAP s;
- Wifipkt h, *w;
+ Wframe w;
	Etherpkt *e;
	int hdrlen;

@@ -110,49 +197,55 @@
		assert(b->rp - b->base >= 8);
	if(BLEN(b) < WIFIHDRSIZE)
		goto drop;
- w = (Wifipkt*)b->rp;
- hdrlen = wifihdrlen(w);
+
+ hdrlen = wifiunpack(&w, b->rp);
	if(BLEN(b) < hdrlen)
		goto drop;
- if(memcmp(srcaddr(w), wifi->ether->ea, Eaddrlen) == 0)
+ if(memcmp(srcaddr(&w), wifi->ether->ea, Eaddrlen) == 0)
		goto drop;
- if(w->fc[1] & 0x40){
+
+ if(w.fc[1] & 0x40){
		/* encrypted */
		qpass(wifi->iq, b);
		return;
	}
- switch(w->fc[0] & 0x0c){
- case 0x00: /* management */
- if((w->fc[1] & 3) != 0x00) /* STA->STA */
+ switch(w.fc[0] & Wfc0typemask){
+ case Wfc0typemgt:
+ if((w.fc[1] & Wfc1dirmask) != Wfc1dirstatosta)
			break;
		qpass(wifi->iq, b);
		return;
- case 0x04: /* control */
+ case Wfc0typectl:
		break;
- case 0x08: /* data */
+ case Wfc0typedat:
		b->flag &= ~Btimestamp;
		b->rp += hdrlen;
- switch(w->fc[0] & 0xf0){
+ switch(w.fc[0] & Wfc0submask){
		default:
			goto drop;
- case 0x80: /* QOS */
- case 0x00:
+
+ case Wfc0subqos:
+ case Wfc0subdata:
			break;
		}
- if(BLEN(b) < SNAPHDRSIZE)
+ if(BLEN(b) < SNAPHDRSIZE) {
+ iprint("wifiq: dropped, no snap\n");
			break;
+ }
+
		memmove(&s, b->rp, SNAPHDRSIZE);
		if(s.dsap != 0xAA || s.ssap != 0xAA || s.control != 3)
			break;
		if(s.orgcode[0] != 0 || s.orgcode[1] != 0 || s.orgcode[2] != 0)
			break;
+
		b->rp += SNAPHDRSIZE-ETHERHDRSIZE;
- h = *w;
		e = (Etherpkt*)b->rp;
- memmove(e->d, dstaddr(&h), Eaddrlen);
- memmove(e->s, srcaddr(&h), Eaddrlen);
+ memmove(e->d, dstaddr(&w), Eaddrlen);
+ memmove(e->s, srcaddr(&w), Eaddrlen);
		memmove(e->type, s.type, 2);
		dmatproxy(b, 0, wifi->ether->ea, &wifi->dmat);
+
		etheriq(wifi->ether, b);
		return;
	}
@@ -161,28 +254,24 @@
 }

 static void
-wifitx(Wifi *wifi, Wnode *wn, Block *b)
+wifitx(Wifi *wifi, Wnode *wn, Wframe *f, Block *b)
 {
- Wifipkt *w;
- uint seq;
-
	wn->lastsend = MACHP(0)->ticks;

- seq = incref(&wifi->txseq);
- seq <<= 4;
-
- w = (Wifipkt*)b->rp;
- w->dur[0] = 0;
- w->dur[1] = 0;
- w->seq[0] = seq;
- w->seq[1] = seq>>8;
-
- if((w->fc[0] & 0x0c) != 0x00){
- b = wifiencrypt(wifi, wn, b);
+ if((f->fc[0] & Wfc0typemask) != Wfc0typemgt){
+ b = wifiencrypt(wifi, wn, f, b);
		if(b == nil)
			return;
	}

+ b = padblock(b, wifilen(f));
+ if(!b)
+ return;
+
+ f->dur = 0;
+ f->seq = incref(&wifi->txseq) << 4;
+ wifipack(f, b->rp);
+
	if((wn->txcount++ & 255) == 255 && wn->actrate != nil &&
	wn->actrate != wn->maxrate){
		uchar *a, *p;

@@ -229,13 +318,14 @@
 void
 wifitxfail(Wifi *wifi, Block *b)
 {
- Wifipkt *w;
+ Wframe w;
	Wnode *wn;

	if(b == nil)
		return;
- w = (Wifipkt*)b->rp;
- wn = nodelookup(wifi, w->a1, 0);
+
+ wifiunpack(&w, b->rp);
+ wn = nodelookup(wifi, w.a1, 0);
	if(wn == nil)
		return;
	wn->txerror++;
@@ -310,7 +400,7 @@
 static void
 wifiprobe(Wifi *wifi, Wnode *wn)
 {
- Wifipkt *w;
+ Wframe f;
	Block *b;
	uchar *p;
	int n;
@@ -322,15 +412,13 @@
		return;
	}

- b = allocb(WIFIHDRSIZE + 512);
- w = (Wifipkt*)b->wp;
-
- w->fc[0] = 0x40; /* probe request */
- w->fc[1] = 0x00; /* STA->STA */
- memmove(w->a1, wifi->ether->bcast, Eaddrlen); /* ???  */
- memmove(w->a2, wifi->ether->ea, Eaddrlen);
- memmove(w->a3, wifi->ether->bcast, Eaddrlen);
- b->wp += WIFIHDRSIZE;
+ b = allocb(512);
+ f.fc[0] = Wfc0typemgt | Wfc0subprobe;
+ f.fc[1] = Wfc1dirstatosta;
+ memmove(f.a1, wifi->ether->bcast, Eaddrlen);
+ memmove(f.a2, wifi->ether->ea, Eaddrlen);
+ memmove(f.a3, wifi->ether->bcast, Eaddrlen);
+
	p = b->wp;

	*p++ = 0; /* set */
@@ -345,24 +433,23 @@
	*p++ = wn->channel;

	b->wp = p;
- wifitx(wifi, wn, b);
+ wifitx(wifi, wn, &f, b);
 }

 static void
 sendauth(Wifi *wifi, Wnode *bss)
 {
- Wifipkt *w;
+ Wframe f;
	Block *b;
	uchar *p;

- b = allocb(WIFIHDRSIZE + 3*2);
- w = (Wifipkt*)b->wp;
- w->fc[0] = 0xB0; /* auth request */
- w->fc[1] = 0x00; /* STA->STA */
- memmove(w->a1, bss->bssid, Eaddrlen); /* ???  */
- memmove(w->a2, wifi->ether->ea, Eaddrlen);
- memmove(w->a3, bss->bssid, Eaddrlen);
- b->wp += WIFIHDRSIZE;
+ b = allocb(3*2);
+ f.fc[0] = Wfc0typemgt | Wfc0subauth;
+ f.fc[1] = Wfc1dirstatosta;
+ memmove(f.a1, bss->bssid, Eaddrlen); /* ???  */
+ memmove(f.a2, wifi->ether->ea, Eaddrlen);
+ memmove(f.a3, bss->bssid, Eaddrlen);
+
	p = b->wp;
	*p++ = 0; /* alg */
	*p++ = 0;
@@ -374,26 +461,24 @@

	bss->aid = 0;

- wifitx(wifi, bss, b);
+ wifitx(wifi, bss, &f, b);
 }

 static void
 sendassoc(Wifi *wifi, Wnode *bss)
 {
- Wifipkt *w;
+ Wframe f;
	Block *b;
	uchar *p;
	int cap, n;

- b = allocb(WIFIHDRSIZE + 512);
- w = (Wifipkt*)b->wp;
- w->fc[0] = 0x00; /* assoc request */
- w->fc[1] = 0x00; /* STA->STA */
- memmove(w->a1, bss->bssid, Eaddrlen); /* ???  */
- memmove(w->a2, wifi->ether->ea, Eaddrlen);
- memmove(w->a3, bss->bssid, Eaddrlen);
+ b = allocb(512);
+ f.fc[0] = Wfc0typemgt | Wfc0subassoc;
+ f.fc[1] = Wfc1dirstatosta;
+ memmove(f.a1, bss->bssid, Eaddrlen); /* ???  */
+ memmove(f.a2, wifi->ether->ea, Eaddrlen);
+ memmove(f.a3, bss->bssid, Eaddrlen);

- b->wp += WIFIHDRSIZE;
	p = b->wp;

	/* capinfo */
@@ -422,7 +507,7 @@
	}

	b->wp = p;
- wifitx(wifi, bss, b);
+ wifitx(wifi, bss, &f, b);
 }

 static void
@@ -621,7 +706,7 @@
 wifiproc(void *arg)
 {
	Wifi *wifi;
- Wifipkt *w;
+ Wframe f;
	Wnode *wn;
	Block *b;

@@ -637,16 +722,17 @@
		}
		if((b = qbread(wifi->iq, 100000)) == nil)
			break;
- w = (Wifipkt*)b->rp;
- if(w->fc[1] & 0x40){
+
+ b->rp += wifiunpack(&f, b->rp);
+ if(f.fc[1] & Wfc1prot){
			/* encrypted */
- if((wn = nodelookup(wifi, w->a2, 0)) == nil)
+ if((wn = nodelookup(wifi, f.a2, 0)) == nil)
				continue;
			wn->lastseen = MACHP(0)->ticks;
- if((b = wifidecrypt(wifi, wn, b)) != nil){
- w = (Wifipkt*)b->rp;
- if(w->fc[1] & 0x40)
+ if((b = wifidecrypt(wifi, wn, &f, b)) != nil){
+ if(f.fc[1] & Wfc1prot)
					continue;
+
				b->flag &= ~Btimestamp;
				wifiiq(wifi, b);
				b = nil;
@@ -653,22 +739,23 @@
			}
			continue;
		}
+
		/* management */
- if((w->fc[0] & 0x0c) != 0x00)
+ if((f.fc[0] & Wfc0typemask) != Wfc0typemgt)
			continue;

- switch(w->fc[0] & 0xf0){
- case 0x50: /* probe response */
+ switch(f.fc[0] & Wfc0submask){
+ case Wfc0subprober:
			if(wifi->debug)
- print("#l%d: got probe from %E\n", wifi->ether->ctlrno, w->a3);
+ print("#l%d: got probe from %E\n", wifi->ether->ctlrno, f.a3);
			/* no break */
- case 0x80: /* beacon */
- if((wn = nodelookup(wifi, w->a3, 1)) == nil)
+ case Wfc0subbeacon:
+ if((wn = nodelookup(wifi, f.a3, 1)) == nil)
				continue;
			wn->lastseen = MACHP(0)->ticks;
			if(b->flag & Btimestamp)
				wn->rs = getts(b->rp - 8);
- b->rp += wifihdrlen(w);
+
			recvbeacon(wifi, wn, b->rp, BLEN(b));

			if(wifi->bss == nil
@@ -681,23 +768,22 @@
			continue;
		}

- if(memcmp(w->a1, wifi->ether->ea, Eaddrlen))
+ if(memcmp(f.a1, wifi->ether->ea, Eaddrlen))
			continue;
- if((wn = nodelookup(wifi, w->a3, 0)) == nil)
+ if((wn = nodelookup(wifi, f.a3, 0)) == nil)
			continue;
		wn->lastseen = MACHP(0)->ticks;
		if(b->flag & Btimestamp)
			wn->rs = getts(b->rp - 8);
- switch(w->fc[0] & 0xf0){
- case 0x10: /* assoc response */
- case 0x30: /* reassoc response */
- b->rp += wifihdrlen(w);
+ switch(f.fc[0] & Wfc0submask){
+ case Wfc0subassocr:
+ case Wfc0subreassocr:
			recvassoc(wifi, wn, b->rp, BLEN(b));
			/* notify driver about node aid association */
			if(wn == wifi->bss)
				(*wifi->transmit)(wifi, wn, nil);
			break;
- case 0xb0: /* auth */
+ case Wfc0subauth:
			if(wifi->debug)
				print("#l%d: got auth from %E\n",
				wifi->ether->ctlrno, wn->bssid);
			if(wn->brsnelen > 0 && wn->rsnelen == 0)
@@ -710,7 +796,7 @@
					sendassoc(wifi, wn);
			}
			break;
- case 0xc0: /* deauth */
+ case Wfc0subdeauth:
			if(wifi->debug)
				print("#l%d: got deauth from %E\n",
				wifi->ether->ctlrno, wn->bssid);
			wifideauth(wifi, wn);
@@ -724,8 +810,7 @@
 wifietheroq(Wifi *wifi, Block *b)
 {
	Etherpkt e;
- Wifipkt h;
- int hdrlen;
+ Wframe f;
	Wnode *wn;
	SNAP *s;

@@ -745,21 +830,19 @@
	} else if(wn->status != Sassoc)
		goto drop;

- h.fc[0] = 0x08; /* data */
- memmove(h.a1, wn->bssid, Eaddrlen);
+ f.fc[0] = Wfc0typedat;
+ memmove(f.a1, wn->bssid, Eaddrlen);
	if(memcmp(e.s, wifi->ether->ea, Eaddrlen) == 0) {
- h.fc[1] = 0x01; /* STA->AP */
+ f.fc[1] = Wfc1dirstatoap;
	} else {
- h.fc[1] = 0x03; /* AP->AP (WDS) */
- memmove(h.a2, wifi->ether->ea, Eaddrlen);
+ f.fc[1] = Wfc1diraptoap;
+ memmove(f.a2, wifi->ether->ea, Eaddrlen);
	}
- memmove(dstaddr(&h), e.d, Eaddrlen);
- memmove(srcaddr(&h), e.s, Eaddrlen);
+ memmove(dstaddr(&f), e.d, Eaddrlen);
+ memmove(srcaddr(&f), e.s, Eaddrlen);

- hdrlen = wifihdrlen(&h);
- b = padblock(b, hdrlen + SNAPHDRSIZE);
- memmove(b->rp, &h, hdrlen);
- s = (SNAP*)(b->rp + hdrlen);
+ b = padblock(b, SNAPHDRSIZE);
+ s = (SNAP*)(b->rp);
	s->dsap = s->ssap = 0xAA;
	s->control = 0x03;
	s->orgcode[0] = 0;
@@ -767,7 +850,7 @@
	s->orgcode[2] = 0;
	memmove(s->type, e.type, 2);

- wifitx(wifi, wn, b);
+ wifitx(wifi, wn, &f, b);
	return;
 drop:
	freeb(b);
@@ -1153,18 +1236,18 @@
	return n;
 }

-static void tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
-static int tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
-static void ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
-static int ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc);
+static void tkipencrypt(Wkey *k, Wframe *w, Block *b, uvlong tsc);
+static int tkipdecrypt(Wkey *k, Wframe *w, Block *b, uvlong tsc);
+static void ccmpencrypt(Wkey *k, Wframe *w, Block *b, uvlong tsc);
+static int ccmpdecrypt(Wkey *k, Wframe *w, Block *b, uvlong tsc);

 static Block*
-wifiencrypt(Wifi *wifi, Wnode *wn, Block *b)
+wifiencrypt(Wifi *wifi, Wnode *wn, Wframe *f, Block *b)
 {
	uvlong tsc;
- int n, kid;
- Wifipkt *w;
+ int kid;
	Wkey *k;
+ uchar *p;

	rlock(&wifi->crypt);

@@ -1175,15 +1258,10 @@
		return b;
	}

- n = wifihdrlen((Wifipkt*)b->rp);
-
	b = padblock(b, 8);
	b = padblock(b, -(8+4));
+ p = b->rp;

- w = (Wifipkt*)b->rp;
- memmove(w, b->rp+8, n);
- b->rp += n;
-
	tsc = ++k->tsc;

	switch(k->cipher){
@@ -1197,7 +1275,7 @@
		b->rp[6] = tsc>>32;
		b->rp[7] = tsc>>40;
		b->rp += 8;
- tkipencrypt(k, w, b, tsc);
+ tkipencrypt(k, f, b, tsc);
		break;
	case CCMP:
		b->rp[0] = tsc;
@@ -1209,29 +1287,24 @@
		b->rp[6] = tsc>>32;
		b->rp[7] = tsc>>40;
		b->rp += 8;
- ccmpencrypt(k, w, b, tsc);
+ ccmpencrypt(k, f, b, tsc);
		break;
	}
- runlock(&wifi->crypt);

- b->rp = (uchar*)w;
- w->fc[1] |= 0x40;
+ runlock(&wifi->crypt);
+ f->fc[1] |= Wfc1prot;
+ b->rp = p;
	return b;
 }

 static Block*
-wifidecrypt(Wifi *wifi, Wnode *wn, Block *b)
+wifidecrypt(Wifi *wifi, Wnode *wn, Wframe *f, Block *b)
 {
	uvlong tsc;
- int n, kid;
- Wifipkt *w;
+ int kid;
	Wkey *k;

	rlock(&wifi->crypt);
-
- w = (Wifipkt*)b->rp;
- n = wifihdrlen(w);
- b->rp += n;
	if(BLEN(b) < 8+8)
		goto drop;

@@ -1238,7 +1311,7 @@
	kid = b->rp[3]>>6;
	if((b->rp[3] & 0x20) == 0)
		goto drop;
- if((w->a1[0] & 1) == 0)
+ if((f->a1[0] & 1) == 0)
		kid = 4; /* use peerwise key for non-unicast */

	k = wn->rxkey[kid];
@@ -1255,7 +1328,7 @@
		b->rp += 8;
		if(tsc <= k->tsc)
			goto drop;
- if(tkipdecrypt(k, w, b, tsc) != 0)
+ if(tkipdecrypt(k, f, b, tsc) != 0)
			goto drop;
		break;
	case CCMP:
@@ -1268,7 +1341,7 @@
		b->rp += 8;
		if(tsc <= k->tsc)
			goto drop;
- if(ccmpdecrypt(k, w, b, tsc) != 0)
+ if(ccmpdecrypt(k, f, b, tsc) != 0)
			goto drop;
		break;
	default:
@@ -1280,10 +1353,7 @@
	runlock(&wifi->crypt);

	k->tsc = tsc;
- b->rp -= n;
- memmove(b->rp, w, n);
- w = (Wifipkt*)b->rp;
- w->fc[1] &= ~0x40;
+ f->fc[1] &= ~Wfc1prot;
	return b;
 }

@@ -1518,7 +1588,7 @@
 static uchar pad4[4] = { 0x00, 0x00, 0x00, 0x00, };

 static void
-tkipencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+tkipencrypt(Wkey *k, Wframe *f, Block *b, uvlong tsc)
 {
	u16int tk[8], p1k[5];
	uchar seed[16];
@@ -1527,8 +1597,8 @@
	ulong crc;

	micsetup(&ms, k->key+24);
- micupdate(&ms, dstaddr(w), Eaddrlen);
- micupdate(&ms, srcaddr(w), Eaddrlen);
+ micupdate(&ms, dstaddr(f), Eaddrlen);
+ micupdate(&ms, srcaddr(f), Eaddrlen);
	micupdate(&ms, pad4, 4);
	micupdate(&ms, b->rp, BLEN(b));
	micfinish(&ms, b->wp);
@@ -1543,7 +1613,7 @@
	b->wp += 4;

	tkipk2tk(k->key, tk);
- tkipphase1(tsc >> 16, w->a2, tk, p1k);
+ tkipphase1(tsc >> 16, f->a2, tk, p1k);
	tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
	setupRC4state(&rs, seed, sizeof(seed));
	rc4(&rs, b->rp, BLEN(b));
@@ -1550,7 +1620,7 @@
 }

 static int
-tkipdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+tkipdecrypt(Wkey *k, Wframe *f, Block *b, uvlong tsc)
 {
	uchar seed[16], mic[8];
	u16int tk[8], p1k[5];
@@ -1562,7 +1632,7 @@
		return -1;

	tkipk2tk(k->key, tk);
- tkipphase1(tsc >> 16, w->a2, tk, p1k);
+ tkipphase1(tsc >> 16, f->a2, tk, p1k);
	tkipphase2(tsc & 0xFFFF, p1k, tk, seed);
	setupRC4state(&rs, seed, sizeof(seed));
	rc4(&rs, b->rp, BLEN(b));
@@ -1577,8 +1647,8 @@

	b->wp -= 8;
	micsetup(&ms, k->key+16);
- micupdate(&ms, dstaddr(w), Eaddrlen);
- micupdate(&ms, srcaddr(w), Eaddrlen);
+ micupdate(&ms, dstaddr(f), Eaddrlen);
+ micupdate(&ms, srcaddr(f), Eaddrlen);
	micupdate(&ms, pad4, 4);
	micupdate(&ms, b->rp, BLEN(b));
	micfinish(&ms, mic);
@@ -1708,12 +1778,12 @@
 }

 static int
-setupCCMP(Wifipkt *w, uvlong tsc, uchar nonce[13], uchar auth[32])
+setupCCMP(Wframe *f, uvlong tsc, uchar nonce[13], uchar auth[32])
 {
	uchar *p;

- nonce[0] = ((w->fc[0] & 0x0c) == 0x00) << 4;
- memmove(&nonce[1], w->a2, Eaddrlen);
+ nonce[0] = ((f->fc[0] & 0x0c) == 0x00) << 4;
+ memmove(&nonce[1], f->a2, Eaddrlen);
	nonce[7] = tsc >> 40;
	nonce[8] = tsc >> 32;
	nonce[9] = tsc >> 24;
@@ -1722,15 +1792,15 @@
	nonce[12] = tsc;

	p = auth;
- *p++ = (w->fc[0] & (((w->fc[0] & 0x0c) == 0x08) ? 0x0f : 0xff));
- *p++ = (w->fc[1] & ~0x38) | 0x40;
- memmove(p, w->a1, Eaddrlen); p += Eaddrlen;
- memmove(p, w->a2, Eaddrlen); p += Eaddrlen;
- memmove(p, w->a3, Eaddrlen); p += Eaddrlen;
- *p++ = w->seq[0] & 0x0f;
+ *p++ = (f->fc[0] & (((f->fc[0] & 0x0c) == 0x08) ? 0x0f : 0xff));
+ *p++ = (f->fc[1] & ~0x38) | 0x40;
+ memmove(p, f->a1, Eaddrlen); p += Eaddrlen;
+ memmove(p, f->a2, Eaddrlen); p += Eaddrlen;
+ memmove(p, f->a3, Eaddrlen); p += Eaddrlen;
+ *p++ = f->seq & 0x0f;
	*p++ = 0;
- if((w->fc[1] & 3) == 0x03) {
- memmove(p, w->a4, Eaddrlen);
+ if((f->fc[1] & 3) == 0x03) {
+ memmove(p, f->a4, Eaddrlen);
		p += Eaddrlen;
	}

@@ -1737,19 +1807,20 @@
	return p - auth;
 }

+
 static void
-ccmpencrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+ccmpencrypt(Wkey *k, Wframe *f, Block *b, uvlong tsc)
 {
	uchar auth[32], nonce[13];

	aesCCMencrypt(2, 8, nonce, auth,
- setupCCMP(w, tsc, nonce, auth),
+ setupCCMP(f, tsc, nonce, auth),
		b->rp, BLEN(b), (AESstate*)k->key);
	b->wp += 8;
 }

 static int
-ccmpdecrypt(Wkey *k, Wifipkt *w, Block *b, uvlong tsc)
+ccmpdecrypt(Wkey *k, Wframe *f, Block *b, uvlong tsc)
 {
	uchar auth[32], nonce[13];

@@ -1758,7 +1829,7 @@

	b->wp -= 8;
	return aesCCMdecrypt(2, 8, nonce, auth,
- setupCCMP(w, tsc, nonce, auth),
+ setupCCMP(f, tsc, nonce, auth),
		b->rp, BLEN(b), (AESstate*)k->key);
 }

--- a/sys/src/9/port/wifi.h
+++ b/sys/src/9/port/wifi.h
@@ -1,7 +1,7 @@
 typedef struct Wkey Wkey;
 typedef struct Wnode Wnode;
+typedef struct Wframe Wframe;
 typedef struct Wifi Wifi;
-typedef struct Wifipkt Wifipkt;
 typedef struct DMAT DMAT;
 typedef struct DMTE DMTE;

@@ -15,6 +15,53 @@
	CCMP = 2,
 };

+/* 802.11 frame fc[0] */
+enum {
+ Wfc0vermask = 0x03,
+ Wfc0typemask = 0x0c,
+ Wfc0submask = 0xf0,
+
+ /* frame types */
+ Wfc0typemgt = 0x00,
+ Wfc0typectl = 0x04,
+ Wfc0typedat = 0x08,
+
+ /* frame subtypes (management) */
+ Wfc0subassoc = 0x00,
+ Wfc0subassocr = 0x10,
+ Wfc0subreassoc = 0x20,
+ Wfc0subreassocr = 0x30,
+ Wfc0subprobe = 0x40,
+ Wfc0subprober = 0x50,
+ Wfc0subbeacon = 0x80,
+ Wfc0subdisassoc = 0xa0,
+ Wfc0subauth = 0xb0,
+ Wfc0subdeauth = 0xc0,
+
+ /* frame subtypes (data) */
+ Wfc0subdata = 0x00,
+ Wfc0subnodata = 0x40,
+ Wfc0subqos = 0x80,
+};
+
+/* 802.11 frame fc[1] */
+enum {
+ Wfc1dirmask = 0x03,
+
+ /* frame direction */
+ Wfc1dirstatosta = 0x00,
+ Wfc1dirstatoap = 0x01,
+ Wfc1diraptosta = 0x02,
+ Wfc1diraptoap = 0x03,
+
+ Wfc1frag = 0x04,
+ Wfc1retry = 0x08,
+ Wfc1pwrmgt = 0x10,
+ Wfc1data = 0x20,
+ Wfc1prot = 0x40,
+ Wfc1order = 0x80,
+};
+
 struct Wkey
 {
	int cipher;
@@ -61,6 +108,20 @@
	uchar brsne[258];
 };

+struct Wframe
+{
+ u8int fc[2];
+
+ u16int dur;
+ u16int seq;
+ u16int qos;
+
+ uchar a1[Eaddrlen];
+ uchar a2[Eaddrlen];
+ uchar a3[Eaddrlen];
+ uchar a4[Eaddrlen];
+};
+
 struct DMTE
 {
	uchar ip[16];
@@ -85,6 +146,7 @@
	ulong watchdog;
	ulong lastauth;
	Ref txseq;
+
	void (*transmit)(Wifi*, Wnode*, Block*);

	/* for searching */
@@ -102,25 +164,33 @@
	DMAT dmat;
 };

-struct Wifipkt
-{
- uchar fc[2];
- uchar dur[2];
- uchar a1[Eaddrlen];
- uchar a2[Eaddrlen];
- uchar a3[Eaddrlen];
- uchar seq[2];
- uchar a4[Eaddrlen];
-};
+#define get16(p) ((p)[0] | (p)[1] << 8)
+#define get32(p) ((p)[0] | (p)[1] << 8 | (p)[2] << 16 | (p)[3]
<< 24)

-enum {
- Btimestamp = 1<<15,
-};
+#define put16(p, v) (p)[0] = (v); (p)[1] = (v) >> 8
+#define put32(p, v) \
+ (p)[0] = (v); \
+ (p)[1] = (v) >> 8; \
+ (p)[2] = (v) >> 16; \
+ (p)[3] = (v) >> 24
+#define put64(p, v) \
+ (p)[0] = (v); \
+ (p)[1] = (v) >> 8; \
+ (p)[2] = (v) >> 16; \
+ (p)[3] = (v) >> 24; \
+ (p)[4] = (v) >> 32; \
+ (p)[5] = (v) >> 40; \
+ (p)[6] = (v) >> 48; \
+ (p)[7] = (v) >> 56

 Wifi *wifiattach(Ether *ether, void (*transmit)(Wifi*, Wnode*, Block*));
+
 void wifiiq(Wifi*, Block*);
-int wifihdrlen(Wifipkt*);
 void wifitxfail(Wifi*, Block*);
+
+int wifilen(Wframe *);
+int wifipack(Wframe *, uchar *p);
+int wifiunpack(Wframe *, uchar *p);

 long wifistat(Wifi*, void*, long, ulong);
 long wifictl(Wifi*, void*, long);


Wed Jun 7 16:32:00 EDT 2023
diff cbe4b116989c0bfec49b9ae7a1d9a85ead6648ae uncommitted
--- a/sys/src/9/boot/nusbrc
+++ b/sys/src/9/boot/nusbrc
@@ -1,4 +1,8 @@
 #!/bin/rc
+
+bind -a '#m' /dev
+bind -a '#b' /dev
+
 if(!  bind -a '#u' /dev)
	exit

@@ -5,7 +9,7 @@
 mkdir -p -m 700 '#σc/usb'
 mkdir -p -m 700 '#σc/usbnet'

-if(!  nusb/usbd)
+if(!  nusb/usbd -d)
	exit

 @{
@@ -70,7 +74,7 @@
		devs='#σc/sdU'^($1 $5)
		rm -rf '#σc/usb/'^$1.* '#σc/usb/'^$5.hid '#σc/usbnet/'^$1.* $devs
		$devs.*
	}
- rc < '#σ/usb/usbevent' &
+ rc -x < '#σ/usb/usbevent' &
 }

 # usbd removes this file once all devices have been enumerated


Wed Jun 7 15:47:24 EDT 2023
TEXT uartgetc(SB), $0
	MOVL p+4(SP), DX
	CALL rmode16(SB)
	STI
	MOVB $0x03, AH
	BIOSCALL(0x14)
	CALL16(pmode32(SB))
	ANDL $0x8100, AX
	MOVL $0x0100, BX
	CMPL BX, AX
	JE _uartread
	XORL AX, AX
	RET


Wed Jun 7 13:00:14 EDT 2023
diff d4124d48f9c7e85fdaa50640035080174c94196e uncommitted
--- a/sys/src/cmd/vmx/vga.c
+++ b/sys/src/cmd/vmx/vga.c
@@ -309,12 +309,25 @@
		return;
	}
	for(;; free(s)){
+ static char *tab[] = {
+ "none", "shift", "esc", "altgr",
+ "ctl", "ctlesc", "shiftesc", "shiftaltgr",
+ "mod4", "altgrmod4",
+ };
		s = Brdstr(bp, '\n', 1);
		if(s == nil) break;
		nf = getfields(s, f, nelem(f), 1, " \t");
		if(nf < 3) continue;
- x = strtol(f[0], &p, 0);
- if(*p != 0) continue;
+
+ for(x = 0; x < nelem(tab); x++){
+ if(strcmp(f[0], tab[x]) == 0)
+ break;
+ }
+ if(x >= nelem(tab)){
+ x = strtol(f[0], &p, 0);
+ if(*p != 0)
+ continue;
+ }
		y = strtol(f[1], &p, 0);
		if(*p != 0) continue;
		if(*f[2] == '\'' || *f[2] == '^'){


Wed Jun 7 09:46:45 EDT 2023
OWO?  What's this?

Wed Jun 7 07:43:15 EDT 2023
But as the gate swung wider and the sorcery of the drug and the dream pushed me
through, I knew that all sights and glories were at an end; for in that new realm
was neither land nor sea, but only the white void of unpeopled and illimitable
space.  So, happier than I had ever dared hope to be, I dissolved again into that
native infinity of crystal oblivion from which the daemon Life had
called me for one brief and desolate hour.

Tue Jun 6 18:37:42 EDT 2023
00008a97 ; magic
00000013 ; text
00000000 ; data
00000000 ; bss
00000000 ; syms
00200028 ; entry
00000000 ; spsz
00000000 ; pcsz
00000000 00200028 ; 64 bit extended entry

; text

; move null pointer into syscall argument
; REX.W MOV ModRM SIB disp8
; 48 89 6c 24 08 ; MOVQ BP,8(SP)
48 c7 44 24 08 00000000 ; MOVQ $8, BP ; move imm32 sign extended to 64 bits to r64

; set syscall number to EXITS 8
; REX.W MOV ModRM imm32
48 c7 c5 08000000 ; MOVQ $8, BP ; move imm32 sign extended to 64 bits to r64
0F05 ; SYSCALL
C3 ; RET


Tue Jun 6 18:37:37 EDT 2023
#include <u.h>
#include <libc.h>
#include <bio.h>

void
usage(void)
{
	fprint(2, "usage: %s [in [out]]\n", argv0);
	exits("usage");
}

void
main(int argc, char *argv[])
{
	int ifd, ofd;
	Biobuf bi, bo;
	int state;
	ulong line;
	int c;
	uchar lh, uh;

	ARGBEGIN{
	default:
		usage();
	}ARGEND;

	if(argc > 2){
		usage();
	}

	if(argc >= 1){
		ifd = open(argv[0], OREAD);
		if(ifd < 0){
			sysfatal("%r");
		}
	}else{
		ifd = 0;
	}
	if(Binit(&bi, ifd, OREAD)){
		sysfatal("%r");
	}

	if(argc == 2){
		ofd = create(argv[1], OWRITE, 0777);
		if(ofd < 0){
			sysfatal("%r");
		}
	}else{
		ofd = 1;
	}
	if(Binit(&bo, ofd, OWRITE)){
		sysfatal("%r");
	}

/*
digit = [0-9A-Fa-f] ;
byte = digit , digit ;
line = [ { byte } ], "\n" ;
grammar = [ { line } ] ;
*/
	line = 1;
	state = 0;
	lh = 0;
	uh = 0;
	for(;;){
		c = Bgetc(&bi);
		if(c < 0){
			break;
		}
		if(state == 0){
			if(c == '\n'){
				line += 1;
			}else if(c == ' '){
			}else if(c == ';'){
				state = 2;
			}else{
				switch(c){
				case '0': uh = 0; break;
				case '1': uh = 1; break;
				case '2': uh = 2; break;
				case '3': uh = 3; break;
				case '4': uh = 4; break;
				case '5': uh = 5; break;
				case '6': uh = 6; break;
				case '7': uh = 7; break;
				case '8': uh = 8; break;
				case '9': uh = 9; break;
				case 'A': uh = 0xA; break;
				case 'B': uh = 0xB; break;
				case 'C': uh = 0xC; break;
				case 'D': uh = 0xD; break;
				case 'E': uh = 0xE; break;
				case 'F': uh = 0xF; break;
				case 'a': uh = 0xa; break;
				case 'b': uh = 0xb; break;
				case 'c': uh = 0xc; break;
				case 'd': uh = 0xd; break;
				case 'e': uh = 0xe; break;
				case 'f': uh = 0xf; break;
				default:
					sysfatal("Invalid byte character on line
					%uld.", line);
				}
				state = 1;
			}
		}else if(state == 1){
			switch(c){
			case '0': lh = 0; break;
			case '1': lh = 1; break;
			case '2': lh = 2; break;
			case '3': lh = 3; break;
			case '4': lh = 4; break;
			case '5': lh = 5; break;
			case '6': lh = 6; break;
			case '7': lh = 7; break;
			case '8': lh = 8; break;
			case '9': lh = 9; break;
			case 'A': lh = 0xA; break;
			case 'B': lh = 0xB; break;
			case 'C': lh = 0xC; break;
			case 'D': lh = 0xD; break;
			case 'E': lh = 0xE; break;
			case 'F': lh = 0xF; break;
			case 'a': lh = 0xa; break;
			case 'b': lh = 0xb; break;
			case 'c': lh = 0xc; break;
			case 'd': lh = 0xd; break;
			case 'e': lh = 0xe; break;
			case 'f': lh = 0xf; break;
			default:
				sysfatal("Invalid byte character on line %uld.",
				line);
			}
			state = 0;
			Bputc(&bo, uh<<4 | lh);
		}else if(state == 2){
			if(c == '\n'){
				line += 1;
				state = 0;
			}
		}else{
			abort();
		}
	}

	Bterm(&bi);
	Bterm(&bo);

	exits(nil);
}


Tue Jun 6 18:05:41 EDT 2023
Options containing NVT ASCII data SHOULD
   NOT include a trailing NULL; however, the receiver of such options
   MUST be prepared to delete trailing nulls if they exist.  The
   receiver MUST NOT require that a trailing null be included in the
   data


Tue Jun 6 17:58:44 EDT 2023
   file 128 Boot file name, null terminated string; "generic"
		    name or null in DHCPDISCOVER, fully qualified
		    directory-path name in DHCPOFFER.


Tue Jun 6 17:17:33 EDT 2023
hal9000# ndb/query -a bootf 9bootpx
hal9000# ndb/query -a bootf 9bootpxe
sys=wopr ether=000024d1c888 ip=192.168.128.1 dom=wopr.local.shike2.net
bootf=9bootpxe
hal9000#


prev | next