Beispiel #1
0
long
netifread(struct netif *nif, struct chan *c, void *a, long n, uint32_t offset)
{
	int i, j;
	struct netfile *f;
	char *p;

	if (c->qid.type & QTDIR)
		return devdirread(c, a, n, (struct dirtab *)nif, 0, netifgen);

	switch (NETTYPE(c->qid.path)) {
		case Ndataqid:
			f = nif->f[NETID(c->qid.path)];
			return qread(f->in, a, n);
		case Nctlqid:
			return readnum(offset, a, n, NETID(c->qid.path), NUMSIZE);
		case Nstatqid:
			p = kzmalloc(READSTR, 0);
			if (p == NULL)
				return 0;
			j = snprintf(p, READSTR, "in: %d\n", nif->inpackets);
			j += snprintf(p + j, READSTR - j, "link: %d\n", nif->link);
			j += snprintf(p + j, READSTR - j, "out: %d\n", nif->outpackets);
			j += snprintf(p + j, READSTR - j, "crc errs: %d\n", nif->crcs);
			j += snprintf(p + j, READSTR - j, "overflows: %d\n",
						  nif->overflows);
			j += snprintf(p + j, READSTR - j, "soft overflows: %d\n",
						  nif->soverflows);
			j += snprintf(p + j, READSTR - j, "framing errs: %d\n",
						  nif->frames);
			j += snprintf(p + j, READSTR - j, "buffer errs: %d\n", nif->buffs);
			j += snprintf(p + j, READSTR - j, "output errs: %d\n", nif->oerrs);
			j += snprintf(p + j, READSTR - j, "prom: %d\n", nif->prom);
			j += snprintf(p + j, READSTR - j, "mbps: %d\n", nif->mbps);
			j += snprintf(p + j, READSTR - j, "addr: ");
			for (i = 0; i < nif->alen; i++)
				j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
			snprintf(p + j, READSTR - j, "\n");
			n = readstr(offset, a, n, p);
			kfree(p);
			return n;
		case Naddrqid:
			p = kzmalloc(READSTR, 0);
			if (p == NULL)
				return 0;
			j = 0;
			for (i = 0; i < nif->alen; i++)
				j += snprintf(p + j, READSTR - j, "%02.2x", nif->addr[i]);
			n = readstr(offset, a, n, p);
			kfree(p);
			return n;
		case Ntypeqid:
			f = nif->f[NETID(c->qid.path)];
			return readnum(offset, a, n, f->type, NUMSIZE);
		case Nifstatqid:
			return 0;
	}
	error(Ebadarg);
	return -1;	/* not reached */
}
Beispiel #2
0
static int
uartstat(Chan *c, uchar *dp, int n)
{
	if(NETTYPE(c->qid.path) == Ndataqid)
		setlength(NETID(c->qid.path));
	return devstat(c, dp, n, uartdir, ndir, devgen);
}
Beispiel #3
0
static long
eiawrite(Chan *c, void *buf, long n, vlong offset)
{
	ssize_t cnt;
	char cmd[Maxctl];
	int port = NETID(c->qid.path);

	USED(offset);

	if(c->qid.type & QTDIR)
		error(Eperm);

	switch(NETTYPE(c->qid.path)) {
	case Ndataqid:
	  	osenter(); 
		cnt = write(eia[port].fd, buf, n);
		osleave(); 
		if(cnt == -1)
			oserror();
		return cnt;
	case Nctlqid:
		if(n >= (long)sizeof(cmd))
			n = sizeof(cmd)-1;
		memmove(cmd, buf, n);
		cmd[n] = 0;
		wrctl(port, cmd);
		return n;
	}
	return 0;
}
Beispiel #4
0
static long
eiaread(Chan *c, void *buf, long n, vlong offset)
{
	DWORD cnt;
	int port = NETID(c->qid.path);
	BOOL good;

	if(c->qid.type & QTDIR)
		return devdirread(c, buf, n, eiadir, ndir, devgen);

	switch(NETTYPE(c->qid.path)) {
	case Ndataqid:
		cnt = 0;
		// if ReadFile timeouts and cnt==0 then just re-read
		// this will give osleave() a chance to detect an
		// interruption (i.e. killprog)
		while(cnt==0) {
  			osenter(); 
			good = ReadFile(eia[port].comfh, buf, n, &cnt, NULL);
			SleepEx(0,FALSE);  //allow another thread access to port
			osleave();
			if(!good)
				oserror();
		}
		return cnt;
	case Nctlqid:
		return readnum(offset, buf, n, eia[port].id, NUMSIZE);
	case Nstatqid:
		return rdstat(port, buf, n, offset);
	}

	return 0;
}
Beispiel #5
0
static long
eiaread(Chan *c, void *buf, long n, vlong offset)
{
	ssize_t cnt;
	int port = NETID(c->qid.path);

	if(c->qid.type & QTDIR)
		return devdirread(c, buf, n, eiadir, ndir, devgen);

	switch(NETTYPE(c->qid.path)) {
	case Ndataqid:
	  	osenter(); 
		cnt = read(eia[port].fd, buf, n);
		osleave(); 
		if(cnt == -1)
			oserror();
		return cnt;
	case Nctlqid:
		return readnum(offset, buf, n, port, NUMSIZE);
	case Nstatqid:
		return rdstat(port, buf, n, offset);
	}

	return 0;
}
Beispiel #6
0
static int
pipegen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp)
{
	int id, len;
	Qid qid;
	Pipe *p;

	USED(name);
	if(i == DEVDOTDOT){
		devdir(c, c->qid, "#|", 0, eve, 0555, dp);
		return 1;
	}
	i++;	/* skip . */
	if(tab==0 || i>=ntab)
		return -1;
	tab += i;
	p = c->aux;
	switch(NETTYPE(tab->qid.path)){
	case Qdata0:
		len = qlen(p->q[0]);
		break;
	case Qdata1:
		len = qlen(p->q[1]);
		break;
	default:
		len = tab->length;
		break;
	}
	id = NETID(c->qid.path);
	qid.path = NETQID(id, tab->qid.path);
	qid.vers = 0;
	qid.type = QTFILE;
	devdir(c, qid, tab->name, len, eve, tab->perm, dp);
	return 1;
}
Beispiel #7
0
static long
uartwrite(Chan *c, void *buf, long n, vlong offset)
{
	Uart *p;
	char cmd[32];

	USED(offset);

	if(c->qid.type & QTDIR)
		error(Eperm);

	p = uart[NETID(c->qid.path)];

	switch(NETTYPE(c->qid.path)){
	case Ndataqid:
		return qwrite(p->oq, buf, n);
	case Nctlqid:

		if(n >= sizeof(cmd))
			n = sizeof(cmd)-1;
		memmove(cmd, buf, n);
		cmd[n] = 0;
		uartctl(p, cmd);
		return n;
	}
}
Beispiel #8
0
static void
uartclose(Chan *c)
{
	Uart *p;

	if(c->qid.type & QTDIR)
		return;
	if((c->flag & COPEN) == 0)
		return;
	switch(NETTYPE(c->qid.path)){
	case Ndataqid:
	case Nctlqid:
		p = uart[NETID(c->qid.path)];
		qlock(p);
		if(--(p->opens) == 0){
			qclose(p->iq);
			ilock(&p->rlock);
			p->ir = p->iw = p->istage;
			iunlock(&p->rlock);

			/*
			 */
			qhangup(p->oq, nil);
			if(!waserror()){
				uartdrainoutput(p);
				poperror();
			}
			qclose(p->oq);
			uartdisable(p);
			p->dcd = p->dsr = p->dohup = 0;
		}
		qunlock(p);
		break;
	}
}
Beispiel #9
0
static int
pipegen(Chan *c, char*, Dirtab *tab, int ntab, int i, Dir *dp)
{
	Qid q;
	int len;
	Pipe *p;

	if(i == DEVDOTDOT){
		devdir(c, c->qid, "#|", 0, eve, DMDIR|0555, dp);
		return 1;
	}
	i++;	/* skip . */
	if(tab==0 || i>=ntab)
		return -1;

	tab += i;
	p = c->aux;
	switch((ulong)tab->qid.path){
	case Qdata0:
		len = qlen(p->q[0]);
		break;
	case Qdata1:
		len = qlen(p->q[1]);
		break;
	default:
		len = tab->length;
		break;
	}
	mkqid(&q, NETQID(NETID(c->qid.path), tab->qid.path), 0, QTFILE);
	devdir(c, q, tab->name, len, eve, p->perm, dp);
	return 1;
}
Beispiel #10
0
int32_t
netifwstat(Netif *nif, Chan *c, uint8_t *db, int32_t n)
{
	Proc *up = externup();
	Dir *dir;
	Netfile *f;
	int l;

	f = nif->f[NETID(c->qid.path)];
	if(f == 0)
		error(Enonexist);

	if(netown(f, up->user, OWRITE) < 0)
		error(Eperm);

	dir = smalloc(sizeof(Dir)+n);
	l = convM2D(db, n, &dir[0], (char*)&dir[1]);
	if(l == 0){
		free(dir);
		error(Eshortstat);
	}
	if(!emptystr(dir[0].uid))
		strncpy(f->owner, dir[0].uid, KNAMELEN);
	if(dir[0].mode != (uint32_t)~0UL)
		f->mode = dir[0].mode;
	free(dir);
	return l;
}
Beispiel #11
0
int netifwstat(struct ether *nif, struct chan *c, uint8_t * db, int n)
{
	struct dir *dir;
	struct netfile *f;
	int m;

	f = nif->f[NETID(c->qid.path)];
	if (f == 0) {
		set_errno(ENOENT);
		error(Enonexist);
	}

	if (netown(f, current->user, OWRITE) < 0)
		error(Eperm);

	dir = kzmalloc(sizeof(struct dir) + n, 0);
	m = convM2D(db, n, &dir[0], (char *)&dir[1]);
	if (m == 0) {
		kfree(dir);
		error(Eshortstat);
	}
	if (!emptystr(dir[0].uid))
		strncpy(f->owner, dir[0].uid, KNAMELEN);
	if (dir[0].mode != ~0UL)
		f->mode = dir[0].mode;
	kfree(dir);
	return m;
}
Beispiel #12
0
Block*
netifbread(Netif *nif, Chan *c, long n, vlong offset)
{
	Netfile *f;
	Block *bp;

	if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid)
		return devbread(c, n, offset);

	f = nif->f[NETID(c->qid.path)];
	if(f->fat){
		/*
		 * Frame at a time (fat) allows us to provide
		 * non-blocking performance with blocking semantics
		 * for consumers that know ahead of time data is
		 * contained within a single frame.  Once empty, we
		 * get in line with other blocking reads and wait our
		 * turn.
		 */
		for(;;){
			if(bp = qget(f->iq))
				return bp;
			if(waserror())
				return nil;
			qsleep(f->iq);
			poperror();
		}
	}
	return qbread(f->iq, n);
}
Beispiel #13
0
struct block *netifbread(struct ether *nif, struct chan *c, long n,
						 uint32_t offset)
{
	if ((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid)
		return devbread(c, n, offset);

	return qbread(nif->f[NETID(c->qid.path)]->in, n);
}
Beispiel #14
0
Block*
netifbread(Netif *nif, Chan *c, long n, ulong offset)
{
	if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid)
		return devbread(c, n, offset);

	return qbread(nif->f[NETID(c->qid.path)]->in, n);
}
Beispiel #15
0
Block*
netifbread(Netif *nif, Chan *c, int32_t n, int64_t offset)
{
	if((c->qid.type & QTDIR) || NETTYPE(c->qid.path) != Ndataqid)
		return devbread(c, n, offset);

	return qbread(nif->f[NETID(c->qid.path)]->iq, n);
}
Beispiel #16
0
void
netifbypass(Netif *nif, Chan *c, void (*bypass)(void*, Block*), void *arg)
{
	Netfile *f;

	f = nif->f[NETID(c->qid.path)];
	qsetbypass(f->iq, bypass, arg);
}
Beispiel #17
0
void
netifclose(Netif *nif, Chan *c)
{
	Netfile *f;
	int t;
	Netaddr *ap;

	if((c->flag & COPEN) == 0)
		return;

	t = NETTYPE(c->qid.path);
	if(t != Ndataqid && t != Nctlqid)
		return;

	f = nif->f[NETID(c->qid.path)];
	qlock(&f->q);
	if(--(f->inuse) == 0){
		if(f->prom){
			qlock(&nif->q);
			if(--(nif->prom) == 0 && nif->promiscuous != nil)
				nif->promiscuous(nif->arg, 0);
			qunlock(&nif->q);
			f->prom = 0;
		}
		if(f->scan){
			qlock(&nif->q);
			if(--(nif->_scan) == 0 && nif->scanbs != nil)
				nif->scanbs(nif->arg, 0);
			qunlock(&nif->q);
			f->prom = 0;
			f->scan = 0;
		}
		if(f->nmaddr){
			qlock(&nif->q);
			t = 0;
			for(ap = nif->maddr; ap; ap = ap->next){
				if(f->maddr[t/8] & (1<<(t%8)))
					netmulti(nif, f, ap->addr, 0);
			}
			qunlock(&nif->q);
			f->nmaddr = 0;
		}
		if(f->type < 0){
			qlock(&nif->q);
			--(nif->all);
			qunlock(&nif->q);
		}
		f->owner[0] = 0;
		f->type = 0;
		f->bridge = 0;
		f->headersonly = 0;
		qclose(f->iq);
	}
	qunlock(&f->q);
}
Beispiel #18
0
static long
uartread(Chan *c, void *buf, long n, vlong offset)
{
	Uart *p;

	if(c->qid.type & QTDIR){
		setlength(-1);
		return devdirread(c, buf, n, uartdir, ndir, devgen);
	}

	p = uart[NETID(c->qid.path)];
	switch(NETTYPE(c->qid.path)){
	case Ndataqid:
		return qread(p->iq, buf, n);
	case Nctlqid:
		return readnum(offset, buf, n, NETID(c->qid.path), NUMSIZE);
	case Nstatqid:
		return uartstatus(c, p, buf, n, offset);
	}

	return 0;
}
Beispiel #19
0
static Chan*
eiaopen(Chan *c, int mode)
{
	int port = NETID(c->qid.path);
	struct termios ts;
	int r;

	c = devopen(c, mode, eiadir, ndir, devgen);

	switch(NETTYPE(c->qid.path)) {
	case Nctlqid:
	case Ndataqid:
	case Nstatqid:
		if(incref(&eia[port].r) != 1)
			break;

		osenter();
		eia[port].fd = open(sysdev[port], O_RDWR);
		osleave();
		if(eia[port].fd < 0)
			oserror();

		/* make port settings sane */
		if(tcgetattr(eia[port].fd, &ts) < 0)
			oserror();
		ts.c_iflag = ts.c_oflag = ts.c_lflag = 0;
		if(eia[port].restore)
		        ts = eia[port].ts;
		else {
			cfsetispeed(&ts, B9600);
			cfsetospeed(&ts, B9600);
			ts.c_iflag |= IGNPAR;
			ts.c_cflag &= ~CSIZE;
			ts.c_cflag |= CS8|CREAD;
			ts.c_cflag &= ~(PARENB|PARODD);
			ts.c_cc[VMIN] = 1;
			ts.c_cc[VTIME] = 0;
		}
		osenter();
		r = tcsetattr(eia[port].fd, TCSANOW, &ts);
		osleave();
		if(r < 0)
			oserror();

		if(eia[port].restore)
		        resxtra(port, &ts);
		break;
	}
	return c;
}
Beispiel #20
0
int
eiawstat(Chan *c, uchar *dp, int n)
{
	Dir d;
	int i;

	if(strcmp(up->env->user, eve) != 0)
		error(Eperm);
	if(c->qid.type & QTDIR)
		error(Eperm);

	n = convM2D(dp, n, &d, nil);
	i = Nqid*NETID(c->qid.path)+NETTYPE(c->qid.path)-Ndataqid;
	eiadir[i+1].perm = d.mode&0666;
	return n;
}
Beispiel #21
0
static long
uartwrite(Chan *c, void *buf, long n, vlong)
{
	Uart *p;
	char *cmd;

	if(c->qid.type & QTDIR)
		error(Eperm);

	p = uart[NETID(c->qid.path)];

	switch(NETTYPE(c->qid.path)){
	case Ndataqid:
		qlock(p);
		if(waserror()){
			qunlock(p);
			nexterror();
		}

		n = qwrite(p->oq, buf, n);

		qunlock(p);
		poperror();
		break;
	case Nctlqid:
		cmd = malloc(n+1);
		memmove(cmd, buf, n);
		cmd[n] = 0;
		qlock(p);
		if(waserror()){
			qunlock(p);
			free(cmd);
			nexterror();
		}

		/* let output drain */
		if(uartctl(p, cmd) < 0)
			error(Ebadarg);

		qunlock(p);
		poperror();
		free(cmd);
		break;
	}

	return n;
}
Beispiel #22
0
static int
eiawstat(Chan *c, uchar *dp, int n)
{
	Dir d;
	int i;

	if(!iseve())
		error(Eperm);
	if(c->qid.type & QTDIR)
		error(Eperm);
	if(NETTYPE(c->qid.path) == Nstatqid)
		error(Eperm);

	n = convM2D(dp, n, &d, nil);
	i = Nqid*NETID(c->qid.path)+NETTYPE(c->qid.path)-Ndataqid;
	if(d.mode != ~0UL)
		eiadir[i+1].perm = d.mode&0666;
	return n;
}
Beispiel #23
0
Chan*
netifopen(Netif *nif, Chan *c, int omode)
{
	Proc *up = externup();
	int id;
	Netfile *f;

	id = 0;
	if(c->qid.type & QTDIR){
		if(omode != OREAD)
			error(Eperm);
	} else {
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			id = NETID(c->qid.path);
			openfile(nif, id);
			break;
		case Ncloneqid:
			id = openfile(nif, -1);
			c->qid.path = NETQID(id, Nctlqid);
			break;
		default:
			if(omode != OREAD)
				error(Ebadarg);
		}
		switch(NETTYPE(c->qid.path)){
		case Ndataqid:
		case Nctlqid:
			f = nif->f[id];
			if(netown(f, up->user, omode&7) < 0){
				netifclose(nif, c);
				error(Eperm);
			}
			break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Beispiel #24
0
static int
uartwstat(Chan *c, uchar *dp, int n)
{
	Dir d;
	Dirtab *dt;

	if(!iseve())
		error(Eperm);
	if(QTDIR & c->qid.type)
		error(Eperm);
	if(NETTYPE(c->qid.path) == Nstatqid)
		error(Eperm);

	dt = &uartdir[1 + 3 * NETID(c->qid.path)];
	n = convM2D(dp, n, &d, nil);
	if(n == 0)
		error(Eshortstat);
	if(d.mode != ~0UL)
		dt[0].perm = dt[1].perm = d.mode;
	return n;
}
Beispiel #25
0
static void
eiaclose(Chan *c)
{
	int port = NETID(c->qid.path);

	if((c->flag & COPEN) == 0)
		return;

	switch(NETTYPE(c->qid.path)) {
	case Nctlqid:
	case Ndataqid:
	case Nstatqid:
		if(decref(&eia[port].r) == 0) {
			osenter();
			CloseHandle(eia[port].comfh);
			osleave();
		}
		break;
	}

}
Beispiel #26
0
static long
eiawrite(Chan *c, void *buf, long n, vlong offset)
{
	DWORD cnt;
	char cmd[Maxctl];
	int port = NETID(c->qid.path);
	BOOL good;
	uchar *data;

	if(c->qid.type & QTDIR)
		error(Eperm);

	switch(NETTYPE(c->qid.path)) {
	case Ndataqid:
		cnt = 0;
		data = (uchar*)buf;
		// if WriteFile times out (i.e. return true; cnt<n) then
		// allow osleave() to check for an interrupt otherwise try
		// to send the unsent data.
		while(n>0) {
	  		osenter(); 
			good = WriteFile(eia[port].comfh, data, n, &cnt, NULL);
			osleave(); 
			if(!good)
				oserror();
			data += cnt;
			n -= cnt;
		}
		return (data-(uchar*)buf);
	case Nctlqid:
		if(n >= sizeof(cmd))
			n = sizeof(cmd)-1;
		memmove(cmd, buf, n);
		cmd[n] = 0;
		wrctl(port, cmd);
		return n;
	}
	return 0;
}
Beispiel #27
0
static int
uartwstat(Chan *c, uchar *dp, int n)
{
	error(Eperm);
	return 0;
#ifdef xxx
	Dir d;
	Dirtab *dt;

	if(!iseve())
		error(Eperm);
	if(c->qid.type & QTDIR)
		error(Eperm);
	if(NETTYPE(c->qid.path) == Nstatqid)
		error(Eperm);

	dt = &uartdir[3 * NETID(c->qid.path)];
	convM2D(dp, &d);
	d.mode &= 0666;
	dt[0].perm = dt[1].perm = d.mode;
#endif
}
Beispiel #28
0
struct chan *netifopen(struct ether *nif, struct chan *c, int omode)
{
	int id;
	struct netfile *f;

	id = 0;
	if (c->qid.type & QTDIR) {
		if (!IS_RDONLY(omode))
			error(Eperm);
	} else {
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				id = NETID(c->qid.path);
				openfile(nif, id);
				break;
			case Ncloneqid:
				id = openfile(nif, -1);
				c->qid.path = NETQID(id, Nctlqid);
				break;
			default:
				if (!IS_RDONLY(omode))
					error(Ebadarg);
		}
		switch (NETTYPE(c->qid.path)) {
			case Ndataqid:
			case Nctlqid:
				f = nif->f[id];
				if (netown(f, current->user, omode & 7) < 0)
					error(Eperm);
				break;
		}
	}
	c->mode = openmode(omode);
	c->flag |= COPEN;
	c->offset = 0;
	c->iounit = qiomaxatomic;
	return c;
}
Beispiel #29
0
static Chan*
uartopen(Chan *c, int omode)
{
	Uart *p;

	c = devopen(c, omode, uartdir, ndir, devgen);

	switch(NETTYPE(c->qid.path)){
	case Nctlqid:
	case Ndataqid:
		p = uart[NETID(c->qid.path)];
		qlock(p);
		if(p->opens++ == 0){
			uartenable(p);
			qreopen(p->iq);
			qreopen(p->oq);
		}
		qunlock(p);
		break;
	}

	return c;
}
Beispiel #30
0
static Chan*
eiaopen(Chan *c, int mode)
{
	int port = NETID(c->qid.path);

	c = devopen(c, mode, eiadir, ndir, devgen);

	switch(NETTYPE(c->qid.path)) {
	case Nctlqid:
	case Ndataqid:
	case Nstatqid:
		if(incref(&eia[port].r) != 1)
			break;
		if(waserror()) {
			decref(&eia[port].r);
			nexterror();
		}
		openport(port);
		poperror();
		break;
	}
	return c;
}