trials = 0;
measure(u_long maxmsec,			/* wait this many msec at most */	u_long wmsec,			/* msec to wait for an answer */	char *hname,	struct sockaddr_in *addr,	int print)			/* print complaints on stderr */{	int length;	int measure_status;	int rcvcount, trials;	int cc, count;	fd_set ready;	long sendtime, recvtime, histime1, histime2;	long idelta, odelta, total;	long min_idelta, min_odelta;	struct timeval tdone, tcur, ttrans, twait, tout;	u_char packet[PACKET_IN], opacket[64];	register struct icmp *icp = (struct icmp *) packet;	register struct icmp *oicp = (struct icmp *) opacket;	struct ip *ip = (struct ip *) packet;	min_idelta = min_odelta = 0x7fffffff;	measure_status = HOSTDOWN;	measure_delta = HOSTDOWN;	errno = 0;	/* open raw socket used to measure time differences */	if (sock_raw < 0) {		sock_raw = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);		if (sock_raw < 0)  {			syslog(LOG_ERR, "opening raw socket: %m");			goto quit;		}	}	    	/*	 * empty the icmp input queue	 */	FD_ZERO(&ready);	for (;;) {		tout.tv_sec = tout.tv_usec = 0;		FD_SET(sock_raw, &ready);		if (select(sock_raw+1, &ready, 0,0, &tout)) {			length = sizeof(struct sockaddr_in);			cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0,				      0,&length);			if (cc < 0)				goto quit;			continue;		}		break;	}	/*	 * Choose the smallest transmission time in each of the two	 * directions. Use these two latter quantities to compute the delta	 * between the two clocks.	 */	oicp->icmp_type = ICMP_TSTAMP;	oicp->icmp_code = 0;	oicp->icmp_id = getpid();	oicp->icmp_rtime = 0;	oicp->icmp_ttime = 0;	oicp->icmp_seq = seqno;	FD_ZERO(&ready);#ifdef sgi	sginap(1);			/* start at a clock tick */#endif /* sgi */	(void)gettimeofday(&tdone, 0);	mstotvround(&tout, maxmsec);	timeradd(&tdone, &tout, &tdone);	/* when we give up */	mstotvround(&twait, wmsec);	rcvcount = 0;	trials = 0;	while (rcvcount < MSGS) {		(void)gettimeofday(&tcur, 0);		/*		 * keep sending until we have sent the max		 */		if (trials < TRIALS) {			trials++;			oicp->icmp_otime = htonl((tcur.tv_sec % SECDAY) * 1000					    + tcur.tv_usec / 1000);			oicp->icmp_cksum = 0;			oicp->icmp_cksum = in_cksum((u_short*)oicp,						    sizeof(*oicp));			count = sendto(sock_raw, opacket, sizeof(*oicp), 0,				       (struct sockaddr*)addr,				       sizeof(struct sockaddr));			if (count < 0) {				if (measure_status == HOSTDOWN)					measure_status = UNREACHABLE;				goto quit;			}			++oicp->icmp_seq;			timeradd(&tcur, &twait, &ttrans);		} else {			ttrans = tdone;		}		while (rcvcount < trials) {			timersub(&ttrans, &tcur, &tout);			if (tout.tv_sec < 0)				tout.tv_sec = 0;			FD_SET(sock_raw, &ready);			count = select(sock_raw+1, &ready, (fd_set *)0,				       (fd_set *)0, &tout);			(void)gettimeofday(&tcur, (struct timezone *)0);			if (count <= 0)				break;			length = sizeof(struct sockaddr_in);			cc = recvfrom(sock_raw, (char *)packet, PACKET_IN, 0,				      0,&length);			if (cc < 0)				goto quit;			/* 			 * got something.  See if it is ours			 */			icp = (struct icmp *)(packet + (ip->ip_hl << 2));			if (cc < sizeof(*ip)			    || icp->icmp_type != ICMP_TSTAMPREPLY			    || icp->icmp_id != oicp->icmp_id			    || icp->icmp_seq < seqno			    || icp->icmp_seq >= oicp->icmp_seq)				continue;			sendtime = ntohl(icp->icmp_otime);			recvtime = ((tcur.tv_sec % SECDAY) * 1000 +				    tcur.tv_usec / 1000);			total = recvtime-sendtime;			if (total < 0)	/* do not hassle midnight */				continue;			rcvcount++;			histime1 = ntohl(icp->icmp_rtime);			histime2 = ntohl(icp->icmp_ttime);			/*			 * a host using a time format different from			 * msec. since midnight UT (as per RFC792) should			 * set the high order bit of the 32-bit time			 * value it transmits.			 */			if ((histime1 & 0x80000000) != 0) {				measure_status = NONSTDTIME;				goto quit;			}			measure_status = GOOD;			idelta = recvtime-histime2;			odelta = histime1-sendtime;			/* do not be confused by midnight */			if (idelta < -MSEC_DAY/2) idelta += MSEC_DAY;			else if (idelta > MSEC_DAY/2) idelta -= MSEC_DAY;			if (odelta < -MSEC_DAY/2) odelta += MSEC_DAY;			else if (odelta > MSEC_DAY/2) odelta -= MSEC_DAY;			/* save the quantization error so that we can get a			 * measurement finer than our system clock.			 */			if (total < MIN_ROUND) {				measure_delta = (odelta - idelta)/2;				goto quit;			}			if (idelta < min_idelta)				min_idelta = idelta;			if (odelta < min_odelta)				min_odelta = odelta;			measure_delta = (min_odelta - min_idelta)/2;		}		if (tcur.tv_sec > tdone.tv_sec		    || (tcur.tv_sec == tdone.tv_sec			&& tcur.tv_usec >= tdone.tv_usec))			break;	}quit:	seqno += TRIALS;		/* allocate our sequence numbers */	/*	 * If no answer is received for TRIALS consecutive times,	 * the machine is assumed to be down	 */	if (measure_status == GOOD) {		if (trace) {			fprintf(fd,				"measured delta %4d, %d trials to %-15s %s\n",			   	measure_delta, trials,				inet_ntoa(addr->sin_addr), hname);		}	} else if (print) {		if (errno != 0)			fprintf(stderr, "measure %s: %s\n", hname,				strerror(errno));	} else {		if (errno != 0) {			syslog(LOG_ERR, "measure %s: %m", hname);		} else {			syslog(LOG_ERR, "measure: %s did not respond", hname);		}		if (trace) {			fprintf(fd,				"measure: %s failed after %d trials\n",				hname, trials);			(void)fflush(fd);		}	}	return(measure_status);}