ntpd.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 1,502 行 · 第 1/3 页

C
1,502
字号
#ifndef lintstatic	char	*sccsid = "@(#)ntpd.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/ntpd.c,v $ $Revision: 3.4.1.9 $ $Date: 89/05/18 18:30:17 $";#endif	lint/* *  $Log:	ntpd.c,v $ * Revision 3.4.1.9  89/05/18  18:30:17  louie * Changes in ntpd.c for reference clock support.  Also, a few diddles to * accomodate the NeXT computer system that has a slightly different nlist.h *  * Revision 3.4.1.8  89/05/03  15:16:17  louie * Add code to save the value of the drift compensation register to a file every * hour.  Add additional configuration file directives which can specify the same * information as on the command line. *  * Revision 3.4.1.7  89/04/10  15:58:45  louie * Add -l option to enable logging of clock adjust messages. *  * Revision 3.4.1.6  89/04/07  19:09:04  louie * Added NOSWAP code for Ultrix systems to lock NTP process in memory.  Deleted * unused variable in ntpd.c *  * Revision 3.4.1.5  89/03/31  16:37:49  louie * Add support for "trusting" directive in NTP configuration file.  It allows  * you to specify at run time if non-configured peers will be synced to. *  * Revision 3.4.1.4  89/03/29  12:30:46  louie * peer->mode has been renamed peer->hmode.  Drop PEER_FL_SYNC since the * PEER_FL_CONFIG flag means much the same thing. *  * Revision 3.4.1.3  89/03/22  18:29:41  louie * patch3: Use new RCS headers. *  * Revision 3.4.1.2  89/03/22  18:03:17  louie * The peer->refid field was being htonl()'ed when it was already in network * byte order. *  * Revision 3.4.1.1  89/03/20  00:12:10  louie * patch1: Diddle syslog messages a bit.  Handle case of udp/ntp not being * patch1: defined in /etc/services.  Compute default value for tickadj if * patch1: the change-kernel-tickadj flag is set, but no tickadj directive * patch1: is present in the configuration file. *  * Revision 3.4  89/03/17  18:37:11  louie * Latest test release. *  * Revision 3.3.1.1  89/03/17  18:26:32  louie * 1 *  * Revision 3.3  89/03/15  14:19:56  louie * New baseline for next release. *  * Revision 3.2.1.2  89/03/15  13:59:50  louie * Initialize random number generator.  The ntpdc query_mode() routine has been * revised to send more peers per packet, a count of the total number of peers * which will be transmited, the number of packets to be transmitted, and a  * sequence number for each packet.  There is a new version number for the * ntpdc query packets, which is now symbolically defined in ntp.h *  * Revision 3.2.1.1  89/03/10  12:27:41  louie * Removed reference to HUGE, and replaced it by a suitable large number.  Added * some #ifdef DEBUG .. #endif around some debug code that was missing.  Display * patchlevel along with version. *  * Revision 3.2  89/03/07  18:26:30  louie * New version of the UNIX NTP daemon based on the 6 March 1989 draft of the * new NTP protcol spec.  A bunch of cosmetic changes.  The peer list is * now doublely linked, and a subroutine (enqueue()) replaces the ENQUEUE * macro used previously. *  * Revision 3.1.1.1  89/02/15  08:58:46  louie * Bugfixes to released version. *  *  * Revision 3.1  89/01/30  14:43:14  louie * Second UNIX NTP test release. *  * Revision 3.0  88/12/12  15:56:38  louie * Test release of new UNIX NTP software.  This version should conform to the * revised NTP protocol specification. *  */#include <stdio.h>#include <sys/types.h>#include <sys/param.h>#include <sys/uio.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/ioctl.h>#include <sys/resource.h>#include <sys/file.h>#ifdef NOSWAP#include <sys/lock.h>#endif#include <net/if.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/udp.h>#include <arpa/inet.h>#include <netdb.h>#include <strings.h>#include <errno.h>#include <syslog.h>#include <nlist.h>#include "ntp.h"#include "patchlevel.h"#define	TRUE	1#define	FALSE	0struct sockaddr_in dst_sock = {AF_INET};struct servent *servp;struct list peer_list;struct itimerval it;struct itimerval *itp = &it;struct timeval tv;char *prog_name;char *conf = NTPINITFILE;char *driftcomp_file = NTPDRIFTCOMP;static int drift_fd = -1;#ifdef	DEBUGint debug = 0;#endif#ifdef	SETTICKADJint	tickadj = 0;int	dotickadj = 0;#endif#ifdef	NOSWAPint	noswap = 0;#endifint doset = 1;int ticked;int selfds;int trusting = 1;int logstats;double WayTooBig = WAYTOOBIG;unsigned long clock_watchdog;struct ntpdata ntpframe;struct sysdata sys;extern int errno;extern char *malloc(), *ntoa();extern double s_fixed_to_double(), ul_fixed_to_double();void finish(), timeout(), tock(), make_new_peer(), init_ntp(), initialize(),	init_kern_vars(), hourly();extern void transmit(), process_packet(), clock_update(),	clear(), clock_filter(), select_clock();extern void init_logical_clock();main(argc, argv)	int argc;	char *argv[];{	struct sockaddr_in *dst = &dst_sock;	struct ntpdata *pkt = &ntpframe;	fd_set readfds, tmpmask;	int dstlen = sizeof(struct sockaddr_in);	int cc;	register int i;	extern char *optarg;	extern int atoi();#if	defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)	void incdebug(), decdebug();#endif	initialize();		/* call NTP protocol initialization first,				   then allow others to override default				   values */	prog_name = argv[0];	while ((cc = getopt(argc, argv, "a:c:dD:lstn")) != EOF) {		switch (cc) {		case 'a':			if (strcmp(optarg, "any") == 0)				WayTooBig = 10e15;			else				WayTooBig = atof(optarg);			break;		case 'd':#ifdef	DEBUG			debug++;#else			fprintf(stderr, "%s: not compiled with DEBUG\n",				prog_name);#endif			break;		case 'D':#ifdef	DEBUG			debug = atoi(optarg);#else			fprintf(stderr, "%s: not compiled with DEBUG\n",				prog_name);#endif			break;		case 's':			doset = 0;			break;		case 't':#ifdef	SETTICKADJ			dotickadj++;#else			fprintf(stderr, "%s: not compiled to set tickadj\n",				prog_name);#endif			break;		case 'n':#ifdef	NOSWAP			noswap = 1;#else			fprintf(stderr, "%s: not compiled for noswap\n",				prog_name);#endif			break;		case 'l':			logstats = 1;			break;		case 'c':			conf = optarg;			break;		default:			fprintf(stderr, "ntpd: -%c: unknown option\n", cc);			break;		}	}#ifdef	DEBUG	if (!debug) {#endif		if (fork())			exit(0);		{			int s;			for (s = getdtablesize(); s >= 0; s--)				(void) close(s);			(void) open("/", 0);			(void) dup2(0, 1);			(void) dup2(0, 2);			(void) setpgrp(0, getpid());			s = open("/dev/tty", 2);			if (s >= 0) {				(void) ioctl(s, (u_long) TIOCNOTTY, (char *) 0);				(void) close(s);			}		}#ifdef	DEBUG	}#endif#ifndef	LOG_DAEMON	openlog("ntpd", LOG_PID);#else#ifndef	LOG_NTP#define	LOG_NTP	LOG_DAEMON#endif	openlog("ntpd", LOG_PID | LOG_NDELAY, LOG_NTP);#ifdef	DEBUG	if (debug)		setlogmask(LOG_UPTO(LOG_DEBUG));	else#endif	/* DEBUG */		setlogmask(LOG_UPTO(LOG_INFO));#endif	/* LOG_DAEMON */	syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.9 $", prog_name);	syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);#ifdef	DEBUG	if (debug)		printf("%s version $Revision: 3.4.1.9 $ patchlevel %d\n",		       prog_name, PATCHLEVEL);#endif	(void) setpriority(PRIO_PROCESS, 0, -10);#ifdef	NOSWAP	if (noswap)		if (plock(PROCLOCK) != 0)  {			syslog(LOG_ERR, "plock() failed: %m");#ifdef	DEBUG			if (debug)				perror("plock() failed");#endif		}#endif	servp = getservbyname("ntp", "udp");	if (servp == NULL) {		syslog(LOG_CRIT, "udp/ntp: service unknown, using default %d",		       NTP_PORT);		(void) create_sockets(htons(NTP_PORT));	} else		(void) create_sockets(servp->s_port);	peer_list.head = peer_list.tail = NULL;	peer_list.members = 0;	init_ntp(conf);	init_kern_vars();	init_logical_clock();	/*	 * Attempt to open for writing the file for storing the drift comp	 * register.  File must already exist for snapshots to be taken.	 */	if ((i = open(driftcomp_file, O_WRONLY|O_CREAT, 0644)) >= 0) {		drift_fd = i;	}	(void) gettimeofday(&tv, (struct timezone *) 0);	srand(tv.tv_sec);	FD_ZERO(&tmpmask);	for (i = 0; i < nintf; i++) {		FD_SET(addrs[i].fd, &tmpmask);#ifdef	DEBUG		if (debug>2) {			if (addrs[i].if_flags & IFF_BROADCAST)				printf("Addr %d: %s fd %d %s broadcast %s\n",				       i, addrs[i].name, addrs[i].fd,				       ntoa(addrs[i].sin.sin_addr),				       ntoa(addrs[i].bcast.sin_addr));			else				printf("Addr %d: %s fd %d %s\n", i,				       addrs[i].name, addrs[i].fd,				       ntoa(addrs[i].sin.sin_addr));		}#endif	}	(void) signal(SIGINT, finish);	(void) signal(SIGTERM, finish);	(void) signal(SIGALRM, tock);#if	defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)	(void) signal(SIGUSR1, incdebug);	(void) signal(SIGUSR2, decdebug);#endif	itp->it_interval.tv_sec = (1<<CLOCK_ADJ);	itp->it_interval.tv_usec = 0;	itp->it_value.tv_sec = 1;	itp->it_value.tv_usec = 0;	/*	 * Find highest fd in use.  This might save a few microseconds in	 * the select system call.	 */	for (selfds = FD_SETSIZE - 1; selfds; selfds--)		if (FD_ISSET(selfds, &tmpmask))			break;#ifdef	DEBUG	if (debug > 2)		printf("Highest fd in use is %d\n", selfds);	if (!selfds) abort();#endif	selfds++;	(void) setitimer(ITIMER_REAL, itp, (struct itimerval *) 0);	for (;;) {		/* go into a finite but hopefully very long				 * loop */		int nfds;		readfds = tmpmask;		nfds = select(selfds, &readfds, (fd_set *) 0, (fd_set *) 0,						(struct timeval *) 0);		(void) gettimeofday(&tv, (struct timezone *) 0);		for(i = 0; i < nintf && nfds; i++) {			if (!FD_ISSET(addrs[i].fd, &readfds))				continue;			addrs[i].uses++;			dstlen = sizeof(struct sockaddr_in);			if ((cc = 			     recvfrom(addrs[i].fd, (char *) pkt, 				      sizeof(ntpframe), 0, 				      (struct sockaddr *) dst, &dstlen)) < 0) {				if (errno != EWOULDBLOCK) {					syslog("recvfrom: %m");#ifdef	DEBUG					if(debug > 2)						perror("recvfrom");#endif				}				continue;			}			if (cc < sizeof(*pkt)) {#ifdef	DEBUG				if (debug)					printf("Runt packet from %s\n",					       ntoa(dst->sin_addr));#endif				continue;			}			if (pkt->stratum == INFO_QUERY || 			    pkt->stratum == INFO_REPLY) {				query_mode(dst, pkt, i);				continue;			}#ifdef	DEBUG			if (debug > 3) {				printf("\nInput ");				dump_pkt(dst, pkt, NULL);			}#endif			if ((pkt->status & VERSIONMASK) != NTPVERSION_1)				continue;			receive(dst, pkt, &tv, i);		}		if (ticked) {			ticked = 0;			timeout();		}	}			/* end of forever loop */}struct ntp_peer *check_peer(dst, sock)	struct sockaddr_in *dst;	int sock;{	register struct ntp_peer *peer = peer_list.head;	while (peer != NULL) {		if ((peer->src.sin_addr.s_addr == dst->sin_addr.s_addr) &&		    (peer->src.sin_port == dst->sin_port) &&		    ((peer->sock == sock) || (peer->sock == -1)))			return peer;		peer = peer->next;	}	return ((struct ntp_peer *) NULL);}#ifdef	DEBUGdump_pkt(dst, pkt, peer)	struct sockaddr_in *dst;	struct ntpdata *pkt;	struct ntp_peer *peer;{	struct in_addr clock_host;	printf("Packet: [%s](%d)\n", inet_ntoa(dst->sin_addr),	       (int) htons(dst->sin_port));	printf("Leap %d, version %d, mode %d, poll %d, precision %d stratum %d",

⌨️ 快捷键说明

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