# 2.11BSD#431 - /usr/src/usr.sbin/ntp/ntpd.c

##### Functions

    GetHostName       X
    check_peer        X
    decdebug          X
    demobilize        X
    dump_pkt          X
    enqueue           X
    finish            X
    hourly            X
    incdebug          X
    init_clock        X
    init_kern_vars    X
    init_ntp          X
    main              X
    make_new_peer     X
    query_mode        X
    read_clock        X
    timeout           X
    tock              X

##### Variables

    WayTooBig         X
    clock_watchdog    X
    conf              X
    debug             X
    doset             X
    driftcomp_file    X
    dst_sock          X
    it                X
    itp               X
    kern_hz           X
    logstats          X
    noswap            X
    ntpframe          X
    peer_list         X
    prog_name         X
    refclocks         X
    selfds            X
    servp             X
    sys               X
    ticked            X
    trusting          X
    tv                X

##### Macros

    FALSE             X
    LOG_NTP           X
    N_NTP_PKTS        X
    PKTBUF_SIZE       X
    TRUE              X

##### struct's

    refclock          X

       1: #if !defined(lint) && defined(DOSCCS)
       2: static char *rcsid = "$Source: /usr/src/new/ntp/ntpd.c,v $ $Revision: 3.4.1.12 $ $Date: 95/07/1 20:35:17 $";
       3: #endif	lint
       4:
       5: /*
       6:  *  $Log:	ntpd.c,v $
       7:  * Revision 3.4.1.11 95/01/31 20:35:17 sms
       8:  * Fix missing initializer before calling sysctl().
       9:  *
      10:  * Revision 3.4.1.10 95/01/27 17:20:17 sms
      11:  * 2.11BSD - remove SETTICKADJ from ntpd.c.  This was done for several reasons:
      12:  * 1) tickadj does not (and never has) existed, 2) this is an old version and
      13:  * not going to be ported to a system with tickadj, 3) with 'securelevel'
      14:  * (see sysctl(3), init(8) and sysctl(8)) set to 1 or 2 /dev/{k}mem can not
      15:  * be written even by root.  If tickadj were ever added it would need an
      16:  * extension to sysctl(3) to have a chance of working.
      17:  *
      18:  * Revision 3.4.1.9  89/05/18  18:30:17  louie
      19:  * Changes in ntpd.c for reference clock support.  Also, a few diddles to
      20:  * accomodate the NeXT computer system that has a slightly different nlist.h
      21:  *
      22:  * Revision 3.4.1.8  89/05/03  15:16:17  louie
      23:  * Add code to save the value of the drift compensation register to a file every
      24:  * hour.  Add additional configuration file directives which can specify the same
      25:  * information as on the command line.
      26:  *
      27:  * Revision 3.4.1.7  89/04/10  15:58:45  louie
      28:  * Add -l option to enable logging of clock adjust messages.
      29:  *
      30:  * Revision 3.4.1.6  89/04/07  19:09:04  louie
      31:  * Added NOSWAP code for Ultrix systems to lock NTP process in memory.  Deleted
      32:  * unused variable in ntpd.c
      33:  *
      34:  * Revision 3.4.1.5  89/03/31  16:37:49  louie
      35:  * Add support for "trusting" directive in NTP configuration file.  It allows
      36:  * you to specify at run time if non-configured peers will be synced to.
      37:  *
      38:  * Revision 3.4.1.4  89/03/29  12:30:46  louie
      39:  * peer->mode has been renamed peer->hmode.  Drop PEER_FL_SYNC since the
      40:  * PEER_FL_CONFIG flag means much the same thing.
      41:  *
      42:  * Revision 3.4.1.3  89/03/22  18:29:41  louie
      43:  * patch3: Use new RCS headers.
      44:  *
      45:  * Revision 3.4.1.2  89/03/22  18:03:17  louie
      46:  * The peer->refid field was being htonl()'ed when it was already in network
      47:  * byte order.
      48:  *
      49:  * Revision 3.4.1.1  89/03/20  00:12:10  louie
      50:  * patch1: Diddle syslog messages a bit.  Handle case of udp/ntp not being
      51:  * patch1: defined in /etc/services.  Compute default value for tickadj if
      52:  * patch1: the change-kernel-tickadj flag is set, but no tickadj directive
      53:  * patch1: is present in the configuration file.
      54:  *
      55:  * Revision 3.4  89/03/17  18:37:11  louie
      56:  * Latest test release.
      57:  *
      58:  * Revision 3.3.1.1  89/03/17  18:26:32  louie
      59:  * 1
      60:  *
      61:  * Revision 3.3  89/03/15  14:19:56  louie
      62:  * New baseline for next release.
      63:  *
      64:  * Revision 3.2.1.2  89/03/15  13:59:50  louie
      65:  * Initialize random number generator.  The ntpdc query_mode() routine has been
      66:  * revised to send more peers per packet, a count of the total number of peers
      67:  * which will be transmited, the number of packets to be transmitted, and a
      68:  * sequence number for each packet.  There is a new version number for the
      69:  * ntpdc query packets, which is now symbolically defined in ntp.h
      70:  *
      71:  * Revision 3.2.1.1  89/03/10  12:27:41  louie
      72:  * Removed reference to HUGE, and replaced it by a suitable large number.  Added
      73:  * some #ifdef DEBUG .. #endif around some debug code that was missing.  Display
      74:  * patchlevel along with version.
      75:  *
      76:  * Revision 3.2  89/03/07  18:26:30  louie
      77:  * New version of the UNIX NTP daemon based on the 6 March 1989 draft of the
      78:  * new NTP protcol spec.  A bunch of cosmetic changes.  The peer list is
      79:  * now doublely linked, and a subroutine (enqueue()) replaces the ENQUEUE
      80:  * macro used previously.
      81:  *
      82:  * Revision 3.1.1.1  89/02/15  08:58:46  louie
      83:  * Bugfixes to released version.
      84:  *
      85:  *
      86:  * Revision 3.1  89/01/30  14:43:14  louie
      87:  * Second UNIX NTP test release.
      88:  *
      89:  * Revision 3.0  88/12/12  15:56:38  louie
      90:  * Test release of new UNIX NTP software.  This version should conform to the
      91:  * revised NTP protocol specification.
      92:  *
      93:  */
      94:
      95: #include <stdio.h>
      96: #include <sys/types.h>
      97: #include <sys/param.h>
      98: #include <sys/uio.h>
      99: #include <sys/socket.h>
     100: #include <sys/time.h>
     101: #include <sys/ioctl.h>
     102: #include <sys/resource.h>
     103: #include <sys/file.h>
     104: #ifdef NOSWAP
     105: #include <sys/lock.h>
     106: #endif
     107:
     108: #include <net/if.h>
     109:
     110: #include <netinet/in.h>
     111: #include <netinet/in_systm.h>
     112: #include <netinet/ip.h>
     113: #include <netinet/udp.h>
     114:
     115: #include <arpa/inet.h>
     116: #include <netdb.h>
     117: #include <strings.h>
     118: #include <errno.h>
     119: #include <syslog.h>
     120:
     121: #include "ntp.h"
     122: #include "patchlevel.h"
     123:
     124: #define TRUE    1
     125: #define FALSE   0
     126:
     127: struct sockaddr_in dst_sock = {AF_INET};
     128:
     129: struct servent *servp;
     130: struct list peer_list;
     131:
     132: struct itimerval it;
     133: struct itimerval *itp = &it;
     134: struct timeval tv;
     135: char *prog_name;
     136:
     137: char *conf = NTPINITFILE;
     138: char *driftcomp_file = NTPDRIFTCOMP;
     139: static int drift_fd = -1;
     140:
     141: #ifdef  DEBUG
     142: int debug = 0;
     143: #endif
     144:
     145: #ifdef  NOSWAP
     146: int noswap = 0;
     147: #endif
     148:
     149: int doset = 1;
     150: int ticked;
     151: int selfds;
     152: int trusting = 1;
     153: int logstats;
     154:
     155: double WayTooBig = WAYTOOBIG;
     156: u_long clock_watchdog;
     157:
     158: struct ntpdata ntpframe;
     159: struct sysdata sys;
     160:
     161: extern int errno;
     162: extern char *malloc(), *ntoa();
     163:
     164: void finish(), timeout(), tock(), make_new_peer(), init_ntp(), initialize(),
     165:     init_kern_vars(), hourly();
     166: extern void transmit(), process_packet(), clock_update(),
     167:     clear(), clock_filter(), select_clock();
     168:
     169: extern void init_logical_clock();
     170:
     171: main(argc, argv)
     172:     int argc;
     173:     char *argv[];
     174: {
     175:     struct sockaddr_in *dst = &dst_sock;
     176:     struct ntpdata *pkt = &ntpframe;
     177:     fd_set readfds, tmpmask;
     178:     int dstlen = sizeof(struct sockaddr_in);
     179:     int cc;
     180:     register int i;
     181:     extern char *optarg;
     182:     extern int atoi();
     183:
     184: #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
     185:     void incdebug(), decdebug();
     186: #endif
     187:     initialize();       /* call NTP protocol initialization first,
     188: 				   then allow others to override default
     189: 				   values */
     190:     prog_name = argv[0];
     191:     while ((cc = getopt(argc, argv, "a:c:dD:lstn")) != EOF) {
     192:         switch (cc) {
     193:         case 'a':
     194:             if (strcmp(optarg, "any") == 0)
     195:                 WayTooBig = 10e15;
     196:             else
     197:                 WayTooBig = atof(optarg);
     198:             break;
     199:
     200:         case 'd':
     201: #ifdef  DEBUG
     202:             debug++;
     203: #else
     204:             fprintf(stderr, "%s: not compiled with DEBUG\n",
     205:                 prog_name);
     206: #endif
     207:             break;
     208:
     209:         case 'D':
     210: #ifdef  DEBUG
     211:             debug = atoi(optarg);
     212: #else
     213:             fprintf(stderr, "%s: not compiled with DEBUG\n",
     214:                 prog_name);
     215: #endif
     216:             break;
     217:
     218:         case 's':
     219:             doset = 0;
     220:             break;
     221:
     222:         case 't':
     223:             fprintf(stderr, "%s: tickadj not supported\n",
     224:                 prog_name);
     225:             break;
     226:
     227:         case 'n':
     228: #ifdef  NOSWAP
     229:             noswap = 1;
     230: #else
     231:             fprintf(stderr, "%s: not compiled for noswap\n",
     232:                 prog_name);
     233: #endif
     234:             break;
     235:
     236:         case 'l':
     237:             logstats = 1;
     238:             break;
     239:
     240:         case 'c':
     241:             conf = optarg;
     242:             break;
     243:
     244:         default:
     245:             fprintf(stderr, "ntpd: -%c: unknown option\n", cc);
     246:             break;
     247:         }
     248:     }
     249:
     250: #ifdef  DEBUG
     251:     if (!debug) {
     252: #endif
     253:         if (fork())
     254:             exit(0);
     255:
     256:         {
     257:             int s;
     258:             for (s = getdtablesize(); s >= 0; s--)
     259:                 (void) close(s);
     260:             (void) open("/", 0);
     261:             (void) dup2(0, 1);
     262:             (void) dup2(0, 2);
     263:             (void) setpgrp(0, getpid());
     264:             s = open("/dev/tty", 2);
     265:             if (s >= 0) {
     266:                 (void) ioctl(s, (u_long) TIOCNOTTY, (char *) 0);
     267:                 (void) close(s);
     268:             }
     269:         }
     270: #ifdef  DEBUG
     271:     }
     272: #endif
     273:
     274: #ifndef LOG_DAEMON
     275:     openlog("ntpd", LOG_PID);
     276: #else
     277:
     278: #ifndef LOG_NTP
     279: #define LOG_NTP LOG_DAEMON
     280: #endif
     281:     openlog("ntpd", LOG_PID | LOG_NDELAY, LOG_NTP);
     282: #ifdef  DEBUG
     283:     if (debug)
     284:         setlogmask(LOG_UPTO(LOG_DEBUG));
     285:     else
     286: #endif	/* DEBUG */
     287:         setlogmask(LOG_UPTO(LOG_INFO));
     288: #endif	/* LOG_DAEMON */
     289:
     290:     syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.9 $", prog_name);
     291:     syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL);
     292:
     293: #ifdef  DEBUG
     294:     if (debug)
     295:         printf("%s version $Revision: 3.4.1.9 $ patchlevel %d\n",
     296:                prog_name, PATCHLEVEL);
     297: #endif
     298:     (void) setpriority(PRIO_PROCESS, 0, -10);
     299:
     300: #ifdef  NOSWAP
     301:     if (noswap)
     302:         if (plock(PROCLOCK) != 0)  {
     303:             syslog(LOG_ERR, "plock() failed: %m");
     304: #ifdef  DEBUG
     305:             if (debug)
     306:                 perror("plock() failed");
     307: #endif
     308:         }
     309: #endif
     310:
     311:     servp = getservbyname("ntp", "udp");
     312:     if (servp == NULL) {
     313:         syslog(LOG_CRIT, "udp/ntp: service unknown, using default %d",
     314:                NTP_PORT);
     315:         (void) create_sockets(htons(NTP_PORT));
     316:     } else
     317:         (void) create_sockets(servp->s_port);
     318:
     319:
     320:     peer_list.head = peer_list.tail = NULL;
     321:     peer_list.members = 0;
     322:
     323:     init_ntp(conf);
     324:     init_kern_vars();
     325:     init_logical_clock();
     326:
     327:     /*
     328: 	 * Attempt to open for writing the file for storing the drift comp
     329: 	 * register.  File must already exist for snapshots to be taken.
     330: 	 */
     331:     if ((i = open(driftcomp_file, O_WRONLY|O_CREAT, 0644)) >= 0) {
     332:         drift_fd = i;
     333:     }
     334:     (void) gettimeofday(&tv, (struct timezone *) 0);
     335:     srand(tv.tv_sec);
     336:
     337:     FD_ZERO(&tmpmask);
     338:     for (i = 0; i < nintf; i++) {
     339:         FD_SET(addrs[i].fd, &tmpmask);
     340: #ifdef  DEBUG
     341:         if (debug>2) {
     342:             if (addrs[i].if_flags & IFF_BROADCAST)
     343:                 printf("Addr %d: %s fd %d %s broadcast %s\n",
     344:                        i, addrs[i].name, addrs[i].fd,
     345:                        ntoa(addrs[i].sin.sin_addr),
     346:                        ntoa(addrs[i].bcast.sin_addr));
     347:             else
     348:                 printf("Addr %d: %s fd %d %s\n", i,
     349:                        addrs[i].name, addrs[i].fd,
     350:                        ntoa(addrs[i].sin.sin_addr));
     351:         }
     352: #endif
     353:     }
     354:
     355:     (void) signal(SIGINT, finish);
     356:     (void) signal(SIGTERM, finish);
     357:     (void) signal(SIGALRM, tock);
     358: #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
     359:     (void) signal(SIGUSR1, incdebug);
     360:     (void) signal(SIGUSR2, decdebug);
     361: #endif
     362:     itp->it_interval.tv_sec = (1<<CLOCK_ADJ);
     363:     itp->it_interval.tv_usec = 0;
     364:     itp->it_value.tv_sec = 1;
     365:     itp->it_value.tv_usec = 0;
     366:
     367:     /*
     368: 	 * Find highest fd in use.  This might save a few microseconds in
     369: 	 * the select system call.
     370: 	 */
     371:     for (selfds = FD_SETSIZE - 1; selfds; selfds--)
     372:         if (FD_ISSET(selfds, &tmpmask))
     373:             break;
     374: #ifdef  DEBUG
     375:     if (debug > 2)
     376:         printf("Highest fd in use is %d\n", selfds);
     377:     if (!selfds) abort();
     378: #endif
     379:     selfds++;
     380:
     381:     (void) setitimer(ITIMER_REAL, itp, (struct itimerval *) 0);
     382:
     383:     for (;;) {      /* go into a finite but hopefully very long
     384: 				 * loop */
     385:         int nfds;
     386:
     387:         readfds = tmpmask;
     388:         nfds = select(selfds, &readfds, (fd_set *) 0, (fd_set *) 0,
     389:                         (struct timeval *) 0);
     390:         (void) gettimeofday(&tv, (struct timezone *) 0);
     391:
     392:         for(i = 0; i < nintf && nfds > 0; i++) {
     393:             if (!FD_ISSET(addrs[i].fd, &readfds))
     394:                 continue;
     395:             addrs[i].uses++;
     396:             dstlen = sizeof(struct sockaddr_in);
     397:             if ((cc =
     398:                  recvfrom(addrs[i].fd, (char *) pkt,
     399:                       sizeof(ntpframe), 0,
     400:                       (struct sockaddr *) dst, &dstlen)) < 0) {
     401:
     402:                 if (errno != EWOULDBLOCK) {
     403:                     syslog(LOG_NOTICE, "recvfrom: %m");
     404: #ifdef  DEBUG
     405:                     if(debug > 2)
     406:                         perror("recvfrom");
     407: #endif
     408:                 }
     409:                 continue;
     410:             }
     411:
     412:             if (cc < sizeof(*pkt)) {
     413: #ifdef  DEBUG
     414:                 if (debug)
     415:                     printf("Runt packet from %s\n",
     416:                            ntoa(dst->sin_addr));
     417: #endif
     418:                 continue;
     419:             }
     420:
     421:             if (pkt->stratum == INFO_QUERY ||
     422:                 pkt->stratum == INFO_REPLY) {
     423:                 query_mode(dst, pkt, i);
     424:                 continue;
     425:             }
     426: #ifdef  DEBUG
     427:             if (debug > 3) {
     428:                 printf("\nInput ");
     429:                 dump_pkt(dst, pkt, NULL);
     430:             }
     431: #endif
     432:             if ((pkt->status & VERSIONMASK) != NTPVERSION_1)
     433:                 continue;
     434:
     435:             receive(dst, pkt, &tv, i);
     436:         }
     437:         if (ticked) {
     438:             ticked = 0;
     439:             timeout();
     440:         }
     441:     }           /* end of forever loop */
     442: }
     443:
     444: struct ntp_peer *
     445: check_peer(dst, sock)
     446:     struct sockaddr_in *dst;
     447:     int sock;
     448: {
     449:     register struct ntp_peer *peer = peer_list.head;
     450:
     451:     while (peer != NULL) {
     452:         if ((peer->src.sin_addr.s_addr == dst->sin_addr.s_addr) &&
     453:             (peer->src.sin_port == dst->sin_port) &&
     454:             ((peer->sock == sock) || (peer->sock == -1)))
     455:             return peer;
     456:         peer = peer->next;
     457:     }
     458:     return ((struct ntp_peer *) NULL);
     459: }
     460:
     461: #ifdef  DEBUG
     462: dump_pkt(dst, pkt, peer)
     463:     struct sockaddr_in *dst;
     464:     struct ntpdata *pkt;
     465:     struct ntp_peer *peer;
     466: {
     467:     struct in_addr clock_host;
     468:
     469:     printf("Packet: [%s](%d)\n", inet_ntoa(dst->sin_addr),
     470:            (int) htons(dst->sin_port));
     471:     printf("Leap %d, version %d, mode %d, poll %d, precision %d stratum %d",
     472:            (pkt->status & LEAPMASK) >> 6, (pkt->status & VERSIONMASK) >> 3,
     473:            pkt->status & MODEMASK, pkt->ppoll, pkt->precision,
     474:            pkt->stratum);
     475:     switch (pkt->stratum) {
     476:     case 0:
     477:     case 1:
     478:         printf(" (%.4s)\n", (char *)&pkt->refid);
     479:         break;
     480:     default:
     481:         clock_host.s_addr = (u_long) pkt->refid;
     482:         printf(" [%s]\n", inet_ntoa(clock_host));
     483:         break;
     484:     }
     485:     printf("Synch Dist is %04x.%04x  Synch Dispersion is %04x.%04x\n",
     486:            ntohs((u_short) pkt->distance.int_part),
     487:            ntohs((u_short) pkt->distance.fraction),
     488:            ntohs((u_short) pkt->dispersion.int_part),
     489:            ntohs((u_short) pkt->dispersion.fraction));
     490:     printf("Reference Timestamp is %08lx.%08lx\n",
     491:            ntohl(pkt->reftime.int_part),
     492:            ntohl(pkt->reftime.fraction));
     493:     printf("Originate Timestamp is %08lx.%08lx\n",
     494:            ntohl(pkt->org.int_part),
     495:            ntohl(pkt->org.fraction));
     496:     printf("Receive Timestamp is   %08lx.%08lx\n",
     497:            ntohl(pkt->rec.int_part),
     498:            ntohl(pkt->rec.fraction));
     499:     printf("Transmit Timestamp is  %08lx.%08lx\n",
     500:            ntohl(pkt->xmt.int_part),
     501:            ntohl(pkt->xmt.fraction));
     502:     if(peer != NULL)
     503:         printf("Input Timestamp is     %08lx.%08lx\n",
     504:                ntohl(peer->rec.int_part),
     505:                ntohl(peer->rec.fraction));
     506:     putchar('\n');
     507: }
     508: #endif
     509:
     510: void
     511: make_new_peer(peer)
     512:     struct ntp_peer *peer;
     513: {
     514:     int i;
     515:
     516:     /*
     517: 	 * initialize peer data fields
     518: 	 */
     519:     peer->src.sin_family = AF_INET;
     520:     peer->src.sin_port = 0;
     521:     peer->src.sin_addr.s_addr = 0;
     522:     peer->hmode = MODE_SYM_PAS; /* default: symmetric passive mode */
     523:     peer->flags = 0;
     524:     peer->timer = 1 << NTP_MINPOLL;
     525:     peer->stopwatch = 0;
     526:     peer->hpoll = NTP_MINPOLL;
     527:     double_to_s_fixed(&peer->dispersion, PEER_MAXDISP);
     528:     peer->reach = 0;
     529:     peer->estoffset = 0.0;
     530:     peer->estdelay = 0.0;
     531:     peer->org.int_part = peer->org.fraction = 0;
     532:     peer->rec.int_part = peer->rec.fraction = 0;
     533:     peer->filter.samples = 0;
     534:     for (i = 0; i < NTP_WINDOW; i++) {
     535:         peer->filter.offset[i] = 0.0;
     536:         peer->filter.delay[i] = 0.0;
     537:     }
     538:     peer->pkt_sent = 0;
     539:     peer->pkt_rcvd = 0;
     540:     peer->pkt_dropped = 0;
     541: }
     542:
     543: /*
     544:  *  This procedure is called to delete a peer from our list of peers.
     545:  */
     546: void
     547: demobilize(l, peer)
     548:     struct list *l;
     549:     struct ntp_peer *peer;
     550: {
     551:     extern struct ntp_peer dummy_peer;
     552:
     553:     if (peer == &dummy_peer)
     554: #ifdef  DEBUG
     555:         abort();
     556: #else
     557:         return;
     558: #endif
     559:
     560: #ifdef  DEBUG
     561:     if ((peer->next == NULL && peer->prev == NULL) ||
     562:         l->tail == NULL || l->head == NULL)
     563:         abort();
     564: #endif
     565:
     566:     /* delete only peer in list? */
     567:     if (l->head == l->tail) {
     568: #ifdef  DEBUG
     569:         if (l->head != peer) abort();
     570: #endif
     571:         l->head = l->tail = NULL;
     572:         goto dropit;
     573:     }
     574:
     575:     /* delete first peer? */
     576:     if (l->head == peer) {
     577:         l->head = peer->next;
     578:         l->head->prev = NULL;
     579:         goto dropit;
     580:     }
     581:
     582:     /* delete last peer? */
     583:     if (l->tail == peer) {
     584:         l->tail = peer->prev;
     585:         l->tail->next = NULL;
     586:         goto dropit;
     587:     }
     588:
     589:     /* drop peer in middle */
     590:     peer->prev->next = peer->next;
     591:     peer->next->prev = peer->prev;
     592:
     593:  dropit:
     594: #ifdef  DEBUG
     595:     /* just some sanity checking */
     596:     if ((l->members < 0) ||
     597:         (l->members && l->tail == NULL) ||
     598:         (l->members == 0 && l->tail != NULL)) {
     599:         syslog(LOG_ERR, "List hosed (demobilize)");
     600:         abort();
     601:     }
     602:     peer->next = peer->prev = NULL;
     603: #endif
     604:     free((char *) peer);
     605:     l->members--;
     606:
     607:     return;
     608: }
     609:
     610: enqueue(l, peer)
     611:     register struct list *l;
     612:     struct ntp_peer *peer;
     613: {
     614:     l->members++;
     615:     if (l->tail == NULL) {
     616:         /* insertion into empty list */
     617:         l->tail = l->head = peer;
     618:         peer->next = peer->prev = NULL;
     619:         return;
     620:     }
     621:
     622:     /* insert at end of list */
     623:     l->tail->next = peer;
     624:     peer->next = NULL;
     625:     peer->prev = l->tail;
     626:     l->tail = peer;
     627: }
     628:
     629: /* XXX */
     630: /*
     631:  *  Trivial signal handler.  Assumes you have Berkeley flavored signals which
     632:  *  re-enable themselves.
     633:  */
     634: void
     635: tock() {
     636:     ticked = 1;
     637: }
     638:
     639: void
     640: timeout()
     641: {
     642:     static int periodic = 0;
     643:     register struct ntp_peer *peer = peer_list.head, *next;
     644: #ifndef XADJTIME2
     645:     extern void adj_host_clock();
     646:
     647:     adj_host_clock();
     648: #endif
     649:     /*
     650: 	 * Count down sys.hold if necessary.
     651: 	 */
     652:     if (sys.hold) {
     653:         if (sys.hold <= (1<<CLOCK_ADJ))
     654:             sys.hold = 0;
     655:         else
     656:             sys.hold -= (1<<CLOCK_ADJ);
     657:     }
     658:     /*
     659: 	 * If interval has expired blast off an NTP to that host.
     660: 	 */
     661:     while (peer != NULL) {
     662: #ifdef  DEBUG
     663:         if (peer->next == NULL && peer != peer_list.tail) {
     664:             printf("Broken peer list\n");
     665:             syslog(LOG_ERR, "Broken peer list");
     666:             abort();
     667:         }
     668: #endif
     669:         next = peer->next;
     670:         if (peer->reach != 0 || peer->hmode != MODE_SERVER) {
     671:             peer->stopwatch +=(1<<CLOCK_ADJ);
     672:             if (peer->timer <= peer->stopwatch) {
     673:                 transmit(peer);
     674:                 peer->stopwatch = 0;
     675:             }
     676:         }
     677:         peer = next;
     678:     }
     679:
     680:     periodic += (1<<CLOCK_ADJ);
     681:     if (periodic >= 60*60) {
     682:         periodic = 0;
     683:         hourly();
     684:     }
     685:
     686:     clock_watchdog += (1 << CLOCK_ADJ);
     687:     if (clock_watchdog >= NTP_MAXAGE) {
     688:         /* woof, woof - barking dogs bite! */
     689:         sys.leap = ALARM;
     690:         if (clock_watchdog < NTP_MAXAGE + (1 << CLOCK_ADJ)) {
     691:             syslog(LOG_ERR,
     692:                    "logical clock adjust timeout (%d seconds)",
     693:                    NTP_MAXAGE);
     694: #ifdef  DEBUG
     695:             if (debug)
     696:              printf("logical clock adjust timeout (%d seconds)\n",
     697:                 NTP_MAXAGE);
     698: #endif
     699:         }
     700:     }
     701:
     702: #ifdef  DEBUG
     703:     if (debug)
     704:         (void) fflush(stdout);
     705: #endif
     706: }
     707:
     708:
     709: /*
     710:  * init_ntp() reads NTP daemon configuration information from disk file.
     711:  */
     712: void
     713: init_ntp(config)
     714:     char *config;
     715: {
     716:     struct sockaddr_in sin;
     717:     char ref_clock[5];
     718:     char name[81];
     719:     FILE *fp;
     720:     int error = FALSE, c;
     721:     struct ntp_peer *peer;
     722:     int precision;
     723:     int stratum;
     724:     int i;
     725:     int debuglevel;
     726:     int stagger = 0;
     727:     double j;
     728:     extern double drift_comp;
     729:
     730:     bzero((char *) &sin, sizeof(sin));
     731:     fp = fopen(config, "r");
     732:     if (fp == NULL) {
     733:         fprintf(stderr,"Problem opening NTP initialization file %s\n",
     734:             config);
     735:         syslog(LOG_ERR,"Problem opening NTP initialization file %s",
     736:             config);
     737:         exit(1);
     738:     }
     739:
     740:     while (fscanf(fp, "%s", name) != EOF) { /* read first word of line
     741: 						 * and compare to key words */
     742:         if (strcmp(name, "maxpeers") == 0) {
     743:             if (fscanf(fp, "%d", &sys.maxpeers) != 1)
     744:                 error = TRUE;
     745:         } else if (strcmp(name, "trusting") == 0) {
     746:             if (fscanf(fp, "%s", name) != 1)
     747:                 error = TRUE;
     748:             else {
     749:                 if (*name == 'Y' || *name == 'y') {
     750:                     trusting = 1;
     751:                 } else if (*name == 'N' || *name == 'n') {
     752:                     trusting = 0;
     753:                 } else
     754:                     trusting = atoi(name);
     755:             }
     756:         } else if (strcmp(name, "logclock") == 0) {
     757:             if (fscanf(fp, "%s", name) != 1)
     758:                 error = TRUE;
     759:             else {
     760:                 if (*name == 'Y' || *name == 'y') {
     761:                     logstats = 1;
     762:                 } else if (*name == 'N' || *name == 'n') {
     763:                     logstats = 0;
     764:                 } else
     765:                     logstats = atoi(name);
     766:             }
     767:         } else if (strcmp(name, "driftfile") == 0) {
     768:             if (fscanf(fp, "%s", name) != 1)
     769:                 error = TRUE;
     770:             else {
     771:                 if (driftcomp_file = malloc(strlen(name)+1))
     772:                     strcpy(driftcomp_file, name);
     773:             }
     774:         } else if (strcmp(name, "waytoobig") == 0 ||
     775:                strcmp(name, "setthreshold") == 0) {
     776:             if (fscanf(fp, "%s", name) != 1)
     777:                 error = TRUE;
     778:             else {
     779:                 if (strcmp(name, "any") == 0)
     780:                     WayTooBig = 10e15;
     781:                 else
     782:                     WayTooBig = atof(name);
     783:             }
     784:         } else if (strncmp(name, "debuglevel", 5) == 0) {
     785:             if (fscanf(fp, "%d", &debuglevel) != 1)
     786:                 error = TRUE;
     787: #ifdef  DEBUG
     788:             else debug += debuglevel;
     789: #endif
     790:         } else if (strcmp(name, "stratum") == 0) {
     791:             fprintf(stderr, "Obsolete command 'stratum'\n");
     792:             error = TRUE;
     793:         } else if (strcmp(name, "precision") == 0) {
     794:             if (fscanf(fp, "%d", &precision) != 1)
     795:                 error = TRUE;
     796:             else sys.precision = (char) precision;
     797: #ifdef  NOSWAP
     798:         } else if (strcmp(name, "noswap") == 0) {
     799:             noswap = 1;
     800: #endif
     801: #ifdef  BROADCAST_NTP
     802:         } else if (strcmp(name, "broadcast") == 0) {
     803:             if (fscanf(fp, "%s", name) != 1) {
     804:                 error = TRUE;
     805:                 goto skipit;
     806:             }
     807:             for (i = 0; i < nintf; i++)
     808:                 if (strcmp(addrs[i].name, name) == 0)
     809:                     break;
     810:             if (i == nintf) {
     811:                 syslog(LOG_ERR, "config file: %s not a known interface");
     812:                 error = TRUE;
     813:                 goto skipit;
     814:             }
     815:             if ((addrs[i].if_flags & IFF_BROADCAST) == 0) {
     816:                 syslog(LOG_ERR, "config file: %s doesn't support broadcast", name);
     817:                 error = TRUE;
     818:                 goto skipit;
     819:             }
     820:             if (peer = check_peer(&addrs[i].bcast, -1)) {
     821:                 syslog(LOG_ERR, "config file: duplicate broadcast for %s",
     822:                        name);
     823:                 error = TRUE;
     824:                 goto skipit;
     825:             }
     826:             peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer));
     827:             if (peer == NULL) {
     828:                 error = TRUE;
     829:                 syslog(LOG_ERR, "No memory");
     830:                 goto skipit;
     831:             }
     832:             make_new_peer(peer);
     833:             peer->flags = PEER_FL_BCAST;
     834:             peer->hmode = MODE_BROADCAST;
     835:             peer->src = addrs[i].bcast;
     836:             peer->sock = i;
     837: #endif	/* BROADCAST_NTP */
     838:         } else if ((strcmp(name, "peer") == 0) ||
     839:                (strcmp(name, "passive") == 0) ||
     840:                (strcmp(name, "server") == 0)) {
     841:             int mode = 0;
     842:
     843:             if (strcmp(name, "peer") == 0) {
     844:                 mode = MODE_SYM_ACT;
     845:             } else if (strcmp(name, "server") == 0) {
     846:                 mode = MODE_CLIENT;
     847:             } else if (strcmp(name, "passive") == 0) {
     848:                 mode = MODE_SYM_PAS;
     849:             } else {
     850:                 printf("can't happen\n");
     851:                 abort();
     852:             }
     853:             if (fscanf(fp, "%s", name) != 1)
     854:                 error = TRUE;
     855: #ifdef REFCLOCK
     856:             else if (name[0] == '/') {
     857:                 int stratum, precision;
     858:                 char clk_type[20];
     859:
     860:                 if (fscanf(fp, "%4s", ref_clock) != 1) {
     861:                     error = TRUE;
     862:                     syslog(LOG_ERR, "reference id missing");
     863:                     goto skipit;
     864:                 }
     865:                 if (fscanf(fp, "%4d", &stratum) != 1) {
     866:                     error = TRUE;
     867:                     syslog(LOG_ERR, "reference stratum missing");
     868:                     goto skipit;
     869:                 }
     870:                 if (fscanf(fp, "%4d", &precision) != 1) {
     871:                     error = TRUE;
     872:                     syslog(LOG_ERR, "reference precision missing");
     873:                     goto skipit;
     874:                 }
     875:                 if (fscanf(fp, "%19s", clk_type) != 1) {
     876:                     error = TRUE;
     877:                     syslog(LOG_ERR, "reference type missing");
     878:                     goto skipit;
     879:                 }
     880:
     881:                 if((i = init_clock(name, clk_type)) < 0) {
     882:                     /* If we could not initialize clock line */
     883: #ifdef DEBUG
     884:                     if (debug)
     885:                         printf("Could not init reference source %s (type %s)\n",
     886:                             name, clk_type);
     887:                     else
     888: #endif DEBUG
     889:                         syslog(LOG_ERR, "Could not init reference source %s (type %s)",
     890:                             name, clk_type);
     891:                     error = TRUE;
     892:                     goto skipit;
     893:                 }
     894:                 peer = (struct ntp_peer *)
     895:                     malloc(sizeof(struct ntp_peer));
     896:                 if (peer == NULL) {
     897:                     close(i);
     898:                     error = TRUE;
     899:                     goto skipit;
     900:                 }
     901:                 make_new_peer(peer);
     902:                 ref_clock[4] = 0;
     903:                 (void) strncpy((char *) &peer->refid,
     904:                         ref_clock, 4);
     905:                 peer->flags = PEER_FL_CONFIG|PEER_FL_REFCLOCK;
     906:                 peer->hmode = MODE_SYM_ACT;
     907:                 peer->stopwatch = stagger;
     908:                 stagger += (1<<CLOCK_ADJ);
     909:                 peer->flags |= PEER_FL_SYNC;
     910:                 peer->sock = i;
     911:                 peer->stratum = stratum;
     912:                 peer->precision = precision;
     913:                 clear(peer);
     914:                 enqueue(&peer_list, peer);
     915:                 if (debug > 1)
     916:                     printf("Peer %s mode %d refid %.4s stratum %d precision %d\n",
     917:                            name,
     918:                            peer->hmode,
     919:                            (char *)&peer->refid,
     920:                            stratum, precision);
     921:                 transmit(peer); /* head start for REFCLOCK */
     922:             }
     923: #endif REFCLOCK
     924:             else if (GetHostName(name, &sin) == 0)
     925:                 syslog(LOG_ERR, "%s: unknown host", name);
     926:             else {
     927:                 for (i=0; i<nintf; i++)
     928:                     if (addrs[i].sin.sin_addr.s_addr ==
     929:                         sin.sin_addr.s_addr)
     930:                         goto skipit;
     931:
     932:                 if (servp)
     933:                     sin.sin_port = servp->s_port;
     934:                 else
     935:                     sin.sin_port = htons(NTP_PORT);
     936:
     937:                 peer = check_peer(&sin, -1);
     938:                 if (peer == NULL) {
     939:                     peer = (struct ntp_peer *)
     940:                         malloc(sizeof(struct ntp_peer));
     941:                     if (peer == NULL)
     942:                         error = TRUE;
     943:                     else {
     944:                         make_new_peer(peer);
     945:                         peer->flags = PEER_FL_CONFIG;
     946:                         switch (mode) {
     947:                         case MODE_SYM_ACT:  /* "peer" */
     948:                             peer->hmode = MODE_SYM_ACT;
     949:                             peer->stopwatch = stagger;
     950:                             stagger += (1<<CLOCK_ADJ);
     951:                             peer->flags |= PEER_FL_SYNC;
     952:                             break;
     953:                         case MODE_CLIENT:   /* "server" */
     954:                             peer->hmode = MODE_CLIENT;
     955:                             peer->stopwatch = stagger;
     956:                             stagger += (1<<CLOCK_ADJ);
     957:                             peer->flags |= PEER_FL_SYNC;
     958:                             break;
     959:                         case MODE_SYM_PAS:  /* "passive" */
     960:                             peer->hmode = MODE_SYM_PAS;
     961:                             peer->flags |= PEER_FL_SYNC;
     962:                             break;
     963:                         default:
     964:                             printf("can't happen\n");
     965:                             abort();
     966:                         }
     967:                         peer->src = sin;
     968:                         peer->sock = -1;
     969:                         clear(peer);
     970:                         enqueue(&peer_list, peer);
     971: #ifdef  DEBUG
     972:                         if (debug > 1)
     973:                             printf("Peer %s/%d af %d mode %d\n",
     974:                                    inet_ntoa(peer->src.sin_addr),
     975:                                    ntohs(peer->src.sin_port),
     976:                                    peer->src.sin_family,
     977:                                    peer->hmode);
     978: #endif
     979:                     }
     980:                 } else {
     981:                     syslog(LOG_WARNING,
     982:                      "Duplicate peer %s in in config file",
     983:                            inet_ntoa(sin));
     984: #ifdef  DEBUG
     985:                     if(debug)
     986:                         printf("Duplicate peer %s in in config file\n",
     987:                                inet_ntoa(sin));
     988: #endif
     989:                 }
     990:             }
     991:             skipit:;
     992:         } else if( *name != '#' ) {
     993:             syslog(LOG_ERR, "config file: %s not recognized", name);
     994: #ifdef DEBUG
     995:             if(debug)
     996:                 printf("unrecognized option in config file: %s\n", name);
     997: #endif
     998:         }
     999:         do
    1000:             c = fgetc(fp);
    1001:         while (c != '\n' && c != EOF);  /* next line */
    1002:     }           /* end while */
    1003:     if (error) {
    1004:         fprintf(stderr, "init_ntp: %s: initialization error\n", config);
    1005:         syslog(LOG_ERR, "init_ntp: %s: initialization error", config);
    1006:
    1007:         exit(1);
    1008:     }
    1009:     /*
    1010: 	 *  Read saved drift compensation register value.
    1011: 	 */
    1012:     if ((fp = fopen(driftcomp_file, "r")) != NULL) {
    1013:         if (fscanf(fp, "%lf", &j) == 1 && j > -1.0 && j < 1.0) {
    1014:             drift_comp = j;
    1015:             syslog(LOG_INFO,
    1016:                    "Drift compensation value initialized to %f", j);
    1017:         } else {
    1018:             fprintf(stderr,
    1019:                 "init_ntp: bad drift compensation value\n");
    1020:             syslog(LOG_ERR,
    1021:                    "init_ntp: bad drift compensation value\n");
    1022:         }
    1023:         fclose(fp);
    1024:     }
    1025: }
    1026:
    1027: int kern_hz;
    1028:
    1029: #include <sys/sysctl.h>
    1030:
    1031: void
    1032: init_kern_vars() {
    1033:     int size, mib[2];
    1034:     struct clockinfo cinfo;
    1035:
    1036:     mib[0] = CTL_KERN;
    1037:     mib[1] = KERN_CLOCKRATE;
    1038:     size = sizeof (struct clockinfo);
    1039:     if  (sysctl(mib, 2, &cinfo, &size, NULL, 0) < 0)
    1040:         {
    1041:         syslog(LOG_ERR, "sysctl() for kern.clockrate: %m\n");
    1042:         return;
    1043:         }
    1044:     kern_hz = cinfo.hz;
    1045:
    1046:     /*
    1047: 	 *  If we have successfully discovered `hz' from the kernel, then we
    1048: 	 *  can set sys.precision, if it has not already been specified.  If
    1049: 	 *  no value of `hz' is available, then use default (-6)
    1050: 	 */
    1051:     if (sys.precision == 0) {
    1052:         if (kern_hz <= 64)
    1053:             sys.precision = -6;
    1054:         else if (kern_hz <= 128)
    1055:             sys.precision = -7;
    1056:         else if (kern_hz <= 256)
    1057:             sys.precision = -8;
    1058:         else if (kern_hz <= 512)
    1059:             sys.precision = -9;
    1060:         else if (kern_hz <= 1024)
    1061:             sys.precision = -10;
    1062:         else sys.precision = -11;
    1063:         syslog(LOG_INFO, "sys.precision set to %d from sys clock of %d HZ",
    1064:                sys.precision, kern_hz);
    1065:     }
    1066: }
    1067:
    1068:
    1069: /*
    1070:  * Given host or net name or internet address in dot notation assign the
    1071:  * internet address in byte format. source is ../routed/startup.c with minor
    1072:  * changes to detect syntax errors.
    1073:  *
    1074:  * We now try to interpret the name as in address before we go off and bother
    1075:  * the domain name servers.
    1076:  *
    1077:  * Unfortunately the library routine inet_addr() does not detect mal formed
    1078:  * addresses that have characters or byte values > 255.
    1079:  */
    1080:
    1081: GetHostName(name, sin)
    1082:     char *name;
    1083:     struct sockaddr_in *sin;
    1084: {
    1085:     long HostAddr;
    1086:     struct hostent *hp;
    1087:
    1088:     if ((HostAddr = inet_addr(name)) != -1) {
    1089:         sin->sin_addr.s_addr = (u_long) HostAddr;
    1090:         sin->sin_family = AF_INET;
    1091:         return (1);
    1092:     }
    1093:
    1094:     if (hp = gethostbyname(name)) {
    1095:         if (hp->h_addrtype != AF_INET)
    1096:             return (0);
    1097:         bcopy((char *) hp->h_addr, (char *) &sin->sin_addr,
    1098:               hp->h_length);
    1099:         sin->sin_family = hp->h_addrtype;
    1100:         return (1);
    1101:     }
    1102:     return (0);
    1103: }
    1104:
    1105: #define PKTBUF_SIZE 536
    1106:
    1107: /* number of clocks per packet */
    1108: #define N_NTP_PKTS \
    1109:       ((PKTBUF_SIZE - sizeof(struct ntpinfo))/(sizeof(struct xclockinfo)))
    1110:
    1111: query_mode(dst, ntp, sock)
    1112:     struct sockaddr_in *dst;
    1113:     struct ntpdata *ntp;
    1114:     int sock;       /* which socket packet arrived on */
    1115: {
    1116:     char packet[PKTBUF_SIZE];
    1117:     register struct ntpinfo *nip = (struct ntpinfo *) packet;
    1118:     register struct ntp_peer *peer = peer_list.head;
    1119:     struct xclockinfo *cip;
    1120:     int seq = 0;
    1121:     int i;
    1122:
    1123:     if (ntp->stratum != INFO_QUERY)
    1124:         return;
    1125:     nip->version = NTPDC_VERSION;
    1126:     nip->type = INFO_REPLY;
    1127:     nip->seq = 0;
    1128:     nip->npkts = peer_list.members/N_NTP_PKTS;
    1129:     if (peer_list.members % N_NTP_PKTS)
    1130:         nip->npkts++;
    1131:     nip->peers = peer_list.members;
    1132:     nip->count = 0;
    1133:     cip = (struct xclockinfo *)&nip[1];
    1134:
    1135:     while (peer != NULL) {
    1136:         cip->net_address = peer->src.sin_addr.s_addr;
    1137:         if (peer->sock < 0)
    1138:             cip->my_address = htonl(0);
    1139:         else
    1140:             cip->my_address = addrs[peer->sock].sin.sin_addr.s_addr;
    1141:         cip->port = peer->src.sin_port; /* already in network order */
    1142:         cip->flags = htons(peer->flags);
    1143:         if (sys.peer == peer)
    1144:             cip->flags |= htons(PEER_FL_SELECTED);
    1145:         cip->pkt_sent = htonl(peer->pkt_sent);
    1146:         cip->pkt_rcvd = htonl(peer->pkt_rcvd);
    1147:         cip->pkt_dropped = htonl(peer->pkt_dropped);
    1148:         cip->timer = htonl(peer->timer);
    1149:         cip->leap = peer->leap;
    1150:         cip->stratum = peer->stratum;
    1151:         cip->ppoll = peer->ppoll;
    1152:         cip->precision = (int) peer->precision;
    1153:         cip->hpoll = peer->hpoll;
    1154:         cip->reach = htons((u_short)peer->reach & NTP_WINDOW_SHIFT_MASK);
    1155:         cip->estdisp = htonl((long) (peer->estdisp * 1000.0));
    1156:         cip->estdelay = htonl((long) (peer->estdelay * 1000.0));
    1157:         cip->estoffset = htonl((long) (peer->estoffset * 1000.0));
    1158:         cip->refid = peer->refid;
    1159:         cip->reftime.int_part = htonl(peer->reftime.int_part);
    1160:         cip->reftime.fraction = htonl(peer->reftime.fraction);
    1161:
    1162:         cip->info_filter.index = htons(peer->filter.samples);
    1163:         for (i = 0; i < PEER_SHIFT; i++) {
    1164:             cip->info_filter.offset[i] =
    1165:                 htonl((long)(peer->filter.offset[i] * 1000.0));
    1166:             cip->info_filter.delay[i] =
    1167:                 htonl((long)(peer->filter.delay[i] * 1000.0));
    1168:         }
    1169:         cip++;
    1170:         if (nip->count++ >= N_NTP_PKTS - 1) {
    1171:             nip->seq =seq++;
    1172:             if ((sendto(addrs[sock].fd, (char *) packet,
    1173:                     sizeof(packet), 0,
    1174:                     (struct sockaddr *) dst,
    1175:                     sizeof(struct sockaddr_in))) < 0) {
    1176:                 syslog(LOG_ERR, "sendto: %s  %m",
    1177:                        inet_ntoa(dst->sin_addr));
    1178:             }
    1179:             nip->type = INFO_REPLY;
    1180:             nip->count = 0;
    1181:             cip = (struct xclockinfo *)&nip[1];
    1182:         }
    1183:         peer = peer->next;
    1184:     }
    1185:     if (nip->count) {
    1186:         nip->seq = seq;
    1187:         if ((sendto(addrs[sock].fd, (char *) packet, sizeof(packet), 0,
    1188:                 dst, sizeof(struct sockaddr_in))) < 0) {
    1189:             syslog(LOG_ERR, "sendto: %s  %m", ntoa(dst->sin_addr));
    1190:         }
    1191:     }
    1192: }
    1193:
    1194: /* every hour, dump some useful information to the log */
    1195: void
    1196: hourly() {
    1197:     char buf[200];
    1198:     register int p = 0;
    1199:     static double drifts[5] = { 0.0, 0.0, 0.0, 0.0, 0.0 };
    1200:     static int drift_count = 0;
    1201:     extern double drift_comp, compliance;
    1202:     extern int peer_switches, peer_sw_inhibited;
    1203:
    1204:     (void) sprintf(buf, "stats: dc %f comp %f peersw %d inh %d",
    1205:                drift_comp, compliance, peer_switches,
    1206:                peer_sw_inhibited);
    1207:
    1208:     if (sys.peer == NULL) {
    1209:         strcat(buf, " UNSYNC");
    1210: #ifdef  REFCLOCK
    1211:     } else if (sys.peer->flags & PEER_FL_REFCLOCK) {
    1212:         p = strlen(buf);
    1213:         (void) sprintf(buf + p, " off %f SYNC %.4s %d",
    1214:                    sys.peer->estoffset,
    1215:                    (char *)&sys.peer->refid,
    1216:                    sys.peer->stratum);
    1217: #endif
    1218:     } else {
    1219:         p = strlen(buf);
    1220:         (void) sprintf(buf + p, " off %f SYNC %s %d",
    1221:                    sys.peer->estoffset,
    1222:                    ntoa(sys.peer->src.sin_addr),
    1223:                    sys.peer->stratum);
    1224:     }
    1225:     syslog(LOG_INFO, buf);
    1226: #ifdef  DEBUG
    1227:     if (debug)
    1228:         puts(buf);
    1229: #endif
    1230:     /*
    1231: 	 *  If the drift compensation snapshot file is open, then write
    1232: 	 *  the current value to it.  Since there's only one block in the
    1233: 	 *  file, and no one else is reading it, we'll just keep the file
    1234: 	 *  open and write to it.
    1235: 	 */
    1236:     if (drift_fd >= 0) {
    1237:         drifts[drift_count % 5] = drift_comp;
    1238:         /* works out to be 70 bytes */
    1239:         (void) sprintf(buf,
    1240:              "%12.10f %12.10f %12.10f %12.10f %12.10f %4d\n",
    1241:                    drifts[drift_count % 5],
    1242:                    drifts[(drift_count+4) % 5],
    1243:                    drifts[(drift_count+3) % 5],
    1244:                    drifts[(drift_count+2) % 5],
    1245:                    drifts[(drift_count+1) % 5],
    1246:                    drift_count + 1);
    1247:
    1248:         (void) lseek(drift_fd, 0L, L_SET);
    1249:         if (write(drift_fd, buf, strlen(buf)) < 0) {
    1250:             syslog(LOG_ERR, "Error writing drift comp file: %m");
    1251:         }
    1252:         drift_count++;
    1253:     }
    1254: }
    1255:
    1256: #if defined(DEBUG) && defined(SIGUSR1) && defined(SIGUSR2)
    1257: void
    1258: incdebug()
    1259: {
    1260:     if (debug == 255)
    1261:         return;
    1262:     debug++;
    1263:     printf("DEBUG LEVEL %d\n", debug);
    1264: #ifdef  LOG_DAEMON
    1265:     (void) setlogmask(LOG_UPTO(LOG_DEBUG));
    1266: #endif
    1267:     syslog(LOG_DEBUG, "DEBUG LEVEL %d", debug);
    1268: }
    1269:
    1270: void
    1271: decdebug()
    1272: {
    1273:     if (debug == 0)
    1274:         return;
    1275:     debug--;
    1276:     printf("DEBUG LEVEL %d\n", debug);
    1277:     syslog(LOG_DEBUG, "DEBUG LEVEL %d", debug);
    1278: #ifdef  LOG_DAEMON
    1279:     if (debug == 0)
    1280:         (void) setlogmask(LOG_UPTO(LOG_INFO));
    1281: #endif
    1282: }
    1283: #endif
    1284:
    1285: void
    1286: finish(sig)
    1287:     int sig;
    1288: {
    1289:     syslog(LOG_NOTICE, "terminated: (sig %d)", sig);
    1290: #ifdef  DEBUG
    1291:     if (debug)
    1292:         printf("ntpd terminated (sig %d)\n", sig);
    1293: #endif
    1294:     exit(1);
    1295: }
    1296:
    1297: #ifdef  REFCLOCK
    1298: struct refclock {
    1299:     int fd;
    1300:     int (*reader)();
    1301:     struct refclock *next;
    1302: } *refclocks = NULL;
    1303:
    1304: int init_clock_local(), read_clock_local();
    1305: #ifdef PSTI
    1306: int init_clock_psti(), read_clock_psti();
    1307: #endif PSTI
    1308:
    1309: init_clock(name, type)
    1310: char *name, *type;
    1311: {
    1312:     struct refclock *r;
    1313:     int (*reader)();
    1314:     int cfd;
    1315:
    1316:     if (strcmp(type, "local") == 0) {
    1317:         reader = read_clock_local;
    1318:         cfd = init_clock_local(name);
    1319:     }
    1320: #ifdef PSTI
    1321:     else if (strcmp(type, "psti") == 0) {
    1322:         reader = read_clock_psti;
    1323:         cfd = init_clock_psti(name);
    1324:     }
    1325: #endif PSTI
    1326:     else {
    1327:         if (debug) printf("Unknown reference type\n"); else
    1328:         syslog(LOG_ERR, "Unknown reference clock type (%s)\n", type);
    1329:         return(-1);
    1330:     }
    1331:     if (cfd >= 0) {
    1332:         r = (struct refclock *)malloc(sizeof(struct refclock));
    1333:         r->fd = cfd;
    1334:         r->reader = reader;
    1335:         r->next = refclocks;
    1336:         refclocks = r;
    1337:     }
    1338:     return(cfd);
    1339: }
    1340:
    1341: read_clock(cfd, tvpp, otvpp)
    1342: int cfd;
    1343: struct timeval **tvpp, **otvpp;
    1344: {
    1345:     struct refclock *r;
    1346:
    1347:     for (r = refclocks; r; r = r->next)
    1348:         if(r->fd == cfd)
    1349:             return((r->reader)(cfd, tvpp, otvpp));
    1350:     return(1); /* Can't happen */
    1351: }
    1352: #endif

