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

##### Functions

    clear             X
    clock_filter      X
    clock_update      X
    decrypt           X
    encrypt           X
    initialize        X
    poll_update       X
    process_packet    X
    receive           X
    refclock_input    X
    sanity_check      X
    select_clock      X
    transmit          X

##### Variables

    dummy_peer        X
    peer_sw_inhibited X
    peer_switches     X

##### Macros

    ACT_ERROR         X
    ACT_PKT           X
    ACT_RECV          X
    ACT_XMIT          X

##### struct's

    sel_lst           X

       1: #if defined(DOSCCS) && !defined(lint)
       2: static char *rcsid = "$Source: /usr/users/louie/ntp/RCS/ntp_proto.c,v $ $Revision: 3.4.1.13 $ $Date: 95/07/01 18:25:04 $";
       3: #endif
       4:
       5: /*
       6:  * This module actually implements the the bulk of the NTP protocol processing.
       7:  * It contains a minimum of machine and operating system dependencies (or at
       8:  * least that's the idea).  Setup of UDP sockets, timers, etc is done in the
       9:  * ntpd.c module, while arithmetic conversion routines are in ntpsubs.c
      10:  */
      11:
      12: /*
      13:  * $Log:	ntp_proto.c,v $
      14:  * Revision 3.4.1.13 95/07/01
      15:  * Fix shifting 1 to 0 with "1<<sys.prec" - need "(u_long)(1L<<sys.prec)"
      16:  *
      17:  * Revision 3.4.1.12  89/05/18  18:25:04  louie
      18:  * Changes for reference clock feature in ntp_proto.c
      19:  *
      20:  * Revision 3.4.1.11  89/05/03  23:51:30  louie
      21:  * Had my head on backwards with a reversed test in the clockhopper avoidance
      22:  * code.  Need to switch to the first selected clock when its stratum is lower
      23:  * than the current sys.peer.
      24:  *
      25:  * Revision 3.4.1.10  89/05/03  19:03:02  louie
      26:  * Stupid typo - dereferenced unused variable in select_clock()
      27:  *
      28:  * Revision 3.4.1.9  89/05/03  15:13:25  louie
      29:  * Add code to count number of peer switches and inhibited peer switches.  Clock
      30:  * selection code has been updated to reflect 21 April 1989 draft of NTP spec.
      31:  *
      32:  * Revision 3.4.1.8  89/04/10  15:57:59  louie
      33:  * New -l option for ntpd to enable logging for clock adjust messages.  Changed
      34:  * our idea of a bogus packet in the packet procedure to include a packet received
      35:  * before a poll is sent.  Fix stupid bug in delay computation having to do with
      36:  * peer->precision.
      37:  *
      38:  * Revision 3.4.1.7  89/04/08  10:36:53  louie
      39:  * The syslog message for peer selection had to be moved to account for the
      40:  * anti-peer flapping code just installed.
      41:  *
      42:  * Revision 3.4.1.6  89/04/07  19:07:10  louie
      43:  * Don't clear peer.reach register in the clear() procedure.  Code to prevent
      44:  * flapping between two peers with very similar dispersions.
      45:  *
      46:  * Revision 3.4.1.5  89/03/31  16:36:38  louie
      47:  * There is now a run-time option that can be specified in the configuration
      48:  * which specifies if we will synchronize to unconfigured hosts.  Fixes to
      49:  * receive() logic state machine.
      50:  *
      51:  * Revision 3.4.1.4  89/03/29  12:29:10  louie
      52:  * The variable 'mode' in the peer structure was renamed 'hmode'.  Add
      53:  * poll_update() calls in a few places per Mills.  The receive() procedure is
      54:  * now table driven.  The poll_update procedure only randomized the timer
      55:  * when the interval changes.  If we lose synchronization, don't zap sys.stratum.
      56:  * Clean up the sanity_check() routine a bit.
      57:  *
      58:  * Revision 3.4.1.3  89/03/22  18:32:31  louie
      59:  * patch3: Use new RCS headers.
      60:  *
      61:  * Revision 3.4.1.2  89/03/22  18:02:22  louie
      62:  * Add some fiddles for BROADCAST NTP mode.  In the receive procedure, set the
      63:  * reachability shift register of peers that are configured, even if we won't
      64:  * synchronized to them.  Fix adjustment of delay in the process_packet()
      65:  * routine.  Repair byteswapping problem.
      66:  *
      67:  *
      68:  * Revision 3.4.1.1  89/03/20  00:10:06  louie
      69:  * patch1: sys.refid could have garbage left if the peer we're synchronized to
      70:  * patch1: is lost.
      71:  *
      72:  * Revision 3.4  89/03/17  18:37:05  louie
      73:  * Latest test release.
      74:  *
      75:  * Revision 3.3.1.1  89/03/17  18:26:02  louie
      76:  * Oh my, peer->hpoll wasn't being set in peer_update!
      77:  *
      78:  * Revision 3.3  89/03/15  14:19:49  louie
      79:  * New baseline for next release.
      80:  *
      81:  * Revision 3.2.1.2  89/03/15  13:54:41  louie
      82:  * Change use of "%lf" in format strings to use "%f" instead.
      83:  * poll_update no longer returns a value, due to a change in the transmit
      84:  * procedure; it is now declared as returning void.  Removed syslog
      85:  * message "Dropping peer ...".  You still get messages for peers which
      86:  * were configured when reachability is lost with them.  Clarification of
      87:  * calling poll_update on sys.peer rather than on the host whose packet
      88:  * we're processing when sys.peer changes.  poll_update has been updated
      89:  * including randomizing peer.timer.
      90:  *
      91:  * Revision 3.2.1.1  89/03/10  11:30:33  louie
      92:  * Remove computation of peer->timer that was present due to a bug in the NTP
      93:  * spec.  Don't set sys.precision in the NTP protocol initialization; this has
      94:  * bad side effects with the code that get tick from the kernel and the NTP
      95:  * config file scanner.
      96:  *
      97:  * Revision 3.2  89/03/07  18:24:54  louie
      98:  * New version of UNIX NTP daemon based on the 6 March 1989 draft of the new
      99:  * NTP protocol specification.  This version has a bunch of bugs fixes and
     100:  * new algorithms which were discussed on the NTP mailing list over the past
     101:  * few weeks.
     102:  *
     103:  * Revision 3.1.1.1  89/02/15  08:57:34  louie
     104:  * *** empty log message ***
     105:  *
     106:  *
     107:  * Revision 3.1  89/01/30  14:43:10  louie
     108:  * Second UNIX NTP test release.
     109:  *
     110:  * Revision 3.0  88/12/12  15:59:35  louie
     111:  * Test release of new UNIX NTP software.  This version should conform to the
     112:  * revised NTP protocol specification.
     113:  *
     114:  */
     115:
     116: #include <stdio.h>
     117: #include <sys/types.h>
     118: #include <sys/param.h>
     119: #include <sys/uio.h>
     120: #include <sys/socket.h>
     121: #include <sys/time.h>
     122: #include <sys/ioctl.h>
     123: #include <sys/resource.h>
     124:
     125: #include <net/if.h>
     126:
     127: #include <netinet/in.h>
     128: #include <netinet/in_systm.h>
     129: #include <netinet/ip.h>
     130: #include <netinet/udp.h>
     131:
     132: #include <arpa/inet.h>
     133: #include <netdb.h>
     134: #include <strings.h>
     135: #include <errno.h>
     136: #include <syslog.h>
     137:
     138: #include "ntp.h"
     139:
     140: int peer_switches, peer_sw_inhibited;
     141:
     142: struct ntp_peer dummy_peer;
     143: extern double WayTooBig;
     144: extern u_long clock_watchdog;
     145: #ifdef  DEBUG
     146: extern int debug;
     147: extern void dump_pkt();
     148: #endif
     149: extern int trusting, logstats;
     150: extern struct sysdata sys;
     151: extern struct list peer_list;
     152: extern struct ntp_peer *check_peer();
     153: extern struct servent *servp;
     154: extern char *malloc(), *ntoa();
     155: extern double drift_comp, compliance;   /* logical clock variables */
     156: extern double s_fixed_to_double(), ul_fixed_to_double();
     157: extern void make_new_peer(), double_to_s_fixed(), tstamp(), demobilize();
     158:
     159:
     160: #ifdef  REFCLOCK
     161: void    refclock_input();
     162: #endif
     163:
     164: void    process_packet(), clock_update(), clear(), clock_filter(),
     165:     receive(), select_clock(), poll_update();
     166:
     167: /* 3.4. Event Processing */
     168:
     169: /* 3.4.1. Transmit Procedure */
     170: void
     171: transmit(peer)
     172:     struct ntp_peer *peer;
     173: {
     174:     struct timeval txtv;
     175:     static struct ntpdata ntpframe;
     176:     struct ntpdata *pkt = &ntpframe;
     177:     int i;
     178:
     179:     pkt->status = sys.leap | NTPVERSION_1 | peer->hmode;
     180:     pkt->stratum = sys.stratum;
     181:     pkt->ppoll = peer->hpoll;
     182:     pkt->precision = (char) sys.precision;
     183:     pkt->distance = sys.distance;
     184:     pkt->dispersion = sys.dispersion;
     185:     pkt->refid = sys.refid;
     186:     pkt->reftime = sys.reftime;
     187:     pkt->org = peer->org;
     188:     pkt->rec = peer->rec;
     189:     (void) gettimeofday(&txtv, (struct timezone *) 0);
     190: #if 0
     191:     if (peer->flags & PEER_FL_AUTHENABLE) {
     192:         /* add encryption time into the timestamp */
     193:         tstamp(&pkt->xmt, &txtv);
     194:         /* call encrypt() procedure */
     195:         pkt->keyid = ???;
     196:         pkt->mac = ???;
     197:     } else {
     198:         pkt->mac[0] = pkt->mac[1] = 0;
     199:         pkt->keyid = 0;         /* XXX */
     200:         tstamp(&pkt->xmt, &txtv);
     201:     }
     202: #else
     203:     tstamp(&pkt->xmt, &txtv);
     204: #endif
     205:
     206:     peer->xmt = pkt->xmt;
     207:
     208:     if ((peer->flags & (PEER_FL_BCAST|PEER_FL_REFCLOCK)) == 0) {
     209:         /* select correct socket to send reply on */
     210:         if (sendto(addrs[(peer->sock < 0 ? 0 : peer->sock)].fd,
     211:                (char *) pkt, sizeof(ntpframe),
     212:                0, &peer->src, sizeof(peer->src)) < 0) {
     213:             syslog(LOG_ERR, "sendto: %s  %m",
     214:                    ntoa(peer->src.sin_addr));
     215:             return;
     216:         }
     217: #ifdef  REFCLOCK
     218:     } else if (peer->flags & PEER_FL_REFCLOCK) {
     219:         /* Special version of code below, adjusted for refclocks */
     220:
     221:
     222:         peer->pkt_sent++;
     223:         i = peer->reach;    /* save a copy */
     224:
     225:         peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK;
     226:
     227:         if (i && peer->reach == 0) {
     228:             syslog(LOG_INFO, "Lost reachability with %.4s",
     229:                    (char *)&peer->refid);
     230: #ifdef  DEBUG
     231:             if (debug)
     232:                 printf("Lost reachability with %.4s\n",
     233:                        (char *)&peer->refid);
     234: #endif
     235:         }
     236:
     237:         if (peer->reach == 0)
     238:             clear(peer);
     239:
     240:         if (peer->valid < 2)
     241:             peer->valid++;
     242:         else {
     243:             clock_filter(peer, 0.0, 0.0);   /* call with invalid values */
     244:             select_clock();     /* and try to reselect clock */
     245:         }
     246:
     247:         peer->timer = 1<<NTP_MINPOLL;   /* poll refclocks frequently */
     248:
     249:         refclock_input(peer, pkt);
     250:         return;
     251: #endif REFCLOCK
     252:     } else {
     253: #ifdef  BROADCAST_NTP
     254:         if (sendto(addrs[peer->sock].fd,
     255:                (char *) pkt, sizeof(ntpframe),
     256:                0, &peer->src, sizeof(peer->src)) < 0) {
     257:             syslog(LOG_ERR, "bcast sendto: %s  %m",
     258:                    ntoa(peer->src.sin_addr));
     259:             return;
     260:         }
     261: #else
     262:         return;
     263: #endif
     264:     }
     265:
     266: #ifdef  DEBUG
     267:     if (debug > 5) {
     268:         printf("\nSent ");
     269:         dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL);
     270:     }
     271: #endif
     272:     peer->pkt_sent++;
     273:     i = peer->reach;    /* save a copy */
     274:
     275:     peer->reach = (peer->reach << 1) & NTP_WINDOW_SHIFT_MASK;
     276:
     277:     if ((peer->reach == 0) &&
     278:         ((peer->flags & PEER_FL_CONFIG) == 0) &&
     279:         (peer != &dummy_peer)) {
     280:         demobilize(&peer_list, peer);
     281:         return;
     282:     }
     283:
     284:     if (i && peer->reach == 0) {
     285:         syslog(LOG_INFO, "Lost reachability with %s",
     286:                    ntoa(peer->src.sin_addr));
     287: #ifdef  DEBUG
     288:         if (debug)
     289:             printf("Lost reachability with %s",
     290:                    ntoa(peer->src.sin_addr));
     291: #endif
     292:     }
     293:
     294:     if (peer->reach == 0) {
     295:         clear(peer);
     296:         peer->sock = -1;    /* since he fell off the end of the
     297: 					   earth, don't depend on local address
     298: 					   any longer */
     299:     }
     300:
     301:     if (peer->valid < 2)
     302:         peer->valid++;
     303:     else {
     304:         clock_filter(peer, 0.0, 0.0);   /* call with invalid values */
     305:         select_clock();     /* and try to reselect clock */
     306:         if (sys.peer != NULL)
     307:             poll_update(sys.peer, NTP_MINPOLL);
     308:     }
     309:
     310:     peer->timer = 1<<(MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)),
     311:                    NTP_MINPOLL));
     312:
     313:     if (peer->estdisp > PEER_THRESHOLD)
     314:         poll_update(peer, peer->hpoll - 1);
     315:     else
     316:         poll_update(peer, peer->hpoll + 1);
     317: }
     318:
     319: #ifdef REFCLOCK
     320: void
     321: refclock_input(peer, pkt)
     322:     struct ntpdata *pkt;
     323:     struct ntp_peer *peer;
     324: {
     325:     struct timeval *tvp;
     326:     struct timeval *otvp;
     327:
     328:     if (read_clock(peer->sock, &tvp, &otvp))
     329:         return;
     330:
     331:     tstamp(&pkt->rec, tvp);
     332:     pkt->xmt = pkt->rec;
     333:     pkt->reftime = pkt->rec;
     334:     tstamp(&pkt->org, otvp);
     335:     peer->xmt = pkt->org;
     336:     pkt->refid = peer->refid;
     337:     pkt->status &= ~ALARM;
     338:     pkt->stratum = peer->stratum;
     339:     pkt->ppoll = 0xff;
     340:     pkt->precision = peer->precision;
     341:     double_to_s_fixed(&pkt->distance, 0.0);
     342:     double_to_s_fixed(&pkt->dispersion, 0.0);
     343: #ifdef  DEBUG
     344:     if (debug > 5) {
     345:         printf("\nFaking packet ");
     346:         dump_pkt(&peer->src, pkt, (struct ntp_peer *)NULL);
     347:     }
     348: #endif
     349:     receive((struct sockaddr_in *)peer, pkt, otvp, -1);
     350:     return;
     351: }
     352: #endif REFCLOCK
     353:
     354: /* 3.4.2. Receive Procedure */
     355: void
     356: receive(dst, pkt, tvp, sock)
     357:     struct sockaddr_in *dst;
     358:     struct ntpdata *pkt;
     359:     struct timeval *tvp;
     360:     int sock;
     361: {
     362:     struct ntp_peer *peer;
     363:     int peer_mode;
     364:
     365: #define ACT_ERROR   1
     366: #define ACT_RECV    2
     367: #define ACT_XMIT    3
     368: #define ACT_PKT     4
     369:
     370:     static char actions[5][5] = {
     371:
     372:  /*      Sym Act   Sym Pas    Client     Server     Broadcast  |Host /       */
     373:  /*      --------   --------  --------   ---------  ---------  |    / Peer   */
     374:  /*                                                            ------------  */
     375:     {ACT_PKT,  ACT_PKT,   ACT_RECV,  ACT_XMIT,  ACT_XMIT},  /* Sym Act   */
     376:     {ACT_PKT,  ACT_ERROR, ACT_RECV,  ACT_ERROR, ACT_ERROR}, /* Sym Pas   */
     377:     {ACT_XMIT, ACT_XMIT,  ACT_ERROR, ACT_XMIT,  ACT_XMIT},  /* Client    */
     378:     {ACT_PKT,  ACT_ERROR, ACT_RECV,  ACT_ERROR, ACT_ERROR}, /* Server    */
     379:     {ACT_PKT,  ACT_ERROR, ACT_RECV,  ACT_ERROR, ACT_ERROR}};/* Broadcast */
     380:
     381:     /* if we're only going to support NTP Version 2 then this stuff
     382: 	   isn't necessary, right? */
     383:
     384:     if ((peer_mode = pkt->status & MODEMASK) == 0 && dst) {
     385:         /* packet from an older NTP implementation.  Synthesize the
     386: 		   correct mode.  The mapping goes like this:
     387:
     388: 		   pkt source port      pkt dst port	Mode
     389: 		   ---------------	------------	----
     390: 		   NTP Port		NTP Port	symmetric active
     391: 		   NTP Port		not NTP Port	server
     392: 		   not NTP Port		NTP Port	client
     393: 		   not NTP Port		not NTP Port	<not possible>
     394:
     395: 		   Now, since we only are processing packets with the
     396: 		   destination being NTP Port, it reduces to the two cases:
     397:
     398: 		   pkt source port      pkt dst port	Mode
     399: 		   ---------------	------------	----
     400: 		   NTP Port		NTP Port	symmetric active
     401: 		   not NTP Port		NTP Port	client		 */
     402:
     403:         if (dst->sin_port == servp->s_port)
     404:             peer_mode = MODE_SYM_ACT;
     405:         else
     406:             peer_mode = MODE_CLIENT;
     407:     }
     408:
     409:     if (peer_mode == MODE_CLIENT) {
     410:         /*
     411: 		 * Special case: Use the dummy peer item that we keep around
     412: 		 * just for this type of thing
     413: 		 */
     414:         peer = &dummy_peer;
     415:         make_new_peer(peer);
     416:         peer->src = *dst;
     417:         peer->sock = sock;
     418:         peer->hmode = MODE_SYM_PAS;
     419:         peer->reach = 0;
     420:         clear(peer);
     421: #ifdef  REFCLOCK
     422:     } else if (sock == -1) {
     423:         /* we're begin called by refclock_input(), get peer ptr */
     424:         peer = (struct ntp_peer *)dst;
     425: #endif
     426:     } else
     427:         peer = check_peer(dst, sock);
     428:
     429:     if (peer == NULL) {
     430:         peer = (struct ntp_peer *) malloc(sizeof(struct ntp_peer));
     431:         if (peer == NULL) {
     432:             syslog(LOG_ERR, "peer malloc: %m");
     433:             return;
     434:         }
     435:         make_new_peer(peer);
     436:         peer->src = *dst;
     437:         peer->sock = sock;  /* remember which socket we heard
     438: 					   this from */
     439:         peer->hmode = MODE_SYM_PAS;
     440:         peer->reach = 0;
     441:         clear(peer);
     442:         /*
     443: 		 *  If we decide to consider any random NTP peer that might
     444: 		 *  come as a peer we might sync to, then set the PEER_FL_SYNC
     445: 		 *  flag in the peer structure.
     446: 		 *
     447: 		 *  Alternatively, we could change the hmode to MODE_SERVER,
     448: 		 *  but then the peer state wouldn't be persistant.
     449: 		 */
     450:         if (trusting)
     451:             peer->flags |= PEER_FL_SYNC;
     452:
     453:         enqueue(&peer_list, peer);
     454:     }
     455:
     456:     /*
     457: 	 *  "pre-configured" peers are initially assigned a socket index of
     458: 	 *  -1, which means we don't know which interface we'll use to talk
     459: 	 *  to them.  Once the first reply comes back, we'll update the
     460: 	 *  peer structure
     461: 	 */
     462:     if (peer->sock == -1)
     463:         peer->sock = sock;
     464:
     465: #ifdef  BROADCAST_NTP
     466:     /*
     467: 	 *  Input frame matched a funny broadcast peer;  these peers only
     468: 	 *  exist to periodically generate broadcasts.  If an input packet
     469: 	 *  matched, it means that it looked like it *came* from the broadcast
     470: 	 *  address.  This is clearly bogus.
     471: 	 */
     472:     if (peer->flags & PEER_FL_BCAST) {
     473: #ifdef  DEBUG
     474:         if (debug > 1)
     475:             printf("receive: input frame for broadcast peer?\n");
     476: #endif
     477:         return;
     478:     }
     479: #endif	/* BROADCAST_NTP */
     480:
     481: #if 0
     482:     if ((peer->flags & PEER_FL_AUTHENABLE) &&
     483:         pkt->mac) {
     484:         /* verify computed crypto-checksum */
     485:     }
     486: #endif
     487:
     488:     if (peer_mode < MODE_SYM_ACT || peer_mode > MODE_BROADCAST) {
     489:         syslog(LOG_DEBUG, "Bogus peer_mode %d from %s", peer_mode,
     490:                ntoa(dst->sin_addr));
     491: #ifdef  DEBUG
     492:         if (debug > 3) abort();
     493: #endif
     494:         return;
     495:     }
     496:
     497:     if (peer->hmode < MODE_SYM_ACT || peer->hmode > MODE_BROADCAST) {
     498:         syslog(LOG_ERR, "Bogus hmode %d for peer %s", peer->hmode,
     499:                ntoa(peer->src.sin_addr));
     500:         abort();
     501:     }
     502:
     503:     switch (actions[peer_mode - 1][peer->hmode - 1]) {
     504:     case ACT_RECV:
     505:         if (!(((peer->flags & PEER_FL_CONFIG) == 0) &&
     506:               STRMCMP(pkt->stratum, >, sys.stratum))) {
     507:             peer->reach |= 1;
     508:             process_packet(dst, pkt, tvp, peer);
     509:             break;
     510:         }
     511:         /* Note fall-through */
     512:     case ACT_ERROR:
     513:         if (((peer->flags & PEER_FL_CONFIG) == 0) &&
     514:             (peer != &dummy_peer))
     515:             demobilize(&peer_list, peer);
     516:         break;
     517:
     518:     case ACT_PKT:
     519:         if (!(((peer->flags & PEER_FL_CONFIG) == 0) &&
     520:               STRMCMP(pkt->stratum, >, sys.stratum))) {
     521:             peer->reach |= 1;
     522:             process_packet(dst, pkt, tvp, peer);
     523:             break;
     524:         }
     525:         /* Note fall-through */
     526:     case ACT_XMIT:
     527:         process_packet(dst, pkt, tvp, peer);
     528:         poll_update(peer, peer->ppoll);
     529:         transmit(peer);
     530:         break;
     531:
     532:     default:
     533:         abort();
     534:     }
     535: }
     536:
     537: #undef  ACT_ERROR
     538: #undef  ACT_RECV
     539: #undef  ACT_XMIT
     540: #undef  ACT_PKT
     541:
     542:
     543: /* 3.4.3 Packet procedure */
     544: void
     545: process_packet(dst, pkt, tvp, peer)
     546:     struct sockaddr_in *dst;
     547:     struct ntpdata *pkt;
     548:     struct timeval *tvp;
     549:     struct ntp_peer *peer;
     550: {
     551:     double t1, t2, t3, t4, offset, delay;
     552:     short duplicate, bogus;
     553:
     554:     duplicate = (pkt->xmt.int_part == peer->org.int_part) &&
     555:         (pkt->xmt.fraction == peer->org.fraction);
     556:
     557:     bogus = ((pkt->org.int_part != peer->xmt.int_part) ||
     558:          (pkt->org.fraction != peer->xmt.fraction))
     559:         || (peer->xmt.int_part == 0);
     560:
     561:     peer->pkt_rcvd++;
     562:     peer->leap = pkt->status & LEAPMASK;
     563:     peer->stratum = pkt->stratum;
     564:     peer->ppoll = pkt->ppoll;
     565:     peer->precision = pkt->precision;
     566:     peer->distance = pkt->distance;
     567:     peer->dispersion = pkt->dispersion;
     568:     peer->refid = pkt->refid;
     569:     peer->reftime = pkt->reftime;
     570:     peer->org = pkt->xmt;
     571:     tstamp(&peer->rec, tvp);
     572:     poll_update(peer, peer->hpoll);
     573:
     574:     /*
     575: 	 * may want to do something special here for Broadcast Mode peers to
     576: 	 * allow these through
     577: 	 */
     578:     if (bogus || duplicate ||
     579:         (pkt->org.int_part == 0 && pkt->org.fraction == 0) ||
     580:         (pkt->rec.int_part == 0 && pkt->org.fraction == 0)) {
     581:         peer->pkt_dropped++;
     582: #ifdef  DEBUG
     583:         if (debug > 3)
     584:             printf("process_packet: dropped duplicate or bogus\n");
     585: #endif
     586:         return;
     587:     }
     588:
     589:     /*
     590: 	 *  Now compute local adjusts
     591: 	 */
     592:     t1 = ul_fixed_to_double(&pkt->org);
     593:     t2 = ul_fixed_to_double(&pkt->rec);
     594:     t3 = ul_fixed_to_double(&pkt->xmt);
     595:     t4 = ul_fixed_to_double(&peer->rec);
     596:
     597:     /*
     598: 	 * although the delay computation looks different than the one in the
     599: 	 * specification, it is correct.  Think about it.
     600: 	 */
     601:     delay = (t2 - t1) - (t3 - t4);
     602:     offset = ((t2 - t1) + (t3 - t4)) / 2.0;
     603:
     604:     delay += 1.0/(u_long)(1L << -sys.precision)
     605: #ifndef REFCLOCK
     606:         + NTP_MAXSKW;
     607: #else
     608:         + (peer->flags&PEER_FL_REFCLOCK) ? NTP_REFMAXSKW : NTP_MAXSKW;
     609: #endif
     610:     if (peer->precision < 0 && -peer->precision < sizeof(long)*NBBY)
     611:         delay += 1.0/(u_long)(1L << -peer->precision);
     612:
     613:     if (delay < 0.0) {
     614:         peer->pkt_dropped++;
     615:         return;
     616:     }
     617:
     618: #ifndef REFCLOCK
     619:     delay = MAX(delay, NTP_MINDIST);
     620: #else
     621:     delay = MAX(delay, (peer->flags & PEER_FL_REFCLOCK) ?
     622:             NTP_REFMINDIST : NTP_MINDIST);
     623: #endif
     624:
     625:     peer->valid = 0;
     626:     clock_filter(peer, delay, offset);  /* invoke clock filter procedure */
     627: #ifdef  DEBUG
     628:     if (debug) {
     629:         printf("host: %s : %f : %f : %f : %f : %f : %lo\n",
     630:                dst ? ntoa(dst->sin_addr) : "refclock",
     631:                delay, offset,
     632:                peer->estdelay, peer->estoffset, peer->estdisp,
     633:                peer->reach);
     634:     }
     635: #endif
     636:     clock_update(peer);     /* call clock update procedure */
     637: }
     638:
     639: /* 3.4.4 Primary clock procedure */
     640: /*
     641:  *  We don't have a primary clock.
     642:  *
     643:  *  TODO:
     644:  *
     645:  *  ``When a  primary clock is connected to the host, it is convient to
     646:  *    incorporate its information into the database as if the clock was
     647:  *    represented as an ordinary peer.  The clock can be polled once a
     648:  *    minute or so and the returned timecheck used to produce a new update
     649:  *    for the logical clock.''
     650:  */
     651:
     652:
     653: /* 3.4.5 Clock update procedure */
     654:
     655: void
     656: clock_update(peer)
     657:     struct ntp_peer *peer;
     658: {
     659:     double temp;
     660:     extern int adj_logical();
     661:
     662:     select_clock();
     663:     if (sys.peer != NULL)
     664:         poll_update(sys.peer, NTP_MINPOLL);
     665:
     666:     /*
     667: 	 * Did we just sync to this peer?
     668: 	 */
     669:     if ((peer == sys.peer) && (sys.hold == 0)) {
     670:         char buf[200];
     671:
     672:         /*
     673: 		 *  Update the local system variables
     674: 		 */
     675:         sys.leap = peer->leap;
     676: #ifndef REFCLOCK
     677:         sys.stratum = peer->stratum + 1;
     678:         sys.refid = peer->src.sin_addr.s_addr;
     679: #else
     680:         if (peer->flags & PEER_FL_REFCLOCK) {
     681:             /* once we re-map the stratums so that stratum 0 is
     682: 			   better than stratum 1, some of this foolishness
     683: 			   can go away */
     684:             sys.stratum = peer->stratum;
     685:             sys.refid = peer->refid;
     686:         } else {
     687:             sys.stratum = peer->stratum + 1;
     688:             sys.refid = peer->src.sin_addr.s_addr;
     689:         }
     690: #endif
     691:
     692:         temp = s_fixed_to_double(&peer->distance) + peer->estdelay;
     693:         double_to_s_fixed(&sys.distance, temp);
     694:
     695:         temp = s_fixed_to_double(&peer->dispersion) + peer->estdisp;
     696:         double_to_s_fixed(&sys.dispersion, temp);
     697:
     698:         sys.reftime = peer->rec;
     699:
     700: #ifdef  DEBUG
     701:         if (debug > 3)
     702:             printf("clock_update: synced to peer, adj clock\n");
     703: #endif
     704:
     705:         /*
     706: 		 * Sanity check: is computed offset insane?
     707: 		 */
     708:         if (peer->estoffset > WayTooBig ||
     709:             peer->estoffset < -WayTooBig) {
     710:             syslog(LOG_ERR, "Clock is too far off %f sec. [%s]",
     711:                    peer->estoffset, ntoa(peer->src.sin_addr));
     712: #ifdef  DEBUG
     713:             if (debug)
     714:                 printf("Clock is too far off %f sec. [%s] (max %f)\n",
     715:                        peer->estoffset,
     716:                        ntoa(peer->src.sin_addr), WayTooBig);
     717: #endif	/*DEBUG*/
     718:             return;
     719:         }
     720:
     721:         clock_watchdog = 0; /* reset watchdog timer */
     722:         if (adj_logical(peer->estoffset) > 0) {
     723:             register struct ntp_peer *p = peer_list.head;
     724:             /* did you know syslog only took 4 parameters? */
     725:             sprintf(buf,
     726:                     "adjust: STEP %s st %d off %f drft %f cmpl %f",
     727:                 inet_ntoa(peer->src.sin_addr), peer->stratum,
     728:                 peer->estoffset, drift_comp, compliance);
     729:             syslog(LOG_INFO, buf);
     730: #ifdef  DEBUG
     731:             if (debug)
     732:                 printf("Clockset from %s stratum %d offset %f\n",
     733:                        inet_ntoa(peer->src.sin_addr),
     734:                        peer->stratum, peer->estoffset);
     735:
     736: #endif
     737:             while (p) {
     738:                 clear(p);
     739:                 p = p->next;
     740:             }
     741:             sys.hold = PEER_SHIFT * (1 << NTP_MINPOLL);
     742: #ifdef  DEBUG
     743:             if (debug > 3)
     744:                 printf("clock_updates: STEP ADJ\n");
     745: #endif
     746:         } else {
     747:             if (logstats) {
     748:                 sprintf(buf,
     749:                     "adjust: SLEW %s st %d off %f drft %f cmpl %f",
     750:                     inet_ntoa(peer->src.sin_addr),
     751:                     peer->stratum,
     752:                     peer->estoffset, drift_comp,
     753:                     compliance);
     754:                 syslog(LOG_INFO, buf);
     755:             }
     756:         }
     757:     }
     758: }
     759:
     760: /* 3.4.6 Initialization procedure */
     761:
     762: void
     763: initialize()
     764: {
     765:     sys.leap = ALARM;   /* indicate unsynchronized */
     766:     sys.stratum = 0;
     767:     sys.precision = 0;  /* may be specified in the config file;
     768: 				   if not, gets set in init_kern_vars() */
     769: #if 0   /* under construction */
     770:     sys.keyid = 0;
     771:     sys.keys = ??;
     772: #endif
     773:     sys.distance.int_part = sys.distance.fraction = 0;
     774:     sys.dispersion.int_part = sys.dispersion.fraction = 0;
     775:     sys.refid = 0;
     776:     sys.reftime.int_part = sys.reftime.fraction = 0;
     777:     sys.hold = 0;
     778:     sys.peer = NULL;
     779: }
     780:
     781: /* 3.4.7 Clear Procedure */
     782: void
     783: clear(peer)
     784:     register struct ntp_peer *peer;
     785: {
     786:     register int i;
     787:
     788: #ifdef  DEBUG
     789:     if (debug > 3)
     790:         printf("clear: emptied filter for %s\n",
     791:                ntoa(peer->src.sin_addr));
     792: #endif
     793:     peer->hpoll = NTP_MINPOLL;
     794:     peer->estdisp = PEER_MAXDISP;
     795:     for (i = 0; i < NTP_WINDOW; i++)
     796:         peer->filter.offset[i] = 0.0;
     797:     peer->filter.samples = 0;   /* Implementation specific */
     798:     peer->valid = 0;
     799:     peer->org.int_part = peer->org.fraction = 0;
     800:     peer->rec.int_part = peer->rec.fraction = 0;
     801:     peer->xmt.int_part = peer->xmt.fraction = 0;
     802:     poll_update(peer, NTP_MINPOLL);
     803:     select_clock();
     804:     if (sys.peer != NULL)
     805:         poll_update(sys.peer, NTP_MINPOLL);
     806: }
     807:
     808:
     809: /* 3.4.8 Poll Update Procedure */
     810: void
     811: poll_update(peer, new_hpoll)
     812:     register struct ntp_peer *peer;
     813:     int new_hpoll;
     814: {
     815:     int interval;
     816:
     817:     peer->hpoll = MAX(NTP_MINPOLL, MIN(NTP_MAXPOLL, new_hpoll));
     818:
     819: #if XTAL    /* if crystal controlled clock */
     820:     if (peer == sys.peer)
     821: #endif
     822:         peer->hpoll = NTP_MINPOLL;
     823:
     824:     interval = 1 << (MAX(MIN(peer->ppoll, MIN(peer->hpoll, NTP_MAXPOLL)),
     825:                NTP_MINPOLL));
     826:
     827: #ifdef  REFCLOCK
     828:     if (peer->flags & PEER_FL_REFCLOCK)
     829:         interval = 1 << NTP_MINPOLL;
     830: #endif
     831:     if (interval == peer->timer)
     832:         return;
     833:
     834:     /* only randomize when poll interval changes */
     835:     if (interval < peer->timer)
     836:         peer->timer = interval;
     837:
     838:     /*
     839: 	 * "Rand uses a multiplicative congruential random number gen-
     840: 	 * erator with period 2**32 to return successive pseudo-random
     841: 	 * numbers in the range from 0 to (2**31)-1"
     842: 	 */
     843:     interval = (double)interval *
     844:         ((double)rand()/(double)((u_long)(1L<<31) - 1));
     845:
     846: #ifdef  DEBUG
     847:     if (debug > 3)
     848:         printf("poll_update: timer %d, poll=%d\n", peer->timer,
     849:                interval);
     850: #endif
     851: }
     852:
     853:
     854: /* 3.4.9 Authentication Procedures */
     855: #if 0
     856: encrypt() {}
     857: decrypt() {}
     858: #endif
     859:
     860: /* 4.1 Clock Filter Procedure */
     861: /*
     862:  *  The previous incarnation of this code made the assumption that
     863:  *  the value of PEER_FILTER was a power of two and used shifting.
     864:  *  This version has been generalized, so that experimenting with
     865:  *  different PEER_FILTER values should be much easier.
     866:  */
     867:
     868: void
     869: clock_filter(peer, new_delay, new_offset)
     870:     register struct ntp_peer *peer;
     871:     double new_delay, new_offset;
     872: {
     873:     double offset[PEER_SHIFT], delay[PEER_SHIFT];
     874:     register double temp, d, w;
     875:     register int i, j, samples;
     876:
     877:     if (peer->filter.samples < PEER_SHIFT)
     878:         peer->filter.samples++;
     879:     /*
     880: 	 *  Too bad C doesn't have a barrel shifter...
     881: 	 */
     882:     for (i = PEER_SHIFT - 1; i; i--) {
     883:         peer->filter.offset[i] = peer->filter.offset[i - 1];
     884:         peer->filter.delay[i] = peer->filter.delay[i - 1];
     885:     }
     886:     peer->filter.offset[0] = new_offset;
     887:     peer->filter.delay[0] = new_delay;
     888:
     889:     samples = 0;
     890:     /*
     891: 	 *  Now sort the valid (non-zero delay) samples into a temporary
     892: 	 *  list by delay.
     893: 	 *
     894: 	 *  First, build the temp list...
     895: 	 */
     896:     for (i = 0; i < peer->filter.samples; i++) {
     897:         if (peer->filter.delay[i] != 0.0) {
     898:             offset[samples] = peer->filter.offset[i];
     899:             delay[samples++] = peer->filter.delay[i];
     900:         }
     901:     }
     902:     /* ..and now sort it. */
     903:     if (samples) {
     904:         for (i = 0; i < samples - 1; i++) {
     905:             for (j = i + 1; j < samples; j++) {
     906:                 if (delay[i] > delay[j]) {
     907:                     temp = delay[i];
     908:                     delay[i] = delay[j];
     909:                     delay[j] = temp;
     910:                     temp = offset[i];
     911:                     offset[i] = offset[j];
     912:                     offset[j] = temp;
     913:                 }
     914:             }
     915:         }
     916:         /* samples are now sorted by delay */
     917:
     918:         peer->estdelay = delay[0];
     919:         peer->estoffset = offset[0];
     920:     }
     921:
     922:     temp = 0.0;
     923:     w = 1.0;
     924:
     925:     for (i = 0; i < PEER_SHIFT; i++) {
     926:         if (i >= samples)
     927:             d = PEER_MAXDISP;
     928:         else {
     929:             if ((d = offset[i] - offset[0]) < 0)
     930:                 d = -d;
     931:             if (d > PEER_MAXDISP)
     932:                 d = PEER_MAXDISP;
     933:         }
     934:         temp += d * w;
     935:         /* compute  PEER_FILTER**i  as we go along */
     936:         w *= PEER_FILTER;
     937:     }
     938:     peer->estdisp = temp;
     939: #ifdef  DEBUG
     940:     if (debug > 3)
     941:         printf("clock_filter: estdelay %f, estoffset %f, estdisp %f\n",
     942:                peer->estdelay, peer->estoffset, peer->estdisp);
     943: #endif
     944: }
     945:
     946: /* 4.2 Clock Select Procedure */
     947: void
     948: select_clock() {
     949:     struct ntp_peer *ptmp, *peer = peer_list.head;
     950:     struct sel_lst {
     951:         struct ntp_peer *peer;
     952:         double distance;
     953:         double precision;
     954:     } sel_lst[X_NTP_CANDIDATES];
     955:     int i, j, stratums, candidates;
     956:     int sanity_check();
     957:     double falsetick(), dtmp;
     958:
     959:     candidates = 0;
     960:     stratums = 0;
     961:
     962:     while (peer != NULL && candidates < X_NTP_CANDIDATES) {
     963:         /*
     964: 		 * Check if this is a candidate for "sys.peer"
     965: 		 */
     966:         peer->flags &= ~(PEER_FL_SANE | PEER_FL_CANDIDATE);
     967:         if(sanity_check(peer)) {
     968:             sel_lst[candidates].peer = peer;
     969:             sel_lst[candidates].distance = peer->estdisp +
     970:                 s_fixed_to_double(&peer->dispersion);
     971:             peer->flags |= PEER_FL_SANE;
     972:             candidates++;
     973:         }
     974:         peer = peer->next;
     975:     }
     976: #ifdef  DEBUG
     977:     if (debug > 3)
     978:         printf("select_clock: step1 %d candidates\n", candidates);
     979: #endif
     980:     /*
     981: 	 *  If no candidates passed the sanity check, then give up.
     982: 	 */
     983:     if (!candidates) {
     984:         if (sys.peer != NULL) {
     985:             syslog(LOG_INFO, "Lost NTP peer %s",
     986:                    inet_ntoa(sys.peer->src.sin_addr));
     987: #ifdef  DEBUG
     988:             if (debug)
     989:                 printf("Lost NTP peer %s\n",
     990:                        inet_ntoa(sys.peer->src.sin_addr));
     991: #endif
     992:         }
     993: #ifdef  DEBUG
     994:         if (debug > 3)
     995:             printf("select_clock: no candidates\n");
     996: #endif
     997:         sys.peer = NULL;
     998:         /*
     999: 		 * leave sys.stratum and sys.refid intact after losing
    1000: 		 * reachability to all clocks.  After 24 hours, we'll
    1001: 		 * set the alarm condition if we didn't get any clock
    1002: 		 * updates.
    1003: 		 */
    1004:         return;
    1005:     }
    1006:
    1007:     /*
    1008: 	 *  Sort the list.  We assume that sanity_check() above trashed any
    1009: 	 *  peers which were stratum 0, so we can safely compare stratums
    1010: 	 *  below.  Sort the list by stratum.  Where stratums are equal, the
    1011: 	 *  peer with the lowest (peer.estdisp + peer.dispersion) is preferred.
    1012: 	 */
    1013:     for (i = 0; i < candidates - 1; i++) {
    1014:         for (j = i + 1; j < candidates; j++) {
    1015:             if ((sel_lst[i].peer->stratum > sel_lst[j].peer->stratum) ||
    1016:                 ((sel_lst[i].peer->stratum == sel_lst[j].peer->stratum)
    1017:                  && (sel_lst[i].distance > sel_lst[j].distance))) {
    1018:                 ptmp = sel_lst[i].peer;
    1019:                 dtmp = sel_lst[i].distance;
    1020:                 sel_lst[i].peer = sel_lst[j].peer;
    1021:                 sel_lst[i].distance = sel_lst[j].distance;
    1022:                 sel_lst[j].peer = ptmp;
    1023:                 sel_lst[j].distance = dtmp;
    1024:             }
    1025:         }
    1026:     }
    1027:
    1028: #ifdef  DEBUG
    1029:     if (debug > 3)
    1030:         printf("select_clock: step2 %d candidates\n", candidates);
    1031: #endif
    1032:
    1033:     /* truncate the list at NTP_MAXLIST peers */
    1034:     if (candidates > NTP_MAXLIST)
    1035:         candidates = NTP_MAXLIST;
    1036:
    1037: #ifdef  DEBUG
    1038:     if (debug > 3)
    1039:         printf("select_clock: step3 %d candidates\n", candidates);
    1040: #endif
    1041:
    1042:     /* truncate list where number of different strata exceeds NTP_MAXSTRA */
    1043:     for (stratums = 0, i = 1; i < candidates; i++) {
    1044:         if (sel_lst[i - 1].peer->stratum != sel_lst[i].peer->stratum) {
    1045:             if (++stratums > NTP_MAXSTRA) {
    1046: #ifdef  DEBUG
    1047:                 if (debug > 2)
    1048:                     printf("select_clock: truncated to %d peers\n", i);
    1049: #endif
    1050:                 candidates = i;
    1051:
    1052:                 break;
    1053:             }
    1054:         }
    1055:     }
    1056: #ifdef  DEBUG
    1057:     if (debug > 3)
    1058:         printf("select_clock: step4 %d candidates\n", candidates);
    1059: #endif
    1060:     /*
    1061: 	 * Kick out falsetickers
    1062: 	 */
    1063:     /* now, re-sort the list by peer.stratum and peer.estdelay */
    1064:     for (i = 0; i < candidates - 1; i++) {
    1065:         for (j = i + 1; j < candidates; j++) {
    1066:             if ((sel_lst[i].peer->stratum > sel_lst[j].peer->stratum) ||
    1067:                 ((sel_lst[i].peer->stratum == sel_lst[j].peer->stratum)
    1068:                  && (sel_lst[i].peer->estdelay >
    1069:                  sel_lst[j].peer->estdelay))) {
    1070:                 ptmp = sel_lst[i].peer;
    1071:                 sel_lst[i].peer = sel_lst[j].peer;
    1072:                 sel_lst[j].peer = ptmp;
    1073:             }
    1074:         }
    1075:     }
    1076:     while (candidates > 1) {
    1077:         double maxdispersion = 0.0, dispersion, weight;
    1078:         double min_precision_thres = 10e20, precision_thres;
    1079:         short worst = 0;    /* shut up GNU CC about unused var */
    1080: #ifdef  DEBUG
    1081:         if (debug > 3)
    1082:             printf("select_clock: step5 %d candidates\n", candidates);
    1083: #endif
    1084:         for (i = 0; i < candidates; i++) {
    1085:             /* compute dispersion of candidate `i' relative to the
    1086: 			   rest of the candidates */
    1087:             dispersion = 0.0;
    1088:             weight = 1.0;
    1089:             sel_lst[i].peer->flags |= PEER_FL_CANDIDATE;
    1090:             for (j = 0; j < candidates; j++) {
    1091:                 dtmp = sel_lst[j].peer->estoffset -
    1092:                     sel_lst[i].peer->estoffset;
    1093:                 if (dtmp < 0)
    1094:                     dtmp = -dtmp;
    1095:                 dispersion += dtmp * weight;
    1096:                 weight *= NTP_SELECT;
    1097:             }
    1098:             /* since we just happen to have this double floating
    1099: 			   around.. */
    1100:             sel_lst[i].distance = dispersion;
    1101:
    1102:             precision_thres = NTP_MAXSKW + 1.0/(u_long)(1L<<-sys.precision);
    1103:             if (sel_lst[i].peer->precision < 0 &&
    1104:                 -sel_lst[i].peer->precision < sizeof(long)*NBBY)
    1105:                 precision_thres +=
    1106:                     1.0/(u_long)(1L<<-sel_lst[i].peer->precision);
    1107:
    1108:             sel_lst[i].precision = precision_thres;
    1109:
    1110:             if (dispersion >= maxdispersion) {
    1111:                 maxdispersion = dispersion;
    1112:                 worst = i;
    1113:             }
    1114:             if (precision_thres < min_precision_thres) {
    1115:                 min_precision_thres = precision_thres;
    1116:             }
    1117: #ifdef  DEBUG
    1118:             if (debug > 4) {
    1119:                 printf(" peer %s => disp %f prec_th %f\n",
    1120:                        ntoa(sel_lst[i].peer->src.sin_addr),
    1121:                        dispersion, precision_thres);
    1122:             }
    1123: #endif
    1124:         }
    1125:         /*
    1126: 		 *  Now check to see if the max dispersion is greater than
    1127: 		 *  the min dispersion limit.  If so, crank again, otherwise
    1128: 		 *  bail out.
    1129: 		 */
    1130:         if (! (maxdispersion > min_precision_thres)) {
    1131: #ifdef  DEBUG
    1132:             if (debug > 4)
    1133:                 printf(" %d left valid\n", candidates);
    1134: #endif
    1135:             break;
    1136:         }
    1137:
    1138: #ifdef  DEBUG
    1139:         if (debug > 4)
    1140:             printf(" peer %s => TOSS\n",
    1141:                    ntoa(sel_lst[worst].peer->src.sin_addr));
    1142: #endif
    1143:         /*
    1144: 		 *  now, we need to trash the peer with the worst dispersion
    1145: 		 *  and interate until there is only one candidate peer left.
    1146: 		 */
    1147:         if (worst != candidates - 1) {
    1148:             sel_lst[worst].peer->flags &= ~PEER_FL_CANDIDATE;
    1149:             for (i = worst, j = worst + 1; j < candidates; )
    1150:                 sel_lst[i++].peer = sel_lst[j++].peer;
    1151:         }
    1152:         candidates--;
    1153:         /* one more time.. */
    1154:     }
    1155: #ifdef  DEBUG
    1156:     if (debug > 3)
    1157:         printf("select_clock: step6 %d candidates\n", candidates);
    1158: #endif
    1159:
    1160:     /*
    1161: 	 *  Check to see if current peer is on the list of candidate peers.  If
    1162: 	 *  don't change sys.peer.  Note that if the first selected clock is
    1163: 	 *  at a lower stratum, don't even bother; we're going to want to
    1164: 	 *  switch to it.
    1165: 	 */
    1166:     if (sys.peer != NULL &&
    1167:         (sys.peer->stratum <= sel_lst[0].peer->stratum)) {
    1168:         for (i = 0; i < candidates; i++) {
    1169:             if (sys.peer == sel_lst[i].peer) {
    1170:                 /*
    1171: 				 * The clock we're currently synchronized to
    1172: 				 * is among the candidate peers.  Don't switch.
    1173: 				 */
    1174:                 if (i != 0) {
    1175:                     /*
    1176: 					 *  Count instances where the best
    1177: 					 *  candidate is different from the
    1178: 					 *  current clock, thus inhibiting
    1179: 					 *  clockhopping.
    1180: 					 */
    1181:                     peer_sw_inhibited++;
    1182:                 }
    1183:                 return;
    1184:             }
    1185:         }
    1186:     }
    1187:
    1188:     /*
    1189: 	 *  The currently selected peer (if any) isn't on the candidate list.
    1190: 	 *  Grab the first one and let it be.
    1191: 	 */
    1192:
    1193:     if (sys.peer != sel_lst[0].peer) {
    1194:         if (sys.peer != NULL)
    1195:             syslog(LOG_INFO, "clock: select peer %s stratum %d was %s stratum %d",
    1196:                    ntoa(sel_lst[0].peer->src.sin_addr),
    1197:                    sel_lst[0].peer->stratum,
    1198:                    ntoa(sys.peer->src.sin_addr), sys.peer->stratum);
    1199:         else
    1200:             syslog(LOG_INFO, "clock: select peer %s stratum %d was UNSYNCED",
    1201:                    ntoa(sel_lst[0].peer->src.sin_addr),
    1202:                    sel_lst[0].peer->stratum);
    1203:
    1204: #ifdef  DEBUG
    1205:         if (debug > 2)
    1206:             printf("clock: select peer %s stratum %d of %d cand\n",
    1207:                    ntoa(sel_lst[0].peer->src.sin_addr),
    1208:                    sel_lst[0].peer->stratum, candidates);
    1209: #endif
    1210:         sys.peer = sel_lst[0].peer;
    1211:         peer_switches++;
    1212:     }
    1213: }
    1214:
    1215: int
    1216: sanity_check(peer)
    1217:     struct ntp_peer *peer;
    1218: {
    1219: #ifdef  DEBUG
    1220:     if (debug > 7)
    1221:         printf("Checking peer %s stratum %d\n",
    1222:                inet_ntoa(peer->src.sin_addr), peer->stratum);
    1223: #endif
    1224:     /* Sanity check 0. ?? */
    1225:     if (!(peer->flags & PEER_FL_SYNC))
    1226:         return(0);
    1227:
    1228:     /* Sanity check 1. */
    1229:     if (peer->stratum <= 0 || peer->stratum >= NTP_INFIN)
    1230:         return(0);
    1231:
    1232:     /* Sanity check 2.
    1233: 	   if peer.stratum is greater than one (synchronized via NTP),
    1234: 	   peer.refid must not match peer.dstadr */
    1235:
    1236:     if (peer->stratum > 1) {
    1237:         register int i;
    1238:         for (i = 1; i < nintf; i++)
    1239:             if (addrs[i].sin.sin_addr.s_addr == peer->refid)
    1240:                 return (0);
    1241:     }
    1242:
    1243:     /* Sanity check 3.
    1244: 	   Both peer.estdelay and
    1245: 	   peer.estdisp to be less than NTP_MAXWGT, which insures that the
    1246: 	   filter register at least half full, yet avoids using data from
    1247: 	   very noisy associations or broken implementations.  	*/
    1248:     if (peer->estdisp > (float)NTP_MAXWGT ||
    1249:         peer->estdelay > (float)NTP_MAXWGT)
    1250:         return(0);
    1251:
    1252:     /*  Sanity check 4.
    1253: 	    The peer clock must be synchronized... and the interval since
    1254: 	    the peer clock was last updated satisfy
    1255:
    1256: 	    peer.org - peer.reftime < NTP.MAXAGE
    1257: 	 */
    1258:     if (peer->leap == ALARM ||
    1259:         (ul_fixed_to_double(&peer->org)
    1260:          - ul_fixed_to_double(&peer->reftime)) >= NTP_MAXAGE)
    1261:         return(0);
    1262:
    1263: #ifdef  DEBUG
    1264:     if (debug > 7)
    1265:         printf("That one is certainly qualified %s\n",
    1266:                inet_ntoa(peer->src.sin_addr));
    1267: #endif
    1268:     return(1);
    1269: }

