xref: /plan9/sys/src/cmd/ip/dhcpd/ping.c (revision 0a84db5e29c8e13ff34694780ad5447552e05609)
17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <ip.h>
45a354e27SDavid du Colombier #include "../icmp.h"
57dd7cddfSDavid du Colombier 
67dd7cddfSDavid du Colombier static void
77dd7cddfSDavid du Colombier catch(void *a, char *msg)
87dd7cddfSDavid du Colombier {
97dd7cddfSDavid du Colombier 	USED(a);
107dd7cddfSDavid du Colombier 	if(strstr(msg, "alarm"))
117dd7cddfSDavid du Colombier 		noted(NCONT);
127dd7cddfSDavid du Colombier 	else
137dd7cddfSDavid du Colombier 		noted(NDFLT);
147dd7cddfSDavid du Colombier }
157dd7cddfSDavid du Colombier 
167dd7cddfSDavid du Colombier #define MSG "dhcp probe"
177dd7cddfSDavid du Colombier 
187dd7cddfSDavid du Colombier /*
197dd7cddfSDavid du Colombier  *  make sure noone is using the address
20*0a84db5eSDavid du Colombier  *  TODO: ipv6 ping
217dd7cddfSDavid du Colombier  */
227dd7cddfSDavid du Colombier int
237dd7cddfSDavid du Colombier icmpecho(uchar *a)
247dd7cddfSDavid du Colombier {
257dd7cddfSDavid du Colombier 	int fd;
267dd7cddfSDavid du Colombier 	char buf[512];
277dd7cddfSDavid du Colombier 	Icmp *ip;
287dd7cddfSDavid du Colombier 	int i, n, len;
297dd7cddfSDavid du Colombier 	ushort sseq, x;
307dd7cddfSDavid du Colombier 	int rv;
317dd7cddfSDavid du Colombier 
327dd7cddfSDavid du Colombier 	rv = 0;
33*0a84db5eSDavid du Colombier 	if (!isv4(a))
34*0a84db5eSDavid du Colombier 		return 0;
357dd7cddfSDavid du Colombier 	sprint(buf, "%I", a);
367dd7cddfSDavid du Colombier 	fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
377dd7cddfSDavid du Colombier 	if(fd < 0){
387dd7cddfSDavid du Colombier 		return 0;
397dd7cddfSDavid du Colombier 	}
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier 	sseq = getpid()*time(0);
427dd7cddfSDavid du Colombier 
437dd7cddfSDavid du Colombier 	ip = (Icmp*)buf;
447dd7cddfSDavid du Colombier 	notify(catch);
457dd7cddfSDavid du Colombier 	for(i = 0; i < 3; i++){
467dd7cddfSDavid du Colombier 		ip->type = EchoRequest;
477dd7cddfSDavid du Colombier 		ip->code = 0;
487dd7cddfSDavid du Colombier 		strcpy((char*)ip->data, MSG);
497dd7cddfSDavid du Colombier 		ip->seq[0] = sseq;
507dd7cddfSDavid du Colombier 		ip->seq[1] = sseq>>8;
515e1edbcaSDavid du Colombier 		len = IPV4HDR_LEN+ICMP_HDRSIZE+sizeof(MSG);
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier 		/* send a request */
547dd7cddfSDavid du Colombier 		if(write(fd, buf, len) < len)
557dd7cddfSDavid du Colombier 			break;
567dd7cddfSDavid du Colombier 
577dd7cddfSDavid du Colombier 		/* wait 1/10th second for a reply and try again */
587dd7cddfSDavid du Colombier 		alarm(100);
597dd7cddfSDavid du Colombier 		n = read(fd, buf, sizeof(buf));
607dd7cddfSDavid du Colombier 		alarm(0);
617dd7cddfSDavid du Colombier 		if(n <= 0)
627dd7cddfSDavid du Colombier 			continue;
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier 		/* an answer to our echo request? */
657dd7cddfSDavid du Colombier 		x = (ip->seq[1]<<8)|ip->seq[0];
667dd7cddfSDavid du Colombier 		if(n >= len)
677dd7cddfSDavid du Colombier 		if(ip->type == EchoReply)
687dd7cddfSDavid du Colombier 		if(x == sseq)
697dd7cddfSDavid du Colombier 		if(strcmp((char*)ip->data, MSG) == 0){
707dd7cddfSDavid du Colombier 			rv = 1;
717dd7cddfSDavid du Colombier 			break;
727dd7cddfSDavid du Colombier 		}
737dd7cddfSDavid du Colombier 	}
747dd7cddfSDavid du Colombier 	close(fd);
757dd7cddfSDavid du Colombier 	return rv;
767dd7cddfSDavid du Colombier }
77