~kris/9p

9hist

53bb7727de42907fa48b2f59833162b9455e5252 — David du Colombier 28 years ago cfee2f1
Plan 9 from Bell Labs 1998-08-13
7 files changed, 128 insertions(+), 28 deletions(-)

M ip/icmp.c
M ip/ip.c
M ip/ip.h
M ip/tcp.c
M ip/udp.c
M pc/devastar.c
M port/chan.c
M ip/icmp.c => ip/icmp.c +103 -19
@@ 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,20 160,48 @@ 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)
{
	Block	*nbp;


@@ 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)
{

M ip/ip.c => ip/ip.c +9 -2
@@ 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,

M ip/ip.h => ip/ip.h +1 -0
@@ 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*);

M ip/tcp.c => ip/tcp.c +12 -5
@@ 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;

M ip/udp.c => ip/udp.c +1 -1
@@ 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,

M pc/devastar.c => pc/devastar.c +1 -1
@@ 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

M port/chan.c => port/chan.c +1 -0
@@ 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);