From 53bb7727de42907fa48b2f59833162b9455e5252 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 13 Aug 1998 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1998-08-13 --- ip/icmp.c | 122 ++++++++++++++++++++++++++++++++++++++++++-------- ip/ip.c | 11 ++++- ip/ip.h | 1 + ip/tcp.c | 17 ++++--- ip/udp.c | 2 +- pc/devastar.c | 2 +- port/chan.c | 1 + 7 files changed, 128 insertions(+), 28 deletions(-) diff --git a/ip/icmp.c b/ip/icmp.c index bcf6e6cea1b77cd57432c7f45286f8cd0d443b40..157c30db3718f53b3a42ea2d66680bf0b7628a0d 100644 --- a/ip/icmp.c +++ b/ip/icmp.c @@ -30,14 +30,17 @@ enum { /* Packet Types */ EchoReply = 0, Unreachable = 3, SrcQuench = 4, + Redirect = 4, EchoRequest = 8, TimeExceed = 11, + InParmProblem = 12, Timestamp = 13, TimestampReply = 14, InfoRequest = 15, InfoReply = 16, - - Maxtype = 16, + AddrMaskRequest = 17, + AddrMaskReply = 18, + Maxtype = 18, }; enum { @@ -46,9 +49,43 @@ enum { ICMP_HDRSIZE = 8, }; +typedef struct Icmpstats Icmpstats; +struct Icmpstats +{ + ulong icmpInMsgs; + ulong icmpInErrors; +// ulong icmpInDestUnreachs; +// ulong icmpInTimeExcds; +// ulong icmpInParmProbs; +// ulong icmpInSrcQuenchs; +// ulong icmpInRedirects; +// ulong icmpInEchos; +// ulong icmpInEchoReps; +// ulong icmpInTimestamps; +// ulong icmpInTimestampReps; +// ulong icmpInAddrMasks; +// ulong icmpInAddrMaskReps; + ulong icmpOutMsgs; + ulong icmpOutErrors; +// ulong icmpOutDestUnreachs; +// ulong icmpOutTimeExcds; +// ulong icmpOutParmProbs; +// ulong icmpOutSrcQuenchs; +// ulong icmpOutRedirects; +// ulong icmpOutEchos; +// ulong icmpOutEchoReps; +// ulong icmpOutTimestamps; +// ulong icmpOutTimestampReps; +// ulong icmpOutAddrMasks; +// ulong icmpOutAddrMaskReps; +}; + typedef struct Icmppriv Icmppriv; struct Icmppriv { + /* MIB Counters */ + Icmpstats istats; + /* non-MIB stats */ ulong csumerr; /* checksum errors */ ulong lenerr; /* short packet */ @@ -123,19 +160,47 @@ icmpkick(Conv *c, int l) return; } p = (Icmp *)(bp->rp); - if(p->type <= Maxtype){ - ipriv = c->p->priv; + ipriv = c->p->priv; + if(p->type <= Maxtype) ipriv->out[p->type]++; - } + v6tov4(p->dst, c->raddr); v6tov4(p->src, c->laddr); p->proto = IP_ICMPPROTO; hnputs(p->icmpid, c->lport); memset(p->cksum, 0, sizeof(p->cksum)); hnputs(p->cksum, ptclcsum(bp, ICMP_IPSIZE, blocklen(bp) - ICMP_IPSIZE)); + ipriv->istats.icmpOutMsgs++; ipoput(c->p->f, bp, 0, c->ttl); } +extern void +icmpttlexceeded(Fs *f, uchar *ia, Block *bp) +{ + Block *nbp; + Icmp *p, *np; + + p = (Icmp *)bp->rp; + + netlog(f, Logicmp, "sending icmpttlexceeded -> %V\n", p->src); + nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8); + nbp->wp += ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8; + np = (Icmp *)nbp->rp; + memmove(np->dst, p->src, sizeof(np->dst)); + v6tov4(np->src, ia); + memmove(np->data, bp->rp, ICMP_IPSIZE + 8); + np->type = TimeExceed; + np->code = 0; + np->proto = IP_ICMPPROTO; + hnputs(np->icmpid, 0); + hnputs(np->seq, 0); + memset(np->cksum, 0, sizeof(np->cksum)); + hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE)); +/* stats.out[TimeExceed]++; */ + ipoput(f, nbp, 0, MAXTTL); + +} + extern void icmpnoconv(Fs *f, Block *bp) { @@ -236,11 +301,14 @@ icmpiput(Proto *icmp, uchar*, Block *bp) Icmppriv *ipriv; ipriv = icmp->priv; + + ipriv->istats.icmpInMsgs++; p = (Icmp *)bp->rp; netlog(icmp->f, Logicmp, "icmpiput %d %d\n", p->type, p->code); n = blocklen(bp); if(n < ICMP_IPSIZE+ICMP_HDRSIZE){ + ipriv->istats.icmpInErrors++; ipriv->hlenerr++; netlog(icmp->f, Logicmp, "icmp hlen %d\n", n); goto raise; @@ -248,10 +316,12 @@ icmpiput(Proto *icmp, uchar*, Block *bp) iplen = nhgets(p->length); if(iplen > n || (iplen % 1)){ ipriv->lenerr++; + ipriv->istats.icmpInErrors++; netlog(icmp->f, Logicmp, "icmp length %d\n", iplen); goto raise; } if(ptclcsum(bp, ICMP_IPSIZE, iplen - ICMP_IPSIZE)){ + ipriv->istats.icmpInErrors++; ipriv->csumerr++; netlog(icmp->f, Logicmp, "icmp checksum error\n"); goto raise; @@ -341,25 +411,39 @@ icmpadvise(Proto *icmp, Block *bp, char *msg) int icmpstats(Proto *icmp, char *buf, int len) { - int i, n; Icmppriv *ipriv; ipriv = icmp->priv; - n = snprint(buf, len, - "icmp: csum %d hlen %d len %d\n", - ipriv->csumerr, ipriv->hlenerr, ipriv->lenerr); - n += snprint(buf+n, len-n, "\trcvd "); - for(i = 0; i < Maxtype && len > n; i++) - n += snprint(buf+n, len-n, " %d", ipriv->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", ipriv->out[i]); - if(n < len) - n += snprint(buf+n, len-n, "\n"); - return n; + return snprint(buf,len,"%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", + ipriv->istats.icmpInMsgs, + ipriv->istats.icmpInErrors, + ipriv->in[Unreachable], + ipriv->in[TimeExceed], + ipriv->in[InParmProblem], + ipriv->in[SrcQuench], + ipriv->in[Redirect], + ipriv->in[EchoRequest], + ipriv->in[EchoReply], + ipriv->in[Timestamp], + ipriv->in[TimestampReply], + ipriv->in[AddrMaskRequest], + ipriv->in[AddrMaskReply], + ipriv->istats.icmpOutMsgs, + ipriv->istats.icmpOutErrors, + ipriv->out[Unreachable], + ipriv->out[TimeExceed], + ipriv->out[InParmProblem], + ipriv->out[SrcQuench], + ipriv->out[Redirect], + ipriv->out[EchoRequest], + ipriv->out[EchoReply], + ipriv->out[Timestamp], + ipriv->out[TimestampReply], + ipriv->out[AddrMaskRequest], + ipriv->out[AddrMaskReply]); } - + void icmpinit(Fs *fs) { diff --git a/ip/ip.c b/ip/ip.c index 549d61ba2393b1269a87882a75f679417c928431..c0d93453485a585c4a39cf39be24e7bfc4c974b9 100644 --- a/ip/ip.c +++ b/ip/ip.c @@ -116,6 +116,10 @@ void iprouting(Fs *f, int on) { f->ip->iprouting = on; + if(f->ip->iprouting==0) + f->ip->istats.ipForwarding = 2; + else + f->ip->istats.ipForwarding = 1; } void @@ -373,9 +377,11 @@ ipiput(Fs *f, uchar *ia, Block *bp) if(notforme) { if(ip->iprouting) { /* gate */ - if(h->ttl <= 1) + if(h->ttl <= 1){ + ip->istats.ipInHdrErrors++; + icmpttlexceeded(f, ia, bp); freeblist(bp); - else { + } else { ip->istats.ipForwDatagrams++; ipoput(f, bp, 1, h->ttl - 1); } @@ -414,6 +420,7 @@ ipstats(Fs *f, char *buf, int len) IP *ip; ip = f->ip; + ip->istats.ipDefaultTTL = MAXTTL; return snprint(buf, len, "%d %d %d %d %d %d %d %d %d %d " "%d %d %d %d %d %d %d %d %d", ip->istats.ipForwarding, ip->istats.ipDefaultTTL, diff --git a/ip/ip.h b/ip/ip.h index 979f0f1b4db51c16fa58f99473271d37366d0aff..d1567903c25da8b3f6106be478158573cfd54d8b 100644 --- a/ip/ip.h +++ b/ip/ip.h @@ -481,6 +481,7 @@ extern long ipselftabread(Fs*, char *a, ulong offset, int n); extern void iprouting(Fs*, int); extern void closeifcconv(Ifcconv*); extern void icmpnoconv(Fs*, Block*); +extern void icmpttlexceeded(Fs*, uchar*, Block*); extern void initfrag(IP*, int); extern ushort ipcsum(uchar*); extern void (*ipextprotoiput)(Block*); diff --git a/ip/tcp.c b/ip/tcp.c index ee2ec943ef9704fceeaf742847230009650c5b47..302748c88bfa7ef5280d5e8be90e240c3b271c5e 100644 --- a/ip/tcp.c +++ b/ip/tcp.c @@ -266,9 +266,6 @@ tcpsetstate(Conv *s, uchar newstate) qclose(s->rq); qclose(s->wq); qclose(s->eq); -// s->lport = 0; /* This connection is toast */ -// s->rport = 0; -// ipmove(s->raddr, IPnoaddr); case Close_wait: /* Remote closes */ qhangup(s->rq, nil); @@ -1573,14 +1570,24 @@ tcpoutput(Conv *s) switch(tcb->state){ case Syn_sent: seg.flags = 0; - /* No break */ - case Syn_received: if(tcb->snd.ptr == tcb->iss){ seg.flags |= SYN; dsize--; seg.mss = tcpmtu(s); } break; + case Syn_received: + /* + * don't send any data with a SYN/ACK packet + * because Linux rejects the packet in its + * attempt to solve the SYN attack problem + */ + if(tcb->snd.ptr == tcb->iss){ + seg.flags |= SYN; + dsize = 0; + seg.mss = tcpmtu(s); + } + break; } tcb->last_ack = tcb->rcv.nxt; seg.seq = tcb->snd.ptr; diff --git a/ip/udp.c b/ip/udp.c index 474241d97faaaea15799a36c59d1973b42a1fbc6..042939e6f838f5f5114527463894d8b39fec28e1 100644 --- a/ip/udp.c +++ b/ip/udp.c @@ -422,7 +422,7 @@ udpstats(Proto *udp, char *buf, int len) Udppriv *upriv; upriv = udp->priv; - return snprint(buf, len, "%d %d %d %d\n", + return snprint(buf, len, "%d %d %d %d", upriv->ustats.udpInDatagrams, upriv->ustats.udpNoPorts, upriv->ustats.udpInErrors, diff --git a/pc/devastar.c b/pc/devastar.c index b41f46ab41469eacfce6795aaab89e3903e347b0..fa16a7ecc72ec233d69df90c9d3691e4bfd163de 100644 --- a/pc/devastar.c +++ b/pc/devastar.c @@ -467,7 +467,7 @@ astarreset(void) break; } if(!(inl(a->port+PCIcommand) & 0x80000000)) - print("#G: didn't reset\n", a->id); + print("#G%d: didn't reset\n", a->id); /* * So the memory can be read before any other diff --git a/port/chan.c b/port/chan.c index 6fb005bf6f123aea79d324af627ae778414114a1..2de9a71169e40746bd59f12551dbc614732efada 100644 --- a/port/chan.c +++ b/port/chan.c @@ -604,6 +604,7 @@ namec(char *name, int amode, int omode, ulong perm) if(*name == 0) isdot = 1; } + c->mnt = nil; if(waserror()){ cclose(c);