#### Defined functions

GetHostName defined in line 1081; used 1 times

- in line 924

check_peer defined in line 444; used 4 times

- in line 820, 937
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 152, 427

decdebug defined in line 1270; used 2 times

- in line 185, 360

demobilize defined in line 546; used 3 times

- in /usr/src/usr.sbin/ntp/ntp_proto.c line 157, 280, 515

dump_pkt defined in line 462; used 4 times

- in line 429
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 147, 269, 346

enqueue defined in line 610; used 3 times

- in line 914, 970
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 453

finish defined in line 1285; used 3 times

- in line 164, 355-356(2)

hourly defined in line 1195; used 2 times

- in line 165, 683

incdebug defined in line 1257; used 2 times

- in line 185, 359

init_clock defined in line 1309; used 1 times

- in line 881

init_kern_vars defined in line 1031; used 2 times

- in line 165, 324

init_ntp defined in line 712; used 2 times

- in line 164, 323

main defined in line 171; never used
make_new_peer defined in line 510; used 7 times

- in line 164, 832, 901, 944
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 157, 415, 435

query_mode defined in line 1111; used 1 times

- in line 423

read_clock defined in line 1341; used 1 times

- in /usr/src/usr.sbin/ntp/ntp_proto.c line 328

timeout defined in line 639; used 2 times

