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