#### Defined functions

clear defined in line 782; used 9 times

- in line 164, 238, 295, 420, 441, 738
- in /usr/src/usr.sbin/ntp/ntpd.c line 167, 913, 969

clock_filter defined in line 868; used 5 times

- in line 164, 243, 304, 626
- in /usr/src/usr.sbin/ntp/ntpd.c line 167

clock_update defined in line 655; used 3 times

- in line 164, 636
- in /usr/src/usr.sbin/ntp/ntpd.c line 166

decrypt defined in line 857; never used
encrypt defined in line 856; never used
initialize defined in line 762; used 2 times

- in /usr/src/usr.sbin/ntp/ntpd.c line 164, 187

poll_update defined in line 810; used 9 times

- in line 165, 307, 314-316(2), 528, 572, 664, 802-805(2)

process_packet defined in line 544; used 5 times

- in line 164, 508, 522-527(2)
- in /usr/src/usr.sbin/ntp/ntpd.c line 166

receive defined in line 355; used 3 times

- in line 165, 349
- in /usr/src/usr.sbin/ntp/ntpd.c line 435

refclock_input defined in line 320; used 2 times

- in line 161, 249

sanity_check defined in line 1215; used 2 times

- in line 956, 967

select_clock defined in line 947; used 6 times

- in line 165, 244, 305, 662, 803
- in /usr/src/usr.sbin/ntp/ntpd.c line 167

transmit defined in line 170; used 4 times

- in line 529
- in /usr/src/usr.sbin/ntp/ntpd.c line 166, 673, 921

#### Defined variables

dummy_peer defined in line 142; used 3 times

- in line 279, 414, 514

peer_sw_inhibited defined in line 140; used 1 times

- in line 1181

peer_switches defined in line 140; used 1 times

- in line 1211

rcsid defined in line 2; never used

#### Defined struct's

sel_lst defined in line 950; never used

#### Defined macros

ACT_ERROR defined in line 365; used 12 times

- in line 376-379(10), 512, 537

ACT_PKT defined in line 368; used 7 times

- in line 375-379(5), 518, 540

ACT_RECV defined in line 366; used 6 times

- in line 375-379(4), 504, 538

ACT_XMIT defined in line 367; used 8 times

- in line 375-377(6), 526, 539

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