1 /* ntp_parser.y
2 *
3 * The parser for the NTP configuration file.
4 *
5 * Written By: Sachin Kamboj
6 * University of Delaware
7 * Newark, DE 19711
8 * Copyright Sachin Kamboj
9 * Copyright the NTPsec project contributors
10 * SPDX-License-Identifier: BSD-2-Clause
11 */
12
13 %{
14 #include "config.h"
15
16 #include "ntp.h"
17 #include "ntpd.h"
18 #include "ntp_machine.h"
19 #include "ntp_stdlib.h"
20 #include "ntp_filegen.h"
21 #include "ntp_scanner.h"
22 #include "ntp_config.h"
23
24 #define YYMALLOC emalloc
25 #define YYFREE free
26 #define YYERROR_VERBOSE
27 #define YYMAXDEPTH 1000 /* stop the madness sooner */
28 void yyerror(const char *msg);
29 %}
30
31 /*
32 * Enable generation of token names array even without YYDEBUG.
33 * We access via token_name() defined below.
34 */
35 %token-table
36
37 %union {
38 char * String;
39 double Double;
40 int Integer;
41 unsigned U_int;
42 gen_fifo * Generic_fifo;
43 attr_val * Attr_val;
44 attr_val_fifo * Attr_val_fifo;
45 int_fifo * Int_fifo;
46 string_fifo * String_fifo;
47 address_node * Address_node;
48 address_fifo * Address_fifo;
49 setvar_node * Set_var;
50 }
51
52 /* Terminals (do not appear left of colon) */
53 %token <Integer> T_Aead
54 %token <Integer> T_Age
55 %token <Integer> T_All
56 %token <Integer> T_Allan
57 %token <Integer> T_Allpeers
58 %token <Integer> T_Ask
59 %token <Integer> T_Auth
60 %token <Integer> T_Average
61 %token <Integer> T_Baud
62 %token <Integer> T_Bias
63 %token <Integer> T_Burst
64 %token <Integer> T_Calibrate
65 %token <Integer> T_Ca
66 %token <Integer> T_Ceiling
67 %token <Integer> T_Cert
68 %token <Integer> T_Clock
69 %token <Integer> T_Clockstats
70 %token <Integer> T_Cohort
71 %token <Integer> T_Cookie
72 %token <Integer> T_ControlKey
73 %token <Integer> T_Ctl
74 %token <Integer> T_Day
75 %token <Integer> T_Default
76 %token <Integer> T_Disable
77 %token <Integer> T_Dispersion
78 %token <Double> T_Double /* Not a token */
79 %token <Integer> T_Driftfile
80 %token <Integer> T_Drop
81 %token <Integer> T_Dscp
82 %token <Integer> T_Expire
83 %token <Integer> T_Ellipsis /* "..." not "ellipsis" */
84 %token <Integer> T_Enable
85 %token <Integer> T_End
86 %token <Integer> T_False
87 %token <Integer> T_File
88 %token <Integer> T_Filegen
89 %token <Integer> T_Filenum
90 %token <Integer> T_Flag1
91 %token <Integer> T_Flag2
92 %token <Integer> T_Flag3
93 %token <Integer> T_Flag4
94 %token <Integer> T_Flake
95 %token <Integer> T_Floor
96 %token <Integer> T_Freq
97 %token <Integer> T_Fudge
98 %token <Integer> T_Holdover
99 %token <Integer> T_Huffpuff
100 %token <Integer> T_Iburst
101 %token <Integer> T_Ignore
102 %token <Integer> T_Incalloc
103 %token <Integer> T_Incmem
104 %token <Integer> T_Initalloc
105 %token <Integer> T_Initmem
106 %token <Integer> T_Includefile
107 %token <Integer> T_Integer /* Not a token, used as tag */
108 %token <Integer> T_Interface
109 %token <Integer> T_Intrange /* Not a token, used as tag */
110 %token <Integer> T_Io
111 %token <Integer> T_Ipv4
112 %token <Integer> T_Ipv4_flag
113 %token <Integer> T_Ipv6
114 %token <Integer> T_Ipv6_flag
115 %token <Integer> T_Kernel
116 %token <Integer> T_Key
117 %token <Integer> T_Keys
118 %token <Integer> T_Kod
119 %token <Integer> T_Mssntp
120 %token <Integer> T_Leapfile
121 %token <Integer> T_Leapsmearinterval
122 %token <Integer> T_Limit
123 %token <Integer> T_Limited
124 %token <Integer> T_Link
125 %token <Integer> T_Listen
126 %token <Integer> T_Logconfig
127 %token <Integer> T_Logfile
128 %token <Integer> T_Loopstats
129 %token <Integer> T_Mask
130 %token <Integer> T_Maxage
131 %token <Integer> T_Maxclock
132 %token <Integer> T_Maxdepth
133 %token <Integer> T_Maxdisp
134 %token <Integer> T_Maxdist
135 %token <Integer> T_Maxmem
136 %token <Integer> T_Maxpoll
137 %token <Integer> T_Maxtls
138 %token <Integer> T_Mdnstries
139 %token <Integer> T_Mem
140 %token <Integer> T_Memlock
141 %token <Integer> T_Minage
142 %token <Integer> T_Minclock
143 %token <Integer> T_Mindepth
144 %token <Integer> T_Mindist
145 %token <Integer> T_Minpoll
146 %token <Integer> T_Minsane
147 %token <Integer> T_Mintls
148 %token <Integer> T_Mode
149 %token <Integer> T_Monitor
150 %token <Integer> T_Month
151 %token <Integer> T_Mru
152 %token <Integer> T_Nic
153 %token <Integer> T_Nolink
154 %token <Integer> T_Nomodify
155 %token <Integer> T_Nomrulist
156 %token <Integer> T_None
157 %token <Integer> T_Nonvolatile
158 %token <Integer> T_Nopeer
159 %token <Integer> T_Noquery
160 %token <Integer> T_Noselect
161 %token <Integer> T_Noserve
162 %token <Integer> T_Notrap
163 %token <Integer> T_Notrust
164 %token <Integer> T_Noval
165 %token <Integer> T_Ntp
166 %token <Integer> T_Ntpport
167 %token <Integer> T_NtpSignDsocket
168 %token <Integer> T_Nts
169 %token <Integer> T_Orphan
170 %token <Integer> T_Orphanwait
171 %token <Integer> T_Panic
172 %token <Integer> T_Path
173 %token <Integer> T_Peer
174 %token <Integer> T_Peerstats
175 %token <Integer> T_Phone
176 %token <Integer> T_Pid
177 %token <Integer> T_Pidfile
178 %token <Integer> T_Pool
179 %token <Integer> T_Ppspath
180 %token <Integer> T_Prefer
181 %token <Integer> T_Protostats
182 %token <Integer> T_Rawstats
183 %token <Integer> T_Refclock
184 %token <Integer> T_Refid
185 %token <Integer> T_Requestkey
186 %token <Integer> T_Require
187 %token <Integer> T_Reset
188 %token <Integer> T_Restrict
189 %token <Integer> T_Rlimit
190 %token <Integer> T_Saveconfigdir
191 %token <Integer> T_Server
192 %token <Integer> T_Setvar
193 %token <Integer> T_Source
194 %token <Integer> T_Stacksize
195 %token <Integer> T_Statistics
196 %token <Integer> T_Stats
197 %token <Integer> T_Statsdir
198 %token <Integer> T_Step
199 %token <Integer> T_Stepback
200 %token <Integer> T_Stepfwd
201 %token <Integer> T_Stepout
202 %token <Integer> T_Stratum
203 %token <Integer> T_Subtype
204 %token <String> T_String /* Not a token */
205 %token <Integer> T_Sys
206 %token <Integer> T_Sysstats
207 %token <Integer> T_Tick
208 %token <Integer> T_Time1
209 %token <Integer> T_Time2
210 %token <Integer> T_Timer
211 %token <Integer> T_Timingstats
212 %token <Integer> T_Tinker
213 %token <Integer> T_Tlsciphers
214 %token <Integer> T_Tlsciphersuites
215 %token <Integer> T_Tos
216 %token <Integer> T_True
217 %token <Integer> T_Trustedkey
218 %token <Integer> T_Type
219 %token <Integer> T_U_int /* Not a token */
220 %token <Integer> T_Unit
221 %token <Integer> T_Unconfig
222 %token <Integer> T_Unpeer
223 %token <Integer> T_Unrestrict
224 %token <Integer> T_Usestats
225 %token <Integer> T_Version
226 %token <Integer> T_WanderThreshold /* Not a token, used as tag */
227 %token <Integer> T_Week
228 %token <Integer> T_Wildcard
229 %token <Integer> T_Year
230 %token <Integer> T_Flag /* Not a token, used as tag */
231 %token <Integer> T_EOC
232
233 /*** NON-TERMINALS ***/
234 %type <Integer> access_control_flag
235 %type <Int_fifo> ac_flag_list
236 %type <Address_node> address
237 %type <Integer> address_fam
238 %type <Integer> boolean
239 %type <Integer> client_type
240 %type <Integer> counter_set_keyword
241 %type <Int_fifo> counter_set_list
242 %type <Attr_val> limit_option
243 %type <Integer> limit_option_keyword
244 %type <Attr_val_fifo> limit_option_list
245 %type <Integer> enable_disable
246 %type <Attr_val> filegen_option
247 %type <Attr_val_fifo> filegen_option_list
248 %type <Integer> filegen_type
249 %type <Attr_val> fudge_factor
250 %type <Integer> fudge_factor_bool_keyword
251 %type <Integer> fudge_factor_dbl_keyword
252 %type <Attr_val_fifo> fudge_factor_list
253 %type <Attr_val_fifo> integer_list_range
254 %type <Attr_val> integer_list_range_elt
255 %type <Attr_val> integer_range
256 %type <Integer> nic_rule_action
257 %type <Integer> interface_command
258 %type <Integer> interface_nic
259 %type <Address_node> ip_address
260 %type <Integer> link_nolink
261 %type <Attr_val> log_config_command
262 %type <Attr_val_fifo> log_config_list
263 %type <Integer> misc_cmd_dbl_keyword
264 %type <Integer> misc_cmd_int_keyword
265 %type <Integer> misc_cmd_str_keyword
266 %type <Integer> misc_cmd_str_lcl_keyword
267 %type <Attr_val> mru_option
268 %type <Integer> mru_option_keyword
269 %type <Attr_val_fifo> mru_option_list
270 %type <Integer> nic_rule_class
271 %type <Double> number
272 %type <Attr_val> option
273 %type <Attr_val> option_flag
274 %type <Integer> option_flag_keyword
275 %type <Attr_val_fifo> option_list
276 %type <Attr_val> option_boolean
277 %type <Integer> option_bool_keyword
278 %type <Attr_val> option_double
279 %type <Integer> option_double_keyword
280 %type <Attr_val> option_int
281 %type <Integer> option_int_keyword
282 %type <Attr_val> option_string
283 %type <Integer> optional_unit
284 %type <Integer> reset_command
285 %type <Integer> rlimit_option_keyword
286 %type <Attr_val> rlimit_option
287 %type <Attr_val_fifo> rlimit_option_list
288 %type <Integer> stat
289 %type <Int_fifo> stats_list
290 %type <String_fifo> string_list
291 %type <Attr_val> system_option
292 %type <Integer> system_option_flag_keyword
293 %type <Integer> system_option_local_flag_keyword
294 %type <Attr_val_fifo> system_option_list
295 %type <Integer> t_default_or_zero
296 %type <Integer> tinker_option_keyword
297 %type <Attr_val> tinker_option
298 %type <Attr_val_fifo> tinker_option_list
299 %type <Integer> nts_string_option_keyword
300 %type <Attr_val> nts_option
301 %type <Attr_val_fifo> nts_option_list
302 %type <Attr_val> tos_option
303 %type <Integer> tos_option_dbl_keyword
304 %type <Integer> tos_option_int_keyword
305 %type <Attr_val_fifo> tos_option_list
306 %type <Integer> unpeer_keyword
307 %type <Set_var> variable_assign
308 %type <Integer> restrict_prefix
309
310 %%
311
312 /* ntp.conf
313 * Configuration File Grammar
314 * --------------------------
315 */
316
317 configuration
318 : command_list
319 ;
320
321 command_list
322 : command_list command T_EOC
323 | command T_EOC
324 | error T_EOC
325 {
326 /* I will need to incorporate much more fine grained
327 * error messages. The following should suffice for
328 * the time being.
329 */
330 struct FILE_INFO * ip_ctx = lex_current();
331 msyslog(LOG_ERR,
332 "CONFIG: syntax error in %s line %d, column %d",
333 ip_ctx->fname,
334 ip_ctx->errpos.nline,
335 ip_ctx->errpos.ncol);
336 parsing_errors++;
337 }
338 ;
339
340 command : /* NULL STATEMENT */
341 | server_command
342 | unpeer_command
343 | other_mode_command
344 | authentication_command
345 | monitoring_command
346 | access_control_command
347 | orphan_mode_command
348 | fudge_command
349 | refclock_command
350 | rlimit_command
351 | system_option_command
352 | tinker_command
353 | nts_command
354 | miscellaneous_command
355 ;
356
357 /* Server Commands
358 * ---------------
359 */
360
361 server_command
362 : client_type address option_list
363 {
364 peer_node *my_node;
365
366 my_node = create_peer_node($1, $2, $3);
367 APPEND_G_FIFO(cfgt.peers, my_node);
368 }
369 ;
370
371 client_type
372 : T_Server
373 | T_Pool
374 | T_Peer
375 ;
376
377 address
378 : ip_address
379 | address_fam T_String
380 { $$ = create_address_node($2, $1); }
381 ;
382
383 ip_address
384 : T_String
385 { $$ = create_address_node($1, AF_UNSPEC); }
386 ;
387
388 address_fam
389 : T_Ipv4_flag
390 { $$ = AF_INET; }
391 | T_Ipv6_flag
392 { $$ = AF_INET6; }
393 ;
394
395 option_list
396 : /* empty list */
397 { $$ = NULL; }
398 | option_list option
399 {
400 $$ = $1;
401 APPEND_G_FIFO($$, $2);
402 }
403 ;
404
405 option
406 : option_flag
407 | option_int
408 | option_double
409 | option_string
410 | option_boolean
411 ;
412
413 option_flag
414 : option_flag_keyword
415 { $$ = create_attr_ival(T_Flag, $1); }
416 ;
417
418 option_flag_keyword
419 : T_Burst
420 | T_Iburst
421 | T_Noselect
422 | T_Noval
423 | T_Nts
424 | T_Prefer
425 | T_True
426 ;
427
428 option_int
429 : option_int_keyword T_Integer
430 { $$ = create_attr_ival($1, $2); }
431 | option_int_keyword T_U_int
432 { $$ = create_attr_uval($1, (unsigned int)$2); }
433 | T_Stratum T_Integer
434 {
435 if ($2 >= 0 && $2 <= STRATUM_UNSPEC) {
436 $$ = create_attr_ival($1, $2);
437 } else {
438 $$ = NULL;
439 yyerror("fudge factor: stratum value out of bounds, ignored");
440 }
441 }
442 ;
443
444 option_int_keyword
445 : T_Expire
446 | T_Key
447 | T_Minpoll
448 | T_Maxpoll
449 | T_Mode
450 | T_Subtype
451 | T_Version
452 | T_Baud
453 | T_Holdover
454 ;
455
456 option_double
457 : option_double_keyword number
458 { $$ = create_attr_dval($1, $2); }
459 ;
460
461 option_boolean
462 : option_bool_keyword boolean
463 { $$ = create_attr_ival($1, $2); }
464 ;
465
466 option_string
467 : T_Refid T_String
468 { $$ = create_attr_sval($1, $2); }
469 | T_Path T_String
470 { $$ = create_attr_sval($1, $2); }
471 | T_Ppspath T_String
472 { $$ = create_attr_sval($1, $2); }
473 | T_Ask T_String
474 { $$ = create_attr_sval($1, $2); }
475 | T_Require T_String
476 { $$ = create_attr_sval($1, $2); }
477 | T_Ca T_String
478 { $$ = create_attr_sval($1, $2); }
479 | T_Cert T_String
480 { $$ = create_attr_sval($1, $2); }
481 | T_Aead T_String
482 { $$ = create_attr_sval($1, $2); }
483 ;
484
485 option_double_keyword
486 : T_Bias
487 | T_Time1
488 | T_Time2
489 ;
490
491 option_bool_keyword
492 : T_Flag1
493 | T_Flag2
494 | T_Flag3
495 | T_Flag4
496 ;
497
498
499 /* unpeer commands
500 * ---------------
501 */
502
503 unpeer_command
504 : unpeer_keyword address
505 {
506 unpeer_node *my_node;
507
508 my_node = create_unpeer_node($2);
509 if (my_node)
510 APPEND_G_FIFO(cfgt.unpeers, my_node);
511 }
512 | unpeer_keyword T_Clock T_String optional_unit
513 {
514 #ifdef REFCLOCK
515 unpeer_node *my_node;
516
517 my_node = create_unpeer_node(addr_from_typeunit($3, $4));
518 if (my_node)
519 APPEND_G_FIFO(cfgt.unpeers, my_node);
520 #else
521 yyerror("no refclock support was compiled in.");
522 #endif /* REFCLOCK */
523 }
524 ;
525 unpeer_keyword
526 : T_Unconfig
527 | T_Unpeer
528 ;
529
530
531 /* Other Modes
532 * ------------------------------------------------
533 */
534
535 other_mode_command
536 : T_Mdnstries T_Integer
537 { cfgt.mdnstries = $2; }
538 ;
539
540
541
542 /* Authentication Commands
543 * -----------------------
544 */
545
546 authentication_command
547 : T_ControlKey T_Integer
548 { cfgt.auth.control_key = $2; }
549 | T_Keys T_String
550 { cfgt.auth.keys = $2; }
551 | T_Requestkey T_Integer
552 {
553 msyslog(LOG_WARNING,
554 "CONFIG: requestkey is a no-op because "
555 "ntpdc has been removed.");
556 }
557 | T_Trustedkey integer_list_range
558 { CONCAT_G_FIFOS(cfgt.auth.trusted_key_list, $2); }
559 | T_NtpSignDsocket T_String
560 { cfgt.auth.ntp_signd_socket = $2; }
561 ;
562
563
564 /* Orphan Mode Commands
565 * --------------------
566 */
567
568 orphan_mode_command
569 : T_Tos tos_option_list
570 { CONCAT_G_FIFOS(cfgt.orphan_cmds, $2); }
571 ;
572
573 tos_option_list
574 : tos_option_list tos_option
575 {
576 $$ = $1;
577 APPEND_G_FIFO($$, $2);
578 }
579 | tos_option
580 {
581 $$ = NULL;
582 APPEND_G_FIFO($$, $1);
583 }
584 ;
585
586 tos_option
587 : tos_option_int_keyword T_Integer
588 { $$ = create_attr_dval($1, (double)$2); }
589 | tos_option_dbl_keyword number
590 { $$ = create_attr_dval($1, $2); }
591 | T_Cohort boolean
592 { $$ = create_attr_dval($1, (double)$2); }
593 ;
594
595 tos_option_int_keyword
596 : T_Ceiling
597 | T_Floor
598 | T_Orphan
599 | T_Orphanwait
600 | T_Minsane
601 ;
602
603 tos_option_dbl_keyword
604 : T_Mindist
605 | T_Maxdisp
606 | T_Maxdist
607 | T_Minclock
608 | T_Maxclock
609 ;
610
611
612 /* Monitoring Commands
613 * -------------------
614 */
615
616 monitoring_command
617 : T_Statistics stats_list
618 { CONCAT_G_FIFOS(cfgt.stats_list, $2); }
619 | T_Statsdir T_String
620 {
621 if (lex_from_file()) {
622 cfgt.stats_dir = $2;
623 } else {
624 YYFREE($2);
625 yyerror("statsdir remote configuration ignored");
626 }
627 }
628 | T_Filegen stat filegen_option_list
629 {
630 filegen_node *fgn;
631
632 fgn = create_filegen_node($2, $3);
633 APPEND_G_FIFO(cfgt.filegen_opts, fgn);
634 }
635 ;
636
637 stats_list
638 : stats_list stat
639 {
640 $$ = $1;
641 APPEND_G_FIFO($$, create_int_node($2));
642 }
643 | stat
644 {
645 $$ = NULL;
646 APPEND_G_FIFO($$, create_int_node($1));
647 }
648 ;
649
650 stat
651 : T_Clockstats
652 | T_Loopstats
653 | T_Peerstats
654 | T_Rawstats
655 | T_Sysstats
656 | T_Protostats
657 | T_Timingstats
658 | T_Usestats
659 ;
660
661 filegen_option_list
662 : /* empty list */
663 { $$ = NULL; }
664 | filegen_option_list filegen_option
665 {
666 $$ = $1;
667 APPEND_G_FIFO($$, $2);
668 }
669 ;
670
671 filegen_option
672 : T_File T_String
673 {
674 if (lex_from_file()) {
675 $$ = create_attr_sval($1, $2);
676 } else {
677 $$ = NULL;
678 YYFREE($2);
679 yyerror("filegen file remote config ignored");
680 }
681 }
682 | T_Type filegen_type
683 {
684 if (lex_from_file()) {
685 $$ = create_attr_ival($1, $2);
686 } else {
687 $$ = NULL;
688 yyerror("filegen type remote config ignored");
689 }
690 }
691 | link_nolink
692 {
693 const char *err;
694
695 if (lex_from_file()) {
696 $$ = create_attr_ival(T_Flag, $1);
697 } else {
698 $$ = NULL;
699 if (T_Link == $1)
700 err = "filegen link remote config ignored";
701 else
702 err = "filegen nolink remote config ignored";
703 yyerror(err);
704 }
705 }
706 | enable_disable
707 { $$ = create_attr_ival(T_Flag, $1); }
708 ;
709
710 link_nolink
711 : T_Link
712 | T_Nolink
713 ;
714
715 enable_disable
716 : T_Enable
717 | T_Disable
718 ;
719
720 filegen_type
721 : T_None
722 | T_Pid
723 | T_Day
724 | T_Week
725 | T_Month
726 | T_Year
727 | T_Age
728 ;
729
730
731 /* Access Control Commands
732 * -----------------------
733 */
734
735 restrict_prefix
736 : T_Restrict
737 | T_Unrestrict
738 ;
739
740 access_control_command
741 : T_Limit limit_option_list
742 {
743 CONCAT_G_FIFOS(cfgt.limit_opts, $2);
744 }
745 | T_Mru mru_option_list
746 {
747 CONCAT_G_FIFOS(cfgt.mru_opts, $2);
748 }
749 | restrict_prefix address ac_flag_list
750 {
751 restrict_node *rn;
752
753 rn = create_restrict_node($1, $2, NULL, $3,
754 lex_current()->curpos.nline);
755 APPEND_G_FIFO(cfgt.restrict_opts, rn);
756 }
757 | restrict_prefix ip_address T_Mask ip_address ac_flag_list
758 {
759 restrict_node *rn;
760
761 rn = create_restrict_node($1, $2, $4, $5,
762 lex_current()->curpos.nline);
763 APPEND_G_FIFO(cfgt.restrict_opts, rn);
764 }
765 | restrict_prefix T_Default ac_flag_list
766 {
767 restrict_node *rn;
768
769 rn = create_restrict_node($1, NULL, NULL, $3,
770 lex_current()->curpos.nline);
771 APPEND_G_FIFO(cfgt.restrict_opts, rn);
772 }
773 | restrict_prefix T_Ipv4_flag T_Default ac_flag_list
774 {
775 restrict_node *rn;
776
777 rn = create_restrict_node($1,
778 create_address_node(
779 estrdup("0.0.0.0"),
780 AF_INET),
781 create_address_node(
782 estrdup("0.0.0.0"),
783 AF_INET),
784 $4,
785 lex_current()->curpos.nline);
786 APPEND_G_FIFO(cfgt.restrict_opts, rn);
787 }
788 | restrict_prefix T_Ipv6_flag T_Default ac_flag_list
789 {
790 restrict_node *rn;
791
792 rn = create_restrict_node($1,
793 create_address_node(
794 estrdup("::"),
795 AF_INET6),
796 create_address_node(
797 estrdup("::"),
798 AF_INET6),
799 $4,
800 lex_current()->curpos.nline);
801 APPEND_G_FIFO(cfgt.restrict_opts, rn);
802 }
803 | restrict_prefix T_Source ac_flag_list
804 {
805 restrict_node * rn;
806
807 APPEND_G_FIFO($3, create_int_node($2));
808 rn = create_restrict_node(
809 $1, NULL, NULL, $3, lex_current()->curpos.nline);
810 APPEND_G_FIFO(cfgt.restrict_opts, rn);
811 }
812 ;
813
814 ac_flag_list
815 : /* empty list is allowed */
816 { $$ = NULL; }
817 | ac_flag_list access_control_flag
818 {
819 $$ = $1;
820 APPEND_G_FIFO($$, create_int_node($2));
821 }
822 ;
823
824 access_control_flag
825 : T_Flake
826 | T_Ignore
827 | T_Kod
828 | T_Mssntp
829 | T_Limited
830 | T_Nomodify
831 | T_Nomrulist
832 | T_Nopeer
833 | T_Noquery
834 | T_Noserve
835 | T_Notrap
836 | T_Notrust
837 | T_Ntpport
838 | T_Version
839 ;
840
841 limit_option_list
842 : limit_option_list limit_option
843 {
844 $$ = $1;
845 APPEND_G_FIFO($$, $2);
846 }
847 | limit_option
848 {
849 $$ = NULL;
850 APPEND_G_FIFO($$, $1);
851 }
852 ;
853
854 limit_option
855 : limit_option_keyword number
856 { $$ = create_attr_dval($1, $2); }
857 ;
858
859 limit_option_keyword
860 : T_Average
861 | T_Burst
862 | T_Kod
863 ;
864
865 mru_option_list
866 : mru_option_list mru_option
867 {
868 $$ = $1;
869 APPEND_G_FIFO($$, $2);
870 }
871 | mru_option
872 {
873 $$ = NULL;
874 APPEND_G_FIFO($$, $1);
875 }
876 ;
877
878 mru_option
879 : mru_option_keyword T_Integer
880 { $$ = create_attr_ival($1, $2); }
881 ;
882
883 mru_option_keyword
884 : T_Incalloc
885 | T_Incmem
886 | T_Initalloc
887 | T_Initmem
888 | T_Maxage
889 | T_Minage
890 | T_Maxdepth
891 | T_Maxmem
892 | T_Mindepth
893 ;
894
895 /* Fudge Commands
896 * --------------
897 */
898
899 fudge_command
900 : T_Fudge address fudge_factor_list
901 {
902 addr_opts_node *aon;
903
904 aon = create_addr_opts_node($2, $3);
905 APPEND_G_FIFO(cfgt.fudge, aon);
906 }
907 ;
908
909 fudge_factor_list
910 : fudge_factor_list fudge_factor
911 {
912 $$ = $1;
913 APPEND_G_FIFO($$, $2);
914 }
915 | fudge_factor
916 {
917 $$ = NULL;
918 APPEND_G_FIFO($$, $1);
919 }
920 ;
921
922 fudge_factor
923 : fudge_factor_dbl_keyword number
924 { $$ = create_attr_dval($1, $2); }
925 | fudge_factor_bool_keyword boolean
926 { $$ = create_attr_ival($1, $2); }
927 | T_Stratum T_Integer
928 {
929 if ($2 >= 0 && $2 <= 16) {
930 $$ = create_attr_ival($1, $2);
931 } else {
932 $$ = NULL;
933 yyerror("fudge factor: stratum value not in [0..16], ignored");
934 }
935 }
936 | T_Refid T_String
937 { $$ = create_attr_sval($1, $2); }
938 ;
939
940 fudge_factor_dbl_keyword
941 : T_Time1
942 | T_Time2
943 ;
944
945 fudge_factor_bool_keyword
946 : T_Flag1
947 | T_Flag2
948 | T_Flag3
949 | T_Flag4
950 ;
951
952 /* Refclock Command
953 * ----------------
954 */
955
956 refclock_command
957 : T_Refclock T_String optional_unit option_list
958 {
959 #ifdef REFCLOCK
960 address_node *fakeaddr = addr_from_typeunit($2, $3);
961 peer_node *my_node = create_peer_node(T_Server, fakeaddr, $4);
962 APPEND_G_FIFO(cfgt.peers, my_node);
963 #endif /* REFCLOCK */
964 }
965 ;
966
967 optional_unit
968 :
969 {$$ = 0;}
970 |
971 T_Unit T_Integer
972 {$$ = $2;}
973 ;
974
975
976 /* rlimit Commands
977 * ---------------
978 */
979
980 rlimit_command
981 : T_Rlimit rlimit_option_list
982 { CONCAT_G_FIFOS(cfgt.rlimit, $2); }
983 ;
984
985 rlimit_option_list
986 : rlimit_option_list rlimit_option
987 {
988 $$ = $1;
989 APPEND_G_FIFO($$, $2);
990 }
991 | rlimit_option
992 {
993 $$ = NULL;
994 APPEND_G_FIFO($$, $1);
995 }
996 ;
997
998 rlimit_option
999 : rlimit_option_keyword T_Integer
1000 { $$ = create_attr_ival($1, $2); }
1001 ;
1002
1003 rlimit_option_keyword
1004 : T_Memlock
1005 | T_Stacksize
1006 | T_Filenum
1007 ;
1008
1009
1010 /* Command for System Options
1011 * --------------------------
1012 */
1013
1014 system_option_command
1015 : T_Enable system_option_list
1016 { CONCAT_G_FIFOS(cfgt.enable_opts, $2); }
1017 | T_Disable system_option_list
1018 { CONCAT_G_FIFOS(cfgt.disable_opts, $2); }
1019 ;
1020
1021 system_option_list
1022 : system_option_list system_option
1023 {
1024 $$ = $1;
1025 APPEND_G_FIFO($$, $2);
1026 }
1027 | system_option
1028 {
1029 $$ = NULL;
1030 APPEND_G_FIFO($$, $1);
1031 }
1032 ;
1033
1034 system_option
1035 : system_option_flag_keyword
1036 { $$ = create_attr_ival(T_Flag, $1); }
1037 | system_option_local_flag_keyword
1038 {
1039 if (lex_from_file()) {
1040 $$ = create_attr_ival(T_Flag, $1);
1041 } else {
1042 char err_str[128];
1043
1044 $$ = NULL;
1045 snprintf(err_str, sizeof(err_str),
1046 "enable/disable %s remote configuration ignored",
1047 keyword($1));
1048 yyerror(err_str);
1049 }
1050 }
1051 ;
1052
1053 system_option_flag_keyword
1054 : T_Calibrate
1055 | T_Kernel
1056 | T_Monitor
1057 | T_Ntp
1058 ;
1059
1060 system_option_local_flag_keyword
1061 : T_Stats
1062 ;
1063
1064 /* Tinker Commands
1065 * ---------------
1066 */
1067
1068 tinker_command
1069 : T_Tinker tinker_option_list
1070 { CONCAT_G_FIFOS(cfgt.tinker, $2); }
1071 ;
1072
1073 tinker_option_list
1074 : tinker_option_list tinker_option
1075 {
1076 $$ = $1;
1077 APPEND_G_FIFO($$, $2);
1078 }
1079 | tinker_option
1080 {
1081 $$ = NULL;
1082 APPEND_G_FIFO($$, $1);
1083 }
1084 ;
1085
1086 tinker_option
1087 : tinker_option_keyword number
1088 { $$ = create_attr_dval($1, $2); }
1089 ;
1090
1091 tinker_option_keyword
1092 : T_Allan
1093 | T_Dispersion
1094 | T_Freq
1095 | T_Huffpuff
1096 | T_Panic
1097 | T_Step
1098 | T_Stepback
1099 | T_Stepfwd
1100 | T_Stepout
1101 | T_Tick
1102 ;
1103
1104
1105 /* NTS Commands
1106 * ---------------
1107 */
1108
1109 nts_command
1110 : T_Nts nts_option_list
1111 { CONCAT_G_FIFOS(cfgt.nts, $2); }
1112 ;
1113
1114 nts_option_list
1115 : nts_option_list nts_option
1116 {
1117 $$ = $1;
1118 APPEND_G_FIFO($$, $2);
1119 }
1120 | nts_option
1121 {
1122 $$ = NULL;
1123 APPEND_G_FIFO($$, $1);
1124 }
1125 ;
1126
1127 nts_option
1128 : nts_string_option_keyword T_String
1129 { $$ = create_attr_sval($1, $2); }
1130 | T_Disable
1131 { $$ = create_attr_ival($1, 0); }
1132 | T_Enable
1133 { $$ = create_attr_ival($1, 1); }
1134 ;
1135
1136 ;
1137
1138 nts_string_option_keyword
1139 : T_Aead
1140 | T_Ca
1141 | T_Cert
1142 | T_Cookie
1143 | T_Key
1144 | T_Tlsciphers
1145 | T_Tlsciphersuites
1146 | T_Maxtls
1147 | T_Mintls
1148
1149
1150 /* Miscellaneous Commands
1151 * ----------------------
1152 */
1153
1154 miscellaneous_command
1155 : interface_command
1156 | reset_command
1157 | misc_cmd_dbl_keyword number
1158 {
1159 attr_val *av;
1160
1161 av = create_attr_dval($1, $2);
1162 APPEND_G_FIFO(cfgt.vars, av);
1163 }
1164 | misc_cmd_int_keyword T_Integer
1165 {
1166 attr_val *av;
1167
1168 av = create_attr_ival($1, $2);
1169 APPEND_G_FIFO(cfgt.vars, av);
1170 }
1171 | misc_cmd_str_keyword T_String
1172 {
1173 attr_val *av;
1174
1175 av = create_attr_sval($1, $2);
1176 APPEND_G_FIFO(cfgt.vars, av);
1177 }
1178 | misc_cmd_str_lcl_keyword T_String
1179 {
1180 char error_text[64];
1181 attr_val *av;
1182
1183 if (lex_from_file()) {
1184 av = create_attr_sval($1, $2);
1185 APPEND_G_FIFO(cfgt.vars, av);
1186 } else {
1187 YYFREE($2);
1188 snprintf(error_text, sizeof(error_text),
1189 "%s remote config ignored",
1190 keyword($1));
1191 yyerror(error_text);
1192 }
1193 }
1194 | T_Includefile T_String command
1195 {
1196 if (!lex_from_file()) {
1197 YYFREE($2); /* avoid leak */
1198 yyerror("remote includefile ignored");
1199 break;
1200 }
1201 if (lex_level() > MAXINCLUDELEVEL) {
1202 fprintf(stderr, "getconfig(): Maximum include file level exceeded.\n");
1203 msyslog(LOG_ERR, "CONFIG: Maximum include file level exceeded.");
1204 } else {
1205 const char * path = $2;
1206 if (!lex_push_file(path)) {
1207 fprintf(stderr, "getconfig(): Couldn't open <%s>\n", path);
1208 msyslog(LOG_ERR, "CONFIG: Couldn't open <%s>", path);
1209 }
1210 }
1211 YYFREE($2); /* avoid leak */
1212 }
1213 | T_End
1214 { lex_flush_stack(); }
1215 | T_Driftfile drift_parm
1216 { /* see drift_parm below for actions */ }
1217 | T_Logconfig log_config_list
1218 { CONCAT_G_FIFOS(cfgt.logconfig, $2); }
1219 | T_Phone string_list
1220 { CONCAT_G_FIFOS(cfgt.phone, $2); }
1221 | T_Setvar variable_assign
1222 { APPEND_G_FIFO(cfgt.setvar, $2); }
1223 ;
1224
1225 misc_cmd_dbl_keyword
1226 : T_Nonvolatile
1227 | T_Tick
1228 ;
1229
1230 misc_cmd_int_keyword
1231 : T_Dscp
1232 ;
1233
1234 misc_cmd_int_keyword
1235 : T_Leapsmearinterval
1236 {
1237 #ifndef ENABLE_LEAP_SMEAR
1238 yyerror("Built without LEAP_SMEAR support.");
1239 #endif
1240 }
1241 ;
1242
1243 misc_cmd_str_keyword
1244 : T_Leapfile
1245 ;
1246
1247 misc_cmd_str_lcl_keyword
1248 : T_Logfile
1249 | T_Pidfile
1250 | T_Saveconfigdir
1251 ;
1252
1253 drift_parm
1254 : T_String
1255 {
1256 if (lex_from_file()) {
1257 attr_val *av;
1258 av = create_attr_sval(T_Driftfile, $1);
1259 APPEND_G_FIFO(cfgt.vars, av);
1260 } else {
1261 YYFREE($1);
1262 yyerror("driftfile remote configuration ignored");
1263 }
1264 }
1265 | T_String T_Double
1266 {
1267 attr_val *av;
1268
1269 av = create_attr_sval(T_Driftfile, $1);
1270 APPEND_G_FIFO(cfgt.vars, av);
1271 av = create_attr_dval(T_WanderThreshold, $2);
1272 APPEND_G_FIFO(cfgt.vars, av);
1273 }
1274 | /* Null driftfile, indicated by empty string "" */
1275 {
1276 attr_val *av;
1277
1278 av = create_attr_sval(T_Driftfile, estrdup(""));
1279 APPEND_G_FIFO(cfgt.vars, av);
1280 }
1281 ;
1282
1283 variable_assign
1284 : T_String '=' T_String t_default_or_zero
1285 { $$ = create_setvar_node($1, $3, $4); }
1286 ;
1287
1288 t_default_or_zero
1289 : T_Default
1290 | /* empty, no "default" modifier */
1291 { $$ = 0; }
1292 ;
1293
1294 log_config_list
1295 : log_config_list log_config_command
1296 {
1297 $$ = $1;
1298 APPEND_G_FIFO($$, $2);
1299 }
1300 | log_config_command
1301 {
1302 $$ = NULL;
1303 APPEND_G_FIFO($$, $1);
1304 }
1305 ;
1306
1307 log_config_command
1308 : T_String
1309 {
1310 char prefix;
1311 char * type;
1312
1313 switch ($1[0]) {
1314
1315 case '+':
1316 case '-':
1317 case '=':
1318 prefix = $1[0];
1319 type = $1 + 1;
1320 break;
1321
1322 default:
1323 prefix = '=';
1324 type = $1;
1325 }
1326
1327 $$ = create_attr_sval(prefix, estrdup(type));
1328 YYFREE($1);
1329 }
1330 ;
1331
1332 interface_command
1333 : interface_nic nic_rule_action nic_rule_class
1334 {
1335 nic_rule_node *nrn;
1336
1337 nrn = create_nic_rule_node($3, NULL, $2);
1338 APPEND_G_FIFO(cfgt.nic_rules, nrn);
1339 }
1340 | interface_nic nic_rule_action T_String
1341 {
1342 nic_rule_node *nrn;
1343
1344 nrn = create_nic_rule_node(0, $3, $2);
1345 APPEND_G_FIFO(cfgt.nic_rules, nrn);
1346 }
1347 ;
1348
1349 interface_nic
1350 : T_Interface
1351 | T_Nic
1352 ;
1353
1354 nic_rule_class
1355 : T_All
1356 | T_Ipv4
1357 | T_Ipv6
1358 | T_Wildcard
1359 ;
1360
1361 nic_rule_action
1362 : T_Listen
1363 | T_Ignore
1364 | T_Drop
1365 ;
1366
1367 reset_command
1368 : T_Reset counter_set_list
1369 { CONCAT_G_FIFOS(cfgt.reset_counters, $2); }
1370 ;
1371
1372 counter_set_list
1373 : counter_set_list counter_set_keyword
1374 {
1375 $$ = $1;
1376 APPEND_G_FIFO($$, create_int_node($2));
1377 }
1378 | counter_set_keyword
1379 {
1380 $$ = NULL;
1381 APPEND_G_FIFO($$, create_int_node($1));
1382 }
1383 ;
1384
1385 counter_set_keyword
1386 : T_Allpeers
1387 | T_Auth
1388 | T_Ctl
1389 | T_Io
1390 | T_Mem
1391 | T_Sys
1392 | T_Timer
1393 ;
1394
1395
1396
1397 /* Miscellaneous Rules
1398 * -------------------
1399 */
1400
1401 integer_list_range
1402 : integer_list_range integer_list_range_elt
1403 {
1404 $$ = $1;
1405 APPEND_G_FIFO($$, $2);
1406 }
1407 | integer_list_range_elt
1408 {
1409 $$ = NULL;
1410 APPEND_G_FIFO($$, $1);
1411 }
1412 ;
1413
1414 integer_list_range_elt
1415 : T_Integer
1416 { $$ = create_attr_ival('i', $1); }
1417 | integer_range
1418 ;
1419
1420 integer_range
1421 : '(' T_Integer T_Ellipsis T_Integer ')'
1422 { $$ = create_attr_rangeval('-', $2, $4); }
1423 ;
1424
1425 string_list
1426 : string_list T_String
1427 {
1428 $$ = $1;
1429 APPEND_G_FIFO($$, create_string_node($2));
1430 }
1431 | T_String
1432 {
1433 $$ = NULL;
1434 APPEND_G_FIFO($$, create_string_node($1));
1435 }
1436 ;
1437
1438 boolean
1439 : T_Integer
1440 {
1441 if ($1 != 0 && $1 != 1) {
1442 yyerror("Integer value is not boolean (0 or 1). Assuming 1");
1443 $$ = 1;
1444 } else {
1445 $$ = $1;
1446 }
1447 }
1448 | T_True { $$ = 1; }
1449 | T_False { $$ = 0; }
1450 ;
1451
1452 number
1453 : T_Integer { $$ = (double)$1; }
1454 | T_Double
1455 ;
1456
1457
1458 %%
1459
1460 #ifdef REFCLOCK
1461 address_node *
1462 addr_from_typeunit(char *type, int unit)
1463 {
1464 char addrbuf[1025]; /* NI_MAXHOSTS on Linux */
1465 int dtype;
1466
1467 for (dtype = 1; dtype < (int)num_refclock_conf; dtype++)
1468 if (refclock_conf[dtype]->basename != NULL && strcasecmp(refclock_conf[dtype]->basename, type) == 0)
1469 goto foundit;
1470 msyslog(LOG_ERR, "CONFIG: Unknown driver name %s", type);
1471 exit(1);
1472 foundit:
1473 snprintf(addrbuf, sizeof(addrbuf), "127.127.%d.%d", dtype, unit);
1474 return create_address_node(estrdup(addrbuf), AF_INET);
1475 }
1476 #endif /* REFCLOCK */
1477
1478 void
yyerror(const char * msg)1479 yyerror(
1480 const char *msg
1481 )
1482 {
1483 int retval;
1484 struct FILE_INFO * ip_ctx;
1485
1486 ip_ctx = lex_current();
1487 ip_ctx->errpos = ip_ctx->tokpos;
1488
1489 msyslog(LOG_ERR, "CONFIG: line %d column %d %s",
1490 ip_ctx->errpos.nline, ip_ctx->errpos.ncol, msg);
1491 if (lex_from_file()) {
1492 /* all is good, so far */
1493 return;
1494 }
1495 /* Uh, oh, got an error */
1496
1497 /* Increment the number of errors */
1498 ++remote_config.no_errors;
1499
1500 /* Save the error message in the correct buffer */
1501 if ((MAXLINE - 10) < remote_config.err_pos) {
1502 /* err_msg already full, ignore this */
1503 return;
1504 }
1505 retval = snprintf(remote_config.err_msg + remote_config.err_pos,
1506 (size_t)(MAXLINE - remote_config.err_pos),
1507 "column %d %s", ip_ctx->errpos.ncol, msg);
1508
1509 /* Increment the value of err_pos */
1510 if (retval > 0) {
1511 /* careful, retval is not bytes written, it is
1512 * bytes that would have been written if space had
1513 * been available */
1514 remote_config.err_pos += retval;
1515 if (MAXLINE < remote_config.err_pos) {
1516 /* err_msg overflowed! */
1517 remote_config.err_pos = MAXLINE;
1518 }
1519 }
1520 }
1521
1522
1523 /*
1524 * token_name - convert T_ token integers to text
1525 * example: token_name(T_Server) returns "T_Server"
1526 */
1527 const char *
token_name(int token)1528 token_name(
1529 int token
1530 )
1531 {
1532 return yytname[YYTRANSLATE(token)];
1533 }
1534
1535
1536 /* Initial Testing function -- ignore */
1537 #if 0
1538 int main(int argc, char *argv[])
1539 {
1540 ip_file = FOPEN(argv[1], "r");
1541 if (!ip_file)
1542 fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
1543 yyparse();
1544 return 0;
1545 }
1546 #endif
1547
1548