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