shithub: riscv

Download patch

ref: 26aca332bb74cf8ee6f27ee7f826413a19182ca9
parent: 575398eb9bc2c6f1bcfce7bf8fffbce73a96e8da
author: cinap_lenrek <[email protected]>
date: Sun Apr 22 14:47:19 EDT 2018

devip: various icmp stuff

no need to rlock ifc in targetttype() as we are called from icmpiput6(),
which the ifc rlocked.

for icmpadvise, the lport, destination *AND* source have to match.

a connection gets a packet when the packets destination matches the source
*OR* the packets source matches the destination.

--- a/sys/src/9/ip/icmp.c
+++ b/sys/src/9/ip/icmp.c
@@ -288,22 +288,20 @@
 static void
 goticmpkt(Proto *icmp, Block *bp)
 {
+	ushort	recid;
+	uchar	dst[IPaddrlen], src[IPaddrlen];
 	Conv	**c, *s;
 	Icmp	*p;
-	uchar	dst[IPaddrlen];
-	ushort	recid;
 
 	p = (Icmp *) bp->rp;
-	v4tov6(dst, p->src);
+	v4tov6(dst, p->dst);
+	v4tov6(src, p->src);
 	recid = nhgets(p->icmpid);
 
-	for(c = icmp->conv; *c; c++) {
-		s = *c;
+	for(c = icmp->conv; (s = *c) != nil; c++){
 		if(s->lport == recid)
-		if(ipcmp(s->raddr, dst) == 0){
-			qpass(s->rq, concatblock(bp));
-			return;
-		}
+		if(ipcmp(s->laddr, dst) == 0 || ipcmp(s->raddr, src) == 0)
+			qpass(s->rq, copyblock(bp, blocklen(bp)));
 	}
 	freeblist(bp);
 }
@@ -317,6 +315,7 @@
 	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));
