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