summaryrefslogtreecommitdiffstats
path: root/src/cmd/ip/dhcpd/ping.c
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2005-12-26 04:48:52 +0000
committerrsc <devnull@localhost>2005-12-26 04:48:52 +0000
commit87a52e0485d3281ebea6bf4b725aa8023690e96f (patch)
tree0abc2d2ddb875196177231639d3cb4519e814b9d /src/cmd/ip/dhcpd/ping.c
parent35d26aa32167e84326cdb745c0e906393b8de71d (diff)
downloadplan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.tar.gz
plan9port-87a52e0485d3281ebea6bf4b725aa8023690e96f.zip
new goodies
Diffstat (limited to 'src/cmd/ip/dhcpd/ping.c')
-rwxr-xr-xsrc/cmd/ip/dhcpd/ping.c112
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;
+}