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