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