diff options
Diffstat (limited to 'ntpd/ntp_parser.y')
-rw-r--r-- | ntpd/ntp_parser.y | 1638 |
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 + |