- in line 164, 439

tock defined in line 634; used 2 times

- in line 164, 357

#### Defined variables

WayTooBig defined in line 155; used 7 times

- in line 195-197(2), 780-782(2)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 708-709(2), 716

clock_watchdog defined in line 156; used 4 times

- in line 686-690(3)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 721

conf defined in line 137; used 2 times

- in line 241, 323

debug defined in line 142; used 31 times

- in line 202, 211, 251, 283, 294, 305, 341, 375, 405, 414, 427, 695, 703, 788, 884, 915, 972, 985, 995, 1227, 1260-1267(4), 1273-1279(5), 1291, 1327

doset defined in line 149; used 3 times

- in line 219
- in /usr/src/usr.sbin/ntp/ntp_adjust.c line 146, 240

drift_fd defined in line 139; used 4 times

- in line 332, 1236, 1248-1249(2)

driftcomp_file defined in line 138; used 4 times

- in line 331, 771-772(2), 1012

dst_sock defined in line 127; used 1 times

- in line 175

it defined in line 132; used 1 times

- in line 133

itp defined in line 133; used 5 times

- in line 362-365(4), 381

kern_hz defined in line 1027; used 7 times

- in line 1044, 1052-1064(6)

logstats defined in line 153; used 5 times

- in line 237, 761-765(3)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 747

