shithub: riscv

Download patch

ref: ef5c862ce9b1d29d5251e35dcaf1ea71f4aafd8d
parent: a8d00e5d56b261376410c3c87c46327362763bd8
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Oct 22 20:25:17 EDT 2016

ip/icmp: only reply to echo request when directed to us and source is unicast

--- a/sys/src/9/ip/icmp.c
+++ b/sys/src/9/ip/icmp.c
@@ -190,6 +190,30 @@
 	ipoput4(c->p->f, bp, 0, c->ttl, c->tos, nil);
 }
 
+static int
+ip4reply(Fs *f, uchar ip4[4])
+{
+	uchar addr[IPaddrlen];
+	int i;
+
+	v4tov6(addr, ip4);
+	if(ipismulticast(addr))
+		return 0;
+	i = ipforme(f, addr);
+	return i == 0 || (i & Runi) != 0;
+}
+
+static int
+ip4me(Fs *f, uchar ip4[4])
+{
+	uchar addr[IPaddrlen];
+
+	v4tov6(addr, ip4);
+	if(ipismulticast(addr))
+		return 0;
+	return (ipforme(f, addr) & Runi) != 0;
+}
+
 extern void
 icmpttlexceeded(Fs *f, uchar *ia, Block *bp)
 {
@@ -197,6 +221,8 @@
 	Icmp	*p, *np;
 
 	p = (Icmp *)bp->rp;
+	if(!ip4reply(f, p->src))
+		return;
 
 	netlog(f, Logicmp, "sending icmpttlexceeded -> %V\n", p->src);
 	nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8);
@@ -214,7 +240,6 @@
 	memset(np->cksum, 0, sizeof(np->cksum));
 	hnputs(np->cksum, ptclcsum(nbp, ICMP_IPSIZE, blocklen(nbp) - ICMP_IPSIZE));
 	ipoput4(f, nbp, 0, MAXTTL, DFLTTOS, nil);
-
 }
 
 static void
@@ -222,20 +247,10 @@
 {
 	Block	*nbp;
 	Icmp	*p, *np;
-	int	i;
-	uchar	addr[IPaddrlen];
 
 	p = (Icmp *)bp->rp;
-
-	/* only do this for unicast sources and destinations */
-	v4tov6(addr, p->dst);
-	i = ipforme(f, addr);
-	if((i&Runi) == 0)
+	if(!ip4me(f, p->dst) || !ip4reply(f, p->src))
 		return;
-	v4tov6(addr, p->src);
-	i = ipforme(f, addr);
-	if(i != 0 && (i&Runi) == 0)
-		return;
 
 	netlog(f, Logicmp, "sending icmpnoconv -> %V\n", p->src);
 	nbp = allocb(ICMP_IPSIZE + ICMP_HDRSIZE + ICMP_IPSIZE + 8);
@@ -283,9 +298,7 @@
 		s = *c;
 		if(s->lport == recid)
 		if(ipcmp(s->raddr, dst) == 0){
-			bp = concatblock(bp);
-			if(bp != nil)
-				qpass(s->rq, bp);
+			qpass(s->rq, concatblock(bp));
 			return;
 		}
 	}
@@ -293,12 +306,14 @@
 }
 
 static Block *
-mkechoreply(Block *bp)
+mkechoreply(Block *bp, Fs *f)
 {
 	Icmp	*q;
 	uchar	ip[4];
 
 	q = (Icmp *)bp->rp;
+	if(!ip4me(f, q->dst) || !ip4reply(f, q->src))
+		return nil;
 	q->vihl = IP_VER4;
 	memmove(ip, q->src, sizeof(q->dst));
 	memmove(q->src, q->dst, sizeof(q->src));
@@ -376,7 +391,11 @@
 	case EchoRequest:
 		if (iplen < n)
 			bp = trimblock(bp, 0, iplen);
-		r = mkechoreply(concatblock(bp));
+		if(bp->next)
+			bp = concatblock(bp);
+		r = mkechoreply(bp, icmp->f);
+		if(r == nil)
+			goto raise;
 		ipriv->out[EchoReply]++;
 		ipoput4(icmp->f, r, 0, MAXTTL, DFLTTOS, nil);
 		break;
--- a/sys/src/9/ip/icmp6.c
+++ b/sys/src/9/ip/icmp6.c
@@ -312,9 +312,7 @@
 	for(c = icmp->conv; *c; c++){
 		s = *c;
 		if(s->lport == recid && ipcmp(s->raddr, addr) == 0){
-			bp = concatblock(bp);
-			if(bp != nil)
-				qpass(s->rq, bp);
+			qpass(s->rq, concatblock(bp));
 			return;
 		}
 	}
@@ -328,6 +326,8 @@
 	uchar addr[IPaddrlen];
 	IPICMP *p = (IPICMP *)(bp->rp);
 
+	if(isv6mcast(p->src))
+		return nil;
 	ipmove(addr, p->src);
 	if(!isv6mcast(p->dst))
 		ipmove(p->src, p->dst);
@@ -730,7 +730,9 @@
 
 	switch(p->type) {
 	case EchoRequestV6:
-		r = mkechoreply6(concatblock(bp), ipifc);
+		if(bp->next)
+			bp = concatblock(bp);
+		r = mkechoreply6(bp, ipifc);
 		if(r == nil)
 			goto raise;
 		ipriv->out[EchoReply]++;
@@ -866,10 +868,6 @@
 		if(icmpnames6[i])
 			p = seprint(p, e, "%s: %lud %lud\n", icmpnames6[i],
 				priv->in[i], priv->out[i]);
-/*		else
-			p = seprint(p, e, "%d: %lud %lud\n", i, priv->in[i],
-				priv->out[i]);
- */
 	return p - buf;
 }