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 = ⁢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 + -
显示快捷键?