📄 ntpd.c
字号:
#ifndef lintstatic char *rcsid = "$Header: /xtel/isode/isode/others/ntp/RCS/ntpd.c,v 9.0 1992/06/16 14:45:01 isode Rel $";#endif lint/* * ntp daemon - based on the 3.4 version but heavily modified for OSI * interworking. * * $Log: ntpd.c,v $ * Revision 9.0 1992/06/16 14:45:01 isode * Release 8.0 * * */#include "ntp.h"#include "patchlevel.h"#ifndef L_SET#define L_SET SEEK_SET#endifchar *conf = NTPINITFILE;char *driftcomp_file = NTPDRIFTCOMP;char *osiaddress = "Internet=localhost+10123";char *myname = "ntpd";int doset = 1;int selfds = 0;int trusting = 1;int keepallpeers = 1;int logstats;#ifdef DEBUGint debug = 0;#endif#ifdef SETTICKADJint tickadj = 0;int dotickadj = 0;#endif#ifdef NOSWAPint noswap = 0;#endifunsigned int servport;unsigned long clock_watchdog;double WayTooBig = WAYTOOBIG;struct list peer_list;struct timeval tv;struct ntpdata ntpframe;struct sysdata sys;fd_set globmask, globwmask;/* STATIC data */static int drift_fd = -1;static LLog _pgm_log = { "ntp.log", NULLCP, NULLCP, LLOG_FATAL | LLOG_EXCEPTIONS | LLOG_NOTICE, LLOG_FATAL, -1, LLOGCLS | LLOGCRT, NOTOK};LLog *pgm_log = &_pgm_log;static int priority = -10;static int ticked;static void timeout();static void init_ntp();void initialize();static void init_kern_vars();static void hourly();static void do_peer ();static SFD finish ();extern void make_new_peer();extern void transmit();extern void process_packet();extern void clock_update();extern void clear();extern void clock_filter();extern void select_clock();extern void advise ();extern void adios ();extern void init_logical_clock();extern void create_osilisten ();extern void iso_init ();extern void poll_update();#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)static SFD incdebug(), decdebug();#endifstruct ntp_peer *find_peer ();main(argc, argv)int argc;char *argv[];{ int cc; extern char *optarg; register int i; if (myname = rindex (argv[0], '/')) myname++; if (myname == NULL || *myname == NULL) myname = argv[0]; isodetailor (myname, 0); initialize(); /* call NTP protocol initialization first, then allow others to override default values */ while ((cc = getopt(argc, argv, "a:c:dD:lstnp:")) != EOF) { switch (cc) { case 'a': if (strcmp(optarg, "any") == 0) WayTooBig = 10e15; else WayTooBig = atof(optarg); break; case 'd':#ifdef DEBUG debug++;#else adios (NULLCP, "%s: not compiled with DEBUG", myname);#endif break; case 'D':#ifdef DEBUG debug = atoi(optarg);#else adios (NULLCP, "%s: not compiled with DEBUG", myname);#endif break; case 's': doset = 0; break; case 't':#ifdef SETTICKADJ dotickadj++;#else adios (NULLCP, "%s: not compiled to set tickadj", myname);#endif break; case 'n':#ifdef NOSWAP noswap = 1;#else adios (NULLCP, "%s: not compiled for noswap", myname);#endif break; case 'l': logstats = 1; break; case 'c': conf = optarg; break; case 'p': servport = htons (atoi(optarg)); break; default: adios (NULLCP, "ntpd: -%c: unknown option", cc); break; } } if (servport == 0) { struct servent *sp; if ((sp = getservbyname ("ntp", "udp")) == NULL) servport = htons (NTP_PORT); else servport = sp -> s_port; } peer_list.head = peer_list.tail = NULL; peer_list.members = 0; srandom(getpid ()); init_ntp(conf); init_kern_vars(); init_logical_clock(); envinit (); create_listeners (); /* * 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; } doit (); return 0;}doit (){ struct timeval tvt; fd_set readfds, writefds; int vecp; char *vec[4]; struct TSAPdisconnect tds; struct TSAPdisconnect *td = &tds; register int i; int newfd; (void) gettimeofday(&tv, (struct timezone *) 0); FD_ZERO(&globmask); FD_ZERO(&globwmask); for (i = 0; i < nintf; i++) { if ((addrs[i].flags & INTF_VALID) == 0) continue; FD_SET(addrs[i].fd, &globmask); if (addrs[i].if_flags & IFF_BROADCAST) TRACE (2, ("Addr %d: %s fd %d %s broadcast %s", i, addrs[i].name, addrs[i].fd, paddr (&addrs[i].addr), ntoa (&addrs[i].bcast))); else TRACE (2, ("Addr %d: %s fd %d %s", i, addrs[i].name, addrs[i].fd, paddr (&addrs[i].addr))); } (void) signal(SIGINT, finish); (void) signal(SIGTERM, finish);#if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2) (void) signal(SIGUSR1, incdebug); (void) signal(SIGUSR2, decdebug);#endif /* * 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, &globmask)) break; TRACE (2, ("Highest fd in use is %d", selfds)); if (!selfds) abort(); selfds++; /* prime the pump! */ ticked = 1; (void) gettimeofday(&tv, (struct timezone *) 0); for (;;) { /* go into a finite but hopefully very long loop */ readfds = globmask; writefds = globwmask; TRACE (7, ("wait nfds %d, fds 0x%x 0x%x", selfds, readfds.fds_bits[0], writefds.fds_bits[0])); if (ticked) { ticked = 0; tvt = tv; } (void) TNetAcceptAux (&vecp, vec, &newfd, NULLTA, selfds, &readfds, &writefds, NULLFD, (1<<CLOCK_ADJ), td); (void) gettimeofday(&tv, (struct timezone *) 0); if (tv.tv_sec - tvt.tv_sec >= (1 << CLOCK_ADJ)) ticked = 1; if (vecp > 0) iso_init (vecp, vec, newfd); for(i = 0; i < nintf; i++) { if ((addrs[i].flags & INTF_SELECT) == 0) continue; if (!FD_ISSET(addrs[i].fd, &readfds) && !FD_ISSET (addrs[i].fd, &writefds)) continue; TRACE (3, ("Activity on if %d fd=%d (%s)", i, addrs[i].fd, addrs[i].name)); if (addrs[i].flags & INTF_PENDING) { struct ntp_peer *p = find_peer (i); if (p) (void) make_osi_conn (find_peer(i), osiaddress); continue; } if (addrs[i].flags & INTF_ACCEPTING) { (void) iso_accept (&addrs[i]); continue; } addrs[i].uses++; switch (addrs[i].addr.type) { case AF_INET: if (recv_inet (&addrs[i], &tv) == -1) continue; break; case AF_OSI: if (recv_osi (&addrs[i], &tv) == -1) continue; break; default: TRACE (1, ("Address family %d not supported", addrs[i].addr.type)); continue; } } if (ticked) timeout((int) (tv.tv_sec - tvt.tv_sec)); }}struct ntp_peer *check_peer(dst, sock) struct Naddr *dst; int sock;{ register struct ntp_peer *peer = peer_list.head; while (peer != NULL) { if (addr_compare (&peer->src, dst) && ((peer->sock == sock) || (peer->sock == -1))) return peer; peer = peer->next; } return ((struct ntp_peer *) NULL);}#ifdef DEBUGvoiddump_pkt(dst, pkt, peer) struct Naddr *dst; struct ntpdata *pkt; struct ntp_peer *peer;{ struct Naddr clock_host; (void) printf("Packet: %s\n", paddr (dst)); (void) printf("Leap %d, version %d, mode %d, poll %d, precision %d stratum %d", (int)(pkt->status & LEAPMASK) >> 6, (int)(pkt->status & VERSIONMASK) >> 3, pkt->status & MODEMASK, pkt->ppoll, pkt->precision, pkt->stratum); switch (pkt->stratum) { case 0: case 1: (void) printf(" (%.4s)\n", (char *)&pkt->refid); break; default: clock_host.inet_ad.sin_addr.s_addr = (u_long) pkt->refid; clock_host.type = AF_INET; (void) printf(" [%s]\n", paddr (&clock_host)); break; } (void) printf("Synch Dist is %04X.%04X Synch Dispersion is %04X.%04X\n", ntohs((u_short) pkt->distance.int_part), ntohs((u_short) pkt->distance.fraction), ntohs((u_short) pkt->dispersion.int_part), ntohs((u_short) pkt->dispersion.fraction)); (void) printf("Reference Timestamp is %08lx.%08lx\n", ntohl(pkt->reftime.int_part), ntohl(pkt->reftime.fraction)); (void) printf("Originate Timestamp is %08lx.%08lx\n", ntohl(pkt->org.int_part), ntohl(pkt->org.fraction)); (void) printf("Receive Timestamp is %08lx.%08lx\n", ntohl(pkt->rec.int_part), ntohl(pkt->rec.fraction)); (void) printf("Transmit Timestamp is %08lx.%08lx\n", ntohl(pkt->xmt.int_part), ntohl(pkt->xmt.fraction)); if(peer != NULL) (void) printf("Input Timestamp is %08lx.%08lx\n", ntohl(peer->rec.int_part), ntohl(peer->rec.fraction)); (void) putchar('\n');}#endifvoidmake_new_peer(peer) struct ntp_peer *peer;{ int i; void double_to_s_fixed (); /* * initialize peer data fields */ bzero ((char *)peer, sizeof (*peer)); peer->src.type = peer->src.inet_ad.sin_family = AF_INET; peer->hmode = MODE_SYM_PAS; /* default: symmetric passive mode */ peer->timer = 1 << NTP_MINPOLL; peer->hpoll = NTP_MINPOLL; peer->ppoll = NTP_MAXPOLL; peer->vers = 2; peer->mode = 0; double_to_s_fixed(&peer->dispersion, PEER_MAXDISP); peer->estoffset = 0.0; peer->estdelay = 0.0; for (i = 0; i < NTP_WINDOW; i++) { peer->filter.offset[i] = 0.0; peer->filter.delay[i] = 0.0; }}/* * This procedure is called to delete a peer from our list of peers. */demobilize(l, peer) struct list *l; struct ntp_peer *peer;{ extern struct ntp_peer dummy_peer; if (keepallpeers) { peer -> flags |= PEER_FL_SNOOZE; return 0; } if (peer == &dummy_peer)#ifdef DEBUG abort();#else return 1;#endif#ifdef DEBUG if ((peer->next == NULL && peer->prev == NULL) || l->tail == NULL || l->head == NULL) abort();#endif /* delete only peer in list? */ if (l->head == l->tail) {#ifdef DEBUG if (l->head != peer) abort();#endif l->head = l->tail = NULL; goto dropit; } /* delete first peer? */ if (l->head == peer) { l->head = peer->next; l->head->prev = NULL; goto dropit; } /* delete last peer? */ if (l->tail == peer) { l->tail = peer->prev; l->tail->next = NULL; goto dropit; } /* drop peer in middle */ peer->prev->next = peer->next; peer->next->prev = peer->prev; dropit:#ifdef DEBUG /* just some sanity checking */ if ((l->members < 0) || (l->members && l->tail == NULL) || (l->members == 0 && l->tail != NULL)) { advise (LLOG_EXCEPTIONS, NULLCP, "List hosed (demobilize)"); abort(); } peer->next = peer->prev = NULL;#endif free((char *) peer); l->members--; return 1;}enqueue(l, peer) register struct list *l; struct ntp_peer *peer;{ l->members++; if (l->tail == NULL) { /* insertion into empty list */ l->tail = l->head = peer; peer->next = peer->prev = NULL; return; } /* insert at end of list */ l->tail->next = peer; peer->next = NULL; peer->prev = l->tail; l->tail = peer;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -