Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/port/stnoether.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname port/stnoether.c 1990/1210
## diff -e /dev/null /n/bootesdump/1990/1210/sys/src/9/port/stnoether.c
0a
/*
 *  ethernet specific multiplexor for nonet
 *
 *  this line discipline gets pushed onto an ethernet channel
 *  to demultiplex/multiplex nonet conversations.
 */
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"errno.h"

static void	etherparse(uchar*, char*);
static void	noetherclose(Queue*);
static void	noetheriput(Queue*, Block*);
static void	noetheropen(Queue*, Stream*);
static void	noetheroput(Queue*, Block*);

/*
 *  ethernet header of a packet
 */
typedef struct Etherhdr	Etherhdr;

struct Etherhdr {
	uchar	d[6];
	uchar	s[6];
	uchar	type[2];
	uchar	circuit[3];	/* circuit number */
	uchar	flag;
	uchar	mid;		/* message id */
	uchar	ack;		/* piggy back ack */
	uchar	remain[2];	/* count of remaing bytes of data */
	uchar	sum[2];		/* checksum (0 means none) */
};
#define EHDRSIZE 24
#define EMAXBODY	(1514-HDRSIZE)	/* maximum ethernet packet body */
#define ETHER_TYPE	0x900	/* most significant byte last */

/*
 *  the ethernet multiplexor stream module definition
 */
Qinfo noetherinfo =
{
	noetheriput,
	noetheroput,
	noetheropen,
	noetherclose,
	"noether"
};

/*
 *  perform the ether specific part of nonetconnect.  just stick
 *  the address into the prototype header.
 */
void
noetherconnect(Noconv *cp, char *ea)
{
	Etherhdr *eh;

	eh = (Etherhdr *)cp->media->rptr;
	etherparse(eh->d, ea);
	eh->type[0] = ETHER_TYPE>>8;
	eh->type[1] = ETHER_TYPE;
}

/*
 *  set up an ether interface
 */
static void
noetheropen(Queue *q, Stream *s)
{
	nonetnewifc(q, s, 1514, 60, 14, noetherconnect);
}

/*
 *  tear down an ether interface
 */
static void
noetherclose(Queue *q)
{
	Noifc *ifc;

	ifc = (Noifc *)(q->ptr);
	nonetfreeifc(ifc);
}

/*
 *  configure the system
 */
static void
noetheroput(Queue *q, Block *bp)
{
	Noifc *ifc;

	ifc = (Noifc *)(q->ptr);
	if(bp->type != M_DATA){
		if(streamparse("config", bp)){
			if(*bp->rptr == 0)
				strcpy(ifc->name, "nonet");
			else
				strncpy(ifc->name, (char *)bp->rptr, sizeof(ifc->name));
		} else
			PUTNEXT(q, bp);
		return;
	}
	PUTNEXT(q, bp);
}

/*
 *  Input a packet and use the ether address to select the correct
 *  nonet device to pass it to.
 *
 *  Simplifying assumption:  one put == one packet && the complete header
 *	is in the first block.  If this isn't true, demultiplexing will not work.
 */
static void
noetheriput(Queue *q, Block *bp)
{
	Noifc *ifc;
	int circuit;
	Noconv *cp, *ep;
	Etherhdr *h;
	Etherhdr *ph;
	ulong s;
	Block *nbp;
	int next;
	Nocall *clp;

	if(bp->type != M_DATA){
		PUTNEXT(q, bp);
		return;
	}

	ifc = (Noifc *)(q->ptr);
	h = (Etherhdr *)(bp->rptr);
	circuit = (h->circuit[2]<<16) | (h->circuit[1]<<8) | h->circuit[0];
	s = (h->sum[1]<<8) | h->sum[0];
	if(s && s!=nonetcksum(bp, 14)){
		print("checksum error %ux %ux\n", s, (h->sum[1]<<8) | h->sum[0]);
		freeb(bp);
		return;
	}

	/*
	 *  look for an existing circuit.
	 */
	ep = &ifc->conv[conf.nnoconv];
	for(cp = &ifc->conv[0]; cp < ep; cp++){
		if(circuit==cp->rcvcircuit && canqlock(cp)){
			ph = (Etherhdr *)(cp->media->rptr);
			if(circuit == cp->rcvcircuit
			&& memcmp(ph->d, h->s, sizeof(h->s)) == 0){
				cp->hdr->flag &= ~NO_NEWCALL;
				bp->rptr += ifc->hsize;
				nonetrcvmsg(cp, bp);
				qunlock(cp);
				return;
			}
			qunlock(cp);
		}
	}

	/*
	 *  if not a new call, then its misaddressed
	 */
	if((h->flag & NO_NEWCALL) == 0) {
		freeb(bp);
		return;
	}

	/*
	 *  Queue call in a circular queue and wakeup a listener.
	 */
	lock(&ifc->lock);
	next = (ifc->wptr + 1) % Nnocalls;
	if(next == ifc->rptr){
		/* no room in the queue */
		unlock(&ifc->lock);
		freeb(bp);
		return;
	}
	clp = &ifc->call[ifc->rptr];
	sprint(clp->raddr, "%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux",
		h->s[0], h->s[1], h->s[2], h->s[3], h->s[4], h->s[5]);
	clp->circuit = circuit^1;
	bp->rptr += ifc->hsize;
	clp->msg = bp;
	ifc->wptr = next;
	unlock(&ifc->lock);
	wakeup(&ifc->listenr);
}

/*
 *  parse an ethernet address (assumed to be 12 ascii hex digits)
 */
static void
etherparse(uchar *to, char *from)
{
	int tdig;
	int fdig;
	int i;

	if(strlen(from) != 12)
		error(Ebadnet);

	for(i = 0; i < 6; i++){
		fdig = *from++;
		tdig = fdig > 'a' ? (fdig - 'a' + 10)
				: (fdig > 'A' ? (fdig - 'A' + 10) : (fdig - '0'));
		fdig = *from++;
		tdig <<= 4;
		tdig |= fdig > 'a' ? (fdig - 'a' + 10)
				: (fdig > 'A' ? (fdig - 'A' + 10) : (fdig - '0'));
		*to++ = tdig;
	}
}
.
## diffname port/stnoether.c 1990/1214
## diff -e /n/bootesdump/1990/1210/sys/src/9/port/stnoether.c /n/bootesdump/1990/1214/sys/src/9/port/stnoether.c
65c
	eh->type[1] = ETHER_TYPE & 0xff;
.
## diffname port/stnoether.c 1990/1229
## diff -e /n/bootesdump/1990/1214/sys/src/9/port/stnoether.c /n/bootesdump/1990/1229/sys/src/9/port/stnoether.c
175a
	DPRINT("call in\n");
.
168a
		DPRINT("misaddressed nonet packet %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n", circuit, h->s[0], h->s[1], h->s[2], h->s[3], h->s[4], h->s[5]);
.
150a
		DPRINT("checking %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n", cp->rcvcircuit, ph->d[0], ph->d[1], ph->d[2], ph->d[3], ph->d[4], ph->d[5]);
.
14a
#define DPRINT if(pnonet)print
extern int pnonet;

.
## diffname port/stnoether.c 1990/1231
## diff -e /n/bootesdump/1990/1229/sys/src/9/port/stnoether.c /n/bootesdump/1990/1231/sys/src/9/port/stnoether.c
154d
## diffname port/stnoether.c 1991/0112
## diff -e /n/bootesdump/1990/1231/sys/src/9/port/stnoether.c /n/bootesdump/1991/0112/sys/src/9/port/stnoether.c
189c
	clp = &ifc->call[ifc->wptr];
.
## diffname port/stnoether.c 1991/0119
## diff -e /n/bootesdump/1991/0112/sys/src/9/port/stnoether.c /n/bootesdump/1991/0119/sys/src/9/port/stnoether.c
171,173c
	if((h->flag & NO_NEWCALL) == 0){
		noetherbad(ifc, bp);
.
158d
114a
 *  respond to a misaddressed message with a close
 */
void
noetherbad(Noifc *ifc, Block *bp)
{
	Etherhdr *eh, *neh;
	int circuit;
	Block *nbp;

	/*
	 *  crack the packet header
	 */
	eh = (Etherhdr *)bp->rptr;
	print("bad c %d m %d f %d\n", eh->circuit[0], eh->mid, eh->flag);
	if(eh->flag & NO_RESET)
		goto out;

	/*
	 *  craft an error reply
	 */
	print("sending reset\n");
	nbp = allocb(60);
	nbp->flags |= S_DELIM;
	nbp->wptr = nbp->rptr + 60;
	memset(bp->rptr, 0, 60);
	neh = (Etherhdr *)nbp->rptr;
	memcpy(neh, eh, sizeof(Etherhdr));
	neh->circuit[0] ^= 1;
	neh->remain[0] = neh->remain[1] = 0;
	neh->flag = NO_HANGUP | NO_RESET;
	neh->ack = eh->mid;
	neh->mid = eh->ack;
	memcpy(neh->s, eh->d, sizeof(neh->s));
	memcpy(neh->d, eh->s, sizeof(neh->d));
	nonetcksum(nbp, 14);
	PUTNEXT(ifc->wq, nbp);
out:
	freeb(bp);
}

/*
.
## diffname port/stnoether.c 1991/0206
## diff -e /n/bootesdump/1991/0119/sys/src/9/port/stnoether.c /n/bootesdump/1991/0206/sys/src/9/port/stnoether.c
195c
		if(circuit==cp->rcvcircuit){
			qlock(cp);
.
128c
	print("bad %.2ux%.2ux%.2ux%.2ux%.2ux%.2ux c %d m %d f %d\n",
		eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4],
		eh->s[5], eh->circuit[0], eh->mid, eh->flag);
.
## diffname port/stnoether.c 1991/0209
## diff -e /n/bootesdump/1991/0206/sys/src/9/port/stnoether.c /n/bootesdump/1991/0209/sys/src/9/port/stnoether.c
131a
		goto out;

	/*
	 *  only one reset per message
	 */
	r = (eh->remain[1]<<8) | eh->remain[0];
	if(r<0)
.
122a
	int r;
.
## diffname port/stnoether.c 1991/0318
## diff -e /n/bootesdump/1991/0209/sys/src/9/port/stnoether.c /n/bootesdump/1991/0318/sys/src/9/port/stnoether.c
157,158c
	memmove(neh->s, eh->d, sizeof(neh->s));
	memmove(neh->d, eh->s, sizeof(neh->d));
.
151c
	memmove(neh, eh, sizeof(Etherhdr));
.
110a

.
77c
	nonetnewifc(q, s, 1514, ETHERMINMTU, 14, noetherconnect);
.
## diffname port/stnoether.c 1991/0319
## diff -e /n/bootesdump/1991/0318/sys/src/9/port/stnoether.c /n/bootesdump/1991/0319/sys/src/9/port/stnoether.c
196c
/*		print("checksum error %ux %ux\n", s, (h->sum[1]<<8) | h->sum[0]); /**/
.
## diffname port/stnoether.c 1991/0320
## diff -e /n/bootesdump/1991/0319/sys/src/9/port/stnoether.c /n/bootesdump/1991/0320/sys/src/9/port/stnoether.c
196c
		print("checksum error %ux %ux\n", s, (h->sum[1]<<8) | h->sum[0]); /**/
.
## diffname port/stnoether.c 1991/0328
## diff -e /n/bootesdump/1991/0320/sys/src/9/port/stnoether.c /n/bootesdump/1991/0328/sys/src/9/port/stnoether.c
224c
		noetherbad(ifc, bp, circuit);
.
135a
ep = &ifc->conv[conf.nnoconv];
for(cp = &ifc->conv[0]; cp < ep; cp++){
	qlock(cp);
	if(cp->media){
		neh = (Etherhdr *)(cp->media->rptr);
		print("%lux	%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux %s c %d\n", neh,
			neh->s[0], neh->s[1], neh->s[2], neh->s[3], neh->s[4],
			neh->s[5], cp->raddr, cp->rcvcircuit);
	}
	qunlock(cp);
}

.
132c
		eh->s[5], circuit, eh->mid, eh->flag);
