| _ni=0; // network indent level |
| |
| defn |
| _ni() { |
| loop 1,_ni do { |
| print("\t"); |
| } |
| } |
| |
| defn |
| ipdev(n) { |
| _ipfs(*(ipfs+4*n)); |
| } |
| |
| // the funny _foo/foo pairs exist so that if we get |
| // interrupted in the middle of one of these, _ni will |
| // get reset to 0 next time an external call happens. |
| |
| defn |
| _ipfs(fs) { |
| complex Fs fs; |
| local i; |
| |
| print("ipfs(", fs\X, ") #I", fs.dev\D, "\n"); |
| i=0; |
| _ni = _ni+1; |
| while i < fs.np do { |
| _proto(*(fs.p+i*4)); |
| i = i + 1; |
| } |
| _ni = _ni-1; |
| } |
| |
| defn |
| ipfs(fs) { |
| _ni = 0; |
| _ipfs(fs); |
| } |
| |
| defn |
| _proto(p) { |
| local c; |
| complex Proto p; |
| _ni(); |
| print("proto(", p\X, ") ", *(p.name\s), "\n"); |
| _ni = _ni+1; |
| local i; |
| i = 0; |
| while i < p.nc do { |
| c = *(p.conv+i*4); |
| complex Conv c; |
| if c != 0 && c.inuse then |
| _conv(*(p.conv+i*4)); |
| i = i + 1; |
| } |
| _ni = _ni - 1; |
| } |
| |
| defn |
| proto(p) { |
| _ni = 0; |
| _proto(p); |
| } |
| |
| defn |
| _conv(c) { |
| complex Conv c; |
| _ni(); |
| local p; |
| p = c.p; |
| complex Proto p; |
| print("conv(", c\X, ") ", *(p.name\s), "/", c.x\D, " ", |
| iptostr(*(c.laddr+12)), "!", c.lport\D, " ", iptostr(*(c.raddr+12)), |
| "!", c.rport\D, " rq ", qtostr(c.rq), " wq ", qtostr(c.wq), |
| " eq ", qtostr(c.eq), "\n"); |
| } |
| |
| defn |
| conv(c) { |
| _ni = 0; |
| _conv(c); |
| } |
| |
| defn |
| iptostr(a) |
| { |
| // BUG: little endian |
| return itoa(a&0xFF)+"."+itoa((a>>8)&0xFF)+"."+itoa((a>>16)&0xFF)+"."+itoa((a>>24)&0xFF); |
| } |
| |
| defn |
| qtostr(q) |
| { |
| complex Queue q; |
| |
| return "queue("+itoa(q, "%lux")+") ["+itoa(q.len, "%d")+","+itoa(q.dlen, "%d")+","+itoa(qblocks(q), "%d")+"]"; |
| } |
| |
| defn |
| qblocks(q) |
| { |
| complex Queue q; |
| local b, n; |
| |
| b = q.bfirst; |
| n = 0; |
| while b != 0 do { |
| n = n + 1; |
| complex Block b; |
| b = b.next; |
| } |
| return n; |
| } |
| |
| defn |
| _queue(q) |
| { |
| complex Queue q; |
| local b; |
| |
| print("queue(", q\X, ") len ", q.len\D, " dlen ", q.dlen\D, " limit ", q.limit\D, " nblocks ", qblocks(q)\D); |
| if q.state & Qstarve then |
| print(" starve"); |
| if q.state & Qmsg then |
| print(" msg"); |
| if q.state & Qclosed then |
| print(" closed"); |
| if q.state & Qflow then |
| print(" flow"); |
| if q.state & Qcoalesce then |
| print(" coalesce"); |
| print("\n"); |
| |
| b = q.bfirst; |
| _ni = _ni+1; |
| while b != 0 do { |
| _block(b); |
| complex Block b; |
| b = b.next; |
| } |
| _ni = _ni - 1; |
| } |
| |
| defn |
| queue(q) |
| { |
| _ni = 0; |
| _queue(q); |
| } |
| |
| defn |
| _block(b) |
| { |
| complex Block b; |
| |
| _ni(); |
| print("block(", b\X, ") base ", b.base\X, " rp ", b.rp\X, "/", b.rp-b.base\D, " wp ", b.wp\X, "/", b.wp-b.base\D, " lim ", b.lim\X, "/", b.lim-b.base\D, "\n"); |
| } |
| |
| defn |
| block(b) |
| { |
| _ni = 0; |
| block(b); |
| } |
| |
| print(acidfile); |
| needacid("tcp"); |
| needacid("qio"); |