System: ntp version 3.4 Patch #: 2 Priority: From: Description: ntp: Use a connected UDP socket to pick up ICMP generated errors. This will allow us to recognized ICMP port unreachable messages when use use the ntp program on a host with no NTP service. ntpd: Add some fiddles for BROADCAST NTP mode. In the receive procedure, set the reachability shift register of peers that are configured, even if we won't synchronized to them. Fix adjustment of delay in the process_packet() routine. Repair byteswapping problem. ntpdc: The peer->refid field was being htonl()'ed when it was already in network byte order. Display dispersion in milliseconds. The peer->refid field was being ntohl()'ed when it should have stayed in network byte order. Repeat-By: Fix: From rn, say "| patch -p -N -d DIR", where DIR is your ntp source directory. Outside of rn, say "cd DIR; patch -p -N #define PATCHLEVEL 2 Index: ntp.c Prereq: 3.4.1.1 *** ntp.c.old Wed Mar 22 18:04:24 1989 --- ntp.c Wed Mar 22 18:04:24 1989 *************** *** 1,9 **** #ifndef lint ! static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/ntp.c,v 3.4.1.1 89/03/20 00:02:32 louie Exp $"; #endif lint /* * $Log: ntp.c,v $ * Revision 3.4.1.1 89/03/20 00:02:32 louie * patch1: Shorten timeout interval and clean up timeout message. * --- 1,12 ---- #ifndef lint ! static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/ntp.c,v 3.4.1.2 89/03/22 17:51:13 louie Exp Locker: louie $"; #endif lint /* * $Log: ntp.c,v $ + * Revision 3.4.1.2 89/03/22 17:51:13 louie + * Use a connect UDP socket so we can pick up ICMP error messages. + * * Revision 3.4.1.1 89/03/20 00:02:32 louie * patch1: Shorten timeout interval and clean up timeout message. * *************** *** 126,135 **** time_t net_time; ref_clock[4] = NULL; - if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - perror("ntp socket"); - exit(1); - } timeout.tv_sec = TIME_OUT; timeout.tv_usec = 0; retry = RETRY_COUNT; --- 129,134 ---- *************** *** 182,209 **** pkt->stratum = UNSPECIFIED; pkt->ppoll = 0; /* * Needed to fill in the time stamp fields */ (void) gettimeofday(&tp, (struct timezone *) 0); - tstamp(&pkt->xmt, &tp); ! if ((sendto(s, (char *) pkt, sizeof(ntp_data), 0, ! (struct sockaddr *) &dst, dstlen)) < 0) { ! perror("ntp sendto"); exit(1); } /* * Wait for the reply by watching the file descriptor */ - FD_ZERO(&readfds); - FD_SET(s, &readfds); /* since it's always modified on ret */ if ((n = select(FD_SETSIZE, (fd_set *) & readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0) { perror("ntp select"); exit(1); } if (n == 0) { fprintf(stderr,"*Timeout*\n"); if (--retry) --- 181,219 ---- pkt->stratum = UNSPECIFIED; pkt->ppoll = 0; + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("ntp socket"); + exit(1); + } + + FD_ZERO(&readfds); + FD_SET(s, &readfds); /* since it's always modified on ret */ + + if (connect(s, (struct sockaddr *)&dst, dstlen)) { + perror("connect"); + exit(1); + } + /* * Needed to fill in the time stamp fields */ (void) gettimeofday(&tp, (struct timezone *) 0); tstamp(&pkt->xmt, &tp); ! if (send(s, (char *) pkt, sizeof(ntp_data), 0) < 0) { ! perror("send"); exit(1); } + /* * Wait for the reply by watching the file descriptor */ if ((n = select(FD_SETSIZE, (fd_set *) & readfds, (fd_set *) 0, (fd_set *) 0, &timeout)) < 0) { perror("ntp select"); exit(1); } + if (n == 0) { fprintf(stderr,"*Timeout*\n"); if (--retry) *************** *** 217,228 **** } if ((recvfrom(s, (char *) pkt, sizeof(ntp_data), 0, (struct sockaddr *) &sin, &dstlen)) < 0) { ! perror("ntp recvfrom"); exit(1); } (void) gettimeofday(&tp, (struct timezone *) 0); tstamp(&in_timestamp, &tp); if (verbose) { printf("Packet from: [%s]\n", inet_ntoa(sin.sin_addr)); printf("Leap %d, version %d, mode %s, poll %d, precision %d stratum %d", --- 227,239 ---- } if ((recvfrom(s, (char *) pkt, sizeof(ntp_data), 0, (struct sockaddr *) &sin, &dstlen)) < 0) { ! perror("recvfrom"); exit(1); } (void) gettimeofday(&tp, (struct timezone *) 0); tstamp(&in_timestamp, &tp); + close(s); if (verbose) { printf("Packet from: [%s]\n", inet_ntoa(sin.sin_addr)); printf("Leap %d, version %d, mode %s, poll %d, precision %d stratum %d", Index: ntp_proto.c Prereq: 3.4.1.1 *** ntp_proto.c.old Wed Mar 22 18:04:29 1989 --- ntp_proto.c Wed Mar 22 18:04:31 1989 *************** *** 1,5 **** #ifndef lint ! static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/ntp_proto.c,v 3.4.1.1 89/03/20 00:10:06 louie Exp $"; #endif /* --- 1,5 ---- #ifndef lint ! static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/ntp_proto.c,v 3.4.1.2 89/03/22 18:02:22 louie Exp Locker: louie $"; #endif /* *************** *** 10,15 **** --- 10,22 ---- * * * $Log: ntp_proto.c,v $ + * Revision 3.4.1.2 89/03/22 18:02:22 louie + * Add some fiddles for BROADCAST NTP mode. In the receive procedure, set the + * reachability shift register of peers that are configured, even if we won't + * synchronized to them. Fix adjustment of delay in the process_packet() + * routine. Repair byteswapping problem. + * + * * Revision 3.4.1.1 89/03/20 00:10:06 louie * patch1: sys.refid could have garbage left if the peer we're synchronized to * patch1: is lost. *************** *** 287,292 **** --- 294,315 ---- enqueue(&peer_list, peer); } + #ifdef BROADCAST_NTP + /* + * Input frame matched a funny broadcast peer; these peers only + * exist to periodically generate broadcasts. If an input packet + * matched, it means that it looked like it *came* from the broadcast + * address. This is clearly bogus. + */ + if (peer->flags & PEER_FL_BCAST) { + #ifdef DEBUG + if (debug > 1) + printf("receive: input frame for broadcast peer?\n"); + #endif + return; + } + #endif /* BROADCAST_NTP */ + /* * "pre-configured" peers are initially assigned a socket index of * -1, which means we don't know which interface we'll use to talk *************** *** 305,310 **** --- 328,343 ---- case MODE_SYM_ACT: if (! STRMCMP(pkt->stratum, <=, sys.stratum)) { + /* + * While not strictly in the spec, pre-configured + * peers will have their reachability kept, even + * though they won't be selected. We might as well + * since we've dedicated the resources to have these + * peers be persistant. + */ + if (peer->flags & PEER_FL_CONFIG) + peer->reach |= 1; + switch (peer->mode) { case MODE_SYM_ACT: case MODE_CLIENT: *************** *** 344,350 **** --- 377,385 ---- } break; + #ifdef BROADCAST_NTP case MODE_BROADCAST: + #endif receive_MODE_BROADCAST: if (peer->flags & PEER_FL_CONFIG) break; *************** *** 424,432 **** delay = (t2 - t1) - (t3 - t4); offset = ((t2 - t1) + (t3 - t4)) / 2.0; ! delay = MAX(delay, 1.0/(1<< -sys.precision) + ! 1.0/(1<< -peer->precision) + NTP_MAXSKW); delay = MAX(delay, NTP_MINDIST); peer->valid = 0; --- 459,473 ---- delay = (t2 - t1) - (t3 - t4); offset = ((t2 - t1) + (t3 - t4)) / 2.0; ! delay += NTP_MAXSKW + 1.0/(unsigned long)(1L << -sys.precision); ! if (-peer->precision < sizeof(long)) ! delay += 1.0/(unsigned long)(1L << -peer->precision); + if (delay < 0.0) { + peer->pkt_dropped++; + return; + } + delay = MAX(delay, NTP_MINDIST); peer->valid = 0; *************** *** 778,784 **** #endif sys.peer = NULL; sys.stratum = 0; ! sys.refid = 'N'<<24 | 'O'<<16 | 'N'<<8 | 'E'; return; } --- 819,825 ---- #endif sys.peer = NULL; sys.stratum = 0; ! sys.refid = htonl('N'<<24 | 'O'<<16 | 'N'<<8 | 'E'); return; } Index: ntpd.c Prereq: 3.4.1.1 *** ntpd.c.old Wed Mar 22 18:04:36 1989 --- ntpd.c Wed Mar 22 18:04:38 1989 *************** *** 1,9 **** #ifndef lint ! static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/ntpd.c,v 3.4.1.1 89/03/20 00:12:10 louie Exp $"; #endif lint /* * $Log: ntpd.c,v $ * Revision 3.4.1.1 89/03/20 00:12:10 louie * patch1: Diddle syslog messages a bit. Handle case of udp/ntp not being * patch1: defined in /etc/services. Compute default value for tickadj if --- 1,13 ---- #ifndef lint ! static char *rcsid = "$Header: /usr/users/louie/ntp/RCS/ntpd.c,v 3.4.1.2 89/03/22 18:03:17 louie Exp Locker: louie $"; #endif lint /* * $Log: ntpd.c,v $ + * Revision 3.4.1.2 89/03/22 18:03:17 louie + * The peer->refid field was being htonl()'ed when it was already in network + * byte order. + * * Revision 3.4.1.1 89/03/20 00:12:10 louie * patch1: Diddle syslog messages a bit. Handle case of udp/ntp not being * patch1: defined in /etc/services. Compute default value for tickadj if *************** *** 231,242 **** setlogmask(LOG_UPTO(LOG_INFO)); #endif /* LOG_DAEMON */ ! syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.1 $", prog_name); syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL); #ifdef DEBUG if (debug) ! printf("%s version $Revision: 3.4.1.1 $ patchlevel %d\n", prog_name, PATCHLEVEL); #endif (void) setpriority(PRIO_PROCESS, 0, -10); --- 235,246 ---- setlogmask(LOG_UPTO(LOG_INFO)); #endif /* LOG_DAEMON */ ! syslog(LOG_NOTICE, "%s version $Revision: 3.4.1.2 $", prog_name); syslog(LOG_NOTICE, "patchlevel %d", PATCHLEVEL); #ifdef DEBUG if (debug) ! printf("%s version $Revision: 3.4.1.2 $ patchlevel %d\n", prog_name, PATCHLEVEL); #endif (void) setpriority(PRIO_PROCESS, 0, -10); *************** *** 888,901 **** } } #ifdef SETTICKADJ - #ifdef DEBUG - if (debug) { - printf("kernel vars: tickadj = %d, hz = %d, tick = %d\n", - kern_tickadj, kern_hz, kern_tick); - printf("desired tickadj = %d, dotickadj = %d\n", tickadj, - dotickadj); - } - #endif /* * If desired value of tickadj is not specified in the configuration * file, compute a "reasonable" value here, based on the assumption --- 892,897 ---- *************** *** 906,911 **** --- 902,916 ---- if (tickadj == 0 && kern_hz) tickadj = 500/kern_hz; + #ifdef DEBUG + if (debug) { + printf("kernel vars: tickadj = %d, hz = %d, tick = %d\n", + kern_tickadj, kern_hz, kern_tick); + printf("desired tickadj = %d, dotickadj = %d\n", tickadj, + dotickadj); + } + #endif + if (dotickadj && tickadj && (tickadj != kern_tickadj)) { close(kmem); if ((kmem = open(memory, O_RDWR)) >= 0) { *************** *** 1051,1057 **** cip->estdisp = htonl((long) (peer->estdisp * 1000.0)); cip->estdelay = htonl((long) (peer->estdelay * 1000.0)); cip->estoffset = htonl((long) (peer->estoffset * 1000.0)); ! cip->refid = htonl(peer->refid); cip->reftime.int_part = htonl(peer->reftime.int_part); cip->reftime.fraction = htonl(peer->reftime.fraction); --- 1056,1062 ---- cip->estdisp = htonl((long) (peer->estdisp * 1000.0)); cip->estdelay = htonl((long) (peer->estdelay * 1000.0)); cip->estoffset = htonl((long) (peer->estoffset * 1000.0)); ! cip->refid = peer->refid; cip->reftime.int_part = htonl(peer->reftime.int_part); cip->reftime.fraction = htonl(peer->reftime.fraction); Index: ntpdc.c Prereq: 3.4.1.1 *** ntpdc.c.old Wed Mar 22 18:04:43 1989 --- ntpdc.c Wed Mar 22 18:04:44 1989 *************** *** 1,9 **** #ifndef lint ! static char *RCSid = "$Header: /usr/users/louie/ntp/RCS/ntpdc.c,v 3.4.1.1 89/03/20 00:13:41 louie Exp $"; #endif /* * $Log: ntpdc.c,v $ * Revision 3.4.1.1 89/03/20 00:13:41 louie * patch1: Delete unused variables. Display interface address in numeric form * patch1: for local address, rather than symbolically. For multiple host --- 1,13 ---- #ifndef lint ! static char *RCSid = "$Header: /usr/users/louie/ntp/RCS/ntpdc.c,v 3.4.1.2 89/03/22 18:04:18 louie Exp Locker: louie $"; #endif /* * $Log: ntpdc.c,v $ + * Revision 3.4.1.2 89/03/22 18:04:18 louie + * Display dispersion in milliseconds. The peer->refid field was being ntohl()'ed + * when it should have stayed in network byte order. + * * Revision 3.4.1.1 89/03/20 00:13:41 louie * patch1: Delete unused variables. Display interface address in numeric form * patch1: for local address, rather than symbolically. For multiple host *************** *** 176,182 **** if ((cc = recvfrom(s, packet, sizeof(packet), 0, (struct sockaddr *)&from, &fromlen)) <= 0) { if (cc == 0 || errno == EINTR) ! continue; perror("recvfrom"); (void) close(s); exit(1); --- 180,186 ---- if ((cc = recvfrom(s, packet, sizeof(packet), 0, (struct sockaddr *)&from, &fromlen)) <= 0) { if (cc == 0 || errno == EINTR) ! continue; perror("recvfrom"); (void) close(s); exit(1); *************** *** 279,285 **** delay[i] = (double) ((long) (ntohl(n->info_filter.delay[i])/1000.0)); offset[i] = (double) ((long) (ntohl(n->info_filter.offset[i])/1000.0)); } ! dsp = ((long) ntohl(n->estdisp))/1000.0; del = (long) ntohl(n->estdelay); /* leave in milliseconds */ off = (long) ntohl(n->estoffset); /* leave in milliseconds */ c = ' '; --- 283,289 ---- delay[i] = (double) ((long) (ntohl(n->info_filter.delay[i])/1000.0)); offset[i] = (double) ((long) (ntohl(n->info_filter.offset[i])/1000.0)); } ! dsp = ((long) ntohl(n->estdisp)); /* leave in milliseconds */ del = (long) ntohl(n->estdelay); /* leave in milliseconds */ off = (long) ntohl(n->estoffset); /* leave in milliseconds */ c = ' '; *************** *** 310,318 **** delay[i] = (double) (long) ntohl(n->info_filter.delay[i]); offset[i] = (double) (long) ntohl(n->info_filter.offset[i]); } ! dsp = (double) ((long) ntohl(n->estdisp)) / 1000.0; ! del = (double) ((long) ntohl(n->estdelay)); ! off = (double) ((long) ntohl(n->estoffset)); printf("Neighbor address %s port:%d", inet_ntoa(sin.sin_addr), (int)ntohs(n->port)); sin.sin_addr.s_addr = n->my_address; --- 314,322 ---- delay[i] = (double) (long) ntohl(n->info_filter.delay[i]); offset[i] = (double) (long) ntohl(n->info_filter.offset[i]); } ! dsp = (double) ((long) ntohl(n->estdisp)); /* in milliseconds */ ! del = (double) ((long) ntohl(n->estdelay)); /* in milliseconds */ ! off = (double) ((long) ntohl(n->estoffset)); /* in milliseconds */ printf("Neighbor address %s port:%d", inet_ntoa(sin.sin_addr), (int)ntohs(n->port)); sin.sin_addr.s_addr = n->my_address; *************** *** 326,337 **** if (n->stratum == 1 || n->stratum == 0) { u_long TmP; - TmP = ntohl(n->refid); (void) strncpy(ref_clock, (char *) &TmP, 4); ref_clock[4] = '\0'; printf("Reference clock ID: %s", ref_clock); } else { ! clock_host.s_addr = (u_long) ntohl(n->refid); printf("Reference clock ID: [%s]", inet_ntoa(clock_host)); } printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part), --- 330,340 ---- if (n->stratum == 1 || n->stratum == 0) { u_long TmP; (void) strncpy(ref_clock, (char *) &TmP, 4); ref_clock[4] = '\0'; printf("Reference clock ID: %s", ref_clock); } else { ! clock_host.s_addr = (u_long) n->refid; printf("Reference clock ID: [%s]", inet_ntoa(clock_host)); } printf(" timestamp: %08lx.%08lx\n", ntohl(n->reftime.int_part), .