noswap defined in line 146; used 3 times

- in line 229, 301, 799

ntpframe defined in line 158; used 2 times

- in line 176, 399

peer_list defined in line 130; used 17 times

- in line 320-321(3), 449, 643, 663, 914, 970, 1118, 1128-1131(3)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 280, 453, 515, 723, 949

prog_name defined in line 135; used 7 times

- in line 190, 205, 214, 224, 232, 290, 296

rcsid defined in line 2; never used
refclocks defined in line 1302; used 3 times

- in line 1335-1336(2), 1347

selfds defined in line 151; used 8 times

- in line 371-379(7), 388

servp defined in line 129; used 6 times

- in line 311-317(3), 932-933(2)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 403

sys defined in line 159; used 81 times

- in line 652-656(4), 689, 743, 796, 1051-1064(8), 1143, 1208-1223(8)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 179-186(7), 306-307(2), 506, 520, 604, 663-669(4), 675-678(3), 684-698(7), 741, 765-778(14), 804-805(2), 820, 984-990(3), 997, 1102, 1166-1169(3), 1193-1198(4), 1210

ticked defined in line 150; used 3 times

- in line 437-438(2), 636

trusting defined in line 152; used 4 times

- in line 750-754(3)
- in /usr/src/usr.sbin/ntp/ntp_proto.c line 450

tv defined in line 134; used 4 times

- in line 334-335(2), 390, 435

#### Defined struct's

refclock defined in line 1298; used 10 times

- in line 1301(2), 1312(2), 1332(4), 1345(2)

#### Defined macros

FALSE defined in line 125; used 1 times

- in line 720

LOG_NTP defined in line 279; used 2 times

- in line 278-281(2)

N_NTP_PKTS defined in line 1108; used 3 times

- in line 1128-1129(2), 1170

PKTBUF_SIZE defined in line 1105; used 2 times

- in line 1109, 1116

TRUE defined in line 124; used 21 times

- in line 744-747(2), 758, 769, 777, 786, 792-795(2), 804, 812-817(2), 823-828(2), 854, 861-876(4), 891, 898, 942

Last modified: 1995-07-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 4415 |