netstat.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  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 port[10];
  84. strncpy(port, p, sizeof(port)-1);
  85. port[sizeof(port)-1] = 0;
  86. if(notrans || (p = csgetvalue(netroot, "port", p, net, nil)) == nil)
  87. return port;
  88. strncpy(port, p, sizeof(port)-1);
  89. port[sizeof(port)-1] = 0;
  90. free(p);
  91. return port;
  92. }
  93. void
  94. pip(char *net, Dir *db)
  95. {
  96. int n, fd;
  97. char buf[128], *p;
  98. char *dname;
  99. if(strcmp(db->name, "clone") == 0)
  100. return;
  101. if(strcmp(db->name, "stats") == 0)
  102. return;
  103. snprint(buf, sizeof buf, "%s/%s/%s/ctl", netroot, net, db->name);
  104. sprint(buf, "%s/%s/%s/status", netroot, net, db->name);
  105. fd = open(buf, OREAD);
  106. if(fd < 0)
  107. return;
  108. n = read(fd, buf, sizeof(buf));
  109. if(n < 0)
  110. return;
  111. buf[n] = 0;
  112. close(fd);
  113. p = strchr(buf, ' ');
  114. if(p != 0)
  115. *p = 0;
  116. Bprint(&out, "%-4s %-4s %-10s %-12s ", net, db->name, db->uid, buf);
  117. sprint(buf, "%s/%s/%s/local", netroot, net, db->name);
  118. fd = open(buf, OREAD);
  119. if(fd < 0) {
  120. Bprint(&out, "\n");
  121. return;
  122. }
  123. n = read(fd, buf, sizeof(buf));
  124. if(n < 0) {
  125. Bprint(&out, "\n");
  126. return;
  127. }
  128. buf[n-1] = 0;
  129. close(fd);
  130. p = strchr(buf, '!');
  131. if(p == 0) {
  132. Bprint(&out, "\n");
  133. return;
  134. }
  135. *p = '\0';
  136. Bprint(&out, "%-10s ", getport(net, p+1));
  137. sprint(buf, "%s/%s/%s/remote", netroot, net, db->name);
  138. fd = open(buf, OREAD);
  139. if(fd < 0) {
  140. print("\n");
  141. return;
  142. }
  143. n = read(fd, buf, sizeof(buf));
  144. if(n < 0) {
  145. print("\n");
  146. return;
  147. }
  148. buf[n-1] = 0;
  149. close(fd);
  150. p = strchr(buf, '!');
  151. *p++ = '\0';
  152. if(notrans){
  153. Bprint(&out, "%-10s %s\n", getport(net, p), buf);
  154. return;
  155. }
  156. dname = csgetvalue(netroot, "ip", buf, "dom", nil);
  157. if(dname == nil) {
  158. Bprint(&out, "%-10s %s\n", getport(net, p), buf);
  159. return;
  160. }
  161. Bprint(&out, "%-10s %s\n", getport(net, p), dname);
  162. Bflush(&out);
  163. free(dname);
  164. }
  165. void
  166. pipifc(void)
  167. {
  168. Ipifc *ip, *nip;
  169. Iplifc *lifc;
  170. char buf[100];
  171. int l, i;
  172. fmtinstall('I', eipfmt);
  173. fmtinstall('M', eipfmt);
  174. ip = readipifc(netroot, nil, -1);
  175. l = 7;
  176. for(nip = ip; nip; nip = nip->next){
  177. for(lifc = nip->lifc; lifc; lifc = lifc->next){
  178. i = snprint(buf, sizeof buf, "%I", lifc->ip);
  179. if(i > l)
  180. l = i;
  181. i = snprint(buf, sizeof buf, "%I", lifc->net);
  182. if(i > l)
  183. l = i;
  184. }
  185. }
  186. for(nip = ip; nip; nip = nip->next){
  187. for(lifc = nip->lifc; lifc; lifc = lifc->next)
  188. Bprint(&out, "%-12s %5d %-*I %5M %-*I %8lud %8lud %8lud %8lud\n",
  189. nip->dev, nip->mtu,
  190. l, lifc->ip, lifc->mask, l, lifc->net,
  191. nip->pktin, nip->pktout,
  192. nip->errin, nip->errout);
  193. }
  194. Bflush(&out);
  195. }