@@ -392,9 +391,9 @@
 
 	switch(p->type) {
 	case EchoRequest:
-		if (iplen < n)
+		if(iplen < n)
 			bp = trimblock(bp, 0, iplen);
-		if(bp->next)
+		if(bp->next != nil)
 			bp = concatblock(bp);
 		r = mkechoreply(bp, icmp->f);
 		if(r == nil)
@@ -458,18 +457,19 @@
 static void
 icmpadvise(Proto *icmp, Block *bp, char *msg)
 {
+	ushort	recid;
+	uchar	dst[IPaddrlen], src[IPaddrlen];
 	Conv	**c, *s;
 	Icmp	*p;
-	uchar	dst[IPaddrlen];
-	ushort	recid;
 
 	p = (Icmp *) bp->rp;
 	v4tov6(dst, p->dst);
+	v4tov6(src, p->src);
 	recid = nhgets(p->icmpid);
 
-	for(c = icmp->conv; *c; c++) {
-		s = *c;
+	for(c = icmp->conv; (s = *c) != nil; c++){
 		if(s->lport == recid)
+		if(ipcmp(s->laddr, src) == 0)
 		if(ipcmp(s->raddr, dst) == 0){
 			if(s->ignoreadvice)
 				break;
@@ -494,7 +494,7 @@
 	for(i = 0; i < Nstats; i++)
 		p = seprint(p, e, "%s: %lud\n", statnames[i], priv->stats[i]);
 	for(i = 0; i <= Maxtype; i++){
-		if(icmpnames[i])
+		if(icmpnames[i] != nil)
 			p = seprint(p, e, "%s: %lud %lud\n", icmpnames[i], priv->in[i], priv->out[i]);
 		else
 			p = seprint(p, e, "%d: %lud %lud\n", i, priv->in[i], priv->out[i]);
--- a/sys/src/9/ip/icmp6.c
+++ b/sys/src/9/ip/icmp6.c
@@ -221,10 +221,10 @@
 	p = (IPICMP *)bp->rp;
 	recid = nhgets(p->icmpid);
 
-	for(c = icmp->conv; *c; c++) {
-		s = *c;
+	for(c = icmp->conv; (s = *c) != nil; c++){
 		if(s->lport == recid)
-		if(ipcmp(s->laddr, p->dst) == 0 || ipcmp(s->raddr, p->dst) == 0){
+		if(ipcmp(s->laddr, p->src) == 0)
+		if(ipcmp(s->raddr, p->dst) == 0){
 			if(s->ignoreadvice)
 				break;
 			qhangup(s->rq, msg);
@@ -309,19 +309,11 @@
 		recid = muxkey;
 		addr = p->dst;
 	}
-
-	for(c = icmp->conv; *c; c++){
-		s = *c;
-		if(s->lport != recid)
-			continue;
-		if(ipcmp(s->laddr, addr) == 0){
-			qpass(s->rq, concatblock(bp));
-			return;
-		}
-		if(ipcmp(s->raddr, addr) == 0)
+	for(c = icmp->conv; (s = *c) != nil; c++){
+		if(s->lport == recid)
+		if(ipcmp(s->laddr, p->dst) == 0 || ipcmp(s->raddr, addr) == 0)
 			qpass(s->rq, copyblock(bp, blocklen(bp)));
 	}
-
 	freeblist(bp);
 }
 
@@ -417,7 +409,7 @@
 	memmove(np->lnaddr, mac, sizeof(np->lnaddr));
 
 	set_cksum(nbp);
-	np = (Ndpkt*) nbp->rp;
+	np = (Ndpkt*)nbp->rp;
 	np->ttl = HOP_LIMIT;
 	np->vcf[0] = 0x06 << 4;
 	ipriv->out[NbrAdvert]++;
@@ -673,7 +665,6 @@
 	Iplifc *lifc;
 	int t;
 
-	rlock(ifc);
 	if((lifc = iplocalonifc(ifc, target)) != nil)
 		t = lifc->tentative? Tunitent: Tunirany;
 	else if(ipproxyifc(f, ifc, target))
@@ -680,17 +671,16 @@
 		t = Tuniproxy;
 	else
 		t = 0;
-	runlock(ifc);
 	return t;
 }
 
 static void
-icmpiput6(Proto *icmp, Ipifc *ipifc, Block *bp)
+icmpiput6(Proto *icmp, Ipifc *ifc, Block *bp)
 {
 	char *msg, m2[128];
 	uchar pktflags;
 	uchar *packet = bp->rp;
-	uchar lsrc[IPaddrlen];
+	uchar ia[IPaddrlen];
 	Block *r;
 	IPICMP *p = (IPICMP *)packet;
 	Icmppriv6 *ipriv = icmp->priv;
@@ -698,7 +688,7 @@
 	Ndpkt* np;
 	Proto *pr;
 
-	if(!valid(icmp, ipifc, bp, ipriv) || p->type > Maxtype6)
+	if(!valid(icmp, ifc, bp, ipriv) || p->type > Maxtype6)
 		goto raise;
 
 	ipriv->in[p->type]++;
@@ -705,9 +695,9 @@
 
 	switch(p->type) {
 	case EchoRequestV6:
-		if(bp->next)
+		if(bp->next != nil)
 			bp = concatblock(bp);
-		r = mkechoreply6(bp, ipifc);
+		r = mkechoreply6(bp, ifc);
 		if(r == nil)
 			goto raise;
 		ipriv->out[EchoReply]++;
@@ -747,7 +737,7 @@
 			}
 			p = (IPICMP *)bp->rp;
 			pr = Fsrcvpcolx(icmp->f, p->proto);
-			if(pr && pr->advise) {
+			if(pr != nil && pr->advise != nil) {
 				(*pr->advise)(pr, bp, m2);
 				return;
 			}
@@ -764,21 +754,21 @@
 	case NbrSolicit:
 		np = (Ndpkt*) p;
 		pktflags = 0;
-		if(ipifc->sendra6)
+		if(ifc->sendra6)
 			pktflags |= Rflag;
-		switch (targettype(icmp->f, ipifc, np->target)) {
+		switch (targettype(icmp->f, ifc, np->target)) {
 		case Tunirany:
 			pktflags |= Oflag;
 			/* fall through */
 
 		case Tuniproxy:
-			if(ipv6local(ipifc, lsrc, np->src)) {
-				arpenter(icmp->f, V6, np->src, np->lnaddr, 8*np->olen-2, lsrc, 0);
+			if(ipv6local(ifc, ia, np->src)) {
+				arpenter(icmp->f, V6, np->src, np->lnaddr, 8*np->olen-2, ia, 0);
 				pktflags |= Sflag;
 			} else
-				ipmove(lsrc, np->target);
-			icmpna(icmp->f, lsrc, (pktflags & Sflag) ? np->src : v6allnodesL,
-				np->target, ipifc->mac, pktflags);
+				ipmove(ia, np->target);
+			icmpna(icmp->f, ia, (pktflags & Sflag)? np->src: v6allnodesL,
+				np->target, ifc->mac, pktflags);
 			break;
 		case Tunitent:
 			/*
@@ -800,11 +790,11 @@
 		 * detection part of ipconfig can discover duplication through
 		 * the arp table.
 		 */
-		lifc = iplocalonifc(ipifc, np->target);
+		lifc = iplocalonifc(ifc, np->target);
 		if(lifc != nil && lifc->tentative)
 			arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, np->target, 0);
-		else if(ipv6local(ipifc, lsrc, np->target))
-			arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, lsrc, 1);
+		else if(ipv6local(ifc, ia, np->target))
+			arpenter(icmp->f, V6, np->target, np->lnaddr, 8*np->olen-2, ia, 1);
 		freeblist(bp);
 		break;