ntpdc.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 437 行

C
437
字号
#ifndef lintstatic	char	*sccsid = "@(#)ntpdc.c	4.1	(ULTRIX)	7/2/90";#endif lint/************************************************************************ *									* *			Copyright (c) 1989-1990 by			* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************/#ifndef	lintstatic char *RCSid = "$Source: /usr/users/louie/ntp/RCS/ntpdc.c,v $ $Revision: 3.4.1.7 $ $Date: 89/05/18 18:31:26 $";#endif/* * $Log:	ntpdc.c,v $ * Revision 3.4.1.7  89/05/18  18:31:26  louie * A few cosmetic changes for ntpd.c *  * Revision 3.4.1.6  89/05/03  15:17:27  louie * ntpdc now will display addional peer flags which indicate how far through * the clock selection process a peer was considered. *  * Revision 3.4.1.5  89/04/08  10:38:06  louie * Minor cosmetic changes and removed dead debug code from ntpd.c *  * Revision 3.4.1.4  89/03/29  12:41:56  louie * Check for success sending query before trying to listen for answers.  Will  * catch case of no server running and an ICMP port unreachable being returned. *  * Revision 3.4.1.3  89/03/22  18:29:53  louie * patch3: Use new RCS headers. *  * Revision 3.4.1.2  89/03/22  18:04:18  louie * Display dispersion in milliseconds.  The peer->refid field was being ntohl()'ed * when it should have stayed in network byte order. *  * Revision 3.4.1.1  89/03/20  00:13:41  louie * patch1: Delete unused variables.  Display interface address in numeric form * patch1: for local address, rather than symbolically.  For multiple host * patch1: queries, the name of the host is emitted prior to the data for that * patch1: host. *  * Revision 3.4  89/03/17  18:37:16  louie * Latest test release. *  * Revision 3.3.1.1  89/03/17  18:27:43  louie * Fix version number mismatch error message. *  * Revision 3.3  89/03/15  14:20:00  louie * New baseline for next release. *  * Revision 3.2.1.2  89/03/15  14:03:02  louie * The logical used to receive replies has been revised considerably.  Each packet * in the reply from the ntpd program carries the total number of packets in the * reply as well as a sequence number for this packet.  Thus, we know how many * packets to expect, and which one's we're received already.  A new UDP socket * is used for each host to prevent the replies from being mixed.  This was * a problem when querying an old ntpd which returned 7 bad version packets.. * Use "%f" rather than "%lf" in format strings. *  * Revision 3.2.1.1  89/03/10  12:28:24  louie * Clean up output fomatting somewhat. *  * Revision 3.2  89/03/07  18:27:52  louie * Cosmetic changes and bug fixes.  Note that this version is likely to be * slightly incompatible with previous versions because the definitions of * the flage bits (PEER_FL_*) in ntp.h have changed. *  * A future version of this program will have a considerably different * packet format when Version 2 support is added. *  * Revision 3.1.1.1  89/02/15  09:01:39  louie * Bugfixes to previous release version. *  *  * Revision 3.1  89/01/30  14:43:16  louie * Second UNIX NTP test release. *  * Revision 3.0  88/12/12  15:57:28  louie * Test release of new UNIX NTP software.  This version should conform to the * revised NTP protocol specification. *  */#include <sys/types.h>#include <sys/param.h>#include <signal.h>#include <sys/uio.h>#include <sys/socket.h>#include <sys/time.h>#include <netinet/in.h>#include <netinet/udp.h>#include <errno.h>#include <stdio.h>#include <netdb.h>#include <strings.h>#include <arpa/inet.h>#include "ntp.h"#define	WTIME	10		/* Time to wait for all responses */#define	STIME	500000		/* usec to wait for another response */#define	MAXPACKETSIZE 1500extern int errno;int debug;int s;int timedout, timeout();int nflag, vflag;struct sockaddr_in sin = {AF_INET};char packet[MAXPACKETSIZE];#ifndef	MAXHOSTNAMELEN#define	MAXHOSTNAMELEN	64#endifchar	LocalHostName[MAXHOSTNAMELEN+1];	/* our hostname */char	*LocalDomain;		/* our local domain name */main(argc, argv)	int argc;	char *argv[];{	char *p;	int on = 48*1024;	(void) gethostname(LocalHostName, sizeof LocalHostName);	if (p = index(LocalHostName, '.')) {		*p++ = '\0';		LocalDomain = p;	}	else		LocalDomain = "";	if (argc < 2) {usage:		printf("usage: %s [ -v ][ -n ] hosts...\n", argv[0]);		exit(1);	}	argv++, argc--;	if (*argv[0] == '-') {		switch (argv[0][1]) {		case 'n':			nflag++;			break;		case 'v':			vflag++;			break;		default:			goto usage;		}		argc--, argv++;	}	if (argc > 1)		printf("--- %s ---\n", *argv);	while (argc > 0) {		/*		 * Get a new socket each time - this will cause us to ignore		 * packets from the previously queried host.		 */		s = socket(AF_INET, SOCK_DGRAM, 0);		if (s < 0) {			perror("socket");			exit(2);		}#ifdef	SO_RCVBUF		if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, &on, sizeof (on)) < 0) {			fprintf(stderr, "setsockopt SO_RCVBUF\n");		}#endif		if (query(*argv))			answer(*argv);		close(s);		argv++;		if (argc-- > 1)			printf("--- %s ---\n", *argv);	}}answer(host)	char *host;{	register struct ntpinfo *msg = (struct ntpinfo *) packet;	register struct clockinfo *n;	struct sockaddr_in from;	int fromlen = sizeof(from);	int count, cc;	fd_set bits;	struct timeval shorttime;	int first = 1;	long replies = 0;	/*	 * Listen for returning packets; may be more than one packet per	 * host. 	 */	FD_ZERO(&bits);	FD_SET(s, &bits);	shorttime.tv_sec = 0;	shorttime.tv_usec = STIME;	(void) signal(SIGALRM, timeout);	(void) alarm(WTIME);	timedout = 0;	while ((first || replies) && 	       (!timedout || select(FD_SETSIZE, &bits, (fd_set *) 0,				    (fd_set *) 0, &shorttime) > 0)) {		if ((cc = recvfrom(s, packet, sizeof(packet), 0,			     (struct sockaddr *)&from, &fromlen)) <= 0) {			if (cc == 0 || errno == EINTR)				continue;			fflush(stdout);			perror(host);			(void) close(s);			return;		}		FD_SET(s, &bits);		if (msg->type != INFO_REPLY)			return;		if (msg->version != NTPDC_VERSION) {			printf("ntpd(%d) - ntpdc(%d) version mismatch\n",			       msg->version, NTPDC_VERSION);			alarm(0);			return;		}		if (first) {			first = 0;			replies = (1L << msg->npkts) - 1;			if (!vflag) {				printf("   (rem)  Address   (lcl)      Strat Poll Reach    Delay   Offset    Disp\n");				printf("==========================================================================\n");			}		}		replies &= ~(1L << msg->seq);		n = (struct clockinfo *)&msg[1];		for (count = msg->count; count > 0; count--) {			if(vflag)				print_verbose(n);			else				print_terse(n);			n++;		}	}	alarm(0);	if (replies)		printf("Timed out waiting for replies\n");}intquery(host)	char *host;{	struct sockaddr_in watcher;	register struct ntpdata *msg = (struct ntpdata *) packet;	struct hostent *hp;	static struct servent *sp = NULL;	long HostAddr;	bzero((char *) &watcher, sizeof(watcher));	watcher.sin_family = AF_INET;	HostAddr = inet_addr(host);	watcher.sin_addr.s_addr = (u_long) HostAddr;	if (HostAddr == -1) {		hp = gethostbyname(host);		if (hp == 0) {			fprintf(stderr,"%s: unknown\n", host);			return 0;		}		bcopy(hp->h_addr, (char *) &watcher.sin_addr, hp->h_length);	}	sp = getservbyname("ntp", "udp");	if (sp == 0) {		fprintf(stderr,"udp/ntp: service unknown, using default %d\n",			NTP_PORT);		watcher.sin_port = htons(NTP_PORT);	} else		watcher.sin_port = sp->s_port;	msg->status = NTPVERSION_1;	msg->stratum = INFO_QUERY;	if (connect(s, (struct sockaddr *) &watcher, sizeof(watcher))) {		perror("connect");		return 0;	}	if (send(s, packet, sizeof(struct ntpdata), 0) < 0) {		perror("send");		return 0;	}	return 1;}timeout(){	timedout = 1;}print_terse (n)	struct clockinfo *n;{	int i;	double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;	char c;	char *cvthname();	int flags;	sin.sin_addr.s_addr = n->net_address;	for (i = 0; i < PEER_SHIFT; i++) {		delay[i] = (double) ((long) (ntohl(n->info_filter.delay[i])/1000.0));		offset[i] = (double) ((long) (ntohl(n->info_filter.offset[i])/1000.0));	}	dsp = (long) ntohl(n->estdisp);		/* leave in milliseconds */	del = (long) ntohl(n->estdelay);	/* leave in milliseconds */	off = (long) ntohl(n->estoffset);	/* leave in milliseconds */	c = ' ';	flags = ntohs(n->flags);	if (flags & PEER_FL_CONFIG)		c = '-';		/* mark pre-configured */	if (flags & PEER_FL_SANE)		c = '.';		/* passed sanity check */	if (flags & PEER_FL_CANDIDATE)		c = '+';		/* made candidate list */	if (flags & PEER_FL_SELECTED)		c = '*';		/* mark peer selection */	sin.sin_addr.s_addr = n->net_address;	printf("%c%-15.15s ", c, cvthname(&sin));	sin.sin_addr.s_addr = n->my_address;	printf("%-16.16s %2d %4d  %03o  %8.1f %8.1f %8.1f\n",	       sin.sin_addr.s_addr ? inet_ntoa(sin.sin_addr) : "wildcard", 	       n->stratum, (int)ntohl((u_long)n->timer), 	       ntohs(n->reach) & SHIFT_MASK, del, off, dsp);}	print_verbose(n)	struct clockinfo *n;{	int i;	struct in_addr clock_host;	double offset[PEER_SHIFT], delay[PEER_SHIFT], dsp,del,off;	char *cvthname();	sin.sin_addr.s_addr = n->net_address;	for (i = 0; i < PEER_SHIFT; i++) {		delay[i] = (double) (long) ntohl(n->info_filter.delay[i]);		offset[i] = (double) (long) ntohl(n->info_filter.offset[i]);	}	dsp = (double) ((long) ntohl(n->estdisp));	/* in milliseconds */	del = (double) ((long) ntohl(n->estdelay));	/* in milliseconds */	off = (double) ((long) ntohl(n->estoffset));	/* in milliseconds */	printf("Neighbor address %s port:%d",	       inet_ntoa(sin.sin_addr), (int)ntohs(n->port));	sin.sin_addr.s_addr = n->my_address;	printf("  local address %s\n", inet_ntoa(sin.sin_addr));	printf("Reach: 0%o stratum: %d, precision: %d\n",	       ntohs(n->reach) & SHIFT_MASK, n->stratum, n->precision);	printf("dispersion: %f, flags: %x, leap: %x\n",	       dsp,	       ntohs(n->flags),	       n->leap);	if (n->stratum == 1 || n->stratum == 0) {		printf("Reference clock ID: %.4s", (char *)&n->refid);	} else {		clock_host.s_addr = (u_long) n->refid;		printf("Reference clock ID: [%s]", inet_ntoa(clock_host));	}	printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part),	       ntohl(n->reftime.fraction));	printf("hpoll: %d, ppoll: %d, timer: %d, sent: %d received: %d\n",	       n->hpoll, n->ppoll,	       (int)ntohl((u_long)n->timer),	       (int)ntohl(n->pkt_sent),	       (int)ntohl(n->pkt_rcvd));	printf("Delay(ms)  ");	for (i = 0; i < PEER_SHIFT; i++)		printf("%7.2f ", delay[i]);	printf("\n");	printf("Offset(ms) ");	for (i = 0; i < PEER_SHIFT; i++)		printf("%7.2f ", offset[i]);	printf("\n");	printf("\n\tdelay: %f offset: %f dsp %f\n", del, off, dsp);	printf("\n");}/* * Return a printable representation of a host address. */char *cvthname(f)	struct sockaddr_in *f;{	struct hostent *hp;	register char *p;	extern char *inet_ntoa();	if (f->sin_family != AF_INET) {		printf("Malformed from address\n");		return ("???");	}	if (!nflag)		hp = gethostbyaddr(&f->sin_addr, sizeof(struct in_addr),				   f->sin_family);	else		return (inet_ntoa(f->sin_addr));	if (hp == 0)		return (inet_ntoa(f->sin_addr));	if ((p = index(hp->h_name, '.')) && strcmp(p + 1, LocalDomain) == 0)		*p = '\0';	return (hp->h_name);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?