1 #include <u.h> 2 #include <libc.h> 3 #include <bio.h> 4 #include <ip.h> 5 #include <ndb.h> 6 7 void pip(char*, char*); 8 void pipifc(char*, char*); 9 void nstat(char*, void (*)(char*, char*)); 10 11 Biobuf out; 12 char *netroot; 13 int notrans; 14 15 void 16 usage(void){ 17 fprint(2, "usage: %s [-in] [network-dir]\n", argv0); 18 exits("usage"); 19 } 20 21 void 22 main(int argc, char *argv[]) 23 { 24 int justinterfaces = 0; 25 26 ARGBEGIN{ 27 case 'n': 28 notrans = 1; 29 break; 30 case 'i': 31 justinterfaces = 1; 32 break; 33 default: 34 usage(); 35 }ARGEND; 36 37 netroot = "/net"; 38 switch(argc){ 39 case 0: 40 break; 41 case 1: 42 netroot = argv[0]; 43 break; 44 default: 45 usage(); 46 } 47 48 Binit(&out, 1, OWRITE); 49 50 if(justinterfaces){ 51 nstat("ipifc", pipifc); 52 exits(0); 53 } 54 55 nstat("tcp", pip); 56 nstat("udp", pip); 57 nstat("rudp", pip); 58 nstat("il", pip); 59 60 exits(0); 61 } 62 63 void 64 nstat(char *net, void (*f)(char*, char*)) 65 { 66 int fdir, i, n, tot; 67 char dir[500*DIRLEN], *mem; 68 69 sprint(dir, "%s/%s", netroot, net); 70 fdir = open(dir, OREAD); 71 if(fdir < 0) 72 return; 73 74 mem = sbrk(0); 75 tot = 0; 76 while((n = read(fdir, dir, sizeof dir)) > 0){ 77 if(brk((void*)(mem + tot + n)) == -1) { 78 fprint(2, "netstat: out of memory"); 79 return; 80 } 81 memmove(mem+tot, dir, n); 82 tot += n; 83 } 84 for(i = 0; i < tot; i += DIRLEN) { 85 (*f)(net, mem+i); 86 Bflush(&out); 87 } 88 close(fdir); 89 } 90 91 char* 92 getport(char *net, char *p) 93 { 94 static char buf[Ndbvlen]; 95 Ndbtuple *t; 96 97 if(notrans) 98 return p; 99 t = csgetval(netroot, "port", p, net, buf); 100 if(t) 101 ndbfree(t); 102 if(buf[0] == 0) 103 return p; 104 return buf; 105 } 106 107 void 108 pip(char *net, char *entry) 109 { 110 Dir db; 111 int n, fd; 112 char buf[128], *p; 113 Ndbtuple *tp; 114 char dname[Ndbvlen]; 115 116 if(strcmp(entry, "clone") == 0) 117 return; 118 if(strcmp(entry, "stats") == 0) 119 return; 120 121 sprint(buf, "%s/%s/%s/ctl", netroot, net, entry); 122 if(dirstat(buf, &db) < 0) 123 return; 124 125 sprint(buf, "%s/%s/%s/status", netroot, net, entry); 126 fd = open(buf, OREAD); 127 if(fd < 0) 128 return; 129 130 n = read(fd, buf, sizeof(buf)); 131 if(n < 0) 132 return; 133 buf[n] = 0; 134 close(fd); 135 136 p = strchr(buf, ' '); 137 if(p != 0) 138 *p = 0; 139 140 Bprint(&out, "%-4s %-4s %-10s %-12s ", net, entry, db.uid, buf); 141 142 sprint(buf, "%s/%s/%s/local", netroot, net, entry); 143 fd = open(buf, OREAD); 144 if(fd < 0) { 145 Bprint(&out, "\n"); 146 return; 147 } 148 n = read(fd, buf, sizeof(buf)); 149 if(n < 0) { 150 Bprint(&out, "\n"); 151 return; 152 } 153 buf[n-1] = 0; 154 close(fd); 155 p = strchr(buf, '!'); 156 if(p == 0) { 157 Bprint(&out, "\n"); 158 return; 159 } 160 *p = '\0'; 161 Bprint(&out, "%-10s ", getport(net, p+1)); 162 163 sprint(buf, "%s/%s/%s/remote", netroot, net, entry); 164 fd = open(buf, OREAD); 165 if(fd < 0) { 166 print("\n"); 167 return; 168 } 169 n = read(fd, buf, sizeof(buf)); 170 if(n < 0) { 171 print("\n"); 172 return; 173 } 174 buf[n-1] = 0; 175 close(fd); 176 p = strchr(buf, '!'); 177 *p++ = '\0'; 178 179 if(notrans){ 180 Bprint(&out, "%-10s %s\n", getport(net, p), buf); 181 return; 182 } 183 tp = csgetval(netroot, "ip", buf, "dom", dname); 184 if(tp) 185 ndbfree(tp); 186 if(dname[0] == 0) { 187 Bprint(&out, "%-10s %s\n", getport(net, p), buf); 188 return; 189 } 190 Bprint(&out, "%-10s %s\n", getport(net, p), dname); 191 Bflush(&out); 192 } 193 194 void 195 pipifc(char *net, char *entry) 196 { 197 int n, fd; 198 char buf[128], *p; 199 char *f[9]; 200 201 if(strcmp(entry, "clone") == 0) 202 return; 203 if(strcmp(entry, "stats") == 0) 204 return; 205 206 sprint(buf, "%s/%s/%s/status", netroot, net, entry); 207 fd = open(buf, OREAD); 208 if(fd < 0) 209 return; 210 211 n = read(fd, buf, sizeof(buf)); 212 if(n < 0) 213 return; 214 buf[n] = 0; 215 close(fd); 216 217 n = getfields(buf, f, 9, 1, " \t\n"); 218 if(n < 7) 219 return; 220 p = strrchr(f[0], '/'); 221 if(p != nil) 222 f[0] = p+1; 223 224 if(n == 9) 225 Bprint(&out, "%-8s %-5s %-16s %-16s %-16s %-10s %-10s %-6s %-6s\n", 226 f[0], f[1], f[2], f[3], f[4], 227 f[5], f[6], f[7], f[8]); 228 else 229 Bprint(&out, " %-16s %-16s %-16s %-10s %-10s %-6s %-6s\n", 230 f[0], f[1], f[2], f[3], f[4], 231 f[5], f[6]); 232 } 233