Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <ip.h>
4
#include "../icmp.h"
5
 
6
static void
7
catch(void *a, char *msg)
8
{
9
	USED(a);
10
	if(strstr(msg, "alarm"))
11
		noted(NCONT);
12
	else
13
		noted(NDFLT);
14
}
15
 
16
#define MSG "dhcp probe"
17
 
18
/*
19
 *  make sure noone is using the address
20
 *  TODO: ipv6 ping
21
 */
22
int
23
icmpecho(uchar *a)
24
{
25
	int fd, i, n, len, rv;
26
	ushort sseq, x;
27
	char buf[512];
28
	Icmphdr *ip;
29
 
30
	rv = 0;
31
	if (!isv4(a))
32
		return 0;
33
	sprint(buf, "%I", a);
34
	fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
35
	if(fd < 0){
36
		return 0;
37
	}
38
 
39
	sseq = getpid()*time(0);
40
 
41
	ip = (Icmphdr *)(buf + IPV4HDR_LEN);
42
	notify(catch);
43
	for(i = 0; i < 3; i++){
44
		ip->type = EchoRequest;
45
		ip->code = 0;
46
		strcpy((char*)ip->data, MSG);
47
		ip->seq[0] = sseq;
48
		ip->seq[1] = sseq>>8;
49
		len = IPV4HDR_LEN + ICMP_HDRSIZE + sizeof(MSG);
50
 
51
		/* send a request */
52
		if(write(fd, buf, len) < len)
53
			break;
54
 
55
		/* wait 1/10th second for a reply and try again */
56
		alarm(100);
57
		n = read(fd, buf, sizeof(buf));
58
		alarm(0);
59
		if(n <= 0)
60
			continue;
61
 
62
		/* an answer to our echo request? */
63
		x = (ip->seq[1]<<8) | ip->seq[0];
64
		if(n >= len && ip->type == EchoReply && x == sseq &&
65
		    strcmp((char*)ip->data, MSG) == 0){
66
			rv = 1;
67
			break;
68
		}
69
	}
70
	close(fd);
71
	return rv;
72
}