plan 9 kernel history: overview | file list | diff list

2002/0507/ip/netlog.c (diff list | history)

2002/0507/sys/src/9/ip/netlog.c:1,2622002/0615/sys/src/9/ip/netlog.c:1,262 (short | long | prev | next)
1997/0327    
#include	"u.h" 
#include	"../port/lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"../port/error.h" 
#include	"../ip/ip.h" 
 
enum { 
	Nlog		= 4*1024, 
}; 
 
/* 
 *  action log 
 */ 
1999/0316    
struct Netlog { 
1997/0327    
	Lock; 
	int	opens; 
	char*	buf; 
	char	*end; 
	char	*rptr; 
	int	len; 
 
1998/0313    
	int	logmask;			/* mask of things to debug */ 
	uchar	iponly[IPaddrlen];		/* ip address to print debugging for */ 
	int	iponlyset; 
 
1997/0327    
	QLock; 
	Rendez; 
1998/0313    
}; 
1997/0327    
 
1999/0316    
typedef struct Netlogflag { 
1997/0327    
	char*	name; 
	int	mask; 
1999/0316    
} Netlogflag; 
1998/0313    
 
1999/0316    
static Netlogflag flags[] = 
1997/0327    
{ 
	{ "ppp",	Logppp, }, 
	{ "ip",		Logip, }, 
	{ "fs",		Logfs, }, 
	{ "tcp",	Logtcp, }, 
	{ "il",		Logil, }, 
	{ "icmp",	Logicmp, }, 
	{ "udp",	Logudp, }, 
	{ "compress",	Logcompress, }, 
	{ "ilmsg",	Logil|Logilmsg, }, 
	{ "gre",	Loggre, }, 
	{ "tcpmsg",	Logtcp|Logtcpmsg, }, 
1997/0806    
	{ "udpmsg",	Logudp|Logudpmsg, }, 
	{ "ipmsg",	Logip|Logipmsg, }, 
1999/0316    
	{ "esp",	Logesp, }, 
1997/0327    
	{ nil,		0, }, 
}; 
 
2001/1120    
char Ebadnetctl[] = "too few arguments for netlog control message"; 
1997/0327    
 
2001/1120    
enum 
{ 
	CMset, 
	CMclear, 
	CMonly, 
}; 
 
static 
Cmdtab routecmd[] = { 
	CMset,		"set",		0, 
	CMclear,	"clear",	0, 
	CMonly,		"only",		0, 
}; 
 
1997/0327    
void 
1998/0313    
netloginit(Fs *f) 
1997/0327    
{ 
1999/0316    
	f->alog = smalloc(sizeof(Netlog)); 
1998/0313    
} 
 
void 
netlogopen(Fs *f) 
{ 
	lock(f->alog); 
1997/0327    
	if(waserror()){ 
1998/0313    
		unlock(f->alog); 
1997/0327    
		nexterror(); 
	} 
1998/0313    
	if(f->alog->opens == 0){ 
		if(f->alog->buf == nil) 
			f->alog->buf = malloc(Nlog); 
		f->alog->rptr = f->alog->buf; 
		f->alog->end = f->alog->buf + Nlog; 
1997/0327    
	} 
1998/0313    
	f->alog->opens++; 
	unlock(f->alog); 
1997/0327    
	poperror(); 
} 
 
void 
1998/0313    
netlogclose(Fs *f) 
1997/0327    
{ 
1998/0313    
	lock(f->alog); 
1997/0327    
	if(waserror()){ 
1998/0313    
		unlock(f->alog); 
1997/0327    
		nexterror(); 
	} 
1998/0313    
	f->alog->opens--; 
	if(f->alog->opens == 0){ 
		free(f->alog->buf); 
		f->alog->buf = nil; 
1997/0327    
	} 
1998/0313    
	unlock(f->alog); 
1997/0327    
	poperror(); 
} 
 
static int 
1998/0313    
netlogready(void *a) 
1997/0327    
{ 
1998/0313    
	Fs *f = a; 
 
	return f->alog->len; 
1997/0327    
} 
 
