+* [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 <stenn@ntp.org>
* [Bug 1483] hostname in ntp.conf "restrict" parameter rejected.
* Use all addresses for each restrict by hostname.
AC_CHECK_FUNCS(kvm_open)
;;
esac
-AC_CHECK_FUNCS(memcpy memmove memset)
case "$host" in
*-*-sco3.2v5.0.*)
# Just stubs. Idiots.
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]]*)
#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
[ -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
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
#ifndef NTP_H
#define NTP_H
+#include <stddef.h>
#include <math.h>
#include <ntp_fp.h>
#include <ntp_types.h>
+#include <ntp_lists.h>
#include <ntp_stdlib.h>
#ifdef OPENSSL
#include <ntp_crypto.h>
* 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) */
#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)))
/*
/*
* 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 */
};
/*
#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
#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
#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
/* 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 */
};
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;
};
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 */
};
/*
- * 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
* 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.
*
* 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 <isc/list.h>
-
+#ifndef TRUE
+# define TRUE 1
+# define NTP_LISTS_UNDEF_TRUE
+#endif
#define LINK_SLIST(listhead, pentry, nextlink) \
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); \
} \
} 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 { \
} 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 */
/* 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) \
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)) \
#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
extern char * numtoa (u_int32);
extern char * numtohost (u_int32);
extern char * socktoa (sockaddr_u *);
-#define localaddrtoa(pif) ((NULL == (pif)) \
- ? "<null>" \
- : 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);
/*
- * Define string ops: strchr strrchr memcmp memmove memset
+ * Define string ops: strchr strrchr memcmp memmove memset
*/
#ifndef NTP_STRING_H
# include <bstring.h>
#endif
-#ifndef STDC_HEADERS
-# ifndef HAVE_STRCHR
-# include <strings.h>
-# 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
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 */
/*
/*
- * 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"
#include "ntp_workimpl.h"
#include "recvbuff.h"
+/*
+ * First half: ntpd types, functions, macros
+ * -----------------------------------------
+ */
+
+
/* ntp_config.c */
#define TAI_1972 10 /* initial TAI offset (s) */
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 *);
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);
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
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);
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 *);
/* 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);
/*
- * Variable declarations for ntpd.
+ * Last half: ntpd variables
+ * -------------------------
*/
+
/* ntp_config.c */
extern char const * progname;
extern char *sys_phone[]; /* ACTS phone numbers */
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) */
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.
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
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 */
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 */
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
iosignal.c \
lib_strbuf.c \
machines.c \
- memmove.c \
mfptoa.c \
ntp_lineedit.c \
mfptoms.c \
ssl_init.c \
statestr.c \
strdup.c \
- strstr.c \
syssignal.c \
tsftomsu.c \
tstotv.c \
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;
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*/
+++ /dev/null
-/*-
- * 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 <config.h>
-#endif
-
-#ifndef HAVE_MEMMOVE
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#include <string.h>
-
-#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
#include <config.h>
-#include "ntp_malloc.h"
-#if !HAVE_STRDUP
+#include <string.h>
+#include "ntp_malloc.h"
-#define NULL 0
+#ifndef HAVE_STRDUP
char *strdup(const char *s);
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
+++ /dev/null
-#include <config.h>
-
-#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
ntpd_SOURCES = \
cmd_args.c \
ntp_config.c \
- ntp_data_structures.c \
ntp_keyword.h \
ntp_io.c \
ntp_parser.y \
jupiter.h \
ntp_control.c \
ntp_crypto.c \
+ ntp_data_structures.c \
ntp_filegen.c \
ntp_intres.c \
ntp_loopfilter.c \
{ 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 */
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 **);
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);
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);
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:
)
{
struct unpeer_node * my_node;
+ u_int u;
char * pch;
my_node = get_node(sizeof(*my_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 {
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.";
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:
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) {
}
-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;
}
}
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);
/* 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
} 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",
)
{
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);
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)
}
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 */
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;
* 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);
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");
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",
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)",
* 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)
/*
* 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);
#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 },
{ 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;
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) */
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;
}
*/
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++;
}
/*
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);
register int req_count;
register int req_data;
register struct ctl_proc *cc;
+ keyid_t *pkid;
int properlen;
int maclen;
* 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++;
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));
*/
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);
}
#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
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);
}
*/
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;
/*
/*
* 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,
}
} 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
*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
* Set us up for another go around.
*/
res_offset += dlen;
- datapt = (u_char *)rpkt.data;
+ datapt = rpkt.data;
}
if (datapt != rpkt.data) {
*datapt++ = ',';
datalinelen++;
- if ((dlen + datalinelen + 1) >= MAXDATALINELEN)
- {
+ if ((dlen + datalinelen + 1) >= MAXDATALINELEN) {
*datapt++ = '\r';
*datapt++ = '\n';
datalinelen = 0;
*/
ctl_flushpkt(CTL_MORE);
}
- memmove((char *)datapt, dp, (unsigned)dlen);
+ memcpy(datapt, dp, dlen);
datapt += dlen;
datalinelen += dlen;
}
/*
* 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;
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++ = '"';
}
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)
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;
*/
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 */
}
*/
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;
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;
while (*ss && *ss != '=')
ss++;
i = ss - k->text;
- if (s+i+1 >= be)
+ if (s + i + 1 >= be)
break;
if (s != t)
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;
}
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
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
*/
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)
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;
}
* 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);
}
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)
* 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.
/*
- * 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
)
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
/*
- * 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
)
* 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 */
}
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,
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,
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
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 *);
* 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
keyid_t cookie; /* crumbles */
int hismode; /* packet mode */
int rval = XEVNT_OK;
- u_char *ptr;
+ const u_char *puch;
u_int32 temp32;
/*
* 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);
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",
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));
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;
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;
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;
/*
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);
{
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
*/
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 */
)
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;
/*
/*
* 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));
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
(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));
} 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);
}
}
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;
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)) {
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)));
}
}
}
ninterfaces--;
- ntp_monclearinterface(iface);
+ mon_clearinterface(iface);
/* remove restrict interface entry */
SET_HOSTMASK(&resmask, AF(&iface->sin));
}
+char *
+localaddrtoa(
+ struct interface *la
+ )
+{
+ return (NULL == la)
+ ? "<null>"
+ : stoa(&la->sin);
+}
+
+
#ifdef HAS_ROUTING_SOCKET
# ifndef UPDATE_GRACE
# define UPDATE_GRACE 2 /* wait UPDATE_GRACE seconds before scanning */
#include <signal.h>
#include <setjmp.h>
-#if defined(VMS) && defined(VMS_LOCALUNIT) /*wjm*/
-#include "ntp_refclock.h"
-#endif /* VMS */
-
#ifdef KERNEL_PLL
#include "ntp_syscall.h"
#endif /* KERNEL_PLL */
#include "ntpd.h"
#include "ntp_io.h"
#include "ntp_if.h"
+#include "ntp_lists.h"
#include "ntp_stdlib.h"
#include <ntp_random.h>
*
* ... 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
/*
* 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() */
* 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
* 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);
}
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;
}
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;
* 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()
}
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 */
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
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;
}
* 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);
}
/*
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;
}
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);
}
#include "openssl/rand.h"
#endif /* OPENSSL */
-#ifdef SYS_WINNT
-extern int accept_wildcard_if_for_winnt;
-#endif
-
/*
* Table of valid association combinations
* ---------------------------------------
/*
* 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
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.
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
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);
}
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;
/*
- * 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(
int mode
)
{
- register struct peer *peer;
+ struct peer *peer;
/*
* start_peer is included so we can locate instances of the
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;
}
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.
/*
* 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;
}
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));
}
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
*/
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;
}
*/
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++;
}
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
)
{
"%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) {
*/
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("<NONE>\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, ("<NONE>\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);
}
}
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);
}
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) {
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
)
{
* associations.
*/
if (peer != NULL)
- return (NULL);
+ return NULL;
/*
* Allocate a new peer structure. Some dirt here, since some of
*/
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)
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;
/*
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;
* 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);
}
* 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;
}
peer_timereset = current_time;
}
+
/*
* peer_reset - reset statistics counters
*/
struct peer *peer
)
{
- if (peer == NULL)
- return;
+ if (NULL == peer)
+ return;
peer->timereset = current_time;
peer->sent = 0;
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);
}
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
* 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;
}
#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.
struct peer *peer /* peer structure pointer */
)
{
- int hpoll;
+ u_char hpoll;
/*
* The polling state machine. There are two kinds of machines,
{
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 */
} 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 */
}
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
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.
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
char *ident /* tally lights */
)
{
- int i;
+ u_char u;
#ifdef OPENSSL
/*
*/
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)) {
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 {
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
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);
}
/*
* 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)
*/
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;
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++;
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;
}
}
* 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
}
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) {
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;
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];
}
*/
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++;
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 -
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 {
*/
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;
msyslog(LOG_ERR, "refclock_open %s: %m", dev);
return (0);
}
+ NTP_INSIST(fd != 0);
if (!refclock_setup(fd, speed, lflags)) {
close(fd);
return (0);
return (fd);
}
+
/*
* refclock_setup - initialize terminal interface structure
*/
/*
* 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)
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 *);
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 *);
* 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),
/*
- * 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
{
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
{
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();
}
register int items;
register int i, j;
sockaddr_u addr;
- extern struct peer *sys_peer;
l_fp ltmp;
items = INFO_NITEMS(inpkt->err_nitems);
register struct info_peer_stats *ip;
register int items;
sockaddr_u addr;
- extern struct peer *sys_peer;
#ifdef DEBUG
if (debug)
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));
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();
}
{
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));
{
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));
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));
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
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)
*/
)
{
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)
}
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));
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();
}
)
{
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);
}
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));
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();
}
*/
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[] = {
{
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));
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;
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;
)
{
keyid_t keyid;
- extern keyid_t ctl_auth_keyid;
/*
* Restrict ourselves to one item only.
{
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));
#include "ntpd.h"
#include "ntp_if.h"
+#include "ntp_lists.h"
#include "ntp_stdlib.h"
/*
* 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;
* 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 *);
/*
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;
}
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,
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++;
/* 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);
}
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;
}
+
}
timer(void)
{
register struct peer *peer, *next_peer;
- u_int n;
l_fp now;
/*
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 */
}
* 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 */
- }
}
}
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
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;
}
snprintf(device, sizeof(device), DEVICE, unit);
fd = refclock_open(device, SPEED232, LDISC_RAW);
#endif /* HAVE_AUDIO */
- if (fd < 0)
+ if (fd <= 0)
return (0);
/*
printf ("starting Dumbclock with device %s\n",device);
#endif
fd = refclock_open(device, SPEED232, 0);
- if (fd < 0)
+ if (!fd)
return (0);
/*
#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 */
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;
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 */
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);
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);
* 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);
/*
# 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
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),
{
alarm_flag++;
}
-#else
+#else /* SYS_WINNT follows */
void CALLBACK
alarming(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
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;
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
* 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();
/*
/*
* ntpdc - control and monitor your ntpd daemon
*/
-
#include <config.h>
#include <stdio.h>
#include <stddef.h>
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef SYS_WINNT
+# include <mswsock.h>
+#endif
+#include <isc/net.h>
+#include <isc/result.h>
#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 <ssl_applink.c>
#include "ntpdc-opts.h"
-#ifdef SYS_WINNT
-# include <Mswsock.h>
-# include <io.h>
-#endif /* SYS_WINNT */
-
#ifdef SYS_VXWORKS
/* vxWorks needs mode flag -casey*/
# define open(name, flags) open(name, flags, 0777)
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
*/
#include <config.h>
#include <stdio.h>
-
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/types.h>
#include <sys/time.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#ifdef SYS_WINNT
+# include <mswsock.h>
+#endif
+#include <isc/net.h>
+#include <isc/result.h>
#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 <ssl_applink.c>
#include "ntpq-opts.h"
-#ifdef SYS_WINNT
-# include <Mswsock.h>
-# include <io.h>
-#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
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
#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
#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() */
* 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 */
HANDLE h;
COMMTIMEOUTS timeouts;
DCB dcb;
+ int fd;
/*
* open communication port handle
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);
if (!GetCommState(h, &dcb)) {
msyslog(LOG_ERR, "Device %s GetCommState error: %m",
windev);
- return -1;
+ return 0;
}
switch (speed) {
default:
msyslog(LOG_ERR, "Device %s unsupported baud rate "
"code %u", windev, speed);
- return -1;
+ return 0;
}
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 */
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;
}
# End Source File\r
# Begin Source File\r
\r
-SOURCE=..\..\..\libntp\memmove.c\r
-# End Source File\r
-# Begin Source File\r
-\r
SOURCE=..\..\..\libntp\mfptoa.c\r
# End Source File\r
# Begin Source File\r
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
- <File
- RelativePath="..\..\..\libntp\memmove.c">
- <FileConfiguration
- Name="Debug|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- BasicRuntimeChecks="3"
- BrowseInformation="1"/>
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="2"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""/>
- </FileConfiguration>
- </File>
<File
RelativePath="..\..\..\libntp\mfptoa.c">
<FileConfiguration
/>
</FileConfiguration>
</File>
- <File
- RelativePath="..\..\..\libntp\memmove.c"
- >
- <FileConfiguration
- Name="Debug|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- <FileConfiguration
- Name="Release|Win32"
- >
- <Tool
- Name="VCCLCompilerTool"
- AdditionalIncludeDirectories=""
- PreprocessorDefinitions=""
- />
- </FileConfiguration>
- </File>
<File
RelativePath="..\..\..\libntp\mfptoa.c"
>
RelativePath="..\..\..\..\lib\isc\md5.c"
>
</File>
- <File
- RelativePath="..\..\..\..\libntp\memmove.c"
- >
- </File>
<File
RelativePath="..\..\..\..\libntp\mfptoa.c"
>
RelativePath="..\..\..\..\lib\isc\win32\strerror.c"
>
</File>
- <File
- RelativePath="..\..\..\..\libntp\strstr.c"
- >
- </File>
<File
RelativePath="..\..\libntp\syslog.c"
>
RelativePath="..\..\..\..\lib\isc\task.c"
>
</File>
+ <File
+ RelativePath="..\..\libntp\termios.c"
+ >
+ </File>
<File
RelativePath="..\..\..\..\lib\isc\win32\thread.c"
>
RelativePath="..\..\..\..\lib\isc\win32\win32os.c"
>
</File>
- <File
- RelativePath="..\..\libntp\termios.c"
- >
- </File>
<File
RelativePath="..\..\..\..\libntp\ymd2yd.c"
>
>
</File>
<File
- RelativePath="..\..\include\sys\time.h"
+ RelativePath="..\..\..\..\lib\isc\win32\include\isc\time.h"
>
</File>
<File
>
</File>
<File
- RelativePath="..\..\..\..\lib\isc\win32\include\isc\time.h"
+ RelativePath="..\..\include\sys\time.h"
>
</File>
<File
AC_DEFINE(HAVE_TERMIOS, 1, [sntp does not care about TTY stuff])
# Checks for library functions.
-AC_CHECK_FUNCS([atexit memset socket])
+AC_CHECK_FUNCS([socket])
AC_MSG_CHECKING(for bin subdirectory)
AC_ARG_WITH(binsubdir,