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
catch(void * a,char * msg)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
200a84db5eSDavid du Colombier * TODO: ipv6 ping
217dd7cddfSDavid du Colombier */
227dd7cddfSDavid du Colombier int
icmpecho(uchar * a)237dd7cddfSDavid du Colombier icmpecho(uchar *a)
247dd7cddfSDavid du Colombier {
25*94aa1c4cSDavid du Colombier int fd, i, n, len, rv;
267dd7cddfSDavid du Colombier ushort sseq, x;
27*94aa1c4cSDavid du Colombier char buf[512];
28*94aa1c4cSDavid du Colombier Icmphdr *ip;
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier rv = 0;
310a84db5eSDavid du Colombier if (!isv4(a))
320a84db5eSDavid du Colombier return 0;
337dd7cddfSDavid du Colombier sprint(buf, "%I", a);
347dd7cddfSDavid du Colombier fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
357dd7cddfSDavid du Colombier if(fd < 0){
367dd7cddfSDavid du Colombier return 0;
377dd7cddfSDavid du Colombier }
387dd7cddfSDavid du Colombier
397dd7cddfSDavid du Colombier sseq = getpid()*time(0);
407dd7cddfSDavid du Colombier
41*94aa1c4cSDavid du Colombier ip = (Icmphdr *)(buf + IPV4HDR_LEN);
427dd7cddfSDavid du Colombier notify(catch);
437dd7cddfSDavid du Colombier for(i = 0; i < 3; i++){
447dd7cddfSDavid du Colombier ip->type = EchoRequest;
457dd7cddfSDavid du Colombier ip->code = 0;
467dd7cddfSDavid du Colombier strcpy((char*)ip->data, MSG);
477dd7cddfSDavid du Colombier ip->seq[0] = sseq;
487dd7cddfSDavid du Colombier ip->seq[1] = sseq>>8;
495e1edbcaSDavid du Colombier len = IPV4HDR_LEN + ICMP_HDRSIZE + sizeof(MSG);
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier /* send a request */
527dd7cddfSDavid du Colombier if(write(fd, buf, len) < len)
537dd7cddfSDavid du Colombier break;
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier /* wait 1/10th second for a reply and try again */
567dd7cddfSDavid du Colombier alarm(100);
577dd7cddfSDavid du Colombier n = read(fd, buf, sizeof(buf));
587dd7cddfSDavid du Colombier alarm(0);
597dd7cddfSDavid du Colombier if(n <= 0)
607dd7cddfSDavid du Colombier continue;
617dd7cddfSDavid du Colombier
627dd7cddfSDavid du Colombier /* an answer to our echo request? */
637dd7cddfSDavid du Colombier x = (ip->seq[1]<<8) | ip->seq[0];
64*94aa1c4cSDavid du Colombier if(n >= len && ip->type == EchoReply && x == sseq &&
65*94aa1c4cSDavid du Colombier strcmp((char*)ip->data, MSG) == 0){
667dd7cddfSDavid du Colombier rv = 1;
677dd7cddfSDavid du Colombier break;
687dd7cddfSDavid du Colombier }
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier close(fd);
717dd7cddfSDavid du Colombier return rv;
727dd7cddfSDavid du Colombier }
73