netlog.c 3.9 KB

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