netstat.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <ip.h>
  5. #include <ndb.h>
  6. void pip(char*, Dir*);
  7. void nstat(char*, void (*)(char*, Dir*));
  8. void pipifc(void);
  9. Biobuf out;
  10. char *netroot;
  11. int notrans;
  12. void
  13. usage(void){
  14. fprint(2, "usage: %s [-in] [network-dir]\n", argv0);
  15. exits("usage");
  16. }
  17. void
  18. main(int argc, char *argv[])
  19. {
  20. int justinterfaces = 0;
  21. int i, tot, fd;
  22. Dir *d;
  23. char buf[128];
  24. ARGBEGIN{
  25. case 'n':
  26. notrans = 1;
  27. break;
  28. case 'i':
  29. justinterfaces = 1;
  30. break;
  31. default:
  32. usage();
  33. }ARGEND;
  34. netroot = "/net";
  35. switch(argc){
  36. case 0:
  37. break;
  38. case 1:
  39. netroot = argv[0];
  40. break;
  41. default:
  42. usage();
  43. }
  44. Binit(&out, 1, OWRITE);
  45. if(justinterfaces){
  46. pipifc();
  47. exits(0);
  48. }
  49. fd = open(netroot, OREAD);
  50. if(fd < 0)
  51. sysfatal("open %s: %r", netroot);
  52. tot = dirreadall(fd, &d);
  53. for(i=0; i<tot; i++){
  54. if(strcmp(d[i].name, "ipifc") == 0)
  55. continue;
  56. snprint(buf, sizeof buf, "%s/%s/0/local", netroot, d[i].name);
  57. if(access(buf, 0) >= 0)
  58. nstat(d[i].name, pip);
  59. }
  60. exits(0);
  61. }
  62. void
  63. nstat(char *net, void (*f)(char*, Dir*))
  64. {
  65. int fdir, i, tot;
  66. Dir *dir;
  67. char buf[128];
  68. snprint(buf, sizeof buf, "%s/%s", netroot, net);
  69. fdir = open(buf, OREAD);
  70. if(fdir < 0)
  71. return;
  72. tot = dirreadall(fdir, &dir);
  73. for(i = 0; i < tot; i++) {
  74. (*f)(net, &dir[i]);
  75. Bflush(&out);
  76. }
  77. free(dir);
  78. close(fdir);
  79. }
  80. char*
  81. getport(char *net, char *p)
  82. {
  83. static char buf[Ndbvlen];
  84. Ndbtuple *t;
  85. if(notrans)
  86. return p;
  87. t = csgetval(netroot, "port", p, net, buf);
  88. if(t)
  89. ndbfree(t);
  90. if(buf[0] == 0)
  91. return p;
  92. return buf;
  93. }
  94. void
  95. pip(char *net, Dir *db)
  96. {
  97. int n, fd;
  98. char buf[128], *p;
  99. Ndbtuple *tp;
  100. char dname[Ndbvlen];
  101. if(strcmp(db->name, "clone") == 0)
  102. return;
  103. if(strcmp(db->name, "stats") == 0)
  104. return;
  105. snprint(buf, sizeof buf, "%s/%s/%s/ctl", netroot, net, db->name);
  106. sprint(buf, "%s/%s/%s/status", netroot, net, db->name);
  107. fd = open(buf, OREAD);
  108. if(fd < 0)
  109. return;
  110. n = read(fd, buf, sizeof(buf));
  111. if(n < 0)
  112. return;
  113. buf[n] = 0;
  114. close(fd);
  115. p = strchr(buf, ' ');
  116. if(p != 0)
  117. *p = 0;
  118. Bprint(&out, "%-4s %-4s %-10s %-12s ", net, db->name, db->uid, buf);
  119. sprint(buf, "%s/%s/%s/local", netroot, net, db->name);
  120. fd = open(buf, OREAD);
  121. if(fd < 0) {
  122. Bprint(&out, "\n");
  123. return;
  124. }
  125. n = read(fd, buf, sizeof(buf));
  126. if(n < 0) {
  127. Bprint(&out, "\n");
  128. return;
  129. }
  130. buf[n-1] = 0;
  131. close(fd);
  132. p = strchr(buf, '!');
  133. if(p == 0) {
  134. Bprint(&out, "\n");
  135. return;
  136. }
  137. *p = '\0';
  138. Bprint(&out, "%-10s ", getport(net, p+1));
  139. sprint(buf, "%s/%s/%s/remote", netroot, net, db->name);
  140. fd = open(buf, OREAD);
  141. if(fd < 0) {
  142. print("\n");
  143. return;
  144. }
  145. n = read(fd, buf, sizeof(buf));
  146. if(n < 0) {
  147. print("\n");
  148. return;
  149. }
  150. buf[n-1] = 0;
  151. close(fd);
  152. p = strchr(buf, '!');
  153. *p++ = '\0';
  154. if(notrans){
  155. Bprint(&out, "%-10s %s\n", getport(net, p), buf);
  156. return;
  157. }
  158. tp = csgetval(netroot, "ip", buf, "dom", dname);
  159. if(tp)
  160. ndbfree(tp);
  161. if(dname[0] == 0) {
  162. Bprint(&out, "%-10s %s\n", getport(net, p), buf);
  163. return;
  164. }
  165. Bprint(&out, "%-10s %s\n", getport(net, p), dname);
  166. Bflush(&out);
  167. }
  168. void
  169. pipifc(void)
  170. {
  171. Ipifc *ip, *nip;
  172. Iplifc *lifc;
  173. char buf[100];
  174. int l, i;
  175. fmtinstall('I', eipfmt);
  176. fmtinstall('M', eipfmt);
  177. ip = readipifc(netroot, nil, -1);
  178. l = 7;
  179. for(nip = ip; nip; nip = nip->next){
  180. for(lifc = nip->lifc; lifc; lifc = lifc->next){
  181. i = snprint(buf, sizeof buf, "%I", lifc->ip);
  182. if(i > l)
  183. l = i;
  184. i = snprint(buf, sizeof buf, "%I", lifc->net);
  185. if(i > l)
  186. l = i;
  187. }
  188. }
  189. for(nip = ip; nip; nip = nip->next){
  190. for(lifc = nip->lifc; lifc; lifc = lifc->next)
  191. Bprint(&out, "%-12s %5d %-*I %5.5M %-*I %8lud %8lud %8lud %8lud\n",
  192. nip->dev, nip->mtu,
  193. l, lifc->ip, lifc->mask, l, lifc->net,
  194. nip->pktin, nip->pktout,
  195. nip->errin, nip->errout);
  196. }
  197. Bflush(&out);
  198. }