long 
1998/0313    
netlogread(Fs *f, void *a, ulong, long n) 
1997/0327    
{ 
	int i, d; 
	char *p, *rptr; 
 
1998/0313    
	qlock(f->alog); 
1997/0327    
	if(waserror()){ 
1998/0313    
		qunlock(f->alog); 
1997/0327    
		nexterror(); 
	} 
 
	for(;;){ 
1998/0313    
		lock(f->alog); 
		if(f->alog->len){ 
			if(n > f->alog->len) 
				n = f->alog->len; 
1997/0327    
			d = 0; 
1998/0313    
			rptr = f->alog->rptr; 
			f->alog->rptr += n; 
			if(f->alog->rptr >= f->alog->end){ 
				d = f->alog->rptr - f->alog->end; 
				f->alog->rptr = f->alog->buf + d; 
1997/0327    
			} 
1998/0313    
			f->alog->len -= n; 
			unlock(f->alog); 
1997/0327    
 
1999/0731    
			i = n-d; 
1997/0327    
			p = a; 
			memmove(p, rptr, i); 
1999/0731    
			memmove(p+i, f->alog->buf, d); 
1997/0327    
			break; 
		} 
		else 
1998/0313    
			unlock(f->alog); 
1997/0327    
 
1998/0314    
		sleep(f->alog, netlogready, f); 
1997/0327    
	} 
 
1998/0313    
	qunlock(f->alog); 
1997/0327    
	poperror(); 
 
	return n; 
} 
 
2001/1120    
void 
netlogctl(Fs *f, char* s, int n) 
1997/0327    
{ 
2001/1120    
	int i, set; 
1999/0316    
	Netlogflag *fp; 
2001/1120    
	Cmdbuf *cb; 
	Cmdtab *ct; 
1997/0327    
 
2001/1120    
	cb = parsecmd(s, n); 
	if(waserror()){ 
		free(cb); 
		nexterror(); 
	} 
1997/0327    
 
2001/1120    
	if(cb->nf < 2) 
		error(Ebadnetctl); 
1997/0327    
 
2001/1120    
	ct = lookupcmd(cb, routecmd, nelem(routecmd)); 
1997/0327    
 
2001/1120    
	SET(set); 
 
	switch(ct->index){ 
	case CMset: 
1997/0327    
		set = 1; 
2001/1120    
		break; 
 
	case CMclear: 
1997/0327    
		set = 0; 
2001/1120    
		break; 
 
	case CMonly: 
		parseip(f->alog->iponly, cb->f[1]); 
1998/0313    
		if(ipcmp(f->alog->iponly, IPnoaddr) == 0) 
			f->alog->iponlyset = 0; 
1998/0306    
		else 
1998/0313    
			f->alog->iponlyset = 1; 
2001/1120    
		free(cb); 
		return; 
1997/0327    
 
2001/1120    
	default: 
		cmderror(cb, "unknown ip control message"); 
	} 
1997/0327    
 
2002/0507    
	for(i = 1; i < n; i++){ 
2002/0615    
	for(i = 1; i < cb->nf; i++){ 
1998/0313    
		for(fp = flags; fp->name; fp++) 
2001/1120    
			if(strcmp(fp->name, cb->f[i]) == 0) 
1997/0327    
				break; 
1998/0313    
		if(fp->name == nil) 
1997/0327    
			continue; 
		if(set) 
1998/0313    
			f->alog->logmask |= fp->mask; 
1997/0327    
		else 
1998/0313    
			f->alog->logmask &= ~fp->mask; 
1997/0327    
	} 
 
2001/1120    
	free(cb); 
	poperror(); 
1997/0327    
} 
 
void 
1998/0313    
netlog(Fs *f, int mask, char *fmt, ...) 
1997/0327    
{ 
1998/0313    
	char buf[128], *t, *fp; 
1997/0327    
	int i, n; 
	va_list arg; 
 
1998/0313    
	if(!(f->alog->logmask & mask)) 
1997/0327    
		return; 
 
1998/0313    
	if(f->alog->opens == 0) 
1997/0327    
		return; 
2002/0217    
 
	va_start(arg, fmt); 
	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf; 
	va_end(arg); 
1997/0327    
 
1998/0313    
	lock(f->alog); 
	i = f->alog->len + n - Nlog; 
1997/0327    
	if(i > 0){ 
1998/0313    
		f->alog->len -= i; 
		f->alog->rptr += i; 
		if(f->alog->rptr >= f->alog->end) 
			f->alog->rptr = f->alog->buf + (f->alog->rptr - f->alog->end); 
1997/0327    
	} 
1998/0313    
	t = f->alog->rptr + f->alog->len; 
	fp = buf; 
	f->alog->len += n; 
1997/0327    
	while(n-- > 0){ 
1998/0313    
		if(t >= f->alog->end) 
			t = f->alog->buf + (t - f->alog->end); 
		*t++ = *fp++; 
1997/0327    
	} 
1998/0313    
	unlock(f->alog); 
1997/0327    
 
1998/0313    
	wakeup(f->alog); 
1997/0327    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)