plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

ping.c (1890B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <ip.h>
      4 
      5 
      6 typedef struct Icmp Icmp;
      7 struct Icmp
      8 {
      9 	uchar	vihl;		/* Version and header length */
     10 	uchar	tos;		/* Type of service */
     11 	uchar	length[2];	/* packet length */
     12 	uchar	id[2];		/* Identification */
     13 	uchar	frag[2];	/* Fragment information */
     14 	uchar	ttl;		/* Time to live */
     15 	uchar	proto;		/* Protocol */
     16 	uchar	ipcksum[2];	/* Header checksum */
     17 	uchar	src[4];		/* Ip source */
     18 	uchar	dst[4];		/* Ip destination */
     19 	uchar	type;
     20 	uchar	code;
     21 	uchar	cksum[2];
     22 	uchar	icmpid[2];
     23 	uchar	seq[2];
     24 	uchar	data[1];
     25 };
     26 
     27 enum
     28 {			/* Packet Types */
     29 	EchoReply	= 0,
     30 	Unreachable	= 3,
     31 	SrcQuench	= 4,
     32 	EchoRequest	= 8,
     33 	TimeExceed	= 11,
     34 	Timestamp	= 13,
     35 	TimestampReply	= 14,
     36 	InfoRequest	= 15,
     37 	InfoReply	= 16,
     38 
     39 	ICMP_IPSIZE	= 20,
     40 	ICMP_HDRSIZE	= 8
     41 };
     42 
     43 static void
     44 catch(void *a, char *msg)
     45 {
     46 	USED(a);
     47 	if(strstr(msg, "alarm"))
     48 		noted(NCONT);
     49 	else
     50 		noted(NDFLT);
     51 }
     52 
     53 #define MSG "dhcp probe"
     54 
     55 /*
     56  *  make sure noone is using the address
     57  */
     58 int
     59 icmpecho(uchar *a)
     60 {
     61 	int fd;
     62 	char buf[512];
     63 	Icmp *ip;
     64 	int i, n, len;
     65 	ushort sseq, x;
     66 	int rv;
     67 
     68 return 0;
     69 	rv = 0;
     70 
     71 	sprint(buf, "%I", a);
     72 	fd = dial(netmkaddr(buf, "icmp", "1"), 0, 0, 0);
     73 	if(fd < 0){
     74 		return 0;
     75 	}
     76 
     77 	sseq = getpid()*time(0);
     78 
     79 	ip = (Icmp*)buf;
     80 	notify(catch);
     81 	for(i = 0; i < 3; i++){
     82 		ip->type = EchoRequest;
     83 		ip->code = 0;
     84 		strcpy((char*)ip->data, MSG);
     85 		ip->seq[0] = sseq;
     86 		ip->seq[1] = sseq>>8;
     87 		len = ICMP_IPSIZE+ICMP_HDRSIZE+sizeof(MSG);
     88 
     89 		/* send a request */
     90 		if(write(fd, buf, len) < len)
     91 			break;
     92 
     93 		/* wait 1/10th second for a reply and try again */
     94 		alarm(100);
     95 		n = read(fd, buf, sizeof(buf));
     96 		alarm(0);
     97 		if(n <= 0)
     98 			continue;
     99 
    100 		/* an answer to our echo request? */
    101 		x = (ip->seq[1]<<8)|ip->seq[0];
    102 		if(n >= len)
    103 		if(ip->type == EchoReply)
    104 		if(x == sseq)
    105 		if(strcmp((char*)ip->data, MSG) == 0){
    106 			rv = 1;
    107 			break;
    108 		}
    109 	}
    110 	close(fd);
    111 	return rv;
    112 }