xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntp_parser.y (revision 7788a0781fe6ff2cce37368b4578a7ade0850cb1)
1 /*	$NetBSD: ntp_parser.y,v 1.5 2012/02/01 07:46:22 kardel Exp $	*/
2 
3 /* ntp_parser.y
4  *
5  * The parser for the NTP configuration file.
6  *
7  * Written By:	Sachin Kamboj
8  *		University of Delaware
9  *		Newark, DE 19711
10  * Copyright (c) 2006
11  */
12 
13 %{
14   #ifdef HAVE_CONFIG_H
15   # include <config.h>
16   #endif
17 
18   #include "ntp.h"
19   #include "ntpd.h"
20   #include "ntp_machine.h"
21   #include "ntp_stdlib.h"
22   #include "ntp_filegen.h"
23   #include "ntp_data_structures.h"
24   #include "ntp_scanner.h"
25   #include "ntp_config.h"
26   #include "ntp_crypto.h"
27 
28   #include "ntpsim.h"		/* HMS: Do we really want this all the time? */
29 				/* SK: It might be a good idea to always
30 				   include the simulator code. That way
31 				   someone can use the same configuration file
32 				   for both the simulator and the daemon
33 				*/
34 
35 
36   struct FILE_INFO *ip_file;   /* Pointer to the configuration file stream */
37 
38   #define YYMALLOC	emalloc
39   #define YYFREE	free
40   #define YYERROR_VERBOSE
41   #define YYMAXDEPTH	1000   /* stop the madness sooner */
42   void yyerror(const char *msg);
43   extern int input_from_file;  /* 0=input from ntpq :config */
44 %}
45 
46 /*
47  * Enable generation of token names array even without YYDEBUG.
48  * We access via token_name() defined below.
49  */
50 %token-table
51 
52 %union {
53     char   *String;
54     double  Double;
55     int     Integer;
56     void   *VoidPtr;
57     queue  *Queue;
58     struct attr_val *Attr_val;
59     struct address_node *Address_node;
60     struct setvar_node *Set_var;
61 
62     /* Simulation types */
63     server_info *Sim_server;
64     script_info *Sim_script;
65 }
66 
67 /* TERMINALS (do not appear left of colon) */
68 %token	<Integer>	T_Age
69 %token	<Integer>	T_All
70 %token	<Integer>	T_Allan
71 %token	<Integer>	T_Auth
72 %token	<Integer>	T_Autokey
73 %token	<Integer>	T_Automax
74 %token	<Integer>	T_Average
75 %token	<Integer>	T_Bclient
76 %token	<Integer>	T_Beacon
77 %token	<Integer>	T_Bias
78 %token	<Integer>	T_Broadcast
79 %token	<Integer>	T_Broadcastclient
80 %token	<Integer>	T_Broadcastdelay
81 %token	<Integer>	T_Burst
82 %token	<Integer>	T_Calibrate
83 %token	<Integer>	T_Calldelay
84 %token	<Integer>	T_Ceiling
85 %token	<Integer>	T_Clockstats
86 %token	<Integer>	T_Cohort
87 %token	<Integer>	T_ControlKey
88 %token	<Integer>	T_Crypto
89 %token	<Integer>	T_Cryptostats
90 %token	<Integer>	T_Day
91 %token	<Integer>	T_Default
92 %token	<Integer>	T_Digest
93 %token	<Integer>	T_Disable
94 %token	<Integer>	T_Discard
95 %token	<Integer>	T_Dispersion
96 %token	<Double>	T_Double
97 %token	<Integer>	T_Driftfile
98 %token	<Integer>	T_Drop
99 %token	<Integer>	T_Ellipsis	/* "..." not "ellipsis" */
100 %token	<Integer>	T_Enable
101 %token	<Integer>	T_End
102 %token	<Integer>	T_False
103 %token	<Integer>	T_File
104 %token	<Integer>	T_Filegen
105 %token	<Integer>	T_Flag1
106 %token	<Integer>	T_Flag2
107 %token	<Integer>	T_Flag3
108 %token	<Integer>	T_Flag4
109 %token	<Integer>	T_Flake
110 %token	<Integer>	T_Floor
111 %token	<Integer>	T_Freq
112 %token	<Integer>	T_Fudge
113 %token	<Integer>	T_Host
114 %token	<Integer>	T_Huffpuff
115 %token	<Integer>	T_Iburst
116 %token	<Integer>	T_Ident
117 %token	<Integer>	T_Ignore
118 %token	<Integer>	T_Includefile
119 %token	<Integer>	T_Integer
120 %token	<Integer>	T_Interface
121 %token	<Integer>	T_Ipv4
122 %token	<Integer>	T_Ipv4_flag
123 %token	<Integer>	T_Ipv6
124 %token	<Integer>	T_Ipv6_flag
125 %token	<Integer>	T_Kernel
126 %token	<Integer>	T_Key
127 %token	<Integer>	T_Keys
128 %token	<Integer>	T_Keysdir
129 %token	<Integer>	T_Kod
130 %token	<Integer>	T_Mssntp
131 %token	<Integer>	T_Leapfile
132 %token	<Integer>	T_Limited
133 %token	<Integer>	T_Link
134 %token	<Integer>	T_Listen
135 %token	<Integer>	T_Logconfig
136 %token	<Integer>	T_Logfile
137 %token	<Integer>	T_Loopstats
138 %token	<Integer>	T_Lowpriotrap
139 %token	<Integer>	T_Manycastclient
140 %token	<Integer>	T_Manycastserver
141 %token	<Integer>	T_Mask
142 %token	<Integer>	T_Maxclock
143 %token	<Integer>	T_Maxdist
144 %token	<Integer>	T_Maxpoll
145 %token	<Integer>	T_Mdnstries
146 %token	<Integer>	T_Minclock
147 %token	<Integer>	T_Mindist
148 %token	<Integer>	T_Minimum
149 %token	<Integer>	T_Minpoll
150 %token	<Integer>	T_Minsane
151 %token	<Integer>	T_Mode
152 %token	<Integer>	T_Monitor
153 %token	<Integer>	T_Month
154 %token	<Integer>	T_Multicastclient
155 %token	<Integer>	T_Nic
156 %token	<Integer>	T_Nolink
157 %token	<Integer>	T_Nomodify
158 %token	<Integer>	T_None
159 %token	<Integer>	T_Nopeer
160 %token	<Integer>	T_Noquery
161 %token	<Integer>	T_Noselect
162 %token	<Integer>	T_Noserve
163 %token	<Integer>	T_Notrap
164 %token	<Integer>	T_Notrust
165 %token	<Integer>	T_Ntp
166 %token	<Integer>	T_Ntpport
167 %token	<Integer>	T_NtpSignDsocket
168 %token	<Integer>	T_Orphan
169 %token	<Integer>	T_Panic
170 %token	<Integer>	T_Peer
171 %token	<Integer>	T_Peerstats
172 %token	<Integer>	T_Phone
173 %token	<Integer>	T_Pid
174 %token	<Integer>	T_Pidfile
175 %token	<Integer>	T_Pool
176 %token	<Integer>	T_Port
177 %token	<Integer>	T_Preempt
178 %token	<Integer>	T_Prefer
179 %token	<Integer>	T_Protostats
180 %token	<Integer>	T_Pw
181 %token	<Integer>	T_Qos
182 %token	<Integer>	T_Randfile
183 %token	<Integer>	T_Rawstats
184 %token	<Integer>	T_Refid
185 %token	<Integer>	T_Requestkey
186 %token	<Integer>	T_Restrict
187 %token	<Integer>	T_Revoke
188 %token	<Integer>	T_Saveconfigdir
189 %token	<Integer>	T_Server
190 %token	<Integer>	T_Setvar
191 %token	<Integer>	T_Sign
192 %token	<Integer>	T_Statistics
193 %token	<Integer>	T_Stats
194 %token	<Integer>	T_Statsdir
195 %token	<Integer>	T_Step
196 %token	<Integer>	T_Stepout
197 %token	<Integer>	T_Stratum
198 %token	<String>	T_String
199 %token	<Integer>	T_Sysstats
200 %token	<Integer>	T_Tick
201 %token	<Integer>	T_Time1
202 %token	<Integer>	T_Time2
203 %token	<Integer>	T_Timingstats
204 %token	<Integer>	T_Tinker
205 %token	<Integer>	T_Tos
206 %token	<Integer>	T_Trap
207 %token	<Integer>	T_True
208 %token	<Integer>	T_Trustedkey
209 %token	<Integer>	T_Ttl
210 %token	<Integer>	T_Type
211 %token	<Integer>	T_Unconfig
212 %token	<Integer>	T_Unpeer
213 %token	<Integer>	T_Version
214 %token	<Integer>	T_WanderThreshold	/* Not a token */
215 %token	<Integer>	T_Week
216 %token	<Integer>	T_Wildcard
217 %token	<Integer>	T_Xleave
218 %token	<Integer>	T_Year
219 %token	<Integer>	T_Flag		/* Not an actual token */
220 %token	<Integer>	T_Void		/* Not an actual token */
221 %token	<Integer>	T_EOC
222 
223 
224 /* NTP Simulator Tokens */
225 %token	<Integer>	T_Simulate
226 %token	<Integer>	T_Beep_Delay
227 %token	<Integer>	T_Sim_Duration
228 %token	<Integer>	T_Server_Offset
229 %token	<Integer>	T_Duration
230 %token	<Integer>	T_Freq_Offset
231 %token	<Integer>	T_Wander
232 %token	<Integer>	T_Jitter
233 %token	<Integer>	T_Prop_Delay
234 %token	<Integer>	T_Proc_Delay
235 
236 
237 
238 /*** NON-TERMINALS ***/
239 %type	<Integer>	access_control_flag
240 %type	<Queue>		ac_flag_list
241 %type	<Address_node>	address
242 %type	<Integer>	address_fam
243 %type	<Queue>		address_list
244 %type	<Integer>	boolean
245 %type	<Integer>	client_type
246 %type	<Attr_val>	crypto_command
247 %type	<Queue>		crypto_command_list
248 %type	<Integer>	crypto_str_keyword
249 %type	<Attr_val>	discard_option
250 %type	<Integer>	discard_option_keyword
251 %type	<Queue>		discard_option_list
252 %type	<Integer>	enable_disable
253 %type	<Attr_val>	filegen_option
254 %type	<Queue>		filegen_option_list
255 %type	<Integer>	filegen_type
256 %type	<Attr_val>	fudge_factor
257 %type	<Integer>	fudge_factor_bool_keyword
258 %type	<Integer>	fudge_factor_dbl_keyword
259 %type	<Queue>		fudge_factor_list
260 %type	<Queue>		integer_list
261 %type	<Queue>		integer_list_range
262 %type	<Attr_val>	integer_list_range_elt
263 %type	<Attr_val>	integer_range
264 %type	<Integer>	nic_rule_action
265 %type	<Integer>	interface_command
266 %type	<Integer>	interface_nic
267 %type	<Address_node>	ip_address
268 %type	<Integer>	link_nolink
269 %type	<Attr_val>	log_config_command
270 %type	<Queue>		log_config_list
271 %type	<Integer>	misc_cmd_dbl_keyword
272 %type	<Integer>	misc_cmd_str_keyword
273 %type	<Integer>	misc_cmd_str_lcl_keyword
274 %type	<Integer>	nic_rule_class
275 %type	<Double>	number
276 %type	<Attr_val>	option
277 %type	<Attr_val>	option_flag
278 %type	<Integer>	option_flag_keyword
279 %type	<Queue>		option_list
280 %type	<Attr_val>	option_int
281 %type	<Integer>	option_int_keyword
282 %type	<Integer>	stat
283 %type	<Queue>		stats_list
284 %type	<Queue>		string_list
285 %type	<Attr_val>	system_option
286 %type	<Integer>	system_option_flag_keyword
287 %type	<Queue>		system_option_list
288 %type	<Integer>	t_default_or_zero
289 %type	<Integer>	tinker_option_keyword
290 %type	<Attr_val>	tinker_option
291 %type	<Queue>		tinker_option_list
292 %type	<Attr_val>	tos_option
293 %type	<Integer>	tos_option_dbl_keyword
294 %type	<Integer>	tos_option_int_keyword
295 %type	<Queue>		tos_option_list
296 %type	<Attr_val>	trap_option
297 %type	<Queue>		trap_option_list
298 %type	<Integer>	unpeer_keyword
299 %type	<Set_var>	variable_assign
300 
301 /* NTP Simulator non-terminals */
302 %type	<Queue>		sim_init_statement_list
303 %type	<Attr_val>	sim_init_statement
304 %type	<Queue>		sim_server_list
305 %type	<Sim_server>	sim_server
306 %type	<Double>	sim_server_offset
307 %type	<Address_node>	sim_server_name
308 %type	<Queue>		sim_act_list
309 %type	<Sim_script>	sim_act
310 %type	<Queue>		sim_act_stmt_list
311 %type	<Attr_val>	sim_act_stmt
312 
313 %%
314 
315 /* ntp.conf
316  * Configuration File Grammar
317  * --------------------------
318  */
319 
320 configuration
321 	:	command_list
322 	;
323 
324 command_list
325 	:	command_list command T_EOC
326 	|	command T_EOC
327 	|	error T_EOC
328 		{
329 			/* I will need to incorporate much more fine grained
330 			 * error messages. The following should suffice for
331 			 * the time being.
332 			 */
333 			msyslog(LOG_ERR,
334 				"syntax error in %s line %d, column %d",
335 				ip_file->fname,
336 				ip_file->err_line_no,
337 				ip_file->err_col_no);
338 		}
339 	;
340 
341 command :	/* NULL STATEMENT */
342 	|	server_command
343 	|	unpeer_command
344 	|	other_mode_command
345 	|	authentication_command
346 	|	monitoring_command
347 	|	access_control_command
348 	|	orphan_mode_command
349 	|	fudge_command
350 	|	system_option_command
351 	|	tinker_command
352 	|	miscellaneous_command
353 	|	simulate_command
354 	;
355 
356 /* Server Commands
357  * ---------------
358  */
359 
360 server_command
361 	:	client_type address option_list
362 		{
363 			struct peer_node *my_node =  create_peer_node($1, $2, $3);
364 			if (my_node)
365 				enqueue(cfgt.peers, my_node);
366 		}
367 	|	client_type address
368 		{
369 			struct peer_node *my_node = create_peer_node($1, $2, NULL);
370 			if (my_node)
371 				enqueue(cfgt.peers, my_node);
372 		}
373 	;
374 
375 client_type
376 	:	T_Server
377 	|	T_Pool
378 	|	T_Peer
379 	|	T_Broadcast
380 	|	T_Manycastclient
381 	;
382 
383 address
384 	:	ip_address
385 	|	address_fam T_String
386 			{ $$ = create_address_node($2, $1); }
387 	;
388 
389 ip_address
390 	:	T_String
391 			{ $$ = create_address_node($1, 0); }
392 	;
393 
394 address_fam
395 	:	T_Ipv4_flag
396 			{ $$ = AF_INET; }
397 	|	T_Ipv6_flag
398 			{ $$ = AF_INET6; }
399 	;
400 
401 option_list
402 	:	option_list option { $$ = enqueue($1, $2); }
403 	|	option { $$ = enqueue_in_new_queue($1); }
404 	;
405 
406 option
407 	:	option_flag
408 	|	option_int
409 	|	T_Bias number
410 			{ $$ = create_attr_dval($1, $2); }
411 	;
412 
413 option_flag
414 	:	option_flag_keyword
415 			{ $$ = create_attr_ival(T_Flag, $1); }
416 	;
417 
418 option_flag_keyword
419 	:	T_Autokey
420 	|	T_Burst
421 	|	T_Iburst
422 	|	T_Noselect
423 	|	T_Preempt
424 	|	T_Prefer
425 	|	T_True
426 	|	T_Xleave
427 	;
428 
429 option_int
430 	:	option_int_keyword T_Integer
431 			{ $$ = create_attr_ival($1, $2); }
432 	;
433 
434 option_int_keyword
435 	:	T_Key
436 	|	T_Minpoll
437 	|	T_Maxpoll
438 	|	T_Ttl
439 	|	T_Mode
440 	|	T_Version
441 	;
442 
443 
444 
445 /* unpeer commands
446  * ---------------
447  */
448 
449 unpeer_command
450 	:	unpeer_keyword address
451 		{
452 			struct unpeer_node *my_node = create_unpeer_node($2);
453 			if (my_node)
454 				enqueue(cfgt.unpeers, my_node);
455 		}
456 	;
457 unpeer_keyword
458 	:	T_Unconfig
459 	|	T_Unpeer
460 	;
461 
462 
463 /* Other Modes
464  * (broadcastclient manycastserver multicastclient)
465  * ------------------------------------------------
466  */
467 
468 other_mode_command
469 	:	T_Broadcastclient
470 			{ cfgt.broadcastclient = 1; }
471 	|	T_Manycastserver address_list
472 			{ append_queue(cfgt.manycastserver, $2); }
473 	|	T_Multicastclient address_list
474 			{ append_queue(cfgt.multicastclient, $2); }
475 	|	T_Mdnstries T_Integer
476 			{ cfgt.mdnstries = $2; }
477 	;
478 
479 
480 
481 /* Authentication Commands
482  * -----------------------
483  */
484 
485 authentication_command
486 	:	T_Automax T_Integer
487 			{ enqueue(cfgt.vars, create_attr_ival($1, $2)); }
488 	|	T_ControlKey T_Integer
489 			{ cfgt.auth.control_key = $2; }
490 	|	T_Crypto crypto_command_list
491 		{
492 			cfgt.auth.cryptosw++;
493 			append_queue(cfgt.auth.crypto_cmd_list, $2);
494 		}
495 	|	T_Keys T_String
496 			{ cfgt.auth.keys = $2; }
497 	|	T_Keysdir T_String
498 			{ cfgt.auth.keysdir = $2; }
499 	|	T_Requestkey T_Integer
500 			{ cfgt.auth.request_key = $2; }
501 	|	T_Revoke T_Integer
502 			{ cfgt.auth.revoke = $2; }
503 	|	T_Trustedkey integer_list_range
504 			{ cfgt.auth.trusted_key_list = $2; }
505 	|	T_NtpSignDsocket T_String
506 			{ cfgt.auth.ntp_signd_socket = $2; }
507 	;
508 
509 crypto_command_list
510 	:	/* empty list */
511 			{ $$ = create_queue(); }
512 	|	crypto_command_list crypto_command
513 		{
514 			if ($2 != NULL)
515 				$$ = enqueue($1, $2);
516 			else
517 				$$ = $1;
518 		}
519 	;
520 
521 crypto_command
522 	:	crypto_str_keyword T_String
523 			{ $$ = create_attr_sval($1, $2); }
524 	|	T_Revoke T_Integer
525 		{
526 			$$ = NULL;
527 			cfgt.auth.revoke = $2;
528 			msyslog(LOG_WARNING,
529 				"'crypto revoke %d' is deprecated, "
530 				"please use 'revoke %d' instead.",
531 				cfgt.auth.revoke, cfgt.auth.revoke);
532 		}
533 	;
534 
535 crypto_str_keyword
536 	:	T_Host
537 	|	T_Ident
538 	|	T_Pw
539 	|	T_Randfile
540 	|	T_Sign
541 	|	T_Digest
542 	;
543 
544 
545 /* Orphan Mode Commands
546  * --------------------
547  */
548 
549 orphan_mode_command
550 	:	T_Tos tos_option_list
551 			{ append_queue(cfgt.orphan_cmds,$2); }
552 	;
553 
554 tos_option_list
555 	:	tos_option_list tos_option { $$ = enqueue($1, $2); }
556 	|	tos_option { $$ = enqueue_in_new_queue($1); }
557 	;
558 
559 tos_option
560 	:	tos_option_int_keyword T_Integer
561 			{ $$ = create_attr_dval($1, (double)$2); }
562 	|	tos_option_dbl_keyword number
563 			{ $$ = create_attr_dval($1, $2); }
564 	|	T_Cohort boolean
565 			{ $$ = create_attr_dval($1, (double)$2); }
566 	;
567 
568 tos_option_int_keyword
569 	:	T_Ceiling
570 	|	T_Floor
571 	|	T_Orphan
572 	|	T_Minsane
573 	|	T_Beacon
574 	;
575 
576 tos_option_dbl_keyword
577 	:	T_Mindist
578 	|	T_Maxdist
579 	|	T_Minclock
580 	|	T_Maxclock
581 	;
582 
583 
584 /* Monitoring Commands
585  * -------------------
586  */
587 
588 monitoring_command
589 	:	T_Statistics stats_list
590 			{ append_queue(cfgt.stats_list, $2); }
591 	|	T_Statsdir T_String
592 		{
593 			if (input_from_file) {
594 				cfgt.stats_dir = $2;
595 			} else {
596 				YYFREE($2);
597 				yyerror("statsdir remote configuration ignored");
598 			}
599 		}
600 	|	T_Filegen stat filegen_option_list
601 		{
602 			enqueue(cfgt.filegen_opts,
603 				create_filegen_node($2, $3));
604 		}
605 	;
606 
607 stats_list
608 	:	stats_list stat { $$ = enqueue($1, create_ival($2)); }
609 	|	stat { $$ = enqueue_in_new_queue(create_ival($1)); }
610 	;
611 
612 stat
613 	:	T_Clockstats
614 	|	T_Cryptostats
615 	|	T_Loopstats
616 	|	T_Peerstats
617 	|	T_Rawstats
618 	|	T_Sysstats
619 	|	T_Timingstats
620 	|	T_Protostats
621 	;
622 
623 filegen_option_list
624 	:	/* empty list */
625 			{ $$ = create_queue(); }
626 	|	filegen_option_list filegen_option
627 		{
628 			if ($2 != NULL)
629 				$$ = enqueue($1, $2);
630 			else
631 				$$ = $1;
632 		}
633 	;
634 
635 filegen_option
636 	:	T_File T_String
637 		{
638 			if (input_from_file) {
639 				$$ = create_attr_sval($1, $2);
640 			} else {
641 				$$ = NULL;
642 				YYFREE($2);
643 				yyerror("filegen file remote config ignored");
644 			}
645 		}
646 	|	T_Type filegen_type
647 		{
648 			if (input_from_file) {
649 				$$ = create_attr_ival($1, $2);
650 			} else {
651 				$$ = NULL;
652 				yyerror("filegen type remote config ignored");
653 			}
654 		}
655 	|	link_nolink
656 		{
657 			const char *err;
658 
659 			if (input_from_file) {
660 				$$ = create_attr_ival(T_Flag, $1);
661 			} else {
662 				$$ = NULL;
663 				if (T_Link == $1)
664 					err = "filegen link remote config ignored";
665 				else
666 					err = "filegen nolink remote config ignored";
667 				yyerror(err);
668 			}
669 		}
670 	|	enable_disable
671 			{ $$ = create_attr_ival(T_Flag, $1); }
672 	;
673 
674 link_nolink
675 	:	T_Link
676 	|	T_Nolink
677 	;
678 
679 enable_disable
680 	:	T_Enable
681 	|	T_Disable
682 	;
683 
684 filegen_type
685 	:	T_None
686 	|	T_Pid
687 	|	T_Day
688 	|	T_Week
689 	|	T_Month
690 	|	T_Year
691 	|	T_Age
692 	;
693 
694 
695 /* Access Control Commands
696  * -----------------------
697  */
698 
699 access_control_command
700 	:	T_Discard discard_option_list
701 		{
702 			append_queue(cfgt.discard_opts, $2);
703 		}
704 	|	T_Restrict address ac_flag_list
705 		{
706 			enqueue(cfgt.restrict_opts,
707 				create_restrict_node($2, NULL, $3, ip_file->line_no));
708 		}
709 	|	T_Restrict T_Default ac_flag_list
710 		{
711 			enqueue(cfgt.restrict_opts,
712 				create_restrict_node(NULL, NULL, $3, ip_file->line_no));
713 		}
714 	|	T_Restrict T_Ipv4_flag T_Default ac_flag_list
715 		{
716 			enqueue(cfgt.restrict_opts,
717 				create_restrict_node(
718 					create_address_node(
719 						estrdup("0.0.0.0"),
720 						AF_INET),
721 					create_address_node(
722 						estrdup("0.0.0.0"),
723 						AF_INET),
724 					$4,
725 					ip_file->line_no));
726 		}
727 	|	T_Restrict T_Ipv6_flag T_Default ac_flag_list
728 		{
729 			enqueue(cfgt.restrict_opts,
730 				create_restrict_node(
731 					create_address_node(
732 						estrdup("::"),
733 						AF_INET6),
734 					create_address_node(
735 						estrdup("::"),
736 						AF_INET6),
737 					$4,
738 					ip_file->line_no));
739 		}
740 	|	T_Restrict ip_address T_Mask ip_address ac_flag_list
741 		{
742 			enqueue(cfgt.restrict_opts,
743 				create_restrict_node($2, $4, $5, ip_file->line_no));
744 		}
745 	;
746 
747 ac_flag_list
748 	:	/* empty list is allowed */
749 			{ $$ = create_queue(); }
750 	|	ac_flag_list access_control_flag
751 			{ $$ = enqueue($1, create_ival($2)); }
752 	;
753 
754 access_control_flag
755 	:	T_Flake
756 	|	T_Ignore
757 	|	T_Kod
758 	|	T_Mssntp
759 	|	T_Limited
760 	|	T_Lowpriotrap
761 	|	T_Nomodify
762 	|	T_Nopeer
763 	|	T_Noquery
764 	|	T_Noserve
765 	|	T_Notrap
766 	|	T_Notrust
767 	|	T_Ntpport
768 	|	T_Version
769 	;
770 
771 discard_option_list
772 	:	discard_option_list discard_option
773 			{ $$ = enqueue($1, $2); }
774 	|	discard_option
775 			{ $$ = enqueue_in_new_queue($1); }
776 	;
777 
778 discard_option
779 	:	discard_option_keyword T_Integer
780 			{ $$ = create_attr_ival($1, $2); }
781 	;
782 
783 discard_option_keyword
784 	:	T_Average
785 	|	T_Minimum
786 	|	T_Monitor
787 	;
788 
789 
790 /* Fudge Commands
791  * --------------
792  */
793 
794 fudge_command
795 	:	T_Fudge address fudge_factor_list
796 			{ enqueue(cfgt.fudge, create_addr_opts_node($2, $3)); }
797 	;
798 
799 fudge_factor_list
800 	:	fudge_factor_list fudge_factor
801 			{ enqueue($1, $2); }
802 	|	fudge_factor
803 			{ $$ = enqueue_in_new_queue($1); }
804 	;
805 
806 fudge_factor
807 	:	fudge_factor_dbl_keyword number
808 			{ $$ = create_attr_dval($1, $2); }
809 	|	fudge_factor_bool_keyword boolean
810 			{ $$ = create_attr_ival($1, $2); }
811 	|	T_Stratum T_Integer
812 			{ $$ = create_attr_ival($1, $2); }
813 	|	T_Refid T_String
814 			{ $$ = create_attr_sval($1, $2); }
815 	;
816 
817 fudge_factor_dbl_keyword
818 	:	T_Time1
819 	|	T_Time2
820 	;
821 
822 fudge_factor_bool_keyword
823 	:	T_Flag1
824 	|	T_Flag2
825 	|	T_Flag3
826 	|	T_Flag4
827 	;
828 
829 
830 /* Command for System Options
831  * --------------------------
832  */
833 
834 system_option_command
835 	:	T_Enable system_option_list
836 			{ append_queue(cfgt.enable_opts, $2);  }
837 	|	T_Disable system_option_list
838 			{ append_queue(cfgt.disable_opts, $2);  }
839 	;
840 
841 system_option_list
842 	:	system_option_list system_option
843 		{
844 			if ($2 != NULL)
845 				$$ = enqueue($1, $2);
846 			else
847 				$$ = $1;
848 		}
849 	|	system_option
850 		{
851 			if ($1 != NULL)
852 				$$ = enqueue_in_new_queue($1);
853 			else
854 				$$ = create_queue();
855 		}
856 	;
857 
858 system_option
859 	:	system_option_flag_keyword
860 			{ $$ = create_attr_ival(T_Flag, $1); }
861 	|	T_Stats
862 		{
863 			if (input_from_file) {
864 				$$ = create_attr_ival(T_Flag, $1);
865 			} else {
866 				$$ = NULL;
867 				yyerror("enable/disable stats remote config ignored");
868 			}
869 		}
870 	;
871 
872 system_option_flag_keyword
873 	:	T_Auth
874 	|	T_Bclient
875 	|	T_Calibrate
876 	|	T_Kernel
877 	|	T_Monitor
878 	|	T_Ntp
879 	;
880 
881 
882 /* Tinker Commands
883  * ---------------
884  */
885 
886 tinker_command
887 	:	T_Tinker tinker_option_list  { append_queue(cfgt.tinker, $2); }
888 	;
889 
890 tinker_option_list
891 	:	tinker_option_list tinker_option  { $$ = enqueue($1, $2); }
892 	|	tinker_option { $$ = enqueue_in_new_queue($1); }
893 	;
894 
895 tinker_option
896 	:	tinker_option_keyword number
897 			{ $$ = create_attr_dval($1, $2); }
898 	;
899 
900 tinker_option_keyword
901 	:	T_Allan
902 	|	T_Dispersion
903 	|	T_Freq
904 	|	T_Huffpuff
905 	|	T_Panic
906 	|	T_Step
907 	|	T_Stepout
908 	;
909 
910 
911 /* Miscellaneous Commands
912  * ----------------------
913  */
914 
915 miscellaneous_command
916 	:	interface_command
917 	|	misc_cmd_dbl_keyword number
918 		{
919 			struct attr_val *av;
920 
921 			av = create_attr_dval($1, $2);
922 			enqueue(cfgt.vars, av);
923 		}
924 	|	misc_cmd_str_keyword T_String
925 		{
926 			struct attr_val *av;
927 
928 			av = create_attr_sval($1, $2);
929 			enqueue(cfgt.vars, av);
930 		}
931 	|	misc_cmd_str_lcl_keyword T_String
932 		{
933 			char error_text[64];
934 			struct attr_val *av;
935 
936 			if (input_from_file) {
937 				av = create_attr_sval($1, $2);
938 				enqueue(cfgt.vars, av);
939 			} else {
940 				YYFREE($2);
941 				snprintf(error_text, sizeof(error_text),
942 					 "%s remote config ignored",
943 					 keyword($1));
944 				yyerror(error_text);
945 			}
946 		}
947 	|	T_Includefile T_String command
948 		{
949 			if (!input_from_file) {
950 				yyerror("remote includefile ignored");
951 				break;
952 			}
953 			if (curr_include_level >= MAXINCLUDELEVEL) {
954 				fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
955 				msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.\n");
956 			} else {
957 				fp[curr_include_level + 1] = F_OPEN(FindConfig($2), "r");
958 				if (fp[curr_include_level + 1] == NULL) {
959 					fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig($2));
960 					msyslog(LOG_ERR, "getconfig: Couldn't open <%s>\n", FindConfig($2));
961 				} else {
962 					ip_file = fp[++curr_include_level];
963 				}
964 			}
965 		}
966 	|	T_End
967 		{
968 			while (curr_include_level != -1)
969 				FCLOSE(fp[curr_include_level--]);
970 		}
971 	|	T_Calldelay T_Integer
972 			{ enqueue(cfgt.vars, create_attr_ival($1, $2)); }
973 	|	T_Driftfile drift_parm
974 			{ /* Null action, possibly all null parms */ }
975 	|	T_Logconfig log_config_list
976 			{ append_queue(cfgt.logconfig, $2); }
977 	|	T_Phone string_list
978 			{ append_queue(cfgt.phone, $2); }
979 	|	T_Setvar variable_assign
980 			{ enqueue(cfgt.setvar, $2); }
981 	|	T_Trap ip_address
982 			{ enqueue(cfgt.trap, create_addr_opts_node($2, NULL)); }
983 	|	T_Trap ip_address trap_option_list
984 			{ enqueue(cfgt.trap, create_addr_opts_node($2, $3)); }
985 	|	T_Ttl integer_list
986 			{ append_queue(cfgt.ttl, $2); }
987 	;
988 
989 misc_cmd_dbl_keyword
990 	:	T_Broadcastdelay
991 	|	T_Tick
992 	;
993 
994 misc_cmd_str_keyword
995 	:	T_Leapfile
996 	|	T_Pidfile
997 	|	T_Qos
998 	;
999 
1000 misc_cmd_str_lcl_keyword
1001 	:	T_Logfile
1002 	|	T_Saveconfigdir
1003 	;
1004 
1005 drift_parm
1006 	:	T_String
1007 			{ enqueue(cfgt.vars, create_attr_sval(T_Driftfile, $1)); }
1008 	|	T_String T_Double
1009 			{ enqueue(cfgt.vars, create_attr_dval(T_WanderThreshold, $2));
1010 			  enqueue(cfgt.vars, create_attr_sval(T_Driftfile, $1)); }
1011 	|	/* Null driftfile */
1012 			{ enqueue(cfgt.vars, create_attr_sval(T_Driftfile, NULL)); }
1013 	;
1014 
1015 variable_assign
1016 	:	T_String '=' T_String t_default_or_zero
1017 			{ $$ = create_setvar_node($1, $3, $4); }
1018 	;
1019 
1020 t_default_or_zero
1021 	:	T_Default
1022 	|	/* empty, no "default" modifier */
1023 		{ $$ = 0; }
1024 	;
1025 
1026 trap_option_list
1027 	:	trap_option_list trap_option
1028 				{ $$ = enqueue($1, $2); }
1029 	|	trap_option	{ $$ = enqueue_in_new_queue($1); }
1030 	;
1031 
1032 trap_option
1033 	:	T_Port T_Integer	{ $$ = create_attr_ival($1, $2); }
1034 	|	T_Interface ip_address	{ $$ = create_attr_pval($1, $2); }
1035 	;
1036 
1037 log_config_list
1038 	:	log_config_list log_config_command { $$ = enqueue($1, $2); }
1039 	|	log_config_command  { $$ = enqueue_in_new_queue($1); }
1040 	;
1041 
1042 log_config_command
1043 	:	T_String
1044 		{
1045 			char prefix = $1[0];
1046 			char *type = $1 + 1;
1047 
1048 			if (prefix != '+' && prefix != '-' && prefix != '=') {
1049 				yyerror("Logconfig prefix is not '+', '-' or '='\n");
1050 			}
1051 			else
1052 				$$ = create_attr_sval(prefix, estrdup(type));
1053 			YYFREE($1);
1054 		}
1055 	;
1056 
1057 interface_command
1058 	:	interface_nic nic_rule_action nic_rule_class
1059 		{
1060 			enqueue(cfgt.nic_rules,
1061 				create_nic_rule_node($3, NULL, $2));
1062 		}
1063 	|	interface_nic nic_rule_action T_String
1064 		{
1065 			enqueue(cfgt.nic_rules,
1066 				create_nic_rule_node(0, $3, $2));
1067 		}
1068 	;
1069 
1070 interface_nic
1071 	:	T_Interface
1072 	|	T_Nic
1073 	;
1074 
1075 nic_rule_class
1076 	:	T_All
1077 	|	T_Ipv4
1078 	|	T_Ipv6
1079 	|	T_Wildcard
1080 	;
1081 
1082 nic_rule_action
1083 	:	T_Listen
1084 	|	T_Ignore
1085 	|	T_Drop
1086 	;
1087 
1088 
1089 
1090 /* Miscellaneous Rules
1091  * -------------------
1092  */
1093 
1094 integer_list
1095 	:	integer_list T_Integer { $$ = enqueue($1, create_ival($2)); }
1096 	|	T_Integer { $$ = enqueue_in_new_queue(create_ival($1)); }
1097 	;
1098 
1099 integer_list_range
1100 	:	integer_list_range integer_list_range_elt
1101 			{ $$ = enqueue($1, $2); }
1102 	|	integer_list_range_elt
1103 			{ $$ = enqueue_in_new_queue($1); }
1104 	;
1105 
1106 integer_list_range_elt
1107 	:	T_Integer
1108 			{ $$ = create_attr_ival('i', $1); }
1109 	|	integer_range		/* default of $$ = $1 is good */
1110 	;
1111 
1112 integer_range		/* limited to unsigned shorts */
1113 	:	'(' T_Integer T_Ellipsis T_Integer ')'
1114 			{ $$ = create_attr_shorts('-', $2, $4); }
1115 	;
1116 
1117 string_list
1118 	:	string_list T_String { $$ = enqueue($1, create_pval($2)); }
1119 	|	T_String { $$ = enqueue_in_new_queue(create_pval($1)); }
1120 	;
1121 
1122 address_list
1123 	:	address_list address { $$ = enqueue($1, $2); }
1124 	|	address { $$ = enqueue_in_new_queue($1); }
1125 	;
1126 
1127 boolean
1128 	:	T_Integer
1129 		{
1130 			if ($1 != 0 && $1 != 1) {
1131 				yyerror("Integer value is not boolean (0 or 1). Assuming 1");
1132 				$$ = 1;
1133 			} else {
1134 				$$ = $1;
1135 			}
1136 		}
1137 	|	T_True    { $$ = 1; }
1138 	|	T_False   { $$ = 0; }
1139 	;
1140 
1141 number
1142 	:	T_Integer { $$ = (double)$1; }
1143 	|	T_Double
1144 	;
1145 
1146 
1147 /* Simulator Configuration Commands
1148  * --------------------------------
1149  */
1150 
1151 simulate_command
1152 	:	sim_conf_start '{' sim_init_statement_list sim_server_list '}'
1153 		{
1154 			cfgt.sim_details = create_sim_node($3, $4);
1155 
1156 			/* Reset the old_config_style variable */
1157 			old_config_style = 1;
1158 		}
1159 	;
1160 
1161 /* The following is a terrible hack to get the configuration file to
1162  * treat newlines as whitespace characters within the simulation.
1163  * This is needed because newlines are significant in the rest of the
1164  * configuration file.
1165  */
1166 sim_conf_start
1167 	:	T_Simulate { old_config_style = 0; }
1168 	;
1169 
1170 sim_init_statement_list
1171 	:	sim_init_statement_list sim_init_statement T_EOC { $$ = enqueue($1, $2); }
1172 	|	sim_init_statement T_EOC			 { $$ = enqueue_in_new_queue($1); }
1173 	;
1174 
1175 sim_init_statement
1176 	:	T_Beep_Delay '=' number   { $$ = create_attr_dval($1, $3); }
1177 	|	T_Sim_Duration '=' number { $$ = create_attr_dval($1, $3); }
1178 	;
1179 
1180 sim_server_list
1181 	:	sim_server_list sim_server { $$ = enqueue($1, $2); }
1182 	|	sim_server		   { $$ = enqueue_in_new_queue($1); }
1183 	;
1184 
1185 sim_server
1186 	:	sim_server_name '{' sim_server_offset sim_act_list '}'
1187 		{ $$ = create_sim_server($1, $3, $4); }
1188 	;
1189 
1190 sim_server_offset
1191 	:	T_Server_Offset '=' number T_EOC { $$ = $3; }
1192 	;
1193 
1194 sim_server_name
1195 	:	T_Server '=' address { $$ = $3; }
1196 	;
1197 
1198 sim_act_list
1199 	:	sim_act_list sim_act { $$ = enqueue($1, $2); }
1200 	|	sim_act		     { $$ = enqueue_in_new_queue($1); }
1201 	;
1202 
1203 sim_act
1204 	:	T_Duration '=' number '{' sim_act_stmt_list '}'
1205 			{ $$ = create_sim_script_info($3, $5); }
1206 	;
1207 
1208 sim_act_stmt_list
1209 	:	sim_act_stmt_list sim_act_stmt T_EOC { $$ = enqueue($1, $2); }
1210 	|	sim_act_stmt T_EOC		     { $$ = enqueue_in_new_queue($1); }
1211 	;
1212 
1213 sim_act_stmt
1214 	:	T_Freq_Offset '=' number
1215 			{ $$ = create_attr_dval($1, $3); }
1216 	|	T_Wander '=' number
1217 			{ $$ = create_attr_dval($1, $3); }
1218 	|	T_Jitter '=' number
1219 			{ $$ = create_attr_dval($1, $3); }
1220 	|	T_Prop_Delay '=' number
1221 			{ $$ = create_attr_dval($1, $3); }
1222 	|	T_Proc_Delay '=' number
1223 			{ $$ = create_attr_dval($1, $3); }
1224 	;
1225 
1226 
1227 %%
1228 
1229 void
1230 yyerror(
1231 	const char *msg
1232 	)
1233 {
1234 	int retval;
1235 
1236 	ip_file->err_line_no = ip_file->prev_token_line_no;
1237 	ip_file->err_col_no = ip_file->prev_token_col_no;
1238 
1239 	msyslog(LOG_ERR,
1240 		"line %d column %d %s",
1241 		ip_file->err_line_no,
1242 		ip_file->err_col_no,
1243 		msg);
1244 	if (!input_from_file) {
1245 		/* Save the error message in the correct buffer */
1246 		retval = snprintf(remote_config.err_msg + remote_config.err_pos,
1247 				  MAXLINE - remote_config.err_pos,
1248 				  "column %d %s",
1249 				  ip_file->err_col_no, msg);
1250 
1251 		/* Increment the value of err_pos */
1252 		if (retval > 0)
1253 			remote_config.err_pos += retval;
1254 
1255 		/* Increment the number of errors */
1256 		++remote_config.no_errors;
1257 	}
1258 }
1259 
1260 
1261 /*
1262  * token_name - Convert T_ token integers to text.
1263  *		Example: token_name(T_Server) returns "T_Server".
1264  *		see also keyword(T_Server) which returns "server".
1265  */
1266 const char *
1267 token_name(
1268 	int token
1269 	)
1270 {
1271 	return yytname[YYTRANSLATE(token)];
1272 }
1273 
1274 
1275 /* Initial Testing function -- ignore
1276 int main(int argc, char *argv[])
1277 {
1278 	ip_file = FOPEN(argv[1], "r");
1279 	if (!ip_file) {
1280 		fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
1281 	}
1282 	key_scanner = create_keyword_scanner(keyword_list);
1283 	print_keyword_scanner(key_scanner, 0);
1284 	yyparse();
1285 	return 0;
1286 }
1287 */
1288 
1289