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>
34 #include <isc/result.h>
39 #include "ntp_unixtime.h"
40 #include "ntp_refclock.h"
41 #include "ntp_filegen.h"
42 #include "ntp_stdlib.h"
43 #include "lib_strbuf.h"
44 #include "ntp_assert.h"
45 #include "ntp_random.h"
47 * [Bug 467]: Some linux headers collide with CONFIG_PHONE and CONFIG_KEYS
48 * so #include these later.
50 #include "ntp_config.h"
51 #include "ntp_cmdargs.h"
52 #include "ntp_scanner.h"
53 #include "ntp_parser.h"
54 #include "ntpd-opts.h"
57 /* list of servers from command line for config_peers() */
58 int cmdline_server_count;
59 char ** cmdline_servers;
61 /* set to zero if admin doesn't want memory locked */
65 * "logconfig" building blocks
68 const char * const name;
72 static struct masks logcfg_class[] = {
73 { "clock", NLOG_OCLOCK },
74 { "peer", NLOG_OPEER },
75 { "sync", NLOG_OSYNC },
80 /* logcfg_noclass_items[] masks are complete and must not be shifted */
81 static struct masks logcfg_noclass_items[] = {
82 { "allall", NLOG_SYSMASK | NLOG_PEERMASK | NLOG_CLOCKMASK | NLOG_SYNCMASK },
83 { "allinfo", NLOG_SYSINFO | NLOG_PEERINFO | NLOG_CLOCKINFO | NLOG_SYNCINFO },
84 { "allevents", NLOG_SYSEVENT | NLOG_PEEREVENT | NLOG_CLOCKEVENT | NLOG_SYNCEVENT },
85 { "allstatus", NLOG_SYSSTATUS | NLOG_PEERSTATUS | NLOG_CLOCKSTATUS | NLOG_SYNCSTATUS },
86 { "allstatistics", NLOG_SYSSTATIST | NLOG_PEERSTATIST | NLOG_CLOCKSTATIST | NLOG_SYNCSTATIST },
87 /* the remainder are misspellings of clockall, peerall, sysall, and syncall. */
88 { "allclock", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OCLOCK },
89 { "allpeer", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OPEER },
90 { "allsys", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYS },
91 { "allsync", (NLOG_INFO | NLOG_STATIST | NLOG_EVENT | NLOG_STATUS) << NLOG_OSYNC },
95 /* logcfg_class_items[] masks are shiftable by NLOG_O* counts */
96 static struct masks logcfg_class_items[] = {
97 { "all", NLOG_INFO | NLOG_EVENT | NLOG_STATUS | NLOG_STATIST },
98 { "info", NLOG_INFO },
99 { "events", NLOG_EVENT },
100 { "status", NLOG_STATUS },
101 { "statistics", NLOG_STATIST },
105 typedef struct peer_resolved_ctx_tag {
107 int host_mode; /* T_* token identifier */
110 u_char hmode; /* MODE_* */
119 #define MAXPHONE 10 /* maximum number of phone strings */
120 #define MAXPPS 20 /* maximum length of PPS device string */
123 * Miscellaneous macros
125 #define ISEOL(c) ((c) == '#' || (c) == '\n' || (c) == '\0')
126 #define ISSPACE(c) ((c) == ' ' || (c) == '\t')
128 #define _UC(str) ((char *)(intptr_t)(str))
131 * Definitions of things either imported from or exported to outside
133 extern int yydebug; /* ntp_parser.c (.y) */
134 config_tree cfgt; /* Parser output stored here */
135 struct config_tree_tag *cfg_tree_history; /* History of configs */
136 char *sys_phone[MAXPHONE] = {NULL}; /* ACTS phone numbers */
137 char default_keysdir[] = NTP_KEYSDIR;
138 char *keysdir = default_keysdir; /* crypto keys directory */
139 char * saveconfigdir;
140 #if defined(HAVE_SCHED_SETSCHEDULER)
141 int config_priority_override = 0;
145 const char *config_file;
146 static char default_ntp_signd_socket[] =
147 #ifdef NTP_SIGND_PATH
152 char *ntp_signd_socket = default_ntp_signd_socket;
154 struct netinfo_config_state *config_netinfo = NULL;
155 int check_netinfo = 1;
156 #endif /* HAVE_NETINFO */
158 char *alt_config_file;
160 char config_file_storage[MAX_PATH];
161 char alt_config_file_storage[MAX_PATH];
162 #endif /* SYS_WINNT */
166 * NetInfo configuration state
168 struct netinfo_config_state {
169 void *domain; /* domain with config */
170 ni_id config_dir; /* ID config dir */
171 int prop_index; /* current property */
172 int val_index; /* current value */
173 char **val_list; /* value list */
177 struct REMOTE_CONFIG_INFO remote_config; /* Remote configuration buffer and
179 int old_config_style = 1; /* A boolean flag, which when set,
180 * indicates that the old configuration
181 * format with a newline at the end of
182 * every command is being used
184 int cryptosw; /* crypto command called */
186 extern char *stats_drift_file; /* name of the driftfile */
188 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
190 * backwards compatibility flags
192 bc_entry bc_list[] = {
193 { T_Bc_bugXXXX, 1 } /* default enabled */
197 * declare an int pointer for each flag for quick testing without
198 * walking bc_list. If the pointer is consumed by libntp rather
199 * than ntpd, declare it in a libntp source file pointing to storage
200 * initialized with the appropriate value for other libntp clients, and
201 * redirect it to point into bc_list during ntpd startup.
203 int *p_bcXXXX_enabled = &bc_list[0].enabled;
206 /* FUNCTION PROTOTYPES */
208 static void init_syntax_tree(config_tree *);
209 static void apply_enable_disable(attr_val_fifo *q, int enable);
212 static void free_auth_node(config_tree *);
213 static void free_all_config_trees(void);
215 static void free_config_access(config_tree *);
216 static void free_config_auth(config_tree *);
217 static void free_config_fudge(config_tree *);
218 static void free_config_logconfig(config_tree *);
219 static void free_config_monitor(config_tree *);
220 static void free_config_nic_rules(config_tree *);
221 static void free_config_other_modes(config_tree *);
222 static void free_config_peers(config_tree *);
223 static void free_config_phone(config_tree *);
224 static void free_config_reset_counters(config_tree *);
225 static void free_config_rlimit(config_tree *);
226 static void free_config_setvar(config_tree *);
227 static void free_config_system_opts(config_tree *);
228 static void free_config_tinker(config_tree *);
229 static void free_config_tos(config_tree *);
230 static void free_config_trap(config_tree *);
231 static void free_config_ttl(config_tree *);
232 static void free_config_unpeers(config_tree *);
233 static void free_config_vars(config_tree *);
236 static void free_config_sim(config_tree *);
238 static void destroy_address_fifo(address_fifo *);
239 #define FREE_ADDRESS_FIFO(pf) \
241 destroy_address_fifo(pf); \
244 void free_all_config_trees(void); /* atexit() */
245 static void free_config_tree(config_tree *ptree);
246 #endif /* FREE_CFG_T */
248 static void destroy_restrict_node(restrict_node *my_node);
249 static int is_sane_resolved_address(sockaddr_u *peeraddr, int hmode);
250 static void save_and_apply_config_tree(int/*BOOL*/ from_file);
251 static void destroy_int_fifo(int_fifo *);
252 #define FREE_INT_FIFO(pf) \
254 destroy_int_fifo(pf); \
257 static void destroy_string_fifo(string_fifo *);
258 #define FREE_STRING_FIFO(pf) \
260 destroy_string_fifo(pf); \
263 static void destroy_attr_val_fifo(attr_val_fifo *);
264 #define FREE_ATTR_VAL_FIFO(pf) \
266 destroy_attr_val_fifo(pf); \
269 static void destroy_filegen_fifo(filegen_fifo *);
270 #define FREE_FILEGEN_FIFO(pf) \
272 destroy_filegen_fifo(pf); \
275 static void destroy_restrict_fifo(restrict_fifo *);
276 #define FREE_RESTRICT_FIFO(pf) \
278 destroy_restrict_fifo(pf); \
281 static void destroy_setvar_fifo(setvar_fifo *);
282 #define FREE_SETVAR_FIFO(pf) \
284 destroy_setvar_fifo(pf); \
287 static void destroy_addr_opts_fifo(addr_opts_fifo *);
288 #define FREE_ADDR_OPTS_FIFO(pf) \
290 destroy_addr_opts_fifo(pf); \
294 static void config_logconfig(config_tree *);
295 static void config_monitor(config_tree *);
296 static void config_rlimit(config_tree *);
297 static void config_system_opts(config_tree *);
298 static void config_tinker(config_tree *);
299 static void config_tos(config_tree *);
300 static void config_vars(config_tree *);
303 static sockaddr_u *get_next_address(address_node *addr);
304 static void config_sim(config_tree *);
305 static void config_ntpdsim(config_tree *);
306 #else /* !SIM follows */
307 static void config_ntpd(config_tree *, int/*BOOL*/ input_from_file);
308 static void config_other_modes(config_tree *);
309 static void config_auth(config_tree *);
310 static void config_access(config_tree *);
311 static void config_mdnstries(config_tree *);
312 static void config_phone(config_tree *);
313 static void config_setvar(config_tree *);
314 static void config_ttl(config_tree *);
315 static void config_trap(config_tree *);
316 static void config_fudge(config_tree *);
317 static void config_peers(config_tree *);
318 static void config_unpeers(config_tree *);
319 static void config_nic_rules(config_tree *, int/*BOOL*/ input_from_file);
320 static void config_reset_counters(config_tree *);
321 static u_char get_correct_host_mode(int token);
322 static int peerflag_bits(peer_node *);
326 static void peer_name_resolved(int, int, void *, const char *, const char *,
327 const struct addrinfo *,
328 const struct addrinfo *);
329 static void unpeer_name_resolved(int, int, void *, const char *, const char *,
330 const struct addrinfo *,
331 const struct addrinfo *);
332 static void trap_name_resolved(int, int, void *, const char *, const char *,
333 const struct addrinfo *,
334 const struct addrinfo *);
339 t_REF, /* Refclock */
340 t_MSK /* Network Mask */
343 static void ntpd_set_tod_using(const char *);
344 static char * normal_dtoa(double);
345 static u_int32 get_pfxmatch(const char **, struct masks *);
346 static u_int32 get_match(const char *, struct masks *);
347 static u_int32 get_logmask(const char *);
349 static int getnetnum(const char *num, sockaddr_u *addr, int complain,
350 enum gnn_type a_type);
355 /* FUNCTIONS FOR INITIALIZATION
356 * ----------------------------
365 if (ptree->auth.keys) {
366 free(ptree->auth.keys);
367 ptree->auth.keys = NULL;
370 if (ptree->auth.keysdir) {
371 free(ptree->auth.keysdir);
372 ptree->auth.keysdir = NULL;
375 if (ptree->auth.ntp_signd_socket) {
376 free(ptree->auth.ntp_signd_socket);
377 ptree->auth.ntp_signd_socket = NULL;
389 ptree->mdnstries = 5;
395 free_all_config_trees(void)
400 ptree = cfg_tree_history;
402 while (ptree != NULL) {
404 free_config_tree(ptree);
415 #if defined(_MSC_VER) && defined (_DEBUG)
419 if (ptree->source.value.s != NULL)
420 free(ptree->source.value.s);
422 free_config_other_modes(ptree);
423 free_config_auth(ptree);
424 free_config_tos(ptree);
425 free_config_monitor(ptree);
426 free_config_access(ptree);
427 free_config_tinker(ptree);
428 free_config_rlimit(ptree);
429 free_config_system_opts(ptree);
430 free_config_logconfig(ptree);
431 free_config_phone(ptree);
432 free_config_setvar(ptree);
433 free_config_ttl(ptree);
434 free_config_trap(ptree);
435 free_config_fudge(ptree);
436 free_config_vars(ptree);
437 free_config_peers(ptree);
438 free_config_unpeers(ptree);
439 free_config_nic_rules(ptree);
440 free_config_reset_counters(ptree);
442 free_config_sim(ptree);
444 free_auth_node(ptree);
448 #if defined(_MSC_VER) && defined (_DEBUG)
452 #endif /* FREE_CFG_T */
458 dump_all_config_trees(
463 config_tree * cfg_ptr;
467 for (cfg_ptr = cfg_tree_history;
469 cfg_ptr = cfg_ptr->link)
470 return_value |= dump_config_tree(cfg_ptr, df, comment);
476 /* The config dumper */
485 unpeer_node *unpeern;
488 address_node *peer_addr;
489 address_node *fudge_addr;
490 filegen_node *fgen_node;
491 restrict_node *rest_node;
492 addr_opts_node *addr_opts;
493 setvar_node *setv_node;
494 nic_rule_node *rule_node;
497 int_node *counter_set;
498 string_node *str_node;
500 const char *s = NULL;
506 DPRINTF(1, ("dump_config_tree(%p)\n", ptree));
509 if (!strftime(timestamp, sizeof(timestamp),
511 localtime(&ptree->timestamp)))
514 fprintf(df, "# %s %s %s\n",
516 (CONF_SOURCE_NTPQ == ptree->source.attr)
517 ? "ntpq remote config from"
518 : "startup configuration file",
519 ptree->source.value.s);
522 /* For options I didn't find documentation I'll just output its name and the cor. value */
523 atrv = HEAD_PFIFO(ptree->vars);
524 for ( ; atrv != NULL; atrv = atrv->link) {
525 switch (atrv->type) {
528 fprintf(df, "\n# dump error:\n"
529 "# unknown vars type %d (%s) for %s\n",
530 atrv->type, token_name(atrv->type),
531 token_name(atrv->attr));
535 fprintf(df, "%s %s\n", keyword(atrv->attr),
536 normal_dtoa(atrv->value.d));
540 fprintf(df, "%s %d\n", keyword(atrv->attr),
545 fprintf(df, "%s \"%s\"", keyword(atrv->attr),
547 if (T_Driftfile == atrv->attr &&
548 atrv->link != NULL &&
549 T_WanderThreshold == atrv->link->attr) {
552 normal_dtoa(atrv->value.d));
560 atrv = HEAD_PFIFO(ptree->logconfig);
562 fprintf(df, "logconfig");
563 for ( ; atrv != NULL; atrv = atrv->link)
564 fprintf(df, " %c%s", atrv->attr, atrv->value.s);
568 if (ptree->stats_dir)
569 fprintf(df, "statsdir \"%s\"\n", ptree->stats_dir);
571 i_n = HEAD_PFIFO(ptree->stats_list);
573 fprintf(df, "statistics");
574 for ( ; i_n != NULL; i_n = i_n->link)
575 fprintf(df, " %s", keyword(i_n->i));
579 fgen_node = HEAD_PFIFO(ptree->filegen_opts);
580 for ( ; fgen_node != NULL; fgen_node = fgen_node->link) {
581 atrv = HEAD_PFIFO(fgen_node->options);
583 fprintf(df, "filegen %s",
584 keyword(fgen_node->filegen_token));
585 for ( ; atrv != NULL; atrv = atrv->link) {
586 switch (atrv->attr) {
589 fprintf(df, "\n# dump error:\n"
590 "# unknown filegen option token %s\n"
592 token_name(atrv->attr),
593 keyword(fgen_node->filegen_token));
597 fprintf(df, " file %s",
602 fprintf(df, " type %s",
603 keyword(atrv->value.i));
608 keyword(atrv->value.i));
616 atrv = HEAD_PFIFO(ptree->auth.crypto_cmd_list);
618 fprintf(df, "crypto");
619 for ( ; atrv != NULL; atrv = atrv->link) {
620 fprintf(df, " %s %s", keyword(atrv->attr),
626 if (ptree->auth.revoke != 0)
627 fprintf(df, "revoke %d\n", ptree->auth.revoke);
629 if (ptree->auth.keysdir != NULL)
630 fprintf(df, "keysdir \"%s\"\n", ptree->auth.keysdir);
632 if (ptree->auth.keys != NULL)
633 fprintf(df, "keys \"%s\"\n", ptree->auth.keys);
635 atrv = HEAD_PFIFO(ptree->auth.trusted_key_list);
637 fprintf(df, "trustedkey");
638 for ( ; atrv != NULL; atrv = atrv->link) {
639 if (T_Integer == atrv->type)
640 fprintf(df, " %d", atrv->value.i);
641 else if (T_Intrange == atrv->type)
642 fprintf(df, " (%d ... %d)",
647 fprintf(df, "\n# dump error:\n"
648 "# unknown trustedkey attr type %d\n"
649 "trustedkey", atrv->type);
655 if (ptree->auth.control_key)
656 fprintf(df, "controlkey %d\n", ptree->auth.control_key);
658 if (ptree->auth.request_key)
659 fprintf(df, "requestkey %d\n", ptree->auth.request_key);
661 /* dump enable list, then disable list */
662 for (enable = 1; enable >= 0; enable--) {
664 ? HEAD_PFIFO(ptree->enable_opts)
665 : HEAD_PFIFO(ptree->disable_opts);
667 fprintf(df, "%s", (enable)
670 for ( ; atrv != NULL; atrv = atrv->link)
672 keyword(atrv->value.i));
677 atrv = HEAD_PFIFO(ptree->orphan_cmds);
680 for ( ; atrv != NULL; atrv = atrv->link) {
681 switch (atrv->type) {
684 fprintf(df, "\n# dump error:\n"
685 "# unknown tos attr type %d %s\n"
687 token_name(atrv->type));
691 fprintf(df, " %s %s",
693 normal_dtoa(atrv->value.d));
700 atrv = HEAD_PFIFO(ptree->rlimit);
702 fprintf(df, "rlimit");
703 for ( ; atrv != NULL; atrv = atrv->link) {
704 INSIST(T_Integer == atrv->type);
705 fprintf(df, " %s %d", keyword(atrv->attr),
711 atrv = HEAD_PFIFO(ptree->tinker);
713 fprintf(df, "tinker");
714 for ( ; atrv != NULL; atrv = atrv->link) {
715 INSIST(T_Double == atrv->type);
716 fprintf(df, " %s %s", keyword(atrv->attr),
717 normal_dtoa(atrv->value.d));
722 if (ptree->broadcastclient)
723 fprintf(df, "broadcastclient\n");
725 peern = HEAD_PFIFO(ptree->peers);
726 for ( ; peern != NULL; peern = peern->link) {
728 fprintf(df, "%s", keyword(peern->host_mode));
729 switch (addr->type) {
732 fprintf(df, "# dump error:\n"
733 "# unknown peer family %d for:\n"
735 keyword(peern->host_mode));
749 fprintf(df, " %s", addr->address);
751 if (peern->minpoll != 0)
752 fprintf(df, " minpoll %u", peern->minpoll);
754 if (peern->maxpoll != 0)
755 fprintf(df, " maxpoll %u", peern->maxpoll);
757 if (peern->ttl != 0) {
758 if (strlen(addr->address) > 8
759 && !memcmp(addr->address, "127.127.", 8))
760 fprintf(df, " mode %u", peern->ttl);
762 fprintf(df, " ttl %u", peern->ttl);
765 if (peern->peerversion != NTP_VERSION)
766 fprintf(df, " version %u", peern->peerversion);
768 if (peern->peerkey != 0)
769 fprintf(df, " key %u", peern->peerkey);
771 if (peern->group != NULL)
772 fprintf(df, " ident \"%s\"", peern->group);
774 atrv = HEAD_PFIFO(peern->peerflags);
775 for ( ; atrv != NULL; atrv = atrv->link) {
776 INSIST(T_Flag == atrv->attr);
777 INSIST(T_Integer == atrv->type);
778 fprintf(df, " %s", keyword(atrv->value.i));
783 addr_opts = HEAD_PFIFO(ptree->fudge);
784 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) {
785 peer_addr = peern->addr;
786 fudge_addr = addr_opts->addr;
788 s1 = peer_addr->address;
789 s2 = fudge_addr->address;
794 fprintf(df, "fudge %s", s1);
796 for (atrv = HEAD_PFIFO(addr_opts->options);
800 switch (atrv->type) {
803 fprintf(df, "\n# dump error:\n"
804 "# unknown fudge atrv->type %d\n"
805 "fudge %s", atrv->type,
810 fprintf(df, " %s %s",
812 normal_dtoa(atrv->value.d));
816 fprintf(df, " %s %d",
822 fprintf(df, " %s %s",
832 addr = HEAD_PFIFO(ptree->manycastserver);
834 fprintf(df, "manycastserver");
835 for ( ; addr != NULL; addr = addr->link)
836 fprintf(df, " %s", addr->address);
840 addr = HEAD_PFIFO(ptree->multicastclient);
842 fprintf(df, "multicastclient");
843 for ( ; addr != NULL; addr = addr->link)
844 fprintf(df, " %s", addr->address);
849 for (unpeern = HEAD_PFIFO(ptree->unpeers);
851 unpeern = unpeern->link)
852 fprintf(df, "unpeer %s\n", unpeern->addr->address);
854 atrv = HEAD_PFIFO(ptree->mru_opts);
857 for ( ; atrv != NULL; atrv = atrv->link)
858 fprintf(df, " %s %d", keyword(atrv->attr),
863 atrv = HEAD_PFIFO(ptree->discard_opts);
865 fprintf(df, "discard");
866 for ( ; atrv != NULL; atrv = atrv->link)
867 fprintf(df, " %s %d", keyword(atrv->attr),
873 for (rest_node = HEAD_PFIFO(ptree->restrict_opts);
875 rest_node = rest_node->link) {
877 if (NULL == rest_node->addr) {
879 flags = HEAD_PFIFO(rest_node->flags);
880 for ( ; flags != NULL; flags = flags->link)
881 if (T_Source == flags->i) {
886 s = rest_node->addr->address;
888 fprintf(df, "restrict %s", s);
889 if (rest_node->mask != NULL)
890 fprintf(df, " mask %s",
891 rest_node->mask->address);
892 flags = HEAD_PFIFO(rest_node->flags);
893 for ( ; flags != NULL; flags = flags->link)
894 if (T_Source != flags->i)
895 fprintf(df, " %s", keyword(flags->i));
899 rule_node = HEAD_PFIFO(ptree->nic_rules);
900 for ( ; rule_node != NULL; rule_node = rule_node->link) {
901 fprintf(df, "interface %s %s\n",
902 keyword(rule_node->action),
903 (rule_node->match_class)
904 ? keyword(rule_node->match_class)
905 : rule_node->if_name);
908 str_node = HEAD_PFIFO(ptree->phone);
909 if (str_node != NULL) {
910 fprintf(df, "phone");
911 for ( ; str_node != NULL; str_node = str_node->link)
912 fprintf(df, " \"%s\"", str_node->s);
916 setv_node = HEAD_PFIFO(ptree->setvar);
917 for ( ; setv_node != NULL; setv_node = setv_node->link) {
918 s1 = quote_if_needed(setv_node->var);
919 s2 = quote_if_needed(setv_node->val);
920 fprintf(df, "setvar %s = %s", s1, s2);
923 if (setv_node->isdefault)
924 fprintf(df, " default");
928 i_n = HEAD_PFIFO(ptree->ttl);
931 for( ; i_n != NULL; i_n = i_n->link)
932 fprintf(df, " %d", i_n->i);
936 addr_opts = HEAD_PFIFO(ptree->trap);
937 for ( ; addr_opts != NULL; addr_opts = addr_opts->link) {
938 addr = addr_opts->addr;
939 fprintf(df, "trap %s", addr->address);
940 atrv = HEAD_PFIFO(addr_opts->options);
941 for ( ; atrv != NULL; atrv = atrv->link) {
942 switch (atrv->attr) {
945 fprintf(df, "\n# dump error:\n"
946 "# unknown trap token %d\n"
947 "trap %s", atrv->attr,
952 fprintf(df, " port %d", atrv->value.i);
956 fprintf(df, " interface %s",
964 counter_set = HEAD_PFIFO(ptree->reset_counters);
965 if (counter_set != NULL) {
966 fprintf(df, "reset");
967 for ( ; counter_set != NULL;
968 counter_set = counter_set->link)
969 fprintf(df, " %s", keyword(counter_set->i));
975 #endif /* SAVECONFIG */
979 /* generic fifo routines for structs linked by 1st member */
992 pf = emalloc_zero(sizeof(*pf));
994 CHECK_FIFO_CONSISTENCY(*pf);
996 LINK_FIFO(*pf, pe, link);
997 CHECK_FIFO_CONSISTENCY(*pf);
1019 CONCAT_FIFO(*pf1, *pf2, link);
1026 /* FUNCTIONS FOR CREATING NODES ON THE SYNTAX TREE
1027 * -----------------------------------------------
1038 my_val = emalloc_zero(sizeof(*my_val));
1039 my_val->attr = attr;
1040 my_val->value.d = value;
1041 my_val->type = T_Double;
1055 my_val = emalloc_zero(sizeof(*my_val));
1056 my_val->attr = attr;
1057 my_val->value.i = value;
1058 my_val->type = T_Integer;
1072 my_val = emalloc_zero(sizeof(*my_val));
1073 my_val->attr = attr;
1074 my_val->value.u = value;
1075 my_val->type = T_U_int;
1082 create_attr_rangeval(
1090 my_val = emalloc_zero(sizeof(*my_val));
1091 my_val->attr = attr;
1092 my_val->value.r.first = first;
1093 my_val->value.r.last = last;
1094 my_val->type = T_Intrange;
1108 my_val = emalloc_zero(sizeof(*my_val));
1109 my_val->attr = attr;
1110 if (NULL == s) /* free() hates NULL */
1112 my_val->value.s = _UC(s);
1113 my_val->type = T_String;
1126 i_n = emalloc_zero(sizeof(*i_n));
1140 sn = emalloc_zero(sizeof(*sn));
1148 create_address_node(
1153 address_node *my_node;
1155 NTP_REQUIRE(NULL != addr);
1156 NTP_REQUIRE(AF_INET == type ||
1157 AF_INET6 == type || AF_UNSPEC == type);
1158 my_node = emalloc_zero(sizeof(*my_node));
1159 my_node->address = addr;
1160 my_node->type = (u_short)type;
1167 destroy_address_node(
1168 address_node *my_node
1171 if (NULL == my_node)
1173 NTP_REQUIRE(NULL != my_node->address);
1175 free(my_node->address);
1183 address_node * addr,
1184 attr_val_fifo * options
1192 my_node = emalloc_zero(sizeof(*my_node));
1194 /* Initialize node values to default */
1195 my_node->peerversion = NTP_VERSION;
1197 /* Now set the node to the read values */
1198 my_node->host_mode = hmode;
1199 my_node->addr = addr;
1202 * the options FIFO mixes items that will be saved in the
1203 * peer_node as explicit members, such as minpoll, and
1204 * those that are moved intact to the peer_node's peerflags
1205 * FIFO. The options FIFO is consumed and reclaimed here.
1208 if (options != NULL)
1209 CHECK_FIFO_CONSISTENCY(*options);
1210 while (options != NULL) {
1211 UNLINK_FIFO(option, *options, link);
1212 if (NULL == option) {
1218 /* Check the kind of option being set */
1219 switch (option->attr) {
1222 APPEND_G_FIFO(my_node->peerflags, option);
1227 if (option->value.i < NTP_MINPOLL ||
1228 option->value.i > UCHAR_MAX) {
1230 "minpoll: provided value (%d) is out of range [%d-%d])",
1231 option->value.i, NTP_MINPOLL,
1233 my_node->minpoll = NTP_MINPOLL;
1236 (u_char)option->value.u;
1241 if (option->value.i < 0 ||
1242 option->value.i > NTP_MAXPOLL) {
1244 "maxpoll: provided value (%d) is out of range [0-%d])",
1245 option->value.i, NTP_MAXPOLL);
1246 my_node->maxpoll = NTP_MAXPOLL;
1249 (u_char)option->value.u;
1254 if (option->value.u >= MAX_TTL) {
1255 msyslog(LOG_ERR, "ttl: invalid argument");
1258 my_node->ttl = (u_char)option->value.u;
1263 my_node->ttl = option->value.u;
1267 if (option->value.u >= KEYID_T_MAX) {
1268 msyslog(LOG_ERR, "key: invalid argument");
1272 (keyid_t)option->value.u;
1277 if (option->value.u >= UCHAR_MAX) {
1278 msyslog(LOG_ERR, "version: invalid argument");
1281 my_node->peerversion =
1282 (u_char)option->value.u;
1287 my_node->group = option->value.s;
1292 "Unknown peer/server option token %s",
1293 token_name(option->attr));
1300 /* Check if errors were reported. If yes, ignore the node */
1315 unpeer_node * my_node;
1319 my_node = emalloc_zero(sizeof(*my_node));
1322 * From the parser's perspective an association ID fits into
1323 * its generic T_String definition of a name/address "address".
1324 * We treat all valid 16-bit numbers as association IDs.
1326 pch = addr->address;
1327 while (*pch && isdigit((unsigned char)*pch))
1331 && 1 == sscanf(addr->address, "%u", &u)
1332 && u <= ASSOCID_MAX) {
1333 my_node->assocID = (associd_t)u;
1334 destroy_address_node(addr);
1335 my_node->addr = NULL;
1337 my_node->assocID = 0;
1338 my_node->addr = addr;
1345 create_filegen_node(
1347 attr_val_fifo * options
1350 filegen_node *my_node;
1352 my_node = emalloc_zero(sizeof(*my_node));
1353 my_node->filegen_token = filegen_token;
1354 my_node->options = options;
1361 create_restrict_node(
1362 address_node * addr,
1363 address_node * mask,
1368 restrict_node *my_node;
1370 my_node = emalloc_zero(sizeof(*my_node));
1371 my_node->addr = addr;
1372 my_node->mask = mask;
1373 my_node->flags = flags;
1374 my_node->line_no = line_no;
1381 destroy_restrict_node(
1382 restrict_node *my_node
1385 /* With great care, free all the memory occupied by
1388 destroy_address_node(my_node->addr);
1389 destroy_address_node(my_node->mask);
1390 destroy_int_fifo(my_node->flags);
1404 UNLINK_FIFO(i_n, *fifo, link);
1415 destroy_string_fifo(
1423 UNLINK_FIFO(sn, *fifo, link);
1435 destroy_attr_val_fifo(
1436 attr_val_fifo * av_fifo
1441 if (av_fifo != NULL) {
1443 UNLINK_FIFO(av, *av_fifo, link);
1446 if (T_String == av->type)
1456 destroy_filegen_fifo(
1464 UNLINK_FIFO(fg, *fifo, link);
1467 destroy_attr_val_fifo(fg->options);
1476 destroy_restrict_fifo(
1477 restrict_fifo * fifo
1484 UNLINK_FIFO(rn, *fifo, link);
1487 destroy_restrict_node(rn);
1495 destroy_setvar_fifo(
1503 UNLINK_FIFO(sv, *fifo, link);
1516 destroy_addr_opts_fifo(
1517 addr_opts_fifo * fifo
1520 addr_opts_node * aon;
1524 UNLINK_FIFO(aon, *fifo, link);
1527 destroy_address_node(aon->addr);
1528 destroy_attr_val_fifo(aon->options);
1543 setvar_node * my_node;
1546 /* do not allow = in the variable name */
1547 pch = strchr(var, '=');
1551 /* Now store the string into a setvar_node */
1552 my_node = emalloc_zero(sizeof(*my_node));
1555 my_node->isdefault = isdefault;
1562 create_nic_rule_node(
1564 char *if_name, /* interface name or numeric address */
1568 nic_rule_node *my_node;
1570 NTP_REQUIRE(match_class != 0 || if_name != NULL);
1572 my_node = emalloc_zero(sizeof(*my_node));
1573 my_node->match_class = match_class;
1574 my_node->if_name = if_name;
1575 my_node->action = action;
1582 create_addr_opts_node(
1583 address_node * addr,
1584 attr_val_fifo * options
1587 addr_opts_node *my_node;
1589 my_node = emalloc_zero(sizeof(*my_node));
1590 my_node->addr = addr;
1591 my_node->options = options;
1599 create_sim_script_info(
1601 attr_val_fifo * script_queue
1604 script_info *my_info;
1605 attr_val *my_attr_val;
1607 my_info = emalloc_zero(sizeof(*my_info));
1609 /* Initialize Script Info with default values*/
1610 my_info->duration = duration;
1611 my_info->prop_delay = NET_DLY;
1612 my_info->proc_delay = PROC_DLY;
1614 /* Traverse the script_queue and fill out non-default values */
1616 for (my_attr_val = HEAD_PFIFO(script_queue);
1617 my_attr_val != NULL;
1618 my_attr_val = my_attr_val->link) {
1620 /* Set the desired value */
1621 switch (my_attr_val->attr) {
1624 my_info->freq_offset = my_attr_val->value.d;
1628 my_info->wander = my_attr_val->value.d;
1632 my_info->jitter = my_attr_val->value.d;
1636 my_info->prop_delay = my_attr_val->value.d;
1640 my_info->proc_delay = my_attr_val->value.d;
1644 msyslog(LOG_ERR, "Unknown script token %d",
1660 const char addr_prefix[] = "192.168.0.";
1661 static int curr_addr_num = 1;
1662 #define ADDR_LENGTH 16 + 1 /* room for 192.168.1.255 */
1663 char addr_string[ADDR_LENGTH];
1664 sockaddr_u *final_addr;
1665 struct addrinfo *ptr;
1668 final_addr = emalloc(sizeof(*final_addr));
1670 if (addr->type == T_String) {
1671 snprintf(addr_string, sizeof(addr_string), "%s%d",
1672 addr_prefix, curr_addr_num++);
1673 printf("Selecting ip address %s for hostname %s\n",
1674 addr_string, addr->address);
1675 gai_err = getaddrinfo(addr_string, "ntp", NULL, &ptr);
1677 gai_err = getaddrinfo(addr->address, "ntp", NULL, &ptr);
1681 fprintf(stderr, "ERROR!! Could not get a new address\n");
1684 memcpy(final_addr, ptr->ai_addr, ptr->ai_addrlen);
1685 fprintf(stderr, "Successful in setting ip address of simulated server to: %s\n",
1697 address_node * addr,
1698 double server_offset,
1699 script_info_fifo * script
1702 server_info *my_info;
1704 my_info = emalloc_zero(sizeof(*my_info));
1705 my_info->server_time = server_offset;
1706 my_info->addr = get_next_address(addr);
1707 my_info->script = script;
1708 UNLINK_FIFO(my_info->curr_script, *my_info->script, link);
1716 attr_val_fifo * init_opts,
1717 server_info_fifo * servers
1722 my_node = emalloc(sizeof(*my_node));
1723 my_node->init_opts = init_opts;
1724 my_node->servers = servers;
1732 /* FUNCTIONS FOR PERFORMING THE CONFIGURATION
1733 * ------------------------------------------
1742 sockaddr_u addr_sock;
1743 address_node * addr_node;
1745 if (ptree->broadcastclient)
1746 proto_config(PROTO_BROADCLIENT, ptree->broadcastclient,
1749 addr_node = HEAD_PFIFO(ptree->manycastserver);
1750 while (addr_node != NULL) {
1751 ZERO_SOCK(&addr_sock);
1752 AF(&addr_sock) = addr_node->type;
1753 if (1 == getnetnum(addr_node->address, &addr_sock, 1,
1755 proto_config(PROTO_MULTICAST_ADD,
1757 sys_manycastserver = 1;
1759 addr_node = addr_node->link;
1762 /* Configure the multicast clients */
1763 addr_node = HEAD_PFIFO(ptree->multicastclient);
1764 if (addr_node != NULL) {
1766 ZERO_SOCK(&addr_sock);
1767 AF(&addr_sock) = addr_node->type;
1768 if (1 == getnetnum(addr_node->address,
1769 &addr_sock, 1, t_UNK)) {
1770 proto_config(PROTO_MULTICAST_ADD, 0, 0.,
1773 addr_node = addr_node->link;
1774 } while (addr_node != NULL);
1775 proto_config(PROTO_MULTICAST_ADD, 1, 0., NULL);
1783 destroy_address_fifo(
1784 address_fifo * pfifo
1787 address_node * addr_node;
1789 if (pfifo != NULL) {
1791 UNLINK_FIFO(addr_node, *pfifo, link);
1792 if (addr_node == NULL)
1794 destroy_address_node(addr_node);
1802 free_config_other_modes(
1806 FREE_ADDRESS_FIFO(ptree->manycastserver);
1807 FREE_ADDRESS_FIFO(ptree->multicastclient);
1809 #endif /* FREE_CFG_T */
1827 /* Crypto Command */
1829 item = -1; /* quiet warning */
1830 my_val = HEAD_PFIFO(ptree->auth.crypto_cmd_list);
1831 for (; my_val != NULL; my_val = my_val->link) {
1832 switch (my_val->attr) {
1839 item = CRYPTO_CONF_PRIV;
1843 item = CRYPTO_CONF_IDENT;
1847 item = CRYPTO_CONF_PW;
1851 item = CRYPTO_CONF_RAND;
1855 item = CRYPTO_CONF_NID;
1858 crypto_config(item, my_val->value.s);
1860 #endif /* AUTOKEY */
1862 /* Keysdir Command */
1863 if (ptree->auth.keysdir) {
1864 if (keysdir != default_keysdir)
1866 keysdir = estrdup(ptree->auth.keysdir);
1870 /* ntp_signd_socket Command */
1871 if (ptree->auth.ntp_signd_socket) {
1872 if (ntp_signd_socket != default_ntp_signd_socket)
1873 free(ntp_signd_socket);
1874 ntp_signd_socket = estrdup(ptree->auth.ntp_signd_socket);
1878 if (ptree->auth.cryptosw && !cryptosw) {
1882 #endif /* AUTOKEY */
1885 * Count the number of trusted keys to preallocate storage and
1886 * size the hash table.
1889 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
1890 for (; my_val != NULL; my_val = my_val->link) {
1891 if (T_Integer == my_val->type) {
1892 first = my_val->value.i;
1893 if (first > 1 && first <= NTP_MAXKEY)
1896 REQUIRE(T_Intrange == my_val->type);
1897 first = my_val->value.r.first;
1898 last = my_val->value.r.last;
1899 if (!(first > last || first < 1 ||
1900 last > NTP_MAXKEY)) {
1901 count += 1 + last - first;
1905 auth_prealloc_symkeys(count);
1908 if (ptree->auth.keys)
1909 getauthkeys(ptree->auth.keys);
1911 /* Control Key Command */
1912 if (ptree->auth.control_key)
1913 ctl_auth_keyid = (keyid_t)ptree->auth.control_key;
1915 /* Requested Key Command */
1916 if (ptree->auth.request_key) {
1917 DPRINTF(4, ("set info_auth_keyid to %08lx\n",
1918 (u_long) ptree->auth.request_key));
1919 info_auth_keyid = (keyid_t)ptree->auth.request_key;
1922 /* Trusted Key Command */
1923 my_val = HEAD_PFIFO(ptree->auth.trusted_key_list);
1924 for (; my_val != NULL; my_val = my_val->link) {
1925 if (T_Integer == my_val->type) {
1926 first = my_val->value.i;
1927 if (first >= 1 && first <= NTP_MAXKEY) {
1928 authtrust(first, TRUE);
1931 "Ignoring invalid trustedkey %d, min 1 max %d.",
1935 first = my_val->value.r.first;
1936 last = my_val->value.r.last;
1937 if (first > last || first < 1 ||
1938 last > NTP_MAXKEY) {
1940 "Ignoring invalid trustedkey range %d ... %d, min 1 max %d.",
1941 first, last, NTP_MAXKEY);
1943 for (i = first; i <= last; i++) {
1951 /* crypto revoke command */
1952 if (ptree->auth.revoke)
1953 sys_revoke = 1UL << ptree->auth.revoke;
1954 #endif /* AUTOKEY */
1965 destroy_attr_val_fifo(ptree->auth.crypto_cmd_list);
1966 ptree->auth.crypto_cmd_list = NULL;
1967 destroy_attr_val_fifo(ptree->auth.trusted_key_list);
1968 ptree->auth.trusted_key_list = NULL;
1970 #endif /* FREE_CFG_T */
1982 item = -1; /* quiet warning */
1983 tos = HEAD_PFIFO(ptree->orphan_cmds);
1984 for (; tos != NULL; tos = tos->link) {
1993 if (val > STRATUM_UNSPEC - 1) {
1994 msyslog(LOG_WARNING,
1995 "Using maximum tos ceiling %d, %g requested",
1996 STRATUM_UNSPEC - 1, val);
1997 val = STRATUM_UNSPEC - 1;
1999 item = PROTO_CEILING;
2007 item = PROTO_COHORT;
2011 item = PROTO_ORPHAN;
2015 item = PROTO_ORPHWAIT;
2019 item = PROTO_MINDISP;
2023 item = PROTO_MAXDIST;
2027 item = PROTO_MINCLOCK;
2031 item = PROTO_MAXCLOCK;
2035 item = PROTO_MINSANE;
2039 item = PROTO_BEACON;
2042 proto_config(item, 0, val, NULL);
2053 FREE_ATTR_VAL_FIFO(ptree->orphan_cmds);
2055 #endif /* FREE_CFG_T */
2063 int_node *pfilegen_token;
2064 const char *filegen_string;
2065 const char *filegen_file;
2067 filegen_node *my_node;
2072 /* Set the statistics directory */
2073 if (ptree->stats_dir)
2074 stats_config(STATS_STATSDIR, ptree->stats_dir);
2077 * Calling filegen_get is brain dead. Doing a string
2078 * comparison to find the relavant filegen structure is
2081 * Through the parser, we already know which filegen is
2082 * being specified. Hence, we should either store a
2083 * pointer to the specified structure in the syntax tree
2084 * or an index into a filegen array.
2086 * Need to change the filegen code to reflect the above.
2089 /* Turn on the specified statistics */
2090 pfilegen_token = HEAD_PFIFO(ptree->stats_list);
2091 for (; pfilegen_token != NULL; pfilegen_token = pfilegen_token->link) {
2092 filegen_string = keyword(pfilegen_token->i);
2093 filegen = filegen_get(filegen_string);
2094 if (NULL == filegen) {
2096 "stats %s unrecognized",
2100 DPRINTF(4, ("enabling filegen for %s statistics '%s%s'\n",
2101 filegen_string, filegen->dir,
2103 filegen_flag = filegen->flag;
2104 filegen_flag |= FGEN_FLAG_ENABLED;
2105 filegen_config(filegen, statsdir, filegen_string,
2106 filegen->type, filegen_flag);
2109 /* Configure the statistics with the options */
2110 my_node = HEAD_PFIFO(ptree->filegen_opts);
2111 for (; my_node != NULL; my_node = my_node->link) {
2112 filegen_string = keyword(my_node->filegen_token);
2113 filegen = filegen_get(filegen_string);
2114 if (NULL == filegen) {
2116 "filegen category '%s' unrecognized",
2120 filegen_file = filegen_string;
2122 /* Initialize the filegen variables to their pre-configuration states */
2123 filegen_flag = filegen->flag;
2124 filegen_type = filegen->type;
2126 /* "filegen ... enabled" is the default (when filegen is used) */
2127 filegen_flag |= FGEN_FLAG_ENABLED;
2129 my_opts = HEAD_PFIFO(my_node->options);
2130 for (; my_opts != NULL; my_opts = my_opts->link) {
2131 switch (my_opts->attr) {
2134 filegen_file = my_opts->value.s;
2138 switch (my_opts->value.i) {
2145 filegen_type = FILEGEN_NONE;
2149 filegen_type = FILEGEN_PID;
2153 filegen_type = FILEGEN_DAY;
2157 filegen_type = FILEGEN_WEEK;
2161 filegen_type = FILEGEN_MONTH;
2165 filegen_type = FILEGEN_YEAR;
2169 filegen_type = FILEGEN_AGE;
2175 switch (my_opts->value.i) {
2178 filegen_flag |= FGEN_FLAG_LINK;
2182 filegen_flag &= ~FGEN_FLAG_LINK;
2186 filegen_flag |= FGEN_FLAG_ENABLED;
2190 filegen_flag &= ~FGEN_FLAG_ENABLED;
2195 "Unknown filegen flag token %d",
2203 "Unknown filegen option token %d",
2208 filegen_config(filegen, statsdir, filegen_file,
2209 filegen_type, filegen_flag);
2216 free_config_monitor(
2220 if (ptree->stats_dir) {
2221 free(ptree->stats_dir);
2222 ptree->stats_dir = NULL;
2225 FREE_INT_FIFO(ptree->stats_list);
2226 FREE_FILEGEN_FIFO(ptree->filegen_opts);
2228 #endif /* FREE_CFG_T */
2237 static int warned_signd;
2239 restrict_node * my_node;
2240 int_node * curr_flag;
2243 struct addrinfo hints;
2244 struct addrinfo * ai_list;
2245 struct addrinfo * pai;
2247 int restrict_default;
2251 const char * signd_warning =
2252 #ifdef HAVE_NTP_SIGND
2253 "MS-SNTP signd operations currently block ntpd degrading service to all clients.";
2255 "mssntp restrict bit ignored, this ntpd was configured without --enable-ntp-signd.";
2258 /* Configure the mru options */
2259 my_opt = HEAD_PFIFO(ptree->mru_opts);
2260 for (; my_opt != NULL; my_opt = my_opt->link) {
2264 switch (my_opt->attr) {
2267 if (0 <= my_opt->value.i)
2268 mru_incalloc = my_opt->value.u;
2274 if (0 <= my_opt->value.i)
2275 mru_incalloc = (my_opt->value.u * 1024U)
2276 / sizeof(mon_entry);
2282 if (0 <= my_opt->value.i)
2283 mru_initalloc = my_opt->value.u;
2289 if (0 <= my_opt->value.i)
2290 mru_initalloc = (my_opt->value.u * 1024U)
2291 / sizeof(mon_entry);
2297 if (0 <= my_opt->value.i)
2298 mru_mindepth = my_opt->value.u;
2304 mru_maxage = my_opt->value.i;
2308 if (0 <= my_opt->value.i)
2309 mru_maxdepth = my_opt->value.u;
2311 mru_maxdepth = UINT_MAX;
2315 if (0 <= my_opt->value.i)
2316 mru_maxdepth = (my_opt->value.u * 1024U) /
2319 mru_maxdepth = UINT_MAX;
2324 "Unknown mru option %s (%d)",
2325 keyword(my_opt->attr), my_opt->attr);
2330 "mru %s %d out of range, ignored.",
2331 keyword(my_opt->attr), my_opt->value.i);
2334 /* Configure the discard options */
2335 my_opt = HEAD_PFIFO(ptree->discard_opts);
2336 for (; my_opt != NULL; my_opt = my_opt->link) {
2338 switch (my_opt->attr) {
2341 if (0 <= my_opt->value.i &&
2342 my_opt->value.i <= UCHAR_MAX)
2343 ntp_minpoll = (u_char)my_opt->value.u;
2346 "discard average %d out of range, ignored.",
2351 ntp_minpkt = my_opt->value.i;
2355 mon_age = my_opt->value.i;
2360 "Unknown discard option %s (%d)",
2361 keyword(my_opt->attr), my_opt->attr);
2366 /* Configure the restrict options */
2367 my_node = HEAD_PFIFO(ptree->restrict_opts);
2368 for (; my_node != NULL; my_node = my_node->link) {
2369 /* Parse the flags */
2373 curr_flag = HEAD_PFIFO(my_node->flags);
2374 for (; curr_flag != NULL; curr_flag = curr_flag->link) {
2375 switch (curr_flag->i) {
2382 mflags |= RESM_NTPONLY;
2386 mflags |= RESM_SOURCE;
2394 flags |= RES_IGNORE;
2402 flags |= RES_MSSNTP;
2406 flags |= RES_LIMITED;
2410 flags |= RES_LPTRAP;
2414 flags |= RES_NOMODIFY;
2418 flags |= RES_NOMRULIST;
2422 flags |= RES_NOPEER;
2426 flags |= RES_NOQUERY;
2430 flags |= RES_DONTSERVE;
2434 flags |= RES_NOTRAP;
2438 flags |= RES_DONTTRUST;
2442 flags |= RES_VERSION;
2447 if ((RES_MSSNTP & flags) && !warned_signd) {
2449 fprintf(stderr, "%s\n", signd_warning);
2450 msyslog(LOG_WARNING, "%s", signd_warning);
2453 /* It would be swell if we could identify the line number */
2454 if ((RES_KOD & flags) && !(RES_LIMITED & flags)) {
2455 const char *kod_where = (my_node->addr)
2456 ? my_node->addr->address
2457 : (mflags & RESM_SOURCE)
2460 const char *kod_warn = "KOD does nothing without LIMITED.";
2462 fprintf(stderr, "restrict %s: %s\n", kod_where, kod_warn);
2463 msyslog(LOG_WARNING, "restrict %s: %s", kod_where, kod_warn);
2469 restrict_default = 0;
2471 if (NULL == my_node->addr) {
2473 if (!(RESM_SOURCE & mflags)) {
2475 * The user specified a default rule
2476 * without a -4 / -6 qualifier, add to
2479 restrict_default = 1;
2481 /* apply "restrict source ..." */
2482 DPRINTF(1, ("restrict source template mflags %x flags %x\n",
2484 hack_restrict(RESTRICT_FLAGS, NULL,
2485 NULL, mflags, flags, 0);
2489 /* Resolve the specified address */
2490 AF(&addr) = (u_short)my_node->addr->type;
2492 if (getnetnum(my_node->addr->address,
2493 &addr, 1, t_UNK) != 1) {
2495 * Attempt a blocking lookup. This
2496 * is in violation of the nonblocking
2497 * design of ntpd's mainline code. The
2498 * alternative of running without the
2499 * restriction until the name resolved
2501 * Ideally some scheme could be used for
2502 * restrict directives in the startup
2503 * ntp.conf to delay starting up the
2504 * protocol machinery until after all
2505 * restrict hosts have been resolved.
2509 hints.ai_protocol = IPPROTO_UDP;
2510 hints.ai_socktype = SOCK_DGRAM;
2511 hints.ai_family = my_node->addr->type;
2512 rc = getaddrinfo(my_node->addr->address,
2517 "restrict: ignoring line %d, address/host '%s' unusable.",
2519 my_node->addr->address);
2522 INSIST(ai_list != NULL);
2524 INSIST(pai->ai_addr != NULL);
2525 INSIST(sizeof(addr) >=
2527 memcpy(&addr, pai->ai_addr,
2529 INSIST(AF_INET == AF(&addr) ||
2530 AF_INET6 == AF(&addr));
2533 SET_HOSTMASK(&mask, AF(&addr));
2535 /* Resolve the mask */
2536 if (my_node->mask) {
2538 AF(&mask) = my_node->mask->type;
2539 if (getnetnum(my_node->mask->address,
2540 &mask, 1, t_MSK) != 1) {
2542 "restrict: ignoring line %d, mask '%s' unusable.",
2544 my_node->mask->address);
2551 if (restrict_default) {
2552 AF(&addr) = AF_INET;
2553 AF(&mask) = AF_INET;
2554 hack_restrict(RESTRICT_FLAGS, &addr,
2555 &mask, mflags, flags, 0);
2556 AF(&addr) = AF_INET6;
2557 AF(&mask) = AF_INET6;
2561 hack_restrict(RESTRICT_FLAGS, &addr,
2562 &mask, mflags, flags, 0);
2564 NULL != (pai = pai->ai_next)) {
2565 INSIST(pai->ai_addr != NULL);
2566 INSIST(sizeof(addr) >=
2569 memcpy(&addr, pai->ai_addr,
2571 INSIST(AF_INET == AF(&addr) ||
2572 AF_INET6 == AF(&addr));
2573 SET_HOSTMASK(&mask, AF(&addr));
2575 } while (pai != NULL);
2577 if (ai_list != NULL)
2578 freeaddrinfo(ai_list);
2590 FREE_ATTR_VAL_FIFO(ptree->mru_opts);
2591 FREE_ATTR_VAL_FIFO(ptree->discard_opts);
2592 FREE_RESTRICT_FIFO(ptree->restrict_opts);
2594 #endif /* FREE_CFG_T */
2602 attr_val * rlimit_av;
2604 rlimit_av = HEAD_PFIFO(ptree->rlimit);
2605 for (; rlimit_av != NULL; rlimit_av = rlimit_av->link) {
2606 switch (rlimit_av->attr) {
2613 if (rlimit_av->value.i != 0) {
2614 #if defined(RLIMIT_MEMLOCK)
2615 ntp_rlimit(RLIMIT_MEMLOCK,
2616 (rlim_t)(rlimit_av->value.i * 1024 * 1024),
2620 /* STDERR as well would be fine... */
2621 msyslog(LOG_WARNING, "'rlimit memlock' specified but is not available on this system.");
2622 #endif /* RLIMIT_MEMLOCK */
2629 #if defined(RLIMIT_STACK)
2630 ntp_rlimit(RLIMIT_STACK,
2631 (rlim_t)(rlimit_av->value.i * 4096),
2635 /* STDERR as well would be fine... */
2636 msyslog(LOG_WARNING, "'rlimit stacksize' specified but is not available on this system.");
2637 #endif /* RLIMIT_STACK */
2641 #if defined(RLIMIT_NOFILE)
2642 ntp_rlimit(RLIMIT_NOFILE,
2643 (rlim_t)(rlimit_av->value.i),
2647 /* STDERR as well would be fine... */
2648 msyslog(LOG_WARNING, "'rlimit filenum' specified but is not available on this system.");
2649 #endif /* RLIMIT_NOFILE */
2665 item = -1; /* quiet warning */
2666 tinker = HEAD_PFIFO(ptree->tinker);
2667 for (; tinker != NULL; tinker = tinker->link) {
2668 switch (tinker->attr) {
2687 item = LOOP_HUFFPUFF;
2699 item = LOOP_MAX_BACK;
2703 item = LOOP_MAX_FWD;
2707 item = LOOP_MINSTEP;
2714 loop_config(item, tinker->value.d);
2725 FREE_ATTR_VAL_FIFO(ptree->rlimit);
2733 FREE_ATTR_VAL_FIFO(ptree->tinker);
2735 #endif /* FREE_CFG_T */
2739 * config_nic_rules - apply interface listen/ignore/drop items
2745 int/*BOOL*/ input_from_file
2748 nic_rule_node * curr_node;
2750 nic_rule_match match_type;
2751 nic_rule_action action;
2757 curr_node = HEAD_PFIFO(ptree->nic_rules);
2759 if (curr_node != NULL
2760 && (HAVE_OPT( NOVIRTUALIPS ) || HAVE_OPT( INTERFACE ))) {
2762 "interface/nic rules are not allowed with --interface (-I) or --novirtualips (-L)%s",
2763 (input_from_file) ? ", exiting" : "");
2764 if (input_from_file)
2770 for (; curr_node != NULL; curr_node = curr_node->link) {
2772 if_name = curr_node->if_name;
2773 if (if_name != NULL)
2774 if_name = estrdup(if_name);
2776 switch (curr_node->match_class) {
2780 * this assignment quiets a gcc "may be used
2781 * uninitialized" warning and is here for no
2784 match_type = MATCH_ALL;
2790 * 0 is out of range for valid token T_...
2791 * and in a nic_rules_node indicates the
2792 * interface descriptor is either a name or
2793 * address, stored in if_name in either case.
2795 INSIST(if_name != NULL);
2796 pchSlash = strchr(if_name, '/');
2797 if (pchSlash != NULL)
2799 if (is_ip_address(if_name, AF_UNSPEC, &addr)) {
2800 match_type = MATCH_IFADDR;
2801 if (pchSlash != NULL
2802 && 1 == sscanf(pchSlash + 1, "%d",
2805 SIZEOF_INADDR(AF(&addr));
2806 prefixlen = max(-1, prefixlen);
2807 prefixlen = min(prefixlen,
2811 match_type = MATCH_IFNAME;
2812 if (pchSlash != NULL)
2818 match_type = MATCH_ALL;
2822 match_type = MATCH_IPV4;
2826 match_type = MATCH_IPV6;
2830 match_type = MATCH_WILDCARD;
2834 switch (curr_node->action) {
2838 * this assignment quiets a gcc "may be used
2839 * uninitialized" warning and is here for no
2842 action = ACTION_LISTEN;
2847 action = ACTION_LISTEN;
2851 action = ACTION_IGNORE;
2855 action = ACTION_DROP;
2859 add_nic_rule(match_type, if_name, prefixlen,
2861 timer_interfacetimeout(current_time + 2);
2862 if (if_name != NULL)
2871 free_config_nic_rules(
2875 nic_rule_node *curr_node;
2877 if (ptree->nic_rules != NULL) {
2879 UNLINK_FIFO(curr_node, *ptree->nic_rules, link);
2880 if (NULL == curr_node)
2882 free(curr_node->if_name);
2885 free(ptree->nic_rules);
2886 ptree->nic_rules = NULL;
2889 #endif /* FREE_CFG_T */
2893 apply_enable_disable(
2894 attr_val_fifo * fifo,
2898 attr_val *curr_flag;
2900 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
2904 for (curr_flag = HEAD_PFIFO(fifo);
2906 curr_flag = curr_flag->link) {
2908 option = curr_flag->value.i;
2913 "can not apply enable/disable token %d, unknown",
2918 proto_config(PROTO_AUTHENTICATE, enable, 0., NULL);
2922 proto_config(PROTO_BROADCLIENT, enable, 0., NULL);
2926 proto_config(PROTO_CAL, enable, 0., NULL);
2930 proto_config(PROTO_KERNEL, enable, 0., NULL);
2934 proto_config(PROTO_MONITOR, enable, 0., NULL);
2938 proto_config(PROTO_NTP, enable, 0., NULL);
2942 proto_config(PROTO_MODE7, enable, 0., NULL);
2946 proto_config(PROTO_FILEGEN, enable, 0., NULL);
2949 #ifdef BC_LIST_FRAMEWORK_NOT_YET_USED
2952 while (pentry->token) {
2953 if (pentry->token == option)
2957 if (!pentry->token) {
2959 "compat token %d not in bc_list[]",
2963 pentry->enabled = enable;
2976 apply_enable_disable(ptree->enable_opts, 1);
2977 apply_enable_disable(ptree->disable_opts, 0);
2983 free_config_system_opts(
2987 FREE_ATTR_VAL_FIFO(ptree->enable_opts);
2988 FREE_ATTR_VAL_FIFO(ptree->disable_opts);
2990 #endif /* FREE_CFG_T */
3000 my_lc = HEAD_PFIFO(ptree->logconfig);
3001 for (; my_lc != NULL; my_lc = my_lc->link) {
3002 switch (my_lc->attr) {
3005 ntp_syslogmask |= get_logmask(my_lc->value.s);
3009 ntp_syslogmask &= ~get_logmask(my_lc->value.s);
3013 ntp_syslogmask = get_logmask(my_lc->value.s);
3025 free_config_logconfig(
3029 FREE_ATTR_VAL_FIFO(ptree->logconfig);
3031 #endif /* FREE_CFG_T */
3044 sn = HEAD_PFIFO(ptree->phone);
3045 for (; sn != NULL; sn = sn->link) {
3046 /* need to leave array entry for NULL terminator */
3047 if (i < COUNTOF(sys_phone) - 1) {
3048 sys_phone[i++] = estrdup(sn->s);
3049 sys_phone[i] = NULL;
3052 "phone: Number of phone entries exceeds %zu. Ignoring phone %s...",
3053 (COUNTOF(sys_phone) - 1), sn->s);
3064 #ifdef HAVE_DNSREGISTRATION
3065 extern int mdnstries;
3066 mdnstries = ptree->mdnstries;
3067 #endif /* HAVE_DNSREGISTRATION */
3076 FREE_STRING_FIFO(ptree->phone);
3078 #endif /* FREE_CFG_T */
3087 setvar_node *my_node;
3088 size_t varlen, vallen, octets;
3092 my_node = HEAD_PFIFO(ptree->setvar);
3093 for (; my_node != NULL; my_node = my_node->link) {
3094 varlen = strlen(my_node->var);
3095 vallen = strlen(my_node->val);
3096 octets = varlen + vallen + 1 + 1;
3097 str = erealloc(str, octets);
3098 snprintf(str, octets, "%s=%s", my_node->var,
3100 set_sys_var(str, octets, (my_node->isdefault)
3116 FREE_SETVAR_FIFO(ptree->setvar);
3118 #endif /* FREE_CFG_T */
3130 curr_ttl = HEAD_PFIFO(ptree->ttl);
3131 for (; curr_ttl != NULL; curr_ttl = curr_ttl->link) {
3132 if (i < COUNTOF(sys_ttl))
3133 sys_ttl[i++] = (u_char)curr_ttl->i;
3136 "ttl: Number of TTL entries exceeds %zu. Ignoring TTL %d...",
3137 COUNTOF(sys_ttl), curr_ttl->i);
3150 FREE_INT_FIFO(ptree->ttl);
3152 #endif /* FREE_CFG_T */
3161 addr_opts_node *curr_trap;
3163 sockaddr_u addr_sock;
3164 sockaddr_u peeraddr;
3165 struct interface *localaddr;
3166 struct addrinfo hints;
3168 settrap_parms *pstp;
3173 /* silence warning about addr_sock potentially uninitialized */
3174 AF(&addr_sock) = AF_UNSPEC;
3176 curr_trap = HEAD_PFIFO(ptree->trap);
3177 for (; curr_trap != NULL; curr_trap = curr_trap->link) {
3182 curr_opt = HEAD_PFIFO(curr_trap->options);
3183 for (; curr_opt != NULL; curr_opt = curr_opt->link) {
3184 if (T_Port == curr_opt->attr) {
3185 if (curr_opt->value.i < 1
3186 || curr_opt->value.i > USHRT_MAX) {
3188 "invalid port number "
3193 port = (u_short)curr_opt->value.i;
3195 else if (T_Interface == curr_opt->attr) {
3196 /* Resolve the interface address */
3197 ZERO_SOCK(&addr_sock);
3198 if (getnetnum(curr_opt->value.s,
3199 &addr_sock, 1, t_UNK) != 1) {
3204 localaddr = findinterface(&addr_sock);
3206 if (NULL == localaddr) {
3208 "can't find interface with address %s",
3215 /* Now process the trap for the specified interface
3221 ZERO_SOCK(&peeraddr);
3222 rc = getnetnum(curr_trap->addr->address,
3223 &peeraddr, 1, t_UNK);
3227 "trap: unable to use IP address %s.",
3228 curr_trap->addr->address);
3229 #else /* WORKER follows */
3231 * save context and hand it off
3232 * for name resolution.
3235 hints.ai_protocol = IPPROTO_UDP;
3236 hints.ai_socktype = SOCK_DGRAM;
3237 snprintf(port_text, sizeof(port_text),
3239 hints.ai_flags = Z_AI_NUMERICSERV;
3240 pstp = emalloc_zero(sizeof(*pstp));
3241 if (localaddr != NULL) {
3242 hints.ai_family = localaddr->family;
3243 pstp->ifaddr_nonnull = 1;
3244 memcpy(&pstp->ifaddr,
3246 sizeof(pstp->ifaddr));
3248 rc = getaddrinfo_sometime(
3249 curr_trap->addr->address,
3252 &trap_name_resolved,
3256 "config_trap: getaddrinfo_sometime(%s,%s): %m",
3257 curr_trap->addr->address,
3262 /* port is at same location for v4 and v6 */
3263 SET_PORT(&peeraddr, port);
3265 if (NULL == localaddr)
3266 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
3268 AF(&peeraddr) = AF(&addr_sock);
3270 if (!ctlsettrap(&peeraddr, localaddr, 0,
3273 "set trap %s -> %s failed.",
3282 * trap_name_resolved()
3284 * Callback invoked when config_trap()'s DNS lookup completes.
3293 const char * service,
3294 const struct addrinfo * hints,
3295 const struct addrinfo * res
3298 settrap_parms *pstp;
3299 struct interface *localaddr;
3300 sockaddr_u peeraddr;
3308 "giving up resolving trap host %s: %s (%d)",
3309 name, gai_strerror(rescode), rescode);
3313 INSIST(sizeof(peeraddr) >= res->ai_addrlen);
3315 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
3317 if (pstp->ifaddr_nonnull)
3318 localaddr = findinterface(&pstp->ifaddr);
3319 if (NULL == localaddr)
3320 localaddr = ANY_INTERFACE_CHOOSE(&peeraddr);
3321 if (!ctlsettrap(&peeraddr, localaddr, 0, NTP_VERSION))
3322 msyslog(LOG_ERR, "set trap %s -> %s failed.",
3323 latoa(localaddr), stoa(&peeraddr));
3326 # endif /* WORKER */
3336 FREE_ADDR_OPTS_FIFO(ptree->trap);
3338 #endif /* FREE_CFG_T */
3347 addr_opts_node *curr_fudge;
3349 sockaddr_u addr_sock;
3350 address_node *addr_node;
3351 struct refclockstat clock_stat;
3354 curr_fudge = HEAD_PFIFO(ptree->fudge);
3355 for (; curr_fudge != NULL; curr_fudge = curr_fudge->link) {
3358 /* Get the reference clock address and
3359 * ensure that it is sane
3361 addr_node = curr_fudge->addr;
3362 ZERO_SOCK(&addr_sock);
3363 if (getnetnum(addr_node->address, &addr_sock, 1, t_REF)
3367 "unrecognized fudge reference clock address %s, line ignored",
3371 if (!ISREFCLOCKADR(&addr_sock)) {
3374 "inappropriate address %s for the fudge command, line ignored",
3378 /* Parse all the options to the fudge command */
3380 curr_opt = HEAD_PFIFO(curr_fudge->options);
3381 for (; curr_opt != NULL; curr_opt = curr_opt->link) {
3382 switch (curr_opt->attr) {
3385 clock_stat.haveflags |= CLK_HAVETIME1;
3386 clock_stat.fudgetime1 = curr_opt->value.d;
3390 clock_stat.haveflags |= CLK_HAVETIME2;
3391 clock_stat.fudgetime2 = curr_opt->value.d;
3395 clock_stat.haveflags |= CLK_HAVEVAL1;
3396 clock_stat.fudgeval1 = curr_opt->value.i;
3400 clock_stat.haveflags |= CLK_HAVEVAL2;
3401 clock_stat.fudgeval2 = 0;
3402 memcpy(&clock_stat.fudgeval2,
3404 min(strlen(curr_opt->value.s), 4));
3408 clock_stat.haveflags |= CLK_HAVEFLAG1;
3409 if (curr_opt->value.i)
3410 clock_stat.flags |= CLK_FLAG1;
3412 clock_stat.flags &= ~CLK_FLAG1;
3416 clock_stat.haveflags |= CLK_HAVEFLAG2;
3417 if (curr_opt->value.i)
3418 clock_stat.flags |= CLK_FLAG2;
3420 clock_stat.flags &= ~CLK_FLAG2;
3424 clock_stat.haveflags |= CLK_HAVEFLAG3;
3425 if (curr_opt->value.i)
3426 clock_stat.flags |= CLK_FLAG3;
3428 clock_stat.flags &= ~CLK_FLAG3;
3432 clock_stat.haveflags |= CLK_HAVEFLAG4;
3433 if (curr_opt->value.i)
3434 clock_stat.flags |= CLK_FLAG4;
3436 clock_stat.flags &= ~CLK_FLAG4;
3441 "Unexpected fudge flag %s (%d) for %s",
3442 token_name(curr_opt->attr),
3443 curr_opt->attr, stoa(&addr_sock));
3444 exit(curr_opt->attr ? curr_opt->attr : 1);
3449 refclock_control(&addr_sock, &clock_stat, NULL);
3462 FREE_ADDR_OPTS_FIFO(ptree->fudge);
3464 #endif /* FREE_CFG_T */
3475 curr_var = HEAD_PFIFO(ptree->vars);
3476 for (; curr_var != NULL; curr_var = curr_var->link) {
3477 /* Determine which variable to set and set it */
3478 switch (curr_var->attr) {
3480 case T_Broadcastdelay:
3481 proto_config(PROTO_BROADDELAY, 0, curr_var->value.d, NULL);
3485 loop_config(LOOP_TICK, curr_var->value.d);
3489 if ('\0' == curr_var->value.s[0]) {
3490 stats_drift_file = 0;
3491 msyslog(LOG_INFO, "config: driftfile disabled");
3493 stats_config(STATS_FREQ_FILE, curr_var->value.s);
3497 /* DSCP is in the upper 6 bits of the IP TOS/DS field */
3498 qos = curr_var->value.i << 2;
3502 sys_ident = curr_var->value.s;
3505 case T_WanderThreshold: /* FALLTHROUGH */
3507 wander_threshold = curr_var->value.d;
3511 stats_config(STATS_LEAP_FILE, curr_var->value.s);
3515 case T_Leapsmearinterval:
3516 leap_smear_intv = curr_var->value.i;
3517 msyslog(LOG_INFO, "config: leap smear interval %i s", leap_smear_intv);
3522 stats_config(STATS_PID_FILE, curr_var->value.s);
3526 if (-1 == change_logfile(curr_var->value.s, TRUE))
3528 "Cannot open logfile %s: %m",
3532 case T_Saveconfigdir:
3533 if (saveconfigdir != NULL)
3534 free(saveconfigdir);
3535 len = strlen(curr_var->value.s);
3537 saveconfigdir = NULL;
3538 } else if (DIR_SEP != curr_var->value.s[len - 1]
3539 #ifdef SYS_WINNT /* slash is also a dir. sep. on Windows */
3540 && '/' != curr_var->value.s[len - 1]
3544 saveconfigdir = emalloc(len + 1);
3545 snprintf(saveconfigdir, len + 1,
3550 saveconfigdir = estrdup(
3557 sys_automax = curr_var->value.i;
3563 "config_vars(): unexpected token %d",
3576 FREE_ATTR_VAL_FIFO(ptree->vars);
3578 #endif /* FREE_CFG_T */
3581 /* Define a function to check if a resolved address is sane.
3582 * If yes, return 1, else return 0;
3585 is_sane_resolved_address(
3586 sockaddr_u * peeraddr,
3590 if (!ISREFCLOCKADR(peeraddr) && ISBADADR(peeraddr)) {
3592 "attempt to configure invalid address %s",
3597 * Shouldn't be able to specify multicast
3598 * address for server/peer!
3599 * and unicast address for manycastclient!
3601 if ((T_Server == hmode || T_Peer == hmode || T_Pool == hmode)
3602 && IS_MCAST(peeraddr)) {
3604 "attempt to configure invalid address %s",
3608 if (T_Manycastclient == hmode && !IS_MCAST(peeraddr)) {
3610 "attempt to configure invalid address %s",
3615 if (IS_IPV6(peeraddr) && !ipv6_works)
3618 /* Ok, all tests succeeded, now we can return 1 */
3625 get_correct_host_mode(
3633 case T_Manycastclient:
3640 return MODE_BROADCAST;
3649 * peerflag_bits() get config_peers() peerflags value from a
3650 * peer_node's queue of flag attr_val entries.
3660 /* translate peerflags options to bits */
3662 option = HEAD_PFIFO(pn->peerflags);
3663 for (; option != NULL; option = option->link) {
3664 switch (option->value.i) {
3671 peerflags |= FLAG_SKEY;
3675 peerflags |= FLAG_BURST;
3679 peerflags |= FLAG_IBURST;
3683 peerflags |= FLAG_NOSELECT;
3687 peerflags |= FLAG_PREEMPT;
3691 peerflags |= FLAG_PREFER;
3695 peerflags |= FLAG_TRUE;
3699 peerflags |= FLAG_XLEAVE;
3713 sockaddr_u peeraddr;
3714 struct addrinfo hints;
3715 peer_node * curr_peer;
3716 peer_resolved_ctx * ctx;
3719 /* add servers named on the command line with iburst implied */
3721 cmdline_server_count > 0;
3722 cmdline_server_count--, cmdline_servers++) {
3724 ZERO_SOCK(&peeraddr);
3726 * If we have a numeric address, we can safely
3727 * proceed in the mainline with it. Otherwise, hand
3728 * the hostname off to the blocking child.
3730 if (is_ip_address(*cmdline_servers, AF_UNSPEC,
3733 SET_PORT(&peeraddr, NTP_PORT);
3734 if (is_sane_resolved_address(&peeraddr,
3749 /* we have a hostname to resolve */
3751 ctx = emalloc_zero(sizeof(*ctx));
3752 ctx->family = AF_UNSPEC;
3753 ctx->host_mode = T_Server;
3754 ctx->hmode = MODE_CLIENT;
3755 ctx->version = NTP_VERSION;
3756 ctx->flags = FLAG_IBURST;
3759 hints.ai_family = (u_short)ctx->family;
3760 hints.ai_socktype = SOCK_DGRAM;
3761 hints.ai_protocol = IPPROTO_UDP;
3763 getaddrinfo_sometime(*cmdline_servers,
3766 &peer_name_resolved,
3768 # else /* !WORKER follows */
3770 "hostname %s can not be used, please use IP address instead.",
3771 curr_peer->addr->address);
3776 /* add associations from the configuration file */
3777 curr_peer = HEAD_PFIFO(ptree->peers);
3778 for (; curr_peer != NULL; curr_peer = curr_peer->link) {
3779 ZERO_SOCK(&peeraddr);
3780 /* Find the correct host-mode */
3781 hmode = get_correct_host_mode(curr_peer->host_mode);
3784 if (T_Pool == curr_peer->host_mode) {
3785 AF(&peeraddr) = curr_peer->addr->type;
3788 curr_peer->addr->address,
3791 curr_peer->peerversion,
3794 peerflag_bits(curr_peer),
3799 * If we have a numeric address, we can safely
3800 * proceed in the mainline with it. Otherwise, hand
3801 * the hostname off to the blocking child.
3803 } else if (is_ip_address(curr_peer->addr->address,
3804 curr_peer->addr->type, &peeraddr)) {
3806 SET_PORT(&peeraddr, NTP_PORT);
3807 if (is_sane_resolved_address(&peeraddr,
3808 curr_peer->host_mode))
3814 curr_peer->peerversion,
3817 peerflag_bits(curr_peer),
3822 /* we have a hostname to resolve */
3824 ctx = emalloc_zero(sizeof(*ctx));
3825 ctx->family = curr_peer->addr->type;
3826 ctx->host_mode = curr_peer->host_mode;
3828 ctx->version = curr_peer->peerversion;
3829 ctx->minpoll = curr_peer->minpoll;
3830 ctx->maxpoll = curr_peer->maxpoll;
3831 ctx->flags = peerflag_bits(curr_peer);
3832 ctx->ttl = curr_peer->ttl;
3833 ctx->keyid = curr_peer->peerkey;
3834 ctx->group = curr_peer->group;
3837 hints.ai_family = ctx->family;
3838 hints.ai_socktype = SOCK_DGRAM;
3839 hints.ai_protocol = IPPROTO_UDP;
3841 getaddrinfo_sometime(curr_peer->addr->address,
3844 &peer_name_resolved, ctx);
3845 # else /* !WORKER follows */
3847 "hostname %s can not be used, please use IP address instead.",
3848 curr_peer->addr->address);
3856 * peer_name_resolved()
3858 * Callback invoked when config_peers()'s DNS lookup completes.
3867 const char * service,
3868 const struct addrinfo * hints,
3869 const struct addrinfo * res
3872 sockaddr_u peeraddr;
3873 peer_resolved_ctx * ctx;
3875 const char * fam_spec;
3882 DPRINTF(1, ("peer_name_resolved(%s) rescode %d\n", name, rescode));
3885 #ifndef IGNORE_DNS_ERRORS
3888 "giving up resolving host %s: %s (%d)",
3889 name, gai_strerror(rescode), rescode);
3890 #else /* IGNORE_DNS_ERRORS follows */
3891 getaddrinfo_sometime(name, service, hints,
3893 &peer_name_resolved, context);
3898 /* Loop to configure a single association */
3899 for (; res != NULL; res = res->ai_next) {
3900 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
3901 if (is_sane_resolved_address(&peeraddr,
3903 NLOG(NLOG_SYSINFO) {
3905 fam_spec = (AF_INET6 == af)
3910 msyslog(LOG_INFO, "DNS %s %s-> %s",
3940 peer_node *curr_peer;
3942 if (ptree->peers != NULL) {
3944 UNLINK_FIFO(curr_peer, *ptree->peers, link);
3945 if (NULL == curr_peer)
3947 destroy_address_node(curr_peer->addr);
3948 destroy_attr_val_fifo(curr_peer->peerflags);
3952 ptree->peers = NULL;
3955 #endif /* FREE_CFG_T */
3964 sockaddr_u peeraddr;
3965 struct addrinfo hints;
3966 unpeer_node * curr_unpeer;
3971 curr_unpeer = HEAD_PFIFO(ptree->unpeers);
3972 for (; curr_unpeer != NULL; curr_unpeer = curr_unpeer->link) {
3974 * Either AssocID will be zero, and we unpeer by name/
3975 * address addr, or it is nonzero and addr NULL.
3977 if (curr_unpeer->assocID) {
3978 p = findpeerbyassoc(curr_unpeer->assocID);
3980 msyslog(LOG_NOTICE, "unpeered %s",
3982 peer_clear(p, "GONE");
3990 AF(&peeraddr) = curr_unpeer->addr->type;
3991 name = curr_unpeer->addr->address;
3992 rc = getnetnum(name, &peeraddr, 0, t_UNK);
3993 /* Do we have a numeric address? */
3995 DPRINTF(1, ("unpeer: searching for %s\n",
3997 p = findexistingpeer(&peeraddr, NULL, NULL, -1, 0);
3999 msyslog(LOG_NOTICE, "unpeered %s",
4001 peer_clear(p, "GONE");
4008 * It's not a numeric IP address, it's a hostname.
4009 * Check for associations with a matching hostname.
4011 for (p = peer_list; p != NULL; p = p->p_link)
4012 if (p->hostname != NULL)
4013 if (!strcasecmp(p->hostname, name))
4016 msyslog(LOG_NOTICE, "unpeered %s", name);
4017 peer_clear(p, "GONE");
4020 /* Resolve the hostname to address(es). */
4023 hints.ai_family = curr_unpeer->addr->type;
4024 hints.ai_socktype = SOCK_DGRAM;
4025 hints.ai_protocol = IPPROTO_UDP;
4026 getaddrinfo_sometime(name, "ntp", &hints,
4028 &unpeer_name_resolved, NULL);
4029 # else /* !WORKER follows */
4031 "hostname %s can not be used, please use IP address instead.",
4040 * unpeer_name_resolved()
4042 * Callback invoked when config_unpeers()'s DNS lookup completes.
4046 unpeer_name_resolved(
4051 const char * service,
4052 const struct addrinfo * hints,
4053 const struct addrinfo * res
4056 sockaddr_u peeraddr;
4059 const char * fam_spec;
4063 DPRINTF(1, ("unpeer_name_resolved(%s) rescode %d\n", name, rescode));
4066 msyslog(LOG_ERR, "giving up resolving unpeer %s: %s (%d)",
4067 name, gai_strerror(rescode), rescode);
4071 * Loop through the addresses found
4073 for (; res != NULL; res = res->ai_next) {
4074 INSIST(res->ai_addrlen <= sizeof(peeraddr));
4075 memcpy(&peeraddr, res->ai_addr, res->ai_addrlen);
4076 DPRINTF(1, ("unpeer: searching for peer %s\n",
4078 peer = findexistingpeer(&peeraddr, NULL, NULL, -1, 0);
4081 fam_spec = (AF_INET6 == af)
4086 msyslog(LOG_NOTICE, "unpeered %s %s-> %s", name,
4087 fam_spec, stoa(&peeraddr));
4088 peer_clear(peer, "GONE");
4098 free_config_unpeers(
4102 unpeer_node *curr_unpeer;
4104 if (ptree->unpeers != NULL) {
4106 UNLINK_FIFO(curr_unpeer, *ptree->unpeers, link);
4107 if (NULL == curr_unpeer)
4109 destroy_address_node(curr_unpeer->addr);
4112 free(ptree->unpeers);
4115 #endif /* FREE_CFG_T */
4120 config_reset_counters(
4124 int_node *counter_set;
4126 for (counter_set = HEAD_PFIFO(ptree->reset_counters);
4127 counter_set != NULL;
4128 counter_set = counter_set->link) {
4129 switch (counter_set->i) {
4131 DPRINTF(1, ("config_reset_counters %s (%d) invalid\n",
4132 keyword(counter_set->i), counter_set->i));
4170 free_config_reset_counters(
4174 FREE_INT_FIFO(ptree->reset_counters);
4176 #endif /* FREE_CFG_T */
4186 server_info *serv_info;
4187 attr_val *init_stmt;
4190 /* Check if a simulate block was found in the configuration code.
4191 * If not, return an error and exit
4193 sim_n = HEAD_PFIFO(ptree->sim_details);
4194 if (NULL == sim_n) {
4195 fprintf(stderr, "ERROR!! I couldn't find a \"simulate\" block for configuring the simulator.\n");
4196 fprintf(stderr, "\tCheck your configuration file.\n");
4200 /* Process the initialization statements
4201 * -------------------------------------
4203 init_stmt = HEAD_PFIFO(sim_n->init_opts);
4204 for (; init_stmt != NULL; init_stmt = init_stmt->link) {
4205 switch(init_stmt->attr) {
4208 simulation.beep_delay = init_stmt->value.d;
4211 case T_Sim_Duration:
4212 simulation.end_time = init_stmt->value.d;
4217 "Unknown simulator init token %d\n",
4223 /* Process the server list
4224 * -----------------------
4226 simulation.num_of_servers = 0;
4227 serv_info = HEAD_PFIFO(sim_n->servers);
4228 for (; serv_info != NULL; serv_info = serv_info->link)
4229 simulation.num_of_servers++;
4230 simulation.servers = eallocarray(simulation.num_of_servers,
4231 sizeof(simulation.servers[0]));
4234 serv_info = HEAD_PFIFO(sim_n->servers);
4235 for (; serv_info != NULL; serv_info = serv_info->link) {
4236 if (NULL == serv_info) {
4237 fprintf(stderr, "Simulator server list is corrupt\n");
4240 simulation.servers[i] = *serv_info;
4241 simulation.servers[i].link = NULL;
4246 printf("Creating server associations\n");
4247 create_server_associations();
4248 fprintf(stderr,"\tServer associations successfully created!!\n");
4259 server_info *serv_n;
4260 script_info *script_n;
4262 if (NULL == ptree->sim_details)
4264 sim_n = HEAD_PFIFO(ptree->sim_details);
4265 free(ptree->sim_details);
4266 ptree->sim_details = NULL;
4270 FREE_ATTR_VAL_FIFO(sim_n->init_opts);
4272 UNLINK_FIFO(serv_n, *sim_n->servers, link);
4275 free(serv_n->curr_script);
4276 if (serv_n->script != NULL) {
4278 UNLINK_FIFO(script_n, *serv_n->script,
4280 if (script_n == NULL)
4284 free(serv_n->script);
4290 #endif /* FREE_CFG_T */
4294 /* Define two different config functions. One for the daemon and the other for
4295 * the simulator. The simulator ignores a lot of the standard ntpd configuration
4302 int/*BOOL*/ input_from_files
4305 config_nic_rules(ptree, input_from_files);
4306 config_monitor(ptree);
4309 config_access(ptree);
4310 config_tinker(ptree);
4311 config_rlimit(ptree);
4312 config_system_opts(ptree);
4313 config_logconfig(ptree);
4314 config_phone(ptree);
4315 config_mdnstries(ptree);
4316 config_setvar(ptree);
4323 config_other_modes(ptree);
4324 config_peers(ptree);
4325 config_unpeers(ptree);
4326 config_fudge(ptree);
4327 config_reset_counters(ptree);
4329 #ifdef TEST_BLOCKING_WORKER
4331 struct addrinfo hints;
4334 hints.ai_socktype = SOCK_STREAM;
4335 hints.ai_protocol = IPPROTO_TCP;
4336 getaddrinfo_sometime("www.cnn.com", "ntp", &hints,
4338 gai_test_callback, (void *)1);
4339 hints.ai_family = AF_INET6;
4340 getaddrinfo_sometime("ipv6.google.com", "ntp", &hints,
4342 gai_test_callback, (void *)0x600);
4355 printf("Configuring Simulator...\n");
4356 printf("Some ntpd-specific commands in the configuration file will be ignored.\n");
4359 config_monitor(ptree);
4360 config_tinker(ptree);
4362 config_rlimit(ptree); /* not needed for the simulator */
4363 config_system_opts(ptree);
4364 config_logconfig(ptree);
4372 * config_remotely() - implements ntpd side of ntpq :config
4376 sockaddr_u * remote_addr
4381 snprintf(origin, sizeof(origin), "remote config from %s",
4383 lex_init_stack(origin, NULL); /* no checking needed... */
4384 init_syntax_tree(&cfgt);
4388 cfgt.source.attr = CONF_SOURCE_NTPQ;
4389 cfgt.timestamp = time(NULL);
4390 cfgt.source.value.s = estrdup(stoa(remote_addr));
4392 DPRINTF(1, ("Finished Parsing!!\n"));
4394 save_and_apply_config_tree(FALSE);
4399 * getconfig() - process startup configuration file e.g /etc/ntp.conf
4410 atexit(free_all_config_trees);
4413 config_file = CONFIG_FILE;
4416 if (!ExpandEnvironmentStringsA(temp, config_file_storage,
4417 sizeof(config_file_storage))) {
4418 msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m");
4421 config_file = config_file_storage;
4423 temp = ALT_CONFIG_FILE;
4424 if (!ExpandEnvironmentStringsA(temp, alt_config_file_storage,
4425 sizeof(alt_config_file_storage))) {
4426 msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m");
4429 alt_config_file = alt_config_file_storage;
4430 #endif /* SYS_WINNT */
4433 * install a non default variable with this daemon version
4435 snprintf(line, sizeof(line), "daemon_version=\"%s\"", Version);
4436 set_sys_var(line, strlen(line) + 1, RO);
4439 * Set up for the first time step to install a variable showing
4440 * which syscall is being used to step.
4442 set_tod_using = &ntpd_set_tod_using;
4444 getCmdOpts(argc, argv);
4445 init_syntax_tree(&cfgt);
4447 !lex_init_stack(FindConfig(config_file), "r")
4449 /* If there is no config_file, try NetInfo. */
4450 && check_netinfo && !(config_netinfo = get_netinfo_config())
4451 #endif /* HAVE_NETINFO */
4453 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(config_file));
4459 /* Under WinNT try alternate_config_file name, first NTP.CONF, then NTP.INI */
4461 if (!lex_init_stack(FindConfig(alt_config_file), "r")) {
4463 * Broadcast clients can sometimes run without
4464 * a configuration file.
4466 msyslog(LOG_INFO, "getconfig: Couldn't open <%s>: %m", FindConfig(alt_config_file));
4471 cfgt.source.value.s = estrdup(alt_config_file);
4472 #endif /* SYS_WINNT */
4474 cfgt.source.value.s = estrdup(config_file);
4477 /*** BULK OF THE PARSER ***/
4479 yydebug = !!(debug >= 5);
4484 DPRINTF(1, ("Finished Parsing!!\n"));
4486 cfgt.source.attr = CONF_SOURCE_FILE;
4487 cfgt.timestamp = time(NULL);
4489 save_and_apply_config_tree(TRUE);
4493 free_netinfo_config(config_netinfo);
4494 #endif /* HAVE_NETINFO */
4499 save_and_apply_config_tree(int/*BOOL*/ input_from_file)
4503 config_tree *punlinked;
4507 * Keep all the configuration trees applied since startup in
4508 * a list that can be used to dump the configuration back to
4511 ptree = emalloc(sizeof(*ptree));
4512 memcpy(ptree, &cfgt, sizeof(*ptree));
4515 LINK_TAIL_SLIST(cfg_tree_history, ptree, link, config_tree);
4518 if (HAVE_OPT( SAVECONFIGQUIT )) {
4523 dumpfile = fopen(OPT_ARG( SAVECONFIGQUIT ), "w");
4524 if (NULL == dumpfile) {
4527 "can not create save file %s, error %d %m\n",
4528 OPT_ARG(SAVECONFIGQUIT), err);
4532 dumpfailed = dump_all_config_trees(dumpfile, 0);
4535 "--saveconfigquit %s error %d\n",
4536 OPT_ARG( SAVECONFIGQUIT ),
4540 "configuration saved to %s\n",
4541 OPT_ARG( SAVECONFIGQUIT ));
4545 #endif /* SAVECONFIG */
4547 /* The actual configuration done depends on whether we are configuring the
4548 * simulator or the daemon. Perform a check and call the appropriate
4549 * function as needed.
4553 config_ntpd(ptree, input_from_file);
4555 config_ntpdsim(ptree);
4559 * With configure --disable-saveconfig, there's no use keeping
4560 * the config tree around after application, so free it.
4563 UNLINK_SLIST(punlinked, cfg_tree_history, ptree, link,
4565 INSIST(punlinked == ptree);
4566 free_config_tree(ptree);
4578 snprintf(line, sizeof(line), "settimeofday=\"%s\"", which);
4579 set_sys_var(line, strlen(line) + 1, RO);
4593 snprintf(buf, LIB_BUFLENGTH, "%g", d);
4595 /* use lowercase 'e', strip any leading zeroes in exponent */
4596 pch_e = strchr(buf, 'e');
4597 if (NULL == pch_e) {
4598 pch_e = strchr(buf, 'E');
4607 while ('0' == *pch_nz)
4609 if (pch_nz == pch_e)
4611 strlcpy(pch_e, pch_nz, LIB_BUFLENGTH - (pch_e - buf));
4617 /* FUNCTIONS COPIED FROM THE OLDER ntp_config.c
4618 * --------------------------------------------
4623 * get_pfxmatch - find value for prefixmatch
4624 * and update char * accordingly
4632 while (m->name != NULL) {
4633 if (strncmp(*pstr, m->name, strlen(m->name)) == 0) {
4634 *pstr += strlen(m->name);
4644 * get_match - find logmask value
4652 while (m->name != NULL) {
4653 if (strcmp(str, m->name) == 0)
4662 * get_logmask - build bitmask for ntp_syslogmask
4673 mask = get_match(str, logcfg_noclass_items);
4678 offset = get_pfxmatch(&t, logcfg_class);
4679 mask = get_match(t, logcfg_class_items);
4682 return mask << offset;
4684 msyslog(LOG_ERR, "logconfig: '%s' not recognized - ignored",
4694 * get_netinfo_config - find the nearest NetInfo domain with an ntp
4695 * configuration and initialize the configuration state.
4697 static struct netinfo_config_state *
4698 get_netinfo_config(void)
4703 struct netinfo_config_state *config;
4705 if (ni_open(NULL, ".", &domain) != NI_OK) return NULL;
4707 while ((status = ni_pathsearch(domain, &config_dir, NETINFO_CONFIG_DIR)) == NI_NODIR) {
4709 if (ni_open(domain, "..", &next_domain) != NI_OK) {
4710 ni_free(next_domain);
4714 domain = next_domain;
4716 if (status != NI_OK) {
4721 config = emalloc(sizeof(*config));
4722 config->domain = domain;
4723 config->config_dir = config_dir;
4724 config->prop_index = 0;
4725 config->val_index = 0;
4726 config->val_list = NULL;
4733 * free_netinfo_config - release NetInfo configuration state
4736 free_netinfo_config(
4737 struct netinfo_config_state *config
4740 ni_free(config->domain);
4746 * gettokens_netinfo - return tokens from NetInfo
4750 struct netinfo_config_state *config,
4755 int prop_index = config->prop_index;
4756 int val_index = config->val_index;
4757 char **val_list = config->val_list;
4760 * Iterate through each keyword and look for a property that matches it.
4764 for (; prop_index < COUNTOF(keywords); prop_index++)
4766 ni_namelist namelist;
4767 struct keyword current_prop = keywords[prop_index];
4771 * For each value associated in the property, we're going to return
4772 * a separate line. We squirrel away the values in the config state
4773 * so the next time through, we don't need to do this lookup.
4776 if (NI_OK == ni_lookupprop(config->domain,
4777 &config->config_dir, current_prop.text,
4780 /* Found the property, but it has no values */
4781 if (namelist.ni_namelist_len == 0) continue;
4785 (namelist.ni_namelist_len + 1),
4787 val_list = config->val_list;
4790 index < namelist.ni_namelist_len;
4794 value = namelist.ni_namelist_val[index];
4795 val_list[index] = estrdup(value);
4797 val_list[index] = NULL;
4801 ni_namelist_free(&namelist);
4803 config->prop_index = prop_index;
4806 /* No list; we're done here. */
4808 return CONFIG_UNKNOWN;
4811 * We have a list of values for the current property.
4812 * Iterate through them and return each in order.
4814 if (val_list[val_index]) {
4817 char *tokens = val_list[val_index];
4819 msyslog(LOG_INFO, "%s %s", keywords[prop_index].text, val_list[val_index]);
4821 (const char*)tokenlist[0] = keywords[prop_index].text;
4822 for (ntok = 1; ntok < MAXTOKENS; ntok++) {
4823 tokenlist[ntok] = tokens;
4824 while (!ISEOL(*tokens) && (!ISSPACE(*tokens) || quoted))
4825 quoted ^= (*tokens++ == '"');
4827 if (ISEOL(*tokens)) {
4830 } else { /* must be space */
4832 while (ISSPACE(*tokens))
4839 if (ntok == MAXTOKENS) {
4840 /* HMS: chomp it to lose the EOL? */
4842 "gettokens_netinfo: too many tokens. Ignoring: %s",
4845 *ntokens = ntok + 1;
4848 config->val_index++; /* HMS: Should this be in the 'else'? */
4850 return keywords[prop_index].keytype;
4853 /* We're done with the current property. */
4854 prop_index = ++config->prop_index;
4856 /* Free val_list and reset counters. */
4857 for (val_index = 0; val_list[val_index]; val_index++)
4858 free(val_list[val_index]);
4860 val_list = config->val_list = NULL;
4861 val_index = config->val_index = 0;
4865 #endif /* HAVE_NETINFO */
4869 * getnetnum - return a net number (this is crude, but careful)
4871 * returns 1 for success, and mysteriously, 0 for most failures, and
4872 * -1 if the address found is IPv6 and we believe IPv6 isn't working.
4880 enum gnn_type a_type /* ignored */
4883 NTP_REQUIRE(AF_UNSPEC == AF(addr) ||
4884 AF_INET == AF(addr) ||
4885 AF_INET6 == AF(addr));
4887 if (!is_ip_address(num, AF(addr), addr))
4890 if (IS_IPV6(addr) && !ipv6_works)
4893 # ifdef ISC_PLATFORM_HAVESALEN
4894 addr->sa.sa_len = SIZEOF_SOCKADDR(AF(addr));
4896 SET_PORT(addr, NTP_PORT);
4898 DPRINTF(2, ("getnetnum given %s, got %s\n", num, stoa(addr)));
4904 #if defined(HAVE_SETRLIMIT)
4910 const char * rl_sstr
4916 # ifdef RLIMIT_MEMLOCK
4917 case RLIMIT_MEMLOCK:
4919 * The default RLIMIT_MEMLOCK is very low on Linux systems.
4920 * Unless we increase this limit malloc calls are likely to
4921 * fail if we drop root privilege. To be useful the value
4922 * has to be larger than the largest ntpd resident set size.
4924 DPRINTF(2, ("ntp_rlimit: MEMLOCK: %d %s\n",
4925 (int)(rl_value / rl_scale), rl_sstr));
4926 rl.rlim_cur = rl.rlim_max = rl_value;
4927 if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1)
4928 msyslog(LOG_ERR, "Cannot set RLIMIT_MEMLOCK: %m");
4930 # endif /* RLIMIT_MEMLOCK */
4932 # ifdef RLIMIT_NOFILE
4935 * For large systems the default file descriptor limit may
4938 DPRINTF(2, ("ntp_rlimit: NOFILE: %d %s\n",
4939 (int)(rl_value / rl_scale), rl_sstr));
4940 rl.rlim_cur = rl.rlim_max = rl_value;
4941 if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
4942 msyslog(LOG_ERR, "Cannot set RLIMIT_NOFILE: %m");
4944 # endif /* RLIMIT_NOFILE */
4946 # ifdef RLIMIT_STACK
4949 * Provide a way to set the stack limit to something
4950 * smaller, so that we don't lock a lot of unused
4953 DPRINTF(2, ("ntp_rlimit: STACK: %d %s pages\n",
4954 (int)(rl_value / rl_scale), rl_sstr));
4955 if (-1 == getrlimit(RLIMIT_STACK, &rl)) {
4956 msyslog(LOG_ERR, "getrlimit(RLIMIT_STACK) failed: %m");
4958 if (rl_value > rl.rlim_max) {
4959 msyslog(LOG_WARNING,
4960 "ntp_rlimit: using maximum allowed stack limit %lu instead of %lu.",
4961 (u_long)rl.rlim_max,
4963 rl_value = rl.rlim_max;
4965 rl.rlim_cur = rl_value;
4966 if (-1 == setrlimit(RLIMIT_STACK, &rl)) {
4968 "ntp_rlimit: Cannot set RLIMIT_STACK: %m");
4972 # endif /* RLIMIT_STACK */
4975 INSIST(!"Unexpected setrlimit() case!");
4979 #endif /* HAVE_SETRLIMIT */