From ef78c62f7c7c8f5315ffe8a3eccc88c0a07f1042 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 16 Sep 1997 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1997-09-16 --- ip/devip.c | 9 ++++++--- ip/icmp.c | 31 +++++++++++++++++++++++++++++++ ip/igmp.c | 20 ++++++++++++++++++++ ip/il.c | 19 ++++++++++++++++++- ip/ip.c | 13 ++++++++++++- ip/ip.h | 2 +- ip/tcp.c | 17 ++++++++++++++++- 7 files changed, 104 insertions(+), 7 deletions(-) diff --git a/ip/devip.c b/ip/devip.c index 0fc0bb01eca30c1679d587644617eb170d41ce2b..d9a0e9c3b80729c6ced9749986b04d6a16e687b2 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -916,11 +916,14 @@ Fspcolstats(char *buf, int len) int n; n = 0; - for(p = fs.p; *p; p++) + for(p = fs.p; *p; p++){ n += snprint(buf + n, len - n, - "%s: csum %d hlen %d len %d order %d rexmit %d wc %d\n", + "%s: csum %d hlen %d len %d order %d rexmit %d\n", (*p)->name, (*p)->csumerr, (*p)->hlenerr, (*p)->lenerr, - (*p)->order, (*p)->rexmit, (*p)->wclosed); + (*p)->order, (*p)->rexmit); + if((*p)->stats) + n += (*(*p)->stats)(buf + n, len - n); + } return n; } diff --git a/ip/icmp.c b/ip/icmp.c index 0708aa16cf5222e81d6b665b3a38a72548ecf68d..b584facdf141f4f618184c082a67fe3a4705d2b4 100644 --- a/ip/icmp.c +++ b/ip/icmp.c @@ -36,6 +36,8 @@ enum { /* Packet Types */ TimestampReply = 14, InfoRequest = 15, InfoReply = 16, + + Maxtype = 16, }; enum { @@ -47,6 +49,12 @@ enum { Proto icmp; extern Fs fs; +static struct Icmpstats +{ + ulong in[Maxtype+1]; + ulong out[Maxtype+1]; +} stats; + static char* icmpconnect(Conv *c, char **argv, int argc) { @@ -112,6 +120,8 @@ icmpkick(Conv *c, int l) return; } p = (Icmp *)(bp->rp); + if(p->type <= Maxtype) + stats.out[p->type]++; hnputl(p->dst, c->raddr); hnputl(p->src, c->laddr); p->proto = IP_ICMPPROTO; @@ -141,6 +151,7 @@ icmpnoconv(Block *bp) hnputs(np->seq, 0); memset(np->cksum, 0, sizeof(np->cksum)); hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE)); + stats.out[Unreachable]++; ipoput(nbp, 0, MAXTTL); } @@ -221,9 +232,12 @@ icmpiput(Media *m, Block *bp) icmp.csumerr++; goto raise; } + if(p->type <= Maxtype) + stats.in[p->type]++; switch(p->type) { case EchoRequest: r = mkechoreply(bp); + stats.out[EchoReply]++; ipoput(r, 0, MAXTTL); break; case Unreachable: @@ -299,6 +313,22 @@ icmpadvise(Block *bp, char *msg) freeblist(bp); } +int +icmpstats(char *buf, int len) +{ + int i, n; + + n = snprint(buf, len, "\trcvd "); + for(i = 0; i < Maxtype && len > n; i++) + n += snprint(buf+n, len-n, " %d", stats.in[i]); + n += snprint(buf+n, len - n, "\n\tsent "); + for(i = 0; i < Maxtype && len > n; i++) + n += snprint(buf+n, len-n, " %d", stats.out[i]); + if(n < len) + n += snprint(buf+n, len-n, "\n"); + return n; +} + void icmpinit(Fs *fs) { @@ -310,6 +340,7 @@ icmpinit(Fs *fs) icmp.create = icmpcreate; icmp.close = icmpclose; icmp.rcv = icmpiput; + icmp.stats = icmpstats; icmp.ctl = nil; icmp.advise = icmpadvise; icmp.ipproto = IP_ICMPPROTO; diff --git a/ip/igmp.c b/ip/igmp.c index fbf1221f3457f1fdf2093d7313ce95d9fb74ff96..365efb465b7e5b472f20c3f17811e6a14e808fb9 100644 --- a/ip/igmp.c +++ b/ip/igmp.c @@ -68,6 +68,14 @@ IGMP igmpalloc; Proto igmp; extern Fs fs; +static struct Stats +{ + ulong inqueries; + ulong outqueries; + ulong inreports; + ulong outreports; +} stats; + void igmpsendreport(Media *m, byte *addr) { @@ -87,6 +95,7 @@ igmpsendreport(Media *m, byte *addr) memmove(p->group, addr, IPaddrlen); hnputs(p->igmpcksum, ptclcsum(bp, IGMP_IPHDRSIZE, IGMP_HDRSIZE)); netlog(Logigmp, "igmpreport %I\n", p->group); + stats.outreports++; ipoput(bp, 0, 1); /* TTL of 1 */ } @@ -190,6 +199,7 @@ igmpiput(Media *m, Block *bp) /* * start reporting groups that we're a member of. */ + stats.inqueries++; for(rp = igmpalloc.reports; rp; rp = rp->next) if(rp->m == m) break; @@ -219,6 +229,7 @@ igmpiput(Media *m, Block *bp) /* * find report list for this medium */ + stats.inreports++; lrp = &igmpalloc.reports; for(rp = *lrp; rp; rp = *lrp){ if(rp->m == m) @@ -250,6 +261,14 @@ error: freeb(bp); } +int +igmpstats(char *buf, int len) +{ + return snprint(buf, len, "\trcvd %d %d\n\tsent %d %d\n", + stats.inqueries, stats.inreports, + stats.outqueries, stats.outreports); +} + void igmpinit(Fs *fs) { @@ -261,6 +280,7 @@ igmpinit(Fs *fs) igmp.state = nil; igmp.close = nil; igmp.rcv = igmpiput; + igmp.stats = igmpstats; igmp.ipproto = IP_IGMPPROTO; igmp.nc = 0; igmp.ptclsize = 0; diff --git a/ip/il.c b/ip/il.c index 17f5bb2f4cc4026d9c93ee2189a56d11abe7af22..d8315e7fd08d5222ffedbc772248f0748f976c8b 100644 --- a/ip/il.c +++ b/ip/il.c @@ -122,6 +122,12 @@ struct Ilhdr byte ilack[4]; /* Acked sequence */ }; +static struct Ilstats +{ + ulong dup; + ulong dupb; +} ilstats; + /* Always Acktime < Fasttime < Slowtime << Ackkeepalive */ enum { @@ -329,6 +335,12 @@ ilcreate(Conv *c) c->wq = qopen(64*1024, 0, 0, 0); } +int +ilxstats(char *buf, int len) +{ + return snprint(buf, len, "\tdupp %d dupb %d\n", ilstats.dup, ilstats.dupb); +} + void ilinit(Fs *fs) { @@ -342,6 +354,7 @@ ilinit(Fs *fs) il.rcv = iliput; il.ctl = nil; il.advise = iladvise; + il.stats = ilxstats; il.ipproto = IP_ILPROTO; il.nc = Nchans; il.ptclsize = sizeof(Ilcb); @@ -819,8 +832,10 @@ ilpullup(Conv *s) freeblist(bp); continue; } - if(oid != ic->recvd+1) + if(oid != ic->recvd+1){ + il.order++; break; + } ic->recvd = oid; ic->outoforder = bp->list; @@ -871,6 +886,8 @@ iloutoforder(Conv *s, Ilhdr *h, Block *bp) newid = nhgetl(lid); if(id <= newid) { if(id == newid) { + ilstats.dup++; + ilstats.dupb += blocklen(bp); qunlock(&ic->outo); freeblist(bp); return; diff --git a/ip/ip.c b/ip/ip.c index 96df261f0bcdfcbf0148bab6351207dd549164b6..6fdb068c59e1e955c038c60a16c453ee5b17cc13 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -67,6 +67,12 @@ ulong ipout, ippout; /* bytes, packets out */ */ #define BKFG(xp) ((Ipfrag*)((xp)->base)) +static struct Stats +{ + ulong noroute; + ulong droppedfrag; +} stats; + ushort ipcsum(byte*); Block* ipreassemble(int, Block*, Iphdr*); void ipfragfree(Fragment*); @@ -109,6 +115,7 @@ ipoput(Block *bp, int gating, int ttl) } else m = Mediaroute(eh->dst, gate); if(m == nil){ + stats.noroute++; netlog(Logip, "no interface %I\n", eh->dst); goto raise; } @@ -307,6 +314,8 @@ ipstats(char *buf, int len) n = snprint(buf, len, "ip: csum %lud inb %lud outb %lud inp %lud outp %lud\n", ipcsumerr, ipin, ipout, ippin, ippout); + n += snprint(buf+n, len - n, "\tnoroute %lud droppedfrag %lud\n", + stats.noroute, stats.droppedfrag); return n; } @@ -341,8 +350,10 @@ ipreassemble(int offset, Block *bp, Iphdr *ip) fnext = f->next; /* because ipfragfree changes the list */ if(f->src == src && f->dst == dst && f->id == id) break; - if(f->age < msec) + if(f->age < msec){ + stats.droppedfrag++; ipfragfree(f); + } } /* diff --git a/ip/ip.h b/ip/ip.h index 955d93e655bf904e75716406c27b9bbed194446d..b1364947e63e8cdda19e07d088b3b6fc6b1a1b61 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -169,6 +169,7 @@ struct Proto void (*rcv)(Media*, Block*); char* (*ctl)(Conv*, char**, int); void (*advise)(Block*, char*); + int (*stats)(char*, int); Conv **conv; /* array of conversations */ int ptclsize; /* size of per protocol ctl block */ @@ -183,7 +184,6 @@ struct Proto ulong lenerr; /* short packet */ ulong order; /* out of order */ ulong rexmit; /* retransmissions */ - ulong wclosed; /* window closed */ }; struct Fs diff --git a/ip/tcp.c b/ip/tcp.c index 54929477d8423dc832a7e3e77f0d620412c44361..5ca168b8175aa9f91e5623134caa21d634f218c0 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -186,6 +186,12 @@ ushort tcp_mss = DEF_MSS; /* Maximum segment size to be sent */ Timer *timers; /* List of active timers */ QLock tl; /* Protect timer list */ +static struct Tcpstats +{ + ulong dup; /* (partially) duplicated packets */ + ulong dupb; /* duplicated bytes */ +} tstats; + void addreseq(Tcpctl*, Tcp*, Block*, ushort); void getreseq(Tcpctl*, Tcp*, Block**, ushort*); void localclose(Conv*, char*); @@ -1250,6 +1256,7 @@ tcpiput(Media *m, Block *bp) if(seg.seq != tcb->rcv.nxt) if(length != 0 || (seg.flags & (SYN|FIN))) { update(s, &seg); + tcp.order++; addreseq(tcb, &seg, bp, length); tcb->flags |= FORCE; goto output; @@ -1469,7 +1476,6 @@ tcpoutput(Conv *s) * window probes to one */ if(tcb->snd.wnd == 0){ - tcp.wclosed++; if(sent != 0) { if ((tcb->flags&FORCE) == 0) break; @@ -1846,6 +1852,8 @@ tcptrim(Tcpctl *tcb, Tcp *seg, Block **bp, ushort *length) dupcnt = tcb->rcv.nxt - seg->seq; if(dupcnt > 0){ tcb->rerecv += dupcnt; + tstats.dup++; + tstats.dupb += dupcnt; if(seg->flags & SYN){ seg->flags &= ~SYN; seg->seq++; @@ -1924,6 +1932,12 @@ tcpctl(Conv* c, char** f, int n) return "unknown control request"; } +int +tcpstats(char *buf, int len) +{ + return snprint(buf, len, "\tdupp %d dupb %d\n", tstats.dup, tstats.dupb); +} + void tcpinit(Fs *fs) { @@ -1937,6 +1951,7 @@ tcpinit(Fs *fs) tcp.close = tcpclose; tcp.rcv = tcpiput; tcp.advise = tcpadvise; + tcp.stats = tcpstats; tcp.ipproto = IP_TCPPROTO; tcp.nc = Nchans; tcp.ptclsize = sizeof(Tcpctl);