shithub: riscv

Download patch

ref: eac7a2b12a9a6df73164132def672c681cf36820
parent: 829a451c2b866d502306bd0b8cbb1991a55faa45
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Tue Apr 10 16:04:20 EDT 2018

ip/gping: icmpv6 support

--- a/sys/src/cmd/ip/gping.c
+++ b/sys/src/cmd/ip/gping.c
@@ -54,6 +54,7 @@
 {
 	Lock;
 	char	*name;
+	int	version;
 	int	pingfd;
 	int	nproc;
 
@@ -423,7 +424,7 @@
 
 
 void
-pingclean(Machine *m, ushort seq, vlong now, int)
+pingclean(Machine *m, ushort seq, vlong now)
 {
 	Req **l, *r;
 	vlong x, y;
@@ -445,24 +446,24 @@
 	}
 }
 
-/* IPv4 only */
 void
 pingsend(Machine *m)
 {
 	int i;
-	char buf[128], err[ERRMAX];
+	uchar buf[128];
+	char err[ERRMAX];
 	Icmphdr *ip;
 	Req *r;
 
-	ip = (Icmphdr *)(buf + IPV4HDR_LEN);
+	ip = (Icmphdr *)(buf + (m->version==4? IPV4HDR_LEN: IPV6HDR_LEN));
 	memset(buf, 0, sizeof buf);
 	r = malloc(sizeof *r);
 	if(r == nil)
 		return;
 
-	for(i = 32; i < MSGLEN; i++)
+	for(i = ip->data-buf; i < MSGLEN; i++)
 		buf[i] = i;
-	ip->type = EchoRequest;
+	ip->type = m->version==4? EchoRequest: EchoRequestV6;
 	ip->code = 0;
 	ip->seq[0] = m->seq;
 	ip->seq[1] = m->seq>>8;
@@ -469,7 +470,7 @@
 	r->seq = m->seq;
 	r->time = nsec();
 	lock(m);
-	pingclean(m, -1, r->time, 0);
+	pingclean(m, -1, r->time);
 	r->next = m->list;
 	m->list = r;
 	unlock(m);
@@ -481,7 +482,6 @@
 	m->seq++;
 }
 
-/* IPv4 only */
 void
 pingrcv(void *arg)
 {
@@ -489,11 +489,9 @@
 	uchar buf[512];
 	ushort x;
 	Icmphdr *ip;
-	Ip4hdr *ip4;
 	Machine *m = arg;
 
-	ip4 = (Ip4hdr *)buf;
-	ip = (Icmphdr *)(buf + IPV4HDR_LEN);
+	ip = (Icmphdr *)(buf + (m->version==4? IPV4HDR_LEN: IPV6HDR_LEN));
 	for(;;){
 		n = read(m->pingfd, buf, sizeof(buf));
 		if(n <= 0)
@@ -500,16 +498,16 @@
 			break;
 		if(n < MSGLEN)
 			continue;
-		for(i = 32; i < MSGLEN; i++)
+		for(i = ip->data-buf; i < MSGLEN; i++)
 			if(buf[i] != (i&0xff))
 				break;
 		if(i != MSGLEN)
 			continue;
 		x = (ip->seq[1]<<8) | ip->seq[0];
-		if(ip->type != EchoReply || ip->code != 0)
+		if(ip->type != (m->version==4? EchoReply: EchoReplyV6) || ip->code != 0)
 			continue;
 		lock(m);
-		pingclean(m, x, nsec(), ip4->ttl);
+		pingclean(m, x, nsec());
 		unlock(m);
 	}
 }
@@ -527,12 +525,21 @@
 		m->name = estrdup(p+1);
 	}else
 		p = name;
-
 	m->name = estrdup(p);
 	m->nproc = 1;
-	m->pingfd = dial(netmkaddr(m->name, "icmp", "1"), nil, nil, &cfd);
-	if(m->pingfd < 0)
+
+	m->version = 4;
+	if(strstr(name, "icmpv6!") != nil)
+		m->version = 6;
+again:
+	m->pingfd = dial(netmkaddr(m->name, m->version==4? "icmp": "icmpv6", "1"), nil, nil, &cfd);
+	if(m->pingfd < 0){
+		if(m->version == 4){
+			m->version = 6;
+			goto again;
+		}
 		sysfatal("dialing %s: %r", m->name);
+	}
 	write(cfd, "ignoreadvice", 12);
 	close(cfd);
 	startproc(pingrcv, m);