summaryrefslogtreecommitdiff
path: root/ntpd/ntp_parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'ntpd/ntp_parser.y')
-rw-r--r--ntpd/ntp_parser.y1638
1 files changed, 1638 insertions, 0 deletions
diff --git a/ntpd/ntp_parser.y b/ntpd/ntp_parser.y
new file mode 100644
index 0000000..e75bffe
--- /dev/null
+++ b/ntpd/ntp_parser.y
@@ -0,0 +1,1638 @@
+/* ntp_parser.y
+ *
+ * The parser for the NTP configuration file.
+ *
+ * Written By: Sachin Kamboj
+ * University of Delaware
+ * Newark, DE 19711
+ * Copyright (c) 2006
+ */
+
+%parse-param {struct FILE_INFO *ip_file}
+%lex-param {struct FILE_INFO *ip_file}
+
+%{
+ #ifdef HAVE_CONFIG_H
+ # include <config.h>
+ #endif
+
+ #include "ntp.h"
+ #include "ntpd.h"
+ #include "ntp_machine.h"
+ #include "ntp_stdlib.h"
+ #include "ntp_filegen.h"
+ #include "ntp_scanner.h"
+ #include "ntp_config.h"
+ #include "ntp_crypto.h"
+
+ #include "ntpsim.h" /* HMS: Do we really want this all the time? */
+ /* SK: It might be a good idea to always
+ include the simulator code. That way
+ someone can use the same configuration file
+ for both the simulator and the daemon
+ */
+
+ #define YYMALLOC emalloc
+ #define YYFREE free
+ #define YYERROR_VERBOSE
+ #define YYMAXDEPTH 1000 /* stop the madness sooner */
+ void yyerror(struct FILE_INFO *ip_file, const char *msg);
+
+ #ifdef SIM
+ # define ONLY_SIM(a) (a)
+ #else
+ # define ONLY_SIM(a) NULL
+ #endif
+%}
+
+/*
+ * Enable generation of token names array even without YYDEBUG.
+ * We access via token_name() defined below.
+ */
+%token-table
+
+%union {
+ char * String;
+ double Double;
+ int Integer;
+ unsigned U_int;
+ gen_fifo * Generic_fifo;
+ attr_val * Attr_val;
+ attr_val_fifo * Attr_val_fifo;
+ int_fifo * Int_fifo;
+ string_fifo * String_fifo;
+ address_node * Address_node;
+ address_fifo * Address_fifo;
+ setvar_node * Set_var;
+ server_info * Sim_server;
+ server_info_fifo * Sim_server_fifo;
+ script_info * Sim_script;
+ script_info_fifo * Sim_script_fifo;
+}
+
+/* TERMINALS (do not appear left of colon) */
+%token <Integer> T_Abbrev
+%token <Integer> T_Age
+%token <Integer> T_All
+%token <Integer> T_Allan
+%token <Integer> T_Allpeers
+%token <Integer> T_Auth
+%token <Integer> T_Autokey
+%token <Integer> T_Automax
+%token <Integer> T_Average
+%token <Integer> T_Bclient
+%token <Integer> T_Beacon
+%token <Integer> T_Broadcast
+%token <Integer> T_Broadcastclient
+%token <Integer> T_Broadcastdelay
+%token <Integer> T_Burst
+%token <Integer> T_Calibrate
+%token <Integer> T_Ceiling
+%token <Integer> T_Clockstats
+%token <Integer> T_Cohort
+%token <Integer> T_ControlKey
+%token <Integer> T_Crypto
+%token <Integer> T_Cryptostats
+%token <Integer> T_Ctl
+%token <Integer> T_Day
+%token <Integer> T_Default
+%token <Integer> T_Digest
+%token <Integer> T_Disable
+%token <Integer> T_Discard
+%token <Integer> T_Dispersion
+%token <Double> T_Double /* not a token */
+%token <Integer> T_Driftfile
+%token <Integer> T_Drop
+%token <Integer> T_Ellipsis /* "..." not "ellipsis" */
+%token <Integer> T_Enable
+%token <Integer> T_End
+%token <Integer> T_False
+%token <Integer> T_File
+%token <Integer> T_Filegen
+%token <Integer> T_Filenum
+%token <Integer> T_Flag1
+%token <Integer> T_Flag2
+%token <Integer> T_Flag3
+%token <Integer> T_Flag4
+%token <Integer> T_Flake
+%token <Integer> T_Floor
+%token <Integer> T_Freq
+%token <Integer> T_Fudge
+%token <Integer> T_Host
+%token <Integer> T_Huffpuff
+%token <Integer> T_Iburst
+%token <Integer> T_Ident
+%token <Integer> T_Ignore
+%token <Integer> T_Incalloc
+%token <Integer> T_Incmem
+%token <Integer> T_Initalloc
+%token <Integer> T_Initmem
+%token <Integer> T_Includefile
+%token <Integer> T_Integer /* not a token */
+%token <Integer> T_Interface
+%token <Integer> T_Intrange /* not a token */
+%token <Integer> T_Io
+%token <Integer> T_Ipv4
+%token <Integer> T_Ipv4_flag
+%token <Integer> T_Ipv6
+%token <Integer> T_Ipv6_flag
+%token <Integer> T_Kernel
+%token <Integer> T_Key
+%token <Integer> T_Keys
+%token <Integer> T_Keysdir
+%token <Integer> T_Kod
+%token <Integer> T_Mssntp
+%token <Integer> T_Leapfile
+%token <Integer> T_Limited
+%token <Integer> T_Link
+%token <Integer> T_Listen
+%token <Integer> T_Logconfig
+%token <Integer> T_Logfile
+%token <Integer> T_Loopstats
+%token <Integer> T_Lowpriotrap
+%token <Integer> T_Manycastclient
+%token <Integer> T_Manycastserver
+%token <Integer> T_Mask
+%token <Integer> T_Maxage
+%token <Integer> T_Maxclock
+%token <Integer> T_Maxdepth
+%token <Integer> T_Maxdist
+%token <Integer> T_Maxmem
+%token <Integer> T_Maxpoll
+%token <Integer> T_Mem
+%token <Integer> T_Memlock
+%token <Integer> T_Minclock
+%token <Integer> T_Mindepth
+%token <Integer> T_Mindist
+%token <Integer> T_Minimum
+%token <Integer> T_Minpoll
+%token <Integer> T_Minsane
+%token <Integer> T_Mode
+%token <Integer> T_Mode7
+%token <Integer> T_Monitor
+%token <Integer> T_Month
+%token <Integer> T_Mru
+%token <Integer> T_Multicastclient
+%token <Integer> T_Nic
+%token <Integer> T_Nolink
+%token <Integer> T_Nomodify
+%token <Integer> T_Nomrulist
+%token <Integer> T_None
+%token <Integer> T_Nonvolatile
+%token <Integer> T_Nopeer
+%token <Integer> T_Noquery
+%token <Integer> T_Noselect
+%token <Integer> T_Noserve
+%token <Integer> T_Notrap
+%token <Integer> T_Notrust
+%token <Integer> T_Ntp
+%token <Integer> T_Ntpport
+%token <Integer> T_NtpSignDsocket
+%token <Integer> T_Orphan
+%token <Integer> T_Orphanwait
+%token <Integer> T_Panic
+%token <Integer> T_Peer
+%token <Integer> T_Peerstats
+%token <Integer> T_Phone
+%token <Integer> T_Pid
+%token <Integer> T_Pidfile
+%token <Integer> T_Pool
+%token <Integer> T_Port
+%token <Integer> T_Preempt
+%token <Integer> T_Prefer
+%token <Integer> T_Protostats
+%token <Integer> T_Pw
+%token <Integer> T_Randfile
+%token <Integer> T_Rawstats
+%token <Integer> T_Refid
+%token <Integer> T_Requestkey
+%token <Integer> T_Reset
+%token <Integer> T_Restrict
+%token <Integer> T_Revoke
+%token <Integer> T_Rlimit
+%token <Integer> T_Saveconfigdir
+%token <Integer> T_Server
+%token <Integer> T_Setvar
+%token <Integer> T_Source
+%token <Integer> T_Stacksize
+%token <Integer> T_Statistics
+%token <Integer> T_Stats
+%token <Integer> T_Statsdir
+%token <Integer> T_Step
+%token <Integer> T_Stepout
+%token <Integer> T_Stratum
+%token <String> T_String /* not a token */
+%token <Integer> T_Sys
+%token <Integer> T_Sysstats
+%token <Integer> T_Tick
+%token <Integer> T_Time1
+%token <Integer> T_Time2
+%token <Integer> T_Timer
+%token <Integer> T_Timingstats
+%token <Integer> T_Tinker
+%token <Integer> T_Tos
+%token <Integer> T_Trap
+%token <Integer> T_True
+%token <Integer> T_Trustedkey
+%token <Integer> T_Ttl
+%token <Integer> T_Type
+%token <Integer> T_U_int /* Not a token */
+%token <Integer> T_Unconfig
+%token <Integer> T_Unpeer
+%token <Integer> T_Version
+%token <Integer> T_WanderThreshold /* Not a token */
+%token <Integer> T_Week
+%token <Integer> T_Wildcard
+%token <Integer> T_Xleave
+%token <Integer> T_Year
+%token <Integer> T_Flag /* Not a token */
+%token <Integer> T_EOC
+
+
+/* NTP Simulator Tokens */
+%token <Integer> T_Simulate
+%token <Integer> T_Beep_Delay
+%token <Integer> T_Sim_Duration
+%token <Integer> T_Server_Offset
+%token <Integer> T_Duration
+%token <Integer> T_Freq_Offset
+%token <Integer> T_Wander
+%token <Integer> T_Jitter
+%token <Integer> T_Prop_Delay
+%token <Integer> T_Proc_Delay
+
+
+
+/*** NON-TERMINALS ***/
+%type <Integer> access_control_flag
+%type <Int_fifo> ac_flag_list
+%type <Address_node> address
+%type <Integer> address_fam
+%type <Address_fifo> address_list
+%type <Integer> boolean
+%type <Integer> client_type
+%type <Integer> counter_set_keyword
+%type <Int_fifo> counter_set_list
+%type <Attr_val> crypto_command
+%type <Attr_val_fifo> crypto_command_list
+%type <Integer> crypto_str_keyword
+%type <Attr_val> discard_option
+%type <Integer> discard_option_keyword
+%type <Attr_val_fifo> discard_option_list
+%type <Integer> enable_disable
+%type <Attr_val> filegen_option
+%type <Attr_val_fifo> filegen_option_list
+%type <Integer> filegen_type
+%type <Attr_val> fudge_factor
+%type <Integer> fudge_factor_bool_keyword
+%type <Integer> fudge_factor_dbl_keyword
+%type <Attr_val_fifo> fudge_factor_list
+%type <Attr_val_fifo> integer_list
+%type <Attr_val_fifo> integer_list_range
+%type <Attr_val> integer_list_range_elt
+%type <Attr_val> integer_range
+%type <Integer> nic_rule_action
+%type <Integer> interface_command
+%type <Integer> interface_nic
+%type <Address_node> ip_address
+%type <Integer> link_nolink
+%type <Attr_val> log_config_command
+%type <Attr_val_fifo> log_config_list
+%type <Integer> misc_cmd_dbl_keyword
+%type <Integer> misc_cmd_str_keyword
+%type <Integer> misc_cmd_str_lcl_keyword
+%type <Attr_val> mru_option
+%type <Integer> mru_option_keyword
+%type <Attr_val_fifo> mru_option_list
+%type <Integer> nic_rule_class
+%type <Double> number
+%type <Attr_val> option
+%type <Attr_val> option_flag
+%type <Integer> option_flag_keyword
+%type <Attr_val_fifo> option_list
+%type <Attr_val> option_int
+%type <Integer> option_int_keyword
+%type <Attr_val> option_str
+%type <Integer> option_str_keyword
+%type <Integer> reset_command
+%type <Integer> rlimit_option_keyword
+%type <Attr_val> rlimit_option
+%type <Attr_val_fifo> rlimit_option_list
+%type <Integer> stat
+%type <Int_fifo> stats_list
+%type <String_fifo> string_list
+%type <Attr_val> system_option
+%type <Integer> system_option_flag_keyword
+%type <Integer> system_option_local_flag_keyword
+%type <Attr_val_fifo> system_option_list
+%type <Integer> t_default_or_zero
+%type <Integer> tinker_option_keyword
+%type <Attr_val> tinker_option
+%type <Attr_val_fifo> tinker_option_list
+%type <Attr_val> tos_option
+%type <Integer> tos_option_dbl_keyword
+%type <Integer> tos_option_int_keyword
+%type <Attr_val_fifo> tos_option_list
+%type <Attr_val> trap_option
+%type <Attr_val_fifo> trap_option_list
+%type <Integer> unpeer_keyword
+%type <Set_var> variable_assign
+
+/* NTP Simulator non-terminals */
+%type <Attr_val> sim_init_statement
+%type <Attr_val_fifo> sim_init_statement_list
+%type <Integer> sim_init_keyword
+%type <Sim_server_fifo> sim_server_list
+%type <Sim_server> sim_server
+%type <Double> sim_server_offset
+%type <Address_node> sim_server_name
+%type <Sim_script> sim_act
+%type <Sim_script_fifo> sim_act_list
+%type <Integer> sim_act_keyword
+%type <Attr_val_fifo> sim_act_stmt_list
+%type <Attr_val> sim_act_stmt
+
+%%
+
+/* ntp.conf
+ * Configuration File Grammar
+ * --------------------------
+ */
+
+configuration
+ : command_list
+ ;
+
+command_list
+ : command_list command T_EOC
+ | command T_EOC
+ | error T_EOC
+ {
+ /* I will need to incorporate much more fine grained
+ * error messages. The following should suffice for
+ * the time being.
+ */
+ msyslog(LOG_ERR,
+ "syntax error in %s line %d, column %d",
+ ip_file->fname,
+ ip_file->err_line_no,
+ ip_file->err_col_no);
+ }
+ ;
+
+command : /* NULL STATEMENT */
+ | server_command
+ | unpeer_command
+ | other_mode_command
+ | authentication_command
+ | monitoring_command
+ | access_control_command
+ | orphan_mode_command
+ | fudge_command
+ | rlimit_command
+ | system_option_command
+ | tinker_command
+ | miscellaneous_command
+ | simulate_command
+ ;
+
+/* Server Commands
+ * ---------------
+ */
+
+server_command
+ : client_type address option_list
+ {
+ peer_node *my_node;
+
+ my_node = create_peer_node($1, $2, $3);
+ APPEND_G_FIFO(cfgt.peers, my_node);
+ }
+ ;
+
+client_type
+ : T_Server
+ | T_Pool
+ | T_Peer
+ | T_Broadcast
+ | T_Manycastclient
+ ;
+
+address
+ : ip_address
+ | address_fam T_String
+ { $$ = create_address_node($2, $1); }
+ ;
+
+ip_address
+ : T_String
+ { $$ = create_address_node($1, AF_UNSPEC); }
+ ;
+
+address_fam
+ : T_Ipv4_flag
+ { $$ = AF_INET; }
+ | T_Ipv6_flag
+ { $$ = AF_INET6; }
+ ;
+
+option_list
+ : /* empty list */
+ { $$ = NULL; }
+ | option_list option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ ;
+
+option
+ : option_flag
+ | option_int
+ | option_str
+ ;
+
+option_flag
+ : option_flag_keyword
+ { $$ = create_attr_ival(T_Flag, $1); }
+ ;
+
+option_flag_keyword
+ : T_Autokey
+ | T_Burst
+ | T_Iburst
+ | T_Noselect
+ | T_Preempt
+ | T_Prefer
+ | T_True
+ | T_Xleave
+ ;
+
+option_int
+ : option_int_keyword T_Integer
+ { $$ = create_attr_ival($1, $2); }
+ | option_int_keyword T_U_int
+ { $$ = create_attr_uval($1, $2); }
+ ;
+
+option_int_keyword
+ : T_Key
+ | T_Minpoll
+ | T_Maxpoll
+ | T_Ttl
+ | T_Mode
+ | T_Version
+ ;
+
+option_str
+ : option_str_keyword T_String
+ { $$ = create_attr_sval($1, $2); }
+ ;
+
+option_str_keyword
+ : T_Ident
+ ;
+
+
+/* unpeer commands
+ * ---------------
+ */
+
+unpeer_command
+ : unpeer_keyword address
+ {
+ unpeer_node *my_node;
+
+ my_node = create_unpeer_node($2);
+ if (my_node)
+ APPEND_G_FIFO(cfgt.unpeers, my_node);
+ }
+ ;
+unpeer_keyword
+ : T_Unconfig
+ | T_Unpeer
+ ;
+
+
+/* Other Modes
+ * (broadcastclient manycastserver multicastclient)
+ * ------------------------------------------------
+ */
+
+other_mode_command
+ : T_Broadcastclient
+ { cfgt.broadcastclient = 1; }
+ | T_Manycastserver address_list
+ { CONCAT_G_FIFOS(cfgt.manycastserver, $2); }
+ | T_Multicastclient address_list
+ { CONCAT_G_FIFOS(cfgt.multicastclient, $2); }
+ ;
+
+
+
+/* Authentication Commands
+ * -----------------------
+ */
+
+authentication_command
+ : T_Automax T_Integer
+ {
+ attr_val *atrv;
+
+ atrv = create_attr_ival($1, $2);
+ APPEND_G_FIFO(cfgt.vars, atrv);
+ }
+ | T_ControlKey T_Integer
+ { cfgt.auth.control_key = $2; }
+ | T_Crypto crypto_command_list
+ {
+ cfgt.auth.cryptosw++;
+ CONCAT_G_FIFOS(cfgt.auth.crypto_cmd_list, $2);
+ }
+ | T_Keys T_String
+ { cfgt.auth.keys = $2; }
+ | T_Keysdir T_String
+ { cfgt.auth.keysdir = $2; }
+ | T_Requestkey T_Integer
+ { cfgt.auth.request_key = $2; }
+ | T_Revoke T_Integer
+ { cfgt.auth.revoke = $2; }
+ | T_Trustedkey integer_list_range
+ {
+ cfgt.auth.trusted_key_list = $2;
+
+ // if (!cfgt.auth.trusted_key_list)
+ // cfgt.auth.trusted_key_list = $2;
+ // else
+ // LINK_SLIST(cfgt.auth.trusted_key_list, $2, link);
+ }
+ | T_NtpSignDsocket T_String
+ { cfgt.auth.ntp_signd_socket = $2; }
+ ;
+
+crypto_command_list
+ : /* empty list */
+ { $$ = NULL; }
+ | crypto_command_list crypto_command
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ ;
+
+crypto_command
+ : crypto_str_keyword T_String
+ { $$ = create_attr_sval($1, $2); }
+ | T_Revoke T_Integer
+ {
+ $$ = NULL;
+ cfgt.auth.revoke = $2;
+ msyslog(LOG_WARNING,
+ "'crypto revoke %d' is deprecated, "
+ "please use 'revoke %d' instead.",
+ cfgt.auth.revoke, cfgt.auth.revoke);
+ }
+ ;
+
+crypto_str_keyword
+ : T_Host
+ | T_Ident
+ | T_Pw
+ | T_Randfile
+ | T_Digest
+ ;
+
+
+/* Orphan Mode Commands
+ * --------------------
+ */
+
+orphan_mode_command
+ : T_Tos tos_option_list
+ { CONCAT_G_FIFOS(cfgt.orphan_cmds, $2); }
+ ;
+
+tos_option_list
+ : tos_option_list tos_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | tos_option
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+tos_option
+ : tos_option_int_keyword T_Integer
+ { $$ = create_attr_dval($1, (double)$2); }
+ | tos_option_dbl_keyword number
+ { $$ = create_attr_dval($1, $2); }
+ | T_Cohort boolean
+ { $$ = create_attr_dval($1, (double)$2); }
+ ;
+
+tos_option_int_keyword
+ : T_Ceiling
+ | T_Floor
+ | T_Orphan
+ | T_Orphanwait
+ | T_Minsane
+ | T_Beacon
+ ;
+
+tos_option_dbl_keyword
+ : T_Mindist
+ | T_Maxdist
+ | T_Minclock
+ | T_Maxclock
+ ;
+
+
+/* Monitoring Commands
+ * -------------------
+ */
+
+monitoring_command
+ : T_Statistics stats_list
+ { CONCAT_G_FIFOS(cfgt.stats_list, $2); }
+ | T_Statsdir T_String
+ {
+ if (input_from_file) {
+ cfgt.stats_dir = $2;
+ } else {
+ YYFREE($2);
+ yyerror(ip_file, "statsdir remote configuration ignored");
+ }
+ }
+ | T_Filegen stat filegen_option_list
+ {
+ filegen_node *fgn;
+
+ fgn = create_filegen_node($2, $3);
+ APPEND_G_FIFO(cfgt.filegen_opts, fgn);
+ }
+ ;
+
+stats_list
+ : stats_list stat
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, create_int_node($2));
+ }
+ | stat
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, create_int_node($1));
+ }
+ ;
+
+stat
+ : T_Clockstats
+ | T_Cryptostats
+ | T_Loopstats
+ | T_Peerstats
+ | T_Rawstats
+ | T_Sysstats
+ | T_Timingstats
+ | T_Protostats
+ ;
+
+filegen_option_list
+ : /* empty list */
+ { $$ = NULL; }
+ | filegen_option_list filegen_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ ;
+
+filegen_option
+ : T_File T_String
+ {
+ if (input_from_file) {
+ $$ = create_attr_sval($1, $2);
+ } else {
+ $$ = NULL;
+ YYFREE($2);
+ yyerror(ip_file, "filegen file remote config ignored");
+ }
+ }
+ | T_Type filegen_type
+ {
+ if (input_from_file) {
+ $$ = create_attr_ival($1, $2);
+ } else {
+ $$ = NULL;
+ yyerror(ip_file, "filegen type remote config ignored");
+ }
+ }
+ | link_nolink
+ {
+ const char *err;
+
+ if (input_from_file) {
+ $$ = create_attr_ival(T_Flag, $1);
+ } else {
+ $$ = NULL;
+ if (T_Link == $1)
+ err = "filegen link remote config ignored";
+ else
+ err = "filegen nolink remote config ignored";
+ yyerror(ip_file, err);
+ }
+ }
+ | enable_disable
+ { $$ = create_attr_ival(T_Flag, $1); }
+ ;
+
+link_nolink
+ : T_Link
+ | T_Nolink
+ ;
+
+enable_disable
+ : T_Enable
+ | T_Disable
+ ;
+
+filegen_type
+ : T_None
+ | T_Pid
+ | T_Day
+ | T_Week
+ | T_Month
+ | T_Year
+ | T_Age
+ ;
+
+
+/* Access Control Commands
+ * -----------------------
+ */
+
+access_control_command
+ : T_Discard discard_option_list
+ {
+ CONCAT_G_FIFOS(cfgt.discard_opts, $2);
+ }
+ | T_Mru mru_option_list
+ {
+ CONCAT_G_FIFOS(cfgt.mru_opts, $2);
+ }
+ | T_Restrict address ac_flag_list
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node($2, NULL, $3,
+ ip_file->line_no);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+ | T_Restrict ip_address T_Mask ip_address ac_flag_list
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node($2, $4, $5,
+ ip_file->line_no);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+ | T_Restrict T_Default ac_flag_list
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node(NULL, NULL, $3,
+ ip_file->line_no);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+ | T_Restrict T_Ipv4_flag T_Default ac_flag_list
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node(
+ create_address_node(
+ estrdup("0.0.0.0"),
+ AF_INET),
+ create_address_node(
+ estrdup("0.0.0.0"),
+ AF_INET),
+ $4,
+ ip_file->line_no);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+ | T_Restrict T_Ipv6_flag T_Default ac_flag_list
+ {
+ restrict_node *rn;
+
+ rn = create_restrict_node(
+ create_address_node(
+ estrdup("::"),
+ AF_INET6),
+ create_address_node(
+ estrdup("::"),
+ AF_INET6),
+ $4,
+ ip_file->line_no);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+ | T_Restrict T_Source ac_flag_list
+ {
+ restrict_node * rn;
+
+ APPEND_G_FIFO($3, create_int_node($2));
+ rn = create_restrict_node(
+ NULL, NULL, $3, ip_file->line_no);
+ APPEND_G_FIFO(cfgt.restrict_opts, rn);
+ }
+ ;
+
+ac_flag_list
+ : /* empty list is allowed */
+ { $$ = NULL; }
+ | ac_flag_list access_control_flag
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, create_int_node($2));
+ }
+ ;
+
+access_control_flag
+ : T_Flake
+ | T_Ignore
+ | T_Kod
+ | T_Mssntp
+ | T_Limited
+ | T_Lowpriotrap
+ | T_Nomodify
+ | T_Nomrulist
+ | T_Nopeer
+ | T_Noquery
+ | T_Noserve
+ | T_Notrap
+ | T_Notrust
+ | T_Ntpport
+ | T_Version
+ ;
+
+discard_option_list
+ : discard_option_list discard_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | discard_option
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+discard_option
+ : discard_option_keyword T_Integer
+ { $$ = create_attr_ival($1, $2); }
+ ;
+
+discard_option_keyword
+ : T_Average
+ | T_Minimum
+ | T_Monitor
+ ;
+
+mru_option_list
+ : mru_option_list mru_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | mru_option
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+mru_option
+ : mru_option_keyword T_Integer
+ { $$ = create_attr_ival($1, $2); }
+ ;
+
+mru_option_keyword
+ : T_Incalloc
+ | T_Incmem
+ | T_Initalloc
+ | T_Initmem
+ | T_Maxage
+ | T_Maxdepth
+ | T_Maxmem
+ | T_Mindepth
+ ;
+
+/* Fudge Commands
+ * --------------
+ */
+
+fudge_command
+ : T_Fudge address fudge_factor_list
+ {
+ addr_opts_node *aon;
+
+ aon = create_addr_opts_node($2, $3);
+ APPEND_G_FIFO(cfgt.fudge, aon);
+ }
+ ;
+
+fudge_factor_list
+ : fudge_factor_list fudge_factor
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | fudge_factor
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+fudge_factor
+ : fudge_factor_dbl_keyword number
+ { $$ = create_attr_dval($1, $2); }
+ | fudge_factor_bool_keyword boolean
+ { $$ = create_attr_ival($1, $2); }
+ | T_Stratum T_Integer
+ { $$ = create_attr_ival($1, $2); }
+ | T_Abbrev T_String
+ { $$ = create_attr_sval($1, $2); }
+ | T_Refid T_String
+ { $$ = create_attr_sval($1, $2); }
+ ;
+
+fudge_factor_dbl_keyword
+ : T_Time1
+ | T_Time2
+ ;
+
+fudge_factor_bool_keyword
+ : T_Flag1
+ | T_Flag2
+ | T_Flag3
+ | T_Flag4
+ ;
+
+/* rlimit Commands
+ * ---------------
+ */
+
+rlimit_command
+ : T_Rlimit rlimit_option_list
+ { CONCAT_G_FIFOS(cfgt.rlimit, $2); }
+ ;
+
+rlimit_option_list
+ : rlimit_option_list rlimit_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | rlimit_option
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+rlimit_option
+ : rlimit_option_keyword T_Integer
+ { $$ = create_attr_ival($1, $2); }
+ ;
+
+rlimit_option_keyword
+ : T_Memlock
+ | T_Stacksize
+ | T_Filenum
+ ;
+
+
+/* Command for System Options
+ * --------------------------
+ */
+
+system_option_command
+ : T_Enable system_option_list
+ { CONCAT_G_FIFOS(cfgt.enable_opts, $2); }
+ | T_Disable system_option_list
+ { CONCAT_G_FIFOS(cfgt.disable_opts, $2); }
+ ;
+
+system_option_list
+ : system_option_list system_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | system_option
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+system_option
+ : system_option_flag_keyword
+ { $$ = create_attr_ival(T_Flag, $1); }
+ | system_option_local_flag_keyword
+ {
+ if (input_from_file) {
+ $$ = create_attr_ival(T_Flag, $1);
+ } else {
+ char err_str[128];
+
+ $$ = NULL;
+ snprintf(err_str, sizeof(err_str),
+ "enable/disable %s remote configuration ignored",
+ keyword($1));
+ yyerror(ip_file, err_str);
+ }
+ }
+ ;
+
+system_option_flag_keyword
+ : T_Auth
+ | T_Bclient
+ | T_Calibrate
+ | T_Kernel
+ | T_Monitor
+ | T_Ntp
+ ;
+
+system_option_local_flag_keyword
+ : T_Mode7
+ | T_Stats
+ ;
+
+/* Tinker Commands
+ * ---------------
+ */
+
+tinker_command
+ : T_Tinker tinker_option_list
+ { CONCAT_G_FIFOS(cfgt.tinker, $2); }
+ ;
+
+tinker_option_list
+ : tinker_option_list tinker_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | tinker_option
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+tinker_option
+ : tinker_option_keyword number
+ { $$ = create_attr_dval($1, $2); }
+ ;
+
+tinker_option_keyword
+ : T_Allan
+ | T_Dispersion
+ | T_Freq
+ | T_Huffpuff
+ | T_Panic
+ | T_Step
+ | T_Stepout
+ | T_Tick
+ ;
+
+
+/* Miscellaneous Commands
+ * ----------------------
+ */
+
+miscellaneous_command
+ : interface_command
+ | reset_command
+ | misc_cmd_dbl_keyword number
+ {
+ attr_val *av;
+
+ av = create_attr_dval($1, $2);
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+ | misc_cmd_str_keyword T_String
+ {
+ attr_val *av;
+
+ av = create_attr_sval($1, $2);
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+ | misc_cmd_str_lcl_keyword T_String
+ {
+ char error_text[64];
+ attr_val *av;
+
+ if (input_from_file) {
+ av = create_attr_sval($1, $2);
+ APPEND_G_FIFO(cfgt.vars, av);
+ } else {
+ YYFREE($2);
+ snprintf(error_text, sizeof(error_text),
+ "%s remote config ignored",
+ keyword($1));
+ yyerror(ip_file, error_text);
+ }
+ }
+ | T_Includefile T_String command
+ {
+ if (!input_from_file) {
+ yyerror(ip_file, "remote includefile ignored");
+ break;
+ }
+ if (curr_include_level >= MAXINCLUDELEVEL) {
+ fprintf(stderr, "getconfig: Maximum include file level exceeded.\n");
+ msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded.");
+ } else {
+ fp[curr_include_level + 1] = F_OPEN(FindConfig($2), "r");
+ if (fp[curr_include_level + 1] == NULL) {
+ fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig($2));
+ msyslog(LOG_ERR, "getconfig: Couldn't open <%s>", FindConfig($2));
+ } else {
+ ip_file = fp[++curr_include_level];
+ }
+ }
+ }
+ | T_End
+ {
+ while (curr_include_level != -1)
+ FCLOSE(fp[curr_include_level--]);
+ }
+ | T_Driftfile drift_parm
+ { /* see drift_parm below for actions */ }
+ | T_Logconfig log_config_list
+ { CONCAT_G_FIFOS(cfgt.logconfig, $2); }
+ | T_Phone string_list
+ { CONCAT_G_FIFOS(cfgt.phone, $2); }
+ | T_Setvar variable_assign
+ { APPEND_G_FIFO(cfgt.setvar, $2); }
+ | T_Trap ip_address trap_option_list
+ {
+ addr_opts_node *aon;
+
+ aon = create_addr_opts_node($2, $3);
+ APPEND_G_FIFO(cfgt.trap, aon);
+ }
+ | T_Ttl integer_list
+ { CONCAT_G_FIFOS(cfgt.ttl, $2); }
+ ;
+
+misc_cmd_dbl_keyword
+ : T_Broadcastdelay
+ | T_Nonvolatile
+ | T_Tick
+ ;
+
+misc_cmd_str_keyword
+ : T_Ident
+ | T_Leapfile
+ | T_Pidfile
+ ;
+
+misc_cmd_str_lcl_keyword
+ : T_Logfile
+ | T_Saveconfigdir
+ ;
+
+drift_parm
+ : T_String
+ {
+ attr_val *av;
+
+ av = create_attr_sval(T_Driftfile, $1);
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+ | T_String T_Double
+ {
+ attr_val *av;
+
+ av = create_attr_sval(T_Driftfile, $1);
+ APPEND_G_FIFO(cfgt.vars, av);
+ av = create_attr_dval(T_WanderThreshold, $2);
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+ | /* Null driftfile, indicated by empty string "" */
+ {
+ attr_val *av;
+
+ av = create_attr_sval(T_Driftfile, "");
+ APPEND_G_FIFO(cfgt.vars, av);
+ }
+ ;
+
+variable_assign
+ : T_String '=' T_String t_default_or_zero
+ { $$ = create_setvar_node($1, $3, $4); }
+ ;
+
+t_default_or_zero
+ : T_Default
+ | /* empty, no "default" modifier */
+ { $$ = 0; }
+ ;
+
+trap_option_list
+ : /* empty list */
+ { $$ = NULL; }
+ | trap_option_list trap_option
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ ;
+
+trap_option
+ : T_Port T_Integer
+ { $$ = create_attr_ival($1, $2); }
+ | T_Interface ip_address
+ {
+ $$ = create_attr_sval($1, estrdup($2->address));
+ destroy_address_node($2);
+ }
+ ;
+
+log_config_list
+ : log_config_list log_config_command
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | log_config_command
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+log_config_command
+ : T_String
+ {
+ char prefix;
+ char * type;
+
+ switch ($1[0]) {
+
+ case '+':
+ case '-':
+ case '=':
+ prefix = $1[0];
+ type = $1 + 1;
+ break;
+
+ default:
+ prefix = '=';
+ type = $1;
+ }
+
+ $$ = create_attr_sval(prefix, estrdup(type));
+ YYFREE($1);
+ }
+ ;
+
+interface_command
+ : interface_nic nic_rule_action nic_rule_class
+ {
+ nic_rule_node *nrn;
+
+ nrn = create_nic_rule_node($3, NULL, $2);
+ APPEND_G_FIFO(cfgt.nic_rules, nrn);
+ }
+ | interface_nic nic_rule_action T_String
+ {
+ nic_rule_node *nrn;
+
+ nrn = create_nic_rule_node(0, $3, $2);
+ APPEND_G_FIFO(cfgt.nic_rules, nrn);
+ }
+ ;
+
+interface_nic
+ : T_Interface
+ | T_Nic
+ ;
+
+nic_rule_class
+ : T_All
+ | T_Ipv4
+ | T_Ipv6
+ | T_Wildcard
+ ;
+
+nic_rule_action
+ : T_Listen
+ | T_Ignore
+ | T_Drop
+ ;
+
+reset_command
+ : T_Reset counter_set_list
+ { CONCAT_G_FIFOS(cfgt.reset_counters, $2); }
+ ;
+
+counter_set_list
+ : counter_set_list counter_set_keyword
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, create_int_node($2));
+ }
+ | counter_set_keyword
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, create_int_node($1));
+ }
+ ;
+
+counter_set_keyword
+ : T_Allpeers
+ | T_Auth
+ | T_Ctl
+ | T_Io
+ | T_Mem
+ | T_Sys
+ | T_Timer
+ ;
+
+
+
+/* Miscellaneous Rules
+ * -------------------
+ */
+
+integer_list
+ : integer_list T_Integer
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, create_int_node($2));
+ }
+ | T_Integer
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, create_int_node($1));
+ }
+ ;
+
+integer_list_range
+ : integer_list_range integer_list_range_elt
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | integer_list_range_elt
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+integer_list_range_elt
+ : T_Integer
+ { $$ = create_attr_ival('i', $1); }
+ | integer_range
+ ;
+
+integer_range
+ : '(' T_Integer T_Ellipsis T_Integer ')'
+ { $$ = create_attr_rangeval('-', $2, $4); }
+ ;
+
+string_list
+ : string_list T_String
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, create_string_node($2));
+ }
+ | T_String
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, create_string_node($1));
+ }
+ ;
+
+address_list
+ : address_list address
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | address
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+boolean
+ : T_Integer
+ {
+ if ($1 != 0 && $1 != 1) {
+ yyerror(ip_file, "Integer value is not boolean (0 or 1). Assuming 1");
+ $$ = 1;
+ } else {
+ $$ = $1;
+ }
+ }
+ | T_True { $$ = 1; }
+ | T_False { $$ = 0; }
+ ;
+
+number
+ : T_Integer { $$ = (double)$1; }
+ | T_Double
+ ;
+
+
+/* Simulator Configuration Commands
+ * --------------------------------
+ */
+
+simulate_command
+ : sim_conf_start '{' sim_init_statement_list sim_server_list '}'
+ {
+ sim_node *sn;
+
+ sn = create_sim_node($3, $4);
+ APPEND_G_FIFO(cfgt.sim_details, sn);
+
+ /* Revert from ; to \n for end-of-command */
+ old_config_style = 1;
+ }
+ ;
+
+/* The following is a terrible hack to get the configuration file to
+ * treat newlines as whitespace characters within the simulation.
+ * This is needed because newlines are significant in the rest of the
+ * configuration file.
+ */
+sim_conf_start
+ : T_Simulate { old_config_style = 0; }
+ ;
+
+sim_init_statement_list
+ : sim_init_statement_list sim_init_statement T_EOC
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | sim_init_statement T_EOC
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+sim_init_statement
+ : sim_init_keyword '=' number
+ { $$ = create_attr_dval($1, $3); }
+ ;
+
+sim_init_keyword
+ : T_Beep_Delay
+ | T_Sim_Duration
+ ;
+
+sim_server_list
+ : sim_server_list sim_server
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | sim_server
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+sim_server
+ : sim_server_name '{' sim_server_offset sim_act_list '}'
+ { $$ = ONLY_SIM(create_sim_server($1, $3, $4)); }
+ ;
+
+sim_server_offset
+ : T_Server_Offset '=' number T_EOC
+ { $$ = $3; }
+ ;
+
+sim_server_name
+ : T_Server '=' address
+ { $$ = $3; }
+ ;
+
+sim_act_list
+ : sim_act_list sim_act
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | sim_act
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+sim_act
+ : T_Duration '=' number '{' sim_act_stmt_list '}'
+ { $$ = ONLY_SIM(create_sim_script_info($3, $5)); }
+ ;
+
+sim_act_stmt_list
+ : sim_act_stmt_list sim_act_stmt T_EOC
+ {
+ $$ = $1;
+ APPEND_G_FIFO($$, $2);
+ }
+ | sim_act_stmt T_EOC
+ {
+ $$ = NULL;
+ APPEND_G_FIFO($$, $1);
+ }
+ ;
+
+sim_act_stmt
+ : sim_act_keyword '=' number
+ { $$ = create_attr_dval($1, $3); }
+ ;
+
+sim_act_keyword
+ : T_Freq_Offset
+ | T_Wander
+ | T_Jitter
+ | T_Prop_Delay
+ | T_Proc_Delay
+ ;
+
+%%
+
+void
+yyerror(
+ struct FILE_INFO *ip_file,
+ const char *msg
+ )
+{
+ int retval;
+
+ ip_file->err_line_no = ip_file->prev_token_line_no;
+ ip_file->err_col_no = ip_file->prev_token_col_no;
+
+ msyslog(LOG_ERR,
+ "line %d column %d %s",
+ ip_file->err_line_no,
+ ip_file->err_col_no,
+ msg);
+ if (!input_from_file) {
+ /* Save the error message in the correct buffer */
+ retval = snprintf(remote_config.err_msg + remote_config.err_pos,
+ MAXLINE - remote_config.err_pos,
+ "column %d %s",
+ ip_file->err_col_no, msg);
+
+ /* Increment the value of err_pos */
+ if (retval > 0)
+ remote_config.err_pos += retval;
+
+ /* Increment the number of errors */
+ ++remote_config.no_errors;
+ }
+}
+
+
+/*
+ * token_name - convert T_ token integers to text
+ * example: token_name(T_Server) returns "T_Server"
+ */
+const char *
+token_name(
+ int token
+ )
+{
+ return yytname[YYTRANSLATE(token)];
+}
+
+
+/* Initial Testing function -- ignore */
+#if 0
+int main(int argc, char *argv[])
+{
+ ip_file = FOPEN(argv[1], "r");
+ if (!ip_file)
+ fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]);
+ yyparse();
+ return 0;
+}
+#endif
+