diff options
| author | rsc <devnull@localhost> | 2005-12-26 04:48:52 +0000 |
|---|---|---|
| committer | rsc <devnull@localhost> | 2005-12-26 04:48:52 +0000 |
| commit | 87a52e0485d3281ebea6bf4b725aa8023690e96f (patch) | |
| tree | 0abc2d2ddb875196177231639d3cb4519e814b9d /src/cmd/ip/dhcpd/ping.c | |
| parent | 35d26aa32167e84326cdb745c0e906393b8de71d (diff) | |
| download | plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.gz plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.zip | |
new goodies
Diffstat (limited to 'src/cmd/ip/dhcpd/ping.c')
| -rwxr-xr-x | src/cmd/ip/dhcpd/ping.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/src/cmd/ip/dhcpd/ping.c b/src/cmd/ip/dhcpd/ping.c new file mode 100755 index 00000000..7fa7a424 --- /dev/null +++ b/src/cmd/ip/dhcpd/ping.c @@ -0,0 +1,112 @@ +#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; +} |
