netstat.c 4.0 KB

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