diff --git a/ChangeLog b/ChangeLog index a54d63cb..ca33cee7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +* [Bug 1483] AI_NUMERICSERV undefined in 4.2.7p20. +* Maintain and use linked list of associations (struct peer) in ntpd, + avoiding walking 128 hash table entries to iterate over peers. +* Remove more workarounds unneeded since we require ISO C90 AKA ANSI C: + - remove fallback implementations for memmove(), memset, strstr(). + - do not test for atexit() or memcpy(). +* Collapse a bunch of code duplication in ntpd/ntp_restrict.c added with + support for IPv6. +* Correct some corner case failures in automatically enabling the MRU + list if any "restrict ... limited" is in effect, and in disabling MRU + maintenance. (ntp_monitor.c, ntp_restrict.c) +* Reverse the internal sort order of the address restriction lists, but + preserve the same behavior. This allows removal of special-case code + related to the default restrictions and more straightforward lookups + of restrictions for a given address (now, stop on first match). +* Move ntp_restrict.c MRU doubly-linked list maintenance code into + ntp_lists.h macros, allowing more duplicated source excision. +* Correct Windows port's refclock_open() to return 0 on failure not -1. +* Correct CHU, dumbclock, and WWVB drivers to check for 0 returned from + refclock_open() on failure. +* Repair ntpdate.c to handle no longer testing HAVE_TIMER_SETTIME. +* Do not reference peer_node/unpeer_node after freeing when built with + --disable-saveconfig and using DNS. (4.2.7p20) 2010/02/13 Released by Harlan Stenn * [Bug 1483] hostname in ntp.conf "restrict" parameter rejected. * Use all addresses for each restrict by hostname. diff --git a/configure.ac b/configure.ac index 9ef10a8f..94bf4729 100644 --- a/configure.ac +++ b/configure.ac @@ -1319,7 +1319,6 @@ case "$ac_cv_header_kvm_h" in AC_CHECK_FUNCS(kvm_open) ;; esac -AC_CHECK_FUNCS(memcpy memmove memset) case "$host" in *-*-sco3.2v5.0.*) # Just stubs. Idiots. @@ -1381,7 +1380,7 @@ case "$host" in esac]) AC_CHECK_FUNCS(setvbuf sigaction) AC_CHECK_FUNCS(sigvec sigset sigsuspend stime strchr sysconf sysctl) -AC_CHECK_FUNCS(snprintf strdup strerror strstr) +AC_CHECK_FUNCS(snprintf strdup strerror) AC_CHECK_FUNCS(timegm) case "$host" in *-*-aix[[456]]*) diff --git a/flock-build b/flock-build index dbdf990a..1756cc4a 100755 --- a/flock-build +++ b/flock-build @@ -18,10 +18,15 @@ PARSE="--enable-parse-clocks" #PARSE= STD="--enable-simulator" -case "$SIMUL" in - '') PARALLEL_BUILDS=1 - ;; - *) PARALLEL_BUILDS=$SIMUL +case "$SIMUL::$FB_FIRSTONLY" in + ::*) + PARALLEL_BUILDS=1 + ;; + *::0) + PARALLEL_BUILDS=$SIMUL + ;; + *) + PARALLEL_BUILDS=1 esac case "$PARALLEL_BUILDS" in @@ -63,19 +68,19 @@ do [ -f .buildkey-$i ] && SKIPTHIS=1 case "$SKIPTHIS" in 1) - echo flock-build running on $i? check LIST, skipping - ;; - 0) - echo $i - echo $SIG > .buildkey-$i - case "1" in - 0) - ssh $i "cd $c_d ; ./build $SIG $PARSE $STD $BUILD_ARGS" & - ssh $i "cd $c_d ; ./build $SIG $PARSE $STD --without-crypto $BUILD_ARGS" & - ssh $i "cd $c_d ; ./build $SIG $STD --disable-all-clocks $BUILD_ARGS" & - ;; - 1) - cat > .flockbuild-$i-$SIG <<-ENDQUOT + echo flock-build running on $i? check LIST, skipping + ;; + 0) + echo $i + echo $SIG > .buildkey-$i + case "1" in + 0) + ssh $i "cd $c_d ; ./build $SIG $PARSE $STD $BUILD_ARGS" & + ssh $i "cd $c_d ; ./build $SIG $PARSE $STD --without-crypto $BUILD_ARGS" & + ssh $i "cd $c_d ; ./build $SIG $STD --disable-all-clocks $BUILD_ARGS" & + ;; + 1) + cat > .flockbuild-$i-$SIG <<-ENDQUOT #!/bin/sh # script uses job control and expects to be invoked @@ -114,10 +119,10 @@ do echo \`date -u '+%H:%M:%S'\` $i flock-build $c_d done. rm .buildkey-$i ENDQUOT - chmod +x .flockbuild-$i-$SIG - ssh -tt $i "$c_d/.flockbuild-$i-$SIG ; \ - rm $c_d/.flockbuild-$i-$SIG" 2>/dev/null & - esac + chmod +x .flockbuild-$i-$SIG + ssh -tt $i "$c_d/.flockbuild-$i-$SIG ; \ + rm $c_d/.flockbuild-$i-$SIG" 2>/dev/null & + esac esac done echo `date -u '+%H:%M:%S'` flock-build launched diff --git a/include/ntp.h b/include/ntp.h index b60523af..e823339e 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -4,10 +4,12 @@ #ifndef NTP_H #define NTP_H +#include #include #include #include +#include #include #ifdef OPENSSL #include @@ -246,8 +248,9 @@ struct interface { * spec. */ struct peer { - struct peer *next; /* link pointer in peer hash */ - struct peer *ass_next; /* link pointer in associd hash */ + struct peer *p_link; /* link pointer in free & peer lists */ + struct peer *adr_link; /* link pointer in address hash */ + struct peer *aid_link; /* link pointer in associd hash */ struct peer *ilink; /* list of peers for interface */ sockaddr_u srcadr; /* address of remote host */ struct interface *dstadr; /* local address (interface) */ @@ -572,10 +575,11 @@ struct pkt { #define PKT_LEAP(li_vn_mode) ((u_char)(((li_vn_mode) >> 6) & 0x3)) /* - * Stuff for putting things back into li_vn_mode + * Stuff for putting things back into li_vn_mode in packets and vn_mode + * in ntp_monitor.c's mon_entry. */ -#define PKT_LI_VN_MODE(li, vn, md) \ - ((u_char)((((li) << 6) & 0xc0) | (((vn) << 3) & 0x38) | ((md) & 0x7))) +#define VN_MODE(v, m) ((((v) & 7) << 3) | ((m) & 0x7)) +#define PKT_LI_VN_MODE(l, v, m) ((((l) & 3) << 6) | VN_MODE((v), (m))) /* @@ -735,21 +739,20 @@ struct pkt { /* * Structure used optionally for monitoring when this is turned on. */ +typedef struct mon_data mon_entry; struct mon_data { - struct mon_data *hash_next; /* next structure in hash list */ - struct mon_data *mru_next; /* next structure in MRU list */ - struct mon_data *mru_prev; /* previous structure in MRU list */ - int flags; /* restrict flags */ - int leak; /* leaky bucket accumulator */ - int count; /* total packet count */ - u_long firsttime; /* first time found */ - u_long lasttime; /* last time found */ - sockaddr_u rmtadr; /* address of remote host */ - struct interface *interface; /* interface on which this arrived */ - u_short rmtport; /* remote port last came from */ - u_char mode; /* packet mode */ - u_char version; /* packet version */ - u_char cast_flags; /* flags MDF_?CAST */ + mon_entry * hash_next; /* next structure in hash list */ + DECL_DLIST_LINK(mon_entry, mru);/* MRU list link pointers */ + struct interface * lcladr; /* address on which this arrived */ + sockaddr_u rmtadr; /* address of remote host */ + int flags; /* restrict flags */ + int leak; /* leaky bucket accumulator */ + int count; /* total packet count */ + u_long firsttime; /* first time found */ + u_long lasttime; /* last time found */ + u_short rmtport; /* remote port last came from */ + u_char vn_mode; /* packet mode & version */ + u_char cast_flags; /* flags MDF_?CAST */ }; /* @@ -758,38 +761,46 @@ struct mon_data { #define MDF_UCAST 0x01 /* unicast */ #define MDF_MCAST 0x02 /* multicast */ #define MDF_BCAST 0x04 /* broadcast */ -#define MDF_LCAST 0x08 /* localcast */ +#define MDF_LCAST 0x08 /* localcast (unused) */ #define MDF_ACAST 0x10 /* manycast */ #define MDF_BCLNT 0x20 /* broadcast client */ #define MDF_ACLNT 0x40 /* manycast client */ - +/* server *cast mode bits */ +#define MDF_SRVCASTMASK (MDF_MCAST | MDF_BCAST | MDF_ACAST) /* * Values used with mon_enabled to indicate reason for enabling monitoring */ -#define MON_OFF 0x00 /* no monitoring */ -#define MON_ON 0x01 /* monitoring explicitly enabled */ -#define MON_RES 0x02 /* implicit monitoring for RES_LIMITED */ +#define MON_OFF 0x00 /* no monitoring */ +#define MON_ON 0x01 /* monitoring explicitly enabled */ +#define MON_RES 0x02 /* implicit monitoring for RES_LIMITED */ /* * Structure used for restrictlist entries */ -struct restrictlist { - struct restrictlist *next; /* link to next entry */ - u_int32 addr; /* Ipv4 host address (host byte order) */ - u_int32 mask; /* Ipv4 mask for address (host byte order) */ - u_long count; /* number of packets matched */ - u_short flags; /* accesslist flags */ - u_short mflags; /* match flags */ -}; - -struct restrictlist6 { - struct restrictlist6 *next; /* link to next entry */ - struct in6_addr addr6; /* Ipv6 host address */ - struct in6_addr mask6; /* Ipv6 mask address */ - u_long count; /* number of packets matched */ - u_short flags; /* accesslist flags */ - u_short mflags; /* match flags */ +typedef struct res_addr4_tag { + u_int32 addr; /* IPv4 addr (host order) */ + u_int32 mask; /* IPv4 mask (host order) */ +} res_addr4; + +typedef struct res_addr6_tag { + struct in6_addr addr; /* IPv6 addr (net order) */ + struct in6_addr mask; /* IPv6 mask (net order) */ +} res_addr6; + +typedef struct restrict_u_tag restrict_u; +struct restrict_u_tag { + restrict_u * link; /* link to next entry */ + u_int32 count; /* number of packets matched */ + u_short flags; /* accesslist flags */ + u_short mflags; /* match flags */ + union { /* variant starting here */ + res_addr4 v4; + res_addr6 v6; + } u; }; - +#define V4_SIZEOF_RESTRICT_U (offsetof(restrict_u, u) \ + + sizeof(res_addr4)) +#define V6_SIZEOF_RESTRICT_U (offsetof(restrict_u, u) \ + + sizeof(res_addr6)) /* * Access flags @@ -813,10 +824,10 @@ struct restrictlist6 { #define RES_MSSNTP 0x0800 /* enable MS-SNTP authentication */ #define RES_TIMEOUT 0x1000 /* timeout this entry */ -#define RES_ALLFLAGS (RES_FLAGS | RES_NOQUERY |\ - RES_NOMODIFY | RES_NOTRAP |\ - RES_LPTRAP | RES_KOD |\ - RES_MSSNTP | RES_TIMEOUT) +#define RES_ALLFLAGS (RES_FLAGS | RES_NOQUERY | \ + RES_NOMODIFY | RES_NOTRAP | \ + RES_LPTRAP | RES_KOD | \ + RES_MSSNTP | RES_TIMEOUT) /* * Match flags @@ -830,7 +841,7 @@ struct restrictlist6 { #define RESTRICT_FLAGS 1 /* add flags to restrict entry */ #define RESTRICT_UNFLAG 2 /* remove flags from restrict entry */ #define RESTRICT_REMOVE 3 /* remove a restrict entry */ -#define RESTRICT_REMOVEIF 4 /* remove an interface restrict entry */ +#define RESTRICT_REMOVEIF 4 /* remove an interface restrict entry */ /* * Endpoint structure for the select algorithm diff --git a/include/ntp_config.h b/include/ntp_config.h index af21cdd4..1539828a 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -64,14 +64,15 @@ /* Structure for storing an attribute-value pair */ struct attr_val { - int attr; - union val{ - double d; - int i; - char *s; - void *p; - } value; - int type; + int attr; + union val{ + double d; + int i; + u_int u; + char *s; + void *p; + } value; + int type; }; /* Structure for nodes on the syntax tree */ @@ -88,19 +89,19 @@ struct restrict_node { }; struct peer_node { - int host_mode; - struct address_node *addr; - queue *peerflags; - int minpoll; - int maxpoll; - int ttl; - int peerversion; - int peerkey; - double bias; + int host_mode; + struct address_node *addr; + queue *peerflags; + u_char minpoll; + u_char maxpoll; + u_char ttl; + u_char peerversion; + keyid_t peerkey; + double bias; }; struct unpeer_node { - u_int assocID; + associd_t assocID; struct address_node * addr; }; diff --git a/include/ntp_crypto.h b/include/ntp_crypto.h index 80e3fb11..9fc4cda5 100644 --- a/include/ntp_crypto.h +++ b/include/ntp_crypto.h @@ -124,7 +124,7 @@ struct value { /* network byte order */ tstamp_t tstamp; /* timestamp */ tstamp_t fstamp; /* filestamp */ u_int32 vallen; /* value length */ - u_char *ptr; /* data pointer (various) */ + void *ptr; /* data pointer (various) */ u_int32 siglen; /* signature length */ u_char *sig; /* signature */ }; diff --git a/include/ntp_lists.h b/include/ntp_lists.h index 218b8fe4..06609029 100644 --- a/include/ntp_lists.h +++ b/include/ntp_lists.h @@ -1,5 +1,8 @@ /* - * ntp_lists.h - singly-linked lists common code + * ntp_lists.h - linked lists common code + * + * SLIST: singly-linked lists + * ========================== * * These macros implement a simple singly-linked list template. Both * the listhead and per-entry next fields are declared as pointers to @@ -19,6 +22,13 @@ * LINK_TAIL_SLIST(listhead, pentry, nextlink, entrytype) * add entry at tail * + * LINK_SORT_SLIST(listhead, pentry, beforecur, nextlink, entrytype) + * add entry in sorted order. beforecur is an expression comparing + * pentry with the current list entry. The current entry can be + * referenced within beforecur as L_S_S_CUR(), which is short for + * LINK_SORT_SLIST_CUR(). beforecur is nonzero if pentry sorts + * before L_S_S_CUR(). + * * UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) * unlink first entry and point punlinked to it, or set punlinked * to NULL if the list is empty. @@ -30,16 +40,29 @@ * * UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, entrytype) * unlink entry where expression expr is nonzero. expr can refer - * to the entry being tested using UNLINK_EXPR_SLIST_CURRENT(). - * See the implementation of UNLINK_SLIST() below for an example. + * to the entry being tested using UNLINK_EXPR_SLIST_CURRENT(), + * alias U_E_S_CUR(). See the implementation of UNLINK_SLIST() + * below for an example. * punlinked is pointed to the removed entry or NULL if none * satisfy expr. + * + * DLIST: doubly-linked lists + * ========================== + * + * Elements on DLISTs always have non-NULL forward and back links, + * because both link chains are circular. The beginning/end is marked + * by the listhead, which is the same type as elements for simplicity. + * An empty list's listhead has both links set to its own address. + * + * */ #ifndef NTP_LISTS_H #define NTP_LISTS_H -#include - +#ifndef TRUE +# define TRUE 1 +# define NTP_LISTS_UNDEF_TRUE +#endif #define LINK_SLIST(listhead, pentry, nextlink) \ do { \ @@ -59,6 +82,30 @@ do { \ *pptail = (pentry); \ } while (0) +#define LINK_SORT_SLIST_CURRENT() (*ppentry) +#define L_S_S_CUR() LINK_SORT_SLIST_CURRENT() + +#define LINK_SORT_SLIST(listhead, pentry, beforecur, nextlink, \ + entrytype) \ +do { \ + entrytype **ppentry; \ + \ + ppentry = &(listhead); \ + while (*ppentry != NULL) { \ + if (beforecur) { \ + (pentry)->nextlink = *ppentry; \ + *ppentry = (pentry); \ + break; \ + } \ + ppentry = &((*ppentry)->nextlink); \ + if (NULL == *ppentry) { \ + (pentry)->nextlink = NULL; \ + *ppentry = (pentry); \ + break; \ + } \ + } \ +} while (0) + #define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \ do { \ (punlinked) = (listhead); \ @@ -68,6 +115,9 @@ do { \ } \ } while (0) +#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry) +#define U_E_S_CUR() UNLINK_EXPR_SLIST_CURRENT() + #define UNLINK_EXPR_SLIST(punlinked, listhead, expr, nextlink, \ entrytype) \ do { \ @@ -90,11 +140,73 @@ do { \ } else \ (punlinked) = NULL; \ } while (0) -#define UNLINK_EXPR_SLIST_CURRENT() (*ppentry) #define UNLINK_SLIST(punlinked, listhead, ptounlink, nextlink, \ entrytype) \ UNLINK_EXPR_SLIST(punlinked, listhead, (ptounlink) == \ - UNLINK_EXPR_SLIST_CURRENT(), nextlink, entrytype) + U_E_S_CUR(), nextlink, entrytype) + +/* + * DLIST + */ +#define DECL_DLIST_LINK(entrytype, link) \ +struct { \ + entrytype * b; \ + entrytype * f; \ +} link + +#define INIT_DLIST(listhead, link) \ +do { \ + (listhead).link.f = &(listhead); \ + (listhead).link.b = &(listhead); \ +} while (0) + +#define HEAD_DLIST(listhead, link) \ + ( \ + (&(listhead) != (listhead).link.f) \ + ? (listhead).link.f \ + : NULL \ + ) + +#define TAIL_DLIST(listhead, link) \ + ( \ + (&(listhead) != (listhead).link.b) \ + ? (listhead).link.b \ + : NULL \ + ) + +#define LINK_DLIST(listhead, pentry, link) \ +do { \ + (pentry)->link.f = (listhead).link.f; \ + (pentry)->link.b = &(listhead); \ + (listhead).link.f->link.b = (pentry); \ + (listhead).link.f = (pentry); \ +} while (0) + +#define UNLINK_DLIST(punlink, link) \ +do { \ + (punlink)->link.b->link.f = (punlink)->link.f; \ + (punlink)->link.f->link.b = (punlink)->link.b; \ + (punlink)->link.b = NULL; \ + (punlink)->link.f = NULL; \ +} while (0) + +#define ITER_DLIST_BEGIN(listhead, iter, link, entrytype) \ +{ \ + entrytype *i_dl_next; \ + \ + for ((iter) = (listhead).link.f; \ + (iter) != &(listhead) \ + && ((i_dl_next = (iter)->link.f), TRUE); \ + (iter) = i_dl_next) { + +#define ITER_DLIST_END() \ + } \ +} + + +#ifdef NTP_LISTS_UNDEF_TRUE +# undef TRUE +#endif #endif /* NTP_LISTS_H */ diff --git a/include/ntp_net.h b/include/ntp_net.h index 9cfebe1c..ea5cbdaf 100644 --- a/include/ntp_net.h +++ b/include/ntp_net.h @@ -110,7 +110,7 @@ typedef union { /* blast a byte value across sockaddr_u v6 address */ #define MEMSET_ADDR6(psau, v) \ - memset((void *)(psau)->sa6.sin6_addr.s6_addr, (v), \ + memset((psau)->sa6.sin6_addr.s6_addr, (v), \ sizeof((psau)->sa6.sin6_addr.s6_addr)) #define SET_ONESMASK(psau) \ @@ -129,18 +129,29 @@ typedef union { SET_ONESMASK(psau); \ } while (0) -/* compare a in6_addr with socket address */ +/* + * compare two in6_addr returning negative, 0, or positive. + * ADDR6_CMP is negative if *pin6A is lower than *pin6B, zero if they + * are equal, positive if *pin6A is higher than *pin6B. IN6ADDR_ANY + * is the lowest address (128 zero bits). + */ +#define ADDR6_CMP(pin6A, pin6B) \ + memcmp((pin6A)->s6_addr, (pin6B)->s6_addr, \ + sizeof(pin6A)->s6_addr) + +/* compare two in6_addr for equality only */ #if !defined(SYS_WINNT) || !defined(in_addr6) -#define S_ADDR6_EQ(psau, my_in6_addr) \ - (!memcmp(&(psau)->sa6.sin6_addr, \ - (my_in6_addr), \ - sizeof((psau)->sa6.sin6_addr))) +#define ADDR6_EQ(pin6A, pin6B) \ + (!ADDR6_CMP(pin6A, pin6B)) #else -#define S_ADDR6_EQ(psau, my_in6_addr) \ - IN6_ADDR_EQUAL(&(psau)->sa6.sin6_addr, \ - (my_in6_addr)) +#define ADDR6_EQ(pin6A, pin6B) \ + IN6_ADDR_EQUAL(pin6A, pin6B) #endif +/* compare a in6_addr with socket address */ +#define S_ADDR6_EQ(psau, pin6) \ + ADDR6_EQ(&(psau)->sa6.sin6_addr, pin6) + /* are two sockaddr_u's addresses equal? */ #define SOCK_EQ(psau1, psau2) \ ((AF(psau1) != AF(psau2)) \ diff --git a/include/ntp_rfc2553.h b/include/ntp_rfc2553.h index b064658a..63241832 100644 --- a/include/ntp_rfc2553.h +++ b/include/ntp_rfc2553.h @@ -150,7 +150,15 @@ struct sockaddr_storage { #endif /* !AI_PASSIVE */ #ifndef AI_NUMERICHOST /* such as AIX 4.3 */ -#define AI_NUMERICHOST 0 +# define Z_AI_NUMERICHOST 0 +#else +# define Z_AI_NUMERICHOST AI_NUMERICHOST +#endif + +#ifndef AI_NUMERICSERV /* not in RFC 2553 */ +# define Z_AI_NUMERICSERV 0 +#else +# define Z_AI_NUMERICSERV AI_NUMERICSERV #endif #ifndef ISC_PLATFORM_HAVEIPV6 diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index 2340bac1..f88965eb 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -102,10 +102,6 @@ extern sockaddr_u * netof (sockaddr_u *); extern char * numtoa (u_int32); extern char * numtohost (u_int32); extern char * socktoa (sockaddr_u *); -#define localaddrtoa(pif) ((NULL == (pif)) \ - ? "" \ - : socktoa(&((pif)->sin))) -#define latoa(pif) localaddrtoa(pif) extern char * socktohost (sockaddr_u *); extern int octtoint (const char *, u_long *); extern u_long ranp2 (int); diff --git a/include/ntp_string.h b/include/ntp_string.h index b9680243..9b62ec2d 100644 --- a/include/ntp_string.h +++ b/include/ntp_string.h @@ -1,5 +1,5 @@ /* - * Define string ops: strchr strrchr memcmp memmove memset + * Define string ops: strchr strrchr memcmp memmove memset */ #ifndef NTP_STRING_H @@ -17,20 +17,6 @@ # include #endif -#ifndef STDC_HEADERS -# ifndef HAVE_STRCHR -# include -# define strchr index -# define strrchr rindex -# endif -# ifndef __GNUC__ -char *strchr(), *strrchr(); -# endif -# ifndef HAVE_MEMCPY -# define NTP_NEED_BOPS -# endif -#endif /* STDC_HEADERS */ - #ifdef NTP_NEED_BOPS #ifdef HAVE_STRINGS_H diff --git a/include/ntp_types.h b/include/ntp_types.h index 51e1b241..ed9b23e9 100644 --- a/include/ntp_types.h +++ b/include/ntp_types.h @@ -80,8 +80,10 @@ typedef u_int32 ntp_u_int32_t; typedef struct ntp_uint64_t { u_int32 val[2]; } ntp_uint64_t; -typedef unsigned short associd_t; /* association ID */ +typedef u_short associd_t; /* association ID */ +#define ASSOCID_MAX USHRT_MAX typedef u_int32 keyid_t; /* cryptographic key ID */ +#define KEYID_T_MAX (0xffffffff) typedef u_int32 tstamp_t; /* NTP seconds timestamp */ /* diff --git a/include/ntpd.h b/include/ntpd.h index a83d8e76..a720d9bd 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -1,5 +1,11 @@ /* - * ntpd.h - Prototypes for ntpd. + * ntpd.h - Prototypes and external variables for ntpd. + * + * Note the first half is primarily function prototypes, type + * declarations, and preprocessor macros, with variables declared + * primarily in the second half. + * + * Each half is further divided into sections for each source file. */ #include "ntp_syslog.h" @@ -12,6 +18,12 @@ #include "ntp_workimpl.h" #include "recvbuff.h" +/* + * First half: ntpd types, functions, macros + * ----------------------------------------- + */ + + /* ntp_config.c */ #define TAI_1972 10 /* initial TAI offset (s) */ @@ -100,8 +112,6 @@ typedef struct interface_info { typedef void (*interface_receiver_t) (void *, interface_info_t *); -extern int disable_dynamic_updates; - extern void interface_enumerate (interface_receiver_t, void *); extern struct interface *findinterface (sockaddr_u *); extern struct interface *findbcastinter(sockaddr_u *); @@ -128,12 +138,14 @@ extern void collect_timing (struct recvbuf *, const char *, int, l_fp *); extern void wait_for_signal (void); extern void unblock_io_and_alarm (void); extern void block_io_and_alarm (void); -#define UNBLOCK_IO_AND_ALARM() unblock_io_and_alarm() -#define BLOCK_IO_AND_ALARM() block_io_and_alarm() +# define UNBLOCK_IO_AND_ALARM() unblock_io_and_alarm() +# define BLOCK_IO_AND_ALARM() block_io_and_alarm() #else -#define UNBLOCK_IO_AND_ALARM() -#define BLOCK_IO_AND_ALARM() +# define UNBLOCK_IO_AND_ALARM() do {} while (0) +# define BLOCK_IO_AND_ALARM() do {} while (0) #endif +extern char * localaddrtoa(struct interface *); +#define latoa(pif) localaddrtoa(pif) /* ntp_loopfilter.c */ extern void init_loopfilter(void); @@ -148,25 +160,31 @@ extern u_int sys_tai; extern void init_mon (void); extern void mon_start (int); extern void mon_stop (int); -extern int ntp_monitor (struct recvbuf *, int); -extern void ntp_monclearinterface (struct interface *interface); +extern int ntp_monitor (struct recvbuf *, int); +extern void mon_clearinterface(struct interface *interface); /* ntp_peer.c */ extern void init_peer (void); -extern struct peer *findexistingpeer (sockaddr_u *, struct peer *, int); -extern struct peer *findpeer (sockaddr_u *, struct interface *, int, int *); -extern struct peer *findpeerbyassoc (u_int); -extern void set_peerdstadr (struct peer *peer, struct interface *interface); -extern struct peer *newpeer (sockaddr_u *, struct interface *, int, int, int, int, u_int, u_char, int, keyid_t); +extern struct peer *findexistingpeer(sockaddr_u *, struct peer *, int); +extern struct peer *findpeer (sockaddr_u *, struct interface *, int, + int *); +extern struct peer *findpeerbyassoc(associd_t); +extern void set_peerdstadr (struct peer *peer, + struct interface *interface); +extern struct peer *newpeer (sockaddr_u *, struct interface *, + u_char, u_char, u_char, u_char, u_int, + u_char, u_char, keyid_t); extern void peer_all_reset (void); extern void peer_clr_stats (void); -extern struct peer *peer_config (sockaddr_u *, struct interface *, int, int, int, int, u_int, int, keyid_t, u_char *); +extern struct peer *peer_config(sockaddr_u *, struct interface *, + u_char, u_char, u_char, u_char, u_int, + u_char, keyid_t, u_char *); extern void peer_reset (struct peer *); -extern void refresh_all_peerinterfaces (void); +extern void refresh_all_peerinterfaces(void); extern void unpeer (struct peer *); extern void clear_all (void); extern int score_all (struct peer *); -extern struct peer *findmanycastpeer (struct recvbuf *); +extern struct peer *findmanycastpeer(struct recvbuf *); /* ntp_crypto.c */ #ifdef OPENSSL @@ -210,13 +228,7 @@ extern int sys_orphan; extern double sys_mindisp; extern double sys_maxdist; -/* - * there seems to be a bug in the IRIX 4 compiler which prevents - * u_char from beeing used in prototyped functions. - * This is also true AIX compiler. - * So give up and define it to be int. WLJ - */ -extern void poll_update (struct peer *, int); +extern void poll_update (struct peer *, u_char); extern void clear (struct peer *); extern void clock_filter (struct peer *, double, double, double); @@ -224,8 +236,8 @@ extern void init_proto (void); extern void proto_config (int, u_long, double, sockaddr_u *); extern void proto_clr_stats (void); -#ifdef REFCLOCK /* ntp_refclock.c */ +#ifdef REFCLOCK extern int refclock_newpeer (struct peer *); extern void refclock_unpeer (struct peer *); extern void refclock_receive (struct peer *); @@ -240,7 +252,8 @@ extern void process_private (struct recvbuf *, int); /* ntp_restrict.c */ extern void init_restrict (void); extern int restrictions (sockaddr_u *); -extern void hack_restrict (int, sockaddr_u *, sockaddr_u *, int, int); +extern void hack_restrict (int, sockaddr_u *, sockaddr_u *, + u_short, u_short); /* ntp_timer.c */ extern void init_timer (void); @@ -292,8 +305,10 @@ extern void parse_cmdline_opts(int *, char ***); /* - * Variable declarations for ntpd. + * Last half: ntpd variables + * ------------------------- */ + /* ntp_config.c */ extern char const * progname; extern char *sys_phone[]; /* ACTS phone numbers */ @@ -352,19 +367,14 @@ extern volatile u_long handler_calls; /* number of calls to interrupt handler */ extern volatile u_long handler_pkts; /* number of pkts received by handler */ extern u_long io_timereset; /* time counters were reset */ -/* - * Interface stuff - */ +/* ntp_io.c */ +extern int disable_dynamic_updates; +extern fd_set activefds; +extern int maxactivefd; extern struct interface *any_interface; /* default ipv4 interface */ extern struct interface *any6_interface;/* default ipv6 interface */ extern struct interface *loopback_interface; /* loopback interface */ -/* - * File descriptor masks etc. for call to select - */ -extern fd_set activefds; -extern int maxactivefd; - /* ntp_loopfilter.c */ extern double drift_comp; /* clock frequency (s/s) */ extern double clock_stability; /* clock stability (s/s) */ @@ -404,16 +414,18 @@ extern double sys_offset; /* system offset (s) */ extern double sys_jitter; /* system jitter (s) */ /* ntp_monitor.c */ -extern struct mon_data mon_mru_list; -extern struct mon_data mon_fifo_list; +extern mon_entry mon_mru_list; +extern mon_entry mon_fifo_list; extern int mon_enabled; /* ntp_peer.c */ -extern struct peer *peer_hash[]; /* peer hash table */ -extern int peer_hash_count[]; /* count of peers in each bucket */ -extern struct peer *assoc_hash[]; /* association ID hash table */ -extern int assoc_hash_count[]; -extern int peer_free_count; +extern struct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */ +extern int peer_hash_count[NTP_HASH_SIZE]; /* count of in each bucket */ +extern struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */ +extern int assoc_hash_count[NTP_HASH_SIZE];/* count of in each bucket */ +extern struct peer *peer_list; /* peer structures list */ +extern int peer_count; /* count in peer_list */ +extern int peer_free_count; /* count in peer_free */ /* * Miscellaneous statistic counters which may be queried. @@ -426,6 +438,7 @@ extern u_long peer_demobilizations; /* number of structs freed to free list */ extern int total_peer_structs; /* number of peer structs in circulation */ extern int peer_associations; /* mobilized associations */ extern int peer_preempt; /* preemptable associations */ + /* ntp_proto.c */ /* * System variables are declared here. See Section 3.2 of the @@ -447,6 +460,7 @@ extern int sys_bclient; /* we set our time to broadcasts */ extern double sys_bdelay; /* broadcast client default delay */ extern int sys_authenticate; /* requre authentication for config */ extern l_fp sys_authdelay; /* authentication delay */ +extern u_long sys_epoch; /* last clock update time */ extern keyid_t sys_private; /* private value for session seed */ extern int sys_manycastserver; /* respond to manycast client pkts */ extern int sys_minclock; /* minimum survivors */ @@ -483,11 +497,17 @@ extern int fdpps; /* pps file descriptor */ extern keyid_t info_auth_keyid; /* keyid used to authenticate requests */ /* ntp_restrict.c */ -extern struct restrictlist *restrictlist; /* the ipv4 restriction list */ -extern struct restrictlist6 *restrictlist6; /* the ipv6 restriction list */ -extern int ntp_minpkt; -extern int ntp_minpoll; -extern int mon_age; /* monitor preempt age */ +extern restrict_u * restrictlist4; /* IPv4 restriction list */ +extern restrict_u * restrictlist6; /* IPv6 restriction list */ +extern int ntp_minpkt; +extern u_char ntp_minpoll; +extern int mon_age; /* monitor preempt age */ + +/* ntp_signd.c */ +#ifdef HAVE_NTP_SIGND +extern void send_via_ntp_signd(struct recvbuf, int, keyid_t, int, + struct pkt *); +#endif /* ntp_timer.c */ extern volatile int alarm_flag; /* alarm flag */ @@ -525,20 +545,14 @@ extern char *group; /* group to switch to */ extern const char *chrootdir; /* directory to chroot() to */ #endif +/* ntservice.c */ +#ifdef SYS_WINNT +extern int accept_wildcard_if_for_winnt; +#endif + /* refclock_conf.c */ #ifdef REFCLOCK extern struct refclock *refclock_conf[]; /* refclock configuration table */ extern u_char num_refclock_conf; #endif -/* ntp_signd.c */ -#ifdef HAVE_NTP_SIGND -extern void -send_via_ntp_signd( - struct recvbuf *rbufp, /* receive packet pointer */ - int xmode, - keyid_t xkeyid, - int flags, - struct pkt *xpkt - ); -#endif diff --git a/libntp/Makefile.am b/libntp/Makefile.am index a4797210..11bdc361 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -38,7 +38,6 @@ libntp_a_SRCS = \ iosignal.c \ lib_strbuf.c \ machines.c \ - memmove.c \ mfptoa.c \ ntp_lineedit.c \ mfptoms.c \ @@ -62,7 +61,6 @@ libntp_a_SRCS = \ ssl_init.c \ statestr.c \ strdup.c \ - strstr.c \ syssignal.c \ tsftomsu.c \ tstotv.c \ diff --git a/libntp/decodenetnum.c b/libntp/decodenetnum.c index 1ce98ae8..814456c1 100644 --- a/libntp/decodenetnum.c +++ b/libntp/decodenetnum.c @@ -40,7 +40,7 @@ decodenetnum( cp = name; } memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_NUMERICHOST; + hints.ai_flags = Z_AI_NUMERICHOST; err = getaddrinfo(cp, NULL, &hints, &ai); if (err != 0) return 0; diff --git a/libntp/machines.c b/libntp/machines.c index 45013804..b31a9e15 100644 --- a/libntp/machines.c +++ b/libntp/machines.c @@ -548,16 +548,3 @@ getpass(const char * prompt) return password; } #endif /* SYS_WINNT */ - -#if !defined(HAVE_MEMSET) -void -ntp_memset( - char *a, - int x, - int c - ) -{ - while (c-- > 0) - *a++ = (char) x; -} -#endif /*POSIX*/ diff --git a/libntp/memmove.c b/libntp/memmove.c deleted file mode 100644 index 8ccc4b1b..00000000 --- a/libntp/memmove.c +++ /dev/null @@ -1,140 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifndef HAVE_MEMMOVE -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include - -#include "l_stdlib.h" - -/* - * sizeof(word) MUST BE A POWER OF TWO - * SO THAT wmask BELOW IS ALL ONES - */ -typedef int word; /* "word" used for optimal copy speed */ - -#define wsize sizeof(word) -#define wmask (wsize - 1) - -/* - * Copy a block of memory, handling overlap. - * This is the routine that actually implements - * (the portable versions of) bcopy, memcpy, and memmove. - */ -void * -memmove( - void *dst0, - const void *src0, - register size_t length - ) -{ - register char *dst = dst0; - register const char *src = src0; - register size_t t; - - if (length == 0 || dst == src) /* nothing to do */ - goto done; - - /* - * Macros: loop-t-times; and loop-t-times, t>0 - */ -#define TLOOP(s) if (t) TLOOP1(s) -#define TLOOP1(s) do { s; } while (--t) - - if ((unsigned long)dst < (unsigned long)src) { - /* - * Copy forward. - */ - t = (int)src; /* only need low bits */ - if ((t | (int)dst) & wmask) { - /* - * Try to align operands. This cannot be done - * unless the low bits match. - */ - if ((t ^ (int)dst) & wmask || length < wsize) - t = length; - else - t = wsize - (t & wmask); - length -= t; - TLOOP1(*dst++ = *src++); - } - /* - * Copy whole words, then mop up any trailing bytes. - */ - t = length / wsize; - TLOOP(*(word *)dst = *(const word *)src; src += wsize; - dst += wsize); - t = length & wmask; - TLOOP(*dst++ = *src++); - } else { - /* - * Copy backwards. Otherwise essentially the same. - * Alignment works as before, except that it takes - * (t&wmask) bytes to align, not wsize-(t&wmask). - */ - src += length; - dst += length; - t = (int)src; - if ((t | (int)dst) & wmask) { - if ((t ^ (int)dst) & wmask || length <= wsize) - t = length; - else - t &= wmask; - length -= t; - TLOOP1(*--dst = *--src); - } - t = length / wsize; - TLOOP(src -= wsize; dst -= wsize; - *(word *)dst = *(const word *)src); - t = length & wmask; - TLOOP(*--dst = *--src); - } - done: - return (dst0); -} -#else -int memmove_bs; -#endif diff --git a/libntp/strdup.c b/libntp/strdup.c index 7d23d7e5..f7565a2f 100644 --- a/libntp/strdup.c +++ b/libntp/strdup.c @@ -1,9 +1,9 @@ #include -#include "ntp_malloc.h" -#if !HAVE_STRDUP +#include +#include "ntp_malloc.h" -#define NULL 0 +#ifndef HAVE_STRDUP char *strdup(const char *s); @@ -12,18 +12,19 @@ strdup( const char *s ) { - char *cp; + size_t octets; + char * cp; + + if (s) { + octets = 1 + strlen(s); + cp = malloc(octets); + if (NULL != cp) + memcpy(cp, s, octets); + else + cp = NULL; - if (s) { - cp = (char *) malloc((unsigned) (strlen(s)+1)); - if (cp) { - (void) strcpy(cp, s); - } - } else { - cp = (char *) NULL; - } - return(cp); + return(cp); } #else -int strdup_bs; +int strdup_c_nonempty_compilation_unit; #endif diff --git a/libntp/strstr.c b/libntp/strstr.c deleted file mode 100644 index a4deb870..00000000 --- a/libntp/strstr.c +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#if !HAVE_STRSTR - -/* - * Amanda, The Advanced Maryland Automatic Network Disk Archiver - * Copyright (c) 1991-1998 University of Maryland at College Park - * All Rights Reserved. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of U.M. not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. U.M. makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * U.M. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL U.M. - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: James da Silva, Systems Design and Analysis Group - * Computer Science Department - * University of Maryland at College Park - */ -/* - * $Id$ - * - * replacement for missing ANSI-C strstr function - */ - -char *strstr(a, b) -char *a, *b; -{ - int alen, blen, i; - - alen = strlen(a); - blen = strlen(b); - - for(i=0; i <= alen-blen; i++, a++) - if(strncmp(a, b, blen) == 0) return a; - - return NULL; -} -#else -int strstr_bs; -#endif diff --git a/ntpd/Makefile.am b/ntpd/Makefile.am index 69dd7077..e299251e 100644 --- a/ntpd/Makefile.am +++ b/ntpd/Makefile.am @@ -136,7 +136,6 @@ check-local: @MAKE_CHECK_Y2K@ $(CHECK_SAVECONFIG) ntpd_SOURCES = \ cmd_args.c \ ntp_config.c \ - ntp_data_structures.c \ ntp_keyword.h \ ntp_io.c \ ntp_parser.y \ @@ -158,6 +157,7 @@ libntpd_a_SOURCES = \ jupiter.h \ ntp_control.c \ ntp_crypto.c \ + ntp_data_structures.c \ ntp_filegen.c \ ntp_intres.c \ ntp_loopfilter.c \ diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index da3b7e31..186006be 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -91,6 +91,19 @@ static struct masks logcfg_item[] = { { NULL, 0 } }; +typedef struct peer_resolved_ctx_tag { + int num_needed; + int flags; + int host_mode; /* T_* token identifier */ + short family; + keyid_t keyid; + u_char hmode; /* MODE_* */ + u_char version; + u_char minpoll; + u_char maxpoll; + u_char ttl; +} peer_resolved_ctx; + /* Limits */ #define MAXPHONE 10 /* maximum number of phone strings */ #define MAXPPS 20 /* maximum length of PPS device string */ @@ -228,7 +241,7 @@ static void free_config_tree(struct config_tree *ptree); double *create_dval(double val); void destroy_restrict_node(struct restrict_node *my_node); static int is_sane_resolved_address(sockaddr_u *peeraddr, int hmode); -static int get_correct_host_mode(int hmode); +static u_char get_correct_host_mode(int token); static int peerflag_bits(struct peer_node *); static void save_and_apply_config_tree(void); void getconfig(int, char **); @@ -794,7 +807,7 @@ dump_config_tree( fprintf(df, " %s", addr->address); if (peer->minpoll != 0) - fprintf(df, " minpoll %d", peer->minpoll); + fprintf(df, " minpoll %u", peer->minpoll); if (peer->maxpoll != 0) fprintf(df, " maxpoll %d", peer->maxpoll); @@ -802,16 +815,16 @@ dump_config_tree( if (peer->ttl != 0) { if (strlen(addr->address) > 8 && !memcmp(addr->address, "127.127.", 8)) - fprintf(df, " mode %d", peer->ttl); + fprintf(df, " mode %u", peer->ttl); else - fprintf(df, " ttl %d", peer->ttl); + fprintf(df, " ttl %u", peer->ttl); } if (peer->peerversion != NTP_VERSION) - fprintf(df, " version %d", peer->peerversion); + fprintf(df, " version %u", peer->peerversion); if (peer->peerkey != 0) - fprintf(df, " key %d", peer->peerkey); + fprintf(df, " key %u", peer->peerkey); if (peer->bias != 0.) fprintf(df, " bias %g", peer->bias); @@ -1270,46 +1283,57 @@ create_peer_node( break; case T_Minpoll: - if (option->value.i < NTP_MINPOLL) { + if (option->value.i < NTP_MINPOLL || + option->value.i > UCHAR_MAX) { msyslog(LOG_INFO, - "minpoll: provided value (%d) is below minimum (%d)", - option->value.i, NTP_MINPOLL); + "minpoll: provided value (%d) is out of range [%d-%d])", + option->value.i, NTP_MINPOLL, UCHAR_MAX); my_node->minpoll = NTP_MINPOLL; - } - else - my_node->minpoll = option->value.i; + } else + my_node->minpoll = (u_char)option->value.u; break; case T_Maxpoll: - if (option->value.i > NTP_MAXPOLL) { + if (option->value.i < 0 || + option->value.i > NTP_MAXPOLL) { msyslog(LOG_INFO, - "maxpoll: provided value (%d) is above maximum (%d)", + "maxpoll: provided value (%d) is out of range [0-%d])", option->value.i, NTP_MAXPOLL); my_node->maxpoll = NTP_MAXPOLL; - } - else - my_node->maxpoll = option->value.i; + } else + my_node->maxpoll = (u_char)option->value.u; break; case T_Ttl: - if (my_node->ttl >= MAX_TTL) { + if (option->value.u >= MAX_TTL) { msyslog(LOG_ERR, "ttl: invalid argument"); errflag = 1; - } - else - my_node->ttl = option->value.i; + } else + my_node->ttl = (u_char)option->value.u; break; case T_Mode: - my_node->ttl = option->value.i; + if (option->value.u >= UCHAR_MAX) { + msyslog(LOG_ERR, "mode: invalid argument"); + errflag = 1; + } else + my_node->ttl = (u_char)option->value.u; break; case T_Key: - my_node->peerkey = option->value.i; + if (option->value.u >= KEYID_T_MAX) { + msyslog(LOG_ERR, "key: invalid argument"); + errflag = 1; + } else + my_node->peerkey = (keyid_t)option->value.u; break; case T_Version: - my_node->peerversion = option->value.i; + if (option->value.u >= UCHAR_MAX) { + msyslog(LOG_ERR, "version: invalid argument"); + errflag = 1; + } else + my_node->peerversion = (u_char)option->value.u; break; case T_Bias: @@ -1342,6 +1366,7 @@ create_unpeer_node( ) { struct unpeer_node * my_node; + u_int u; char * pch; my_node = get_node(sizeof(*my_node)); @@ -1356,9 +1381,9 @@ create_unpeer_node( pch++; if (!*pch - && 1 == sscanf(addr->address, "%u", &my_node->assocID) - && my_node->assocID <= USHRT_MAX) { - + && 1 == sscanf(addr->address, "%u", &u) + && u <= ASSOCID_MAX) { + my_node->assocID = (associd_t)u; destroy_address_node(addr); my_node->addr = NULL; } else { @@ -2071,9 +2096,9 @@ config_access( struct addrinfo * ai_list; struct addrinfo * pai; int rc; - int flags; - int mflags; int restrict_default; + u_short flags; + u_short mflags; const char * signd_warning = #ifdef HAVE_NTP_SIGND "MS-SNTP signd operations currently block ntpd degrading service to all clients."; @@ -2088,7 +2113,13 @@ config_access( switch(my_opt->attr) { case T_Average: - ntp_minpoll = my_opt->value.i; + if (0 <= my_opt->value.i && + my_opt->value.i <= UCHAR_MAX) + ntp_minpoll = (u_char)my_opt->value.u; + else + msyslog(LOG_ERR, + "discard average %d out of range, ignored.", + my_opt->value.i); break; case T_Minimum: @@ -2957,7 +2988,7 @@ config_trap( hints.ai_socktype = SOCK_DGRAM; snprintf(port_text, sizeof(port_text), "%u", port); - hints.ai_flags = AI_NUMERICSERV; + hints.ai_flags = Z_AI_NUMERICSERV; pstp = emalloc(sizeof(*pstp)); memset(pstp, 0, sizeof(*pstp)); if (localaddr != NULL) { @@ -3351,25 +3382,26 @@ is_sane_resolved_address( } -static int +static u_char get_correct_host_mode( int token ) { switch (token) { - case T_Server: - case T_Pool: - case T_Manycastclient: + + case T_Server: + case T_Pool: + case T_Manycastclient: return MODE_CLIENT; - break; - case T_Peer: + + case T_Peer: return MODE_ACTIVE; - break; - case T_Broadcast: + + case T_Broadcast: return MODE_BROADCAST; - break; - default: - return -1; + + default: + return 0; } } @@ -3442,7 +3474,8 @@ config_peers( isc_netaddr_t i_netaddr; struct addrinfo hints; struct peer_node *curr_peer; - int hmode; + peer_resolved_ctx *ctx; + u_char hmode; int num_needed; for (curr_peer = queue_head(ptree->peers); @@ -3451,7 +3484,7 @@ config_peers( /* Find the correct host-mode */ hmode = get_correct_host_mode(curr_peer->host_mode); - NTP_INSIST(hmode != -1); + NTP_INSIST(hmode != 0); /* Find the number of associations needed. * If a pool coomand is specified, then sys_maxclock needed @@ -3495,13 +3528,26 @@ config_peers( } else { /* we have a hostname to resolve */ #ifdef WORKER + ctx = emalloc(sizeof(*ctx)); + ctx->family = curr_peer->addr->type; + ctx->num_needed = num_needed; + ctx->host_mode = curr_peer->host_mode; + ctx->hmode = hmode; + ctx->version = curr_peer->peerversion; + ctx->minpoll = curr_peer->minpoll; + ctx->maxpoll = curr_peer->maxpoll; + ctx->flags = peerflag_bits(curr_peer); + ctx->ttl = curr_peer->ttl; + ctx->keyid = curr_peer->peerkey; + memset(&hints, 0, sizeof(hints)); - hints.ai_family = (u_short)curr_peer->addr->type; + hints.ai_family = (u_short)ctx->family; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; + getaddrinfo_sometime(curr_peer->addr->address, "ntp", &hints, &peer_name_resolved, - (void *)curr_peer); + (void *)ctx); #else /* !WORKER follows */ msyslog(LOG_ERR, "hostname %s can not be used, please use address\n", @@ -3530,19 +3576,18 @@ peer_name_resolved( ) { sockaddr_u peeraddr; - struct peer_node * curr_peer; - int num_needed; - int hmode; + peer_resolved_ctx * ctx; int i; int af; const char * fam_spec; - curr_peer = context; + ctx = context; DPRINTF(1, ("peer_name_resolved(%s) rescode %d\n", name, rescode)); if (rescode) { #ifndef IGNORE_DNS_ERRORS + free(ctx); msyslog(LOG_ERR, "giving up resolving host %s: %s (%d)", name, gai_strerror(rescode), rescode); @@ -3553,24 +3598,18 @@ peer_name_resolved( return; } - hmode = get_correct_host_mode(curr_peer->host_mode); - NTP_INSIST(hmode != -1); - num_needed = (T_Pool == curr_peer->host_mode) - ? sys_maxclock - : 1; - /* Loop to configure the desired number of associations */ for (i = 0; - res != NULL && i < num_needed; + res != NULL && i < ctx->num_needed; res = res->ai_next) { memcpy(&peeraddr, res->ai_addr, res->ai_addrlen); if (is_sane_resolved_address(&peeraddr, - curr_peer->host_mode)) { + ctx->host_mode)) { i++; NLOG(NLOG_SYSINFO) { - af = curr_peer->addr->type; + af = ctx->family; fam_spec = (AF_INET6 == af) ? "(AAAA) " : (AF_INET == af) @@ -3582,16 +3621,17 @@ peer_name_resolved( } peer_config(&peeraddr, NULL, - hmode, - curr_peer->peerversion, - curr_peer->minpoll, - curr_peer->maxpoll, - peerflag_bits(curr_peer), - curr_peer->ttl, - curr_peer->peerkey, + ctx->hmode, + ctx->version, + ctx->minpoll, + ctx->maxpoll, + ctx->flags, + ctx->ttl, + ctx->keyid, (u_char *)"*"); } } + free(ctx); } #endif /* WORKER */ @@ -3618,12 +3658,11 @@ config_unpeers( struct config_tree *ptree ) { - sockaddr_u peeraddr; + sockaddr_u peeraddr; struct addrinfo hints; isc_netaddr_t i_netaddr; - struct unpeer_node *curr_unpeer; - struct peer *peer; - int found; + struct unpeer_node * curr_unpeer; + struct peer * peer; for (curr_unpeer = queue_head(ptree->unpeers); curr_unpeer != NULL; @@ -3634,7 +3673,7 @@ config_unpeers( * address addr, or it is nonzero and addr NULL. */ if (curr_unpeer->assocID) { - peer = findpeerbyassoc((u_int)curr_unpeer->assocID); + peer = findpeerbyassoc(curr_unpeer->assocID); if (peer != NULL) { peer_clear(peer, "GONE"); unpeer(peer); @@ -3660,18 +3699,15 @@ config_unpeers( SET_ADDR4N(&peeraddr, i_netaddr.type.in.s_addr); - found = 0; - peer = NULL; - DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); - + peer = NULL; do { peer = findexistingpeer(&peeraddr, peer, -1); - if (NULL != peer && (FLAG_CONFIG & peer->flags)) - found = 1; - } while (!found && NULL != peer); + if (peer != NULL && (FLAG_CONFIG & peer->flags)) + break; + } while (peer != NULL); - if (found) { + if (peer != NULL) { msyslog(LOG_INFO, "unpeered %s", stoa(&peeraddr)); peer_clear(peer, "GONE"); @@ -3684,9 +3720,10 @@ config_unpeers( hints.ai_family = (u_short)curr_unpeer->addr->type; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; - getaddrinfo_sometime(curr_unpeer->addr->address, "ntp", - &hints, &unpeer_name_resolved, - (void *)curr_unpeer); + getaddrinfo_sometime(curr_unpeer->addr->address, + "ntp", &hints, + &unpeer_name_resolved, + (void *)hints.ai_family); #else /* !WORKER follows */ msyslog(LOG_ERR, "hostname %s can not be used, please use address\n", @@ -3714,16 +3751,14 @@ unpeer_name_resolved( const struct addrinfo * res ) { - sockaddr_u peeraddr; - struct unpeer_node * curr_unpeer; - struct peer * peer; - int found; - int af; - const char * fam_spec; + sockaddr_u peeraddr; + struct peer * peer; + int af; + const char * fam_spec; DPRINTF(1, ("unpeer_name_resolved(%s) rescode %d\n", name, rescode)); - curr_unpeer = context; + af = (int)context; if (rescode) msyslog(LOG_ERR, "giving up resolving unpeer %s: %s (%d)", @@ -3733,20 +3768,16 @@ unpeer_name_resolved( * Loop through the addresses found */ while (res) { - found = 0; - peer = NULL; - memcpy(&peeraddr, res->ai_addr, res->ai_addrlen); DPRINTF(1, ("searching for peer %s\n", stoa(&peeraddr))); - + peer = NULL; do { peer = findexistingpeer(&peeraddr, peer, -1); - if (NULL != peer && (FLAG_CONFIG & peer->flags)) - found = 1; - } while (!found && NULL != peer); + if (peer != NULL && (FLAG_CONFIG & peer->flags)) + break; + } while (peer != NULL); - if (found) { - af = curr_unpeer->addr->type; + if (peer != NULL) { fam_spec = (AF_INET6 == af) ? "(AAAA) " : (AF_INET == af) diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 7f7c529b..63a4b685 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -44,14 +44,13 @@ struct ctl_proc { /* * Request processing routines */ -static void ctl_error (int); +static void ctl_error (u_char); #ifdef REFCLOCK static u_short ctlclkstatus (struct refclockstat *); #endif -static void ctl_flushpkt (int); +static void ctl_flushpkt (u_char); static void ctl_putdata (const char *, unsigned int, int); -static void ctl_putstr (const char *, const char *, - unsigned int); +static void ctl_putstr (const char *, const char *, size_t); static void ctl_putdbl (const char *, double); static void ctl_putuint (const char *, u_long); static void ctl_puthex (const char *, u_long); @@ -67,28 +66,30 @@ static void ctl_putfs (const char *, tstamp_t); #ifdef REFCLOCK static void ctl_putclock (int, struct refclockstat *, int); #endif /* REFCLOCK */ -static struct ctl_var *ctl_getitem (struct ctl_var *, char **); -static u_long count_var (struct ctl_var *); +static struct ctl_var *ctl_getitem(struct ctl_var *, char **); +static u_short count_var (struct ctl_var *); static void control_unspec (struct recvbuf *, int); static void read_status (struct recvbuf *, int); +static void read_sysvars (void); +static void read_peervars (void); static void read_variables (struct recvbuf *, int); static void write_variables (struct recvbuf *, int); -static void read_clock_status (struct recvbuf *, int); -static void write_clock_status (struct recvbuf *, int); +static void read_clockstatus(struct recvbuf *, int); +static void write_clockstatus(struct recvbuf *, int); static void set_trap (struct recvbuf *, int); static void unset_trap (struct recvbuf *, int); static void configure (struct recvbuf *, int); static void save_config (struct recvbuf *, int); -static struct ctl_trap *ctlfindtrap (sockaddr_u *, - struct interface *); +static struct ctl_trap *ctlfindtrap(sockaddr_u *, + struct interface *); static struct ctl_proc control_codes[] = { { CTL_OP_UNSPEC, NOAUTH, control_unspec }, { CTL_OP_READSTAT, NOAUTH, read_status }, { CTL_OP_READVAR, NOAUTH, read_variables }, { CTL_OP_WRITEVAR, AUTH, write_variables }, - { CTL_OP_READCLOCK, NOAUTH, read_clock_status }, - { CTL_OP_WRITECLOCK, NOAUTH, write_clock_status }, + { CTL_OP_READCLOCK, NOAUTH, read_clockstatus }, + { CTL_OP_WRITECLOCK, NOAUTH, write_clockstatus }, { CTL_OP_SETTRAP, NOAUTH, set_trap }, { CTL_OP_UNSETTRAP, NOAUTH, unset_trap }, { CTL_OP_SAVECONFIG, AUTH, save_config }, @@ -135,7 +136,7 @@ static struct ctl_var sys_var[] = { { CS_GROUP, RO, "group" }, /* 30 */ { CS_DIGEST, RO, "digest" }, /* 31 */ #endif /* OPENSSL */ - { 0, EOV, "" } /* 24/3 2*/ + { 0, EOV, "" } /* 24/32 */ }; static struct ctl_var *ext_sys_var = (struct ctl_var *)0; @@ -401,8 +402,8 @@ static u_char clocktypes[] = { CTL_SST_TS_NTP, /* not used (24) */ CTL_SST_TS_NTP, /* not used (25) */ CTL_SST_TS_UHF, /* REFCLK_GPS_HP (26) */ - CTL_SST_TS_TELEPHONE, /* REFCLK_ARCRON_MSF (27) */ - CTL_SST_TS_TELEPHONE, /* REFCLK_SHM (28) */ + CTL_SST_TS_LF, /* REFCLK_ARCRON_MSF (27) */ + CTL_SST_TS_UHF, /* REFCLK_SHM (28) */ CTL_SST_TS_UHF, /* REFCLK_PALISADE (29) */ CTL_SST_TS_UHF, /* REFCLK_ONCORE (30) */ CTL_SST_TS_UHF, /* REFCLK_JUPITER (31) */ @@ -505,7 +506,7 @@ init_control(void) ctl_sys_num_events = 0; num_ctl_traps = 0; - for (i = 0; i < CTL_MAXTRAPS; i++) + for (i = 0; i < COUNTOF(ctl_trap); i++) ctl_trap[i].tr_flags = 0; } @@ -515,37 +516,37 @@ init_control(void) */ static void ctl_error( - int errcode + u_char errcode ) { - DPRINTF(3, ("sending control error %d\n", errcode)); + int maclen; + keyid_t * pkid; + + numctlerrors++; + DPRINTF(3, ("sending control error %u\n", errcode)); /* * Fill in the fields. We assume rpkt.sequence and rpkt.associd * have already been filled in. */ - rpkt.r_m_e_op = (u_char) (CTL_RESPONSE|CTL_ERROR|(res_opcode & - CTL_OP_MASK)); - rpkt.status = htons((u_short) ((errcode<<8) & 0xff00)); + rpkt.r_m_e_op = CTL_RESPONSE | CTL_ERROR | + (res_opcode & CTL_OP_MASK); + rpkt.status = htons((errcode << 8) & 0xff00); rpkt.count = 0; /* * send packet and bump counters */ if (res_authenticate && sys_authenticate) { - int maclen; - - *(u_int32 *)((u_char *)&rpkt + CTL_HEADER_LEN) = - htonl(res_keyid); - maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, + pkid = (void *)((char *)&rpkt + CTL_HEADER_LEN); + *pkid = htonl(res_keyid); + maclen = authencrypt(res_keyid, (void *)&rpkt, CTL_HEADER_LEN); - sendpkt(rmt_addr, lcl_inter, -2, (struct pkt *)&rpkt, + sendpkt(rmt_addr, lcl_inter, -2, (void *)&rpkt, CTL_HEADER_LEN + maclen); - } else { - sendpkt(rmt_addr, lcl_inter, -3, (struct pkt *)&rpkt, + } else + sendpkt(rmt_addr, lcl_inter, -3, (void *)&rpkt, CTL_HEADER_LEN); - } - numctlerrors++; } /* @@ -571,7 +572,7 @@ save_config( FILE *fptr; #endif - if (restrict_mask & RES_NOMODIFY) { + if (RES_NOMODIFY & restrict_mask) { snprintf(reply, sizeof(reply), "saveconfig prohibited by restrict ... nomodify"); ctl_putdata(reply, strlen(reply), 0); @@ -682,6 +683,7 @@ process_control( register int req_count; register int req_data; register struct ctl_proc *cc; + keyid_t *pkid; int properlen; int maclen; @@ -700,16 +702,16 @@ process_control( * it is a response or a fragment, ignore this. */ if (rbufp->recv_length < CTL_HEADER_LEN - || pkt->r_m_e_op & (CTL_RESPONSE|CTL_MORE|CTL_ERROR) + || (CTL_RESPONSE | CTL_MORE | CTL_ERROR) & pkt->r_m_e_op || pkt->offset != 0) { DPRINTF(1, ("invalid format in control packet\n")); if (rbufp->recv_length < CTL_HEADER_LEN) numctltooshort++; - if (pkt->r_m_e_op & CTL_RESPONSE) + if (CTL_RESPONSE & pkt->r_m_e_op) numctlinputresp++; - if (pkt->r_m_e_op & CTL_MORE) + if (CTL_MORE & pkt->r_m_e_op) numctlinputfrag++; - if (pkt->r_m_e_op & CTL_ERROR) + if (CTL_ERROR & pkt->r_m_e_op) numctlinputerr++; if (pkt->offset != 0) numctlbadoffset++; @@ -769,8 +771,8 @@ process_control( maclen >= MIN_MAC_LEN && maclen <= MAX_MAC_LEN && sys_authenticate) { res_authenticate = 1; - res_keyid = ntohl(*(u_int32 *)((u_char *)pkt + - properlen)); + pkid = (void *)((char *)pkt + properlen); + res_keyid = ntohl(*pkid); DPRINTF(3, ("recv_len %d, properlen %d, wants auth with keyid %08x, MAC length=%d\n", rbufp->recv_length, properlen, res_keyid, maclen)); @@ -826,24 +828,24 @@ process_control( */ u_short ctlpeerstatus( - register struct peer *peer + register struct peer *p ) { u_short status; - status = peer->status; - if (!(peer->flags & FLAG_PREEMPT)) + status = p->status; + if (!(FLAG_PREEMPT & p->flags)) status |= CTL_PST_CONFIG; - if (peer->keyid != 0) + if (p->keyid) status |= CTL_PST_AUTHENABLE; - if (peer->flags & FLAG_AUTHENTIC) + if (FLAG_AUTHENTIC & p->flags) status |= CTL_PST_AUTHENTIC; - if (peer->reach != 0) + if (p->reach) status |= CTL_PST_REACH; - if (peer->cast_flags & (MDF_BCAST | MDF_MCAST | MDF_ACAST)) + if (MDF_SRVCASTMASK & p->cast_flags) status |= CTL_PST_BCAST; - return (u_short)CTL_PEER_STATUS(status, peer->num_events, - peer->last_event); + + return CTL_PEER_STATUS(status, p->num_events, p->last_event); } @@ -853,11 +855,10 @@ ctlpeerstatus( #ifdef REFCLOCK static u_short ctlclkstatus( - struct refclockstat *this_clock + struct refclockstat *pcs ) { - return (u_short)CTL_PEER_STATUS(0, this_clock->lastevent, - this_clock->currentstatus); + return CTL_PEER_STATUS(0, pcs->lastevent, pcs->currentstatus); } #endif @@ -872,21 +873,18 @@ ctlsysstatus(void) this_clock = CTL_SST_TS_UNSPEC; #ifdef REFCLOCK - if (sys_peer != 0) { - if (sys_peer->sstclktype != CTL_SST_TS_UNSPEC) { + if (sys_peer != NULL) { + if (CTL_SST_TS_UNSPEC != sys_peer->sstclktype) this_clock = sys_peer->sstclktype; - } else { - if (sys_peer->refclktype < sizeof(clocktypes)) - this_clock = - clocktypes[sys_peer->refclktype]; - } + else if (sys_peer->refclktype < COUNTOF(clocktypes)) + this_clock = clocktypes[sys_peer->refclktype]; } #else /* REFCLOCK */ if (sys_peer != 0) this_clock = CTL_SST_TS_NTP; #endif /* REFCLOCK */ - return (u_short)CTL_SYS_STATUS(sys_leap, this_clock, - ctl_sys_num_events, ctl_sys_last_event); + return CTL_SYS_STATUS(sys_leap, this_clock, ctl_sys_num_events, + ctl_sys_last_event); } @@ -896,20 +894,25 @@ ctlsysstatus(void) */ static void ctl_flushpkt( - int more + u_char more ) { + int i; int dlen; int sendlen; + int maclen; + int totlen; + keyid_t keyid; - if (!more && datanotbinflag) { + dlen = datapt - rpkt.data; + if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) { /* * Big hack, output a trailing \r\n */ *datapt++ = '\r'; *datapt++ = '\n'; + dlen += 2; } - dlen = datapt - (u_char *)rpkt.data; sendlen = dlen + CTL_HEADER_LEN; /* @@ -923,19 +926,18 @@ ctl_flushpkt( /* * Fill in the packet with the current info */ - rpkt.r_m_e_op = (u_char)(CTL_RESPONSE|more|(res_opcode & - CTL_OP_MASK)); - rpkt.count = htons((u_short) dlen); - rpkt.offset = htons( (u_short) res_offset); + rpkt.r_m_e_op = CTL_RESPONSE | more | + (res_opcode & CTL_OP_MASK); + rpkt.count = htons((u_short)dlen); + rpkt.offset = htons((u_short)res_offset); if (res_async) { - register int i; - - for (i = 0; i < CTL_MAXTRAPS; i++) { - if (ctl_trap[i].tr_flags & TRAP_INUSE) { + for (i = 0; i < COUNTOF(ctl_trap); i++) { + if (TRAP_INUSE & ctl_trap[i].tr_flags) { rpkt.li_vn_mode = - PKT_LI_VN_MODE(sys_leap, - ctl_trap[i].tr_version, - MODE_CONTROL); + PKT_LI_VN_MODE( + sys_leap, + ctl_trap[i].tr_version, + MODE_CONTROL); rpkt.sequence = htons(ctl_trap[i].tr_sequence); sendpkt(&ctl_trap[i].tr_addr, @@ -948,10 +950,7 @@ ctl_flushpkt( } } else { if (res_authenticate && sys_authenticate) { - int maclen; - int totlen = sendlen; - keyid_t keyid = htonl(res_keyid); - + totlen = sendlen; /* * If we are going to authenticate, then there * is an additional requirement that the MAC @@ -961,15 +960,15 @@ ctl_flushpkt( *datapt++ = '\0'; totlen++; } - memcpy(datapt, &keyid, sizeof keyid); + keyid = htonl(res_keyid); + memcpy(datapt, &keyid, sizeof(keyid)); maclen = authencrypt(res_keyid, (u_int32 *)&rpkt, totlen); sendpkt(rmt_addr, lcl_inter, -5, (struct pkt *)&rpkt, totlen + maclen); - } else { + } else sendpkt(rmt_addr, lcl_inter, -6, (struct pkt *)&rpkt, sendlen); - } if (more) numctlfrags++; else @@ -980,7 +979,7 @@ ctl_flushpkt( * Set us up for another go around. */ res_offset += dlen; - datapt = (u_char *)rpkt.data; + datapt = rpkt.data; } @@ -1004,8 +1003,7 @@ ctl_putdata( if (datapt != rpkt.data) { *datapt++ = ','; datalinelen++; - if ((dlen + datalinelen + 1) >= MAXDATALINELEN) - { + if ((dlen + datalinelen + 1) >= MAXDATALINELEN) { *datapt++ = '\r'; *datapt++ = '\n'; datalinelen = 0; @@ -1025,7 +1023,7 @@ ctl_putdata( */ ctl_flushpkt(CTL_MORE); } - memmove((char *)datapt, dp, (unsigned)dlen); + memcpy(datapt, dp, dlen); datapt += dlen; datalinelen += dlen; } @@ -1033,12 +1031,18 @@ ctl_putdata( /* * ctl_putstr - write a tagged string into the response packet + * in the form: + * + * tag="data" + * + * len is the data length excluding the NUL terminator, + * as in ctl_putstr("var", "value", strlen("value")); */ static void ctl_putstr( - const char *tag, - const char *data, - unsigned int len + const char * tag, + const char * data, + size_t len ) { register char *cp; @@ -1052,9 +1056,9 @@ ctl_putstr( if (len > 0) { *cp++ = '='; *cp++ = '"'; - if (len > (int) (sizeof(buffer) - (cp - buffer) - 1)) + if (len > (sizeof(buffer) - (cp - buffer) - 1)) len = sizeof(buffer) - (cp - buffer) - 1; - memmove(cp, data, (unsigned)len); + memcpy(cp, data, len); cp += len; *cp++ = '"'; } @@ -1445,11 +1449,11 @@ ctl_putsys( sys_var[CS_VARLIST].text); s += strlen(s); t = s; - for (k = sys_var; !(k->flags & EOV); k++) { - if (k->flags & PADDING) + for (k = sys_var; !(EOV & k->flags); k++) { + if (PADDING & k->flags) continue; i = strlen(k->text); - if (s+i+1 >= be) + if (s + i + 1 >= be) break; if (s != t) @@ -1458,9 +1462,9 @@ ctl_putsys( s += i; } - for (k = ext_sys_var; k && !(k->flags & EOV); + for (k = ext_sys_var; k && !(EOV & k->flags); k++) { - if (k->flags & PADDING) + if (PADDING & k->flags) continue; ss = k->text; @@ -1574,299 +1578,267 @@ ctl_putsys( */ static void ctl_putpeer( - int varid, - struct peer *peer + int id, + struct peer *p ) { - int temp; + char buf[CTL_MAX_DATA_LEN]; + char *s; + char *t; + char *be; + int i; + struct ctl_var *k; #ifdef OPENSSL - char str[256]; struct autokey *ap; + const EVP_MD *dp; + const char *str; #endif /* OPENSSL */ - switch (varid) { + switch (id) { - case CP_CONFIG: - ctl_putuint(peer_var[CP_CONFIG].text, - (unsigned)((peer->flags & FLAG_PREEMPT) == 0)); + case CP_CONFIG: + ctl_putuint(peer_var[id].text, + !(FLAG_PREEMPT & p->flags)); break; - case CP_AUTHENABLE: - ctl_putuint(peer_var[CP_AUTHENABLE].text, - (unsigned)(peer->keyid != 0)); + case CP_AUTHENABLE: + ctl_putuint(peer_var[id].text, !(p->keyid)); break; - case CP_AUTHENTIC: - ctl_putuint(peer_var[CP_AUTHENTIC].text, - (unsigned)((peer->flags & FLAG_AUTHENTIC) != 0)); + case CP_AUTHENTIC: + ctl_putuint(peer_var[id].text, + !!(FLAG_AUTHENTIC & p->flags)); break; - case CP_SRCADR: - ctl_putadr(peer_var[CP_SRCADR].text, 0, - &peer->srcadr); + case CP_SRCADR: + ctl_putadr(peer_var[id].text, 0, &p->srcadr); break; - case CP_SRCPORT: - ctl_putuint(peer_var[CP_SRCPORT].text, - ntohs(((struct sockaddr_in*)&peer->srcadr)->sin_port)); + case CP_SRCPORT: + ctl_putuint(peer_var[id].text, SRCPORT(&p->srcadr)); break; - case CP_DSTADR: - if (peer->dstadr) { - ctl_putadr(peer_var[CP_DSTADR].text, 0, - &(peer->dstadr->sin)); - } else { - ctl_putadr(peer_var[CP_DSTADR].text, 0, - NULL); - } + case CP_DSTADR: + ctl_putadr(peer_var[id].text, 0, + (p->dstadr != NULL) + ? &p->dstadr->sin + : NULL); break; - case CP_DSTPORT: - ctl_putuint(peer_var[CP_DSTPORT].text, - (u_long)(peer->dstadr ? - ntohs(((struct sockaddr_in*)&peer->dstadr->sin)->sin_port) : 0)); + case CP_DSTPORT: + ctl_putuint(peer_var[id].text, + (p->dstadr != NULL) + ? SRCPORT(&p->dstadr->sin) + : 0); break; - case CP_IN: - if (peer->r21 > 0) - ctl_putdbl(peer_var[CP_IN].text, - peer->r21 / 1e3); + case CP_IN: + if (p->r21 > 0.) + ctl_putdbl(peer_var[id].text, p->r21 / 1e3); break; - case CP_OUT: - if (peer->r34 >0) - ctl_putdbl(peer_var[CP_OUT].text, - peer->r34 / 1e3); + case CP_OUT: + if (p->r34 > 0.) + ctl_putdbl(peer_var[id].text, p->r34 / 1e3); break; - case CP_RATE: - ctl_putuint(peer_var[CP_RATE].text, peer->throttle); + case CP_RATE: + ctl_putuint(peer_var[id].text, p->throttle); break; - case CP_LEAP: - ctl_putuint(peer_var[CP_LEAP].text, peer->leap); + case CP_LEAP: + ctl_putuint(peer_var[id].text, p->leap); break; - case CP_HMODE: - ctl_putuint(peer_var[CP_HMODE].text, peer->hmode); + case CP_HMODE: + ctl_putuint(peer_var[id].text, p->hmode); break; - case CP_STRATUM: - ctl_putuint(peer_var[CP_STRATUM].text, peer->stratum); + case CP_STRATUM: + ctl_putuint(peer_var[id].text, p->stratum); break; - case CP_PPOLL: - ctl_putuint(peer_var[CP_PPOLL].text, peer->ppoll); + case CP_PPOLL: + ctl_putuint(peer_var[id].text, p->ppoll); break; - case CP_HPOLL: - ctl_putuint(peer_var[CP_HPOLL].text, peer->hpoll); + case CP_HPOLL: + ctl_putuint(peer_var[id].text, p->hpoll); break; - case CP_PRECISION: - ctl_putint(peer_var[CP_PRECISION].text, - peer->precision); + case CP_PRECISION: + ctl_putint(peer_var[id].text, p->precision); break; - case CP_ROOTDELAY: - ctl_putdbl(peer_var[CP_ROOTDELAY].text, - peer->rootdelay * 1e3); + case CP_ROOTDELAY: + ctl_putdbl(peer_var[id].text, p->rootdelay * 1e3); break; - case CP_ROOTDISPERSION: - ctl_putdbl(peer_var[CP_ROOTDISPERSION].text, - peer->rootdisp * 1e3); + case CP_ROOTDISPERSION: + ctl_putdbl(peer_var[id].text, p->rootdisp * 1e3); break; - case CP_REFID: - if (peer->flags & FLAG_REFCLOCK) { - ctl_putid(peer_var[CP_REFID].text, - (char *)&peer->refid); - } else { - if (peer->stratum > 1 && peer->stratum < - STRATUM_UNSPEC) - ctl_putadr(peer_var[CP_REFID].text, - peer->refid, NULL); - else - ctl_putid(peer_var[CP_REFID].text, - (char *)&peer->refid); - } + case CP_REFID: + if (FLAG_REFCLOCK & p->flags) + ctl_putid(peer_var[id].text, (char *)&p->refid); + else if (1 < p->stratum && p->stratum < STRATUM_UNSPEC) + ctl_putadr(peer_var[id].text, p->refid, NULL); + else + ctl_putid(peer_var[id].text, (char *)&p->refid); break; - case CP_REFTIME: - ctl_putts(peer_var[CP_REFTIME].text, &peer->reftime); + case CP_REFTIME: + ctl_putts(peer_var[id].text, &p->reftime); break; - case CP_ORG: - ctl_putts(peer_var[CP_ORG].text, &peer->aorg); + case CP_ORG: + ctl_putts(peer_var[id].text, &p->aorg); break; - case CP_REC: - ctl_putts(peer_var[CP_REC].text, &peer->dst); + case CP_REC: + ctl_putts(peer_var[id].text, &p->dst); break; - case CP_XMT: - if (peer->xleave != 0) - ctl_putdbl(peer_var[CP_XMT].text, peer->xleave * - 1e3); + case CP_XMT: + if (p->xleave) + ctl_putdbl(peer_var[id].text, p->xleave * 1e3); break; - case CP_BIAS: - if (peer->bias != 0) - ctl_putdbl(peer_var[CP_BIAS].text, peer->bias * - 1e3); + case CP_BIAS: + if (p->bias != 0.) + ctl_putdbl(peer_var[id].text, p->bias * 1e3); break; - case CP_REACH: - ctl_puthex(peer_var[CP_REACH].text, peer->reach); + case CP_REACH: + ctl_puthex(peer_var[id].text, p->reach); break; - case CP_FLASH: - temp = peer->flash; - ctl_puthex(peer_var[CP_FLASH].text, temp); + case CP_FLASH: + ctl_puthex(peer_var[id].text, p->flash); break; - case CP_TTL: - if (peer->ttl > 0) - ctl_putint(peer_var[CP_TTL].text, - sys_ttl[peer->ttl]); + case CP_TTL: + if (p->ttl) + ctl_putint(peer_var[id].text, + sys_ttl[p->ttl]); break; - case CP_UNREACH: - ctl_putuint(peer_var[CP_UNREACH].text, peer->unreach); + case CP_UNREACH: + ctl_putuint(peer_var[id].text, p->unreach); break; - case CP_TIMER: - ctl_putuint(peer_var[CP_TIMER].text, - peer->nextdate - current_time); + case CP_TIMER: + ctl_putuint(peer_var[id].text, + p->nextdate - current_time); break; - case CP_DELAY: - ctl_putdbl(peer_var[CP_DELAY].text, peer->delay * 1e3); + case CP_DELAY: + ctl_putdbl(peer_var[id].text, p->delay * 1e3); break; - case CP_OFFSET: - ctl_putdbl(peer_var[CP_OFFSET].text, peer->offset * - 1e3); + case CP_OFFSET: + ctl_putdbl(peer_var[id].text, p->offset * 1e3); break; - case CP_JITTER: - ctl_putdbl(peer_var[CP_JITTER].text, peer->jitter * - 1e3); + case CP_JITTER: + ctl_putdbl(peer_var[id].text, p->jitter * 1e3); break; - case CP_DISPERSION: - ctl_putdbl(peer_var[CP_DISPERSION].text, peer->disp * - 1e3); + case CP_DISPERSION: + ctl_putdbl(peer_var[id].text, p->disp * 1e3); break; - case CP_KEYID: - if (peer->keyid > NTP_MAXKEY) - ctl_puthex(peer_var[CP_KEYID].text, - peer->keyid); + case CP_KEYID: + if (p->keyid > NTP_MAXKEY) + ctl_puthex(peer_var[id].text, p->keyid); else - ctl_putuint(peer_var[CP_KEYID].text, - peer->keyid); + ctl_putuint(peer_var[id].text, p->keyid); break; - case CP_FILTDELAY: - ctl_putarray(peer_var[CP_FILTDELAY].text, - peer->filter_delay, (int)peer->filter_nextpt); + case CP_FILTDELAY: + ctl_putarray(peer_var[id].text, p->filter_delay, + (int)p->filter_nextpt); break; - case CP_FILTOFFSET: - ctl_putarray(peer_var[CP_FILTOFFSET].text, - peer->filter_offset, (int)peer->filter_nextpt); + case CP_FILTOFFSET: + ctl_putarray(peer_var[id].text, p->filter_offset, + (int)p->filter_nextpt); break; - case CP_FILTERROR: - ctl_putarray(peer_var[CP_FILTERROR].text, - peer->filter_disp, (int)peer->filter_nextpt); + case CP_FILTERROR: + ctl_putarray(peer_var[id].text, p->filter_disp, + (int)p->filter_nextpt); break; - case CP_PMODE: - ctl_putuint(peer_var[CP_PMODE].text, peer->pmode); + case CP_PMODE: + ctl_putuint(peer_var[id].text, p->pmode); break; - case CP_RECEIVED: - ctl_putuint(peer_var[CP_RECEIVED].text, peer->received); + case CP_RECEIVED: + ctl_putuint(peer_var[id].text, p->received); break; - case CP_SENT: - ctl_putuint(peer_var[CP_SENT].text, peer->sent); + case CP_SENT: + ctl_putuint(peer_var[id].text, p->sent); break; - case CP_VARLIST: - { - char buf[CTL_MAX_DATA_LEN]; - register char *s, *t, *be; - register int i; - register struct ctl_var *k; - - s = buf; - be = buf + sizeof(buf); - if (s + strlen(peer_var[CP_VARLIST].text) + 4 > be) - break; /* really long var name */ - - snprintf(s, sizeof(buf), "%s=\"", - peer_var[CP_VARLIST].text); - s += strlen(s); - t = s; - for (k = peer_var; !(k->flags & EOV); k++) { - if (k->flags & PADDING) - continue; - - i = strlen(k->text); - if (s + i + 1 >= be) - break; - - if (s != t) - *s++ = ','; - memcpy(s, k->text, i); - s += i; - } - if (s+2 >= be) - break; + case CP_VARLIST: + s = buf; + be = buf + sizeof(buf); + if (s + strlen(peer_var[id].text) + 4 > be) + break; /* really long var name */ - *s++ = '"'; - *s = '\0'; - ctl_putdata(buf, (unsigned)(s - buf), 0); - } - break; + snprintf(s, sizeof(buf), "%s=\"", peer_var[id].text); + s += strlen(s); + t = s; + for (k = peer_var; !(EOV & k->flags); k++) { + if (PADDING & k->flags) + continue; + i = strlen(k->text); + if (s + i + 1 >= be) + break; + if (s != t) + *s++ = ','; + memcpy(s, k->text, i); + s += i; + } + if (s + 2 < be) { + *s++ = '"'; + *s = '\0'; + ctl_putdata(buf, (u_int)(s - buf), 0); + } + break; #ifdef OPENSSL - case CP_FLAGS: - if (peer->crypto) - ctl_puthex(peer_var[CP_FLAGS].text, peer->crypto); + case CP_FLAGS: + if (p->crypto) + ctl_puthex(peer_var[id].text, p->crypto); break; - case CP_SIGNATURE: - if (peer->crypto) { - const EVP_MD *dp; - - dp = EVP_get_digestbynid(peer->crypto >> 16); - strcpy(str, OBJ_nid2ln(EVP_MD_pkey_type(dp))); - ctl_putstr(peer_var[CP_SIGNATURE].text, str, - strlen(str)); + case CP_SIGNATURE: + if (p->crypto) { + dp = EVP_get_digestbynid(p->crypto >> 16); + str = OBJ_nid2ln(EVP_MD_pkey_type(dp)); + ctl_putstr(peer_var[id].text, str, strlen(str)); } break; - case CP_HOST: - if (peer->subject != NULL) - ctl_putstr(peer_var[CP_HOST].text, - peer->subject, strlen(peer->subject)); + case CP_HOST: + if (p->subject != NULL) + ctl_putstr(peer_var[id].text, p->subject, + strlen(p->subject)); break; - case CP_VALID: /* not used */ + case CP_VALID: /* not used */ break; - case CP_INITSEQ: - if ((ap = (struct autokey *)peer->recval.ptr) == NULL) + case CP_INITSEQ: + if (NULL == (ap = p->recval.ptr)) break; ctl_putint(peer_var[CP_INITSEQ].text, ap->seq); ctl_puthex(peer_var[CP_INITKEY].text, ap->key); ctl_putfs(peer_var[CP_INITTSP].text, - ntohl(peer->recval.tstamp)); + ntohl(p->recval.tstamp)); break; #endif /* OPENSSL */ } @@ -1879,89 +1851,90 @@ ctl_putpeer( */ static void ctl_putclock( - int varid, - struct refclockstat *clock_stat, + int id, + struct refclockstat *pcs, int mustput ) { - switch(varid) { + switch (id) { case CC_TYPE: - if (mustput || clock_stat->clockdesc == NULL - || *(clock_stat->clockdesc) == '\0') { - ctl_putuint(clock_var[CC_TYPE].text, clock_stat->type); + if (mustput || pcs->clockdesc == NULL + || *(pcs->clockdesc) == '\0') { + ctl_putuint(clock_var[id].text, pcs->type); } break; case CC_TIMECODE: - ctl_putstr(clock_var[CC_TIMECODE].text, - clock_stat->p_lastcode, - (unsigned)clock_stat->lencode); + ctl_putstr(clock_var[id].text, + pcs->p_lastcode, + (unsigned)pcs->lencode); break; case CC_POLL: - ctl_putuint(clock_var[CC_POLL].text, clock_stat->polls); + ctl_putuint(clock_var[id].text, pcs->polls); break; case CC_NOREPLY: - ctl_putuint(clock_var[CC_NOREPLY].text, - clock_stat->noresponse); + ctl_putuint(clock_var[id].text, + pcs->noresponse); break; case CC_BADFORMAT: - ctl_putuint(clock_var[CC_BADFORMAT].text, - clock_stat->badformat); + ctl_putuint(clock_var[id].text, + pcs->badformat); break; case CC_BADDATA: - ctl_putuint(clock_var[CC_BADDATA].text, - clock_stat->baddata); + ctl_putuint(clock_var[id].text, + pcs->baddata); break; case CC_FUDGETIME1: - if (mustput || (clock_stat->haveflags & CLK_HAVETIME1)) - ctl_putdbl(clock_var[CC_FUDGETIME1].text, - clock_stat->fudgetime1 * 1e3); + if (mustput || (pcs->haveflags & CLK_HAVETIME1)) + ctl_putdbl(clock_var[id].text, + pcs->fudgetime1 * 1e3); break; case CC_FUDGETIME2: - if (mustput || (clock_stat->haveflags & CLK_HAVETIME2)) ctl_putdbl(clock_var[CC_FUDGETIME2].text, - clock_stat->fudgetime2 * 1e3); + if (mustput || (pcs->haveflags & CLK_HAVETIME2)) + ctl_putdbl(clock_var[id].text, + pcs->fudgetime2 * 1e3); break; case CC_FUDGEVAL1: - if (mustput || (clock_stat->haveflags & CLK_HAVEVAL1)) - ctl_putint(clock_var[CC_FUDGEVAL1].text, - clock_stat->fudgeval1); + if (mustput || (pcs->haveflags & CLK_HAVEVAL1)) + ctl_putint(clock_var[id].text, + pcs->fudgeval1); break; case CC_FUDGEVAL2: - if (mustput || (clock_stat->haveflags & CLK_HAVEVAL2)) { - if (clock_stat->fudgeval1 > 1) - ctl_putadr(clock_var[CC_FUDGEVAL2].text, - (u_int32)clock_stat->fudgeval2, NULL); + if (mustput || (pcs->haveflags & CLK_HAVEVAL2)) { + if (pcs->fudgeval1 > 1) + ctl_putadr(clock_var[id].text, + (u_int32)pcs->fudgeval2, NULL); else - ctl_putid(clock_var[CC_FUDGEVAL2].text, - (char *)&clock_stat->fudgeval2); + ctl_putid(clock_var[id].text, + (char *)&pcs->fudgeval2); } break; case CC_FLAGS: - if (mustput || (clock_stat->haveflags & (CLK_HAVEFLAG1 | + if (mustput || (pcs->haveflags & (CLK_HAVEFLAG1 | CLK_HAVEFLAG2 | CLK_HAVEFLAG3 | CLK_HAVEFLAG4))) - ctl_putuint(clock_var[CC_FLAGS].text, - clock_stat->flags); + ctl_putuint(clock_var[id].text, + pcs->flags); break; case CC_DEVICE: - if (clock_stat->clockdesc == NULL || - *(clock_stat->clockdesc) == '\0') { + if (pcs->clockdesc == NULL || + *(pcs->clockdesc) == '\0') { if (mustput) - ctl_putstr(clock_var[CC_DEVICE].text, + ctl_putstr(clock_var[id].text, "", 0); } else { - ctl_putstr(clock_var[CC_DEVICE].text, - clock_stat->clockdesc, - strlen(clock_stat->clockdesc)); + ctl_putstr(clock_var[id].text, + pcs->clockdesc, + strlen(pcs->clockdesc)); } break; @@ -1998,9 +1971,8 @@ ctl_putclock( s += i; } - for (k = clock_stat->kv_list; k && !(k->flags & - EOV); k++) { - if (k->flags & PADDING) + for (k = pcs->kv_list; k && !(EOV & k->flags); k++) { + if (PADDING & k->flags) continue; ss = k->text; @@ -2010,7 +1982,7 @@ ctl_putclock( while (*ss && *ss != '=') ss++; i = ss - k->text; - if (s+i+1 >= be) + if (s + i + 1 >= be) break; if (s != t) @@ -2019,12 +1991,12 @@ ctl_putclock( s += i; *s = '\0'; } - if (s+2 >= be) + if (s + 2 >= be) break; *s++ = '"'; *s = '\0'; - ctl_putdata(buf, (unsigned)( s - buf ), 0); + ctl_putdata(buf, (unsigned)(s - buf), 0); } break; } @@ -2042,11 +2014,12 @@ ctl_getitem( char **data ) { + static struct ctl_var eol = { 0, EOV, }; + static char buf[128]; + static u_long quiet_until; register struct ctl_var *v; register char *cp; register char *tp; - static struct ctl_var eol = { 0, EOV, }; - static char buf[128]; /* * Delete leading commas and white space @@ -2055,10 +2028,10 @@ ctl_getitem( isspace((unsigned char)*reqpt))) reqpt++; if (reqpt >= reqend) - return (0); + return NULL; - if (var_list == (struct ctl_var *)0) - return (&eol); + if (NULL == var_list) + return &eol; /* * Look for a first character match on the tag. If we find @@ -2066,18 +2039,18 @@ ctl_getitem( */ v = var_list; cp = reqpt; - while (!(v->flags & EOV)) { - if (!(v->flags & PADDING) && *cp == *(v->text)) { + for (v = var_list; !(EOV & v->flags); v++) { + if (!(PADDING & v->flags) && *cp == *(v->text)) { tp = v->text; - while (*tp != '\0' && *tp != '=' && cp < - reqend && *cp == *tp) { + while ('\0' != *tp && '=' != *tp && cp < reqend + && *cp == *tp) { cp++; tp++; } - if ((*tp == '\0') || (*tp == '=')) { - while (cp < reqend && isspace((unsigned char)*cp)) + if ('\0' == *tp || '=' == *tp) { + while (cp < reqend && isspace((u_char)*cp)) cp++; - if (cp == reqend || *cp == ',') { + if (cp == reqend || ',' == *cp) { buf[0] = '\0'; *data = buf; if (cp < reqend) @@ -2085,42 +2058,37 @@ ctl_getitem( reqpt = cp; return v; } - if (*cp == '=') { + if ('=' == *cp) { cp++; tp = buf; - while (cp < reqend && isspace((unsigned char)*cp)) + while (cp < reqend && isspace((u_char)*cp)) cp++; while (cp < reqend && *cp != ',') { *tp++ = *cp++; if (tp >= buf + sizeof(buf)) { ctl_error(CERR_BADFMT); numctlbadpkts++; -#if 0 /* Avoid possible DOS attack */ -/* If we get a smarter msyslog we can re-enable this */ - msyslog(LOG_WARNING, - "Possible 'ntpdx' exploit from %s:%d (possibly spoofed)\n", - stoa(rmt_addr), SRCPORT(rmt_addr) - ); -#endif - return (0); + NLOG(NLOG_SYSEVENT) + if (quiet_until <= current_time) { + quiet_until = current_time + 300; + msyslog(LOG_WARNING, +"Possible 'ntpdx' exploit from %s#%u (possibly spoofed)\n", stoa(rmt_addr), SRCPORT(rmt_addr)); + } + return NULL; } } if (cp < reqend) cp++; *tp-- = '\0'; - while (tp >= buf) { - if (!isspace((unsigned int)(*tp))) - break; + while (tp >= buf && isspace((u_char)*tp)) *tp-- = '\0'; - } reqpt = cp; *data = buf; - return (v); + return v; } } cp = reqpt; } - v++; } return v; } @@ -2143,15 +2111,15 @@ control_unspec( * I return no errors and no data, unless a specified assocation * doesn't exist. */ - if (res_associd != 0) { - if ((peer = findpeerbyassoc(res_associd)) == 0) { + if (res_associd) { + peer = findpeerbyassoc(res_associd); + if (NULL == peer) { ctl_error(CERR_BADASSOC); return; } rpkt.status = htons(ctlpeerstatus(peer)); - } else { + } else rpkt.status = htons(ctlsysstatus()); - } ctl_flushpkt(0); } @@ -2167,9 +2135,11 @@ read_status( int restrict_mask ) { - register int i; register struct peer *peer; - u_short ass_stat[CTL_MAX_DATA_LEN / sizeof(u_short)]; + register u_char *cp; + register int n; + /* a_st holds association ID, status pairs alternating */ + u_short a_st[CTL_MAX_DATA_LEN / sizeof(u_short)]; #ifdef DEBUG if (debug > 2) @@ -2180,166 +2150,175 @@ read_status( * zero we return all known assocation ID's. Otherwise * we return a bunch of stuff about the particular peer. */ - if (res_associd == 0) { - register int n; - - n = 0; - rpkt.status = htons(ctlsysstatus()); - for (i = 0; i < NTP_HASH_SIZE; i++) { - for (peer = assoc_hash[i]; peer != 0; - peer = peer->ass_next) { - ass_stat[n++] = htons(peer->associd); - ass_stat[n++] = - htons(ctlpeerstatus(peer)); - if (n == - CTL_MAX_DATA_LEN/sizeof(u_short)) { - ctl_putdata((char *)ass_stat, - n * sizeof(u_short), 1); - n = 0; - } - } - } - - if (n != 0) - ctl_putdata((char *)ass_stat, n * - sizeof(u_short), 1); - ctl_flushpkt(0); - } else { + if (res_associd) { peer = findpeerbyassoc(res_associd); - if (peer == 0) { + if (NULL == peer) { ctl_error(CERR_BADASSOC); - } else { - register u_char *cp; - - rpkt.status = htons(ctlpeerstatus(peer)); - if (res_authokay) - peer->num_events = 0; - /* - * For now, output everything we know about the - * peer. May be more selective later. - */ - for (cp = def_peer_var; *cp != 0; cp++) - ctl_putpeer((int)*cp, peer); - ctl_flushpkt(0); + return; } + rpkt.status = htons(ctlpeerstatus(peer)); + if (res_authokay) + peer->num_events = 0; + /* + * For now, output everything we know about the + * peer. May be more selective later. + */ + for (cp = def_peer_var; *cp != 0; cp++) + ctl_putpeer((int)*cp, peer); + ctl_flushpkt(0); + return; } + n = 0; + rpkt.status = htons(ctlsysstatus()); + for (peer = peer_list; peer != NULL; peer = peer->p_link) { + a_st[n++] = htons(peer->associd); + a_st[n++] = htons(ctlpeerstatus(peer)); + /* two entries each loop iteration, so n + 1 */ + if (n + 1 >= COUNTOF(a_st)) { + ctl_putdata((void *)a_st, n * sizeof(a_st[0]), + 1); + n = 0; + } + } + if (n) + ctl_putdata((void *)a_st, n * sizeof(a_st[0]), 1); + ctl_flushpkt(0); } /* - * read_variables - return the variables the caller asks for + * read_peervars - half of read_variables() implementation */ -/*ARGSUSED*/ static void -read_variables( - struct recvbuf *rbufp, - int restrict_mask - ) +read_peervars(void) { register struct ctl_var *v; + register struct peer *peer; + register u_char *cp; register int i; - char *valuep; + char * valuep; + u_char wants[CP_MAXCODE + 1]; + u_int gotvar; + + /* + * Wants info for a particular peer. See if we know + * the guy. + */ + peer = findpeerbyassoc(res_associd); + if (NULL == peer) { + ctl_error(CERR_BADASSOC); + return; + } + rpkt.status = htons(ctlpeerstatus(peer)); + if (res_authokay) + peer->num_events = 0; + memset(&wants, 0, sizeof(wants)); + gotvar = 0; + while (NULL != (v = ctl_getitem(peer_var, &valuep))) { + if (v->flags & EOV) { + ctl_error(CERR_UNKNOWNVAR); + return; + } + NTP_INSIST(v->code < COUNTOF(wants)); + wants[v->code] = 1; + gotvar = 1; + } + if (gotvar) { + for (i = 1; i < COUNTOF(wants); i++) + if (wants[i]) + ctl_putpeer(i, peer); + } else + for (cp = def_peer_var; *cp != 0; cp++) + ctl_putpeer((int)*cp, peer); + ctl_flushpkt(0); +} + + +/* + * read_sysvars - half of read_variables() implementation + */ +static void +read_sysvars(void) +{ + register struct ctl_var *v; + register struct ctl_var *kv; + u_int n; + u_int gotvar; + u_char *cs; + char * valuep; + char * pch; u_char *wants; - unsigned int gotvar = (CS_MAXCODE > CP_MAXCODE) ? (CS_MAXCODE + - 1) : (CP_MAXCODE + 1); - if (res_associd == 0) { - /* - * Wants system variables. Figure out which he wants - * and give them to him. - */ - rpkt.status = htons(ctlsysstatus()); - if (res_authokay) - ctl_sys_num_events = 0; - gotvar += count_var(ext_sys_var); - wants = (u_char *)emalloc(gotvar); - memset((char *)wants, 0, gotvar); - gotvar = 0; - while ((v = ctl_getitem(sys_var, &valuep)) != 0) { - if (v->flags & EOV) { - if ((v = ctl_getitem(ext_sys_var, - &valuep)) != 0) { - if (v->flags & EOV) { - ctl_error(CERR_UNKNOWNVAR); - free((char *)wants); - return; - } - wants[CS_MAXCODE + 1 + - v->code] = 1; - gotvar = 1; - continue; - } else { - break; /* shouldn't happen ! */ - } - } + size_t wants_count; + + /* + * Wants system variables. Figure out which he wants + * and give them to him. + */ + rpkt.status = htons(ctlsysstatus()); + if (res_authokay) + ctl_sys_num_events = 0; + wants_count = CS_MAXCODE + 1 + count_var(ext_sys_var); + wants = emalloc(wants_count); + memset(wants, 0, wants_count); + gotvar = 0; + while (NULL != (v = ctl_getitem(sys_var, &valuep))) { + if (!(EOV & v->flags)) { + NTP_INSIST(v->code < wants_count); wants[v->code] = 1; gotvar = 1; - } - if (gotvar) { - for (i = 1; i <= CS_MAXCODE; i++) - if (wants[i]) - ctl_putsys(i); - for (i = 0; ext_sys_var && - !(ext_sys_var[i].flags & EOV); i++) - if (wants[i + CS_MAXCODE + 1]) - ctl_putdata(ext_sys_var[i].text, - strlen(ext_sys_var[i].text), - 0); } else { - register u_char *cs; - register struct ctl_var *kv; - - for (cs = def_sys_var; *cs != 0; cs++) - ctl_putsys((int)*cs); - for (kv = ext_sys_var; kv && !(kv->flags & EOV); - kv++) - if (kv->flags & DEF) - ctl_putdata(kv->text, - strlen(kv->text), 0); - } - free((char *)wants); - } else { - register struct peer *peer; - - /* - * Wants info for a particular peer. See if we know - * the guy. - */ - peer = findpeerbyassoc(res_associd); - if (peer == 0) { - ctl_error(CERR_BADASSOC); - return; - } - rpkt.status = htons(ctlpeerstatus(peer)); - if (res_authokay) - peer->num_events = 0; - wants = (u_char *)emalloc(gotvar); - memset((char*)wants, 0, gotvar); - gotvar = 0; - while ((v = ctl_getitem(peer_var, &valuep)) != 0) { - if (v->flags & EOV) { + v = ctl_getitem(ext_sys_var, &valuep); + NTP_INSIST(v != NULL); + if (EOV & v->flags) { ctl_error(CERR_UNKNOWNVAR); - free((char *)wants); + free(wants); return; } - wants[v->code] = 1; + n = v->code + CS_MAXCODE + 1; + NTP_INSIST(n < wants_count); + wants[n] = 1; gotvar = 1; } - if (gotvar) { - for (i = 1; i <= CP_MAXCODE; i++) - if (wants[i]) - ctl_putpeer(i, peer); - } else { - register u_char *cp; - - for (cp = def_peer_var; *cp != 0; cp++) - ctl_putpeer((int)*cp, peer); - } - free((char *)wants); } + if (gotvar) { + for (n = 1; n <= CS_MAXCODE; n++) + if (wants[n]) + ctl_putsys(n); + for (n = 0; n + CS_MAXCODE + 1 < wants_count; n++) + if (wants[n + CS_MAXCODE + 1]) { + pch = ext_sys_var[n].text; + ctl_putdata(pch, strlen(pch), 0); + } + } else { + for (cs = def_sys_var; *cs != 0; cs++) + ctl_putsys((int)*cs); + for (kv = ext_sys_var; kv && !(EOV & kv->flags); kv++) + if (DEF & kv->flags) + ctl_putdata(kv->text, strlen(kv->text), + 0); + } + free(wants); ctl_flushpkt(0); } +/* + * read_variables - return the variables the caller asks for + */ +/*ARGSUSED*/ +static void +read_variables( + struct recvbuf *rbufp, + int restrict_mask + ) +{ + if (res_associd) + read_peervars(); + else + read_sysvars(); +} + + /* * write_variables - write into variables. We only allow leap bit * writing this way. @@ -2531,11 +2510,11 @@ static void configure( /* - * read_clock_status - return clock radio status + * read_clockstatus - return clock radio status */ /*ARGSUSED*/ static void -read_clock_status( +read_clockstatus( struct recvbuf *rbufp, int restrict_mask ) @@ -2552,102 +2531,84 @@ read_clock_status( char *valuep; u_char *wants; unsigned int gotvar; - struct refclockstat clock_stat; - - if (res_associd == 0) { + register u_char *cc; + register struct ctl_var *kv; + struct refclockstat cs; + if (res_associd) + peer = findpeerbyassoc(res_associd); + else { /* * Find a clock for this jerk. If the system peer - * is a clock use it, else search the hash tables - * for one. + * is a clock use it, else search peer_list for one. */ - if (sys_peer != 0 && (sys_peer->flags & FLAG_REFCLOCK)) - { + if (sys_peer != NULL && (FLAG_REFCLOCK & + sys_peer->flags)) peer = sys_peer; - } else { - peer = 0; - for (i = 0; peer == 0 && i < NTP_HASH_SIZE; i++) { - for (peer = assoc_hash[i]; peer != 0; - peer = peer->ass_next) { - if (peer->flags & FLAG_REFCLOCK) - break; - } - } - if (peer == 0) { - ctl_error(CERR_BADASSOC); - return; - } - } - } else { - peer = findpeerbyassoc(res_associd); - if (peer == 0 || !(peer->flags & FLAG_REFCLOCK)) { - ctl_error(CERR_BADASSOC); - return; - } + else + for (peer = peer_list; + peer != NULL; + peer = peer->p_link) + if (FLAG_REFCLOCK & peer->flags) + break; + } + if (NULL == peer || !(FLAG_REFCLOCK & peer->flags)) { + ctl_error(CERR_BADASSOC); + return; } - /* * If we got here we have a peer which is a clock. Get his * status. */ - clock_stat.kv_list = (struct ctl_var *)0; - refclock_control(&peer->srcadr, (struct refclockstat *)0, - &clock_stat); - + cs.kv_list = NULL; + refclock_control(&peer->srcadr, NULL, &cs); + kv = cs.kv_list; /* * Look for variables in the packet. */ - rpkt.status = htons(ctlclkstatus(&clock_stat)); - gotvar = CC_MAXCODE + 1 + count_var(clock_stat.kv_list); - wants = (u_char *)emalloc(gotvar); - memset((char*)wants, 0, gotvar); + rpkt.status = htons(ctlclkstatus(&cs)); + gotvar = CC_MAXCODE + 1 + count_var(kv); + wants = emalloc(gotvar); + memset(wants, 0, gotvar); gotvar = 0; - while ((v = ctl_getitem(clock_var, &valuep)) != 0) { - if (v->flags & EOV) { - if ((v = ctl_getitem(clock_stat.kv_list, - &valuep)) != 0) { - if (v->flags & EOV) { - ctl_error(CERR_UNKNOWNVAR); - free((char*)wants); - free_varlist(clock_stat.kv_list); - return; - } - wants[CC_MAXCODE + 1 + v->code] = 1; - gotvar = 1; - continue; - } else { - break; /* shouldn't happen ! */ + while (NULL != (v = ctl_getitem(clock_var, &valuep))) { + if (!(EOV & v->flags)) { + wants[v->code] = 1; + gotvar = 1; + } else { + v = ctl_getitem(kv, &valuep); + NTP_INSIST(NULL != v); + if (EOV & v->flags) { + ctl_error(CERR_UNKNOWNVAR); + free(wants); + free_varlist(cs.kv_list); + return; } + wants[CC_MAXCODE + 1 + v->code] = 1; + gotvar = 1; } - wants[v->code] = 1; - gotvar = 1; } if (gotvar) { for (i = 1; i <= CC_MAXCODE; i++) if (wants[i]) - ctl_putclock(i, &clock_stat, 1); - for (i = 0; clock_stat.kv_list && - !(clock_stat.kv_list[i].flags & EOV); i++) - if (wants[i + CC_MAXCODE + 1]) - ctl_putdata(clock_stat.kv_list[i].text, - strlen(clock_stat.kv_list[i].text), - 0); + ctl_putclock(i, &cs, 1); + if (kv != NULL) + for (i = 0; !(EOV & kv[i].flags); i++) + if (wants[i + CC_MAXCODE + 1]) + ctl_putdata(kv[i].text, + strlen(kv[i].text), 0); } else { - register u_char *cc; - register struct ctl_var *kv; - for (cc = def_clock_var; *cc != 0; cc++) - ctl_putclock((int)*cc, &clock_stat, 0); - for (kv = clock_stat.kv_list; kv && !(kv->flags & EOV); - kv++) - if (kv->flags & DEF) + ctl_putclock((int)*cc, &cs, 0); + for ( ; kv != NULL && !(EOV & kv->flags); kv++) + if (DEF & kv->flags) ctl_putdata(kv->text, strlen(kv->text), 0); } - free((char*)wants); - free_varlist(clock_stat.kv_list); + free(wants); + free_varlist(cs.kv_list); ctl_flushpkt(0); #endif @@ -2655,11 +2616,11 @@ read_clock_status( /* - * write_clock_status - we don't do this + * write_clockstatus - we don't do this */ /*ARGSUSED*/ static void -write_clock_status( +write_clockstatus( struct recvbuf *rbufp, int restrict_mask ) @@ -3038,24 +2999,23 @@ report_event( * reflect info on exception */ if (err == PEVNT_CLOCK) { - struct refclockstat clock_stat; + struct refclockstat cs; struct ctl_var *kv; - clock_stat.kv_list = (struct ctl_var *)0; - refclock_control(&peer->srcadr, - (struct refclockstat *)0, &clock_stat); + cs.kv_list = NULL; + refclock_control(&peer->srcadr, NULL, &cs); ctl_puthex("refclockstatus", - ctlclkstatus(&clock_stat)); + ctlclkstatus(&cs)); for (i = 1; i <= CC_MAXCODE; i++) - ctl_putclock(i, &clock_stat, 0); - for (kv = clock_stat.kv_list; kv && + ctl_putclock(i, &cs, 0); + for (kv = cs.kv_list; kv && !(kv->flags & EOV); kv++) if (kv->flags & DEF) ctl_putdata(kv->text, strlen(kv->text), 0); - free_varlist(clock_stat.kv_list); + free_varlist(cs.kv_list); } #endif /* REFCLOCK */ } @@ -3091,22 +3051,25 @@ ctl_clr_stats(void) numasyncmsgs = 0; } -static u_long +static u_short count_var( struct ctl_var *k ) { - register u_long c; + register u_int c; - if (!k) - return (0); + if (NULL == k) + return 0; c = 0; - while (!(k++->flags & EOV)) + while (!(EOV & (k++)->flags)) c++; - return (c); + + NTP_ENSURE(c <= USHRT_MAX); + return (u_short)c; } + char * add_var( struct ctl_var **kv, @@ -3114,27 +3077,23 @@ add_var( u_short def ) { - register u_long c; - register struct ctl_var *k; + register u_short c; + struct ctl_var *k; c = count_var(*kv); - + *kv = erealloc(*kv, (c + 2) * sizeof(**kv)); k = *kv; - *kv = (struct ctl_var *)emalloc((c+2)*sizeof(struct ctl_var)); - if (k) { - memmove((char *)*kv, (char *)k, - sizeof(struct ctl_var)*c); - free((char *)k); - } - (*kv)[c].code = (u_short) c; - (*kv)[c].text = (char *)emalloc(size); - (*kv)[c].flags = def; - (*kv)[c+1].code = 0; - (*kv)[c+1].text = (char *)0; - (*kv)[c+1].flags = EOV; - return (char *)(*kv)[c].text; + k[c].code = c; + k[c].text = emalloc(size); + k[c].flags = def; + k[c + 1].code = 0; + k[c + 1].text = NULL; + k[c + 1].flags = EOV; + + return k[c].text; } + void set_var( struct ctl_var **kv, @@ -3148,39 +3107,37 @@ set_var( register const char *t; char *td; - if (!data || !size) + if (NULL == data || !size) return; k = *kv; if (k != NULL) { - while (!(k->flags & EOV)) { - s = data; - t = k->text; - if (t) { + while (!(EOV & k->flags)) { + if (NULL == k->text) { + k->text = emalloc(size); + memcpy(k->text, data, size); + k->flags = def; + return; + } else { + s = data; + t = k->text; while (*t != '=' && *s - *t == 0) { s++; t++; } if (*s == *t && ((*t == '=') || !*t)) { - free((void *)k->text); - td = (char *)emalloc(size); - memmove(td, data, size); - k->text =td; + k->text = erealloc(k->text, + size); + memcpy(k->text, data, size); k->flags = def; return; } - } else { - td = (char *)emalloc(size); - memmove(td, data, size); - k->text = td; - k->flags = def; - return; } k++; } } td = add_var(kv, size, def); - memmove(td, data, size); + memcpy(td, data, size); } void diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index 609e8528..b3a013cc 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -161,7 +161,7 @@ static int crypto_mv (struct exten *, struct peer *); static int crypto_send (struct exten *, struct value *, int); static tstamp_t crypto_time (void); static u_long asn2ntp (ASN1_TIME *); -static struct cert_info *cert_parse (u_char *, long, tstamp_t); +static struct cert_info *cert_parse (const u_char *, long, tstamp_t); static int cert_sign (struct exten *, struct value *); static struct cert_info *cert_install (struct exten *, struct peer *); static int cert_hike (struct peer *, struct cert_info *); @@ -308,7 +308,7 @@ make_keylist( * cookie if client mode or the host cookie if symmetric modes. */ mpoll = 1 << min(peer->ppoll, peer->hpoll); - lifetime = min(1 << sys_automax, NTP_MAXSESSION * mpoll); + lifetime = min(1U << sys_automax, NTP_MAXSESSION * mpoll); if (peer->hmode == MODE_BROADCAST) cookie = 0; else @@ -401,7 +401,7 @@ crypto_recv( keyid_t cookie; /* crumbles */ int hismode; /* packet mode */ int rval = XEVNT_OK; - u_char *ptr; + const u_char *puch; u_int32 temp32; /* @@ -626,8 +626,8 @@ crypto_recv( * signature/digest NID. */ if (peer->pkey == NULL) { - ptr = (u_char *)xinfo->cert.ptr; - cert = d2i_X509(NULL, &ptr, + puch = xinfo->cert.ptr; + cert = d2i_X509(NULL, &puch, ntohl(xinfo->cert.vallen)); peer->pkey = X509_get_pubkey(cert); X509_free(cert); @@ -1551,13 +1551,14 @@ crypto_encrypt( tstamp_t tstamp; /* NTP timestamp */ u_int32 temp32; u_int len; - u_char *ptr; + const u_char *ptr; + u_char *puch; /* * Extract the public key from the request. */ len = ntohl(ep->vallen); - ptr = (u_char *)ep->pkt; + ptr = (void *)ep->pkt; pkey = d2i_PublicKey(EVP_PKEY_RSA, NULL, &ptr, len); if (pkey == NULL) { msyslog(LOG_ERR, "crypto_encrypt: %s", @@ -1575,9 +1576,9 @@ crypto_encrypt( len = EVP_PKEY_size(pkey); vp->vallen = htonl(len); vp->ptr = emalloc(len); - ptr = vp->ptr; + puch = vp->ptr; temp32 = htonl(*cookie); - if (RSA_public_encrypt(4, (u_char *)&temp32, ptr, + if (RSA_public_encrypt(4, (u_char *)&temp32, puch, pkey->pkey.rsa, RSA_PKCS1_OAEP_PADDING) <= 0) { msyslog(LOG_ERR, "crypto_encrypt: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -1743,7 +1744,7 @@ crypto_send( i = 0; if (vallen > 0 && vp->ptr != NULL) { j = vallen / 4; - if (j * 4 < vallen) + if (j * 4 < (int)vallen) ep->pkt[i + j++] = 0; memcpy(&ep->pkt[i], vp->ptr, vallen); i += j; @@ -1756,7 +1757,7 @@ crypto_send( ep->pkt[i++] = vp->siglen; if (siglen > 0 && vp->sig != NULL) { j = vallen / 4; - if (j * 4 < siglen) + if (j * 4 < (int)siglen) ep->pkt[i + j++] = 0; memcpy(&ep->pkt[i], vp->sig, siglen); i += j; @@ -2944,7 +2945,8 @@ cert_sign( EVP_MD_CTX ctx; /* message digest context */ tstamp_t tstamp; /* NTP timestamp */ u_int len; - u_char *ptr; + const u_char *cptr; + u_char *ptr; int i, temp; /* @@ -2956,8 +2958,8 @@ cert_sign( if (tstamp == 0) return (XEVNT_TSP); - ptr = (u_char *)ep->pkt; - if ((req = d2i_X509(NULL, &ptr, ntohl(ep->vallen))) == NULL) { + cptr = (void *)ep->pkt; + if ((req = d2i_X509(NULL, &cptr, ntohl(ep->vallen))) == NULL) { msyslog(LOG_ERR, "cert_sign: %s", ERR_error_string(ERR_get_error(), NULL)); return (XEVNT_CRT); @@ -3130,7 +3132,7 @@ cert_hike( { struct cert_info *xp; /* subject certificate */ X509 *cert; /* X509 certificate */ - u_char *ptr; + const u_char *ptr; /* * Save the issuer on the new certificate, but remember the old @@ -3219,7 +3221,7 @@ cert_hike( */ struct cert_info * /* certificate information structure */ cert_parse( - u_char *asn1cert, /* X509 certificate */ + const u_char *asn1cert, /* X509 certificate */ long len, /* certificate length */ tstamp_t fstamp /* filestamp */ ) @@ -3229,7 +3231,8 @@ cert_parse( struct cert_info *ret; /* certificate info/value */ BIO *bp; char pathbuf[MAXFILENAME]; - u_char *ptr; + const u_char *ptr; + char *pch; int temp, cnt, i; /* @@ -3249,8 +3252,8 @@ cert_parse( /* * Extract version, subject name and public key. */ - ret = emalloc(sizeof(struct cert_info)); - memset(ret, 0, sizeof(struct cert_info)); + ret = emalloc(sizeof(*ret)); + memset(ret, 0, sizeof(*ret)); if ((ret->pkey = X509_get_pubkey(cert)) == NULL) { msyslog(LOG_ERR, "cert_parse: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -3261,15 +3264,15 @@ cert_parse( ret->version = X509_get_version(cert); X509_NAME_oneline(X509_get_subject_name(cert), pathbuf, MAXFILENAME); - ptr = strstr(pathbuf, "CN="); - if (ptr == NULL) { + pch = strstr(pathbuf, "CN="); + if (NULL == pch) { msyslog(LOG_NOTICE, "cert_parse: invalid subject %s", pathbuf); cert_free(ret); X509_free(cert); return (NULL); } - ret->subject = estrdup(ptr + 3); + ret->subject = estrdup(pch + 3); /* * Extract remaining objects. Note that the NTP serial number is @@ -3284,14 +3287,14 @@ cert_parse( (u_long)ASN1_INTEGER_get(X509_get_serialNumber(cert)); X509_NAME_oneline(X509_get_issuer_name(cert), pathbuf, MAXFILENAME); - if ((ptr = strstr(pathbuf, "CN=")) == NULL) { + if ((pch = strstr(pathbuf, "CN=")) == NULL) { msyslog(LOG_NOTICE, "cert_parse: invalid issuer %s", pathbuf); cert_free(ret); X509_free(cert); return (NULL); } - ret->issuer = estrdup(ptr + 3); + ret->issuer = estrdup(pch + 3); ret->first = asn2ntp(X509_get_notBefore(cert)); ret->last = asn2ntp(X509_get_notAfter(cert)); @@ -3808,7 +3811,7 @@ crypto_setup(void) } else if (strcmp(hostval.ptr, sys_groupname) != 0) { msyslog(LOG_ERR, "crypto_setup: trusted certificate name %s does not match group name %s", - hostval.ptr, sys_groupname); + (char *)hostval.ptr, sys_groupname); exit (-1); } } diff --git a/ntpd/ntp_intres.c b/ntpd/ntp_intres.c index 5353c27f..d4afed53 100644 --- a/ntpd/ntp_intres.c +++ b/ntpd/ntp_intres.c @@ -845,7 +845,7 @@ scheduled_sleep( time_t now; if (scheduled < ignore_scheduled_before) { - DPRINTF(1, ("ignoring sleep until %s scheduled at %s (before %s)", + DPRINTF(1, ("ignoring sleep until %s scheduled at %s (before %s)\n", humantime(earliest), humantime(scheduled), humantime(ignore_scheduled_before))); return; @@ -854,7 +854,7 @@ scheduled_sleep( now = time(NULL); if (now < earliest) { - DPRINTF(1, ("sleep until %s scheduled at %s (>= %s)", + DPRINTF(1, ("sleep until %s scheduled at %s (>= %s)\n", humantime(earliest), humantime(scheduled), humantime(ignore_scheduled_before))); if (-1 == worker_sleep(earliest - now)) { @@ -866,7 +866,7 @@ scheduled_sleep( next_res_init = now + 60; res_init(); #endif - DPRINTF(1, ("sleep interrupted by daemon, ignoring sleeps scheduled before now (%s)", + DPRINTF(1, ("sleep interrupted by daemon, ignoring sleeps scheduled before now (%s)\n", humantime(ignore_scheduled_before))); } } diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 50febc1a..cb0461ef 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -949,7 +949,7 @@ remove_interface( } ninterfaces--; - ntp_monclearinterface(iface); + mon_clearinterface(iface); /* remove restrict interface entry */ SET_HOSTMASK(&resmask, AF(&iface->sin)); @@ -4183,6 +4183,17 @@ find_flagged_addr_in_list( } +char * +localaddrtoa( + struct interface *la + ) +{ + return (NULL == la) + ? "" + : stoa(&la->sin); +} + + #ifdef HAS_ROUTING_SOCKET # ifndef UPDATE_GRACE # define UPDATE_GRACE 2 /* wait UPDATE_GRACE seconds before scanning */ diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index 1846b552..32556d07 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -19,10 +19,6 @@ #include #include -#if defined(VMS) && defined(VMS_LOCALUNIT) /*wjm*/ -#include "ntp_refclock.h" -#endif /* VMS */ - #ifdef KERNEL_PLL #include "ntp_syscall.h" #endif /* KERNEL_PLL */ diff --git a/ntpd/ntp_monitor.c b/ntpd/ntp_monitor.c index 05dca322..b992a8fa 100644 --- a/ntpd/ntp_monitor.c +++ b/ntpd/ntp_monitor.c @@ -8,6 +8,7 @@ #include "ntpd.h" #include "ntp_io.h" #include "ntp_if.h" +#include "ntp_lists.h" #include "ntp_stdlib.h" #include @@ -44,11 +45,15 @@ * * ... I don't believe the above is true anymore ... jdg */ -#ifndef MAXMONMEM -#define MAXMONMEM 600 /* we allocate up to 600 structures */ +#ifdef MAXMONMEM /* old name */ +# define MAX_MONLIST MAXMONMEM +#elif !defined(MAX_MONLIST) +# define MAX_MONLIST 600 /* recycle LRU at this limit */ #endif -#ifndef MONMEMINC -#define MONMEMINC 40 /* allocate them 40 at a time */ +#ifdef MONMEMINC /* old name */ +# define INC_MONLIST MONMEMINC +#elif !defined(INC_MONLIST) +# define INC_MONLIST 15 /* allocation granularity */ #endif /* @@ -63,14 +68,14 @@ * for the hash and count tables is only allocated if monitoring is * turned on. */ -static struct mon_data *mon_hash[MON_HASH_SIZE]; /* list ptrs */ +static mon_entry *mon_hash[MON_HASH_SIZE]; /* list ptrs */ struct mon_data mon_mru_list; /* * List of free structures structures, and counters of free and total * structures. The free structures are linked with the hash_next field. */ -static struct mon_data *mon_free; /* free list or null if none */ +static mon_entry *mon_free; /* free list or null if none */ static int mon_total_mem; /* total structures allocated */ static int mon_mem_increments; /* times called malloc() */ @@ -81,17 +86,18 @@ static int mon_mem_increments; /* times called malloc() */ * is less than eight times the increment. */ int ntp_minpkt = NTP_MINPKT; /* minimum (log 2 s) */ -int ntp_minpoll = NTP_MINPOLL; /* increment (log 2 s) */ +u_char ntp_minpoll = NTP_MINPOLL; /* increment (log 2 s) */ /* * Initialization state. We may be monitoring, we may not. If * we aren't, we may not even have allocated any memory yet. */ -int mon_enabled; /* enable switch */ -int mon_age = 3000; /* preemption limit */ -static int mon_have_memory; -static void mon_getmoremem (void); -static void remove_from_hash (struct mon_data *); + int mon_enabled; /* enable switch */ + int mon_age = 3000; /* preemption limit */ +static int mon_have_memory; +static void mon_getmoremem(void); +static void remove_from_hash(mon_entry *); + /* * init_mon - initialize monitoring global data @@ -104,12 +110,6 @@ init_mon(void) * until someone explicitly starts us. */ mon_enabled = MON_OFF; - mon_have_memory = 0; - mon_total_mem = 0; - mon_mem_increments = 0; - mon_free = NULL; - memset(&mon_hash[0], 0, sizeof mon_hash); - memset(&mon_mru_list, 0, sizeof mon_mru_list); } @@ -121,24 +121,16 @@ mon_start( int mode ) { - - if (mon_enabled != MON_OFF) { + if (MON_OFF == mode) /* MON_OFF is 0 */ + return; + if (mon_enabled) { mon_enabled |= mode; return; } - if (mode == MON_OFF) - return; - - if (!mon_have_memory) { - mon_total_mem = 0; - mon_mem_increments = 0; - mon_free = NULL; + if (!mon_have_memory) mon_getmoremem(); - mon_have_memory = 1; - } - mon_mru_list.mru_next = &mon_mru_list; - mon_mru_list.mru_prev = &mon_mru_list; + INIT_DLIST(mon_mru_list, mru); mon_enabled = mode; } @@ -151,10 +143,10 @@ mon_stop( int mode ) { - register struct mon_data *md, *md_next; - register int i; + mon_entry *md; + int i; - if (mon_enabled == MON_OFF) + if (MON_OFF == mon_enabled) return; if ((mon_enabled & mode) == 0 || mode == MON_OFF) return; @@ -167,35 +159,36 @@ mon_stop( * Put everything back on the free list */ for (i = 0; i < MON_HASH_SIZE; i++) { - md = mon_hash[i]; /* get next list */ - mon_hash[i] = NULL; /* zero the list head */ - while (md != NULL) { - md_next = md->hash_next; - md->hash_next = mon_free; - mon_free = md; - md = md_next; + while (mon_hash[i] != NULL) { + UNLINK_HEAD_SLIST(md, mon_hash[i], hash_next); + memset(md, 0, sizeof(*md)); + LINK_SLIST(mon_free, md, hash_next); } } - mon_mru_list.mru_next = &mon_mru_list; - mon_mru_list.mru_prev = &mon_mru_list; + INIT_DLIST(mon_mru_list, mru); } + void -ntp_monclearinterface(struct interface *interface) +mon_clearinterface( + struct interface *lcladr + ) { - struct mon_data *md; - - for (md = mon_mru_list.mru_next; md != &mon_mru_list; - md = md->mru_next) { - if (md->interface == interface) { - /* dequeue from mru list and put to free list */ - md->mru_prev->mru_next = md->mru_next; - md->mru_next->mru_prev = md->mru_prev; - remove_from_hash(md); - md->hash_next = mon_free; - mon_free = md; + mon_entry *mon; + + /* iterate mon over mon_mru_list */ + ITER_DLIST_BEGIN(mon_mru_list, mon, mru, mon_entry) + + if (mon->lcladr == lcladr) { + /* remove from mru list and hash */ + UNLINK_DLIST(mon, mru); + remove_from_hash(mon); + /* put on free list */ + memset(mon, 0, sizeof(*mon)); + LINK_SLIST(mon_free, mon, hash_next); } - } + + ITER_DLIST_END() } @@ -210,21 +203,22 @@ ntp_monitor( int flags ) { - register struct pkt *pkt; - register struct mon_data *md; - sockaddr_u addr; - register u_int hash; - register int mode; - int interval; + struct pkt * pkt; + mon_entry * md; + sockaddr_u addr; + u_int hash; + u_char mode; + u_char version; + int interval; if (mon_enabled == MON_OFF) return (flags); pkt = &rbufp->recv_pkt; - memset(&addr, 0, sizeof(addr)); - memcpy(&addr, &(rbufp->recv_srcadr), sizeof(addr)); + memcpy(&addr, &rbufp->recv_srcadr, sizeof(addr)); hash = MON_HASH(&addr); mode = PKT_MODE(pkt->li_vn_mode); + version = PKT_VERSION(pkt->li_vn_mode); md = mon_hash[hash]; while (md != NULL) { int head; /* headway increment */ @@ -240,18 +234,13 @@ ntp_monitor( md->count++; md->flags = flags; md->rmtport = NSRCPORT(&rbufp->recv_srcadr); - md->mode = (u_char) mode; - md->version = PKT_VERSION(pkt->li_vn_mode); + md->vn_mode = VN_MODE(version, mode); /* * Shuffle to the head of the MRU list. */ - md->mru_next->mru_prev = md->mru_prev; - md->mru_prev->mru_next = md->mru_next; - md->mru_next = mon_mru_list.mru_next; - md->mru_prev = &mon_mru_list; - mon_mru_list.mru_next->mru_prev = md; - mon_mru_list.mru_next = md; + UNLINK_DLIST(md, mru); + LINK_DLIST(mon_mru_list, md, mru); /* * At this point the most recent arrival is @@ -289,12 +278,12 @@ ntp_monitor( leak < limit) { md->leak = leak - 2; md->flags &= ~(RES_LIMITED | RES_KOD); - } else if (md->leak < limit) { + } else if (md->leak < limit) md->leak = limit + head; - } else { + else md->flags &= ~RES_KOD; - } - return (md->flags); + + return md->flags; } md = md->hash_next; } @@ -304,24 +293,22 @@ ntp_monitor( * guy. Get him some memory, either from the free list * or from the tail of the MRU list. */ - if (mon_free == NULL && mon_total_mem >= MAXMONMEM) { - + if (NULL == mon_free && mon_total_mem >= MAX_MONLIST) { /* * Preempt from the MRU list if old enough. */ - md = mon_mru_list.mru_prev; + md = TAIL_DLIST(mon_mru_list, mru); if (md->count == 1 || ntp_random() / (2. * FRAC) > (double)(current_time - md->lasttime) / mon_age) - return (flags & ~RES_LIMITED); + return ~RES_LIMITED & flags; - md->mru_prev->mru_next = &mon_mru_list; - mon_mru_list.mru_prev = md->mru_prev; + UNLINK_DLIST(md, mru); remove_from_hash(md); + memset(md, 0, sizeof(*md)); } else { - if (mon_free == NULL) + if (NULL == mon_free) mon_getmoremem(); - md = mon_free; - mon_free = md->hash_next; + UNLINK_HEAD_SLIST(md, mon_free, hash_next); } /* @@ -331,28 +318,23 @@ ntp_monitor( md->count = 1; md->flags = flags & ~RES_LIMITED; md->leak = 0; - memset(&md->rmtadr, 0, sizeof(md->rmtadr)); - memcpy(&md->rmtadr, &addr, sizeof(addr)); + memcpy(&md->rmtadr, &addr, sizeof(md->rmtadr)); md->rmtport = NSRCPORT(&rbufp->recv_srcadr); - md->mode = (u_char) mode; - md->version = PKT_VERSION(pkt->li_vn_mode); - md->interface = rbufp->dstadr; + md->vn_mode = VN_MODE(version, mode); + md->lcladr = rbufp->dstadr; md->cast_flags = (u_char)(((rbufp->dstadr->flags & - INT_MCASTOPEN) && rbufp->fd == md->interface->fd) ? - MDF_MCAST: rbufp->fd == md->interface->bfd ? MDF_BCAST : + INT_MCASTOPEN) && rbufp->fd == md->lcladr->fd) ? + MDF_MCAST: rbufp->fd == md->lcladr->bfd ? MDF_BCAST : MDF_UCAST); /* * Drop him into front of the hash table. Also put him on top of * the MRU list. */ - md->hash_next = mon_hash[hash]; - mon_hash[hash] = md; - md->mru_next = mon_mru_list.mru_next; - md->mru_prev = &mon_mru_list; - mon_mru_list.mru_next->mru_prev = md; - mon_mru_list.mru_next = md; - return (md->flags); + LINK_SLIST(mon_hash[hash], md, hash_next); + LINK_DLIST(mon_mru_list, md, mru); + + return md->flags; } @@ -362,47 +344,31 @@ ntp_monitor( static void mon_getmoremem(void) { - register struct mon_data *md; - register int i; - struct mon_data *freedata; /* 'old' free list (null) */ - - md = (struct mon_data *)emalloc(MONMEMINC * - sizeof(struct mon_data)); - freedata = mon_free; - mon_free = md; - for (i = 0; i < (MONMEMINC-1); i++) { - md->hash_next = (md + 1); - md++; - } + mon_entry *md; + int i; - /* - * md now points at the last. Link in the rest of the chain. - */ - md->hash_next = freedata; - mon_total_mem += MONMEMINC; + md = emalloc(INC_MONLIST * sizeof(*md)); + memset(md, 0, INC_MONLIST * sizeof(*md)); + + for (i = INC_MONLIST - 1; i >= 0; i--) + LINK_SLIST(mon_free, &md[i], hash_next); + + mon_total_mem += INC_MONLIST; mon_mem_increments++; + mon_have_memory = 1; } + static void remove_from_hash( - struct mon_data *md + mon_entry *mon ) { - register u_int hash; - register struct mon_data *md_prev; + u_int hash; + mon_entry *punlinked; - hash = MON_HASH(&md->rmtadr); - if (mon_hash[hash] == md) { - mon_hash[hash] = md->hash_next; - } else { - md_prev = mon_hash[hash]; - while (md_prev->hash_next != md) { - md_prev = md_prev->hash_next; - if (md_prev == NULL) { - /* logic error */ - return; - } - } - md_prev->hash_next = md->hash_next; - } + hash = MON_HASH(&mon->rmtadr); + UNLINK_SLIST(punlinked, mon_hash[hash], mon, hash_next, + mon_entry); + NTP_ENSURE(punlinked == mon); } diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index 9c36194e..06e00e73 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -17,10 +17,6 @@ #include "openssl/rand.h" #endif /* OPENSSL */ -#ifdef SYS_WINNT -extern int accept_wildcard_if_for_winnt; -#endif - /* * Table of valid association combinations * --------------------------------------- @@ -68,11 +64,19 @@ int AM[AM_MODES][AM_MODES] = { /* * These routines manage the allocation of memory to peer structures - * and the maintenance of the peer hash table. The three main entry - * points are findpeer(), which looks for matching peer structures in - * the peer list, newpeer(), which allocates a new peer structure and - * adds it to the list, and unpeer(), which demobilizes the association - * and deallocates the structure. + * and the maintenance of three data structures involving all peers: + * + * - peer_list is a single list with all peers, suitable for scanning + * operations over all peers. + * - peer_adr_hash is an array of lists indexed by hashed peer address. + * - peer_aid_hash is an array of lists indexed by hashed associd. + * + * They also maintain a free list of peer structures, peer_free. + * + * The three main entry points are findpeer(), which looks for matching + * peer structures in the peer list, newpeer(), which allocates a new + * peer structure and adds it to the list, and unpeer(), which + * demobilizes the association and deallocates the structure. */ /* * Peer hash tables @@ -80,21 +84,23 @@ int AM[AM_MODES][AM_MODES] = { struct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */ int peer_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */ struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */ -int assoc_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */ +int assoc_hash_count[NTP_HASH_SIZE];/* peers in each bucket */ +struct peer *peer_list; /* peer structures list */ static struct peer *peer_free; /* peer structures free list */ +int peer_count; /* count of peer_list */ int peer_free_count; /* count of free structures */ /* * Association ID. We initialize this value randomly, then assign a new - * value every time the peer structure is incremented. + * value every time an association is mobilized. */ static associd_t current_association_ID; /* association ID */ /* * Memory allocation watermarks. */ -#define INIT_PEER_ALLOC 15 /* initialize for 15 peers */ -#define INC_PEER_ALLOC 5 /* when run out, add 5 more */ +#define INIT_PEER_ALLOC 8 /* static preallocation */ +#define INC_PEER_ALLOC 4 /* add N more when empty */ /* * Miscellaneous statistic counters which may be queried. @@ -109,10 +115,11 @@ int peer_associations; /* mobilized associations */ int peer_preempt; /* preemptable associations */ static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */ -static void getmorepeermem (void); -static struct interface *select_peerinterface (struct peer *, sockaddr_u *, struct interface *, u_char); - -static int score(struct peer *); +static void getmorepeermem(void); +static int score(struct peer *); +static struct interface * select_peerinterface(struct peer *, + sockaddr_u *, struct interface *, + u_char); /* * init_peer - initialize peer data structures and counters @@ -123,35 +130,22 @@ static int score(struct peer *); void init_peer(void) { - register int i; - - /* - * Clear hash tables and counters. - */ - memset(peer_hash, 0, sizeof(peer_hash)); - memset(peer_hash_count, 0, sizeof(peer_hash_count)); - memset(assoc_hash, 0, sizeof(assoc_hash)); - memset(assoc_hash_count, 0, sizeof(assoc_hash_count)); - - /* - * Clear stat counters - */ - findpeer_calls = peer_allocations = 0; - assocpeer_calls = peer_demobilizations = 0; + int i; /* - * Initialize peer memory. + * Initialize peer free list from static allocation. */ - peer_free = NULL; - for (i = 0; i < INIT_PEER_ALLOC; i++) - LINK_SLIST(peer_free, &init_peer_alloc[i], next); - total_peer_structs = INIT_PEER_ALLOC; - peer_free_count = INIT_PEER_ALLOC; + for (i = COUNTOF(init_peer_alloc) - 1; i >= 0; i--) + LINK_SLIST(peer_free, &init_peer_alloc[i], p_link); + total_peer_structs = COUNTOF(init_peer_alloc); + peer_free_count = COUNTOF(init_peer_alloc); /* * Initialize our first association ID */ - while ((current_association_ID = ntp_random() & 0xffff) == 0); + do + current_association_ID = ntp_random() & ASSOCID_MAX; + while (!current_association_ID); } @@ -161,15 +155,14 @@ init_peer(void) static void getmorepeermem(void) { - register int i; - register struct peer *peer; - - peer = (struct peer *)emalloc(INC_PEER_ALLOC * - sizeof(struct peer)); - for (i = 0; i < INC_PEER_ALLOC; i++) { - LINK_SLIST(peer_free, peer, next); - peer++; - } + int i; + struct peer *peers; + + peers = emalloc(INC_PEER_ALLOC * sizeof(*peers)); + memset(peers, 0, INC_PEER_ALLOC * sizeof(*peers)); + + for (i = INC_PEER_ALLOC - 1; i >= 0; i--) + LINK_SLIST(peer_free, &peers[i], p_link); total_peer_structs += INC_PEER_ALLOC; peer_free_count += INC_PEER_ALLOC; @@ -177,7 +170,7 @@ getmorepeermem(void) /* - * findexistingpeer - return a pointer to a peer in the hash table + * findexistingpeer - search by address and return a pointer to a peer. */ struct peer * findexistingpeer( @@ -186,7 +179,7 @@ findexistingpeer( int mode ) { - register struct peer *peer; + struct peer *peer; /* * start_peer is included so we can locate instances of the @@ -195,16 +188,16 @@ findexistingpeer( if (NULL == start_peer) peer = peer_hash[NTP_HASH_ADDR(addr)]; else - peer = start_peer->next; + peer = start_peer->adr_link; while (peer != NULL) { if (SOCK_EQ(addr, &peer->srcadr) && NSRCPORT(addr) == NSRCPORT(&peer->srcadr) && (-1 == mode || peer->hmode == mode)) break; - peer = peer->next; + peer = peer->adr_link; } - return (peer); + return peer; } @@ -219,28 +212,28 @@ findpeer( int *action ) { - register struct peer *peer; + struct peer *p; u_int hash; findpeer_calls++; hash = NTP_HASH_ADDR(srcadr); - for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) { - if (SOCK_EQ(srcadr, &peer->srcadr) && - NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) { + for (p = peer_hash[hash]; p != NULL; p = p->adr_link) { + if (SOCK_EQ(srcadr, &p->srcadr) && + NSRCPORT(srcadr) == NSRCPORT(&p->srcadr)) { /* * if the association matching rules determine * that this is not a valid combination, then * look for the next valid peer association. */ - *action = MATCH_ASSOC(peer->hmode, pkt_mode); + *action = MATCH_ASSOC(p->hmode, pkt_mode); /* * if an error was returned, exit back right * here. */ if (*action == AM_ERR) - return ((struct peer *)0); + return NULL; /* * if a match is found, we stop our search. @@ -253,34 +246,31 @@ findpeer( /* * If no matching association is found */ - if (peer == 0) { + if (NULL == p) *action = MATCH_ASSOC(NO_PEER, pkt_mode); - return ((struct peer *)0); - } - set_peerdstadr(peer, dstadr); - return (peer); + else + set_peerdstadr(p, dstadr); + + return p; } /* - * findpeerbyassocid - find and return a peer using his association ID + * findpeerbyassoc - find and return a peer using his association ID */ struct peer * findpeerbyassoc( - u_int assoc + associd_t assoc ) { - register struct peer *peer; + struct peer *p; u_int hash; assocpeer_calls++; - hash = assoc & NTP_HASH_MASK; - for (peer = assoc_hash[hash]; peer != 0; peer = - peer->ass_next) { - if (assoc == peer->associd) - return (peer); - } - return (NULL); + for (p = assoc_hash[hash]; p != NULL; p = p->aid_link) + if (assoc == p->associd) + break; + return p; } @@ -290,26 +280,17 @@ findpeerbyassoc( void clear_all(void) { - struct peer *peer, *next_peer; - int n; + struct peer *p; /* * This routine is called when the clock is stepped, and so all * previously saved time values are untrusted. */ - for (n = 0; n < NTP_HASH_SIZE; n++) { - for (peer = peer_hash[n]; peer != 0; peer = next_peer) { - next_peer = peer->next; - if (!(peer->cast_flags & (MDF_ACAST | - MDF_MCAST | MDF_BCAST))) { - peer_clear(peer, "STEP"); - } - } - } -#ifdef DEBUG - if (debug) - printf("clear_all: at %lu\n", current_time); -#endif + for (p = peer_list; p != NULL; p = p->p_link) + if (!(MDF_SRVCASTMASK & p->cast_flags)) + peer_clear(p, "STEP"); + + DPRINTF(1, ("clear_all: at %lu\n", current_time)); } @@ -321,9 +302,9 @@ score_all( struct peer *peer /* peer structure pointer */ ) { - struct peer *speer, *next_peer; - int n; + struct peer *speer; int temp, tamp; + int x; /* * This routine finds the minimum score for all ephemeral @@ -332,25 +313,18 @@ score_all( */ tamp = score(peer); temp = 100; - for (n = 0; n < NTP_HASH_SIZE; n++) { - for (speer = peer_hash[n]; speer != 0; speer = - next_peer) { - int x; - - next_peer = speer->next; - if ((x = score(speer)) < temp && (peer->flags & - FLAG_PREEMPT)) - temp = x; - } + for (speer = peer_list; speer != NULL; speer = speer->p_link) { + x = score(speer); + if (x < temp && (FLAG_PREEMPT & peer->flags)) + temp = x; } -#ifdef DEBUG - if (debug) - printf("score_all: at %lu score %d min %d\n", - current_time, tamp, temp); -#endif + DPRINTF(1, ("score_all: at %lu score %d min %d\n", + current_time, tamp, temp)); + if (tamp != temp) temp = 0; - return (temp); + + return temp; } @@ -390,58 +364,65 @@ score( */ void unpeer( - struct peer *peer_to_remove + struct peer *peer ) { - register struct peer *unlinked; + struct peer *unlinked; int hash; char tbuf[80]; - snprintf(tbuf, sizeof(tbuf), "assoc %d", - peer_to_remove->associd); - report_event(PEVNT_DEMOBIL, peer_to_remove, tbuf); - set_peerdstadr(peer_to_remove, NULL); - hash = NTP_HASH_ADDR(&peer_to_remove->srcadr); + snprintf(tbuf, sizeof(tbuf), "assoc %u", peer->associd); + report_event(PEVNT_DEMOBIL, peer, tbuf); + set_peerdstadr(peer, NULL); + hash = NTP_HASH_ADDR(&peer->srcadr); peer_hash_count[hash]--; peer_demobilizations++; peer_associations--; - if (peer_to_remove->flags & FLAG_PREEMPT) + if (FLAG_PREEMPT & peer->flags) peer_preempt--; #ifdef REFCLOCK /* * If this peer is actually a clock, shut it down first */ - if (peer_to_remove->flags & FLAG_REFCLOCK) - refclock_unpeer(peer_to_remove); + if (FLAG_REFCLOCK & peer->flags) + refclock_unpeer(peer); #endif - peer_to_remove->action = 0; /* disable timeout actions */ - - UNLINK_SLIST(unlinked, peer_hash[hash], peer_to_remove, next, - struct peer); + peer->action = NULL; /* disable timeout actions */ + UNLINK_SLIST(unlinked, peer_hash[hash], peer, adr_link, + struct peer); if (NULL == unlinked) { peer_hash_count[hash]++; - msyslog(LOG_ERR, "peer struct for %s not in table!", - stoa(&peer_to_remove->srcadr)); + msyslog(LOG_ERR, "peer %s not in address table!", + stoa(&peer->srcadr)); } /* * Remove him from the association hash as well. */ - hash = peer_to_remove->associd & NTP_HASH_MASK; + hash = peer->associd & NTP_HASH_MASK; assoc_hash_count[hash]--; - UNLINK_SLIST(unlinked, assoc_hash[hash], peer_to_remove, - ass_next, struct peer); - + UNLINK_SLIST(unlinked, assoc_hash[hash], peer, aid_link, + struct peer); if (NULL == unlinked) { assoc_hash_count[hash]++; msyslog(LOG_ERR, - "peer struct for %s not in association table!", - stoa(&peer_to_remove->srcadr)); + "peer %s not in association ID table!", + stoa(&peer->srcadr)); } - LINK_SLIST(peer_free, peer_to_remove, next); + /* Remove him from the overall list. */ + UNLINK_SLIST(unlinked, peer_list, peer, p_link, struct peer); + if (NULL == unlinked) + msyslog(LOG_ERR, "%s not in peer list!", + stoa(&peer->srcadr)); + else + peer_count--; + + /* Add his corporeal form to peer free list */ + memset(peer, 0, sizeof(*peer)); + LINK_SLIST(peer_free, peer, p_link); peer_free_count++; } @@ -453,13 +434,13 @@ struct peer * peer_config( sockaddr_u *srcadr, struct interface *dstadr, - int hmode, - int version, - int minpoll, - int maxpoll, - u_int flags, - int ttl, - keyid_t key, + u_char hmode, + u_char version, + u_char minpoll, + u_char maxpoll, + u_int flags, + u_char ttl, + keyid_t key, u_char *keystr ) { @@ -531,9 +512,7 @@ set_peerdstadr( "%s interface %s -> %s", stoa(&peer->srcadr), stoa(&peer->dstadr->sin), - (interface != NULL) - ? stoa(&interface->sin) - : "(null)"); + latoa(interface)); } peer->dstadr = interface; if (peer->dstadr != NULL) { @@ -548,64 +527,54 @@ set_peerdstadr( */ static void peer_refresh_interface( - struct peer *peer + struct peer *p ) { struct interface *niface, *piface; - niface = select_peerinterface(peer, &peer->srcadr, NULL, - peer->cast_flags); - -#ifdef DEBUG - if (debug > 3) - { - printf( - "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ", - latoa(peer->dstadr), stoa(&peer->srcadr), - peer->hmode, peer->version, peer->minpoll, - peer->maxpoll, peer->flags, peer->cast_flags, - peer->ttl, peer->keyid); - if (niface != NULL) { - printf( - "fd=%d, bfd=%d, name=%.16s, flags=0x%x, scope=%d, ", - niface->fd, niface->bfd, niface->name, - niface->flags, niface->scopeid); - printf(", sin=%s", stoa((&niface->sin))); - if (niface->flags & INT_BROADCAST) - printf(", bcast=%s,", - stoa((&niface->bcast))); - printf(", mask=%s\n", stoa((&niface->mask))); - } else { - printf("\n"); - } + niface = select_peerinterface(p, &p->srcadr, NULL, + p->cast_flags); + + DPRINTF(4, ( + "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ", + latoa(p->dstadr), stoa(&p->srcadr), p->hmode, p->version, + p->minpoll, p->maxpoll, p->flags, p->cast_flags, p->ttl, + p->keyid)); + if (NULL == niface) + DPRINTF(4, ("\n")); + else { + DPRINTF(4, ( + "fd=%d, bfd=%d, name=%.16s, flags=0x%x, scope=%d, addr=%s", + niface->fd, niface->bfd, niface->name, + niface->flags, niface->scopeid, latoa(niface))); + if (niface->flags & INT_BROADCAST) + DPRINTF(4, (", bcast=%s,", + stoa(&niface->bcast))); + DPRINTF(4, (", mask=%s\n", stoa(&niface->mask))); } -#endif - piface = peer->dstadr; - set_peerdstadr(peer, niface); - if (peer->dstadr) { + piface = p->dstadr; + set_peerdstadr(p, niface); + if (p->dstadr != NULL) { /* * clear crypto if we change the local address */ - if (peer->dstadr != piface && !(peer->cast_flags & - MDF_ACAST) && peer->pmode != MODE_BROADCAST) - peer_clear(peer, "XFAC"); + if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags) + && MODE_BROADCAST != p->pmode) + peer_clear(p, "XFAC"); /* * Broadcast needs the socket enabled for broadcast */ - if (peer->cast_flags & MDF_BCAST) { - enable_broadcast(peer->dstadr, &peer->srcadr); - } + if (MDF_BCAST & p->cast_flags) + enable_broadcast(p->dstadr, &p->srcadr); /* * Multicast needs the socket interface enabled for * multicast */ - if (peer->cast_flags & MDF_MCAST) { - enable_multicast_if(peer->dstadr, - &peer->srcadr); - } + if (MDF_MCAST & p->cast_flags) + enable_multicast_if(p->dstadr, &p->srcadr); } } @@ -616,19 +585,14 @@ peer_refresh_interface( void refresh_all_peerinterfaces(void) { - struct peer *peer, *next_peer; - int n; + struct peer *p; /* * this is called when the interface list has changed * give all peers a chance to find a better interface */ - for (n = 0; n < NTP_HASH_SIZE; n++) { - for (peer = peer_hash[n]; peer != 0; peer = next_peer) { - next_peer = peer->next; - peer_refresh_interface(peer); - } - } + for (p = peer_list; p != NULL; p = p->p_link) + peer_refresh_interface(p); } @@ -656,7 +620,7 @@ select_peerinterface( if (ISREFCLOCKADR(srcadr)) interface = loopback_interface; else - if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) { + if (cast_flags & (MDF_BCLNT | MDF_SRVCASTMASK)) { interface = findbcastinter(srcadr); #ifdef DEBUG if (debug > 3) { @@ -704,13 +668,13 @@ struct peer * newpeer( sockaddr_u *srcadr, struct interface *dstadr, - int hmode, - int version, - int minpoll, - int maxpoll, + u_char hmode, + u_char version, + u_char minpoll, + u_char maxpoll, u_int flags, u_char cast_flags, - int ttl, + u_char ttl, keyid_t key ) { @@ -761,7 +725,7 @@ newpeer( * associations. */ if (peer != NULL) - return (NULL); + return NULL; /* * Allocate a new peer structure. Some dirt here, since some of @@ -769,7 +733,7 @@ newpeer( */ if (peer_free_count == 0) getmorepeermem(); - UNLINK_HEAD_SLIST(peer, peer_free, next); + UNLINK_HEAD_SLIST(peer, peer_free, p_link); peer_free_count--; peer_associations++; if (flags & FLAG_PREEMPT) @@ -789,8 +753,8 @@ newpeer( peer->srcadr = *srcadr; set_peerdstadr(peer, select_peerinterface(peer, srcadr, dstadr, cast_flags)); - peer->hmode = (u_char)hmode; - peer->version = (u_char)version; + peer->hmode = hmode; + peer->version = version; peer->flags = flags; /* @@ -803,11 +767,11 @@ newpeer( if (minpoll == 0) peer->minpoll = NTP_MINDPOLL; else - peer->minpoll = (u_char)min(minpoll, NTP_MAXPOLL); + peer->minpoll = min(minpoll, NTP_MAXPOLL); if (maxpoll == 0) peer->maxpoll = NTP_MAXDPOLL; else - peer->maxpoll = (u_char)max(maxpoll, NTP_MINPOLL); + peer->maxpoll = max(maxpoll, NTP_MINPOLL); if (peer->minpoll > peer->maxpoll) peer->minpoll = peer->maxpoll; @@ -872,7 +836,7 @@ newpeer( * Dump it, something screwed up */ set_peerdstadr(peer, NULL); - LINK_SLIST(peer_free, peer, next); + LINK_SLIST(peer_free, peer, p_link); peer_free_count++; return (NULL); } @@ -883,18 +847,22 @@ newpeer( * Put the new peer in the hash tables. */ hash = NTP_HASH_ADDR(&peer->srcadr); - LINK_SLIST(peer_hash[hash], peer, next); + LINK_SLIST(peer_hash[hash], peer, adr_link); peer_hash_count[hash]++; hash = peer->associd & NTP_HASH_MASK; - LINK_SLIST(assoc_hash[hash], peer, ass_next); + LINK_SLIST(assoc_hash[hash], peer, aid_link); assoc_hash_count[hash]++; + LINK_SLIST(peer_list, peer, p_link); + peer_count++; + snprintf(tbuf, sizeof(tbuf), "assoc %d", peer->associd); report_event(PEVNT_MOBIL, peer, tbuf); + DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n", latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode, peer->version, peer->minpoll, peer->maxpoll, peer->flags, peer->cast_flags, peer->ttl, peer->keyid)); - return (peer); + return peer; } @@ -911,6 +879,7 @@ peer_clr_stats(void) peer_timereset = current_time; } + /* * peer_reset - reset statistics counters */ @@ -919,8 +888,8 @@ peer_reset( struct peer *peer ) { - if (peer == NULL) - return; + if (NULL == peer) + return; peer->timereset = current_time; peer->sent = 0; @@ -941,10 +910,8 @@ void peer_all_reset(void) { struct peer *peer; - int hash; - for (hash = 0; hash < NTP_HASH_SIZE; hash++) - for (peer = peer_hash[hash]; peer != 0; peer = peer->next) + for (peer = peer_list; peer != NULL; peer = peer->p_link) peer_reset(peer); } @@ -957,10 +924,9 @@ findmanycastpeer( struct recvbuf *rbufp /* receive buffer pointer */ ) { - register struct peer *peer; + struct peer *peer; struct pkt *pkt; l_fp p_org; - int i; /* * This routine is called upon arrival of a server-mode message @@ -970,18 +936,12 @@ findmanycastpeer( * for possibly more than one manycast association are unique. */ pkt = &rbufp->recv_pkt; - for (i = 0; i < NTP_HASH_SIZE; i++) { - if (peer_hash_count[i] == 0) - continue; - - for (peer = peer_hash[i]; peer != 0; peer = - peer->next) { - if (peer->cast_flags & MDF_ACAST) { - NTOHL_FP(&pkt->org, &p_org); - if (L_ISEQU(&p_org, &peer->aorg)) - return (peer); - } + for (peer = peer_list; peer != NULL; peer = peer->p_link) + if (MDF_ACAST & peer->cast_flags) { + NTOHL_FP(&pkt->org, &p_org); + if (L_ISEQU(&p_org, &peer->aorg)) + break; } - } - return (NULL); + + return peer; } diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index db5e04d5..4b544a06 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -21,10 +21,6 @@ #endif /* HAVE_LIBSCF_H */ -#if defined(VMS) && defined(VMS_LOCALUNIT) /*wjm*/ -#include "ntp_refclock.h" -#endif - /* * This macro defines the authentication state. If x is 1 authentication * is required; othewise it is optional. @@ -136,7 +132,7 @@ transmit( struct peer *peer /* peer structure pointer */ ) { - int hpoll; + u_char hpoll; /* * The polling state machine. There are two kinds of machines, @@ -296,10 +292,10 @@ receive( { register struct peer *peer; /* peer structure pointer */ register struct pkt *pkt; /* receive packet pointer */ - int hisversion; /* packet version */ - int hisleap; /* packet leap indicator */ - int hismode; /* packet mode */ - int hisstratum; /* packet stratum */ + u_char hisversion; /* packet version */ + u_char hisleap; /* packet leap indicator */ + u_char hismode; /* packet mode */ + u_char hisstratum; /* packet stratum */ int restrict_mask; /* restrict bits */ int has_mac; /* length of MAC field */ int authlen; /* offset of MAC field */ @@ -443,8 +439,8 @@ receive( } else { opcode = ntohl(((u_int32 *)pkt)[authlen / 4]); len = opcode & 0xffff; - if (len % 4 != 0 || len < 4 || len + authlen > - rbufp->recv_length) { + if (len % 4 != 0 || len < 4 || (int)len + + authlen > rbufp->recv_length) { sys_badlength++; return; /* bad length */ } @@ -1289,7 +1285,7 @@ receive( if (peer->flip != 0) { peer->rec = p_rec; peer->dst = rbufp->recv_time; - if (peer->nextdate - current_time < (1 << min(peer->ppoll, + if (peer->nextdate - current_time < (1U << min(peer->ppoll, peer->hpoll)) / 2) peer->nextdate++; else @@ -1777,11 +1773,12 @@ clock_update( void poll_update( struct peer *peer, /* peer structure pointer */ - int mpoll + u_char mpoll ) { - int hpoll, minpkt; + int minpkt; u_long next, utemp; + u_char hpoll; /* * This routine figures out when the next poll should be sent. @@ -1886,8 +1883,7 @@ poll_update( peer->nextdate = next; else peer->nextdate = utemp; - hpoll = peer->throttle - (1 << peer->minpoll); - if (hpoll > 0) + if (peer->throttle > (1 << peer->minpoll)) peer->nextdate += minpkt; } #ifdef DEBUG @@ -1911,7 +1907,7 @@ peer_clear( char *ident /* tally lights */ ) { - int i; + u_char u; #ifdef OPENSSL /* @@ -1953,9 +1949,9 @@ peer_clear( */ if (peer->flags & FLAG_XLEAVE) peer->flip = 1; - for (i = 0; i < NTP_SHIFT; i++) { - peer->filter_order[i] = i; - peer->filter_disp[i] = MAXDISPERSE; + for (u = 0; u < NTP_SHIFT; u++) { + peer->filter_order[u] = u; + peer->filter_disp[u] = MAXDISPERSE; } #ifdef REFCLOCK if (!(peer->flags & FLAG_REFCLOCK)) { @@ -2051,7 +2047,7 @@ clock_filter( peer->filter_disp[j] = MAXDISPERSE; dst[i] = MAXDISPERSE; } else if (peer->update - peer->filter_epoch[j] > - ULOGTOD(allan_xpt)) { + (u_long)ULOGTOD(allan_xpt)) { dst[i] = peer->filter_delay[j] + peer->filter_disp[j]; } else { @@ -2217,10 +2213,11 @@ clock_select(void) static int list_alloc = 0; static struct endpoint *endpoint = NULL; static int *indx = NULL; - static struct peer **peer_list = NULL; + static struct peer **peers = NULL; static u_int endpoint_size = 0; static u_int indx_size = 0; - static u_int peer_list_size = 0; + static u_int peers_size = 0; + size_t octets; /* * Initialize and create endpoint, index and peer lists big @@ -2234,24 +2231,18 @@ clock_select(void) sys_stratum = STRATUM_UNSPEC; memcpy(&sys_refid, "DOWN", 4); #endif /* LOCKCLOCK */ - nlist = 0; - for (n = 0; n < NTP_HASH_SIZE; n++) - nlist += peer_hash_count[n]; + nlist = peer_count; if (nlist > list_alloc) { - if (list_alloc > 0) { - free(endpoint); - free(indx); - free(peer_list); - } while (list_alloc < nlist) { list_alloc += 5; endpoint_size += 5 * 3 * sizeof(*endpoint); indx_size += 5 * 3 * sizeof(*indx); - peer_list_size += 5 * sizeof(*peer_list); + peers_size += 5 * sizeof(*peers); } - endpoint = (struct endpoint *)emalloc(endpoint_size); - indx = (int *)emalloc(indx_size); - peer_list = (struct peer **)emalloc(peer_list_size); + octets = endpoint_size + indx_size + peers_size; + endpoint = erealloc(endpoint, octets); + indx = (int *)((char *)endpoint + endpoint_size); + peers = (struct peer **)((char *)indx + indx_size); } /* @@ -2265,101 +2256,98 @@ clock_select(void) * bucks and collectively crank the chimes. */ nlist = nl3 = 0; /* none yet */ - for (n = 0; n < NTP_HASH_SIZE; n++) { - for (peer = peer_hash[n]; peer != NULL; peer = - peer->next) { - peer->flags &= ~FLAG_SYSPEER; - peer->status = CTL_PST_SEL_REJECT; + for (peer = peer_list; peer != NULL; peer = peer->p_link) { + peer->flags &= ~FLAG_SYSPEER; + peer->status = CTL_PST_SEL_REJECT; - /* - * Leave the island immediately if the peer is - * unfit to synchronize. - */ - if (peer_unfit(peer)) - continue; + /* + * Leave the island immediately if the peer is + * unfit to synchronize. + */ + if (peer_unfit(peer)) + continue; - /* - * If this is an orphan, choose the one with - * the lowest metric defined as the IPv4 address - * or the first 64 bits of the hashed IPv6 address. - */ - if (peer->stratum == sys_orphan) { - double ftemp; + /* + * If this is an orphan, choose the one with + * the lowest metric defined as the IPv4 address + * or the first 64 bits of the hashed IPv6 address. + */ + if (peer->stratum == sys_orphan) { + double ftemp; - ftemp = addr2refid(&peer->srcadr); - if (ftemp < orphdist) { - typeorphan = peer; - orphdist = ftemp; - } - continue; + ftemp = addr2refid(&peer->srcadr); + if (ftemp < orphdist) { + typeorphan = peer; + orphdist = ftemp; } + continue; + } #ifdef REFCLOCK - /* - * The following are special cases. We deal - * with them later. - */ - switch (peer->refclktype) { - case REFCLK_LOCALCLOCK: - if (typelocal == NULL && - !(peer->flags & FLAG_PREFER)) - typelocal = peer; - continue; + /* + * The following are special cases. We deal + * with them later. + */ + switch (peer->refclktype) { + case REFCLK_LOCALCLOCK: + if (typelocal == NULL && + !(peer->flags & FLAG_PREFER)) + typelocal = peer; + continue; - case REFCLK_ACTS: - if (typeacts == NULL && - !(peer->flags & FLAG_PREFER)) - typeacts = peer; - continue; - } + case REFCLK_ACTS: + if (typeacts == NULL && + !(peer->flags & FLAG_PREFER)) + typeacts = peer; + continue; + } #endif /* REFCLOCK */ - /* - * If we get this far, the peer can stay on the - * island, but does not yet have the immunity - * idol. - */ - peer->status = CTL_PST_SEL_SANE; - peer_list[nlist++] = peer; + /* + * If we get this far, the peer can stay on the + * island, but does not yet have the immunity + * idol. + */ + peer->status = CTL_PST_SEL_SANE; + peers[nlist++] = peer; - /* - * Insert each interval endpoint on the sorted - * list. - */ - e = peer->offset; /* Upper end */ - f = root_distance(peer); - e = e + f; - for (i = nl3 - 1; i >= 0; i--) { - if (e >= endpoint[indx[i]].val) - break; + /* + * Insert each interval endpoint on the sorted + * list. + */ + e = peer->offset; /* Upper end */ + f = root_distance(peer); + e = e + f; + for (i = nl3 - 1; i >= 0; i--) { + if (e >= endpoint[indx[i]].val) + break; - indx[i + 3] = indx[i]; - } - indx[i + 3] = nl3; - endpoint[nl3].type = 1; - endpoint[nl3++].val = e; + indx[i + 3] = indx[i]; + } + indx[i + 3] = nl3; + endpoint[nl3].type = 1; + endpoint[nl3++].val = e; - e = e - f; /* Center point */ - for (; i >= 0; i--) { - if (e >= endpoint[indx[i]].val) - break; + e = e - f; /* Center point */ + for (; i >= 0; i--) { + if (e >= endpoint[indx[i]].val) + break; - indx[i + 2] = indx[i]; - } - indx[i + 2] = nl3; - endpoint[nl3].type = 0; - endpoint[nl3++].val = e; + indx[i + 2] = indx[i]; + } + indx[i + 2] = nl3; + endpoint[nl3].type = 0; + endpoint[nl3++].val = e; - e = e - f; /* Lower end */ - for (; i >= 0; i--) { - if (e >= endpoint[indx[i]].val) - break; + e = e - f; /* Lower end */ + for (; i >= 0; i--) { + if (e >= endpoint[indx[i]].val) + break; - indx[i + 1] = indx[i]; - } - indx[i + 1] = nl3; - endpoint[nl3].type = -1; - endpoint[nl3++].val = e; + indx[i + 1] = indx[i]; } + indx[i + 1] = nl3; + endpoint[nl3].type = -1; + endpoint[nl3++].val = e; } #ifdef DEBUG if (debug > 2) @@ -2448,7 +2436,7 @@ clock_select(void) */ j = 0; for (i = 0; i < nlist; i++) { - peer = peer_list[i]; + peer = peers[i]; if (nlist > 1 && (peer->offset <= low || peer->offset >= high) && !(peer->flags & FLAG_TRUE)) continue; @@ -2482,11 +2470,11 @@ clock_select(void) if (d >= synch[k - 1]) break; - peer_list[k] = peer_list[k - 1]; + peers[k] = peers[k - 1]; error[k] = error[k - 1]; synch[k] = synch[k - 1]; } - peer_list[k] = peer; + peers[k] = peer; error[k] = peer->jitter; synch[k] = d; j++; @@ -2504,15 +2492,15 @@ clock_select(void) synch[0] = 0; #ifdef REFCLOCK if (typeacts != NULL) { - peer_list[0] = typeacts; + peers[0] = typeacts; nlist = 1; } else if (typelocal != NULL) { - peer_list[0] = typelocal; + peers[0] = typelocal; nlist = 1; } #endif /* REFCLOCK */ if (typeorphan != NULL) { - peer_list[0] = typeorphan; + peers[0] = typeorphan; nlist = 1; } } @@ -2521,11 +2509,11 @@ clock_select(void) * Mark the candidates at this point as truechimers. */ for (i = 0; i < nlist; i++) { - peer_list[i]->status = CTL_PST_SEL_SELCAND; + peers[i]->status = CTL_PST_SEL_SELCAND; #ifdef DEBUG if (debug > 1) printf("select: survivor %s %f\n", - stoa(&peer_list[i]->srcadr), synch[i]); + stoa(&peers[i]->srcadr), synch[i]); #endif } @@ -2549,8 +2537,8 @@ clock_select(void) f = 0; if (nlist > 1) { for (j = 0; j < nlist; j++) - f += DIFF(peer_list[j]->offset, - peer_list[i]->offset); + f += DIFF(peers[j]->offset, + peers[i]->offset); f = SQRT(f / (nlist - 1)); } if (f * synch[i] > e) { @@ -2563,7 +2551,7 @@ clock_select(void) if (nlist <= sys_minsane || nlist <= sys_minclock) { break; - } else if (f <= d || peer_list[k]->flags & + } else if (f <= d || peers[k]->flags & (FLAG_TRUE | FLAG_PREFER)) { seljitter = f; break; @@ -2572,12 +2560,12 @@ clock_select(void) if (debug > 2) printf( "select: drop %s seljit %.6f jit %.6f\n", - ntoa(&peer_list[k]->srcadr), g, d); + ntoa(&peers[k]->srcadr), g, d); #endif if (nlist > sys_maxclock) - peer_list[k]->status = CTL_PST_SEL_EXCESS; + peers[k]->status = CTL_PST_SEL_EXCESS; for (j = k + 1; j < nlist; j++) { - peer_list[j - 1] = peer_list[j]; + peers[j - 1] = peers[j]; synch[j - 1] = synch[j]; error[j - 1] = error[j]; } @@ -2597,7 +2585,7 @@ clock_select(void) */ leap_vote = 0; for (i = 0; i < nlist; i++) { - peer = peer_list[i]; + peer = peers[i]; peer->unreach = 0; peer->status = CTL_PST_SEL_SYNCCAND; sys_survivors++; @@ -2621,7 +2609,7 @@ clock_select(void) if (nlist > 0 && nlist >= sys_minsane) { double x; - typesystem = peer_list[0]; + typesystem = peers[0]; if (osys_peer == NULL || osys_peer == typesystem) { sys_clockhop = 0; } else if ((x = fabs(typesystem->offset - @@ -2653,7 +2641,7 @@ clock_select(void) if (typesystem != NULL) { if (sys_prefer == NULL) { typesystem->status = CTL_PST_SEL_SYSPEER; - clock_combine(peer_list, sys_survivors); + clock_combine(peers, sys_survivors); sys_jitter = SQRT(SQUARE(typesystem->jitter) + SQUARE(sys_jitter) + SQUARE(seljitter)); } else { @@ -3319,7 +3307,7 @@ fast_xmit( */ cookie = session_key(&rbufp->recv_srcadr, &rbufp->dstadr->sin, 0, sys_private, 0); - if (rbufp->recv_length > sendlen + MAX_MAC_LEN) { + if (rbufp->recv_length > sendlen + (int)MAX_MAC_LEN) { session_key(&rbufp->dstadr->sin, &rbufp->recv_srcadr, xkeyid, 0, 2); temp32 = CRYPTO_RESP; diff --git a/ntpd/ntp_refclock.c b/ntpd/ntp_refclock.c index 82752943..5d6e024c 100644 --- a/ntpd/ntp_refclock.c +++ b/ntpd/ntp_refclock.c @@ -758,6 +758,7 @@ refclock_open( msyslog(LOG_ERR, "refclock_open %s: %m", dev); return (0); } + NTP_INSIST(fd != 0); if (!refclock_setup(fd, speed, lflags)) { close(fd); return (0); @@ -769,6 +770,7 @@ refclock_open( return (fd); } + /* * refclock_setup - initialize terminal interface structure */ @@ -1311,7 +1313,7 @@ refclock_pps( /* * Convert to signed fraction offset and stuff in median filter. */ - pp->lastrec.l_ui = ap->ts.tv_sec + JAN_1970; + pp->lastrec.l_ui = (u_int32)ap->ts.tv_sec + JAN_1970; dtemp = ap->ts.tv_nsec / 1e9; pp->lastrec.l_uf = (u_int32)(dtemp * FRAC); if (dtemp > .5) diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index c863d2c5..76d60fa6 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -66,8 +66,8 @@ static char * prepare_pkt (sockaddr_u *, struct interface *, struct req_pkt *, size_t); static char * more_pkt (void); static void flush_pkt (void); -static void peer_list (sockaddr_u *, struct interface *, struct req_pkt *); -static void peer_list_sum (sockaddr_u *, struct interface *, struct req_pkt *); +static void list_peers (sockaddr_u *, struct interface *, struct req_pkt *); +static void list_peers_sum (sockaddr_u *, struct interface *, struct req_pkt *); static void peer_info (sockaddr_u *, struct interface *, struct req_pkt *); static void peer_stats (sockaddr_u *, struct interface *, struct req_pkt *); static void sys_info (sockaddr_u *, struct interface *, struct req_pkt *); @@ -81,6 +81,8 @@ static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *); static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long); +static void list_restrict4 (restrict_u *, struct info_restrict **); +static void list_restrict6 (restrict_u *, struct info_restrict **); static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *); static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *); static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); @@ -120,8 +122,8 @@ static void get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *) * ntpd request codes */ static struct req_proc ntp_codes[] = { - { REQ_PEER_LIST, NOAUTH, 0, 0, peer_list }, - { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, peer_list_sum }, + { REQ_PEER_LIST, NOAUTH, 0, 0, list_peers }, + { REQ_PEER_LIST_SUM, NOAUTH, 0, 0, list_peers_sum }, { REQ_PEER_INFO, NOAUTH, v4sizeof(struct info_peer_list), sizeof(struct info_peer_list), peer_info}, { REQ_PEER_STATS, NOAUTH, v4sizeof(struct info_peer_list), @@ -653,10 +655,10 @@ process_private( /* - * peer_list - send a list of the peers + * list_peers - send a list of the peers */ static void -peer_list( +list_peers( sockaddr_u *srcadr, struct interface *inter, struct req_pkt *inpkt @@ -664,56 +666,52 @@ peer_list( { register struct info_peer_list *ip; register struct peer *pp; - register int i; register int skip = 0; ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_peer_list)); - for (i = 0; i < NTP_HASH_SIZE && ip != 0; i++) { - pp = peer_hash[i]; - while (pp != 0 && ip != 0) { - if (IS_IPV6(&pp->srcadr)) { - if (client_v6_capable) { - ip->addr6 = SOCK_ADDR6(&pp->srcadr); - ip->v6_flag = 1; - skip = 0; - } else { - skip = 1; - break; - } - } else { - ip->addr = NSRCADR(&pp->srcadr); - if (client_v6_capable) - ip->v6_flag = 0; + for (pp = peer_list; pp != NULL && ip != NULL; pp = pp->p_link) { + if (IS_IPV6(&pp->srcadr)) { + if (client_v6_capable) { + ip->addr6 = SOCK_ADDR6(&pp->srcadr); + ip->v6_flag = 1; skip = 0; + } else { + skip = 1; + break; } + } else { + ip->addr = NSRCADR(&pp->srcadr); + if (client_v6_capable) + ip->v6_flag = 0; + skip = 0; + } - if(!skip) { - ip->port = NSRCPORT(&pp->srcadr); - ip->hmode = pp->hmode; - ip->flags = 0; - if (pp->flags & FLAG_CONFIG) - ip->flags |= INFO_FLAG_CONFIG; - if (pp == sys_peer) - ip->flags |= INFO_FLAG_SYSPEER; - if (pp->status == CTL_PST_SEL_SYNCCAND) - ip->flags |= INFO_FLAG_SEL_CANDIDATE; - if (pp->status >= CTL_PST_SEL_SYSPEER) - ip->flags |= INFO_FLAG_SHORTLIST; - ip = (struct info_peer_list *)more_pkt(); - } - pp = pp->next; + if (!skip) { + ip->port = NSRCPORT(&pp->srcadr); + ip->hmode = pp->hmode; + ip->flags = 0; + if (pp->flags & FLAG_CONFIG) + ip->flags |= INFO_FLAG_CONFIG; + if (pp == sys_peer) + ip->flags |= INFO_FLAG_SYSPEER; + if (pp->status == CTL_PST_SEL_SYNCCAND) + ip->flags |= INFO_FLAG_SEL_CANDIDATE; + if (pp->status >= CTL_PST_SEL_SYSPEER) + ip->flags |= INFO_FLAG_SHORTLIST; + ip = (struct info_peer_list *)more_pkt(); } - } + } /* for pp */ + flush_pkt(); } /* - * peer_list_sum - return extended peer list + * list_peers_sum - return extended peer list */ static void -peer_list_sum( +list_peers_sum( sockaddr_u *srcadr, struct interface *inter, struct req_pkt *inpkt @@ -721,94 +719,85 @@ peer_list_sum( { register struct info_peer_summary *ips; register struct peer *pp; - register int i; l_fp ltmp; register int skip; -#ifdef DEBUG - if (debug > 2) - printf("wants peer list summary\n"); -#endif + DPRINTF(3, ("wants peer list summary\n")); + ips = (struct info_peer_summary *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_peer_summary)); - for (i = 0; i < NTP_HASH_SIZE && ips != 0; i++) { - pp = peer_hash[i]; - while (pp != 0 && ips != 0) { -#ifdef DEBUG - if (debug > 3) - printf("sum: got one\n"); -#endif - /* - * Be careful here not to return v6 peers when we - * want only v4. - */ - if (IS_IPV6(&pp->srcadr)) { - if (client_v6_capable) { - ips->srcadr6 = SOCK_ADDR6(&pp->srcadr); - ips->v6_flag = 1; - if (pp->dstadr) - ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin); - else - memset(&ips->dstadr6, 0, sizeof(ips->dstadr6)); - skip = 0; - } else { - skip = 1; - break; - } + for (pp = peer_list; pp != NULL && ips != NULL; pp = pp->p_link) { + DPRINTF(4, ("sum: got one\n")); + /* + * Be careful here not to return v6 peers when we + * want only v4. + */ + if (IS_IPV6(&pp->srcadr)) { + if (client_v6_capable) { + ips->srcadr6 = SOCK_ADDR6(&pp->srcadr); + ips->v6_flag = 1; + if (pp->dstadr) + ips->dstadr6 = SOCK_ADDR6(&pp->dstadr->sin); + else + memset(&ips->dstadr6, 0, sizeof(ips->dstadr6)); + skip = 0; } else { - ips->srcadr = NSRCADR(&pp->srcadr); - if (client_v6_capable) - ips->v6_flag = 0; - - if (pp->dstadr) { - if (!pp->processed) + skip = 1; + break; + } + } else { + ips->srcadr = NSRCADR(&pp->srcadr); + if (client_v6_capable) + ips->v6_flag = 0; + + if (pp->dstadr) { + if (!pp->processed) + ips->dstadr = NSRCADR(&pp->dstadr->sin); + else { + if (MDF_BCAST == pp->cast_flags) + ips->dstadr = NSRCADR(&pp->dstadr->bcast); + else if (pp->cast_flags) { ips->dstadr = NSRCADR(&pp->dstadr->sin); - else { - if (MDF_BCAST == pp->cast_flags) + if (!ips->dstadr) ips->dstadr = NSRCADR(&pp->dstadr->bcast); - else if (pp->cast_flags) { - ips->dstadr = NSRCADR(&pp->dstadr->sin); - if (!ips->dstadr) - ips->dstadr = NSRCADR(&pp->dstadr->bcast); - } } - } else - ips->dstadr = 0; + } + } else + ips->dstadr = 0; - skip = 0; - } - - if (!skip){ - ips->srcport = NSRCPORT(&pp->srcadr); - ips->stratum = pp->stratum; - ips->hpoll = pp->hpoll; - ips->ppoll = pp->ppoll; - ips->reach = pp->reach; - ips->flags = 0; - if (pp == sys_peer) - ips->flags |= INFO_FLAG_SYSPEER; - if (pp->flags & FLAG_CONFIG) - ips->flags |= INFO_FLAG_CONFIG; - if (pp->flags & FLAG_REFCLOCK) - ips->flags |= INFO_FLAG_REFCLOCK; - if (pp->flags & FLAG_PREFER) - ips->flags |= INFO_FLAG_PREFER; - if (pp->flags & FLAG_BURST) - ips->flags |= INFO_FLAG_BURST; - if (pp->status == CTL_PST_SEL_SYNCCAND) - ips->flags |= INFO_FLAG_SEL_CANDIDATE; - if (pp->status >= CTL_PST_SEL_SYSPEER) - ips->flags |= INFO_FLAG_SHORTLIST; - ips->hmode = pp->hmode; - ips->delay = HTONS_FP(DTOFP(pp->delay)); - DTOLFP(pp->offset, <mp); - HTONL_FP(<mp, &ips->offset); - ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); - } - pp = pp->next; - ips = (struct info_peer_summary *)more_pkt(); + skip = 0; } - } + + if (!skip) { + ips->srcport = NSRCPORT(&pp->srcadr); + ips->stratum = pp->stratum; + ips->hpoll = pp->hpoll; + ips->ppoll = pp->ppoll; + ips->reach = pp->reach; + ips->flags = 0; + if (pp == sys_peer) + ips->flags |= INFO_FLAG_SYSPEER; + if (pp->flags & FLAG_CONFIG) + ips->flags |= INFO_FLAG_CONFIG; + if (pp->flags & FLAG_REFCLOCK) + ips->flags |= INFO_FLAG_REFCLOCK; + if (pp->flags & FLAG_PREFER) + ips->flags |= INFO_FLAG_PREFER; + if (pp->flags & FLAG_BURST) + ips->flags |= INFO_FLAG_BURST; + if (pp->status == CTL_PST_SEL_SYNCCAND) + ips->flags |= INFO_FLAG_SEL_CANDIDATE; + if (pp->status >= CTL_PST_SEL_SYSPEER) + ips->flags |= INFO_FLAG_SHORTLIST; + ips->hmode = pp->hmode; + ips->delay = HTONS_FP(DTOFP(pp->delay)); + DTOLFP(pp->offset, <mp); + HTONL_FP(<mp, &ips->offset); + ips->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); + } + ips = (struct info_peer_summary *)more_pkt(); + } /* for pp */ + flush_pkt(); } @@ -829,7 +818,6 @@ peer_info ( register int items; register int i, j; sockaddr_u addr; - extern struct peer *sys_peer; l_fp ltmp; items = INFO_NITEMS(inpkt->err_nitems); @@ -960,7 +948,6 @@ peer_stats ( register struct info_peer_stats *ip; register int items; sockaddr_u addr; - extern struct peer *sys_peer; #ifdef DEBUG if (debug) @@ -1178,17 +1165,6 @@ mem_stats( register struct info_mem_stats *ms; register int i; - /* - * Importations from the peer module - */ - extern int peer_hash_count[NTP_HASH_SIZE]; - extern int peer_free_count; - extern u_long peer_timereset; - extern u_long findpeer_calls; - extern u_long peer_allocations; - extern u_long peer_demobilizations; - extern int total_peer_structs; - ms = (struct info_mem_stats *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_mem_stats)); @@ -1199,14 +1175,11 @@ mem_stats( ms->allocations = htonl((u_int32)peer_allocations); ms->demobilizations = htonl((u_int32)peer_demobilizations); - for (i = 0; i < NTP_HASH_SIZE; i++) { - if (peer_hash_count[i] > 255) - ms->hashcount[i] = 255; - else - ms->hashcount[i] = (u_char)peer_hash_count[i]; - } + for (i = 0; i < NTP_HASH_SIZE; i++) + ms->hashcount[i] = (u_char) + max((u_int)peer_hash_count[i], UCHAR_MAX); - (void) more_pkt(); + more_pkt(); flush_pkt(); } @@ -1223,11 +1196,6 @@ io_stats( { register struct info_io_stats *io; - /* - * Importations from the io module - */ - extern u_long io_timereset; - io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_io_stats)); @@ -1261,13 +1229,6 @@ timer_stats( { register struct info_timer_stats *ts; - /* - * Importations from the timer module - */ - extern u_long timer_timereset; - extern u_long timer_overflows; - extern u_long timer_xmtcalls; - ts = (struct info_timer_stats *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_timer_stats)); @@ -1294,14 +1255,6 @@ loop_info( register struct info_loop *li; l_fp ltmp; - /* - * Importations from the loop filter module - */ - extern double last_offset; - extern double drift_comp; - extern int tc_counter; - extern u_long sys_epoch; - li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_loop)); @@ -1731,6 +1684,58 @@ setclr_flags( loop_config(LOOP_DRIFTCOMP, drift_comp); } +/* + * list_restrict4 - recursive helper for list_restrict dumps IPv4 + * restriction list in reverse order. + */ +static void +list_restrict4( + restrict_u * res, + struct info_restrict ** ppir + ) +{ + struct info_restrict * pir; + + if (res->link != NULL) + list_restrict4(res->link, ppir); + + pir = *ppir; + pir->addr = htonl(res->u.v4.addr); + if (client_v6_capable) + pir->v6_flag = 0; + pir->mask = htonl(res->u.v4.mask); + pir->count = htonl(res->count); + pir->flags = htons(res->flags); + pir->mflags = htons(res->mflags); + *ppir = (struct info_restrict *)more_pkt(); +} + + +/* + * list_restrict6 - recursive helper for list_restrict dumps IPv6 + * restriction list in reverse order. + */ +static void +list_restrict6( + restrict_u * res, + struct info_restrict ** ppir + ) +{ + struct info_restrict * pir; + + if (res->link != NULL) + list_restrict6(res->link, ppir); + + pir = *ppir; + pir->addr6 = res->u.v6.addr; + pir->mask6 = res->u.v6.mask; + pir->v6_flag = 1; + pir->count = htonl(res->count); + pir->flags = htons(res->flags); + pir->mflags = htons(res->mflags); + *ppir = (struct info_restrict *)more_pkt(); +} + /* * list_restrict - return the restrict list @@ -1742,43 +1747,26 @@ list_restrict( struct req_pkt *inpkt ) { - register struct info_restrict *ir; - register struct restrictlist *rl; - register struct restrictlist6 *rl6; + struct info_restrict *ir; -#ifdef DEBUG - if (debug > 2) - printf("wants restrict list summary\n"); -#endif + DPRINTF(3, ("wants restrict list summary\n")); ir = (struct info_restrict *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_restrict)); - for (rl = restrictlist; rl != 0 && ir != 0; rl = rl->next) { - ir->addr = htonl(rl->addr); - if (client_v6_capable) - ir->v6_flag = 0; - ir->mask = htonl(rl->mask); - ir->count = htonl((u_int32)rl->count); - ir->flags = htons(rl->flags); - ir->mflags = htons(rl->mflags); - ir = (struct info_restrict *)more_pkt(); - } + /* + * The restriction lists are kept sorted in the reverse order + * than they were originally. To preserve the output semantics, + * dump each list in reverse order. A recursive helper function + * achieves that. + */ + list_restrict4(restrictlist4, &ir); if (client_v6_capable) - for (rl6 = restrictlist6; rl6 != 0 && ir != 0; rl6 = rl6->next) { - ir->addr6 = rl6->addr6; - ir->mask6 = rl6->mask6; - ir->v6_flag = 1; - ir->count = htonl((u_int32)rl6->count); - ir->flags = htons(rl6->flags); - ir->mflags = htons(rl6->mflags); - ir = (struct info_restrict *)more_pkt(); - } + list_restrict6(restrictlist6, &ir); flush_pkt(); } - /* * do_resaddflags - add flags to a restrict entry (or create one) */ @@ -1913,9 +1901,7 @@ mon_getlist_0( ) { register struct info_monitor *im; - register struct mon_data *md; - extern struct mon_data mon_mru_list; - extern int mon_enabled; + register mon_entry *md; #ifdef DEBUG if (debug > 2) @@ -1927,8 +1913,8 @@ mon_getlist_0( } im = (struct info_monitor *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_monitor)); - for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; - md = md->mru_next) { + + ITER_DLIST_BEGIN(mon_mru_list, md, mru, mon_entry) im->lasttime = htonl((u_int32)((current_time - md->firsttime) / md->count)); im->firsttime = htonl((u_int32)(current_time - md->lasttime)); @@ -1945,10 +1931,13 @@ mon_getlist_0( im->v6_flag = 0; } im->port = md->rmtport; - im->mode = md->mode; - im->version = md->version; + im->mode = PKT_MODE(md->vn_mode); + im->version = PKT_VERSION(md->vn_mode); im = (struct info_monitor *)more_pkt(); - } + if (NULL == im) + break; + ITER_DLIST_END() + flush_pkt(); } @@ -1963,9 +1952,7 @@ mon_getlist_1( ) { register struct info_monitor_1 *im; - register struct mon_data *md; - extern struct mon_data mon_mru_list; - extern int mon_enabled; + register mon_entry *md; if (!mon_enabled) { req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); @@ -1973,8 +1960,8 @@ mon_getlist_1( } im = (struct info_monitor_1 *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_monitor_1)); - for (md = mon_mru_list.mru_next; md != &mon_mru_list && im != 0; - md = md->mru_next) { + + ITER_DLIST_BEGIN(mon_mru_list, md, mru, mon_entry) im->lasttime = htonl((u_int32)((current_time - md->firsttime) / md->count)); im->firsttime = htonl((u_int32)(current_time - md->lasttime)); @@ -1985,26 +1972,29 @@ mon_getlist_1( continue; im->addr6 = SOCK_ADDR6(&md->rmtadr); im->v6_flag = 1; - im->daddr6 = SOCK_ADDR6(&md->interface->sin); + im->daddr6 = SOCK_ADDR6(&md->lcladr->sin); } else { im->addr = NSRCADR(&md->rmtadr); if (client_v6_capable) im->v6_flag = 0; if (MDF_BCAST == md->cast_flags) - im->daddr = NSRCADR(&md->interface->bcast); + im->daddr = NSRCADR(&md->lcladr->bcast); else if (md->cast_flags) { - im->daddr = NSRCADR(&md->interface->sin); + im->daddr = NSRCADR(&md->lcladr->sin); if (!im->daddr) - im->daddr = NSRCADR(&md->interface->bcast); + im->daddr = NSRCADR(&md->lcladr->bcast); } else im->daddr = 4; } im->flags = htonl(md->cast_flags); im->port = md->rmtport; - im->mode = md->mode; - im->version = md->version; + im->mode = PKT_MODE(md->vn_mode); + im->version = PKT_VERSION(md->vn_mode); im = (struct info_monitor_1 *)more_pkt(); - } + if (NULL == im) + break; + ITER_DLIST_END() + flush_pkt(); } @@ -2013,7 +2003,7 @@ mon_getlist_1( */ struct reset_entry { int flag; /* flag this corresponds to */ - void (*handler) (void); /* routine to handle request */ + void (*handler)(void); /* routine to handle request */ }; struct reset_entry reset_entries[] = { @@ -2226,18 +2216,6 @@ get_auth_info( { register struct info_auth *ia; - /* - * Importations from the authentication module - */ - extern u_long authnumkeys; - extern int authnumfreekeys; - extern u_long authkeylookups; - extern u_long authkeynotfound; - extern u_long authencryptions; - extern u_long authdecryptions; - extern u_long authkeyuncached; - extern u_long authkeyexpired; - ia = (struct info_auth *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_auth)); @@ -2264,15 +2242,6 @@ get_auth_info( static void reset_auth_stats(void) { - /* - * Importations from the authentication module - */ - extern u_long authkeylookups; - extern u_long authkeynotfound; - extern u_long authencryptions; - extern u_long authdecryptions; - extern u_long authkeyuncached; - authkeylookups = 0; authkeynotfound = 0; authencryptions = 0; @@ -2296,12 +2265,6 @@ req_get_traps( register struct ctl_trap *tr; register int i; - /* - * Imported from the control module - */ - extern struct ctl_trap ctl_trap[]; - extern int num_ctl_traps; - if (num_ctl_traps == 0) { req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); return; @@ -2488,7 +2451,6 @@ set_control_keyid( ) { keyid_t keyid; - extern keyid_t ctl_auth_keyid; /* * Restrict ourselves to one item only. @@ -2518,25 +2480,6 @@ get_ctl_stats( { register struct info_control *ic; - /* - * Importations from the control module - */ - extern u_long ctltimereset; - extern u_long numctlreq; - extern u_long numctlbadpkts; - extern u_long numctlresponses; - extern u_long numctlfrags; - extern u_long numctlerrors; - extern u_long numctltooshort; - extern u_long numctlinputresp; - extern u_long numctlinputfrag; - extern u_long numctlinputerr; - extern u_long numctlbadoffset; - extern u_long numctlbadversion; - extern u_long numctldatatooshort; - extern u_long numctlbadop; - extern u_long numasyncmsgs; - ic = (struct info_control *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_control)); diff --git a/ntpd/ntp_restrict.c b/ntpd/ntp_restrict.c index d3080aad..3d97a841 100644 --- a/ntpd/ntp_restrict.c +++ b/ntpd/ntp_restrict.c @@ -10,6 +10,7 @@ #include "ntpd.h" #include "ntp_if.h" +#include "ntp_lists.h" #include "ntp_stdlib.h" /* @@ -41,39 +42,36 @@ * addresses. This is not protocol-independant but for now I can't * find a way to respect this. We'll check this later... JFB 07/2001 */ -#define SET_IPV6_ADDR_MASK(dst, src, msk) \ - do { \ - int idx; \ - for (idx = 0; idx < 16; idx++) { \ - (dst)->s6_addr[idx] = \ - (u_char) ((src)->s6_addr[idx] & (msk)->s6_addr[idx]); \ - } \ +#define MASK_IPV6_ADDR(dst, src, msk) \ + do { \ + int idx; \ + for (idx = 0; idx < COUNTOF((dst)->s6_addr); idx++) { \ + (dst)->s6_addr[idx] = (src)->s6_addr[idx] \ + & (msk)->s6_addr[idx]; \ + } \ } while (0) /* - * Memory allocation parameters. We allocate INITRESLIST entries - * initially, and add INCRESLIST entries to the free list whenever - * we run out. + * We allocate INC_RESLIST{4|6} entries to the free list whenever empty. + * Auto-tune these to be just less than 1KB (leaving at least 16 bytes + * for allocator overhead). */ -#define INITRESLIST 10 -#define INCRESLIST 5 +#define INC_RESLIST4 ((1024 - 16) / V4_SIZEOF_RESTRICT_U) +#define INC_RESLIST6 ((1024 - 16) / V6_SIZEOF_RESTRICT_U) /* * The restriction list */ -struct restrictlist *restrictlist; -struct restrictlist6 *restrictlist6; -static int restrictcount; /* count of entries in the res list */ -static int restrictcount6; /* count of entries in the res list 2*/ +restrict_u *restrictlist4; +restrict_u *restrictlist6; +static int restrictcount; /* count in the restrict lists */ /* * The free list and associated counters. Also some uninteresting * stat counters. */ -static struct restrictlist *resfree; -static struct restrictlist6 *resfree6; -static int numresfree; /* number of struct on free list */ -static int numresfree6; /* number of struct on free list 2 */ +static restrict_u *resfree4; /* available entries (free list) */ +static restrict_u *resfree6; static u_long res_calls; static u_long res_found; @@ -85,13 +83,26 @@ static u_long res_not_found; * control) */ static u_long res_limited_refcnt; -static u_long res_limited_refcnt6; /* - * Our initial allocation of lists entries. + * Our default entries. */ -static struct restrictlist resinit[INITRESLIST]; -static struct restrictlist6 resinit6[INITRESLIST]; +static restrict_u restrict_def4; +static restrict_u restrict_def6; + +/* + * private functions + */ +static restrict_u * alloc_res4(void); +static restrict_u * alloc_res6(void); +static void inc_res_limited(void); +static void dec_res_limited(void); +static restrict_u * match_restrict4_addr(u_int32, u_short); +static restrict_u * match_restrict6_addr(const struct in6_addr *, + u_short); +static restrict_u * match_restrict_entry(const restrict_u *, int); +static int res_sorts_before4(restrict_u *, restrict_u *); +static int res_sorts_before6(restrict_u *, restrict_u *); /* @@ -100,49 +111,250 @@ static struct restrictlist6 resinit6[INITRESLIST]; void init_restrict(void) { - register int i; - /* - * Zero the list and put all but one on the free list + * The restriction lists begin with a default entry with address + * and mask 0, which will match any entry. The lists are kept + * sorted by descending address followed by descending mask: + * + * address mask + * 192.168.0.0 255.255.255.0 kod limited noquery nopeer + * 192.168.0.0 255.255.0.0 kod limited + * 0.0.0.0 0.0.0.0 kod limited noquery + * + * The first entry which matches an address is used. With the + * example restrictions above, 192.168.0.0/24 matches the first + * entry, the rest of 192.168.0.0/16 matches the second, and + * everything else matches the third (default). + * + * Note this achieves the same result a little more efficiently + * than the documented behavior, which is to keep the lists + * sorted by ascending address followed by ascending mask, with + * the _last_ matching entry used. + * + * An additional wrinkle is we may have multiple entries with + * the same address and mask but differing match flags (mflags). + * At present there is only one, RESM_NTPONLY. Entries with + * RESM_NTPONLY are sorted earlier so they take precedence over + * any otherwise similar entry without. Again, this is the same + * behavior as but reversed implementation compared to the docs. + * */ - resfree = 0; - memset((char *)resinit, 0, sizeof resinit); - resfree6 = 0; - memset((char *)resinit6, 0, sizeof resinit6); - for (i = 1; i < INITRESLIST; i++) { - resinit[i].next = resfree; - resinit6[i].next = resfree6; - resfree = &resinit[i]; - resfree6 = &resinit6[i]; + LINK_SLIST(restrictlist4, &restrict_def4, link); + LINK_SLIST(restrictlist6, &restrict_def6, link); + restrictcount = 2; +} + + +static restrict_u * +alloc_res4(void) +{ + const size_t cb = V4_SIZEOF_RESTRICT_U; + const size_t count = INC_RESLIST4; + restrict_u * rl; + restrict_u * res; + int i; + + UNLINK_HEAD_SLIST(res, resfree4, link); + if (res != NULL) + return res; + + rl = emalloc(count * cb); + memset(rl, 0, count * cb); + /* link all but the first onto free list */ + res = (void *)((char *)rl + (count - 1) * cb); + for (i = count - 1; i > 0; i--) { + LINK_SLIST(resfree4, res, link); + res = (void *)((char *)res - cb); } - numresfree = INITRESLIST-1; - numresfree6 = INITRESLIST-1; + NTP_INSIST(rl == res); + /* allocate the first */ + return res; +} - /* - * Put the remaining item at the head of the list as our default - * entry. Everything in here should be zero for now. - */ - resinit[0].addr = htonl(INADDR_ANY); - resinit[0].mask = 0; - memset(&resinit6[0].addr6, 0, sizeof(struct in6_addr)); - memset(&resinit6[0].mask6, 0, sizeof(struct in6_addr)); - restrictlist = &resinit[0]; - restrictlist6 = &resinit6[0]; - restrictcount = 1; - restrictcount = 2; - /* - * fix up stat counters - */ - res_calls = 0; - res_found = 0; - res_not_found = 0; +static restrict_u * +alloc_res6(void) +{ + const size_t cb = V6_SIZEOF_RESTRICT_U; + const size_t count = INC_RESLIST6; + restrict_u * rl; + restrict_u * res; + int i; + + UNLINK_HEAD_SLIST(res, resfree6, link); + if (res != NULL) + return res; + + rl = emalloc(count * cb); + memset(rl, 0, count * cb); + /* link all but the first onto free list */ + res = (void *)((char *)rl + (count - 1) * cb); + for (i = count - 1; i > 0; i--) { + LINK_SLIST(resfree4, res, link); + res = (void *)((char *)res - cb); + } + NTP_INSIST(rl == res); + /* allocate the first */ + return res; +} - /* - * set default values for RES_LIMIT functionality - */ - res_limited_refcnt = 0; - res_limited_refcnt6 = 0; + +static void +inc_res_limited(void) +{ + if (!res_limited_refcnt) + mon_start(MON_RES); + res_limited_refcnt++; +} + + +static void +dec_res_limited(void) +{ + res_limited_refcnt--; + if (!res_limited_refcnt) + mon_stop(MON_RES); +} + + +static restrict_u * +match_restrict4_addr( + u_int32 addr, + u_short port + ) +{ + restrict_u *res; + + for (res = restrictlist4; res != NULL; res = res->link) + if (res->u.v4.addr == (addr & res->u.v4.mask) + && (!(RESM_NTPONLY & res->mflags) + || NTP_PORT == port)) + break; + return res; +} + + +static restrict_u * +match_restrict6_addr( + const struct in6_addr * addr, + u_short port + ) +{ + restrict_u * res; + struct in6_addr masked; + + for (res = restrictlist6; res != NULL; res = res->link) { + MASK_IPV6_ADDR(&masked, addr, &res->u.v6.mask); + if (ADDR6_EQ(&masked, &res->u.v6.addr) + && (!(RESM_NTPONLY & res->mflags) + || NTP_PORT == port)) + break; + } + return res; +} + + +/* + * match_restrict_entry - find an exact match on a restrict list. + * + * Exact match is addr, mask, and mflags all equal. + * In order to use more common code for IPv4 and IPv6, this routine + * requires the caller to populate a restrict_u with mflags and either + * the v4 or v6 address and mask as appropriate. Other fields in the + * input restrict_u are ignored. + */ +static restrict_u * +match_restrict_entry( + const restrict_u * pmatch, + int v6 + ) +{ + restrict_u *res; + restrict_u *rlist; + size_t cb; + + if (v6) { + rlist = restrictlist6; + cb = sizeof(pmatch->u.v6); + } else { + rlist = restrictlist4; + cb = sizeof(pmatch->u.v4); + } + + for (res = rlist; res != NULL; res = res->link) + if (res->mflags == pmatch->mflags && + !memcmp(&res->u, &pmatch->u, cb)) + break; + return res; +} + + +/* + * res_sorts_before4 - compare two restrict4 entries + * + * Returns nonzero if r1 sorts before r2. We sort by descending + * address, then descending mask, then descending mflags, so sorting + * before means having a higher value. + */ +static int +res_sorts_before4( + restrict_u *r1, + restrict_u *r2 + ) +{ + int r1_before_r2; + + if (r1->u.v4.addr > r2->u.v4.addr) + r1_before_r2 = 1; + else if (r1->u.v4.addr < r2->u.v4.addr) + r1_before_r2 = 0; + else if (r1->u.v4.mask > r2->u.v4.mask) + r1_before_r2 = 1; + else if (r1->u.v4.mask < r2->u.v4.mask) + r1_before_r2 = 0; + else if (r1->mflags > r2->mflags) + r1_before_r2 = 1; + else + r1_before_r2 = 0; + + return r1_before_r2; +} + + +/* + * res_sorts_before6 - compare two restrict6 entries + * + * Returns nonzero if r1 sorts before r2. We sort by descending + * address, then descending mask, then descending mflags, so sorting + * before means having a higher value. + */ +static int +res_sorts_before6( + restrict_u *r1, + restrict_u *r2 + ) +{ + int r1_before_r2; + int cmp; + + cmp = ADDR6_CMP(&r1->u.v6.addr, &r2->u.v6.addr); + if (cmp > 0) /* r1->addr > r2->addr */ + r1_before_r2 = 1; + else if (cmp < 0) /* r2->addr > r1->addr */ + r1_before_r2 = 0; + else { + cmp = ADDR6_CMP(&r1->u.v6.mask, &r2->u.v6.mask); + if (cmp > 0) /* r1->mask > r2->mask*/ + r1_before_r2 = 1; + else if (cmp < 0) /* r2->mask > r1->mask */ + r1_before_r2 = 0; + else if (r1->mflags > r2->mflags) + r1_before_r2 = 1; + else + r1_before_r2 = 0; + } + + return r1_before_r2; } @@ -154,27 +366,13 @@ restrictions( sockaddr_u *srcadr ) { - struct restrictlist *rl; - struct restrictlist *match = NULL; - struct restrictlist6 *rl6; - struct restrictlist6 *match6 = NULL; - struct in6_addr hostaddr6; - struct in6_addr hostservaddr6; - u_int32 hostaddr; + restrict_u *match; + struct in6_addr *pin6; int flags = 0; - int isntpport; res_calls++; /* IPv4 source address */ if (IS_IPV4(srcadr)) { - - /* - * We need the host address in host order. Also need to - * know whether this is from the ntp port or not. - */ - hostaddr = SRCADR(srcadr); - isntpport = (NTP_PORT == SRCPORT(srcadr)); - /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, @@ -183,21 +381,15 @@ restrictions( if (IN_CLASSD(SRCADR(srcadr))) return (int)RES_IGNORE; + match = match_restrict4_addr(SRCADR(srcadr), + SRCPORT(srcadr)); + match->count++; /* - * Set match to first entry, which is default entry. - * Work our way down from there. + * res_not_found counts only use of the final default + * entry, not any "restrict default ntpport ...", which + * would be just before the final default. */ - match = restrictlist; - for (rl = match->next; rl != 0 && rl->addr <= hostaddr; - rl = rl->next) - if ((hostaddr & rl->mask) == rl->addr) { - if ((rl->mflags & RESM_NTPONLY) && - !isntpport) - continue; - match = rl; - } - match->count++; - if (match == restrictlist) + if (&restrict_def4 == match) res_not_found++; else res_found++; @@ -206,46 +398,23 @@ restrictions( /* IPv6 source address */ if (IS_IPV6(srcadr)) { - - /* - * We need the host address in network order. Also need - * to know whether this is from the ntp port or not. - */ - hostaddr6 = SOCK_ADDR6(srcadr); - isntpport = (NTP_PORT == SRCPORT(srcadr)); + pin6 = PSOCK_ADDR6(srcadr); /* * Ignore any packets with a multicast source address * (this should be done early in the receive process, * not later!) */ - if (IN6_IS_ADDR_MULTICAST(&hostaddr6)) + if (IN6_IS_ADDR_MULTICAST(pin6)) return (int)RES_IGNORE; - /* - * Set match to first entry, which is default entry. - * Work our way down from there. - */ - match6 = restrictlist6; - for (rl6 = match6->next; rl6 != 0 && - (memcmp(&(rl6->addr6), &hostaddr6, - sizeof(hostaddr6)) <= 0); rl6 = rl6->next) { - SET_IPV6_ADDR_MASK(&hostservaddr6, &hostaddr6, - &rl6->mask6); - if (memcmp(&hostservaddr6, &(rl6->addr6), - sizeof(hostservaddr6)) == 0) { - if ((rl6->mflags & RESM_NTPONLY) && - !isntpport) - continue; - match6 = rl6; - } - } - match6->count++; - if (match6 == restrictlist6) + match = match_restrict6_addr(pin6, SRCPORT(srcadr)); + match->count++; + if (&restrict_def6 == match) res_not_found++; else res_found++; - flags = match6->flags; + flags = match->flags; } return (flags); } @@ -259,323 +428,129 @@ hack_restrict( int op, sockaddr_u *resaddr, sockaddr_u *resmask, - int mflags, - int flags + u_short mflags, + u_short flags ) { - register u_int32 addr = 0; - register u_int32 mask = 0; - struct in6_addr addr6; - struct in6_addr mask6; - register struct restrictlist *rl = NULL; - register struct restrictlist *rlprev = NULL; - register struct restrictlist6 *rl6 = NULL; - register struct restrictlist6 *rlprev6 = NULL; - int i, addr_cmp, mask_cmp; - - DPRINTF(1, ("restrict: addr %s mask %s mflags %08x flags %08x\n", - stoa(resaddr), stoa(resmask), mflags, flags)); - - memset(&addr6, 0, sizeof(addr6)); - memset(&mask6, 0, sizeof(mask6)); + int v6; + restrict_u match; + restrict_u * res; + restrict_u ** plisthead; + + DPRINTF(1, ("restrict: op %d addr %s mask %s mflags %08x flags %08x\n", + op, stoa(resaddr), stoa(resmask), mflags, flags)); + + memset(&match, 0, sizeof(match)); + /* silence VC9 potentially uninit warnings */ + res = NULL; + v6 = 0; if (IS_IPV4(resaddr)) { + v6 = 0; /* - * Get address and mask in host byte order + * Get address and mask in host byte order for easy + * comparison as u_int32 */ - addr = SRCADR(resaddr); - mask = SRCADR(resmask); - addr &= mask; /* make sure low bits zero */ + match.u.v4.addr = SRCADR(resaddr); + match.u.v4.mask = SRCADR(resmask); + match.u.v4.addr &= match.u.v4.mask; + } else if (IS_IPV6(resaddr)) { + v6 = 1; /* - * If this is the default address, point at first on - * list. Else go searching for it. + * Get address and mask in network byte order for easy + * comparison as byte sequences (e.g. memcmp()) */ - if (addr == 0) { - rlprev = 0; - rl = restrictlist; - } else { - rlprev = restrictlist; - rl = rlprev->next; - while (rl != 0) { - if (rl->addr > addr) { - rl = 0; - break; - } else if (rl->addr == addr) { - if (rl->mask == mask) { - if ((mflags & - RESM_NTPONLY) == - (rl->mflags & - RESM_NTPONLY)) - break; - - if (!(mflags & - RESM_NTPONLY)) { - rl = 0; - break; - } - } else if (rl->mask > mask) { - rl = 0; - break; - } - } - rlprev = rl; - rl = rl->next; - } - } - } + match.u.v6.mask = SOCK_ADDR6(resmask); + MASK_IPV6_ADDR(&match.u.v6.addr, PSOCK_ADDR6(resaddr), + &match.u.v6.mask); - if (IS_IPV6(resaddr)) { - mask6 = SOCK_ADDR6(resmask); - SET_IPV6_ADDR_MASK(&addr6, - PSOCK_ADDR6(resaddr), &mask6); - if (IN6_IS_ADDR_UNSPECIFIED(&addr6)) { - rlprev6 = NULL; - rl6 = restrictlist6; - } else { - rlprev6 = restrictlist6; - rl6 = rlprev6->next; - while (rl6 != 0) { - addr_cmp = memcmp(&rl6->addr6, &addr6, - sizeof(addr6)); - if (addr_cmp > 0) { - rl6 = 0; - break; - - } else if (addr_cmp == 0) { - mask_cmp = memcmp(&rl6->mask6, - &mask6, sizeof(mask6)); - if (mask_cmp == 0) { - if ((mflags & - RESM_NTPONLY) == - (rl6->mflags & - RESM_NTPONLY)) - break; - - if (!(mflags & - RESM_NTPONLY)) { - rl6 = 0; - break; - } - } else if (mask_cmp > 0) { - rl6 = 0; - break; - } - } - rlprev6 = rl6; - rl6 = rl6->next; - } - } - } + } else /* not IPv4 nor IPv6 */ + NTP_REQUIRE(0); - /* - * In case the above wasn't clear :-), either rl now points - * at the entry this call refers to, or rl is zero and rlprev - * points to the entry prior to where this one should go in - * the sort. - */ - /* - * Switch based on operation - */ - if (IS_IPV4(resaddr)) { - switch (op) { - case RESTRICT_FLAGS: - - /* - * Here we add bits to the flags. If this is a - * new restriction add it. - */ - if (rl == 0) { - if (numresfree == 0) { - rl = (struct restrictlist *) - emalloc(INCRESLIST * - sizeof(struct - restrictlist)); - memset((char *)rl, 0, - INCRESLIST * sizeof(struct - restrictlist)); - for (i = 0; i < INCRESLIST; - i++) { - rl->next = resfree; - resfree = rl; - rl++; - } - numresfree = INCRESLIST; - } - rl = resfree; - resfree = rl->next; - numresfree--; - rl->addr = addr; - rl->mask = mask; - rl->mflags = (u_short)mflags; - if (rlprev == NULL) { - rl->next = restrictlist; - restrictlist = rl; - } else { - rl->next = rlprev->next; - rlprev->next = rl; - } - restrictcount++; - } - if ((rl->flags ^ (u_short)flags) & - RES_LIMITED) { - res_limited_refcnt++; - mon_start(MON_RES); - } - rl->flags |= (u_short)flags; - break; + match.flags = flags; + match.mflags = mflags; + res = match_restrict_entry(&match, v6); - case RESTRICT_UNFLAG: - - /* - * Remove some bits from the flags. If we didn't - * find this one, just return. - */ - if (rl != 0) { - if ((rl->flags ^ (u_short)flags) & - RES_LIMITED) { - res_limited_refcnt--; - if (res_limited_refcnt == 0) - mon_stop(MON_RES); - } - rl->flags &= (u_short)~flags; - } - break; - - case RESTRICT_REMOVE: - case RESTRICT_REMOVEIF: - - /* - * Remove an entry from the table entirely if we - * found one. Don't remove the default entry and - * don't remove an interface entry. - */ - if (rl != 0 - && rl->addr != htonl(INADDR_ANY) - && !(rl->mflags & RESM_INTERFACE && op != - RESTRICT_REMOVEIF)) { - if (rlprev != NULL) { - rlprev->next = rl->next; - } else { - restrictlist = rl->next; - } - restrictcount--; - if (rl->flags & RES_LIMITED) { - res_limited_refcnt--; - if (res_limited_refcnt == 0) - mon_stop(MON_RES); - } - memset((char *)rl, 0, - sizeof(struct restrictlist)); - - rl->next = resfree; - resfree = rl; - numresfree++; - } - break; + switch (op) { - default: - break; - } - } else if (IS_IPV6(resaddr)) { - switch (op) { - case RESTRICT_FLAGS: - - /* - * Here we add bits to the flags. If this is a - * new restriction add it. - */ - if (rl6 == 0) { - if (numresfree6 == 0) { - rl6 = (struct - restrictlist6 *)emalloc( - INCRESLIST * sizeof(struct - restrictlist6)); - memset((char *)rl6, 0, - INCRESLIST * sizeof(struct - restrictlist6)); - - for (i = 0; i < INCRESLIST; - i++) { - rl6->next = resfree6; - resfree6 = rl6; - rl6++; - } - numresfree6 = INCRESLIST; - } - rl6 = resfree6; - resfree6 = rl6->next; - numresfree6--; - rl6->addr6 = addr6; - rl6->mask6 = mask6; - rl6->mflags = (u_short)mflags; - if (rlprev6 != NULL) { - rl6->next = rlprev6->next; - rlprev6->next = rl6; - } else { - rl6->next = restrictlist6; - restrictlist6 = rl6; - } - restrictcount6++; - } - if ((rl6->flags ^ (u_short)flags) & - RES_LIMITED) { - res_limited_refcnt6++; - mon_start(MON_RES); + case RESTRICT_FLAGS: + /* + * Here we add bits to the flags. If this is a + * new restriction add it. + */ + if (NULL == res) { + if (v6) { + res = alloc_res6(); + memcpy(res, &match, + V6_SIZEOF_RESTRICT_U); + plisthead = &restrictlist6; + } else { + res = alloc_res4(); + memcpy(res, &match, + V4_SIZEOF_RESTRICT_U); + plisthead = &restrictlist4; } - rl6->flags |= (u_short)flags; - break; + LINK_SORT_SLIST( + *plisthead, res, + (v6) + ? res_sorts_before6(res, L_S_S_CUR()) + : res_sorts_before4(res, L_S_S_CUR()), + link, restrict_u); + restrictcount++; + if (RES_LIMITED & flags) + inc_res_limited(); + } else { + if ((RES_LIMITED & flags) && + !(RES_LIMITED & res->flags)) + inc_res_limited(); + res->flags |= flags; + } + break; - case RESTRICT_UNFLAG: - - /* - * Remove some bits from the flags. If we didn't - * find this one, just return. - */ - if (rl6 != 0) { - if ((rl6->flags ^ (u_short)flags) & - RES_LIMITED) { - res_limited_refcnt6--; - if (res_limited_refcnt6 == 0) - mon_stop(MON_RES); - } - rl6->flags &= (u_short)~flags; - } - break; + case RESTRICT_UNFLAG: + /* + * Remove some bits from the flags. If we didn't + * find this one, just return. + */ + if (res != NULL) { + if ((RES_LIMITED & res->flags) + && (RES_LIMITED & flags)) + dec_res_limited(); + res->flags &= ~flags; + } + break; - case RESTRICT_REMOVE: - case RESTRICT_REMOVEIF: - - /* - * Remove an entry from the table entirely if we - * found one. Don't remove the default entry and - * don't remove an interface entry. - */ - if (rl6 != 0 && - !IN6_IS_ADDR_UNSPECIFIED(&rl6->addr6) - && !(rl6->mflags & RESM_INTERFACE && op != - RESTRICT_REMOVEIF)) { - if (rlprev6 != NULL) { - rlprev6->next = rl6->next; - } else { - restrictlist6 = rl6->next; - } - restrictcount6--; - if (rl6->flags & RES_LIMITED) { - res_limited_refcnt6--; - if (res_limited_refcnt6 == 0) - mon_stop(MON_RES); - } - memset((char *)rl6, 0, - sizeof(struct restrictlist6)); - rl6->next = resfree6; - resfree6 = rl6; - numresfree6++; + case RESTRICT_REMOVE: + case RESTRICT_REMOVEIF: + /* + * Remove an entry from the table entirely if we + * found one. Don't remove the default entry and + * don't remove an interface entry. + */ + if (res != NULL + && res != &restrict_def4 + && res != &restrict_def6 + && (RESTRICT_REMOVEIF == op + || !(RESM_INTERFACE & res->mflags))) { + + restrictcount--; + if (RES_LIMITED && res->flags) + dec_res_limited(); + if (v6) { + memset(res, 0, V6_SIZEOF_RESTRICT_U); + plisthead = &resfree6; + } else { + memset(res, 0, V4_SIZEOF_RESTRICT_U); + plisthead = &resfree4; } - break; - - default: - break; + LINK_SLIST(*plisthead, res, link); } + break; + + default: /* unknown op */ + NTP_INSIST(0); + break; } + } diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index 626ea3dd..bc12b412 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -246,7 +246,6 @@ void timer(void) { register struct peer *peer, *next_peer; - u_int n; l_fp now; /* @@ -259,12 +258,10 @@ timer(void) adjust_timer += 1; adj_host_clock(); #ifdef REFCLOCK - for (n = 0; n < NTP_HASH_SIZE; n++) { - for (peer = peer_hash[n]; peer != 0; peer = next_peer) { - next_peer = peer->next; - if (peer->flags & FLAG_REFCLOCK) - refclock_timer(peer); - } + for (peer = peer_list; peer != NULL; peer = next_peer) { + next_peer = peer->p_link; + if (peer->flags & FLAG_REFCLOCK) + refclock_timer(peer); } #endif /* REFCLOCK */ } @@ -274,31 +271,29 @@ timer(void) * careful here, since the peer structure might go away as the * result of the call. */ - for (n = 0; n < NTP_HASH_SIZE; n++) { - for (peer = peer_hash[n]; peer != 0; peer = next_peer) { - next_peer = peer->next; - if (peer->action && peer->nextaction <= - current_time) - peer->action(peer); - - /* - * Restrain the non-burst packet rate not more - * than one packet every 16 seconds. This is - * usually tripped using iburst and minpoll of - * 128 s or less. - */ - if (peer->throttle > 0) - peer->throttle--; - if (peer->nextdate <= current_time) { + for (peer = peer_list; peer != NULL; peer = next_peer) { + next_peer = peer->p_link; + if (peer->action != NULL && peer->nextaction <= + current_time) + (*peer->action)(peer); + + /* + * Restrain the non-burst packet rate not more + * than one packet every 16 seconds. This is + * usually tripped using iburst and minpoll of + * 128 s or less. + */ + if (peer->throttle > 0) + peer->throttle--; + if (peer->nextdate <= current_time) { #ifdef REFCLOCK - if (peer->flags & FLAG_REFCLOCK) - refclock_transmit(peer); - else - transmit(peer); -#else /* REFCLOCK */ + if (peer->flags & FLAG_REFCLOCK) + refclock_transmit(peer); + else transmit(peer); +#else /* REFCLOCK */ + transmit(peer); #endif /* REFCLOCK */ - } } } diff --git a/ntpd/ntp_util.c b/ntpd/ntp_util.c index 2e56af11..d3d6f246 100644 --- a/ntpd/ntp_util.c +++ b/ntpd/ntp_util.c @@ -18,6 +18,9 @@ #ifdef HAVE_SYS_IOCTL_H # include #endif +#ifdef HAVE_UNISTD_H +# include +#endif #ifdef HAVE_IEEEFP_H # include diff --git a/ntpd/refclock_chronolog.c b/ntpd/refclock_chronolog.c index ba4f60b4..cc766572 100644 --- a/ntpd/refclock_chronolog.c +++ b/ntpd/refclock_chronolog.c @@ -297,7 +297,7 @@ chronolog_receive( pp->lastref = pp->lastrec; refclock_receive(peer); record_clock_stats(&peer->srcadr, pp->a_lastcode); - up->lasthour = pp->hour; + up->lasthour = (u_char)pp->hour; } diff --git a/ntpd/refclock_chu.c b/ntpd/refclock_chu.c index de348863..ca14dc60 100644 --- a/ntpd/refclock_chu.c +++ b/ntpd/refclock_chu.c @@ -500,7 +500,7 @@ chu_start( snprintf(device, sizeof(device), DEVICE, unit); fd = refclock_open(device, SPEED232, LDISC_RAW); #endif /* HAVE_AUDIO */ - if (fd < 0) + if (fd <= 0) return (0); /* diff --git a/ntpd/refclock_dumbclock.c b/ntpd/refclock_dumbclock.c index 32e56f83..f300ac9b 100644 --- a/ntpd/refclock_dumbclock.c +++ b/ntpd/refclock_dumbclock.c @@ -121,7 +121,7 @@ dumbclock_start( printf ("starting Dumbclock with device %s\n",device); #endif fd = refclock_open(device, SPEED232, 0); - if (fd < 0) + if (!fd) return (0); /* diff --git a/ntpd/refclock_jupiter.c b/ntpd/refclock_jupiter.c index 16cfd877..68da2392 100644 --- a/ntpd/refclock_jupiter.c +++ b/ntpd/refclock_jupiter.c @@ -56,8 +56,8 @@ #define getshort(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) #define putshort(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) #else -#define getshort(s) (s) -#define putshort(s) (s) +#define getshort(s) ((u_short)(s)) +#define putshort(s) ((u_short)(s)) #endif /* XXX */ @@ -422,7 +422,7 @@ jupiter_pps(struct instance *instance) return 1; instance->ts = ts; - tstmp.l_ui = ts.tv_sec + JAN_1970; + tstmp.l_ui = (u_int32)ts.tv_sec + JAN_1970; dtemp = ts.tv_nsec * FRAC / 1e9; tstmp.l_uf = (u_int32)dtemp; instance->peer->procptr->lastrec = tstmp; @@ -538,7 +538,7 @@ jupiter_receive(struct recvbuf *rbufp) bpcnt = rbufp->recv_length; /* This shouldn't happen */ - if (bpcnt > sizeof(instance->sbuf) - instance->ssize) + if (bpcnt > (int)sizeof(instance->sbuf) - instance->ssize) bpcnt = sizeof(instance->sbuf) - instance->ssize; /* Append to input buffer */ @@ -612,7 +612,7 @@ jupiter_receive(struct recvbuf *rbufp) break; /* Add the new sample to a median filter */ - tstamp.l_ui = JAN_1970 + last_timecode; + tstamp.l_ui = JAN_1970 + (u_int32)last_timecode; tstamp.l_uf = 0; refclock_process_offset(pp, tstamp, pp->lastrec, pp->fudgetime1); @@ -932,8 +932,8 @@ jupiter_send(struct instance *instance, struct jheader *hp) if ((cc = write(instance->peer->procptr->io.fd, (char *)hp, size)) < 0) { snprintf(errstr, sizeof(errstr), "write: %s", strerror(errno)); return (errstr); - } else if (cc != size) { - snprintf(errstr, sizeof(errstr), "short write (%d != %d)", cc, size); + } else if (cc != (int)size) { + snprintf(errstr, sizeof(errstr), "short write (%d != %u)", cc, size); return (errstr); } return (NULL); diff --git a/ntpd/refclock_wwvb.c b/ntpd/refclock_wwvb.c index e327fb16..e53104bb 100644 --- a/ntpd/refclock_wwvb.c +++ b/ntpd/refclock_wwvb.c @@ -189,7 +189,7 @@ wwvb_start( * Open serial port. Use CLK line discipline, if available. */ snprintf(device, sizeof(device), DEVICE, unit); - if (-1 == (fd = refclock_open(device, SPEED232, LDISC_CLK))) + if (0 == (fd = refclock_open(device, SPEED232, LDISC_CLK))) return (0); /* diff --git a/ntpdate/ntpdate.c b/ntpdate/ntpdate.c index 16b8e7fe..082c5b08 100644 --- a/ntpdate/ntpdate.c +++ b/ntpdate/ntpdate.c @@ -88,7 +88,7 @@ UINT wTimerRes; # define NTPDATE_PRIO (100) #endif -#if defined(HAVE_TIMER_SETTIME) || defined (HAVE_TIMER_CREATE) +#ifdef HAVE_TIMER_CREATE /* POSIX TIMERS - vxWorks doesn't have itimer - casey */ static timer_t ntpdate_timerid; #endif @@ -1260,7 +1260,7 @@ clock_adjust(void) lfptoa(&server->offset, 6)); } } else { -#if !defined SYS_WINNT && !defined SYS_CYGWIN32 +#ifndef SYS_WINNT if (simple_query || l_adj_systime(&server->offset)) { msyslog(LOG_NOTICE, "adjust time server %s offset %s sec", stoa(&server->srcadr), @@ -1479,7 +1479,7 @@ alarming( { alarm_flag++; } -#else +#else /* SYS_WINNT follows */ void CALLBACK alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { @@ -1505,16 +1505,14 @@ static void init_alarm(void) { #ifndef SYS_WINNT -# ifndef HAVE_TIMER_SETTIME - struct itimerval itimer; +# ifdef HAVE_TIMER_CREATE + struct itimerspec its; # else - struct itimerspec ntpdate_itimer; + struct itimerval itv; # endif -#else +#else /* SYS_WINNT follows */ TIMECAPS tc; UINT wTimerID; -# endif /* SYS_WINNT */ -#if defined SYS_CYGWIN32 || defined SYS_WINNT HANDLE hToken; TOKEN_PRIVILEGES tkp; DWORD dwUser = 0; @@ -1523,7 +1521,7 @@ init_alarm(void) alarm_flag = 0; #ifndef SYS_WINNT -# if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) +# ifdef HAVE_TIMER_CREATE alarm_flag = 0; /* this code was put in as setitimer() is non existant this us the * POSIX "equivalents" setup - casey @@ -1545,44 +1543,26 @@ init_alarm(void) * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) * seconds from now and they continue on every 1/TIMER_HZ seconds. */ - (void) signal_no_reset(SIGALRM, alarming); - ntpdate_itimer.it_interval.tv_sec = ntpdate_itimer.it_value.tv_sec = 0; - ntpdate_itimer.it_interval.tv_nsec = 1000000000/TIMER_HZ; - ntpdate_itimer.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1); - timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &ntpdate_itimer, NULL); -# else + signal_no_reset(SIGALRM, alarming); + its.it_interval.tv_sec = 0; + its.it_value.tv_sec = 0; + its.it_interval.tv_nsec = 1000000000/TIMER_HZ; + its.it_value.tv_nsec = 1000000000/(TIMER_HZ<<1); + timer_settime(ntpdate_timerid, 0 /* !TIMER_ABSTIME */, &its, NULL); +# else /* !HAVE_TIMER_CREATE follows */ /* * Set up the alarm interrupt. The first comes 1/(2*TIMER_HZ) * seconds from now and they continue on every 1/TIMER_HZ seconds. */ - (void) signal_no_reset(SIGALRM, alarming); - itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0; - itimer.it_interval.tv_usec = 1000000/TIMER_HZ; - itimer.it_value.tv_usec = 1000000/(TIMER_HZ<<1); - - setitimer(ITIMER_REAL, &itimer, (struct itimerval *)0); -# endif -#if defined SYS_CYGWIN32 - /* - * Get privileges needed for fiddling with the clock - */ - - /* get the current process token handle */ - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { - msyslog(LOG_ERR, "OpenProcessToken failed: %m"); - exit(1); - } - /* get the LUID for system-time privilege. */ - LookupPrivilegeValue(NULL, SE_SYSTEMTIME_NAME, &tkp.Privileges[0].Luid); - tkp.PrivilegeCount = 1; /* one privilege to set */ - tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - /* get set-time privilege for this process. */ - AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES) NULL, 0); - /* cannot test return value of AdjustTokenPrivileges. */ - if (GetLastError() != ERROR_SUCCESS) - msyslog(LOG_ERR, "AdjustTokenPrivileges failed: %m"); -#endif -#else /* SYS_WINNT */ + signal_no_reset(SIGALRM, alarming); + itv.it_interval.tv_sec = 0; + itv.it_value.tv_sec = 0; + itv.it_interval.tv_usec = 1000000/TIMER_HZ; + itv.it_value.tv_usec = 1000000/(TIMER_HZ<<1); + + setitimer(ITIMER_REAL, &itv, NULL); +# endif /* !HAVE_TIMER_CREATE */ +#else /* SYS_WINNT follows */ _tzset(); /* diff --git a/ntpdc/ntpdc.c b/ntpdc/ntpdc.c index 66e50991..41940b54 100644 --- a/ntpdc/ntpdc.c +++ b/ntpdc/ntpdc.c @@ -1,30 +1,33 @@ /* * ntpdc - control and monitor your ntpd daemon */ - #include #include #include #include #include #include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef SYS_WINNT +# include +#endif +#include +#include #include "ntpdc.h" #include "ntp_select.h" #include "ntp_stdlib.h" #include "ntp_assert.h" #include "ntp_lineedit.h" -#include "isc/net.h" -#include "isc/result.h" #include #include "ntpdc-opts.h" -#ifdef SYS_WINNT -# include -# include -#endif /* SYS_WINNT */ - #ifdef SYS_VXWORKS /* vxWorks needs mode flag -casey*/ # define open(name, flags) open(name, flags, 0777) @@ -492,7 +495,7 @@ openhost( hints.ai_family = ai_fam_templ; hints.ai_protocol = IPPROTO_UDP; hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_NUMERICHOST; + hints.ai_flags = Z_AI_NUMERICHOST; a_info = getaddrinfo(hname, service, &hints, &ai); if (a_info == EAI_NONAME diff --git a/ntpq/ntpq.c b/ntpq/ntpq.c index de89017c..1543ebe0 100644 --- a/ntpq/ntpq.c +++ b/ntpq/ntpq.c @@ -3,34 +3,37 @@ */ #include #include - #include #include #include #include #include +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef SYS_WINNT +# include +#endif +#include +#include #include "ntpq.h" +#include "ntp_stdlib.h" #include "ntp_unixtime.h" #include "ntp_calendar.h" #include "ntp_select.h" -#include "ntp_stdlib.h" #include "ntp_assert.h" #include "ntp_lineedit.h" #include "ntp_debug.h" -#include "isc/net.h" -#include "isc/result.h" #include #include "ntpq-opts.h" -#ifdef SYS_WINNT -# include -# include -#endif /* SYS_WINNT */ -#ifdef SYS_VXWORKS - /* vxWorks needs mode flag -casey*/ +#ifdef SYS_VXWORKS /* vxWorks needs mode flag -casey*/ # define open(name, flags) open(name, flags, 0777) # define SERVER_PORT_NUM 123 #endif @@ -676,7 +679,7 @@ openhost( hints.ai_family = ai_fam_templ; hints.ai_protocol = IPPROTO_UDP; hints.ai_socktype = SOCK_DGRAM; - hints.ai_flags = AI_NUMERICHOST; + hints.ai_flags = Z_AI_NUMERICHOST; a_info = getaddrinfo(hname, service, &hints, &ai); if (a_info == EAI_NONAME @@ -693,7 +696,7 @@ openhost( #ifdef AI_ADDRCONFIG /* Some older implementations don't like AI_ADDRCONFIG. */ if (a_info == EAI_BADFLAGS) { - hints.ai_flags = AI_CANONNAME; + hints.ai_flags &= ~AI_ADDRCONFIG; a_info = getaddrinfo(hname, service, &hints, &ai); } #endif diff --git a/ports/winnt/include/config.h b/ports/winnt/include/config.h index f75ee0b5..d49c2f08 100644 --- a/ports/winnt/include/config.h +++ b/ports/winnt/include/config.h @@ -374,7 +374,6 @@ typedef __int32 int32_t; /* define a typedef for int32_t */ #define HAVE_LIMITS_H 1 #define HAVE_STRDUP 1 -#define HAVE_STRCHR 1 #define HAVE_FCNTL_H 1 #define HAVE_SYS_RESOURCE_H #define HAVE_BSD_NICE /* emulate BSD setpriority() */ diff --git a/ports/winnt/libntp/termios.c b/ports/winnt/libntp/termios.c index f7c199d0..36bc45ae 100644 --- a/ports/winnt/libntp/termios.c +++ b/ports/winnt/libntp/termios.c @@ -159,7 +159,7 @@ int tty_open( * refclock_open - open serial port for reference clock * * This routine opens a serial port for I/O and sets default options. It - * returns the file descriptor or -1 indicating failure. + * returns the file descriptor or 0 indicating failure. */ int refclock_open( char * dev, /* device name pointer */ @@ -171,6 +171,7 @@ int refclock_open( HANDLE h; COMMTIMEOUTS timeouts; DCB dcb; + int fd; /* * open communication port handle @@ -181,13 +182,13 @@ int refclock_open( if (INVALID_HANDLE_VALUE == h) { msyslog(LOG_ERR, "Device %s CreateFile error: %m", windev); - return -1; + return 0; } /* Change the input/output buffers to be large. */ if (!SetupComm(h, 1024, 1024)) { msyslog(LOG_ERR, "Device %s SetupComm error: %m", windev); - return -1; + return 0; } dcb.DCBlength = sizeof(dcb); @@ -195,7 +196,7 @@ int refclock_open( if (!GetCommState(h, &dcb)) { msyslog(LOG_ERR, "Device %s GetCommState error: %m", windev); - return -1; + return 0; } switch (speed) { @@ -239,7 +240,7 @@ int refclock_open( default: msyslog(LOG_ERR, "Device %s unsupported baud rate " "code %u", windev, speed); - return -1; + return 0; } @@ -265,13 +266,13 @@ int refclock_open( if (!SetCommState(h, &dcb)) { msyslog(LOG_ERR, "Device %s SetCommState error: %m", windev); - return -1; + return 0; } /* watch out for CR (dcb.EvtChar) as well as the CD line */ if (!SetCommMask(h, EV_RXFLAG | EV_RLSD)) { msyslog(LOG_ERR, "Device %s SetCommMask error: %m", windev); - return -1; + return 0; } /* configure the handle to never block */ @@ -283,10 +284,14 @@ int refclock_open( if (!SetCommTimeouts(h, &timeouts)) { msyslog(LOG_ERR, "Device %s SetCommTimeouts error: %m", windev); - return -1; + return 0; } - return (int)_open_osfhandle((int)h, _O_TEXT); + fd = _open_osfhandle((int)h, _O_TEXT); + if (fd < 0) + return 0; + NTP_INSIST(fd != 0); + return fd; } diff --git a/ports/winnt/vc6/libntp.dsp b/ports/winnt/vc6/libntp.dsp index 64fa5bb0..51d2904b 100644 --- a/ports/winnt/vc6/libntp.dsp +++ b/ports/winnt/vc6/libntp.dsp @@ -270,10 +270,6 @@ SOURCE=..\..\..\lib\isc\md5.c # End Source File # Begin Source File -SOURCE=..\..\..\libntp\memmove.c -# End Source File -# Begin Source File - SOURCE=..\..\..\libntp\mfptoa.c # End Source File # Begin Source File diff --git a/ports/winnt/vs2003/libntp.vcproj b/ports/winnt/vs2003/libntp.vcproj index f2664142..56873c17 100644 --- a/ports/winnt/vs2003/libntp.vcproj +++ b/ports/winnt/vs2003/libntp.vcproj @@ -950,27 +950,6 @@ PreprocessorDefinitions=""/> - - - - - - - - - - - - - - - - diff --git a/ports/winnt/vs2008/libntp/libntp.vcproj b/ports/winnt/vs2008/libntp/libntp.vcproj index 1e415e77..115a70e1 100644 --- a/ports/winnt/vs2008/libntp/libntp.vcproj +++ b/ports/winnt/vs2008/libntp/libntp.vcproj @@ -379,10 +379,6 @@ RelativePath="..\..\..\..\lib\isc\md5.c" > - - @@ -519,10 +515,6 @@ RelativePath="..\..\..\..\lib\isc\win32\strerror.c" > - - @@ -539,6 +531,10 @@ RelativePath="..\..\..\..\lib\isc\task.c" > + + @@ -579,10 +575,6 @@ RelativePath="..\..\..\..\lib\isc\win32\win32os.c" > - - @@ -853,7 +845,7 @@ >