.
124a
	Noconv *cp, *ep;
.
122d
119c
noetherbad(Noifc *ifc, Block *bp, int circuit)
.
13a
#include	"../port/nonet.h"
.
## diffname port/stnoether.c 1991/0330
## diff -e /n/bootesdump/1991/0328/sys/src/9/port/stnoether.c /n/bootesdump/1991/0330/sys/src/9/port/stnoether.c
272a

#ifdef MAGNUM
	/* Dot means ip address */
	if(strchr(from, '.')) {
		ip = ipparse(from);
		if(ip == 0)
			error(Ebadnet);

		hnputl(nip, ip);			
		if(arp_lookup(nip, to))
			return;
	}
#endif
.
269a
	ulong ip;
	uchar nip[4];
.
## diffname port/stnoether.c 1991/0401
## diff -e /n/bootesdump/1991/0330/sys/src/9/port/stnoether.c /n/bootesdump/1991/0401/sys/src/9/port/stnoether.c
209c
/*		print("checksum error %ux %ux\n", s, (h->sum[1]<<8) | h->sum[0]); /**/
.
## diffname port/stnoether.c 1991/0407
## diff -e /n/bootesdump/1991/0401/sys/src/9/port/stnoether.c /n/bootesdump/1991/0407/sys/src/9/port/stnoether.c
255c
		eh->s[0], eh->s[1], eh->s[2], eh->s[3], eh->s[4], eh->s[5]);
