netstat.c 4.4 KB

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