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

2000/0308/ip/netlog.c (diff list | history)

ip/netlog.c on 1997/0327
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, }, 
}; 
 
static char Ebadnetctl[] = "unknown netlog ctl message"; 
 
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; 
} 
 
char* 
1998/0313    
netlogctl(Fs *f, char* s, int len) 
1997/0327    
{ 
	int i, n, set; 
1999/0316    
	Netlogflag *fp; 
1997/0423    
	char *fields[10], *p, buf[256]; 
1997/0327    
 
	if(len == 0) 
		return Ebadnetctl; 
 
	if(len >= sizeof(buf)) 
		len = sizeof(buf)-1; 
	strncpy(buf, s, len); 
	buf[len] = 0; 
	if(len > 0 && buf[len-1] == '\n') 
		buf[len-1] = 0; 
 
2000/0308    
	n = getfields(buf, fields, 10, 1, " "); 
1997/0327    
	if(n < 2) 
		return Ebadnetctl; 
 
	if(strcmp("set", fields[0]) == 0) 
		set = 1; 
	else if(strcmp("clear", fields[0]) == 0) 
		set = 0; 
	else if(strcmp("only", fields[0]) == 0){ 
1998/0313    
		parseip(f->alog->iponly, fields[1]); 
		if(ipcmp(f->alog->iponly, IPnoaddr) == 0) 
			f->alog->iponlyset = 0; 
1998/0306    
		else 
1998/0313    
			f->alog->iponlyset = 1; 
1997/0327    
		return nil; 
	} else 
		return Ebadnetctl; 
 
	p = strchr(fields[n-1], '\n'); 
	if(p) 
		*p = 0; 
 
	for(i = 1; i < n; i++){ 
1998/0313    
		for(fp = flags; fp->name; fp++) 
			if(strcmp(fp->name, fields[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    
	} 
 
	return nil; 
} 
 
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; 
 
	va_start(arg, fmt); 
	n = doprint(buf, buf+sizeof(buf), fmt, arg) - buf; 
	va_end(arg); 
1998/0306    
 
1998/0313    
	if(f->alog->opens == 0) 
1997/0327    
		return; 
 
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)