ip/gping: icmpv6 support
This commit is contained in:
parent
829a451c2b
commit
eac7a2b12a
|
@ -54,6 +54,7 @@ struct Machine
|
||||||
{
|
{
|
||||||
Lock;
|
Lock;
|
||||||
char *name;
|
char *name;
|
||||||
|
int version;
|
||||||
int pingfd;
|
int pingfd;
|
||||||
int nproc;
|
int nproc;
|
||||||
|
|
||||||
|
@ -423,7 +424,7 @@ pingreply(Machine *m, Req *r)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pingclean(Machine *m, ushort seq, vlong now, int)
|
pingclean(Machine *m, ushort seq, vlong now)
|
||||||
{
|
{
|
||||||
Req **l, *r;
|
Req **l, *r;
|
||||||
vlong x, y;
|
vlong x, y;
|
||||||
|
@ -445,31 +446,31 @@ pingclean(Machine *m, ushort seq, vlong now, int)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IPv4 only */
|
|
||||||
void
|
void
|
||||||
pingsend(Machine *m)
|
pingsend(Machine *m)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char buf[128], err[ERRMAX];
|
uchar buf[128];
|
||||||
|
char err[ERRMAX];
|
||||||
Icmphdr *ip;
|
Icmphdr *ip;
|
||||||
Req *r;
|
Req *r;
|
||||||
|
|
||||||
ip = (Icmphdr *)(buf + IPV4HDR_LEN);
|
ip = (Icmphdr *)(buf + (m->version==4? IPV4HDR_LEN: IPV6HDR_LEN));
|
||||||
memset(buf, 0, sizeof buf);
|
memset(buf, 0, sizeof buf);
|
||||||
r = malloc(sizeof *r);
|
r = malloc(sizeof *r);
|
||||||
if(r == nil)
|
if(r == nil)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for(i = 32; i < MSGLEN; i++)
|
for(i = ip->data-buf; i < MSGLEN; i++)
|
||||||
buf[i] = i;
|
buf[i] = i;
|
||||||
ip->type = EchoRequest;
|
ip->type = m->version==4? EchoRequest: EchoRequestV6;
|
||||||
ip->code = 0;
|
ip->code = 0;
|
||||||
ip->seq[0] = m->seq;
|
ip->seq[0] = m->seq;
|
||||||
ip->seq[1] = m->seq>>8;
|
ip->seq[1] = m->seq>>8;
|
||||||
r->seq = m->seq;
|
r->seq = m->seq;
|
||||||
r->time = nsec();
|
r->time = nsec();
|
||||||
lock(m);
|
lock(m);
|
||||||
pingclean(m, -1, r->time, 0);
|
pingclean(m, -1, r->time);
|
||||||
r->next = m->list;
|
r->next = m->list;
|
||||||
m->list = r;
|
m->list = r;
|
||||||
unlock(m);
|
unlock(m);
|
||||||
|
@ -481,7 +482,6 @@ pingsend(Machine *m)
|
||||||
m->seq++;
|
m->seq++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* IPv4 only */
|
|
||||||
void
|
void
|
||||||
pingrcv(void *arg)
|
pingrcv(void *arg)
|
||||||
{
|
{
|
||||||
|
@ -489,27 +489,25 @@ pingrcv(void *arg)
|
||||||
uchar buf[512];
|
uchar buf[512];
|
||||||
ushort x;
|
ushort x;
|
||||||
Icmphdr *ip;
|
Icmphdr *ip;
|
||||||
Ip4hdr *ip4;
|
|
||||||
Machine *m = arg;
|
Machine *m = arg;
|
||||||
|
|
||||||
ip4 = (Ip4hdr *)buf;
|
ip = (Icmphdr *)(buf + (m->version==4? IPV4HDR_LEN: IPV6HDR_LEN));
|
||||||
ip = (Icmphdr *)(buf + IPV4HDR_LEN);
|
|
||||||
for(;;){
|
for(;;){
|
||||||
n = read(m->pingfd, buf, sizeof(buf));
|
n = read(m->pingfd, buf, sizeof(buf));
|
||||||
if(n <= 0)
|
if(n <= 0)
|
||||||
break;
|
break;
|
||||||
if(n < MSGLEN)
|
if(n < MSGLEN)
|
||||||
continue;
|
continue;
|
||||||
for(i = 32; i < MSGLEN; i++)
|
for(i = ip->data-buf; i < MSGLEN; i++)
|
||||||
if(buf[i] != (i&0xff))
|
if(buf[i] != (i&0xff))
|
||||||
break;
|
break;
|
||||||
if(i != MSGLEN)
|
if(i != MSGLEN)
|
||||||
continue;
|
continue;
|
||||||
x = (ip->seq[1]<<8) | ip->seq[0];
|
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;
|
continue;
|
||||||
lock(m);
|
lock(m);
|
||||||
pingclean(m, x, nsec(), ip4->ttl);
|
pingclean(m, x, nsec());
|
||||||
unlock(m);
|
unlock(m);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -527,12 +525,21 @@ initmach(Machine *m, char *name)
|
||||||
m->name = estrdup(p+1);
|
m->name = estrdup(p+1);
|
||||||
}else
|
}else
|
||||||
p = name;
|
p = name;
|
||||||
|
|
||||||
m->name = estrdup(p);
|
m->name = estrdup(p);
|
||||||
m->nproc = 1;
|
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);
|
sysfatal("dialing %s: %r", m->name);
|
||||||
|
}
|
||||||
write(cfd, "ignoreadvice", 12);
|
write(cfd, "ignoreadvice", 12);
|
||||||
close(cfd);
|
close(cfd);
|
||||||
startproc(pingrcv, m);
|
startproc(pingrcv, m);
|
||||||
|
|
Loading…
Reference in a new issue