xref: /inferno-os/os/ip/netlog.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"u.h"
2*74a4d8c2SCharles.Forsyth #include	"../port/lib.h"
3*74a4d8c2SCharles.Forsyth #include	"mem.h"
4*74a4d8c2SCharles.Forsyth #include	"dat.h"
5*74a4d8c2SCharles.Forsyth #include	"fns.h"
6*74a4d8c2SCharles.Forsyth #include	"../port/error.h"
7*74a4d8c2SCharles.Forsyth #include	"../ip/ip.h"
8*74a4d8c2SCharles.Forsyth 
9*74a4d8c2SCharles.Forsyth enum {
10*74a4d8c2SCharles.Forsyth 	Nlog		= 4*1024,
11*74a4d8c2SCharles.Forsyth };
12*74a4d8c2SCharles.Forsyth 
13*74a4d8c2SCharles.Forsyth /*
14*74a4d8c2SCharles.Forsyth  *  action log
15*74a4d8c2SCharles.Forsyth  */
16*74a4d8c2SCharles.Forsyth struct Netlog {
17*74a4d8c2SCharles.Forsyth 	Lock;
18*74a4d8c2SCharles.Forsyth 	int	opens;
19*74a4d8c2SCharles.Forsyth 	char*	buf;
20*74a4d8c2SCharles.Forsyth 	char	*end;
21*74a4d8c2SCharles.Forsyth 	char	*rptr;
22*74a4d8c2SCharles.Forsyth 	int	len;
23*74a4d8c2SCharles.Forsyth 
24*74a4d8c2SCharles.Forsyth 	int	logmask;			/* mask of things to debug */
25*74a4d8c2SCharles.Forsyth 	uchar	iponly[IPaddrlen];		/* ip address to print debugging for */
26*74a4d8c2SCharles.Forsyth 	int	iponlyset;
27*74a4d8c2SCharles.Forsyth 
28*74a4d8c2SCharles.Forsyth 	QLock;
29*74a4d8c2SCharles.Forsyth 	Rendez;
30*74a4d8c2SCharles.Forsyth };
31*74a4d8c2SCharles.Forsyth 
32*74a4d8c2SCharles.Forsyth typedef struct Netlogflag {
33*74a4d8c2SCharles.Forsyth 	char*	name;
34*74a4d8c2SCharles.Forsyth 	int	mask;
35*74a4d8c2SCharles.Forsyth } Netlogflag;
36*74a4d8c2SCharles.Forsyth 
37*74a4d8c2SCharles.Forsyth static Netlogflag flags[] =
38*74a4d8c2SCharles.Forsyth {
39*74a4d8c2SCharles.Forsyth 	{ "ppp",	Logppp, },
40*74a4d8c2SCharles.Forsyth 	{ "ip",		Logip, },
41*74a4d8c2SCharles.Forsyth 	{ "fs",		Logfs, },
42*74a4d8c2SCharles.Forsyth 	{ "tcp",	Logtcp, },
43*74a4d8c2SCharles.Forsyth 	{ "il",		Logil, },
44*74a4d8c2SCharles.Forsyth 	{ "icmp",	Logicmp, },
45*74a4d8c2SCharles.Forsyth 	{ "udp",	Logudp, },
46*74a4d8c2SCharles.Forsyth 	{ "compress",	Logcompress, },
47*74a4d8c2SCharles.Forsyth 	{ "ilmsg",	Logil|Logilmsg, },
48*74a4d8c2SCharles.Forsyth 	{ "gre",	Loggre, },
49*74a4d8c2SCharles.Forsyth 	{ "tcpwin",	Logtcp|Logtcpwin, },
50*74a4d8c2SCharles.Forsyth 	{ "tcprxmt",	Logtcp|Logtcprxmt, },
51*74a4d8c2SCharles.Forsyth 	{ "udpmsg",	Logudp|Logudpmsg, },
52*74a4d8c2SCharles.Forsyth 	{ "ipmsg",	Logip|Logipmsg, },
53*74a4d8c2SCharles.Forsyth 	{ "esp",	Logesp, },
54*74a4d8c2SCharles.Forsyth 	{ nil,		0, },
55*74a4d8c2SCharles.Forsyth };
56*74a4d8c2SCharles.Forsyth 
57*74a4d8c2SCharles.Forsyth char Ebadnetctl[] = "too few arguments for netlog control message";
58*74a4d8c2SCharles.Forsyth 
59*74a4d8c2SCharles.Forsyth enum
60*74a4d8c2SCharles.Forsyth {
61*74a4d8c2SCharles.Forsyth 	CMset,
62*74a4d8c2SCharles.Forsyth 	CMclear,
63*74a4d8c2SCharles.Forsyth 	CMonly,
64*74a4d8c2SCharles.Forsyth };
65*74a4d8c2SCharles.Forsyth 
66*74a4d8c2SCharles.Forsyth static
67*74a4d8c2SCharles.Forsyth Cmdtab routecmd[] = {
68*74a4d8c2SCharles.Forsyth 	CMset,		"set",		0,
69*74a4d8c2SCharles.Forsyth 	CMclear,	"clear",	0,
70*74a4d8c2SCharles.Forsyth 	CMonly,		"only",		0,
71*74a4d8c2SCharles.Forsyth };
72*74a4d8c2SCharles.Forsyth 
73*74a4d8c2SCharles.Forsyth void
netloginit(Fs * f)74*74a4d8c2SCharles.Forsyth netloginit(Fs *f)
75*74a4d8c2SCharles.Forsyth {
76*74a4d8c2SCharles.Forsyth 	f->alog = smalloc(sizeof(Netlog));
77*74a4d8c2SCharles.Forsyth }
78*74a4d8c2SCharles.Forsyth 
79*74a4d8c2SCharles.Forsyth void
netlogopen(Fs * f)80*74a4d8c2SCharles.Forsyth netlogopen(Fs *f)
81*74a4d8c2SCharles.Forsyth {
82*74a4d8c2SCharles.Forsyth 	lock(f->alog);
83*74a4d8c2SCharles.Forsyth 	if(waserror()){
84*74a4d8c2SCharles.Forsyth 		unlock(f->alog);
85*74a4d8c2SCharles.Forsyth 		nexterror();
86*74a4d8c2SCharles.Forsyth 	}
87*74a4d8c2SCharles.Forsyth 	if(f->alog->opens == 0){
88*74a4d8c2SCharles.Forsyth 		if(f->alog->buf == nil)
89*74a4d8c2SCharles.Forsyth 			f->alog->buf = malloc(Nlog);
90*74a4d8c2SCharles.Forsyth 		f->alog->rptr = f->alog->buf;
91*74a4d8c2SCharles.Forsyth 		f->alog->end = f->alog->buf + Nlog;
92*74a4d8c2SCharles.Forsyth 	}
93*74a4d8c2SCharles.Forsyth 	f->alog->opens++;
94*74a4d8c2SCharles.Forsyth 	unlock(f->alog);
95*74a4d8c2SCharles.Forsyth 	poperror();
96*74a4d8c2SCharles.Forsyth }
97*74a4d8c2SCharles.Forsyth 
98*74a4d8c2SCharles.Forsyth void
netlogclose(Fs * f)99*74a4d8c2SCharles.Forsyth netlogclose(Fs *f)
100*74a4d8c2SCharles.Forsyth {
101*74a4d8c2SCharles.Forsyth 	lock(f->alog);
102*74a4d8c2SCharles.Forsyth 	if(waserror()){
103*74a4d8c2SCharles.Forsyth 		unlock(f->alog);
104*74a4d8c2SCharles.Forsyth 		nexterror();
105*74a4d8c2SCharles.Forsyth 	}
106*74a4d8c2SCharles.Forsyth 	f->alog->opens--;
107*74a4d8c2SCharles.Forsyth 	if(f->alog->opens == 0){
108*74a4d8c2SCharles.Forsyth 		free(f->alog->buf);
109*74a4d8c2SCharles.Forsyth 		f->alog->buf = nil;
110*74a4d8c2SCharles.Forsyth 	}
111*74a4d8c2SCharles.Forsyth 	unlock(f->alog);
112*74a4d8c2SCharles.Forsyth 	poperror();
113*74a4d8c2SCharles.Forsyth }
114*74a4d8c2SCharles.Forsyth 
115*74a4d8c2SCharles.Forsyth static int
netlogready(void * a)116*74a4d8c2SCharles.Forsyth netlogready(void *a)
117*74a4d8c2SCharles.Forsyth {
118*74a4d8c2SCharles.Forsyth 	Fs *f = a;
119*74a4d8c2SCharles.Forsyth 
120*74a4d8c2SCharles.Forsyth 	return f->alog->len;
121*74a4d8c2SCharles.Forsyth }
122*74a4d8c2SCharles.Forsyth 
123*74a4d8c2SCharles.Forsyth long
netlogread(Fs * f,void * a,ulong,long n)124*74a4d8c2SCharles.Forsyth netlogread(Fs *f, void *a, ulong, long n)
125*74a4d8c2SCharles.Forsyth {
126*74a4d8c2SCharles.Forsyth 	int i, d;
127*74a4d8c2SCharles.Forsyth 	char *p, *rptr;
128*74a4d8c2SCharles.Forsyth 
129*74a4d8c2SCharles.Forsyth 	qlock(f->alog);
130*74a4d8c2SCharles.Forsyth 	if(waserror()){
131*74a4d8c2SCharles.Forsyth 		qunlock(f->alog);
132*74a4d8c2SCharles.Forsyth 		nexterror();
133*74a4d8c2SCharles.Forsyth 	}
134*74a4d8c2SCharles.Forsyth 
135*74a4d8c2SCharles.Forsyth 	for(;;){
136*74a4d8c2SCharles.Forsyth 		lock(f->alog);
137*74a4d8c2SCharles.Forsyth 		if(f->alog->len){
138*74a4d8c2SCharles.Forsyth 			if(n > f->alog->len)
139*74a4d8c2SCharles.Forsyth 				n = f->alog->len;
140*74a4d8c2SCharles.Forsyth 			d = 0;
141*74a4d8c2SCharles.Forsyth 			rptr = f->alog->rptr;
142*74a4d8c2SCharles.Forsyth 			f->alog->rptr += n;
143*74a4d8c2SCharles.Forsyth 			if(f->alog->rptr >= f->alog->end){
144*74a4d8c2SCharles.Forsyth 				d = f->alog->rptr - f->alog->end;
145*74a4d8c2SCharles.Forsyth 				f->alog->rptr = f->alog->buf + d;
146*74a4d8c2SCharles.Forsyth 			}
147*74a4d8c2SCharles.Forsyth 			f->alog->len -= n;
148*74a4d8c2SCharles.Forsyth 			unlock(f->alog);
149*74a4d8c2SCharles.Forsyth 
150*74a4d8c2SCharles.Forsyth 			i = n-d;
151*74a4d8c2SCharles.Forsyth 			p = a;
152*74a4d8c2SCharles.Forsyth 			memmove(p, rptr, i);
153*74a4d8c2SCharles.Forsyth 			memmove(p+i, f->alog->buf, d);
154*74a4d8c2SCharles.Forsyth 			break;
155*74a4d8c2SCharles.Forsyth 		}
156*74a4d8c2SCharles.Forsyth 		else
157*74a4d8c2SCharles.Forsyth 			unlock(f->alog);
158*74a4d8c2SCharles.Forsyth 
159*74a4d8c2SCharles.Forsyth 		sleep(f->alog, netlogready, f);
160*74a4d8c2SCharles.Forsyth 	}
161*74a4d8c2SCharles.Forsyth 
162*74a4d8c2SCharles.Forsyth 	qunlock(f->alog);
163*74a4d8c2SCharles.Forsyth 	poperror();
164*74a4d8c2SCharles.Forsyth 
165*74a4d8c2SCharles.Forsyth 	return n;
166*74a4d8c2SCharles.Forsyth }
167*74a4d8c2SCharles.Forsyth 
168*74a4d8c2SCharles.Forsyth void
netlogctl(Fs * f,char * s,int n)169*74a4d8c2SCharles.Forsyth netlogctl(Fs *f, char* s, int n)
170*74a4d8c2SCharles.Forsyth {
171*74a4d8c2SCharles.Forsyth 	int i, set;
172*74a4d8c2SCharles.Forsyth 	Netlogflag *fp;
173*74a4d8c2SCharles.Forsyth 	Cmdbuf *cb;
174*74a4d8c2SCharles.Forsyth 	Cmdtab *ct;
175*74a4d8c2SCharles.Forsyth 
176*74a4d8c2SCharles.Forsyth 	cb = parsecmd(s, n);
177*74a4d8c2SCharles.Forsyth 	if(waserror()){
178*74a4d8c2SCharles.Forsyth 		free(cb);
179*74a4d8c2SCharles.Forsyth 		nexterror();
180*74a4d8c2SCharles.Forsyth 	}
181*74a4d8c2SCharles.Forsyth 
182*74a4d8c2SCharles.Forsyth 	if(cb->nf < 2)
183*74a4d8c2SCharles.Forsyth 		error(Ebadnetctl);
184*74a4d8c2SCharles.Forsyth 
185*74a4d8c2SCharles.Forsyth 	ct = lookupcmd(cb, routecmd, nelem(routecmd));
186*74a4d8c2SCharles.Forsyth 
187*74a4d8c2SCharles.Forsyth 	SET(set);
188*74a4d8c2SCharles.Forsyth 
189*74a4d8c2SCharles.Forsyth 	switch(ct->index){
190*74a4d8c2SCharles.Forsyth 	case CMset:
191*74a4d8c2SCharles.Forsyth 		set = 1;
192*74a4d8c2SCharles.Forsyth 		break;
193*74a4d8c2SCharles.Forsyth 
194*74a4d8c2SCharles.Forsyth 	case CMclear:
195*74a4d8c2SCharles.Forsyth 		set = 0;
196*74a4d8c2SCharles.Forsyth 		break;
197*74a4d8c2SCharles.Forsyth 
198*74a4d8c2SCharles.Forsyth 	case CMonly:
199*74a4d8c2SCharles.Forsyth 		parseip(f->alog->iponly, cb->f[1]);
200*74a4d8c2SCharles.Forsyth 		if(ipcmp(f->alog->iponly, IPnoaddr) == 0)
201*74a4d8c2SCharles.Forsyth 			f->alog->iponlyset = 0;
202*74a4d8c2SCharles.Forsyth 		else
203*74a4d8c2SCharles.Forsyth 			f->alog->iponlyset = 1;
204*74a4d8c2SCharles.Forsyth 		free(cb);
205*74a4d8c2SCharles.Forsyth 		return;
206*74a4d8c2SCharles.Forsyth 
207*74a4d8c2SCharles.Forsyth 	default:
208*74a4d8c2SCharles.Forsyth 		cmderror(cb, "unknown ip control message");
209*74a4d8c2SCharles.Forsyth 	}
210*74a4d8c2SCharles.Forsyth 
211*74a4d8c2SCharles.Forsyth 	for(i = 1; i < cb->nf; i++){
212*74a4d8c2SCharles.Forsyth 		for(fp = flags; fp->name; fp++)
213*74a4d8c2SCharles.Forsyth 			if(strcmp(fp->name, cb->f[i]) == 0)
214*74a4d8c2SCharles.Forsyth 				break;
215*74a4d8c2SCharles.Forsyth 		if(fp->name == nil)
216*74a4d8c2SCharles.Forsyth 			continue;
217*74a4d8c2SCharles.Forsyth 		if(set)
218*74a4d8c2SCharles.Forsyth 			f->alog->logmask |= fp->mask;
219*74a4d8c2SCharles.Forsyth 		else
220*74a4d8c2SCharles.Forsyth 			f->alog->logmask &= ~fp->mask;
221*74a4d8c2SCharles.Forsyth 	}
222*74a4d8c2SCharles.Forsyth 
223*74a4d8c2SCharles.Forsyth 	free(cb);
224*74a4d8c2SCharles.Forsyth 	poperror();
225*74a4d8c2SCharles.Forsyth }
226*74a4d8c2SCharles.Forsyth 
227*74a4d8c2SCharles.Forsyth void
netlog(Fs * f,int mask,char * fmt,...)228*74a4d8c2SCharles.Forsyth netlog(Fs *f, int mask, char *fmt, ...)
229*74a4d8c2SCharles.Forsyth {
230*74a4d8c2SCharles.Forsyth 	char buf[128], *t, *fp;
231*74a4d8c2SCharles.Forsyth 	int i, n;
232*74a4d8c2SCharles.Forsyth 	va_list arg;
233*74a4d8c2SCharles.Forsyth 
234*74a4d8c2SCharles.Forsyth 	if(!(f->alog->logmask & mask))
235*74a4d8c2SCharles.Forsyth 		return;
236*74a4d8c2SCharles.Forsyth 
237*74a4d8c2SCharles.Forsyth 	if(f->alog->opens == 0)
238*74a4d8c2SCharles.Forsyth 		return;
239*74a4d8c2SCharles.Forsyth 
240*74a4d8c2SCharles.Forsyth 	va_start(arg, fmt);
241*74a4d8c2SCharles.Forsyth 	n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
242*74a4d8c2SCharles.Forsyth 	va_end(arg);
243*74a4d8c2SCharles.Forsyth 
244*74a4d8c2SCharles.Forsyth 	lock(f->alog);
245*74a4d8c2SCharles.Forsyth 	i = f->alog->len + n - Nlog;
246*74a4d8c2SCharles.Forsyth 	if(i > 0){
247*74a4d8c2SCharles.Forsyth 		f->alog->len -= i;
248*74a4d8c2SCharles.Forsyth 		f->alog->rptr += i;
249*74a4d8c2SCharles.Forsyth 		if(f->alog->rptr >= f->alog->end)
250*74a4d8c2SCharles.Forsyth 			f->alog->rptr = f->alog->buf + (f->alog->rptr - f->alog->end);
251*74a4d8c2SCharles.Forsyth 	}
252*74a4d8c2SCharles.Forsyth 	t = f->alog->rptr + f->alog->len;
253*74a4d8c2SCharles.Forsyth 	fp = buf;
254*74a4d8c2SCharles.Forsyth 	f->alog->len += n;
255*74a4d8c2SCharles.Forsyth 	while(n-- > 0){
256*74a4d8c2SCharles.Forsyth 		if(t >= f->alog->end)
257*74a4d8c2SCharles.Forsyth 			t = f->alog->buf + (t - f->alog->end);
258*74a4d8c2SCharles.Forsyth 		*t++ = *fp++;
259*74a4d8c2SCharles.Forsyth 	}
260*74a4d8c2SCharles.Forsyth 	unlock(f->alog);
261*74a4d8c2SCharles.Forsyth 
262*74a4d8c2SCharles.Forsyth 	wakeup(f->alog);
263*74a4d8c2SCharles.Forsyth }
264