.
236c
	if((nh->flag & NO_NEWCALL) == 0){
.
223c
			&& memcmp(peh->d, eh->s, sizeof(eh->s)) == 0){
.
221c
			peh = (Etherpkt*)cp->media->rptr;
.
204,209c
	ifc = (Noifc*)q->ptr;
	eh = (Etherpkt*)bp->rptr;
	nh = (Nohdr*)eh->data;
	circuit = (nh->circuit[2]<<16) | (nh->circuit[1]<<8) | nh->circuit[0];
	s = (nh->sum[1]<<8) | nh->sum[0];
	if(s && s!=nonetcksum(bp, ETHERHDRSIZE)){
/*		print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
.
192,193c
	Etherpkt *eh, *peh;
	Nohdr *nh;
.
164,170c
	neh = (Etherpkt *)nbp->rptr;
	nnh = (Nohdr*)neh->data;
	memmove(neh, eh, EHDRSIZE);
	nnh->circuit[0] ^= 1;
	nnh->remain[0] = nnh->remain[1] = 0;
	nnh->flag = NO_HANGUP | NO_RESET;
	nnh->ack = nh->mid;
	nnh->mid = nh->ack;
.
152c
	r = (nh->remain[1]<<8) | nh->remain[0];
.
137,148d
133,134c
		eh->s[5], circuit, nh->mid, nh->flag);
	if(nh->flag & NO_RESET)
.
130c
	eh = (Etherpkt*)bp->rptr;
	nh = (Nohdr*)eh->data;
.
122c
	Etherpkt *eh, *neh;
	Nohdr *nh, *nnh;
.
101c
	ifc = (Noifc*)q->ptr;
.
89c
	ifc = (Noifc*)q->ptr;
.
78c
	nonetnewifc(q, s, ETHERMAXTU, ETHERMINTU, ETHERHDRSIZE, noetherconnect);
.
66c
	eh = (Etherpkt*)cp->media->rptr;
.
64c
	Etherpkt *eh;
.
28,42c
#define EHDRSIZE 	(ETHERHDRSIZE + NO_HDRSIZE)
#define EMAXBODY	(ETHERMAXTU - EHDRSIZE)	/* maximum ethernet packet body */
.
## diffname port/stnoether.c 1991/0410
## diff -e /n/bootesdump/1991/0407/sys/src/9/port/stnoether.c /n/bootesdump/1991/0410/sys/src/9/port/stnoether.c
151c
	nonetcksum(nbp, ETHERHDRSIZE);
.
## diffname port/stnoether.c 1991/0413
## diff -e /n/bootesdump/1991/0410/sys/src/9/port/stnoether.c /n/bootesdump/1991/0413/sys/src/9/port/stnoether.c
64a
	streamenter(s);
.
## diffname port/stnoether.c 1991/0417
## diff -e /n/bootesdump/1991/0413/sys/src/9/port/stnoether.c /n/bootesdump/1991/0417/sys/src/9/port/stnoether.c
137c
/*	print("sending reset\n"); /**/
.
123c
		eh->s[5], circuit, nh->mid, nh->flag); /**/
.
121c
/*	print("bad %.2ux%.2ux%.2ux%.2ux%.2ux%.2ux c %d m %d f %d\n",
.
## diffname port/stnoether.c 1991/0510
## diff -e /n/bootesdump/1991/0417/sys/src/9/port/stnoether.c /n/bootesdump/1991/0510/sys/src/9/port/stnoether.c
189c
		print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
.
## diffname port/stnoether.c 1991/0511
## diff -e /n/bootesdump/1991/0510/sys/src/9/port/stnoether.c /n/bootesdump/1991/0511/sys/src/9/port/stnoether.c
189c
/*		print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
.
## diffname port/stnoether.c 1991/0608
## diff -e /n/bootesdump/1991/0511/sys/src/9/port/stnoether.c /n/bootesdump/1991/0608/sys/src/9/port/stnoether.c
278,279c
		tdig |= fdig >= 'a' ? ((fdig - 'a') + 10)
				: (fdig >= 'A' ? ((fdig - 'A') + 10) : (fdig - '0'));
.
273,276c
		fdig = (*from++)&0x7f;
		tdig = fdig >= 'a' ? ((fdig - 'a') + 10)
				: (fdig >= 'A' ? ((fdig - 'A') + 10) : (fdig - '0'));
		fdig = (*from++)&0x7f;
.
## diffname port/stnoether.c 1991/1107
## diff -e /n/bootesdump/1991/0608/sys/src/9/port/stnoether.c /n/bootesdump/1991/1107/sys/src/9/port/stnoether.c
199,203c
		nbp = cp->media;
		if(nbp == 0)
			continue;
		peh = (Etherpkt*)nbp->rptr;
		if(circuit==cp->rcvcircuit && memcmp(peh->d, eh->s, sizeof(eh->s))==0){
			if(!canqlock(cp)){
				freeb(bp);
				return;
			}
			peh = (Etherpkt*)nbp->rptr;
			if(circuit==cp->rcvcircuit
			&& memcmp(peh->d, eh->s, sizeof(eh->s))==0){
.
## diffname port/stnoether.c 1991/1121
## diff -e /n/bootesdump/1991/1107/sys/src/9/port/stnoether.c /n/bootesdump/1991/1121/sys/src/9/port/stnoether.c
248a
	DPRINT("call from %s wptr %d\n", clp->raddr, ifc->wptr);
.
231d
223c
	if((nh->flag & NO_NEWCALL) == 0 || nh->mid != 1){
.
## diffname port/stnoether.c 1991/1214
## diff -e /n/bootesdump/1991/1121/sys/src/9/port/stnoether.c /n/bootesdump/1991/1214/sys/src/9/port/stnoether.c
189c
		print("checksum error %ux %ux\n", s, (nh->sum[1]<<8) | nh->sum[0]); /**/
.
## diffname port/stnoether.c 1992/0111
## diff -e /n/bootesdump/1991/1214/sys/src/9/port/stnoether.c /n/bootesdump/1992/0111/sys/src/9/port/stnoether.c
13c
#include	"../port/error.h"
.
## diffname port/stnoether.c 1992/0114
## diff -e /n/bootesdump/1992/0111/sys/src/9/port/stnoether.c /n/bootesdump/1992/0114/sys/src/9/port/stnoether.c
277c
		error(Enetaddr);
.
268c
			error(Enetaddr);
.
## diffname port/stnoether.c 1992/0303 # deleted
## diff -e /n/bootesdump/1992/0114/sys/src/9/port/stnoether.c /n/bootesdump/1992/0303/sys/src/9/port/stnoether.c
1,289d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to [email protected].