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