|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include <ip.h> | 
|  |  | 
|  |  | 
|  | typedef struct Icmp Icmp; | 
|  | struct Icmp | 
|  | { | 
|  | uchar	vihl;		/* Version and header length */ | 
|  | uchar	tos;		/* Type of service */ | 
|  | uchar	length[2];	/* packet length */ | 
|  | uchar	id[2];		/* Identification */ | 
|  | uchar	frag[2];	/* Fragment information */ | 
|  | uchar	ttl;		/* Time to live */ | 
|  | uchar	proto;		/* Protocol */ | 
|  | uchar	ipcksum[2];	/* Header checksum */ | 
|  | uchar	src[4];		/* Ip source */ | 
|  | uchar	dst[4];		/* Ip destination */ | 
|  | uchar	type; | 
|  | uchar	code; | 
|  | uchar	cksum[2]; | 
|  | uchar	icmpid[2]; | 
|  | uchar	seq[2]; | 
|  | uchar	data[1]; | 
|  | }; | 
|  |  | 
|  | enum | 
|  | {			/* Packet Types */ | 
|  | EchoReply	= 0, | 
|  | Unreachable	= 3, | 
|  | SrcQuench	= 4, | 
|  | EchoRequest	= 8, | 
|  | TimeExceed	= 11, | 
|  | Timestamp	= 13, | 
|  | TimestampReply	= 14, | 
|  | InfoRequest	= 15, | 
|  | InfoReply	= 16, | 
|  |  | 
|  | ICMP_IPSIZE	= 20, | 
|  | ICMP_HDRSIZE	= 8 | 
|  | }; | 
|  |  | 
|  | static void | 
|  | catch(void *a, char *msg) | 
|  | { | 
|  | USED(a); | 
|  | if(strstr(msg, "alarm")) | 
|  | noted(NCONT); | 
|  | else | 
|  | noted(NDFLT); | 
|  | } | 
|  |  | 
|  | #define MSG "dhcp probe" | 
|  |  | 
|  | /* | 
|  | *  make sure noone is using the address | 
|  | */ | 
|  | int | 
|  | icmpecho(uchar *a) | 
|  | { | 
|  | int fd; | 
|  | char buf[512]; | 
|  | Icmp *ip; | 
|  | int i, n, len; | 
|  | ushort sseq, x; | 
|  | int rv; | 
|  |  | 
|  | return 0; | 
|  | rv = 0; | 
|  |  | 
|  | sprint(buf, "%I", a); | 
|  | fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0); | 
|  | if(fd < 0){ | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | sseq = getpid()*time(0); | 
|  |  | 
|  | ip = (Icmp*)buf; | 
|  | notify(catch); | 
|  | for(i = 0; i < 3; i++){ | 
|  | ip->type = EchoRequest; | 
|  | ip->code = 0; | 
|  | strcpy((char*)ip->data, MSG); | 
|  | ip->seq[0] = sseq; | 
|  | ip->seq[1] = sseq>>8; | 
|  | len = ICMP_IPSIZE+ICMP_HDRSIZE+sizeof(MSG); | 
|  |  | 
|  | /* send a request */ | 
|  | if(write(fd, buf, len) < len) | 
|  | break; | 
|  |  | 
|  | /* wait 1/10th second for a reply and try again */ | 
|  | alarm(100); | 
|  | n = read(fd, buf, sizeof(buf)); | 
|  | alarm(0); | 
|  | if(n <= 0) | 
|  | continue; | 
|  |  | 
|  | /* an answer to our echo request? */ | 
|  | x = (ip->seq[1]<<8)|ip->seq[0]; | 
|  | if(n >= len) | 
|  | if(ip->type == EchoReply) | 
|  | if(x == sseq) | 
|  | if(strcmp((char*)ip->data, MSG) == 0){ | 
|  | rv = 1; | 
|  | break; | 
|  | } | 
|  | } | 
|  | close(fd); | 
|  | return rv; | 
|  | } |