3 * This file contains the ntpd configuration code.
5 * Written By: Sachin Kamboj
6 * University of Delaware
8 * Some parts borrowed from the older ntp_config.c
17 # include <netinfo/ni.h>
22 #ifdef HAVE_SYS_PARAM_H
23 # include <sys/param.h>
27 # define SIGCHLD SIGCLD
29 #ifdef HAVE_SYS_WAIT_H
30 # include <sys/wait.h>
35 #include <isc/result.h>
40 #include "ntp_unixtime.h"
41 #include "ntp_refclock.h"
42 #include "ntp_filegen.h"
43 #include "ntp_stdlib.h"
44 #include "lib_strbuf.h"
45 #include "ntp_assert.h"
46 #include "ntp_random.h"
48 * [Bug 467]: Some linux headers collide with CONFIG_PHONE and CONFIG_KEYS
49 * so #include these later.
51 #include "ntp_config.h"
52 #include "ntp_cmdargs.h"
53 #include "ntp_scanner.h"
54 #include "ntp_parser.h"
55 #include "ntpd-opts.h"
57 #ifndef IGNORE_DNS_ERRORS
60 # define DNSFLAGS GAIR_F_IGNDNSERR
63 extern int yyparse(void);
66 #if defined(HAVE_SYS_MMAN_H)
67 # include <sys/mman.h>
70 /* list of servers from command line for config_peers() */
71 int cmdline_server_count;
72 char ** cmdline_servers;
74 /* Current state of memory locking:
76 * 0: memory locking disabled
77 * 1: Memory locking enabled
82 * "logconfig" building blocks
85 const char * const name;
89 static struct masks logcfg_class[] = {
90 { "clock", NLOG_OCLOCK },
91 { "peer", NLOG_OPEER },
92 { "sync", NLOG_OSYNC },
97 /* logcfg_noclass_items[] masks are complete and must not be shifted */
98 static struct masks logcfg_noclass_items[] = {
99 { "allall", NLOG_SYSMASK | NLOG_PEERMASK | NLOG_CLOCKMASK | NLOG_SYNCMASK },
100 { "allinfo", NLOG_SYSINFO | NLOG_PEERINFO | NLOG_CLOCKINFO | NLOG_SYNCINFO },
101 { "allevents", NLOG_SYSEVENT | NLOG_PEEREVENT | NLOG_CLOCKEVENT | NLOG_SYNCEVENT },
102 { "allstatus", NLOG_SYSSTATUS | NLOG_PEERSTATUS | NLOG_CLOCKSTATUS | NLOG_SYNCSTATUS },
103 { "allstatistics", NLOG_SYSSTATIST | NLOG_PEERSTATIST | NLOG_CLOCKSTATIST | NLOG_SYNCSTATIST },
104 /* the remainder are misspellings of clockall, peerall, sysall, and syncall. */
105 { "allclock", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OCLOCK },
106 { "allpeer", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OPEER },
107 { "allsys", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYS },
108 { "allsync", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYNC },
112 /* logcfg_class_items[] masks are shiftable by NLOG_O* counts */
113 static struct masks logcfg_class_items[] = {
114 { "all", NLOG_INFO | NLOG_EVENT | NLOG_STATUS | NLOG_STATIST },
115 { "info", NLOG_INFO },
116 { "events", NLOG_EVENT },
117 { "status", NLOG_STATUS },
118 { "statistics", NLOG_STATIST },
122 typedef struct peer_resolved_ctx_tag {
124 int host_mode; /* T_* token identifier */
127 u_char hmode; /* MODE_* */
136 #define MAXPHONE 10 /* maximum number of phone strings */
137 #define MAXPPS 20 /* maximum length of PPS device string */
140 * Miscellaneous macros
142 #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
143 #define ISSPACE(c) ((c) == ' ' || (c) == '\t')
145 #define _UC(str) ((char *)(intptr_t)(str))
148 * Definitions of things either imported from or exported to outside
150 extern int yydebug; /* ntp_parser.c (.y) */
151 config_tree cfgt; /* Parser output stored here */
152 config_tree *cfg_tree_history; /* History of configs */
153 char * sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */
154 char default_keysdir[] = NTP_KEYSDIR;
155 char * keysdir = default_keysdir; /* crypto keys directory */
156 char * saveconfigdir;
157 #if defined(HAVE_SCHED_SETSCHEDULER)
158 int config_priority_override = 0;
162 const char *config_file;
163 static char default_ntp_signd_socket[] =
164 #ifdef NTP_SIGND_PATH
169 char *ntp_signd_socket = default_ntp_signd_socket;
171 struct netinfo_config_state *config_netinfo = NULL;
172 int check_netinfo = 1;
173 #endif /* HAVE_NETINFO */
175 char *alt_config_file;
177 char config_file_storage[MAX_PATH];
178 char alt_config_file_storage[MAX_PATH];
179 #endif /* SYS_WINNT */
183 * NetInfo configuration state
185 struct netinfo_config_state {
186 void *domain; /* domain with config */
187 ni_id config_dir; /* ID config dir */
188 int prop_index; /* current property */
189 int val_index; /* current value */
190 char **val_list; /* value list */
194 struct REMOTE_CONFIG_INFO remote_config; /* Remote configuration buffer and
196 int old_config_style = 1; /* A boolean flag, which when set,
197 * indicates that the old configuration
198 * format with a newline at the end of
199 * every command is being used
201 int cryptosw; /* crypto command called */
203 extern char *stats_drift_file; /* name of the driftfile */
205 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
207 * backwards compatibility flags
209 bc_entry bc_list[] = {
210 { T_Bc_bugXXXX, 1 } /* default enabled */
214 * declare an int pointer for each flag for quick testing without
215 * walking bc_list. If the pointer is consumed by libntp rather
216 * than ntpd, declare it in a libntp source file pointing to storage
217 * initialized with the appropriate value for other libntp clients, and
218 * redirect it to point into bc_list during ntpd startup.
220 int *p_bcXXXX_enabled = &bc_list[0].enabled;
223 /* FUNCTION PROTOTYPES */
225 static void init_syntax_tree(config_tree *);
226 static void apply_enable_disable(attr_val_fifo *q, int enable);
229 static void free_auth_node(config_tree *);
230 static void free_all_config_trees(void);
232 static void free_config_access(config_tree *);
233 static void free_config_auth(config_tree *);
234 static void free_config_fudge(config_tree *);
235 static void free_config_logconfig(config_tree *);
236 static void free_config_monitor(config_tree *);
237 static void free_config_nic_rules(config_tree *);
238 static void free_config_other_modes(config_tree *);
239 static void free_config_peers(config_tree *);
240 static void free_config_phone(config_tree *);
241 static void free_config_reset_counters(config_tree *);
242 static void free_config_rlimit(config_tree *);
243 static void free_config_setvar(config_tree *);
244 static void free_config_system_opts(config_tree *);
245 static void free_config_tinker(config_tree *);
246 static void free_config_tos(config_tree *);
247 static void free_config_trap(config_tree *);
248 static void free_config_ttl(config_tree *);
249 static void free_config_unpeers(config_tree *);
250 static void free_config_vars(config_tree *);
253 static void free_config_sim(config_tree *);
255 static void destroy_address_fifo(address_fifo *);
256 #define FREE_ADDRESS_FIFO(pf) \
258 destroy_address_fifo(pf); \
261 void free_all_config_trees(void); /* atexit() */
262 static void free_config_tree(config_tree *ptree);
263 #endif /* FREE_CFG_T */
265 static void destroy_restrict_node(restrict_node *my_node);
266 static int is_sane_resolved_address(sockaddr_u *peeraddr, int hmode);
267 static void save_and_apply_config_tree(int/*BOOL*/ from_file);
268 static void destroy_int_fifo(int_fifo *);
269 #define FREE_INT_FIFO(pf) \
271 destroy_int_fifo(pf); \
274 static void destroy_string_fifo(string_fifo *);
275 #define FREE_STRING_FIFO(pf) \
277 destroy_string_fifo(pf); \
280 static void destroy_attr_val_fifo(attr_val_fifo *);
281 #define FREE_ATTR_VAL_FIFO(pf) \
283 destroy_attr_val_fifo(pf); \
286 static void destroy_filegen_fifo(filegen_fifo *);
287 #define FREE_FILEGEN_FIFO(pf) \
289 destroy_filegen_fifo(pf); \
292 static void destroy_restrict_fifo(restrict_fifo *);
293 #define FREE_RESTRICT_FIFO(pf) \
295 destroy_restrict_fifo(pf); \
298 static void destroy_setvar_fifo(setvar_fifo *);
299 #define FREE_SETVAR_FIFO(pf) \
301 destroy_setvar_fifo(pf); \
304 static void destroy_addr_opts_fifo(addr_opts_fifo *);
305 #define FREE_ADDR_OPTS_FIFO(pf) \
307 destroy_addr_opts_fifo(pf); \
311 static void config_logconfig(config_tree *);
312 static void config_monitor(config_tree *);
313 static void config_rlimit(config_tree *);
314 static void config_system_opts(config_tree *);
315 static void config_tinker(config_tree *);
316 static int config_tos_clock(config_tree *);
317 static void config_tos(config_tree *);
318 static void config_vars(config_tree *);
321 static sockaddr_u *get_next_address(address_node *addr);
322 static void config_sim(config_tree *);
323 static void config_ntpdsim(config_tree *);
324 #else /* !SIM follows */
325 static void config_ntpd(config_tree *, int/*BOOL*/ input_from_file);
326 static void config_other_modes(config_tree *);
327 static void config_auth(config_tree *);
328 static void attrtopsl(int poll, attr_val *avp);
329 static void config_access(config_tree *);
330 static void config_mdnstries(config_tree *);
331 static void config_phone(config_tree *);
332 static void config_setvar(config_tree *);
333 static void config_ttl(config_tree *);
334 static void config_trap(config_tree *);
335 static void config_fudge(config_tree *);
336 static void config_peers(config_tree *);
337 static void config_unpeers(config_tree *);
338 static void config_nic_rules(config_tree *, int/*BOOL*/ input_from_file);
339 static void config_reset_counters(config_tree *);
340 static u_char get_correct_host_mode(int token);
341 static int peerflag_bits(peer_node *);
345 static void peer_name_resolved(int, int, void *, const char *, const char *,
346 const struct addrinfo *,
347 const struct addrinfo *);
348 static void unpeer_name_resolved(int, int, void *, const char *, const char *,
349 const struct addrinfo *,
350 const struct addrinfo *);
351 static void trap_name_resolved(int, int, void *, const char *, const char *,
352 const struct addrinfo *,
353 const struct addrinfo *);
358 t_REF, /* Refclock */
359 t_MSK /* Network Mask */
362 static void ntpd_set_tod_using(const char *);
363 static char * normal_dtoa(double);
364 static u_int32 get_pfxmatch(const char **, struct masks *);
365 static u_int32 get_match(const char *, struct masks *);
366 static u_int32 get_logmask(const char *);
367 static int/*BOOL*/ is_refclk_addr(const address_node * addr);
369 static void appendstr(char *, size_t, const char *);
373 static int getnetnum(const char *num, sockaddr_u *addr, int complain,
374 enum gnn_type a_type);
378 #if defined(__GNUC__) /* this covers CLANG, too */
379 static void __attribute__((noreturn,format(printf,1,2))) fatal_error(const char *fmt, ...)
380 #elif defined(_MSC_VER)
381 static void __declspec(noreturn) fatal_error(const char *fmt, ...)
383 static void fatal_error(const char *fmt, ...)
389 mvsyslog(LOG_EMERG, fmt, va);
395 /* FUNCTIONS FOR INITIALIZATION
396 * ----------------------------
405 if (ptree->auth.keys) {
406 free(ptree->auth.keys);
407 ptree->auth.keys = NULL;
410 if (ptree->auth.keysdir) {
411 free(ptree->auth.keysdir);
412 ptree->auth.keysdir = NULL;
415 if (ptree->auth.ntp_signd_socket) {
416 free(ptree->auth.ntp_signd_socket);
417 ptree->auth.ntp_signd_socket = NULL;
429 ptree->mdnstries = 5;
435 free_all_config_trees(void)
440 ptree = cfg_tree_history;
442 while (ptree != NULL) {
444 free_config_tree(ptree);
455 #if defined(_MSC_VER) && defined (_DEBUG)
459 if (ptree->source.value.s != NULL)
460 free(ptree->source.value.s);
462 free_config_other_modes(ptree);
463 free_config_auth(ptree);
464 free_config_tos(ptree);
465 free_config_monitor(ptree);
466 free_config_access(ptree);
467 free_config_tinker(ptree);
468 free_config_rlimit(ptree);
469 free_config_system_opts(ptree);
470 free_config_logconfig(ptree);
471 free_config_phone(ptree);
472 free_config_setvar(ptree);
473 free_config_ttl(ptree);
474 free_config_trap(ptree);
475 free_config_fudge(ptree);
476 free_config_vars(ptree);
477 free_config_peers(ptree);
478 free_config_unpeers(ptree);
479 free_config_nic_rules(ptree);
480 free_config_reset_counters(ptree);
482 free_config_sim(ptree);
484 free_auth_node(ptree);
488 #if defined(_MSC_VER) && defined (_DEBUG)
492 #endif /* FREE_CFG_T */
498 dump_all_config_trees(
503 config_tree * cfg_ptr;
505 time_t now = time(NULL);
506 struct tm tm = *localtime(&now);
508 fprintf(df, "#NTF:D %04d%02d%02d@%02d:%02d:%02d\n",
509 tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
510 tm.tm_hour, tm.tm_min, tm.tm_sec);
511 fprintf(df, "#NTF:V %s\n", Version);
514 for (cfg_ptr = cfg_tree_history;
516 cfg_ptr = cfg_ptr->link)
517 return_value |= dump_config_tree(cfg_ptr, df, comment);
523 /* The config dumper */
532 unpeer_node *unpeern;
535 address_node *peer_addr;
536 address_node *fudge_addr;
537 filegen_node *fgen_node;
538 restrict_node *rest_node;
539 addr_opts_node *addr_opts;
540 setvar_node *setv_node;
541 nic_rule_node *rule_node;
543 int_node *counter_set;
544 string_node *str_node;
546 const char *s = NULL;
552 DPRINTF(1, ("dump_config_tree(%p)\n", ptree));
555 if (!strftime(timestamp, sizeof(timestamp),
557 localtime(&ptree->timestamp)))
560 fprintf(df, "# %s %s %s\n",
562 (CONF_SOURCE_NTPQ == ptree->source.attr)
563 ? "ntpq remote config from"
564 : "startup configuration file",
565 ptree->source.value.s);
569 * For options without documentation we just output the name
572 atrv = HEAD_PFIFO(ptree->vars);
573 for ( ; atrv != NULL; atrv = atrv->link) {
574 switch (atrv->type) {
577 fprintf(df, "\n# dump error:\n"
578 "# unknown vars type %d (%s) for %s\n",
579 atrv->type, token_name(atrv->type),
580 token_name(atrv->attr));
584 fprintf(df, "%s %s\n", keyword(atrv->attr),
585 normal_dtoa(atrv->value.d));
589 fprintf(df, "%s %d\n", keyword(atrv->attr),
594 fprintf(df, "%s \"%s\"", keyword(atrv->attr),
596 if (T_Driftfile == atrv->attr &&
597 atrv->link != NULL &&
598 T_WanderThreshold == atrv->link->attr) {
601 normal_dtoa(atrv->value.d));
602 } else if (T_Leapfile == atrv->attr) {
614 atrv = HEAD_PFIFO(ptree->logconfig);
616 fprintf(df, "logconfig");
617 for ( ; atrv != NULL; atrv = atrv->link)
618 fprintf(df, " %c%s", atrv->attr, atrv->value.s);
622 if (ptree->stats_dir)
623 fprintf(df, "statsdir \"%s\"\n", ptree->stats_dir);
625 i_n = HEAD_PFIFO(ptree->stats_list);
627 fprintf(df, "statistics");
628 for ( ; i_n != NULL; i_n = i_n->link)
629 fprintf(df, " %s", keyword(i_n->i));
633 fgen_node = HEAD_PFIFO(ptree->filegen_opts);
634 for ( ; fgen_node != NULL; fgen_node = fgen_node->link) {
635 atrv = HEAD_PFIFO(fgen_node->options);
637 fprintf(df, "filegen %s",
638 keyword(fgen_node->filegen_token));
639 for ( ; atrv != NULL; atrv = atrv->link) {
640 switch (atrv->attr) {
643 fprintf(df, "\n# dump error:\n"
644 "# unknown filegen option token %s\n"
646 token_name(atrv->attr),
647 keyword(fgen_node->filegen_token));
651 fprintf(df, " file %s",
656 fprintf(df, " type %s",
657 keyword(atrv->value.i));
662 keyword(atrv->value.i));
670 atrv = HEAD_PFIFO(ptree->auth.crypto_cmd_list);
672 fprintf(df, "crypto");
673 for ( ; atrv != NULL; atrv = atrv->link) {
674 fprintf(df, " %s %s", keyword(atrv->attr),
680 if (ptree->auth.revoke != 0)
681 fprintf(df, "revoke %d\n", ptree->auth.revoke);
683 if (ptree->auth.keysdir != NULL)
684 fprintf(df, "keysdir \"%s\"\n", ptree->auth.keysdir);
686 if (ptree->auth.keys != NULL)
687 fprintf(df, "keys \"%s\"\n", ptree->auth.keys);
689 atrv = HEAD_PFIFO(ptree->auth.trusted_key_list);
691 fprintf(df, "trustedkey");
692 for ( ; atrv != NULL; atrv = atrv->link) {
693 if (T_Integer == atrv->type)
694 fprintf(df, " %d", atrv->value.i);
695 else if (T_Intrange == atrv->type)
696 fprintf(df, " (%d ... %d)",
701 fprintf(df, "\n# dump error:\n"
702 "# unknown trustedkey attr type %d\n"
703 "trustedkey", atrv->type);
709 if (ptree->auth.control_key)
710 fprintf(df, "controlkey %d\n", ptree->auth.control_key);
712 if (ptree->auth.request_key)
713 fprintf(df, "requestkey %d\n", ptree->auth.request_key);
715 /* dump enable list, then disable list */
716 for (enable = 1; enable >= 0; enable--) {
718 ? HEAD_PFIFO(ptree->enable_opts)
719 : HEAD_PFIFO(ptree->disable_opts);
721 fprintf(df, "%s", (enable)
724 for ( ; atrv != NULL; atrv = atrv->link)
726 keyword(atrv->value.i));
731 atrv = HEAD_PFIFO(ptree->orphan_cmds);
734 for ( ; atrv != NULL; atrv = atrv->link) {
735 switch (atrv->type) {
738 fprintf(df, "\n# dump error:\n"
739 "# unknown tos attr type %d %s\n"
741 token_name(atrv->type));
745 if (atrv->attr == T_Basedate) {
747 ntpcal_rd_to_date(&jd, atrv->value.i + DAY_NTP_STARTS);
748 fprintf(df, " %s \"%04hu-%02hu-%02hu\"",
749 keyword(atrv->attr), jd.year,
751 (u_short)jd.monthday);
753 fprintf(df, " %s %d",
760 fprintf(df, " %s %s",
762 normal_dtoa(atrv->value.d));
769 atrv = HEAD_PFIFO(ptree->rlimit);
771 fprintf(df, "rlimit");
772 for ( ; atrv != NULL; atrv = atrv->link) {
773 INSIST(T_Integer == atrv->type);
774 fprintf(df, " %s %d", keyword(atrv->attr),
780 atrv = HEAD_PFIFO(ptree->tinker);
782 fprintf(df, "tinker");
783 for ( ; atrv != NULL; atrv = atrv->link) {
784 INSIST(T_Double == atrv->type);
785 fprintf(df, " %s %s", keyword(atrv->attr),
786 normal_dtoa(atrv->value.d));
791 if (ptree->broadcastclient)
792 fprintf(df, "broadcastclient\n");
794 peern = HEAD_PFIFO(ptree->peers);
795 for ( ; peern != NULL; peern = peern->link) {
797 fprintf(df, "%s", keyword(peern->host_mode));
798 switch (addr->type) {
801 fprintf(df, "# dump error:\n"
802 "# unknown peer family %d for:\n"
804 keyword(peern->host_mode));
818 fprintf(df, " %s", addr->address);
820 if (peern->minpoll != 0)
821 fprintf(df, " minpoll %u", peern->minpoll);
823 if (peern->maxpoll != 0)
824 fprintf(df, " maxpoll %u", peern->maxpoll);
826 if (peern->ttl != 0) {
827 if (strlen(addr->address) > 8
828 && !memcmp(addr->address, "127.127.", 8))
829 fprintf(df, " mode %u", peern->ttl);
831 fprintf(df, " ttl %u", peern->ttl);
834 if (peern->peerversion != NTP_VERSION)
835 fprintf(df, " version %u", peern->peerversion);
837 if (peern->peerkey != 0)
838 fprintf(df, " key %u", peern->peerkey);
840 if (peern->group != NULL)
841 fprintf(df, " ident \"%s\"", peern->group);
843 atrv = HEAD_PFIFO(peern->peerflags);
844 for ( ; atrv != NULL; atrv = atrv->link) {
845 INSIST(T_Flag == atrv->attr);
846 INSIST(T_Integer == atrv->type);
847 fprintf(df, " %s", keyword(atrv->value.i));
852 addr_opts = HEAD_PFIFO(ptree->fudge);
853 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) {
854 peer_addr = peern->addr;
855 fudge_addr = addr_opts->addr;
857 s1 = peer_addr->address;
858 s2 = fudge_addr->address;
863 fprintf(df, "fudge %s", s1);
865 for (atrv = HEAD_PFIFO(addr_opts->options);
869 switch (atrv->type) {
872 fprintf(df, "\n# dump error:\n"
873 "# unknown fudge atrv->type %d\n"
874 "fudge %s", atrv->type,
879 fprintf(df, " %s %s",
881 normal_dtoa(atrv->value.d));
885 fprintf(df, " %s %d",
891 fprintf(df, " %s %s",
901 addr = HEAD_PFIFO(ptree->manycastserver);
903 fprintf(df, "manycastserver");
904 for ( ; addr != NULL; addr = addr->link)
905 fprintf(df, " %s", addr->address);
909 addr = HEAD_PFIFO(ptree->multicastclient);
911 fprintf(df, "multicastclient");
912 for ( ; addr != NULL; addr = addr->link)
913 fprintf(df, " %s", addr->address);
918 for (unpeern = HEAD_PFIFO(ptree->unpeers);
920 unpeern = unpeern->link)
921 fprintf(df, "unpeer %s\n", unpeern->addr->address);
923 atrv = HEAD_PFIFO(ptree->mru_opts);
926 for ( ; atrv != NULL; atrv = atrv->link)
927 fprintf(df, " %s %d", keyword(atrv->attr),
932 atrv = HEAD_PFIFO(ptree->discard_opts);
934 fprintf(df, "discard");
935 for ( ; atrv != NULL; atrv = atrv->link)
936 fprintf(df, " %s %d", keyword(atrv->attr),
941 atrv = HEAD_PFIFO(ptree->pollskewlist);
943 fprintf(df, "pollskewlist");
944 for ( ; atrv != NULL; atrv = atrv->link) {
945 if (-1 == atrv->attr) {
946 fprintf(df, " default");
948 fprintf(df, " %d", atrv->attr);
950 fprintf(df, " %d|%d",
951 atrv->value.r.first, atrv->value.r.last);
956 for (rest_node = HEAD_PFIFO(ptree->restrict_opts);
958 rest_node = rest_node->link) {
961 if (NULL == rest_node->addr) {
963 /* Don't need to set is_default=1 here */
964 atrv = HEAD_PFIFO(rest_node->flag_tok_fifo);
965 for ( ; atrv != NULL; atrv = atrv->link) {
966 if ( T_Integer == atrv->type
967 && T_Source == atrv->attr) {
973 const char *ap = rest_node->addr->address;
977 mp = rest_node->mask->address;
979 if ( rest_node->addr->type == AF_INET
980 && !strcmp(ap, "0.0.0.0")
981 && !strcmp(mp, "0.0.0.0")) {
984 } else if ( rest_node->mask
985 && rest_node->mask->type == AF_INET6
987 && !strcmp(mp, "::")) {
994 fprintf(df, "restrict %s", s);
995 if (rest_node->mask != NULL && !is_default)
996 fprintf(df, " mask %s",
997 rest_node->mask->address);
998 fprintf(df, " ippeerlimit %d", rest_node->ippeerlimit);
999 atrv = HEAD_PFIFO(rest_node->flag_tok_fifo);
1000 for ( ; atrv != NULL; atrv = atrv->link) {
1001 if ( T_Integer == atrv->type
1002 && T_Source != atrv->attr) {
1003 fprintf(df, " %s", keyword(atrv->attr));
1009 msyslog(LOG_INFO, "Dumping flag_tok_fifo:");
1010 atrv = HEAD_PFIFO(rest_node->flag_tok_fifo);
1011 for ( ; atrv != NULL; atrv = atrv->link) {
1012 msyslog(LOG_INFO, "- flag_tok_fifo: flags: %08x", atrv->flag);
1013 switch(atrv->type) {
1015 msyslog(LOG_INFO, "- T_Integer: attr <%s>/%d, value %d",
1016 keyword(atrv->attr), atrv->attr, atrv->value.i);
1019 msyslog(LOG_INFO, "- Other: attr <%s>/%d, value ???",
1020 keyword(atrv->attr), atrv->attr);
1029 rule_node = HEAD_PFIFO(ptree->nic_rules);
1030 for ( ; rule_node != NULL; rule_node = rule_node->link) {
1031 fprintf(df, "interface %s %s\n",
1032 keyword(rule_node->action),
1033 (rule_node->match_class)
1034 ? keyword(rule_node->match_class)
1035 : rule_node->if_name);
1038 str_node = HEAD_PFIFO(ptree->phone);
1039 if (str_node != NULL) {
1040 fprintf(df, "phone");
1041 for ( ; str_node != NULL; str_node = str_node->link)
1042 fprintf(df, " \"%s\"", str_node->s);
1046 setv_node = HEAD_PFIFO(ptree->setvar);
1047 for ( ; setv_node != NULL; setv_node = setv_node->link) {
1048 s1 = quote_if_needed(setv_node->var);
1049 s2 = quote_if_needed(setv_node->val);
1050 fprintf(df, "setvar %s = %s", s1, s2);
1053 if (setv_node->isdefault)
1054 fprintf(df, " default");
1058 i_n = HEAD_PFIFO(ptree->ttl);
1061 for( ; i_n != NULL; i_n = i_n->link)
1062 fprintf(df, " %d", i_n->i);
1066 addr_opts = HEAD_PFIFO(ptree->trap);
1067 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) {
1068 addr = addr_opts->addr;
1069 fprintf(df, "trap %s", addr->address);
1070 atrv = HEAD_PFIFO(addr_opts->options);
1071 for ( ; atrv != NULL; atrv = atrv->link) {
1072 switch (atrv->attr) {
1075 fprintf(df, "\n# dump error:\n"
1076 "# unknown trap token %d\n"
1077 "trap %s", atrv->attr,
1082 fprintf(df, " port %d", atrv->value.i);
1086 fprintf(df, " interface %s",
1094 counter_set = HEAD_PFIFO(ptree->reset_counters);
1095 if (counter_set != NULL) {
1096 fprintf(df, "reset");
1097 for ( ; counter_set != NULL;
1098 counter_set = counter_set->link)
1099 fprintf(df, " %s", keyword(counter_set->i));
1105 #endif /* SAVECONFIG */
1108 /* generic fifo routines for structs linked by 1st member */
1121 pf = emalloc_zero(sizeof(*pf));
1123 CHECK_FIFO_CONSISTENCY(*pf);
1125 LINK_FIFO(*pf, pe, link);
1126 CHECK_FIFO_CONSISTENCY(*pf);
1148 CONCAT_FIFO(*pf1, *pf2, link);
1160 any_node * np = NULL;
1161 any_node_fifo * pf1 = fifo;
1167 UNLINK_FIFO(np, *pf1, link);
1177 /* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE
1178 * -----------------------------------------------
1187 if (T_String == av->type)
1201 my_val = emalloc_zero(sizeof(*my_val));
1202 my_val->attr = attr;
1203 my_val->value.d = value;
1204 my_val->type = T_Double;
1218 my_val = emalloc_zero(sizeof(*my_val));
1219 my_val->attr = attr;
1220 my_val->value.i = value;
1221 my_val->type = T_Integer;
1235 my_val = emalloc_zero(sizeof(*my_val));
1236 my_val->attr = attr;
1237 my_val->value.u = value;
1238 my_val->type = T_U_int;
1253 my_val = emalloc_zero(sizeof(*my_val));
1254 my_val->attr = attr;
1255 my_val->value.r.first = first;
1256 my_val->value.r.last = last;
1257 my_val->type = T_Intrange;
1271 my_val = emalloc_zero(sizeof(*my_val));
1272 my_val->attr = attr;
1273 if (NULL == s) /* free() hates NULL */
1275 my_val->value.s = _UC(s);
1276 my_val->type = T_String;
1289 i_n = emalloc_zero(sizeof(*i_n));
1303 sn = emalloc_zero(sizeof(*sn));
1311 create_address_node(
1316 address_node *my_node;
1318 REQUIRE(NULL != addr);
1319 REQUIRE(AF_INET == type || AF_INET6 == type || AF_UNSPEC == type);
1320 my_node = emalloc_zero(sizeof(*my_node));
1321 my_node->address = addr;
1322 my_node->type = (u_short)type;
1329 destroy_address_node(
1330 address_node *my_node
1333 if (NULL == my_node)
1335 REQUIRE(NULL != my_node->address);
1337 free(my_node->address);
1345 address_node * addr,
1346 attr_val_fifo * options
1354 my_node = emalloc_zero(sizeof(*my_node));
1356 /* Initialize node values to default */
1357 my_node->peerversion = NTP_VERSION;
1359 /* Now set the node to the read values */
1360 my_node->host_mode = hmode;
1361 my_node->addr = addr;
1364 * the options FIFO mixes items that will be saved in the
1365 * peer_node as explicit members, such as minpoll, and
1366 * those that are moved intact to the peer_node's peerflags
1367 * FIFO. The options FIFO is consumed and reclaimed here.
1370 if (options != NULL)
1371 CHECK_FIFO_CONSISTENCY(*options);
1372 while (options != NULL) {
1373 UNLINK_FIFO(option, *options, link);
1374 if (NULL == option) {
1380 /* Check the kind of option being set */
1381 switch (option->attr) {
1384 APPEND_G_FIFO(my_node->peerflags, option);
1389 if (option->value.i < NTP_MINPOLL ||
1390 option->value.i > UCHAR_MAX) {
1392 "minpoll: provided value (%d) is out of range [%d-%d])",
1393 option->value.i, NTP_MINPOLL,
1395 my_node->minpoll = NTP_MINPOLL;
1398 (u_char)option->value.u;
1403 if (option->value.i < 0 ||
1404 option->value.i > NTP_MAXPOLL) {
1406 "maxpoll: provided value (%d) is out of range [0-%d])",
1407 option->value.i, NTP_MAXPOLL);
1408 my_node->maxpoll = NTP_MAXPOLL;
1411 (u_char)option->value.u;
1416 if (is_refclk_addr(addr)) {
1417 msyslog(LOG_ERR, "'ttl' does not apply for refclocks");
1419 } else if (option->value.u >= MAX_TTL) {
1420 msyslog(LOG_ERR, "ttl: invalid argument");
1423 my_node->ttl = (u_char)option->value.u;
1428 if (is_refclk_addr(addr)) {
1429 my_node->ttl = option->value.u;
1431 msyslog(LOG_ERR, "'mode' does not apply for network peers");
1437 if (option->value.u >= KEYID_T_MAX) {
1438 msyslog(LOG_ERR, "key: invalid argument");
1442 (keyid_t)option->value.u;
1447 if (option->value.u >= UCHAR_MAX) {
1448 msyslog(LOG_ERR, "version: invalid argument");
1451 my_node->peerversion =
1452 (u_char)option->value.u;
1457 my_node->group = option->value.s;
1462 "Unknown peer/server option token %s",
1463 token_name(option->attr));
1470 /* Check if errors were reported. If yes, ignore the node */
1485 unpeer_node * my_node;
1489 my_node = emalloc_zero(sizeof(*my_node));
1492 * From the parser's perspective an association ID fits into
1493 * its generic T_String definition of a name/address "address".
1494 * We treat all valid 16-bit numbers as association IDs.
1496 for (u = 0, pch = (u_char*)addr->address; isdigit(*pch); ++pch) {
1497 /* accumulate with overflow retention */
1498 u = (10 * u + *pch - '0') | (u & 0xFF000000u);
1501 if (!*pch && u <= ASSOCID_MAX) {
1502 my_node->assocID = (associd_t)u;
1503 my_node->addr = NULL;
1504 destroy_address_node(addr);
1506 my_node->assocID = 0;
1507 my_node->addr = addr;
1514 create_filegen_node(
1516 attr_val_fifo * options
1519 filegen_node *my_node;
1521 my_node = emalloc_zero(sizeof(*my_node));
1522 my_node->filegen_token = filegen_token;
1523 my_node->options = options;
1530 create_restrict_node(
1531 address_node * addr,
1532 address_node * mask,
1534 attr_val_fifo * flag_tok_fifo,
1538 restrict_node *my_node;
1540 my_node = emalloc_zero(sizeof(*my_node));
1541 my_node->addr = addr;
1542 my_node->mask = mask;
1543 my_node->ippeerlimit = ippeerlimit;
1544 my_node->flag_tok_fifo = flag_tok_fifo;
1545 my_node->line_no = nline;
1552 destroy_restrict_node(
1553 restrict_node *my_node
1556 /* With great care, free all the memory occupied by
1559 destroy_address_node(my_node->addr);
1560 destroy_address_node(my_node->mask);
1561 destroy_attr_val_fifo(my_node->flag_tok_fifo);
1575 UNLINK_FIFO(i_n, *fifo, link);
1586 destroy_string_fifo(
1594 UNLINK_FIFO(sn, *fifo, link);
1606 destroy_attr_val_fifo(
1607 attr_val_fifo * av_fifo
1612 if (av_fifo != NULL) {
1614 UNLINK_FIFO(av, *av_fifo, link);
1617 destroy_attr_val(av);
1625 destroy_filegen_fifo(
1633 UNLINK_FIFO(fg, *fifo, link);
1636 destroy_attr_val_fifo(fg->options);
1645 destroy_restrict_fifo(
1646 restrict_fifo * fifo
1653 UNLINK_FIFO(rn, *fifo, link);
1656 destroy_restrict_node(rn);
1664 destroy_setvar_fifo(
1672 UNLINK_FIFO(sv, *fifo, link);
1685 destroy_addr_opts_fifo(
1686 addr_opts_fifo * fifo
1689 addr_opts_node * aon;
1693 UNLINK_FIFO(aon, *fifo, link);
1696 destroy_address_node(aon->addr);
1697 destroy_attr_val_fifo(aon->options);
1712 setvar_node * my_node;
1715 /* do not allow = in the variable name */
1716 pch = strchr(var, '=');
1720 /* Now store the string into a setvar_node */
1721 my_node = emalloc_zero(sizeof(*my_node));
1724 my_node->isdefault = isdefault;
1731 create_nic_rule_node(
1733 char *if_name, /* interface name or numeric address */
1737 nic_rule_node *my_node;
1739 REQUIRE(match_class != 0 || if_name != NULL);
1741 my_node = emalloc_zero(sizeof(*my_node));
1742 my_node->match_class = match_class;
1743 my_node->if_name = if_name;
1744 my_node->action = action;
1751 create_addr_opts_node(
1752 address_node * addr,
1753 attr_val_fifo * options
1756 addr_opts_node *my_node;
1758 my_node = emalloc_zero(sizeof(*my_node));
1759 my_node->addr = addr;
1760 my_node->options = options;
1768 create_sim_script_info(
1770 attr_val_fifo * script_queue
1773 script_info *my_info;
1774 attr_val *my_attr_val;
1776 my_info = emalloc_zero(sizeof(*my_info));
1778 /* Initialize Script Info with default values*/
1779 my_info->duration = duration;
1780 my_info->prop_delay = NET_DLY;
1781 my_info->proc_delay = PROC_DLY;
1783 /* Traverse the script_queue and fill out non-default values */
1785 for (my_attr_val = HEAD_PFIFO(script_queue);
1786 my_attr_val != NULL;
1787 my_attr_val = my_attr_val->link) {
1789 /* Set the desired value */
1790 switch (my_attr_val->attr) {
1793 my_info->freq_offset = my_attr_val->value.d;
1797 my_info->wander = my_attr_val->value.d;
1801 my_info->jitter = my_attr_val->value.d;
1805 my_info->prop_delay = my_attr_val->value.d;
1809 my_info->proc_delay = my_attr_val->value.d;
1813 msyslog(LOG_ERR, "Unknown script token %d",
1829 const char addr_prefix[] = "192.168.0.";
1830 static int curr_addr_num = 1;
1831 #define ADDR_LENGTH 16 + 1 /* room for 192.168.1.255 */
1832 char addr_string[ADDR_LENGTH];
1833 sockaddr_u *final_addr;
1834 struct addrinfo *ptr;
1837 final_addr = emalloc(sizeof(*final_addr));
1839 if (addr->type == T_String) {
1840 snprintf(addr_string, sizeof(addr_string), "%s%d",
1841 addr_prefix, curr_addr_num++);
1842 printf("Selecting ip address %s for hostname %s\n",
1843 addr_string, addr->address);
1844 gai_err = getaddrinfo(addr_string, "ntp", NULL, &ptr);
1846 gai_err = getaddrinfo(addr->address, "ntp", NULL, &ptr);
1850 fprintf(stderr, "ERROR!! Could not get a new address\n");
1853 memcpy(final_addr, ptr->ai_addr, ptr->ai_addrlen);
1854 fprintf(stderr, "Successful in setting ip address of simulated server to: %s\n",
1866 address_node * addr,
1867 double server_offset,
1868 script_info_fifo * script
1871 server_info *my_info;
1873 my_info = emalloc_zero(sizeof(*my_info));
1874 my_info->server_time = server_offset;
1875 my_info->addr = get_next_address(addr);
1876 my_info->script = script;
1877 UNLINK_FIFO(my_info->curr_script, *my_info->script, link);
1885 attr_val_fifo * init_opts,
1886 server_info_fifo * servers
1891 my_node = emalloc(sizeof(*my_node));
1892 my_node->init_opts = init_opts;
1893 my_node->servers = servers;
1901 /* FUNCTIONS FOR PERFORMING THE CONFIGURATION
1902 * ------------------------------------------
1911 sockaddr_u addr_sock;
1912 address_node * addr_node;
1914 if (ptree->broadcastclient)
1915 proto_config(PROTO_BROADCLIENT, ptree->broadcastclient,
1918 addr_node = HEAD_PFIFO(ptree->manycastserver);
1919 while (addr_node != NULL) {
1920 ZERO_SOCK(&addr_sock);
1921 AF(&addr_sock) = addr_node->type;
1922 if (1 == getnetnum(addr_node->address, &addr_sock, 1,
1924 proto_config(PROTO_MULTICAST_ADD,
1926 sys_manycastserver = 1;
1928 addr_node = addr_node->link;
1931 /* Configure the multicast clients */
1932 addr_node = HEAD_PFIFO(ptree->multicastclient);
1933 if (addr_node != NULL) {
1935 ZERO_SOCK(&addr_sock);
1936 AF(&addr_sock) = addr_node->type;
1937 if (1 == getnetnum(addr_node->address,
1938 &addr_sock, 1, t_UNK)) {
1939 proto_config(PROTO_MULTICAST_ADD, 0, 0.,
1942 addr_node = addr_node->link;
1943 } while (addr_node != NULL);
1944 proto_config(PROTO_MULTICAST_ADD, 1, 0., NULL);
1952 destroy_address_fifo(
1953 address_fifo * pfifo
1956 address_node * addr_node;
1958 if (pfifo != NULL) {
1960 UNLINK_FIFO(addr_node, *pfifo, link);
1961 if (addr_node == NULL)
1963 destroy_address_node(addr_node);
1971 free_config_other_modes(
1975 FREE_ADDRESS_FIFO(ptree->manycastserver);
1976 FREE_ADDRESS_FIFO(ptree->multicastclient);
1978 #endif /* FREE_CFG_T */
1996 /* Crypto Command */
1998 my_val = HEAD_PFIFO(ptree->auth.crypto_cmd_list);
1999 for (; my_val != NULL; my_val = my_val->link) {
2000 switch (my_val->attr) {
2003 fatal_error("config_auth: attr-token=%d", my_val->attr);
2006 item = CRYPTO_CONF_PRIV;
2010 item = CRYPTO_CONF_IDENT;
2014 item = CRYPTO_CONF_PW;
2018 item = CRYPTO_CONF_RAND;
2022 item = CRYPTO_CONF_NID;
2025 crypto_config(item, my_val->value.s);
2027 #endif /* AUTOKEY */
2029 /* Keysdir Command */
2030 if (ptree->auth.keysdir) {
2031 if (keysdir != default_keysdir)
2033 keysdir = estrdup(ptree->auth.keysdir);
2037 /* ntp_signd_socket Command */
2038 if (ptree->auth.ntp_signd_socket) {
2039 if (ntp_signd_socket != default_ntp_signd_socket)
2040 free(ntp_signd_socket);
2041 ntp_signd_socket = estrdup(ptree->auth.ntp_signd_socket);
2045 if (ptree->auth.cryptosw && !cryptosw) {
2049 #endif /* AUTOKEY */
2052 * Count the number of trusted keys to preallocate storage and
2053 * size the hash table.
2056 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
2057 for (; my_val != NULL; my_val = my_val->link) {
2058 if (T_Integer == my_val->type) {
2059 first = my_val->value.i;
2060 if (first > 1 && first <= NTP_MAXKEY)
2063 REQUIRE(T_Intrange == my_val->type);
2064 first = my_val->value.r.first;
2065 last = my_val->value.r.last;
2066 if (!(first > last || first < 1 ||
2067 last > NTP_MAXKEY)) {
2068 count += 1 + last - first;
2072 auth_prealloc_symkeys(count);
2075 if (ptree->auth.keys)
2076 getauthkeys(ptree->auth.keys);
2078 /* Control Key Command */
2079 if (ptree->auth.control_key)
2080 ctl_auth_keyid = (keyid_t)ptree->auth.control_key;
2082 /* Requested Key Command */
2083 if (ptree->auth.request_key) {
2084 DPRINTF(4, ("set info_auth_keyid to %08lx\n",
2085 (u_long) ptree->auth.request_key));
2086 info_auth_keyid = (keyid_t)ptree->auth.request_key;
2089 /* Trusted Key Command */
2090 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
2091 for (; my_val != NULL; my_val = my_val->link) {
2092 if (T_Integer == my_val->type) {
2093 first = my_val->value.i;
2094 if (first >= 1 && first <= NTP_MAXKEY) {
2095 authtrust(first, TRUE);
2098 "Ignoring invalid trustedkey %d, min 1 max %d.",
2102 first = my_val->value.r.first;
2103 last = my_val->value.r.last;
2104 if (first > last || first < 1 ||
2105 last > NTP_MAXKEY) {
2107 "Ignoring invalid trustedkey range %d ... %d, min 1 max %d.",
2108 first, last, NTP_MAXKEY);
2110 for (i = first; i <= last; i++) {
2118 /* crypto revoke command */
2119 if (ptree->auth.revoke > 2 && ptree->auth.revoke < 32)
2120 sys_revoke = (u_char)ptree->auth.revoke;
2121 else if (ptree->auth.revoke)
2123 "'revoke' value %d ignored",
2124 ptree->auth.revoke);
2125 #endif /* AUTOKEY */
2136 destroy_attr_val_fifo(ptree->auth.crypto_cmd_list);
2137 ptree->auth.crypto_cmd_list = NULL;
2138 destroy_attr_val_fifo(ptree->auth.trusted_key_list);
2139 ptree->auth.trusted_key_list = NULL;
2141 #endif /* FREE_CFG_T */
2144 /* Configure low-level clock-related parameters. Return TRUE if the
2145 * clock might need adjustment like era-checking after the call, FALSE
2157 tos = HEAD_PFIFO(ptree->orphan_cmds);
2158 for (; tos != NULL; tos = tos->link) {
2165 basedate_set_day(tos->value.i);
2171 if (basedate_get_day() <= NTP_TO_UNIX_DAYS)
2172 basedate_set_day(basedate_eval_buildstamp() - 11);
2186 /* [Bug 2896] For the daemon to work properly it is essential
2187 * that minsane < minclock <= maxclock.
2189 * If either constraint is violated, the daemon will be or might
2190 * become dysfunctional. Fixing the values is too fragile here,
2191 * since three variables with interdependecies are involved. We
2192 * just log an error but do not stop: This might be caused by
2193 * remote config, and it might be fixed by remote config, too.
2195 int l_maxclock = sys_maxclock;
2196 int l_minclock = sys_minclock;
2197 int l_minsane = sys_minsane;
2199 /* -*- phase one: inspect / sanitize the values */
2200 tos = HEAD_PFIFO(ptree->orphan_cmds);
2201 for (; tos != NULL; tos = tos->link) {
2202 /* not all attributes are doubles (any more), so loading
2203 * 'val' in all cases is not a good idea: It should be
2204 * done as needed in every case processed here.
2213 msyslog(LOG_WARNING,
2214 "Using maximum bcpollbstep ceiling %d, %d requested",
2217 } else if (val < 0) {
2218 msyslog(LOG_WARNING,
2219 "Using minimum bcpollbstep floor %d, %d requested",
2227 if (val > STRATUM_UNSPEC - 1) {
2228 msyslog(LOG_WARNING,
2229 "Using maximum tos ceiling %d, %d requested",
2230 STRATUM_UNSPEC - 1, (int)val);
2231 tos->value.d = STRATUM_UNSPEC - 1;
2232 } else if (val < 1) {
2233 msyslog(LOG_WARNING,
2234 "Using minimum tos floor %d, %d requested",
2242 if ((int)tos->value.d < 1)
2244 l_minclock = (int)tos->value.d;
2249 if ((int)tos->value.d < 1)
2251 l_maxclock = (int)tos->value.d;
2256 if ((int)tos->value.d < 0)
2258 l_minsane = (int)tos->value.d;
2263 if ( ! (l_minsane < l_minclock && l_minclock <= l_maxclock)) {
2265 "tos error: must have minsane (%d) < minclock (%d) <= maxclock (%d)"
2266 " - daemon will not operate properly!",
2267 l_minsane, l_minclock, l_maxclock);
2270 /* -*- phase two: forward the values to the protocol machinery */
2271 tos = HEAD_PFIFO(ptree->orphan_cmds);
2272 for (; tos != NULL; tos = tos->link) {
2276 fatal_error("config-tos: attr-token=%d", tos->attr);
2279 item = PROTO_BCPOLLBSTEP;
2283 item = PROTO_CEILING;
2291 item = PROTO_COHORT;
2295 item = PROTO_ORPHAN;
2299 item = PROTO_ORPHWAIT;
2303 item = PROTO_MINDISP;
2307 item = PROTO_MAXDIST;
2311 item = PROTO_MINCLOCK;
2315 item = PROTO_MAXCLOCK;
2319 item = PROTO_MINSANE;
2323 item = PROTO_BEACON;
2327 continue; /* SKIP proto-config for this! */
2329 proto_config(item, 0, tos->value.d, NULL);
2340 FREE_ATTR_VAL_FIFO(ptree->orphan_cmds);
2342 #endif /* FREE_CFG_T */
2350 int_node *pfilegen_token;
2351 const char *filegen_string;
2352 const char *filegen_file;
2354 filegen_node *my_node;
2359 /* Set the statistics directory */
2360 if (ptree->stats_dir)
2361 stats_config(STATS_STATSDIR, ptree->stats_dir, 0);
2364 * Calling filegen_get is brain dead. Doing a string
2365 * comparison to find the relavant filegen structure is
2368 * Through the parser, we already know which filegen is
2369 * being specified. Hence, we should either store a
2370 * pointer to the specified structure in the syntax tree
2371 * or an index into a filegen array.
2373 * Need to change the filegen code to reflect the above.
2376 /* Turn on the specified statistics */
2377 pfilegen_token = HEAD_PFIFO(ptree->stats_list);
2378 for (; pfilegen_token != NULL; pfilegen_token = pfilegen_token->link) {
2379 filegen_string = keyword(pfilegen_token->i);
2380 filegen = filegen_get(filegen_string);
2381 if (NULL == filegen) {
2383 "stats %s unrecognized",
2387 DPRINTF(4, ("enabling filegen for %s statistics '%s%s'\n",
2388 filegen_string, filegen->dir,
2390 filegen_flag = filegen->flag;
2391 filegen_flag |= FGEN_FLAG_ENABLED;
2392 filegen_config(filegen, statsdir, filegen_string,
2393 filegen->type, filegen_flag);
2396 /* Configure the statistics with the options */
2397 my_node = HEAD_PFIFO(ptree->filegen_opts);
2398 for (; my_node != NULL; my_node = my_node->link) {
2399 filegen_string = keyword(my_node->filegen_token);
2400 filegen = filegen_get(filegen_string);
2401 if (NULL == filegen) {
2403 "filegen category '%s' unrecognized",
2407 filegen_file = filegen_string;
2409 /* Initialize the filegen variables to their pre-configuration states */
2410 filegen_flag = filegen->flag;
2411 filegen_type = filegen->type;
2413 /* "filegen ... enabled" is the default (when filegen is used) */
2414 filegen_flag |= FGEN_FLAG_ENABLED;
2416 my_opts = HEAD_PFIFO(my_node->options);
2417 for (; my_opts != NULL; my_opts = my_opts->link) {
2418 switch (my_opts->attr) {
2421 filegen_file = my_opts->value.s;
2425 switch (my_opts->value.i) {
2428 fatal_error("config-monitor: type-token=%d", my_opts->value.i);
2431 filegen_type = FILEGEN_NONE;
2435 filegen_type = FILEGEN_PID;
2439 filegen_type = FILEGEN_DAY;
2443 filegen_type = FILEGEN_WEEK;
2447 filegen_type = FILEGEN_MONTH;
2451 filegen_type = FILEGEN_YEAR;
2455 filegen_type = FILEGEN_AGE;
2461 switch (my_opts->value.i) {
2464 filegen_flag |= FGEN_FLAG_LINK;
2468 filegen_flag &= ~FGEN_FLAG_LINK;
2472 filegen_flag |= FGEN_FLAG_ENABLED;
2476 filegen_flag &= ~FGEN_FLAG_ENABLED;
2481 "Unknown filegen flag token %d",
2489 "Unknown filegen option token %d",
2494 filegen_config(filegen, statsdir, filegen_file,
2495 filegen_type, filegen_flag);
2502 free_config_monitor(
2506 if (ptree->stats_dir) {
2507 free(ptree->stats_dir);
2508 ptree->stats_dir = NULL;
2511 FREE_INT_FIFO(ptree->stats_list);
2512 FREE_FILEGEN_FIFO(ptree->filegen_opts);
2514 #endif /* FREE_CFG_T */
2523 static int warned_signd;
2525 restrict_node * my_node;
2528 struct addrinfo hints;
2529 struct addrinfo * ai_list;
2530 struct addrinfo * pai;
2532 int restrict_default;
2537 psl_item my_psl_item;
2539 attr_val * dflt_psl_atr;
2540 const char * signd_warning =
2541 #ifdef HAVE_NTP_SIGND
2542 "MS-SNTP signd operations currently block ntpd degrading service to all clients.";
2544 "mssntp restrict bit ignored, this ntpd was configured without --enable-ntp-signd.";
2547 /* Configure the mru options */
2548 my_opt = HEAD_PFIFO(ptree->mru_opts);
2549 for (; my_opt != NULL; my_opt = my_opt->link) {
2553 switch (my_opt->attr) {
2556 if (0 <= my_opt->value.i)
2557 mru_incalloc = my_opt->value.u;
2563 if (0 <= my_opt->value.i)
2564 mru_incalloc = (my_opt->value.u * 1024U)
2565 / sizeof(mon_entry);
2571 if (0 <= my_opt->value.i)
2572 mru_initalloc = my_opt->value.u;
2578 if (0 <= my_opt->value.i)
2579 mru_initalloc = (my_opt->value.u * 1024U)
2580 / sizeof(mon_entry);
2586 if (0 <= my_opt->value.i)
2587 mru_mindepth = my_opt->value.u;
2593 mru_maxage = my_opt->value.i;
2597 if (0 <= my_opt->value.i)
2598 mru_maxdepth = my_opt->value.u;
2600 mru_maxdepth = UINT_MAX;
2604 if (0 <= my_opt->value.i)
2605 mru_maxdepth = (my_opt->value.u * 1024U) /
2608 mru_maxdepth = UINT_MAX;
2613 "Unknown mru option %s (%d)",
2614 keyword(my_opt->attr), my_opt->attr);
2619 "mru %s %d out of range, ignored.",
2620 keyword(my_opt->attr), my_opt->value.i);
2623 /* Configure the discard options */
2624 my_opt = HEAD_PFIFO(ptree->discard_opts);
2625 for (; my_opt != NULL; my_opt = my_opt->link) {
2627 switch (my_opt->attr) {
2630 if (0 <= my_opt->value.i &&
2631 my_opt->value.i <= UCHAR_MAX)
2632 ntp_minpoll = (u_char)my_opt->value.u;
2635 "discard average %d out of range, ignored.",
2640 ntp_minpkt = my_opt->value.i;
2644 mon_age = my_opt->value.i;
2649 "Unknown discard option %s (%d)",
2650 keyword(my_opt->attr), my_opt->attr);
2655 /* Configure each line of restrict options */
2656 my_node = HEAD_PFIFO(ptree->restrict_opts);
2658 for (; my_node != NULL; my_node = my_node->link) {
2660 /* Grab the ippeerlmit */
2661 ippeerlimit = my_node->ippeerlimit;
2663 /* Parse the flags */
2667 my_opt = HEAD_PFIFO(my_node->flag_tok_fifo);
2668 for (; my_opt != NULL; my_opt = my_opt->link) {
2669 switch (my_opt->attr) {
2672 fatal_error("config_access: Unknown flag-type-token=%s/%d", keyword(my_opt->attr), my_opt->attr);
2675 mflags |= RESM_NTPONLY;
2679 mflags |= RESM_SOURCE;
2683 rflags |= RES_FLAKE;
2687 rflags |= RES_IGNORE;
2695 rflags |= RES_LIMITED;
2699 rflags |= RES_LPTRAP;
2703 rflags |= RES_MSSNTP;
2707 rflags |= RES_NOMODIFY;
2711 rflags |= RES_NOMRULIST;
2715 rflags |= RES_NOEPEER;
2719 rflags |= RES_NOPEER;
2723 rflags |= RES_NOQUERY;
2727 rflags |= RES_DONTSERVE;
2731 rflags |= RES_NOTRAP;
2735 rflags |= RES_DONTTRUST;
2738 case T_ServerresponseFuzz:
2739 rflags |= RES_SRVRSPFUZ;
2743 rflags |= RES_VERSION;
2748 if ((RES_MSSNTP & rflags) && !warned_signd) {
2750 fprintf(stderr, "%s\n", signd_warning);
2751 msyslog(LOG_WARNING, "%s", signd_warning);
2754 /* It would be swell if we could identify the line number */
2755 if ((RES_KOD & rflags) && !(RES_LIMITED & rflags)) {
2756 const char *kod_where = (my_node->addr)
2757 ? my_node->addr->address
2758 : (mflags & RESM_SOURCE)
2761 const char *kod_warn = "KOD does nothing without LIMITED.";
2763 fprintf(stderr, "restrict %s: %s\n", kod_where, kod_warn);
2764 msyslog(LOG_WARNING, "restrict %s: %s", kod_where, kod_warn);
2770 restrict_default = 0;
2772 if (NULL == my_node->addr) {
2774 if (!(RESM_SOURCE & mflags)) {
2776 * The user specified a default rule
2777 * without a -4 / -6 qualifier, add to
2780 restrict_default = 1;
2782 /* apply "restrict source ..." */
2783 DPRINTF(1, ("restrict source template ippeerlimit %d mflags %x rflags %x\n",
2784 ippeerlimit, mflags, rflags));
2785 hack_restrict(RESTRICT_FLAGS, NULL, NULL,
2786 ippeerlimit, mflags, rflags, 0);
2790 /* Resolve the specified address */
2791 AF(&addr) = (u_short)my_node->addr->type;
2793 if (getnetnum(my_node->addr->address,
2794 &addr, 1, t_UNK) != 1) {
2796 * Attempt a blocking lookup. This
2797 * is in violation of the nonblocking
2798 * design of ntpd's mainline code. The
2799 * alternative of running without the
2800 * restriction until the name resolved
2802 * Ideally some scheme could be used for
2803 * restrict directives in the startup
2804 * ntp.conf to delay starting up the
2805 * protocol machinery until after all
2806 * restrict hosts have been resolved.
2810 hints.ai_protocol = IPPROTO_UDP;
2811 hints.ai_socktype = SOCK_DGRAM;
2812 hints.ai_family = my_node->addr->type;
2813 rc = getaddrinfo(my_node->addr->address,
2818 "restrict: ignoring line %d, address/host '%s' unusable.",
2820 my_node->addr->address);
2823 INSIST(ai_list != NULL);
2825 INSIST(pai->ai_addr != NULL);
2826 INSIST(sizeof(addr) >=
2828 memcpy(&addr, pai->ai_addr,
2830 INSIST(AF_INET == AF(&addr) ||
2831 AF_INET6 == AF(&addr));
2834 SET_HOSTMASK(&mask, AF(&addr));
2836 /* Resolve the mask */
2837 if (my_node->mask) {
2839 AF(&mask) = my_node->mask->type;
2840 if (getnetnum(my_node->mask->address,
2841 &mask, 1, t_MSK) != 1) {
2843 "restrict: ignoring line %d, mask '%s' unusable.",
2845 my_node->mask->address);
2852 if (restrict_default) {
2853 AF(&addr) = AF_INET;
2854 AF(&mask) = AF_INET;
2855 hack_restrict(RESTRICT_FLAGS, &addr, &mask,
2856 ippeerlimit, mflags, rflags, 0);
2857 AF(&addr) = AF_INET6;
2858 AF(&mask) = AF_INET6;
2862 hack_restrict(RESTRICT_FLAGS, &addr, &mask,
2863 ippeerlimit, mflags, rflags, 0);
2865 NULL != (pai = pai->ai_next)) {
2866 INSIST(pai->ai_addr != NULL);
2867 INSIST(sizeof(addr) >=
2870 memcpy(&addr, pai->ai_addr,
2872 INSIST(AF_INET == AF(&addr) ||
2873 AF_INET6 == AF(&addr));
2874 SET_HOSTMASK(&mask, AF(&addr));
2876 } while (pai != NULL);
2878 if (ai_list != NULL)
2879 freeaddrinfo(ai_list);
2882 /* Deal with the Poll Skew List */
2888 * First, find the last default pollskewlist item.
2889 * There should only be one of these with the current grammar,
2890 * but better safe than sorry.
2892 dflt_psl_atr = NULL;
2893 atrv = HEAD_PFIFO(ptree->pollskewlist);
2894 for ( ; atrv != NULL; atrv = atrv->link) {
2895 switch (atrv->attr) {
2896 case -1: /* default */
2897 dflt_psl_atr = atrv;
2900 case 3: /* Fall through */
2901 case 4: /* Fall through */
2902 case 5: /* Fall through */
2903 case 6: /* Fall through */
2904 case 7: /* Fall through */
2905 case 8: /* Fall through */
2906 case 9: /* Fall through */
2907 case 10: /* Fall through */
2908 case 11: /* Fall through */
2909 case 12: /* Fall through */
2910 case 13: /* Fall through */
2911 case 14: /* Fall through */
2912 case 15: /* Fall through */
2913 case 16: /* Fall through */
2920 "config_access: default PSL scan: ignoring unexpected poll value %d",
2926 /* If we have a nonzero default, initialize the PSL */
2928 && ( 0 != dflt_psl_atr->value.r.first
2929 || 0 != dflt_psl_atr->value.r.last)) {
2932 for (i = 3; i <= 17; ++i) {
2933 attrtopsl(i, dflt_psl_atr);
2937 /* Finally, update the PSL with any explicit entries */
2938 atrv = HEAD_PFIFO(ptree->pollskewlist);
2939 for ( ; atrv != NULL; atrv = atrv->link) {
2940 switch (atrv->attr) {
2941 case -1: /* default */
2945 case 3: /* Fall through */
2946 case 4: /* Fall through */
2947 case 5: /* Fall through */
2948 case 6: /* Fall through */
2949 case 7: /* Fall through */
2950 case 8: /* Fall through */
2951 case 9: /* Fall through */
2952 case 10: /* Fall through */
2953 case 11: /* Fall through */
2954 case 12: /* Fall through */
2955 case 13: /* Fall through */
2956 case 14: /* Fall through */
2957 case 15: /* Fall through */
2958 case 16: /* Fall through */
2960 attrtopsl(atrv->attr, atrv);
2964 break; /* Ignore - we reported this above */
2970 msyslog(LOG_INFO, "Dumping PSL:");
2971 for (p = 3; p <= 17; ++p) {
2974 if (0 == get_pollskew(p, &psi)) {
2975 msyslog(LOG_INFO, "poll %d: sub %d, qty %d, msk %d",
2976 p, psi.sub, psi.qty, psi.msk);
2978 msyslog(LOG_ERR, "Dumping PSL: get_pollskew(%d) failed!", p);
2986 attrtopsl(int poll, attr_val *avp)
2989 DEBUG_INSIST((poll - 3) < sizeof psl);
2990 if (poll < 3 || poll > 17) {
2991 msyslog(LOG_ERR, "attrtopsl(%d, ...): Poll value is out of range - ignoring", poll);
2993 int pao = poll - 3; /* poll array offset */
2994 int lower = avp->value.r.first; /* a positive number */
2995 int upper = avp->value.r.last;
2996 int psmax = 1 << (poll - 1);
2999 if (lower > psmax) {
3000 msyslog(LOG_WARNING, "attrtopsl: default: poll %d lower bound reduced from %d to %d",
3001 poll, lower, psmax);
3004 if (upper > psmax) {
3005 msyslog(LOG_WARNING, "attrtopsl: default: poll %d upper bound reduced from %d to %d",
3006 poll, upper, psmax);
3009 psl[pao].sub = lower;
3010 psl[pao].qty = lower + upper;
3013 while (qmsk < (lower + upper)) {
3017 psl[pao].msk = qmsk;
3032 DEBUG_INSIST(3 <= p && 17 >= p);
3033 if (3 <= p && 17 >= p) {
3038 msyslog(LOG_ERR, "get_pollskew(%d): poll is not between 3 and 17!", p);
3052 FREE_ATTR_VAL_FIFO(ptree->mru_opts);
3053 FREE_ATTR_VAL_FIFO(ptree->discard_opts);
3054 FREE_RESTRICT_FIFO(ptree->restrict_opts);
3056 #endif /* FREE_CFG_T */
3064 attr_val * rlimit_av;
3066 rlimit_av = HEAD_PFIFO(ptree->rlimit);
3067 for (; rlimit_av != NULL; rlimit_av = rlimit_av->link) {
3068 switch (rlimit_av->attr) {
3071 fatal_error("config-rlimit: value-token=%d", rlimit_av->attr);
3074 /* What if we HAVE_OPT(SAVECONFIGQUIT) ? */
3075 if (HAVE_OPT( SAVECONFIGQUIT )) {
3078 if (rlimit_av->value.i == -1) {
3079 # if defined(HAVE_MLOCKALL)
3080 if (cur_memlock != 0) {
3081 if (-1 == munlockall()) {
3082 msyslog(LOG_ERR, "munlockall() failed: %m");
3086 # endif /* HAVE_MLOCKALL */
3087 } else if (rlimit_av->value.i >= 0) {
3088 #if defined(RLIMIT_MEMLOCK)
3089 # if defined(HAVE_MLOCKALL)
3090 if (cur_memlock != 1) {
3091 if (-1 == mlockall(MCL_CURRENT|MCL_FUTURE)) {
3092 msyslog(LOG_ERR, "mlockall() failed: %m");
3095 # endif /* HAVE_MLOCKALL */
3096 ntp_rlimit(RLIMIT_MEMLOCK,
3097 (rlim_t)(rlimit_av->value.i * 1024 * 1024),
3102 /* STDERR as well would be fine... */
3103 msyslog(LOG_WARNING, "'rlimit memlock' specified but is not available on this system.");
3104 #endif /* RLIMIT_MEMLOCK */
3106 msyslog(LOG_WARNING, "'rlimit memlock' value of %d is unexpected!", rlimit_av->value.i);
3111 #if defined(RLIMIT_STACK)
3112 ntp_rlimit(RLIMIT_STACK,
3113 (rlim_t)(rlimit_av->value.i * 4096),
3117 /* STDERR as well would be fine... */
3118 msyslog(LOG_WARNING, "'rlimit stacksize' specified but is not available on this system.");
3119 #endif /* RLIMIT_STACK */
3123 #if defined(RLIMIT_NOFILE)
3124 ntp_rlimit(RLIMIT_NOFILE,
3125 (rlim_t)(rlimit_av->value.i),
3129 /* STDERR as well would be fine... */
3130 msyslog(LOG_WARNING, "'rlimit filenum' specified but is not available on this system.");
3131 #endif /* RLIMIT_NOFILE */
3147 tinker = HEAD_PFIFO(ptree->tinker);
3148 for (; tinker != NULL; tinker = tinker->link) {
3149 switch (tinker->attr) {
3152 fatal_error("config_tinker: attr-token=%d", tinker->attr);
3167 item = LOOP_HUFFPUFF;
3179 item = LOOP_MAX_BACK;
3183 item = LOOP_MAX_FWD;
3187 item = LOOP_MINSTEP;
3194 loop_config(item, tinker->value.d);
3205 FREE_ATTR_VAL_FIFO(ptree->rlimit);
3213 FREE_ATTR_VAL_FIFO(ptree->tinker);
3215 #endif /* FREE_CFG_T */
3219 * config_nic_rules - apply interface listen/ignore/drop items
3225 int/*BOOL*/ input_from_file
3228 nic_rule_node * curr_node;
3230 nic_rule_match match_type;
3231 nic_rule_action action;
3237 curr_node = HEAD_PFIFO(ptree->nic_rules);
3239 if (curr_node != NULL
3240 && (HAVE_OPT( NOVIRTUALIPS ) || HAVE_OPT( INTERFACE ))) {
3242 "interface/nic rules are not allowed with --interface (-I) or --novirtualips (-L)%s",
3243 (input_from_file) ? ", exiting" : "");
3244 if (input_from_file)
3250 for (; curr_node != NULL; curr_node = curr_node->link) {
3252 if_name = curr_node->if_name;
3253 if (if_name != NULL)
3254 if_name = estrdup(if_name);
3256 switch (curr_node->match_class) {
3259 fatal_error("config_nic_rules: match-class-token=%d", curr_node->match_class);
3263 * 0 is out of range for valid token T_...
3264 * and in a nic_rules_node indicates the
3265 * interface descriptor is either a name or
3266 * address, stored in if_name in either case.
3268 INSIST(if_name != NULL);
3269 pchSlash = strchr(if_name, '/');
3270 if (pchSlash != NULL)
3272 if (is_ip_address(if_name, AF_UNSPEC, &addr)) {
3273 match_type = MATCH_IFADDR;
3274 if (pchSlash != NULL
3275 && 1 == sscanf(pchSlash + 1, "%d",
3278 SIZEOF_INADDR(AF(&addr));
3279 prefixlen = max(-1, prefixlen);
3280 prefixlen = min(prefixlen,
3284 match_type = MATCH_IFNAME;
3285 if (pchSlash != NULL)
3291 match_type = MATCH_ALL;
3295 match_type = MATCH_IPV4;
3299 match_type = MATCH_IPV6;
3303 match_type = MATCH_WILDCARD;
3307 switch (curr_node->action) {
3310 fatal_error("config_nic_rules: action-token=%d", curr_node->action);
3313 action = ACTION_LISTEN;
3317 action = ACTION_IGNORE;
3321 action = ACTION_DROP;
3325 add_nic_rule(match_type, if_name, prefixlen,
3327 timer_interfacetimeout(current_time + 2);
3328 if (if_name != NULL)
3337 free_config_nic_rules(
3341 nic_rule_node *curr_node;
3343 if (ptree->nic_rules != NULL) {
3345 UNLINK_FIFO(curr_node, *ptree->nic_rules, link);
3346 if (NULL == curr_node)
3348 free(curr_node->if_name);
3351 free(ptree->nic_rules);
3352 ptree->nic_rules = NULL;
3355 #endif /* FREE_CFG_T */
3359 apply_enable_disable(
3360 attr_val_fifo * fifo,
3364 attr_val *curr_tok_fifo;
3366 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
3370 for (curr_tok_fifo = HEAD_PFIFO(fifo);
3371 curr_tok_fifo != NULL;
3372 curr_tok_fifo = curr_tok_fifo->link) {
3374 option = curr_tok_fifo->value.i;
3379 "can not apply enable/disable token %d, unknown",
3384 proto_config(PROTO_AUTHENTICATE, enable, 0., NULL);
3388 proto_config(PROTO_BROADCLIENT, enable, 0., NULL);
3392 proto_config(PROTO_CAL, enable, 0., NULL);
3396 proto_config(PROTO_KERNEL, enable, 0., NULL);
3400 proto_config(PROTO_MONITOR, enable, 0., NULL);
3404 proto_config(PROTO_MODE7, enable, 0., NULL);
3408 proto_config(PROTO_NTP, enable, 0., NULL);
3412 proto_config(PROTO_PCEDIGEST, enable, 0., NULL);
3416 proto_config(PROTO_FILEGEN, enable, 0., NULL);
3420 proto_config(PROTO_UECRYPTO, enable, 0., NULL);
3424 proto_config(PROTO_UECRYPTONAK, enable, 0., NULL);
3428 proto_config(PROTO_UEDIGEST, enable, 0., NULL);
3431 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
3434 while (pentry->token) {
3435 if (pentry->token == option)
3439 if (!pentry->token) {
3441 "compat token %d not in bc_list[]",
3445 pentry->enabled = enable;
3458 apply_enable_disable(ptree->enable_opts, 1);
3459 apply_enable_disable(ptree->disable_opts, 0);
3465 free_config_system_opts(
3469 FREE_ATTR_VAL_FIFO(ptree->enable_opts);
3470 FREE_ATTR_VAL_FIFO(ptree->disable_opts);
3472 #endif /* FREE_CFG_T */
3482 my_lc = HEAD_PFIFO(ptree->logconfig);
3483 for (; my_lc != NULL; my_lc = my_lc->link) {
3484 switch (my_lc->attr) {
3487 ntp_syslogmask |= get_logmask(my_lc->value.s);
3491 ntp_syslogmask &= ~get_logmask(my_lc->value.s);
3495 ntp_syslogmask = get_logmask(my_lc->value.s);
3498 fatal_error("config-logconfig: modifier='%c'", my_lc->attr);
3506 free_config_logconfig(
3510 FREE_ATTR_VAL_FIFO(ptree->logconfig);
3512 #endif /* FREE_CFG_T */
3525 sn = HEAD_PFIFO(ptree->phone);
3526 for (; sn != NULL; sn = sn->link) {
3527 /* need to leave array entry for NULL terminator */
3528 if (i < COUNTOF(sys_phone) - 1) {
3529 sys_phone[i++] = estrdup(sn->s);
3530 sys_phone[i] = NULL;
3533 "phone: Number of phone entries exceeds %zu. Ignoring phone %s...",
3534 (COUNTOF(sys_phone) - 1), sn->s);
3545 #ifdef HAVE_DNSREGISTRATION
3546 extern int mdnstries;
3547 mdnstries = ptree->mdnstries;
3548 #endif /* HAVE_DNSREGISTRATION */
3557 FREE_STRING_FIFO(ptree->phone);
3559 #endif /* FREE_CFG_T */
3568 setvar_node *my_node;
3569 size_t varlen, vallen, octets;
3573 my_node = HEAD_PFIFO(ptree->setvar);
3574 for (; my_node != NULL; my_node = my_node->link) {
3575 varlen = strlen(my_node->var);
3576 vallen = strlen(my_node->val);
3577 octets = varlen + vallen + 1 + 1;
3578 str = erealloc(str, octets);
3579 snprintf(str, octets, "%s=%s", my_node->var,
3581 set_sys_var(str, octets, (my_node->isdefault)
3597 FREE_SETVAR_FIFO(ptree->setvar);
3599 #endif /* FREE_CFG_T */
3611 /* [Bug 3465] There is a built-in default for the TTLs. We must
3612 * overwrite 'sys_ttlmax' if we change that preset, and leave it
3615 curr_ttl = HEAD_PFIFO(ptree->ttl);
3616 for (; curr_ttl != NULL; curr_ttl = curr_ttl->link) {
3617 if (i < COUNTOF(sys_ttl))
3618 sys_ttl[i++] = (u_char)curr_ttl->i;
3621 "ttl: Number of TTL entries exceeds %zu. Ignoring TTL %d...",
3622 COUNTOF(sys_ttl), curr_ttl->i);
3624 if (0 != i) /* anything written back at all? */
3636 FREE_INT_FIFO(ptree->ttl);
3638 #endif /* FREE_CFG_T */
3647 addr_opts_node *curr_trap;
3649 sockaddr_u addr_sock;
3650 sockaddr_u peeraddr;
3651 struct interface *localaddr;
3652 struct addrinfo hints;
3654 settrap_parms *pstp;
3659 /* silence warning about addr_sock potentially uninitialized */
3660 AF(&addr_sock) = AF_UNSPEC;
3662 curr_trap = HEAD_PFIFO(ptree->trap);
3663 for (; curr_trap != NULL; curr_trap = curr_trap->link) {
3668 curr_opt = HEAD_PFIFO(curr_trap->options);
3669 for (; curr_opt != NULL; curr_opt = curr_opt->link) {
3670 if (T_Port == curr_opt->attr) {
3671 if (curr_opt->value.i < 1
3672 || curr_opt->value.i > USHRT_MAX) {
3674 "invalid port number "
3679 port = (u_short)curr_opt->value.i;
3681 else if (T_Interface == curr_opt->attr) {
3682 /* Resolve the interface address */
3683 ZERO_SOCK(&addr_sock);
3684 if (getnetnum(curr_opt->value.s,
3685 &addr_sock, 1, t_UNK) != 1) {
3690 localaddr = findinterface(&addr_sock);
3692 if (NULL == localaddr) {
3694 "can't find interface with address %s",
3701 /* Now process the trap for the specified interface
3707 ZERO_SOCK(&peeraddr);
3708 rc = getnetnum(curr_trap->addr->address,
3709 &peeraddr, 1, t_UNK);
3713 "trap: unable to use IP address %s.",
3714 curr_trap->addr->address);
3715 #else /* WORKER follows */
3717 * save context and hand it off
3718 * for name resolution.
3721 hints.ai_protocol = IPPROTO_UDP;
3722 hints.ai_socktype = SOCK_DGRAM;
3723 snprintf(port_text, sizeof(port_text),
3725 hints.ai_flags = Z_AI_NUMERICSERV;
3726 pstp = emalloc_zero(sizeof(*pstp));
3727 if (localaddr != NULL) {
3728 hints.ai_family = localaddr->family;
3729 pstp->ifaddr_nonnull = 1;
3730 memcpy(&pstp->ifaddr,
3732 sizeof(pstp->ifaddr));
3734 rc = getaddrinfo_sometime(
3735 curr_trap->addr->address,
3738 &trap_name_resolved,
3742 "config_trap: getaddrinfo_sometime(%s,%s): %m",
3743 curr_trap->addr->address,
3748 /* port is at same location for v4 and v6 */
3749 SET_PORT(&peeraddr, port);
3751 if (NULL == localaddr)
3752 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
3754 AF(&peeraddr) = AF(&addr_sock);
3756 if (!ctlsettrap(&peeraddr, localaddr, 0,
3759 "set trap %s -> %s failed.",
3768 * trap_name_resolved()
3770 * Callback invoked when config_trap()'s DNS lookup completes.
3779 const char * service,
3780 const struct addrinfo * hints,
3781 const struct addrinfo * res
3784 settrap_parms *pstp;
3785 struct interface *localaddr;
3786 sockaddr_u peeraddr;
3794 "giving up resolving trap host %s: %s (%d)",
3795 name, gai_strerror(rescode), rescode);
3799 INSIST(sizeof(peeraddr) >= res->ai_addrlen);
3801 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
3803 if (pstp->ifaddr_nonnull)
3804 localaddr = findinterface(&pstp->ifaddr);
3805 if (NULL == localaddr)
3806 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
3807 if (!ctlsettrap(&peeraddr, localaddr, 0, NTP_VERSION))
3808 msyslog(LOG_ERR, "set trap %s -> %s failed.",
3809 latoa(localaddr), stoa(&peeraddr));
3812 # endif /* WORKER */
3822 FREE_ADDR_OPTS_FIFO(ptree->trap);
3824 #endif /* FREE_CFG_T */
3833 addr_opts_node *curr_fudge;
3835 sockaddr_u addr_sock;
3836 address_node *addr_node;
3837 struct refclockstat clock_stat;
3840 curr_fudge = HEAD_PFIFO(ptree->fudge);
3841 for (; curr_fudge != NULL; curr_fudge = curr_fudge->link) {
3844 /* Get the reference clock address and
3845 * ensure that it is sane
3847 addr_node = curr_fudge->addr;
3848 ZERO_SOCK(&addr_sock);
3849 if (getnetnum(addr_node->address, &addr_sock, 1, t_REF)
3853 "unrecognized fudge reference clock address %s, line ignored",
3854 addr_node->address);
3855 } else if (!ISREFCLOCKADR(&addr_sock)) {
3858 "inappropriate address %s for the fudge command, line ignored",
3862 /* Parse all the options to the fudge command */
3864 /* some things are not necessarily cleared by ZERO...*/
3865 clock_stat.fudgeminjitter = 0.0;
3866 clock_stat.fudgetime1 = 0.0;
3867 clock_stat.fudgetime2 = 0.0;
3868 clock_stat.p_lastcode = NULL;
3869 clock_stat.clockdesc = NULL;
3870 clock_stat.kv_list = NULL;
3871 curr_opt = HEAD_PFIFO(curr_fudge->options);
3872 for (; curr_opt != NULL; curr_opt = curr_opt->link) {
3873 switch (curr_opt->attr) {
3876 clock_stat.haveflags |= CLK_HAVETIME1;
3877 clock_stat.fudgetime1 = curr_opt->value.d;
3881 clock_stat.haveflags |= CLK_HAVETIME2;
3882 clock_stat.fudgetime2 = curr_opt->value.d;
3886 clock_stat.haveflags |= CLK_HAVEVAL1;
3887 clock_stat.fudgeval1 = curr_opt->value.i;
3891 clock_stat.haveflags |= CLK_HAVEVAL2;
3892 /* strncpy() does exactly what we want here: */
3893 strncpy((char*)&clock_stat.fudgeval2,
3894 curr_opt->value.s, 4);
3898 clock_stat.haveflags |= CLK_HAVEFLAG1;
3899 if (curr_opt->value.i)
3900 clock_stat.flags |= CLK_FLAG1;
3902 clock_stat.flags &= ~CLK_FLAG1;
3906 clock_stat.haveflags |= CLK_HAVEFLAG2;
3907 if (curr_opt->value.i)
3908 clock_stat.flags |= CLK_FLAG2;
3910 clock_stat.flags &= ~CLK_FLAG2;
3914 clock_stat.haveflags |= CLK_HAVEFLAG3;
3915 if (curr_opt->value.i)
3916 clock_stat.flags |= CLK_FLAG3;
3918 clock_stat.flags &= ~CLK_FLAG3;
3922 clock_stat.haveflags |= CLK_HAVEFLAG4;
3923 if (curr_opt->value.i)
3924 clock_stat.flags |= CLK_FLAG4;
3926 clock_stat.flags &= ~CLK_FLAG4;
3930 clock_stat.haveflags |= CLK_HAVEMINJIT;
3931 clock_stat.fudgeminjitter = curr_opt->value.d;
3936 "Unexpected fudge flag %s (%d) for %s",
3937 token_name(curr_opt->attr),
3938 curr_opt->attr, addr_node->address);
3939 exit(curr_opt->attr ? curr_opt->attr : 1);
3944 refclock_control(&addr_sock, &clock_stat, NULL);
3957 FREE_ADDR_OPTS_FIFO(ptree->fudge);
3959 #endif /* FREE_CFG_T */
3970 curr_var = HEAD_PFIFO(ptree->vars);
3971 for (; curr_var != NULL; curr_var = curr_var->link) {
3972 /* Determine which variable to set and set it */
3973 switch (curr_var->attr) {
3975 case T_Broadcastdelay:
3976 proto_config(PROTO_BROADDELAY, 0, curr_var->value.d, NULL);
3980 loop_config(LOOP_TICK, curr_var->value.d);
3984 if ('\0' == curr_var->value.s[0]) {
3985 stats_drift_file = 0;
3986 msyslog(LOG_INFO, "config: driftfile disabled");
3988 stats_config(STATS_FREQ_FILE, curr_var->value.s, 0);
3992 /* DSCP is in the upper 6 bits of the IP TOS/DS field */
3993 qos = curr_var->value.i << 2;
3997 sys_ident = curr_var->value.s;
4000 case T_WanderThreshold: /* FALLTHROUGH */
4002 wander_threshold = curr_var->value.d;
4006 stats_config(STATS_LEAP_FILE, curr_var->value.s, curr_var->flag);
4010 case T_Leapsmearinterval:
4011 leap_smear_intv = curr_var->value.i;
4012 msyslog(LOG_INFO, "config: leap smear interval %i s", leap_smear_intv);
4017 stats_config(STATS_PID_FILE, curr_var->value.s, 0);
4021 if (-1 == change_logfile(curr_var->value.s, TRUE))
4023 "Cannot open logfile %s: %m",
4027 case T_Saveconfigdir:
4028 if (saveconfigdir != NULL)
4029 free(saveconfigdir);
4030 len = strlen(curr_var->value.s);
4032 saveconfigdir = NULL;
4033 } else if (DIR_SEP != curr_var->value.s[len - 1]
4034 #ifdef SYS_WINNT /* slash is also a dir. sep. on Windows */
4035 && '/' != curr_var->value.s[len - 1]
4039 saveconfigdir = emalloc(len + 1);
4040 snprintf(saveconfigdir, len + 1,
4045 saveconfigdir = estrdup(
4052 if (curr_var->value.i > 2 && curr_var->value.i < 32)
4053 sys_automax = (u_char)curr_var->value.i;
4056 "'automax' value %d ignored",
4063 "config_vars(): unexpected token %d",
4076 FREE_ATTR_VAL_FIFO(ptree->vars);
4078 #endif /* FREE_CFG_T */
4081 /* Define a function to check if a resolved address is sane.
4082 * If yes, return 1, else return 0;
4085 is_sane_resolved_address(
4086 sockaddr_u * peeraddr,
4090 if (!ISREFCLOCKADR(peeraddr) && ISBADADR(peeraddr)) {
4092 "attempt to configure invalid address %s",
4097 * Shouldn't be able to specify:
4098 * - multicast address for server/peer!
4099 * - unicast address for manycastclient!
4101 if ((T_Server == hmode || T_Peer == hmode || T_Pool == hmode)
4102 && IS_MCAST(peeraddr)) {
4104 "attempt to configure invalid address %s",
4108 if (T_Manycastclient == hmode && !IS_MCAST(peeraddr)) {
4110 "attempt to configure invalid address %s",
4115 if (IS_IPV6(peeraddr) && !ipv6_works)
4118 /* Ok, all tests succeeded, now we can return 1 */
4125 get_correct_host_mode(
4133 case T_Manycastclient:
4140 return MODE_BROADCAST;
4149 * peerflag_bits() get config_peers() peerflags value from a
4150 * peer_node's queue of flag attr_val entries.
4162 /* translate peerflags options to bits */
4164 hmode = pn->host_mode;
4165 option = HEAD_PFIFO(pn->peerflags);
4166 for (; option != NULL; option = option->link) {
4167 switch (option->value.i) {
4170 fatal_error("peerflag_bits: option-token=%d", option->value.i);
4173 peerflags |= FLAG_SKEY;
4177 peerflags |= FLAG_BURST;
4181 peerflags |= FLAG_IBURST;
4185 peerflags |= FLAG_NOSELECT;
4189 peerflags |= FLAG_PREEMPT;
4193 peerflags |= FLAG_PREFER;
4197 peerflags |= FLAG_TRUE;
4201 peerflags |= FLAG_XLEAVE;
4205 if ( MODE_CLIENT == hmode ) {
4206 peerflags |= FLAG_LOOPNONCE;
4221 sockaddr_u peeraddr;
4222 struct addrinfo hints;
4223 peer_node * curr_peer;
4224 peer_resolved_ctx * ctx;
4227 /* add servers named on the command line with iburst implied */
4229 cmdline_server_count > 0;
4230 cmdline_server_count--, cmdline_servers++) {
4232 ZERO_SOCK(&peeraddr);
4234 * If we have a numeric address, we can safely
4235 * proceed in the mainline with it. Otherwise, hand
4236 * the hostname off to the blocking child.
4238 * Note that if we're told to add the peer here, we
4239 * do that regardless of ippeerlimit.
4241 if (is_ip_address(*cmdline_servers, AF_UNSPEC,
4244 SET_PORT(&peeraddr, NTP_PORT);
4245 if (is_sane_resolved_address(&peeraddr,
4261 /* we have a hostname to resolve */
4263 ctx = emalloc_zero(sizeof(*ctx));
4264 ctx->family = AF_UNSPEC;
4265 ctx->host_mode = T_Server;
4266 ctx->hmode = MODE_CLIENT;
4267 ctx->version = NTP_VERSION;
4268 ctx->flags = FLAG_IBURST;
4271 hints.ai_family = (u_short)ctx->family;
4272 hints.ai_socktype = SOCK_DGRAM;
4273 hints.ai_protocol = IPPROTO_UDP;
4275 getaddrinfo_sometime_ex(*cmdline_servers,
4278 &peer_name_resolved,
4279 (void *)ctx, DNSFLAGS);
4280 # else /* !WORKER follows */
4282 "hostname %s can not be used, please use IP address instead.",
4283 curr_peer->addr->address);
4288 /* add associations from the configuration file */
4289 curr_peer = HEAD_PFIFO(ptree->peers);
4290 for (; curr_peer != NULL; curr_peer = curr_peer->link) {
4291 ZERO_SOCK(&peeraddr);
4292 /* Find the correct host-mode */
4293 hmode = get_correct_host_mode(curr_peer->host_mode);
4296 if (T_Pool == curr_peer->host_mode) {
4297 AF(&peeraddr) = curr_peer->addr->type;
4300 curr_peer->addr->address,
4304 curr_peer->peerversion,
4307 peerflag_bits(curr_peer),
4312 * If we have a numeric address, we can safely
4313 * proceed in the mainline with it. Otherwise, hand
4314 * the hostname off to the blocking child.
4316 } else if (is_ip_address(curr_peer->addr->address,
4317 curr_peer->addr->type, &peeraddr)) {
4319 SET_PORT(&peeraddr, NTP_PORT);
4320 if (is_sane_resolved_address(&peeraddr,
4321 curr_peer->host_mode))
4328 curr_peer->peerversion,
4331 peerflag_bits(curr_peer),
4336 /* we have a hostname to resolve */
4338 ctx = emalloc_zero(sizeof(*ctx));
4339 ctx->family = curr_peer->addr->type;
4340 ctx->host_mode = curr_peer->host_mode;
4342 ctx->version = curr_peer->peerversion;
4343 ctx->minpoll = curr_peer->minpoll;
4344 ctx->maxpoll = curr_peer->maxpoll;
4345 ctx->flags = peerflag_bits(curr_peer);
4346 ctx->ttl = curr_peer->ttl;
4347 ctx->keyid = curr_peer->peerkey;
4348 ctx->group = curr_peer->group;
4351 hints.ai_family = ctx->family;
4352 hints.ai_socktype = SOCK_DGRAM;
4353 hints.ai_protocol = IPPROTO_UDP;
4355 getaddrinfo_sometime_ex(curr_peer->addr->address,
4358 &peer_name_resolved, ctx,
4360 # else /* !WORKER follows */
4362 "hostname %s can not be used, please use IP address instead.",
4363 curr_peer->addr->address);
4371 * peer_name_resolved()
4373 * Callback invoked when config_peers()'s DNS lookup completes.
4382 const char * service,
4383 const struct addrinfo * hints,
4384 const struct addrinfo * res
4387 sockaddr_u peeraddr;
4388 peer_resolved_ctx * ctx;
4390 const char * fam_spec;
4397 DPRINTF(1, ("peer_name_resolved(%s) rescode %d\n", name, rescode));
4402 "giving up resolving host %s: %s (%d)",
4403 name, gai_strerror(rescode), rescode);
4407 /* Loop to configure a single association */
4408 for (; res != NULL; res = res->ai_next) {
4409 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
4410 if (is_sane_resolved_address(&peeraddr,
4412 NLOG(NLOG_SYSINFO) {
4414 fam_spec = (AF_INET6 == af)
4419 msyslog(LOG_INFO, "DNS %s %s-> %s",
4450 peer_node *curr_peer;
4452 if (ptree->peers != NULL) {
4454 UNLINK_FIFO(curr_peer, *ptree->peers, link);
4455 if (NULL == curr_peer)
4457 destroy_address_node(curr_peer->addr);
4458 destroy_attr_val_fifo(curr_peer->peerflags);
4462 ptree->peers = NULL;
4465 #endif /* FREE_CFG_T */
4474 sockaddr_u peeraddr;
4475 struct addrinfo hints;
4476 unpeer_node * curr_unpeer;
4481 curr_unpeer = HEAD_PFIFO(ptree->unpeers);
4482 for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) {
4484 * If we have no address attached, assume we have to
4485 * unpeer by AssocID.
4487 if (!curr_unpeer->addr) {
4488 p = findpeerbyassoc(curr_unpeer->assocID);
4490 msyslog(LOG_NOTICE, "unpeered %s",
4492 peer_clear(p, "GONE");
4499 AF(&peeraddr) = curr_unpeer->addr->type;
4500 name = curr_unpeer->addr->address;
4501 rc = getnetnum(name, &peeraddr, 0, t_UNK);
4502 /* Do we have a numeric address? */
4504 DPRINTF(1, ("unpeer: searching for %s\n",
4506 p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL);
4508 msyslog(LOG_NOTICE, "unpeered %s",
4510 peer_clear(p, "GONE");
4516 * It's not a numeric IP address, it's a hostname.
4517 * Check for associations with a matching hostname.
4519 for (p = peer_list; p != NULL; p = p->p_link)
4520 if (p->hostname != NULL)
4521 if (!strcasecmp(p->hostname, name))
4524 msyslog(LOG_NOTICE, "unpeered %s", name);
4525 peer_clear(p, "GONE");
4528 /* Resolve the hostname to address(es). */
4531 hints.ai_family = curr_unpeer->addr->type;
4532 hints.ai_socktype = SOCK_DGRAM;
4533 hints.ai_protocol = IPPROTO_UDP;
4534 getaddrinfo_sometime(name, "ntp", &hints,
4536 &unpeer_name_resolved, NULL);
4537 # else /* !WORKER follows */
4539 "hostname %s can not be used, please use IP address instead.",
4548 * unpeer_name_resolved()
4550 * Callback invoked when config_unpeers()'s DNS lookup completes.
4554 unpeer_name_resolved(
4559 const char * service,
4560 const struct addrinfo * hints,
4561 const struct addrinfo * res
4564 sockaddr_u peeraddr;
4567 const char * fam_spec;
4571 DPRINTF(1, ("unpeer_name_resolved(%s) rescode %d\n", name, rescode));
4574 msyslog(LOG_ERR, "giving up resolving unpeer %s: %s (%d)",
4575 name, gai_strerror(rescode), rescode);
4579 * Loop through the addresses found
4581 for (; res != NULL; res = res->ai_next) {
4582 INSIST(res->ai_addrlen <= sizeof(peeraddr));
4583 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
4584 DPRINTF(1, ("unpeer: searching for peer %s\n",
4586 peer = findexistingpeer(&peeraddr, NULL, NULL, -1, 0, NULL);
4589 fam_spec = (AF_INET6 == af)
4594 msyslog(LOG_NOTICE, "unpeered %s %s-> %s", name,
4595 fam_spec, stoa(&peeraddr));
4596 peer_clear(peer, "GONE");
4606 free_config_unpeers(
4610 unpeer_node *curr_unpeer;
4612 if (ptree->unpeers != NULL) {
4614 UNLINK_FIFO(curr_unpeer, *ptree->unpeers, link);
4615 if (NULL == curr_unpeer)
4617 destroy_address_node(curr_unpeer->addr);
4620 free(ptree->unpeers);
4623 #endif /* FREE_CFG_T */
4628 config_reset_counters(
4632 int_node *counter_set;
4634 for (counter_set = HEAD_PFIFO(ptree->reset_counters);
4635 counter_set != NULL;
4636 counter_set = counter_set->link) {
4637 switch (counter_set->i) {
4639 DPRINTF(1, ("config_reset_counters %s (%d) invalid\n",
4640 keyword(counter_set->i), counter_set->i));
4678 free_config_reset_counters(
4682 FREE_INT_FIFO(ptree->reset_counters);
4684 #endif /* FREE_CFG_T */
4694 server_info *serv_info;
4695 attr_val *init_stmt;
4698 /* Check if a simulate block was found in the configuration code.
4699 * If not, return an error and exit
4701 sim_n = HEAD_PFIFO(ptree->sim_details);
4702 if (NULL == sim_n) {
4703 fprintf(stderr, "ERROR!! I couldn't find a \"simulate\" block for configuring the simulator.\n");
4704 fprintf(stderr, "\tCheck your configuration file.\n");
4708 /* Process the initialization statements
4709 * -------------------------------------
4711 init_stmt = HEAD_PFIFO(sim_n->init_opts);
4712 for (; init_stmt != NULL; init_stmt = init_stmt->link) {
4713 switch(init_stmt->attr) {
4716 simulation.beep_delay = init_stmt->value.d;
4719 case T_Sim_Duration:
4720 simulation.end_time = init_stmt->value.d;
4725 "Unknown simulator init token %d\n",
4731 /* Process the server list
4732 * -----------------------
4734 simulation.num_of_servers = 0;
4735 serv_info = HEAD_PFIFO(sim_n->servers);
4736 for (; serv_info != NULL; serv_info = serv_info->link)
4737 simulation.num_of_servers++;
4738 simulation.servers = eallocarray(simulation.num_of_servers,
4739 sizeof(simulation.servers[0]));
4742 serv_info = HEAD_PFIFO(sim_n->servers);
4743 for (; serv_info != NULL; serv_info = serv_info->link) {
4744 if (NULL == serv_info) {
4745 fprintf(stderr, "Simulator server list is corrupt\n");
4748 simulation.servers[i] = *serv_info;
4749 simulation.servers[i].link = NULL;
4754 printf("Creating server associations\n");
4755 create_server_associations();
4756 fprintf(stderr,"\tServer associations successfully created!!\n");
4767 server_info *serv_n;
4768 script_info *script_n;
4770 if (NULL == ptree->sim_details)
4772 sim_n = HEAD_PFIFO(ptree->sim_details);
4773 free(ptree->sim_details);
4774 ptree->sim_details = NULL;
4778 FREE_ATTR_VAL_FIFO(sim_n->init_opts);
4780 UNLINK_FIFO(serv_n, *sim_n->servers, link);
4783 free(serv_n->curr_script);
4784 if (serv_n->script != NULL) {
4786 UNLINK_FIFO(script_n, *serv_n->script,
4788 if (script_n == NULL)
4792 free(serv_n->script);
4798 #endif /* FREE_CFG_T */
4802 /* Define two different config functions. One for the daemon and the other for
4803 * the simulator. The simulator ignores a lot of the standard ntpd configuration
4810 int/*BOOL*/ input_from_files
4813 /* [Bug 3435] check and esure clock sanity if configured from
4814 * file and clock sanity parameters (-> basedate) are given. Do
4815 * this ASAP, so we don't disturb the closed loop controller.
4817 if (input_from_files) {
4818 if (config_tos_clock(ptree))
4822 config_nic_rules(ptree, input_from_files);
4823 config_monitor(ptree);
4826 config_access(ptree);
4827 config_tinker(ptree);
4828 config_rlimit(ptree);
4829 config_system_opts(ptree);
4830 config_logconfig(ptree);
4831 config_phone(ptree);
4832 config_mdnstries(ptree);
4833 config_setvar(ptree);
4837 io_open_sockets(); /* [bug 2837] dep. on config_vars() */
4839 config_trap(ptree); /* [bug 2923] dep. on io_open_sockets() */
4840 config_other_modes(ptree);
4841 config_peers(ptree);
4842 config_unpeers(ptree);
4843 config_fudge(ptree);
4844 config_reset_counters(ptree);
4852 #ifdef TEST_BLOCKING_WORKER
4854 struct addrinfo hints;
4857 hints.ai_socktype = SOCK_STREAM;
4858 hints.ai_protocol = IPPROTO_TCP;
4859 getaddrinfo_sometime("www.cnn.com", "ntp", &hints,
4861 gai_test_callback, (void *)1);
4862 hints.ai_family = AF_INET6;
4863 getaddrinfo_sometime("ipv6.google.com", "ntp", &hints,
4865 gai_test_callback, (void *)0x600);
4878 printf("Configuring Simulator...\n");
4879 printf("Some ntpd-specific commands in the configuration file will be ignored.\n");
4882 config_monitor(ptree);
4883 config_tinker(ptree);
4885 config_rlimit(ptree); /* not needed for the simulator */
4886 config_system_opts(ptree);
4887 config_logconfig(ptree);
4895 * config_remotely() - implements ntpd side of ntpq :config
4899 sockaddr_u * remote_addr
4904 snprintf(origin, sizeof(origin), "remote config from %s",
4906 lex_init_stack(origin, NULL); /* no checking needed... */
4907 init_syntax_tree(&cfgt);
4911 cfgt.source.attr = CONF_SOURCE_NTPQ;
4912 cfgt.timestamp = time(NULL);
4913 cfgt.source.value.s = estrdup(stoa(remote_addr));
4915 DPRINTF(1, ("Finished Parsing!!\n"));
4917 save_and_apply_config_tree(FALSE);
4922 * getconfig() - process startup configuration file e.g /etc/ntp.conf
4933 atexit(free_all_config_trees);
4936 config_file = CONFIG_FILE;
4939 if (!ExpandEnvironmentStringsA(temp, config_file_storage,
4940 sizeof(config_file_storage))) {
4941 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m");
4944 config_file = config_file_storage;
4946 temp = ALT_CONFIG_FILE;
4947 if (!ExpandEnvironmentStringsA(temp, alt_config_file_storage,
4948 sizeof(alt_config_file_storage))) {
4949 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m");
4952 alt_config_file = alt_config_file_storage;
4953 #endif /* SYS_WINNT */
4956 * install a non default variable with this daemon version
4958 snprintf(line, sizeof(line), "daemon_version=\"%s\"", Version);
4959 set_sys_var(line, strlen(line) + 1, RO);
4962 * Set up for the first time step to install a variable showing
4963 * which syscall is being used to step.
4965 set_tod_using = &ntpd_set_tod_using;
4967 getCmdOpts(argc, argv);
4968 init_syntax_tree(&cfgt);
4970 !lex_init_stack(FindConfig(config_file), "r")
4972 /* If there is no config_file, try NetInfo. */
4973 && check_netinfo && !(config_netinfo = get_netinfo_config())
4974 #endif /* HAVE_NETINFO */
4976 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(config_file));
4982 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
4984 if (!lex_init_stack(FindConfig(alt_config_file), "r")) {
4986 * Broadcast clients can sometimes run without
4987 * a configuration file.
4989 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(alt_config_file));
4994 cfgt.source.value.s = estrdup(alt_config_file);
4995 #endif /* SYS_WINNT */
4997 cfgt.source.value.s = estrdup(config_file);
5000 /*** BULK OF THE PARSER ***/
5002 yydebug = !!(debug >= 5);
5007 DPRINTF(1, ("Finished Parsing!!\n"));
5009 cfgt.source.attr = CONF_SOURCE_FILE;
5010 cfgt.timestamp = time(NULL);
5012 save_and_apply_config_tree(TRUE);
5016 free_netinfo_config(config_netinfo);
5017 #endif /* HAVE_NETINFO */
5022 save_and_apply_config_tree(int/*BOOL*/ input_from_file)
5026 config_tree *punlinked;
5030 * Keep all the configuration trees applied since startup in
5031 * a list that can be used to dump the configuration back to
5034 ptree = emalloc(sizeof(*ptree));
5035 memcpy(ptree, &cfgt, sizeof(*ptree));
5038 LINK_TAIL_SLIST(cfg_tree_history, ptree, link, config_tree);
5041 if (HAVE_OPT( SAVECONFIGQUIT )) {
5046 dumpfile = fopen(OPT_ARG( SAVECONFIGQUIT ), "w");
5047 if (NULL == dumpfile) {
5050 "can not create save file %s, error %d %m\n",
5051 OPT_ARG(SAVECONFIGQUIT), err);
5055 dumpfailed = dump_all_config_trees(dumpfile, 0);
5058 "--saveconfigquit %s error %d\n",
5059 OPT_ARG( SAVECONFIGQUIT ),
5063 "configuration saved to %s\n",
5064 OPT_ARG( SAVECONFIGQUIT ));
5068 #endif /* SAVECONFIG */
5070 /* The actual configuration done depends on whether we are configuring the
5071 * simulator or the daemon. Perform a check and call the appropriate
5072 * function as needed.
5076 config_ntpd(ptree, input_from_file);
5078 config_ntpdsim(ptree);
5082 * With configure --disable-saveconfig, there's no use keeping
5083 * the config tree around after application, so free it.
5086 UNLINK_SLIST(punlinked, cfg_tree_history, ptree, link,
5088 INSIST(punlinked == ptree);
5089 free_config_tree(ptree);
5093 /* Hack to disambiguate 'server' statements for refclocks and network peers.
5094 * Please note the qualification 'hack'. It's just that.
5098 const address_node * addr
5101 return addr && addr->address && !strncmp(addr->address, "127.127.", 8);
5111 snprintf(line, sizeof(line), "settimeofday=\"%s\"", which);
5112 set_sys_var(line, strlen(line) + 1, RO);
5126 snprintf(buf, LIB_BUFLENGTH, "%g", d);
5128 /* use lowercase 'e', strip any leading zeroes in exponent */
5129 pch_e = strchr(buf, 'e');
5130 if (NULL == pch_e) {
5131 pch_e = strchr(buf, 'E');
5140 while ('0' == *pch_nz)
5142 if (pch_nz == pch_e)
5144 strlcpy(pch_e, pch_nz, LIB_BUFLENGTH - (pch_e - buf));
5150 /* FUNCTIONS COPIED FROM THE OLDER ntp_config.c
5151 * --------------------------------------------
5156 * get_pfxmatch - find value for prefixmatch
5157 * and update char * accordingly
5165 while (m->name != NULL) {
5166 if (strncmp(*pstr, m->name, strlen(m->name)) == 0) {
5167 *pstr += strlen(m->name);
5177 * get_match - find logmask value
5185 while (m->name != NULL) {
5186 if (strcmp(str, m->name) == 0)
5195 * get_logmask - build bitmask for ntp_syslogmask
5206 mask = get_match(str, logcfg_noclass_items);
5211 offset = get_pfxmatch(&t, logcfg_class);
5212 mask = get_match(t, logcfg_class_items);
5215 return mask << offset;
5217 msyslog(LOG_ERR, "logconfig: '%s' not recognized - ignored",
5227 * get_netinfo_config - find the nearest NetInfo domain with an ntp
5228 * configuration and initialize the configuration state.
5230 static struct netinfo_config_state *
5231 get_netinfo_config(void)
5236 struct netinfo_config_state *config;
5238 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL;
5240 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) {
5242 if (ni_open(domain, "..", &next_domain) != NI_OK) {
5243 ni_free(next_domain);
5247 domain = next_domain;
5249 if (status != NI_OK) {
5254 config = emalloc(sizeof(*config));
5255 config->domain = domain;
5256 config->config_dir = config_dir;
5257 config->prop_index = 0;
5258 config->val_index = 0;
5259 config->val_list = NULL;
5266 * free_netinfo_config - release NetInfo configuration state
5269 free_netinfo_config(
5270 struct netinfo_config_state *config
5273 ni_free(config->domain);
5279 * gettokens_netinfo - return tokens from NetInfo
5283 struct netinfo_config_state *config,
5288 int prop_index = config->prop_index;
5289 int val_index = config->val_index;
5290 char **val_list = config->val_list;
5293 * Iterate through each keyword and look for a property that matches it.
5297 for (; prop_index < COUNTOF(keywords); prop_index++)
5299 ni_namelist namelist;
5300 struct keyword current_prop = keywords[prop_index];
5304 * For each value associated in the property, we're going to return
5305 * a separate line. We squirrel away the values in the config state
5306 * so the next time through, we don't need to do this lookup.
5309 if (NI_OK == ni_lookupprop(config->domain,
5310 &config->config_dir, current_prop.text,
5313 /* Found the property, but it has no values */
5314 if (namelist.ni_namelist_len == 0) continue;
5318 (namelist.ni_namelist_len + 1),
5320 val_list = config->val_list;
5323 index < namelist.ni_namelist_len;
5327 value = namelist.ni_namelist_val[index];
5328 val_list[index] = estrdup(value);
5330 val_list[index] = NULL;
5334 ni_namelist_free(&namelist);
5336 config->prop_index = prop_index;
5339 /* No list; we're done here. */
5341 return CONFIG_UNKNOWN;
5344 * We have a list of values for the current property.
5345 * Iterate through them and return each in order.
5347 if (val_list[val_index]) {
5350 char *tokens = val_list[val_index];
5352 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]);
5354 (const char*)tokenlist[0] = keywords[prop_index].text;
5355 for (ntok = 1; ntok < MAXTOKENS; ntok++) {
5356 tokenlist[ntok] = tokens;
5357 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted))
5358 quoted ^= (*tokens++ == '"');
5360 if (ISEOL(*tokens)) {
5363 } else { /* must be space */
5365 while (ISSPACE(*tokens))
5372 if (ntok == MAXTOKENS) {
5373 /* HMS: chomp it to lose the EOL? */
5375 "gettokens_netinfo: too many tokens. Ignoring: %s",
5378 *ntokens = ntok + 1;
5381 config->val_index++; /* HMS: Should this be in the 'else'? */
5383 return keywords[prop_index].keytype;
5386 /* We're done with the current property. */
5387 prop_index = ++config->prop_index;
5389 /* Free val_list and reset counters. */
5390 for (val_index = 0; val_list[val_index]; val_index++)
5391 free(val_list[val_index]);
5393 val_list = config->val_list = NULL;
5394 val_index = config->val_index = 0;
5398 #endif /* HAVE_NETINFO */
5402 * getnetnum - return a net number (this is crude, but careful)
5404 * returns 1 for success, and mysteriously, 0 for most failures, and
5405 * -1 if the address found is IPv6 and we believe IPv6 isn't working.
5413 enum gnn_type a_type /* ignored */
5416 REQUIRE(AF_UNSPEC == AF(addr) ||
5417 AF_INET == AF(addr) ||
5418 AF_INET6 == AF(addr));
5420 if (!is_ip_address(num, AF(addr), addr))
5423 if (IS_IPV6(addr) && !ipv6_works)
5426 # ifdef ISC_PLATFORM_HAVESALEN
5427 addr->sa.sa_len = SIZEOF_SOCKADDR(AF(addr));
5429 SET_PORT(addr, NTP_PORT);
5431 DPRINTF(2, ("getnetnum given %s, got %s\n", num, stoa(addr)));
5437 #if defined(HAVE_SETRLIMIT)
5443 const char * rl_sstr
5449 # ifdef RLIMIT_MEMLOCK
5450 case RLIMIT_MEMLOCK:
5451 if (HAVE_OPT( SAVECONFIGQUIT )) {
5455 * The default RLIMIT_MEMLOCK is very low on Linux systems.
5456 * Unless we increase this limit malloc calls are likely to
5457 * fail if we drop root privilege. To be useful the value
5458 * has to be larger than the largest ntpd resident set size.
5460 DPRINTF(2, ("ntp_rlimit: MEMLOCK: %d %s\n",
5461 (int)(rl_value / rl_scale), rl_sstr));
5462 rl.rlim_cur = rl.rlim_max = rl_value;
5463 if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1)
5464 msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
5466 # endif /* RLIMIT_MEMLOCK */
5468 # ifdef RLIMIT_NOFILE
5471 * For large systems the default file descriptor limit may
5474 DPRINTF(2, ("ntp_rlimit: NOFILE: %d %s\n",
5475 (int)(rl_value / rl_scale), rl_sstr));
5476 rl.rlim_cur = rl.rlim_max = rl_value;
5477 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
5478 msyslog(LOG_ERR, "Cannot set RLIMIT_NOFILE: %m");
5480 # endif /* RLIMIT_NOFILE */
5482 # ifdef RLIMIT_STACK
5485 * Provide a way to set the stack limit to something
5486 * smaller, so that we don't lock a lot of unused
5489 DPRINTF(2, ("ntp_rlimit: STACK: %d %s pages\n",
5490 (int)(rl_value / rl_scale), rl_sstr));
5491 if (-1 == getrlimit(RLIMIT_STACK, &rl)) {
5492 msyslog(LOG_ERR, "getrlimit(RLIMIT_STACK) failed: %m");
5494 if (rl_value > rl.rlim_max) {
5495 msyslog(LOG_WARNING,
5496 "ntp_rlimit: using maximum allowed stack limit %lu instead of %lu.",
5497 (u_long)rl.rlim_max,
5499 rl_value = rl.rlim_max;
5501 rl.rlim_cur = rl_value;
5502 if (-1 == setrlimit(RLIMIT_STACK, &rl)) {
5504 "ntp_rlimit: Cannot set RLIMIT_STACK: %m");
5508 # endif /* RLIMIT_STACK */
5511 fatal_error("ntp_rlimit: unexpected RLIMIT case: %d", rl_what);
5514 #endif /* HAVE_SETRLIMIT */
5522 static char ifs[1024];
5526 if (iflags & INT_UP) {
5528 appendstr(ifs, sizeof ifs, "up");
5531 if (iflags & INT_PPP) {
5533 appendstr(ifs, sizeof ifs, "ppp");
5536 if (iflags & INT_LOOPBACK) {
5537 iflags &= ~INT_LOOPBACK;
5538 appendstr(ifs, sizeof ifs, "loopback");
5541 if (iflags & INT_BROADCAST) {
5542 iflags &= ~INT_BROADCAST;
5543 appendstr(ifs, sizeof ifs, "broadcast");
5546 if (iflags & INT_MULTICAST) {
5547 iflags &= ~INT_MULTICAST;
5548 appendstr(ifs, sizeof ifs, "multicast");
5551 if (iflags & INT_BCASTOPEN) {
5552 iflags &= ~INT_BCASTOPEN;
5553 appendstr(ifs, sizeof ifs, "bcastopen");
5556 if (iflags & INT_MCASTOPEN) {
5557 iflags &= ~INT_MCASTOPEN;
5558 appendstr(ifs, sizeof ifs, "mcastopen");
5561 if (iflags & INT_WILDCARD) {
5562 iflags &= ~INT_WILDCARD;
5563 appendstr(ifs, sizeof ifs, "wildcard");
5566 if (iflags & INT_MCASTIF) {
5567 iflags &= ~INT_MCASTIF;
5568 appendstr(ifs, sizeof ifs, "MCASTif");
5571 if (iflags & INT_PRIVACY) {
5572 iflags &= ~INT_PRIVACY;
5573 appendstr(ifs, sizeof ifs, "IPv6privacy");
5576 if (iflags & INT_BCASTXMIT) {
5577 iflags &= ~INT_BCASTXMIT;
5578 appendstr(ifs, sizeof ifs, "bcastxmit");
5584 snprintf(string, sizeof string, "%0x", iflags);
5585 appendstr(ifs, sizeof ifs, string);
5597 static char mfs[1024];
5601 if (mflags & RESM_NTPONLY) {
5602 mflags &= ~RESM_NTPONLY;
5603 appendstr(mfs, sizeof mfs, "ntponly");
5606 if (mflags & RESM_SOURCE) {
5607 mflags &= ~RESM_SOURCE;
5608 appendstr(mfs, sizeof mfs, "source");
5614 snprintf(string, sizeof string, "%0x", mflags);
5615 appendstr(mfs, sizeof mfs, string);
5627 static char rfs[1024];
5631 if (rflags & RES_FLAKE) {
5632 rflags &= ~RES_FLAKE;
5633 appendstr(rfs, sizeof rfs, "flake");
5636 if (rflags & RES_IGNORE) {
5637 rflags &= ~RES_IGNORE;
5638 appendstr(rfs, sizeof rfs, "ignore");
5641 if (rflags & RES_KOD) {
5643 appendstr(rfs, sizeof rfs, "kod");
5646 if (rflags & RES_MSSNTP) {
5647 rflags &= ~RES_MSSNTP;
5648 appendstr(rfs, sizeof rfs, "mssntp");
5651 if (rflags & RES_LIMITED) {
5652 rflags &= ~RES_LIMITED;
5653 appendstr(rfs, sizeof rfs, "limited");
5656 if (rflags & RES_LPTRAP) {
5657 rflags &= ~RES_LPTRAP;
5658 appendstr(rfs, sizeof rfs, "lptrap");
5661 if (rflags & RES_NOMODIFY) {
5662 rflags &= ~RES_NOMODIFY;
5663 appendstr(rfs, sizeof rfs, "nomodify");
5666 if (rflags & RES_NOMRULIST) {
5667 rflags &= ~RES_NOMRULIST;
5668 appendstr(rfs, sizeof rfs, "nomrulist");
5671 if (rflags & RES_NOEPEER) {
5672 rflags &= ~RES_NOEPEER;
5673 appendstr(rfs, sizeof rfs, "noepeer");
5676 if (rflags & RES_NOPEER) {
5677 rflags &= ~RES_NOPEER;
5678 appendstr(rfs, sizeof rfs, "nopeer");
5681 if (rflags & RES_NOQUERY) {
5682 rflags &= ~RES_NOQUERY;
5683 appendstr(rfs, sizeof rfs, "noquery");
5686 if (rflags & RES_DONTSERVE) {
5687 rflags &= ~RES_DONTSERVE;
5688 appendstr(rfs, sizeof rfs, "dontserve");
5691 if (rflags & RES_NOTRAP) {
5692 rflags &= ~RES_NOTRAP;
5693 appendstr(rfs, sizeof rfs, "notrap");
5696 if (rflags & RES_DONTTRUST) {
5697 rflags &= ~RES_DONTTRUST;
5698 appendstr(rfs, sizeof rfs, "notrust");
5701 if (rflags & RES_SRVRSPFUZ) {
5702 rflags &= ~RES_SRVRSPFUZ;
5703 appendstr(rfs, sizeof rfs, "srvrspfuz");
5706 if (rflags & RES_VERSION) {
5707 rflags &= ~RES_VERSION;
5708 appendstr(rfs, sizeof rfs, "version");
5714 snprintf(string, sizeof string, "%0x", rflags);
5715 appendstr(rfs, sizeof rfs, string);
5718 if ('\0' == rfs[0]) {
5719 appendstr(rfs, sizeof rfs, "(none)");
5733 if (*string != '\0') {
5734 (void)strlcat(string, ",", s);
5736 (void)strlcat(string, new, s);