xref: /netbsd-src/external/bsd/ntp/dist/ntpd/ntp_parser.y (revision 7d62b00eb9ad855ffcd7da46b41e23feb5476fac)
1 /*	$NetBSD: ntp_parser.y,v 1.19 2020/05/25 20:47:25 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 "ntp.h"
19   #include "ntpd.h"
20   #include "ntp_machine.h"
21   #include "ntp_stdlib.h"
22   #include "ntp_filegen.h"
23   #include "ntp_scanner.h"
24   #include "ntp_config.h"
25   #include "ntp_crypto.h"
26   #include "ntp_calendar.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   #define YYMALLOC	emalloc
36   #define YYFREE	free
37   #define YYERROR_VERBOSE
38   #define YYMAXDEPTH	1000	/* stop the madness sooner */
39   void yyerror(const char *msg);
40 
41   #ifdef SIM
42   #  define ONLY_SIM(a)	(a)
43   #else
44   #  define ONLY_SIM(a)	NULL
45   #endif
46 %}
47 
48 /*
49  * Enable generation of token names array even without YYDEBUG.
50  * We access via token_name() defined below.
51  */
52 %token-table
53 
54 %union {
55 	char *			String;
56 	double			Double;
57 	int			Integer;
58 	unsigned		U_int;
59 	gen_fifo *		Generic_fifo;
60 	attr_val *		Attr_val;
61 	attr_val_fifo *		Attr_val_fifo;
62 	int_fifo *		Int_fifo;
63 	string_fifo *		String_fifo;
64 	address_node *		Address_node;
65 	address_fifo *		Address_fifo;
66 	setvar_node *		Set_var;
67 	server_info *		Sim_server;
68 	server_info_fifo *	Sim_server_fifo;
69 	script_info *		Sim_script;
70 	script_info_fifo *	Sim_script_fifo;
71 }
72 
73 /* TERMINALS (do not appear left of colon) */
74 %token	<Integer>	T_Abbrev
75 %token	<Integer>	T_Age
76 %token	<Integer>	T_All
77 %token	<Integer>	T_Allan
78 %token	<Integer>	T_Allpeers
79 %token	<Integer>	T_Auth
80 %token	<Integer>	T_Autokey
81 %token	<Integer>	T_Automax
82 %token	<Integer>	T_Average
83 %token	<Integer>	T_Basedate
84 %token	<Integer>	T_Bclient
85 %token	<Integer>	T_Bcpollbstep
86 %token	<Integer>	T_Beacon
87 %token	<Integer>	T_Broadcast
88 %token	<Integer>	T_Broadcastclient
89 %token	<Integer>	T_Broadcastdelay
90 %token	<Integer>	T_Burst
91 %token	<Integer>	T_Calibrate
92 %token	<Integer>	T_Ceiling
93 %token	<Integer>	T_Checkhash
94 %token	<Integer>	T_Clockstats
95 %token	<Integer>	T_Cohort
96 %token	<Integer>	T_ControlKey
97 %token	<Integer>	T_Crypto
98 %token	<Integer>	T_Cryptostats
99 %token	<Integer>	T_Ctl
100 %token	<Integer>	T_Day
101 %token	<Integer>	T_Default
102 %token	<Integer>	T_Digest
103 %token	<Integer>	T_Disable
104 %token	<Integer>	T_Discard
105 %token	<Integer>	T_Dispersion
106 %token	<Double>	T_Double		/* not a token */
107 %token	<Integer>	T_Driftfile
108 %token	<Integer>	T_Drop
109 %token	<Integer>	T_Dscp
110 %token	<Integer>	T_Ellipsis	/* "..." not "ellipsis" */
111 %token	<Integer>	T_Enable
112 %token	<Integer>	T_End
113 %token	<Integer>	T_Epeer
114 %token	<Integer>	T_False
115 %token	<Integer>	T_File
116 %token	<Integer>	T_Filegen
117 %token	<Integer>	T_Filenum
118 %token	<Integer>	T_Flag1
119 %token	<Integer>	T_Flag2
120 %token	<Integer>	T_Flag3
121 %token	<Integer>	T_Flag4
122 %token	<Integer>	T_Flake
123 %token	<Integer>	T_Floor
124 %token	<Integer>	T_Freq
125 %token	<Integer>	T_Fudge
126 %token	<Integer>	T_Fuzz
127 %token	<Integer>	T_Host
128 %token	<Integer>	T_Huffpuff
129 %token	<Integer>	T_Iburst
130 %token	<Integer>	T_Ident
131 %token	<Integer>	T_Ignore
132 %token	<Integer>	T_Ignorehash
133 %token	<Integer>	T_Incalloc
134 %token	<Integer>	T_Incmem
135 %token	<Integer>	T_Initalloc
136 %token	<Integer>	T_Initmem
137 %token	<Integer>	T_Includefile
138 %token	<Integer>	T_Integer		/* not a token */
139 %token	<Integer>	T_Interface
140 %token	<Integer>	T_Intrange		/* not a token */
141 %token	<Integer>	T_Io
142 %token	<Integer>	T_Ippeerlimit
143 %token	<Integer>	T_Ipv4
144 %token	<Integer>	T_Ipv4_flag
145 %token	<Integer>	T_Ipv6
146 %token	<Integer>	T_Ipv6_flag
147 %token	<Integer>	T_Kernel
148 %token	<Integer>	T_Key
149 %token	<Integer>	T_Keys
150 %token	<Integer>	T_Keysdir
151 %token	<Integer>	T_Kod
152 %token	<Integer>	T_Leapfile
153 %token	<Integer>	T_Leapsmearinterval
154 %token	<Integer>	T_Limited
155 %token	<Integer>	T_Link
156 %token	<Integer>	T_Listen
157 %token	<Integer>	T_Logconfig
158 %token	<Integer>	T_Logfile
159 %token	<Integer>	T_Loopstats
160 %token	<Integer>	T_Lowpriotrap
161 %token	<Integer>	T_Manycastclient
162 %token	<Integer>	T_Manycastserver
163 %token	<Integer>	T_Mask
164 %token	<Integer>	T_Maxage
165 %token	<Integer>	T_Maxclock
166 %token	<Integer>	T_Maxdepth
167 %token	<Integer>	T_Maxdist
168 %token	<Integer>	T_Maxmem
169 %token	<Integer>	T_Maxpoll
170 %token	<Integer>	T_Mdnstries
171 %token	<Integer>	T_Mem
172 %token	<Integer>	T_Memlock
173 %token	<Integer>	T_Minclock
174 %token	<Integer>	T_Mindepth
175 %token	<Integer>	T_Mindist
176 %token	<Integer>	T_Minimum
177 %token	<Integer>	T_Minjitter
178 %token	<Integer>	T_Minpoll
179 %token	<Integer>	T_Minsane
180 %token	<Integer>	T_Mode
181 %token	<Integer>	T_Mode7
182 %token	<Integer>	T_Monitor
183 %token	<Integer>	T_Month
184 %token	<Integer>	T_Mru
185 %token	<Integer>	T_Mssntp
186 %token	<Integer>	T_Multicastclient
187 %token	<Integer>	T_Nic
188 %token	<Integer>	T_Nolink
189 %token	<Integer>	T_Nomodify
190 %token	<Integer>	T_Nomrulist
191 %token	<Integer>	T_None
192 %token	<Integer>	T_Nonvolatile
193 %token	<Integer>	T_Noepeer
194 %token	<Integer>	T_Nopeer
195 %token	<Integer>	T_Noquery
196 %token	<Integer>	T_Noselect
197 %token	<Integer>	T_Noserve
198 %token	<Integer>	T_Notrap
199 %token	<Integer>	T_Notrust
200 %token	<Integer>	T_Ntp
201 %token	<Integer>	T_Ntpport
202 %token	<Integer>	T_NtpSignDsocket
203 %token	<Integer>	T_Orphan
204 %token	<Integer>	T_Orphanwait
205 %token	<Integer>	T_PCEdigest
206 %token	<Integer>	T_Panic
207 %token	<Integer>	T_Peer
208 %token	<Integer>	T_Peerstats
209 %token	<Integer>	T_Phone
210 %token	<Integer>	T_Pid
211 %token	<Integer>	T_Pidfile
212 %token	<Integer>	T_Poll
213 %token	<Integer>	T_PollSkewList
214 %token	<Integer>	T_Pool
215 %token	<Integer>	T_Port
216 %token	<Integer>	T_Preempt
217 %token	<Integer>	T_Prefer
218 %token	<Integer>	T_Protostats
219 %token	<Integer>	T_Pw
220 %token	<Integer>	T_Randfile
221 %token	<Integer>	T_Rawstats
222 %token	<Integer>	T_Refid
223 %token	<Integer>	T_Requestkey
224 %token	<Integer>	T_Reset
225 %token	<Integer>	T_Restrict
226 %token	<Integer>	T_Revoke
227 %token	<Integer>	T_Rlimit
228 %token	<Integer>	T_Saveconfigdir
229 %token	<Integer>	T_Server
230 %token	<Integer>	T_Serverresponse
231 %token	<Integer>	T_ServerresponseFuzz	/* Not a token */
232 %token	<Integer>	T_Setvar
233 %token	<Integer>	T_Source
234 %token	<Integer>	T_Stacksize
235 %token	<Integer>	T_Statistics
236 %token	<Integer>	T_Stats
237 %token	<Integer>	T_Statsdir
238 %token	<Integer>	T_Step
239 %token	<Integer>	T_Stepback
240 %token	<Integer>	T_Stepfwd
241 %token	<Integer>	T_Stepout
242 %token	<Integer>	T_Stratum
243 %token	<String>	T_String		/* not a token */
244 %token	<Integer>	T_Sys
245 %token	<Integer>	T_Sysstats
246 %token	<Integer>	T_Tick
247 %token	<Integer>	T_Time1
248 %token	<Integer>	T_Time2
249 %token	<Integer>	T_Timer
250 %token	<Integer>	T_Timingstats
251 %token	<Integer>	T_Tinker
252 %token	<Integer>	T_Tos
253 %token	<Integer>	T_Trap
254 %token	<Integer>	T_True
255 %token	<Integer>	T_Trustedkey
256 %token	<Integer>	T_Ttl
257 %token	<Integer>	T_Type
258 %token	<Integer>	T_U_int			/* Not a token */
259 %token	<Integer>	T_UEcrypto
260 %token	<Integer>	T_UEcryptonak
261 %token	<Integer>	T_UEdigest
262 %token	<Integer>	T_Unconfig
263 %token	<Integer>	T_Unpeer
264 %token	<Integer>	T_Version
265 %token	<Integer>	T_WanderThreshold	/* Not a token */
266 %token	<Integer>	T_Week
267 %token	<Integer>	T_Wildcard
268 %token	<Integer>	T_Xleave
269 %token	<Integer>	T_Xmtnonce
270 %token	<Integer>	T_Year
271 %token	<Integer>	T_Flag			/* Not a token */
272 %token	<Integer>	T_EOC
273 
274 
275 /* NTP Simulator Tokens */
276 %token	<Integer>	T_Simulate
277 %token	<Integer>	T_Beep_Delay
278 %token	<Integer>	T_Sim_Duration
279 %token	<Integer>	T_Server_Offset
280 %token	<Integer>	T_Duration
281 %token	<Integer>	T_Freq_Offset
282 %token	<Integer>	T_Wander
283 %token	<Integer>	T_Jitter
284 %token	<Integer>	T_Prop_Delay
285 %token	<Integer>	T_Proc_Delay
286 
287 
288 
289 /*** NON-TERMINALS ***/
290 %type	<Integer>	access_control_flag
291 %type	<Attr_val_fifo>	ac_flag_list
292 %type	<Address_node>	address
293 %type	<Integer>	address_fam
294 %type	<Address_fifo>	address_list
295 %type	<Integer>	basedate
296 %type	<Integer>	boolean
297 %type	<Integer>	client_type
298 %type	<Integer>	counter_set_keyword
299 %type	<Int_fifo>	counter_set_list
300 %type	<Attr_val>	crypto_command
301 %type	<Attr_val_fifo>	crypto_command_list
302 %type	<Integer>	crypto_str_keyword
303 %type	<Attr_val>	discard_option
304 %type	<Integer>	discard_option_keyword
305 %type	<Attr_val_fifo>	discard_option_list
306 %type	<Integer>	enable_disable
307 %type	<Attr_val>	filegen_option
308 %type	<Attr_val_fifo>	filegen_option_list
309 %type	<Integer>	filegen_type
310 %type	<Attr_val>	fudge_factor
311 %type	<Integer>	fudge_factor_bool_keyword
312 %type	<Integer>	fudge_factor_dbl_keyword
313 %type	<Attr_val_fifo>	fudge_factor_list
314 %type	<Attr_val_fifo>	integer_list
315 %type	<Attr_val_fifo>	integer_list_range
316 %type	<Attr_val>	integer_list_range_elt
317 %type	<Attr_val>	integer_range
318 %type	<Integer>	nic_rule_action
319 %type	<Integer>	interface_command
320 %type	<Integer>	interface_nic
321 %type	<Address_node>	ip_address
322 %type	<Integer>	res_ippeerlimit
323 %type	<Integer>	link_nolink
324 %type	<Attr_val>	log_config_command
325 %type	<Attr_val_fifo>	log_config_list
326 %type	<Integer>	misc_cmd_dbl_keyword
327 %type	<Integer>	misc_cmd_int_keyword
328 %type	<Integer>	misc_cmd_str_keyword
329 %type	<Integer>	misc_cmd_str_lcl_keyword
330 %type	<Attr_val>	mru_option
331 %type	<Integer>	mru_option_keyword
332 %type	<Attr_val_fifo>	mru_option_list
333 %type	<Integer>	nic_rule_class
334 %type	<Double>	number
335 %type	<Integer>	opt_hash_check
336 %type	<Attr_val>	option
337 %type	<Attr_val>	option_flag
338 %type	<Integer>	option_flag_keyword
339 %type	<Attr_val_fifo>	option_list
340 %type	<Attr_val>	option_int
341 %type	<Integer>	option_int_keyword
342 %type	<Attr_val>	option_str
343 %type	<Integer>	option_str_keyword
344 %type	<Attr_val_fifo>	pollskew_list
345 %type	<Attr_val>	pollskew_cycle
346 %type	<Attr_val>	pollskew_spec
347 %type	<Integer>	reset_command
348 %type	<Integer>	rlimit_option_keyword
349 %type	<Attr_val>	rlimit_option
350 %type	<Attr_val_fifo>	rlimit_option_list
351 %type	<Integer>	stat
352 %type	<Int_fifo>	stats_list
353 %type	<String_fifo>	string_list
354 %type	<Attr_val>	system_option
355 %type	<Integer>	system_option_flag_keyword
356 %type	<Integer>	system_option_local_flag_keyword
357 %type	<Attr_val_fifo>	system_option_list
358 %type	<Integer>	t_default_or_zero
359 %type	<Integer>	tinker_option_keyword
360 %type	<Attr_val>	tinker_option
361 %type	<Attr_val_fifo>	tinker_option_list
362 %type	<Attr_val>	tos_option
363 %type	<Integer>	tos_option_dbl_keyword
364 %type	<Integer>	tos_option_int_keyword
365 %type	<Attr_val_fifo>	tos_option_list
366 %type	<Attr_val>	trap_option
367 %type	<Attr_val_fifo>	trap_option_list
368 %type	<Integer>	unpeer_keyword
369 %type	<Set_var>	variable_assign
370 
371 /* NTP Simulator non-terminals */
372 %type	<Attr_val>		sim_init_statement
373 %type	<Attr_val_fifo>		sim_init_statement_list
374 %type	<Integer>		sim_init_keyword
375 %type	<Sim_server_fifo>	sim_server_list
376 %type	<Sim_server>		sim_server
377 %type	<Double>		sim_server_offset
378 %type	<Address_node>		sim_server_name
379 %type	<Sim_script>		sim_act
380 %type	<Sim_script_fifo>	sim_act_list
381 %type	<Integer>		sim_act_keyword
382 %type	<Attr_val_fifo>		sim_act_stmt_list
383 %type	<Attr_val>		sim_act_stmt
384 
385 %%
386 
387 /* ntp.conf
388  * Configuration File Grammar
389  * --------------------------
390  */
391 
392 configuration
393 	:	command_list
394 	;
395 
396 command_list
397 	:	command_list command T_EOC
398 	|	command T_EOC
399 	|	error T_EOC
400 		{
401 			/* I will need to incorporate much more fine grained
402 			 * error messages. The following should suffice for
403 			 * the time being.
404 			 */
405 			struct FILE_INFO * ip_ctx = lex_current();
406 			msyslog(LOG_ERR,
407 				"syntax error in %s line %d, column %d",
408 				ip_ctx->fname,
409 				ip_ctx->errpos.nline,
410 				ip_ctx->errpos.ncol);
411 		}
412 	;
413 
414 command :	/* NULL STATEMENT */
415 	|	server_command
416 	|	unpeer_command
417 	|	other_mode_command
418 	|	authentication_command
419 	|	monitoring_command
420 	|	access_control_command
421 	|	orphan_mode_command
422 	|	fudge_command
423 	|	rlimit_command
424 	|	system_option_command
425 	|	tinker_command
426 	|	miscellaneous_command
427 	|	simulate_command
428 	;
429 
430 /* Server Commands
431  * ---------------
432  */
433 
434 server_command
435 	:	client_type address option_list
436 		{
437 			peer_node *my_node;
438 
439 			my_node = create_peer_node($1, $2, $3);
440 			APPEND_G_FIFO(cfgt.peers, my_node);
441 		}
442 	;
443 
444 client_type
445 	:	T_Server
446 	|	T_Pool
447 	|	T_Peer
448 	|	T_Broadcast
449 	|	T_Manycastclient
450 	;
451 
452 address
453 	:	ip_address
454 	|	address_fam T_String
455 			{ $$ = create_address_node($2, $1); }
456 	;
457 
458 ip_address
459 	:	T_String
460 			{ $$ = create_address_node($1, AF_UNSPEC); }
461 	;
462 
463 address_fam
464 	:	T_Ipv4_flag
465 			{ $$ = AF_INET; }
466 	|	T_Ipv6_flag
467 			{ $$ = AF_INET6; }
468 	;
469 
470 option_list
471 	:	/* empty list */
472 			{ $$ = NULL; }
473 	|	option_list option
474 		{
475 			$$ = $1;
476 			APPEND_G_FIFO($$, $2);
477 		}
478 	;
479 
480 option
481 	:	option_flag
482 	|	option_int
483 	|	option_str
484 	;
485 
486 option_flag
487 	:	option_flag_keyword
488 			{ $$ = create_attr_ival(T_Flag, $1); }
489 	;
490 
491 option_flag_keyword
492 	:	T_Autokey
493 	|	T_Burst
494 	|	T_Iburst
495 	|	T_Noselect
496 	|	T_Preempt
497 	|	T_Prefer
498 	|	T_True
499 	|	T_Xleave
500 	|	T_Xmtnonce
501 	;
502 
503 option_int
504 	:	option_int_keyword T_Integer
505 			{ $$ = create_attr_ival($1, $2); }
506 	|	option_int_keyword T_U_int
507 			{ $$ = create_attr_uval($1, $2); }
508 	;
509 
510 option_int_keyword
511 	:	T_Key
512 	|	T_Minpoll
513 	|	T_Maxpoll
514 	|	T_Ttl
515 	|	T_Mode
516 	|	T_Version
517 	;
518 
519 option_str
520 	:	option_str_keyword T_String
521 			{ $$ = create_attr_sval($1, $2); }
522 	;
523 
524 option_str_keyword
525 	:	T_Ident
526 	;
527 
528 
529 /* unpeer commands
530  * ---------------
531  */
532 
533 unpeer_command
534 	:	unpeer_keyword address
535 		{
536 			unpeer_node *my_node;
537 
538 			my_node = create_unpeer_node($2);
539 			if (my_node)
540 				APPEND_G_FIFO(cfgt.unpeers, my_node);
541 		}
542 	;
543 unpeer_keyword
544 	:	T_Unconfig
545 	|	T_Unpeer
546 	;
547 
548 
549 /* Other Modes
550  * (broadcastclient manycastserver multicastclient)
551  * ------------------------------------------------
552  */
553 
554 other_mode_command
555 	:	T_Broadcastclient
556 			{ cfgt.broadcastclient = 1; }
557 	|	T_Manycastserver address_list
558 			{ CONCAT_G_FIFOS(cfgt.manycastserver, $2); }
559 	|	T_Multicastclient address_list
560 			{ CONCAT_G_FIFOS(cfgt.multicastclient, $2); }
561 	|	T_Mdnstries T_Integer
562 			{ cfgt.mdnstries = $2; }
563 	;
564 
565 
566 
567 /* Authentication Commands
568  * -----------------------
569  */
570 
571 authentication_command
572 	:	T_Automax T_Integer
573 		{
574 			attr_val *atrv;
575 
576 			atrv = create_attr_ival($1, $2);
577 			APPEND_G_FIFO(cfgt.vars, atrv);
578 		}
579 	|	T_ControlKey T_Integer
580 			{ cfgt.auth.control_key = $2; }
581 	|	T_Crypto crypto_command_list
582 		{
583 			cfgt.auth.cryptosw++;
584 			CONCAT_G_FIFOS(cfgt.auth.crypto_cmd_list, $2);
585 		}
586 	|	T_Keys T_String
587 			{ cfgt.auth.keys = $2; }
588 	|	T_Keysdir T_String
589 			{ cfgt.auth.keysdir = $2; }
590 	|	T_Requestkey T_Integer
591 			{ cfgt.auth.request_key = $2; }
592 	|	T_Revoke T_Integer
593 			{ cfgt.auth.revoke = $2; }
594 	|	T_Trustedkey integer_list_range
595 		{
596 			/* [Bug 948] leaves it open if appending or
597 			 * replacing the trusted key list is the right
598 			 * way. In any case, either alternative should
599 			 * be coded correctly!
600 			 */
601 			DESTROY_G_FIFO(cfgt.auth.trusted_key_list, destroy_attr_val); /* remove for append */
602 			CONCAT_G_FIFOS(cfgt.auth.trusted_key_list, $2);
603 		}
604 	|	T_NtpSignDsocket T_String
605 			{ cfgt.auth.ntp_signd_socket = $2; }
606 	;
607 
608 crypto_command_list
609 	:	/* empty list */
610 			{ $$ = NULL; }
611 	|	crypto_command_list crypto_command
612 		{
613 			$$ = $1;
614 			APPEND_G_FIFO($$, $2);
615 		}
616 	;
617 
618 crypto_command
619 	:	crypto_str_keyword T_String
620 			{ $$ = create_attr_sval($1, $2); }
621 	|	T_Revoke T_Integer
622 		{
623 			$$ = NULL;
624 			cfgt.auth.revoke = $2;
625 			msyslog(LOG_WARNING,
626 				"'crypto revoke %d' is deprecated, "
627 				"please use 'revoke %d' instead.",
628 				cfgt.auth.revoke, cfgt.auth.revoke);
629 		}
630 	;
631 
632 crypto_str_keyword
633 	:	T_Host
634 	|	T_Ident
635 	|	T_Pw
636 	|	T_Randfile
637 	|	T_Digest
638 	;
639 
640 
641 /* Orphan Mode Commands
642  * --------------------
643  */
644 
645 orphan_mode_command
646 	:	T_Tos tos_option_list
647 			{ CONCAT_G_FIFOS(cfgt.orphan_cmds, $2); }
648 	;
649 
650 tos_option_list
651 	:	tos_option_list tos_option
652 		{
653 			$$ = $1;
654 			APPEND_G_FIFO($$, $2);
655 		}
656 	|	tos_option
657 		{
658 			$$ = NULL;
659 			APPEND_G_FIFO($$, $1);
660 		}
661 	;
662 
663 tos_option
664 	:	tos_option_int_keyword T_Integer
665 			{ $$ = create_attr_dval($1, (double)$2); }
666 	|	tos_option_dbl_keyword number
667 			{ $$ = create_attr_dval($1, $2); }
668 	|	T_Cohort boolean
669 			{ $$ = create_attr_dval($1, (double)$2); }
670 	|	basedate
671 			{ $$ = create_attr_ival(T_Basedate, $1); }
672 	;
673 
674 tos_option_int_keyword
675 	:	T_Bcpollbstep
676 	|	T_Beacon
677 	|	T_Ceiling
678 	|	T_Floor
679 	|	T_Maxclock
680 	|	T_Minclock
681 	|	T_Minsane
682 	|	T_Orphan
683 	|	T_Orphanwait
684 	;
685 
686 tos_option_dbl_keyword
687 	:	T_Mindist
688 	|	T_Maxdist
689 	;
690 
691 
692 /* Monitoring Commands
693  * -------------------
694  */
695 
696 monitoring_command
697 	:	T_Statistics stats_list
698 			{ CONCAT_G_FIFOS(cfgt.stats_list, $2); }
699 	|	T_Statsdir T_String
700 		{
701 			if (lex_from_file()) {
702 				cfgt.stats_dir = $2;
703 			} else {
704 				YYFREE($2);
705 				yyerror("statsdir remote configuration ignored");
706 			}
707 		}
708 	|	T_Filegen stat filegen_option_list
709 		{
710 			filegen_node *fgn;
711 
712 			fgn = create_filegen_node($2, $3);
713 			APPEND_G_FIFO(cfgt.filegen_opts, fgn);
714 		}
715 	;
716 
717 stats_list
718 	:	stats_list stat
719 		{
720 			$$ = $1;
721 			APPEND_G_FIFO($$, create_int_node($2));
722 		}
723 	|	stat
724 		{
725 			$$ = NULL;
726 			APPEND_G_FIFO($$, create_int_node($1));
727 		}
728 	;
729 
730 stat
731 	:	T_Clockstats
732 	|	T_Cryptostats
733 	|	T_Loopstats
734 	|	T_Peerstats
735 	|	T_Rawstats
736 	|	T_Sysstats
737 	|	T_Timingstats
738 	|	T_Protostats
739 	;
740 
741 filegen_option_list
742 	:	/* empty list */
743 			{ $$ = NULL; }
744 	|	filegen_option_list filegen_option
745 		{
746 			$$ = $1;
747 			APPEND_G_FIFO($$, $2);
748 		}
749 	;
750 
751 filegen_option
752 	:	T_File T_String
753 		{
754 			if (lex_from_file()) {
755 				$$ = create_attr_sval($1, $2);
756 			} else {
757 				$$ = NULL;
758 				YYFREE($2);
759 				yyerror("filegen file remote config ignored");
760 			}
761 		}
762 	|	T_Type filegen_type
763 		{
764 			if (lex_from_file()) {
765 				$$ = create_attr_ival($1, $2);
766 			} else {
767 				$$ = NULL;
768 				yyerror("filegen type remote config ignored");
769 			}
770 		}
771 	|	link_nolink
772 		{
773 			const char *err;
774 
775 			if (lex_from_file()) {
776 				$$ = create_attr_ival(T_Flag, $1);
777 			} else {
778 				$$ = NULL;
779 				if (T_Link == $1)
780 					err = "filegen link remote config ignored";
781 				else
782 					err = "filegen nolink remote config ignored";
783 				yyerror(err);
784 			}
785 		}
786 	|	enable_disable
787 			{ $$ = create_attr_ival(T_Flag, $1); }
788 	;
789 
790 link_nolink
791 	:	T_Link
792 	|	T_Nolink
793 	;
794 
795 enable_disable
796 	:	T_Enable
797 	|	T_Disable
798 	;
799 
800 filegen_type
801 	:	T_None
802 	|	T_Pid
803 	|	T_Day
804 	|	T_Week
805 	|	T_Month
806 	|	T_Year
807 	|	T_Age
808 	;
809 
810 
811 /* Access Control Commands
812  * -----------------------
813  */
814 
815 access_control_command
816 	:	T_Discard discard_option_list
817 		{
818 			CONCAT_G_FIFOS(cfgt.discard_opts, $2);
819 		}
820 	|	T_Mru mru_option_list
821 		{
822 			CONCAT_G_FIFOS(cfgt.mru_opts, $2);
823 		}
824 	|	T_Restrict address res_ippeerlimit ac_flag_list
825 		{
826 			restrict_node *rn;
827 
828 			rn = create_restrict_node($2, NULL, $3, $4,
829 						  lex_current()->curpos.nline);
830 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
831 		}
832 	|	T_Restrict address T_Mask ip_address res_ippeerlimit ac_flag_list
833 		{
834 			restrict_node *rn;
835 
836 			rn = create_restrict_node($2, $4, $5, $6,
837 						  lex_current()->curpos.nline);
838 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
839 		}
840 	|	T_Restrict T_Default res_ippeerlimit ac_flag_list
841 		{
842 			restrict_node *rn;
843 
844 			rn = create_restrict_node(NULL, NULL, $3, $4,
845 						  lex_current()->curpos.nline);
846 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
847 		}
848 	|	T_Restrict T_Ipv4_flag T_Default res_ippeerlimit ac_flag_list
849 		{
850 			restrict_node *rn;
851 
852 			rn = create_restrict_node(
853 				create_address_node(
854 					estrdup("0.0.0.0"),
855 					AF_INET),
856 				create_address_node(
857 					estrdup("0.0.0.0"),
858 					AF_INET),
859 				$4, $5,
860 				lex_current()->curpos.nline);
861 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
862 		}
863 	|	T_Restrict T_Ipv6_flag T_Default res_ippeerlimit ac_flag_list
864 		{
865 			restrict_node *rn;
866 
867 			rn = create_restrict_node(
868 				create_address_node(
869 					estrdup("::"),
870 					AF_INET6),
871 				create_address_node(
872 					estrdup("::"),
873 					AF_INET6),
874 				$4, $5,
875 				lex_current()->curpos.nline);
876 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
877 		}
878 	|	T_Restrict T_Source res_ippeerlimit ac_flag_list
879 		{
880 			restrict_node *	rn;
881 
882 			APPEND_G_FIFO($4, create_attr_ival($2, 1));
883 			rn = create_restrict_node(
884 				NULL, NULL, $3, $4, lex_current()->curpos.nline);
885 			APPEND_G_FIFO(cfgt.restrict_opts, rn);
886 		}
887 	;
888 
889 res_ippeerlimit
890 	:	/* empty ippeerlimit defaults to -1 (unlimited) */
891 			{ $$ = -1; }
892 	|	T_Ippeerlimit  T_Integer
893 		{
894 			if (($2 < -1) || ($2 > 100)) {
895 				struct FILE_INFO * ip_ctx;
896 
897 				ip_ctx = lex_current();
898 				msyslog(LOG_ERR,
899 					"Unreasonable ippeerlimit value (%d) in %s line %d, column %d.  Using 0.",
900 					$2,
901 					ip_ctx->fname,
902 					ip_ctx->errpos.nline,
903 					ip_ctx->errpos.ncol);
904 				$2 = 0;
905 			}
906 			$$ = $2;
907 		}
908 	;
909 
910 ac_flag_list
911 	:	/* empty list is allowed */
912 			{ $$ = NULL; }
913 	|	ac_flag_list access_control_flag
914 		{
915 			attr_val *av;
916 
917 			$$ = $1;
918 			av = create_attr_ival($2, 1);
919 			APPEND_G_FIFO($$, av);
920 		}
921 	|	ac_flag_list T_Serverresponse T_Fuzz
922 		{
923 			attr_val *av;
924 
925 			$$ = $1;
926 			av = create_attr_ival(T_ServerresponseFuzz, 1);
927 			APPEND_G_FIFO($$, av);
928 		}
929 	;
930 
931 access_control_flag
932 	:	T_Epeer
933 	|	T_Flake
934 	|	T_Ignore
935 	|	T_Kod
936 	|	T_Limited
937 	|	T_Lowpriotrap
938 	|	T_Mssntp
939 	|	T_Noepeer
940 	|	T_Nomodify
941 	|	T_Nomrulist
942 	|	T_Nopeer
943 	|	T_Noquery
944 	|	T_Noserve
945 	|	T_Notrap
946 	|	T_Notrust
947 	|	T_Ntpport
948 	|	T_Version
949 	;
950 
951 discard_option_list
952 	:	discard_option_list discard_option
953 		{
954 			$$ = $1;
955 			APPEND_G_FIFO($$, $2);
956 		}
957 	|	discard_option
958 		{
959 			$$ = NULL;
960 			APPEND_G_FIFO($$, $1);
961 		}
962 	;
963 
964 discard_option
965 	:	discard_option_keyword T_Integer
966 			{ $$ = create_attr_ival($1, $2); }
967 	;
968 
969 discard_option_keyword
970 	:	T_Average
971 	|	T_Minimum
972 	|	T_Monitor
973 	;
974 
975 mru_option_list
976 	:	mru_option_list mru_option
977 		{
978 			$$ = $1;
979 			APPEND_G_FIFO($$, $2);
980 		}
981 	|	mru_option
982 		{
983 			$$ = NULL;
984 			APPEND_G_FIFO($$, $1);
985 		}
986 	;
987 
988 mru_option
989 	:	mru_option_keyword T_Integer
990 			{ $$ = create_attr_ival($1, $2); }
991 	;
992 
993 mru_option_keyword
994 	:	T_Incalloc
995 	|	T_Incmem
996 	|	T_Initalloc
997 	|	T_Initmem
998 	|	T_Maxage
999 	|	T_Maxdepth
1000 	|	T_Maxmem
1001 	|	T_Mindepth
1002 	;
1003 
1004 /* Fudge Commands
1005  * --------------
1006  */
1007 
1008 fudge_command
1009 	:	T_Fudge address fudge_factor_list
1010 		{
1011 			addr_opts_node *aon;
1012 
1013 			aon = create_addr_opts_node($2, $3);
1014 			APPEND_G_FIFO(cfgt.fudge, aon);
1015 		}
1016 	;
1017 
1018 fudge_factor_list
1019 	:	fudge_factor_list fudge_factor
1020 		{
1021 			$$ = $1;
1022 			APPEND_G_FIFO($$, $2);
1023 		}
1024 	|	fudge_factor
1025 		{
1026 			$$ = NULL;
1027 			APPEND_G_FIFO($$, $1);
1028 		}
1029 	;
1030 
1031 fudge_factor
1032 	:	fudge_factor_dbl_keyword number
1033 			{ $$ = create_attr_dval($1, $2); }
1034 	|	fudge_factor_bool_keyword boolean
1035 			{ $$ = create_attr_ival($1, $2); }
1036 	|	T_Stratum T_Integer
1037 		{
1038 			if ($2 >= 0 && $2 <= 16) {
1039 				$$ = create_attr_ival($1, $2);
1040 			} else {
1041 				$$ = NULL;
1042 				yyerror("fudge factor: stratum value not in [0..16], ignored");
1043 			}
1044 		}
1045 	|	T_Abbrev T_String
1046 			{ $$ = create_attr_sval($1, $2); }
1047 	|	T_Refid T_String
1048 			{ $$ = create_attr_sval($1, $2); }
1049 	;
1050 
1051 fudge_factor_dbl_keyword
1052 	:	T_Time1
1053 	|	T_Time2
1054 	|	T_Minjitter
1055 	;
1056 
1057 fudge_factor_bool_keyword
1058 	:	T_Flag1
1059 	|	T_Flag2
1060 	|	T_Flag3
1061 	|	T_Flag4
1062 	;
1063 
1064 /* rlimit Commands
1065  * ---------------
1066  */
1067 
1068 rlimit_command
1069 	:	T_Rlimit rlimit_option_list
1070 			{ CONCAT_G_FIFOS(cfgt.rlimit, $2); }
1071 	;
1072 
1073 rlimit_option_list
1074 	:	rlimit_option_list rlimit_option
1075 		{
1076 			$$ = $1;
1077 			APPEND_G_FIFO($$, $2);
1078 		}
1079 	|	rlimit_option
1080 		{
1081 			$$ = NULL;
1082 			APPEND_G_FIFO($$, $1);
1083 		}
1084 	;
1085 
1086 rlimit_option
1087 	:	rlimit_option_keyword T_Integer
1088 			{ $$ = create_attr_ival($1, $2); }
1089 	;
1090 
1091 rlimit_option_keyword
1092 	:	T_Memlock
1093 	|	T_Stacksize
1094 	|	T_Filenum
1095 	;
1096 
1097 
1098 /* Command for System Options
1099  * --------------------------
1100  */
1101 
1102 system_option_command
1103 	:	T_Enable system_option_list
1104 			{ CONCAT_G_FIFOS(cfgt.enable_opts, $2); }
1105 	|	T_Disable system_option_list
1106 			{ CONCAT_G_FIFOS(cfgt.disable_opts, $2); }
1107 	;
1108 
1109 system_option_list
1110 	:	system_option_list system_option
1111 		{
1112 			$$ = $1;
1113 			APPEND_G_FIFO($$, $2);
1114 		}
1115 	|	system_option
1116 		{
1117 			$$ = NULL;
1118 			APPEND_G_FIFO($$, $1);
1119 		}
1120 	;
1121 
1122 system_option
1123 	:	system_option_flag_keyword
1124 			{ $$ = create_attr_ival(T_Flag, $1); }
1125 	|	system_option_local_flag_keyword
1126 		{
1127 			if (lex_from_file()) {
1128 				$$ = create_attr_ival(T_Flag, $1);
1129 			} else {
1130 				char err_str[128];
1131 
1132 				$$ = NULL;
1133 				snprintf(err_str, sizeof(err_str),
1134 					 "enable/disable %s remote configuration ignored",
1135 					 keyword($1));
1136 				yyerror(err_str);
1137 			}
1138 		}
1139 	;
1140 
1141 system_option_flag_keyword
1142 	:	T_Auth
1143 	|	T_Bclient
1144 	|	T_Calibrate
1145 	|	T_Kernel
1146 	|	T_Monitor
1147 	|	T_Ntp
1148 	;
1149 
1150 system_option_local_flag_keyword
1151 	:	T_Mode7
1152 	|	T_PCEdigest
1153 	|	T_Stats
1154 	|	T_UEcrypto
1155 	|	T_UEcryptonak
1156 	|	T_UEdigest
1157 	;
1158 
1159 /* Tinker Commands
1160  * ---------------
1161  */
1162 
1163 tinker_command
1164 	:	T_Tinker tinker_option_list
1165 			{ CONCAT_G_FIFOS(cfgt.tinker, $2); }
1166 	;
1167 
1168 tinker_option_list
1169 	:	tinker_option_list tinker_option
1170 		{
1171 			$$ = $1;
1172 			APPEND_G_FIFO($$, $2);
1173 		}
1174 	|	tinker_option
1175 		{
1176 			$$ = NULL;
1177 			APPEND_G_FIFO($$, $1);
1178 		}
1179 	;
1180 
1181 tinker_option
1182 	:	tinker_option_keyword number
1183 			{ $$ = create_attr_dval($1, $2); }
1184 	;
1185 
1186 tinker_option_keyword
1187 	:	T_Allan
1188 	|	T_Dispersion
1189 	|	T_Freq
1190 	|	T_Huffpuff
1191 	|	T_Panic
1192 	|	T_Step
1193 	|	T_Stepback
1194 	|	T_Stepfwd
1195 	|	T_Stepout
1196 	|	T_Tick
1197 	;
1198 
1199 
1200 /* Miscellaneous Commands
1201  * ----------------------
1202  */
1203 
1204 miscellaneous_command
1205 	:	interface_command
1206 	|	reset_command
1207 	|	misc_cmd_dbl_keyword number
1208 		{
1209 			attr_val *av;
1210 
1211 			av = create_attr_dval($1, $2);
1212 			APPEND_G_FIFO(cfgt.vars, av);
1213 		}
1214 	|	misc_cmd_int_keyword T_Integer
1215 		{
1216 			attr_val *av;
1217 
1218 			av = create_attr_ival($1, $2);
1219 			APPEND_G_FIFO(cfgt.vars, av);
1220 		}
1221 	|	misc_cmd_str_keyword T_String
1222 		{
1223 			attr_val *av;
1224 
1225 			av = create_attr_sval($1, $2);
1226 			APPEND_G_FIFO(cfgt.vars, av);
1227 		}
1228 	|	misc_cmd_str_lcl_keyword T_String
1229 		{
1230 			char error_text[64];
1231 			attr_val *av;
1232 
1233 			if (lex_from_file()) {
1234 				av = create_attr_sval($1, $2);
1235 				APPEND_G_FIFO(cfgt.vars, av);
1236 			} else {
1237 				YYFREE($2);
1238 				snprintf(error_text, sizeof(error_text),
1239 					 "%s remote config ignored",
1240 					 keyword($1));
1241 				yyerror(error_text);
1242 			}
1243 		}
1244 	|	T_Includefile T_String command
1245 		{
1246 			if (!lex_from_file()) {
1247 				YYFREE($2); /* avoid leak */
1248 				yyerror("remote includefile ignored");
1249 				break;
1250 			}
1251 			if (lex_level() > MAXINCLUDELEVEL) {
1252 				fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
1253 				msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.");
1254 			} else {
1255 				const char * path = FindConfig($2); /* might return $2! */
1256 				if (!lex_push_file(path, "r")) {
1257 					fprintf(stderr, "getconfig: Couldn't open <%s>\n", path);
1258 					msyslog(LOG_ERR, "getconfig: Couldn't open <%s>", path);
1259 				}
1260 			}
1261 			YYFREE($2); /* avoid leak */
1262 		}
1263 	|	T_Leapfile T_String opt_hash_check
1264 		{
1265 			attr_val *av;
1266 
1267 			av = create_attr_sval($1, $2);
1268 			av->flag = $3;
1269 			APPEND_G_FIFO(cfgt.vars, av);
1270 		}
1271 	|	T_End
1272 			{ lex_flush_stack(); }
1273 	|	T_Driftfile drift_parm
1274 			{ /* see drift_parm below for actions */ }
1275 	|	T_Logconfig log_config_list
1276 			{ CONCAT_G_FIFOS(cfgt.logconfig, $2); }
1277 	|	T_Phone string_list
1278 			{ CONCAT_G_FIFOS(cfgt.phone, $2); }
1279 	|	T_PollSkewList pollskew_list
1280 			{ CONCAT_G_FIFOS(cfgt.pollskewlist, $2); }
1281 	|	T_Setvar variable_assign
1282 			{ APPEND_G_FIFO(cfgt.setvar, $2); }
1283 	|	T_Trap ip_address trap_option_list
1284 		{
1285 			addr_opts_node *aon;
1286 
1287 			aon = create_addr_opts_node($2, $3);
1288 			APPEND_G_FIFO(cfgt.trap, aon);
1289 		}
1290 	|	T_Ttl integer_list
1291 			{ CONCAT_G_FIFOS(cfgt.ttl, $2); }
1292 	;
1293 
1294 misc_cmd_dbl_keyword
1295 	:	T_Broadcastdelay
1296 	|	T_Nonvolatile
1297 	|	T_Tick
1298 	;
1299 
1300 misc_cmd_int_keyword
1301 	:	T_Dscp
1302 	;
1303 
1304 misc_cmd_int_keyword
1305 	:	T_Leapsmearinterval
1306 		{
1307 #ifndef LEAP_SMEAR
1308 			yyerror("Built without LEAP_SMEAR support.");
1309 #endif
1310 		}
1311 	;
1312 
1313 opt_hash_check
1314 	:	T_Ignorehash
1315 			{ $$ = FALSE; }
1316 	|	T_Checkhash
1317 			{ $$ = TRUE; }
1318 	|	/*EMPTY*/
1319 			{  $$ = TRUE; }
1320 	;
1321 
1322 misc_cmd_str_keyword
1323 	:	T_Ident
1324 	;
1325 
1326 misc_cmd_str_lcl_keyword
1327 	:	T_Logfile
1328 	|	T_Pidfile
1329 	|	T_Saveconfigdir
1330 	;
1331 
1332 drift_parm
1333 	:	T_String
1334 		{
1335 			if (lex_from_file()) {
1336 				attr_val *av;
1337 				av = create_attr_sval(T_Driftfile, $1);
1338 				APPEND_G_FIFO(cfgt.vars, av);
1339 			} else {
1340 				YYFREE($1);
1341 				yyerror("driftfile remote configuration ignored");
1342 			}
1343 		}
1344 	|	T_String T_Double
1345 		{
1346 			if (lex_from_file()) {
1347 				attr_val *av;
1348 				av = create_attr_sval(T_Driftfile, $1);
1349 				APPEND_G_FIFO(cfgt.vars, av);
1350 				av = create_attr_dval(T_WanderThreshold, $2);
1351 				APPEND_G_FIFO(cfgt.vars, av);
1352 			msyslog(LOG_WARNING,
1353 				"'driftfile FILENAME WanderValue' is deprecated, "
1354 				"please use separate 'driftfile FILENAME' and "
1355 				"'nonvolatile WanderValue' lines instead.");
1356 			} else {
1357 				YYFREE($1);
1358 				yyerror("driftfile remote configuration ignored");
1359 			}
1360 		}
1361 	|	/* Null driftfile,  indicated by empty string "" */
1362 		{
1363 			if (lex_from_file()) {
1364 				attr_val *av;
1365 				av = create_attr_sval(T_Driftfile, estrdup(""));
1366 				APPEND_G_FIFO(cfgt.vars, av);
1367 			} else {
1368 				yyerror("driftfile remote configuration ignored");
1369 			}
1370 		}
1371 	;
1372 
1373 pollskew_list
1374 	:	/* empty */
1375 			{ $$ = NULL; }
1376 	|	pollskew_list pollskew_spec
1377 			{ $$ = append_gen_fifo($1, $2); }
1378 	;
1379 
1380 pollskew_spec
1381 	:	pollskew_cycle T_Integer '|' T_Integer
1382 		{
1383 			if ($2 < 0 || $4 < 0) {
1384 				/* bad numbers */
1385 				yyerror("pollskewlist: skew values must be >=0");
1386 				destroy_attr_val($1);
1387 				$1 = NULL;
1388 			} else if ($1 == NULL) {
1389 				yyerror("pollskewlist: poll value must be 3-17, inclusive");
1390 			} else if ($1->attr <= 0) {
1391 				/* process default range */
1392 				$1->value.r.first = $2;
1393 				$1->value.r.last  = $4;
1394 			} else if ($2 < (1 << ($1->attr - 1)) && $4 < (1 << ($1->attr - 1))) {
1395 				$1->value.r.first = $2;
1396 				$1->value.r.last  = $4;
1397 			} else {
1398 				yyerror("pollskewlist: randomization limit must be <= half the poll interval");
1399 				destroy_attr_val($1);
1400 				$1 = NULL;
1401 			}
1402 			$$ = $1;
1403 		}
1404 	;
1405 
1406 pollskew_cycle
1407 	:	T_Integer { $$ = ($1 >= 3 && $1 <= 17) ? create_attr_rval($1, 0, 0) : NULL; }
1408 	|	T_Default { $$ = create_attr_rval(-1, 0, 0); }
1409 	;
1410 
1411 
1412 variable_assign
1413 	:	T_String '=' T_String t_default_or_zero
1414 			{ $$ = create_setvar_node($1, $3, $4); }
1415 	;
1416 
1417 t_default_or_zero
1418 	:	T_Default
1419 	|	/* empty, no "default" modifier */
1420 			{ $$ = 0; }
1421 	;
1422 
1423 trap_option_list
1424 	:	/* empty list */
1425 			{ $$ = NULL; }
1426 	|	trap_option_list trap_option
1427 		{
1428 			$$ = $1;
1429 			APPEND_G_FIFO($$, $2);
1430 		}
1431 	;
1432 
1433 trap_option
1434 	:	T_Port T_Integer
1435 			{ $$ = create_attr_ival($1, $2); }
1436 	|	T_Interface ip_address
1437 		{
1438 			$$ = create_attr_sval($1, estrdup($2->address));
1439 			destroy_address_node($2);
1440 		}
1441 	;
1442 
1443 log_config_list
1444 	:	log_config_list log_config_command
1445 		{
1446 			$$ = $1;
1447 			APPEND_G_FIFO($$, $2);
1448 		}
1449 	|	log_config_command
1450 		{
1451 			$$ = NULL;
1452 			APPEND_G_FIFO($$, $1);
1453 		}
1454 	;
1455 
1456 log_config_command
1457 	:	T_String
1458 		{
1459 			char	prefix;
1460 			char *	type;
1461 
1462 			switch ($1[0]) {
1463 
1464 			case '+':
1465 			case '-':
1466 			case '=':
1467 				prefix = $1[0];
1468 				type = $1 + 1;
1469 				break;
1470 
1471 			default:
1472 				prefix = '=';
1473 				type = $1;
1474 			}
1475 
1476 			$$ = create_attr_sval(prefix, estrdup(type));
1477 			YYFREE($1);
1478 		}
1479 	;
1480 
1481 interface_command
1482 	:	interface_nic nic_rule_action nic_rule_class
1483 		{
1484 			nic_rule_node *nrn;
1485 
1486 			nrn = create_nic_rule_node($3, NULL, $2);
1487 			APPEND_G_FIFO(cfgt.nic_rules, nrn);
1488 		}
1489 	|	interface_nic nic_rule_action T_String
1490 		{
1491 			nic_rule_node *nrn;
1492 
1493 			nrn = create_nic_rule_node(0, $3, $2);
1494 			APPEND_G_FIFO(cfgt.nic_rules, nrn);
1495 		}
1496 	;
1497 
1498 interface_nic
1499 	:	T_Interface
1500 	|	T_Nic
1501 	;
1502 
1503 nic_rule_class
1504 	:	T_All
1505 	|	T_Ipv4
1506 	|	T_Ipv6
1507 	|	T_Wildcard
1508 	;
1509 
1510 nic_rule_action
1511 	:	T_Listen
1512 	|	T_Ignore
1513 	|	T_Drop
1514 	;
1515 
1516 reset_command
1517 	:	T_Reset counter_set_list
1518 			{ CONCAT_G_FIFOS(cfgt.reset_counters, $2); }
1519 	;
1520 
1521 counter_set_list
1522 	:	counter_set_list counter_set_keyword
1523 		{
1524 			$$ = $1;
1525 			APPEND_G_FIFO($$, create_int_node($2));
1526 		}
1527 	|	counter_set_keyword
1528 		{
1529 			$$ = NULL;
1530 			APPEND_G_FIFO($$, create_int_node($1));
1531 		}
1532 	;
1533 
1534 counter_set_keyword
1535 	:	T_Allpeers
1536 	|	T_Auth
1537 	|	T_Ctl
1538 	|	T_Io
1539 	|	T_Mem
1540 	|	T_Sys
1541 	|	T_Timer
1542 	;
1543 
1544 
1545 
1546 /* Miscellaneous Rules
1547  * -------------------
1548  */
1549 
1550 integer_list
1551 	:	integer_list T_Integer
1552 		{
1553 			$$ = $1;
1554 			APPEND_G_FIFO($$, create_int_node($2));
1555 		}
1556 	|	T_Integer
1557 		{
1558 			$$ = NULL;
1559 			APPEND_G_FIFO($$, create_int_node($1));
1560 		}
1561 	;
1562 
1563 integer_list_range
1564 	:	integer_list_range integer_list_range_elt
1565 		{
1566 			$$ = $1;
1567 			APPEND_G_FIFO($$, $2);
1568 		}
1569 	|	integer_list_range_elt
1570 		{
1571 			$$ = NULL;
1572 			APPEND_G_FIFO($$, $1);
1573 		}
1574 	;
1575 
1576 integer_list_range_elt
1577 	:	T_Integer
1578 			{ $$ = create_attr_ival('i', $1); }
1579 	|	integer_range
1580 	;
1581 
1582 integer_range
1583 	:	'(' T_Integer T_Ellipsis T_Integer ')'
1584 			{ $$ = create_attr_rval('-', $2, $4); }
1585 	;
1586 
1587 string_list
1588 	:	string_list T_String
1589 		{
1590 			$$ = $1;
1591 			APPEND_G_FIFO($$, create_string_node($2));
1592 		}
1593 	|	T_String
1594 		{
1595 			$$ = NULL;
1596 			APPEND_G_FIFO($$, create_string_node($1));
1597 		}
1598 	;
1599 
1600 address_list
1601 	:	address_list address
1602 		{
1603 			$$ = $1;
1604 			APPEND_G_FIFO($$, $2);
1605 		}
1606 	|	address
1607 		{
1608 			$$ = NULL;
1609 			APPEND_G_FIFO($$, $1);
1610 		}
1611 	;
1612 
1613 boolean
1614 	:	T_Integer
1615 		{
1616 			if ($1 != 0 && $1 != 1) {
1617 				yyerror("Integer value is not boolean (0 or 1). Assuming 1");
1618 				$$ = 1;
1619 			} else {
1620 				$$ = $1;
1621 			}
1622 		}
1623 	|	T_True	{ $$ = 1; }
1624 	|	T_False	{ $$ = 0; }
1625 	;
1626 
1627 number
1628 	:	T_Integer	{ $$ = (double)$1; }
1629 	|	T_Double
1630 	;
1631 
1632 basedate
1633 	:	T_Basedate T_String
1634 			{ $$ = basedate_eval_string($2); YYFREE($2); }
1635 
1636 /* Simulator Configuration Commands
1637  * --------------------------------
1638  */
1639 
1640 simulate_command
1641 	:	sim_conf_start '{' sim_init_statement_list sim_server_list '}'
1642 		{
1643 			sim_node *sn;
1644 
1645 			sn =  create_sim_node($3, $4);
1646 			APPEND_G_FIFO(cfgt.sim_details, sn);
1647 
1648 			/* Revert from ; to \n for end-of-command */
1649 			old_config_style = 1;
1650 		}
1651 	;
1652 
1653 /* The following is a terrible hack to get the configuration file to
1654  * treat newlines as whitespace characters within the simulation.
1655  * This is needed because newlines are significant in the rest of the
1656  * configuration file.
1657  */
1658 sim_conf_start
1659 	:	T_Simulate { old_config_style = 0; }
1660 	;
1661 
1662 sim_init_statement_list
1663 	:	sim_init_statement_list sim_init_statement T_EOC
1664 		{
1665 			$$ = $1;
1666 			APPEND_G_FIFO($$, $2);
1667 		}
1668 	|	sim_init_statement T_EOC
1669 		{
1670 			$$ = NULL;
1671 			APPEND_G_FIFO($$, $1);
1672 		}
1673 	;
1674 
1675 sim_init_statement
1676 	:	sim_init_keyword '=' number
1677 			{ $$ = create_attr_dval($1, $3); }
1678 	;
1679 
1680 sim_init_keyword
1681 	:	T_Beep_Delay
1682 	|	T_Sim_Duration
1683 	;
1684 
1685 sim_server_list
1686 	:	sim_server_list sim_server
1687 		{
1688 			$$ = $1;
1689 			APPEND_G_FIFO($$, $2);
1690 		}
1691 	|	sim_server
1692 		{
1693 			$$ = NULL;
1694 			APPEND_G_FIFO($$, $1);
1695 		}
1696 	;
1697 
1698 sim_server
1699 	:	sim_server_name '{' sim_server_offset sim_act_list '}'
1700 			{ $$ = ONLY_SIM(create_sim_server($1, $3, $4)); }
1701 	;
1702 
1703 sim_server_offset
1704 	:	T_Server_Offset '=' number T_EOC
1705 			{ $$ = $3; }
1706 	;
1707 
1708 sim_server_name
1709 	:	T_Server '=' address
1710 			{ $$ = $3; }
1711 	;
1712 
1713 sim_act_list
1714 	:	sim_act_list sim_act
1715 		{
1716 			$$ = $1;
1717 			APPEND_G_FIFO($$, $2);
1718 		}
1719 	|	sim_act
1720 		{
1721 			$$ = NULL;
1722 			APPEND_G_FIFO($$, $1);
1723 		}
1724 	;
1725 
1726 sim_act
1727 	:	T_Duration '=' number '{' sim_act_stmt_list '}'
1728 			{ $$ = ONLY_SIM(create_sim_script_info($3, $5)); }
1729 	;
1730 
1731 sim_act_stmt_list
1732 	:	sim_act_stmt_list sim_act_stmt T_EOC
1733 		{
1734 			$$ = $1;
1735 			APPEND_G_FIFO($$, $2);
1736 		}
1737 	|	sim_act_stmt T_EOC
1738 		{
1739 			$$ = NULL;
1740 			APPEND_G_FIFO($$, $1);
1741 		}
1742 	;
1743 
1744 sim_act_stmt
1745 	:	sim_act_keyword '=' number
1746 			{ $$ = create_attr_dval($1, $3); }
1747 	;
1748 
1749 sim_act_keyword
1750 	:	T_Freq_Offset
1751 	|	T_Wander
1752 	|	T_Jitter
1753 	|	T_Prop_Delay
1754 	|	T_Proc_Delay
1755 	;
1756 
1757 %%
1758 
1759 void
1760 yyerror(
1761 	const char *msg
1762 	)
1763 {
1764 	int retval;
1765 	struct FILE_INFO * ip_ctx;
1766 
1767 	ip_ctx = lex_current();
1768 	ip_ctx->errpos = ip_ctx->tokpos;
1769 
1770 	msyslog(LOG_ERR, "line %d column %d %s",
1771 		ip_ctx->errpos.nline, ip_ctx->errpos.ncol, msg);
1772 	if (!lex_from_file()) {
1773 		/* Save the error message in the correct buffer */
1774 		retval = snprintf(remote_config.err_msg + remote_config.err_pos,
1775 				  MAXLINE - remote_config.err_pos,
1776 				  "column %d %s",
1777 				  ip_ctx->errpos.ncol, msg);
1778 
1779 		/* Increment the value of err_pos */
1780 		if (retval > 0)
1781 			remote_config.err_pos += retval;
1782 
1783 		/* Increment the number of errors */
1784 		++remote_config.no_errors;
1785 	}
1786 }
1787 
1788 
1789 /*
1790  * token_name - convert T_ token integers to text
1791  *		example: token_name(T_Server) returns "T_Server"
1792  */
1793 const char *
1794 token_name(
1795 	int token
1796 	)
1797 {
1798 	return yytname[YYTRANSLATE(token)];
1799 }
1800 
1801 
1802 /* Initial Testing function -- ignore */
1803 #if 0
1804 int main(int argc, char *argv[])
1805 {
1806 	ip_file = FOPEN(argv[1], "r");
1807 	if (!ip_file)
1808 		fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
1809 	yyparse();
1810 	return 0;
1811 }
1812 #endif
1813 
1814