1 /* $NetBSD: ntp_parser.y,v 1.4 2010/12/04 23:08:35 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 "ntpd.h" 19 #include "ntp_machine.h" 20 #include "ntp.h" 21 #include "ntp_stdlib.h" 22 #include "ntp_filegen.h" 23 #include "ntp_data_structures.h" 24 #include "ntp_scanner.h" 25 #include "ntp_config.h" 26 #include "ntp_crypto.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 36 struct FILE_INFO *ip_file; /* Pointer to the configuration file stream */ 37 38 #define YYMALLOC emalloc 39 #define YYFREE free 40 #define YYERROR_VERBOSE 41 #define YYMAXDEPTH 1000 /* stop the madness sooner */ 42 void yyerror (const char *msg); 43 extern int input_from_file; /* 0=input from ntpq :config */ 44 %} 45 46 /* 47 * Enable generation of token names array even without YYDEBUG. 48 * We access via token_name() defined below. 49 */ 50 %token-table 51 52 %union { 53 char *String; 54 double Double; 55 int Integer; 56 void *VoidPtr; 57 queue *Queue; 58 struct attr_val *Attr_val; 59 struct address_node *Address_node; 60 struct setvar_node *Set_var; 61 62 /* Simulation types */ 63 server_info *Sim_server; 64 script_info *Sim_script; 65 } 66 67 /* TERMINALS (do not appear left of colon) */ 68 %token <Integer> T_Age 69 %token <Integer> T_All 70 %token <Integer> T_Allan 71 %token <Integer> T_Auth 72 %token <Integer> T_Autokey 73 %token <Integer> T_Automax 74 %token <Integer> T_Average 75 %token <Integer> T_Bclient 76 %token <Integer> T_Beacon 77 %token <Integer> T_Bias 78 %token <Integer> T_Broadcast 79 %token <Integer> T_Broadcastclient 80 %token <Integer> T_Broadcastdelay 81 %token <Integer> T_Burst 82 %token <Integer> T_Calibrate 83 %token <Integer> T_Calldelay 84 %token <Integer> T_Ceiling 85 %token <Integer> T_Clockstats 86 %token <Integer> T_Cohort 87 %token <Integer> T_ControlKey 88 %token <Integer> T_Crypto 89 %token <Integer> T_Cryptostats 90 %token <Integer> T_Day 91 %token <Integer> T_Default 92 %token <Integer> T_Digest 93 %token <Integer> T_Disable 94 %token <Integer> T_Discard 95 %token <Integer> T_Dispersion 96 %token <Double> T_Double 97 %token <Integer> T_Driftfile 98 %token <Integer> T_Drop 99 %token <Integer> T_Enable 100 %token <Integer> T_End 101 %token <Integer> T_False 102 %token <Integer> T_File 103 %token <Integer> T_Filegen 104 %token <Integer> T_Flag1 105 %token <Integer> T_Flag2 106 %token <Integer> T_Flag3 107 %token <Integer> T_Flag4 108 %token <Integer> T_Flake 109 %token <Integer> T_Floor 110 %token <Integer> T_Freq 111 %token <Integer> T_Fudge 112 %token <Integer> T_Host 113 %token <Integer> T_Huffpuff 114 %token <Integer> T_Iburst 115 %token <Integer> T_Ident 116 %token <Integer> T_Ignore 117 %token <Integer> T_Includefile 118 %token <Integer> T_Integer 119 %token <Integer> T_Interface 120 %token <Integer> T_Ipv4 121 %token <Integer> T_Ipv4_flag 122 %token <Integer> T_Ipv6 123 %token <Integer> T_Ipv6_flag 124 %token <Integer> T_Kernel 125 %token <Integer> T_Key 126 %token <Integer> T_Keys 127 %token <Integer> T_Keysdir 128 %token <Integer> T_Kod 129 %token <Integer> T_Mssntp 130 %token <Integer> T_Leapfile 131 %token <Integer> T_Limited 132 %token <Integer> T_Link 133 %token <Integer> T_Listen 134 %token <Integer> T_Logconfig 135 %token <Integer> T_Logfile 136 %token <Integer> T_Loopstats 137 %token <Integer> T_Lowpriotrap 138 %token <Integer> T_Manycastclient 139 %token <Integer> T_Manycastserver 140 %token <Integer> T_Mask 141 %token <Integer> T_Maxclock 142 %token <Integer> T_Maxdist 143 %token <Integer> T_Maxpoll 144 %token <Integer> T_Mdnstries 145 %token <Integer> T_Minclock 146 %token <Integer> T_Mindist 147 %token <Integer> T_Minimum 148 %token <Integer> T_Minpoll 149 %token <Integer> T_Minsane 150 %token <Integer> T_Mode 151 %token <Integer> T_Monitor 152 %token <Integer> T_Month 153 %token <Integer> T_Multicastclient 154 %token <Integer> T_Nic 155 %token <Integer> T_Nolink 156 %token <Integer> T_Nomodify 157 %token <Integer> T_None 158 %token <Integer> T_Nopeer 159 %token <Integer> T_Noquery 160 %token <Integer> T_Noselect 161 %token <Integer> T_Noserve 162 %token <Integer> T_Notrap 163 %token <Integer> T_Notrust 164 %token <Integer> T_Ntp 165 %token <Integer> T_Ntpport 166 %token <Integer> T_NtpSignDsocket 167 %token <Integer> T_Orphan 168 %token <Integer> T_Panic 169 %token <Integer> T_Peer 170 %token <Integer> T_Peerstats 171 %token <Integer> T_Phone 172 %token <Integer> T_Pid 173 %token <Integer> T_Pidfile 174 %token <Integer> T_Pool 175 %token <Integer> T_Port 176 %token <Integer> T_Preempt 177 %token <Integer> T_Prefer 178 %token <Integer> T_Protostats 179 %token <Integer> T_Pw 180 %token <Integer> T_Qos 181 %token <Integer> T_Randfile 182 %token <Integer> T_Rawstats 183 %token <Integer> T_Refid 184 %token <Integer> T_Requestkey 185 %token <Integer> T_Restrict 186 %token <Integer> T_Revoke 187 %token <Integer> T_Saveconfigdir 188 %token <Integer> T_Server 189 %token <Integer> T_Setvar 190 %token <Integer> T_Sign 191 %token <Integer> T_Statistics 192 %token <Integer> T_Stats 193 %token <Integer> T_Statsdir 194 %token <Integer> T_Step 195 %token <Integer> T_Stepout 196 %token <Integer> T_Stratum 197 %token <String> T_String 198 %token <Integer> T_Sysstats 199 %token <Integer> T_Tick 200 %token <Integer> T_Time1 201 %token <Integer> T_Time2 202 %token <Integer> T_Timingstats 203 %token <Integer> T_Tinker 204 %token <Integer> T_Tos 205 %token <Integer> T_Trap 206 %token <Integer> T_True 207 %token <Integer> T_Trustedkey 208 %token <Integer> T_Ttl 209 %token <Integer> T_Type 210 %token <Integer> T_Unconfig 211 %token <Integer> T_Unpeer 212 %token <Integer> T_Version 213 %token <Integer> T_WanderThreshold /* Not a token */ 214 %token <Integer> T_Week 215 %token <Integer> T_Wildcard 216 %token <Integer> T_Xleave 217 %token <Integer> T_Year 218 %token <Integer> T_Flag /* Not an actual token */ 219 %token <Integer> T_Void /* Not an actual token */ 220 %token <Integer> T_EOC 221 222 223 /* NTP Simulator Tokens */ 224 %token <Integer> T_Simulate 225 %token <Integer> T_Beep_Delay 226 %token <Integer> T_Sim_Duration 227 %token <Integer> T_Server_Offset 228 %token <Integer> T_Duration 229 %token <Integer> T_Freq_Offset 230 %token <Integer> T_Wander 231 %token <Integer> T_Jitter 232 %token <Integer> T_Prop_Delay 233 %token <Integer> T_Proc_Delay 234 235 236 237 /*** NON-TERMINALS ***/ 238 %type <Integer> access_control_flag 239 %type <Queue> ac_flag_list 240 %type <Address_node> address 241 %type <Queue> address_list 242 %type <Integer> boolean 243 %type <Integer> client_type 244 %type <Attr_val> crypto_command 245 %type <Queue> crypto_command_line 246 %type <Queue> crypto_command_list 247 %type <Attr_val> discard_option 248 %type <Queue> discard_option_list 249 %type <Attr_val> filegen_option 250 %type <Queue> filegen_option_list 251 %type <Integer> filegen_type 252 %type <Attr_val> fudge_factor 253 %type <Queue> fudge_factor_list 254 %type <Queue> integer_list 255 %type <Integer> nic_rule_action 256 %type <Queue> interface_command 257 %type <Integer> interface_nic 258 %type <Address_node> ip_address 259 %type <Attr_val> log_config_command 260 %type <Queue> log_config_list 261 %type <Integer> nic_rule_class 262 %type <Double> number 263 %type <Attr_val> option 264 %type <Queue> option_list 265 %type <Integer> stat 266 %type <Queue> stats_list 267 %type <Queue> string_list 268 %type <Attr_val> system_option 269 %type <Queue> system_option_list 270 %type <Attr_val> tinker_option 271 %type <Queue> tinker_option_list 272 %type <Attr_val> tos_option 273 %type <Queue> tos_option_list 274 %type <Attr_val> trap_option 275 %type <Queue> trap_option_list 276 %type <Integer> unpeer_keyword 277 %type <Set_var> variable_assign 278 279 /* NTP Simulator non-terminals */ 280 %type <Queue> sim_init_statement_list 281 %type <Attr_val> sim_init_statement 282 %type <Queue> sim_server_list 283 %type <Sim_server> sim_server 284 %type <Double> sim_server_offset 285 %type <Address_node> sim_server_name 286 %type <Queue> sim_act_list 287 %type <Sim_script> sim_act 288 %type <Queue> sim_act_stmt_list 289 %type <Attr_val> sim_act_stmt 290 291 %% 292 293 /* ntp.conf 294 * Configuration File Grammar 295 * -------------------------- 296 */ 297 298 configuration 299 : command_list 300 ; 301 302 command_list 303 : command_list command T_EOC 304 | command T_EOC 305 | error T_EOC 306 { 307 /* I will need to incorporate much more fine grained 308 * error messages. The following should suffice for 309 * the time being. 310 */ 311 msyslog(LOG_ERR, 312 "syntax error in %s line %d, column %d", 313 ip_file->fname, 314 ip_file->err_line_no, 315 ip_file->err_col_no); 316 } 317 ; 318 319 command : /* NULL STATEMENT */ 320 | server_command 321 | unpeer_command 322 | other_mode_command 323 | authentication_command 324 | monitoring_command 325 | access_control_command 326 | orphan_mode_command 327 | fudge_command 328 | system_option_command 329 | tinker_command 330 | miscellaneous_command 331 | simulate_command 332 ; 333 334 /* Server Commands 335 * --------------- 336 */ 337 338 server_command 339 : client_type address option_list 340 { 341 struct peer_node *my_node = create_peer_node($1, $2, $3); 342 if (my_node) 343 enqueue(cfgt.peers, my_node); 344 } 345 | client_type address 346 { 347 struct peer_node *my_node = create_peer_node($1, $2, NULL); 348 if (my_node) 349 enqueue(cfgt.peers, my_node); 350 } 351 ; 352 353 client_type 354 : T_Server 355 | T_Pool 356 | T_Peer 357 | T_Broadcast 358 | T_Manycastclient 359 ; 360 361 address 362 : ip_address 363 | T_Ipv4_flag T_String { $$ = create_address_node($2, AF_INET); } 364 | T_Ipv6_flag T_String { $$ = create_address_node($2, AF_INET6); } 365 ; 366 367 ip_address 368 : T_String { $$ = create_address_node($1, 0); } 369 ; 370 371 option_list 372 : option_list option { $$ = enqueue($1, $2); } 373 | option { $$ = enqueue_in_new_queue($1); } 374 ; 375 376 option 377 : T_Autokey { $$ = create_attr_ival(T_Flag, $1); } 378 | T_Bias number { $$ = create_attr_dval($1, $2); } 379 | T_Burst { $$ = create_attr_ival(T_Flag, $1); } 380 | T_Iburst { $$ = create_attr_ival(T_Flag, $1); } 381 | T_Key T_Integer { $$ = create_attr_ival($1, $2); } 382 | T_Minpoll T_Integer { $$ = create_attr_ival($1, $2); } 383 | T_Maxpoll T_Integer { $$ = create_attr_ival($1, $2); } 384 | T_Noselect { $$ = create_attr_ival(T_Flag, $1); } 385 | T_Preempt { $$ = create_attr_ival(T_Flag, $1); } 386 | T_Prefer { $$ = create_attr_ival(T_Flag, $1); } 387 | T_True { $$ = create_attr_ival(T_Flag, $1); } 388 | T_Xleave { $$ = create_attr_ival(T_Flag, $1); } 389 | T_Ttl T_Integer { $$ = create_attr_ival($1, $2); } 390 | T_Mode T_Integer { $$ = create_attr_ival($1, $2); } 391 | T_Version T_Integer { $$ = create_attr_ival($1, $2); } 392 ; 393 394 395 /* unpeer commands 396 * --------------- 397 */ 398 399 unpeer_command 400 : unpeer_keyword address 401 { 402 struct unpeer_node *my_node = create_unpeer_node($2); 403 if (my_node) 404 enqueue(cfgt.unpeers, my_node); 405 } 406 ; 407 unpeer_keyword 408 : T_Unconfig 409 | T_Unpeer 410 ; 411 412 413 /* Other Modes 414 * (broadcastclient manycastserver multicastclient) 415 * ------------------------------------------------ 416 */ 417 418 other_mode_command 419 : T_Broadcastclient 420 { cfgt.broadcastclient = 1; } 421 | T_Manycastserver address_list 422 { append_queue(cfgt.manycastserver, $2); } 423 | T_Multicastclient address_list 424 { append_queue(cfgt.multicastclient, $2); } 425 | T_Mdnstries T_Integer 426 { cfgt.mdnstries = $2; } 427 ; 428 429 430 431 /* Authentication Commands 432 * ----------------------- 433 */ 434 435 authentication_command 436 : T_Automax T_Integer 437 { enqueue(cfgt.vars, create_attr_ival($1, $2)); } 438 | T_ControlKey T_Integer 439 { cfgt.auth.control_key = $2; } 440 | T_Crypto crypto_command_line 441 { 442 cfgt.auth.cryptosw++; 443 append_queue(cfgt.auth.crypto_cmd_list, $2); 444 } 445 | T_Keys T_String 446 { cfgt.auth.keys = $2; } 447 | T_Keysdir T_String 448 { cfgt.auth.keysdir = $2; } 449 | T_Requestkey T_Integer 450 { cfgt.auth.request_key = $2; } 451 | T_Revoke T_Integer 452 { cfgt.auth.revoke = $2; } 453 | T_Trustedkey integer_list 454 { cfgt.auth.trusted_key_list = $2; } 455 | T_NtpSignDsocket T_String 456 { cfgt.auth.ntp_signd_socket = $2; } 457 ; 458 459 crypto_command_line 460 : crypto_command_list 461 | /* Null list */ 462 { $$ = create_queue(); } 463 ; 464 465 crypto_command_list 466 : crypto_command_list crypto_command 467 { 468 if ($2 != NULL) 469 $$ = enqueue($1, $2); 470 else 471 $$ = $1; 472 } 473 | crypto_command 474 { 475 if ($1 != NULL) 476 $$ = enqueue_in_new_queue($1); 477 else 478 $$ = create_queue(); 479 } 480 ; 481 482 crypto_command 483 : T_Host T_String 484 { $$ = create_attr_sval($1, $2); } 485 | T_Ident T_String 486 { $$ = create_attr_sval($1, $2); } 487 | T_Pw T_String 488 { $$ = create_attr_sval($1, $2); } 489 | T_Randfile T_String 490 { $$ = create_attr_sval($1, $2); } 491 | T_Sign T_String 492 { $$ = create_attr_sval($1, $2); } 493 | T_Digest T_String 494 { $$ = create_attr_sval($1, $2); } 495 | T_Revoke T_Integer 496 { 497 $$ = NULL; 498 cfgt.auth.revoke = $2; 499 msyslog(LOG_WARNING, 500 "'crypto revoke %d' is deprecated, " 501 "please use 'revoke %d' instead.", 502 cfgt.auth.revoke, cfgt.auth.revoke); 503 } 504 ; 505 506 507 /* Orphan Mode Commands 508 * -------------------- 509 */ 510 511 orphan_mode_command 512 : T_Tos tos_option_list 513 { append_queue(cfgt.orphan_cmds,$2); } 514 ; 515 516 tos_option_list 517 : tos_option_list tos_option { $$ = enqueue($1, $2); } 518 | tos_option { $$ = enqueue_in_new_queue($1); } 519 ; 520 521 tos_option 522 : T_Ceiling T_Integer 523 { $$ = create_attr_dval($1, (double)$2); } 524 | T_Floor T_Integer 525 { $$ = create_attr_dval($1, (double)$2); } 526 | T_Cohort boolean 527 { $$ = create_attr_dval($1, (double)$2); } 528 | T_Orphan T_Integer 529 { $$ = create_attr_dval($1, (double)$2); } 530 | T_Mindist number 531 { $$ = create_attr_dval($1, $2); } 532 | T_Maxdist number 533 { $$ = create_attr_dval($1, $2); } 534 | T_Minclock number 535 { $$ = create_attr_dval($1, $2); } 536 | T_Maxclock number 537 { $$ = create_attr_dval($1, $2); } 538 | T_Minsane T_Integer 539 { $$ = create_attr_dval($1, (double)$2); } 540 | T_Beacon T_Integer 541 { $$ = create_attr_dval($1, (double)$2); } 542 ; 543 544 545 /* Monitoring Commands 546 * ------------------- 547 */ 548 549 monitoring_command 550 : T_Statistics stats_list 551 { append_queue(cfgt.stats_list, $2); } 552 | T_Statsdir T_String 553 { 554 if (input_from_file) 555 cfgt.stats_dir = $2; 556 else { 557 free($2); 558 yyerror("statsdir remote configuration ignored"); 559 } 560 } 561 | T_Filegen stat filegen_option_list 562 { 563 enqueue(cfgt.filegen_opts, 564 create_filegen_node($2, $3)); 565 } 566 ; 567 568 stats_list 569 : stats_list stat { $$ = enqueue($1, create_ival($2)); } 570 | stat { $$ = enqueue_in_new_queue(create_ival($1)); } 571 ; 572 573 stat 574 : T_Clockstats 575 | T_Cryptostats 576 | T_Loopstats 577 | T_Peerstats 578 | T_Rawstats 579 | T_Sysstats 580 | T_Timingstats 581 | T_Protostats 582 ; 583 584 filegen_option_list 585 : filegen_option_list filegen_option 586 { 587 if ($2 != NULL) 588 $$ = enqueue($1, $2); 589 else 590 $$ = $1; 591 } 592 | filegen_option 593 { 594 if ($1 != NULL) 595 $$ = enqueue_in_new_queue($1); 596 else 597 $$ = create_queue(); 598 } 599 ; 600 601 filegen_option 602 : T_File T_String 603 { 604 if (input_from_file) 605 $$ = create_attr_sval($1, $2); 606 else { 607 $$ = NULL; 608 free($2); 609 yyerror("filegen file remote configuration ignored"); 610 } 611 } 612 | T_Type filegen_type 613 { 614 if (input_from_file) 615 $$ = create_attr_ival($1, $2); 616 else { 617 $$ = NULL; 618 yyerror("filegen type remote configuration ignored"); 619 } 620 } 621 | T_Link 622 { 623 if (input_from_file) 624 $$ = create_attr_ival(T_Flag, $1); 625 else { 626 $$ = NULL; 627 yyerror("filegen link remote configuration ignored"); 628 } 629 } 630 | T_Nolink 631 { 632 if (input_from_file) 633 $$ = create_attr_ival(T_Flag, $1); 634 else { 635 $$ = NULL; 636 yyerror("filegen nolink remote configuration ignored"); 637 } 638 } 639 | T_Enable { $$ = create_attr_ival(T_Flag, $1); } 640 | T_Disable { $$ = create_attr_ival(T_Flag, $1); } 641 ; 642 643 filegen_type 644 : T_None 645 | T_Pid 646 | T_Day 647 | T_Week 648 | T_Month 649 | T_Year 650 | T_Age 651 ; 652 653 654 /* Access Control Commands 655 * ----------------------- 656 */ 657 658 access_control_command 659 : T_Discard discard_option_list 660 { 661 append_queue(cfgt.discard_opts, $2); 662 } 663 | T_Restrict address ac_flag_list 664 { 665 enqueue(cfgt.restrict_opts, 666 create_restrict_node($2, NULL, $3, ip_file->line_no)); 667 } 668 | T_Restrict T_Default ac_flag_list 669 { 670 enqueue(cfgt.restrict_opts, 671 create_restrict_node(NULL, NULL, $3, ip_file->line_no)); 672 } 673 | T_Restrict T_Ipv4_flag T_Default ac_flag_list 674 { 675 enqueue(cfgt.restrict_opts, 676 create_restrict_node( 677 create_address_node( 678 estrdup("0.0.0.0"), 679 AF_INET), 680 create_address_node( 681 estrdup("255.255.255.255"), 682 AF_INET), 683 $4, 684 ip_file->line_no)); 685 } 686 | T_Restrict T_Ipv6_flag T_Default ac_flag_list 687 { 688 enqueue(cfgt.restrict_opts, 689 create_restrict_node( 690 create_address_node( 691 estrdup("::"), 692 AF_INET6), 693 create_address_node( 694 estrdup("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"), 695 AF_INET6), 696 $4, 697 ip_file->line_no)); 698 } 699 | T_Restrict ip_address T_Mask ip_address ac_flag_list 700 { 701 enqueue(cfgt.restrict_opts, 702 create_restrict_node($2, $4, $5, ip_file->line_no)); 703 } 704 ; 705 706 ac_flag_list 707 : /* Null statement */ 708 { $$ = create_queue(); } 709 | ac_flag_list access_control_flag 710 { $$ = enqueue($1, create_ival($2)); } 711 ; 712 713 access_control_flag 714 : T_Flake 715 | T_Ignore 716 | T_Kod 717 | T_Mssntp 718 | T_Limited 719 | T_Lowpriotrap 720 | T_Nomodify 721 | T_Nopeer 722 | T_Noquery 723 | T_Noserve 724 | T_Notrap 725 | T_Notrust 726 | T_Ntpport 727 | T_Version 728 ; 729 730 discard_option_list 731 : discard_option_list discard_option 732 { $$ = enqueue($1, $2); } 733 | discard_option 734 { $$ = enqueue_in_new_queue($1); } 735 ; 736 737 discard_option 738 : T_Average T_Integer { $$ = create_attr_ival($1, $2); } 739 | T_Minimum T_Integer { $$ = create_attr_ival($1, $2); } 740 | T_Monitor T_Integer { $$ = create_attr_ival($1, $2); } 741 ; 742 743 /* Fudge Commands 744 * -------------- 745 */ 746 747 fudge_command 748 : T_Fudge address fudge_factor_list 749 { enqueue(cfgt.fudge, create_addr_opts_node($2, $3)); } 750 ; 751 752 fudge_factor_list 753 : fudge_factor_list fudge_factor 754 { enqueue($1, $2); } 755 | fudge_factor 756 { $$ = enqueue_in_new_queue($1); } 757 ; 758 759 fudge_factor 760 : T_Time1 number { $$ = create_attr_dval($1, $2); } 761 | T_Time2 number { $$ = create_attr_dval($1, $2); } 762 | T_Stratum T_Integer { $$ = create_attr_ival($1, $2); } 763 | T_Refid T_String { $$ = create_attr_sval($1, $2); } 764 | T_Flag1 boolean { $$ = create_attr_ival($1, $2); } 765 | T_Flag2 boolean { $$ = create_attr_ival($1, $2); } 766 | T_Flag3 boolean { $$ = create_attr_ival($1, $2); } 767 | T_Flag4 boolean { $$ = create_attr_ival($1, $2); } 768 ; 769 770 /* Command for System Options 771 * -------------------------- 772 */ 773 774 system_option_command 775 : T_Enable system_option_list 776 { append_queue(cfgt.enable_opts, $2); } 777 | T_Disable system_option_list 778 { append_queue(cfgt.disable_opts, $2); } 779 ; 780 781 system_option_list 782 : system_option_list system_option 783 { 784 if ($2 != NULL) 785 $$ = enqueue($1, $2); 786 else 787 $$ = $1; 788 } 789 | system_option 790 { 791 if ($1 != NULL) 792 $$ = enqueue_in_new_queue($1); 793 else 794 $$ = create_queue(); 795 } 796 ; 797 798 system_option 799 : T_Auth { $$ = create_attr_ival(T_Flag, $1); } 800 | T_Bclient { $$ = create_attr_ival(T_Flag, $1); } 801 | T_Calibrate { $$ = create_attr_ival(T_Flag, $1); } 802 | T_Kernel { $$ = create_attr_ival(T_Flag, $1); } 803 | T_Monitor { $$ = create_attr_ival(T_Flag, $1); } 804 | T_Ntp { $$ = create_attr_ival(T_Flag, $1); } 805 | T_Stats 806 { 807 if (input_from_file) 808 $$ = create_attr_ival(T_Flag, $1); 809 else { 810 $$ = NULL; 811 yyerror("enable/disable stats remote configuration ignored"); 812 } 813 } 814 ; 815 816 /* Tinker Commands 817 * --------------- 818 */ 819 820 tinker_command 821 : T_Tinker tinker_option_list { append_queue(cfgt.tinker, $2); } 822 ; 823 824 tinker_option_list 825 : tinker_option_list tinker_option { $$ = enqueue($1, $2); } 826 | tinker_option { $$ = enqueue_in_new_queue($1); } 827 ; 828 829 tinker_option 830 : T_Allan number { $$ = create_attr_dval($1, $2); } 831 | T_Dispersion number { $$ = create_attr_dval($1, $2); } 832 | T_Freq number { $$ = create_attr_dval($1, $2); } 833 | T_Huffpuff number { $$ = create_attr_dval($1, $2); } 834 | T_Panic number { $$ = create_attr_dval($1, $2); } 835 | T_Step number { $$ = create_attr_dval($1, $2); } 836 | T_Stepout number { $$ = create_attr_dval($1, $2); } 837 ; 838 839 840 /* Miscellaneous Commands 841 * ---------------------- 842 */ 843 844 miscellaneous_command 845 : interface_command 846 | T_Includefile T_String command 847 { 848 if (curr_include_level >= MAXINCLUDELEVEL) { 849 fprintf(stderr, "getconfig: Maximum include file level exceeded.\n"); 850 msyslog(LOG_ERR, "getconfig: Maximum include file level exceeded."); 851 } 852 else { 853 fp[curr_include_level + 1] = F_OPEN(FindConfig($2), "r"); 854 if (fp[curr_include_level + 1] == NULL) { 855 fprintf(stderr, "getconfig: Couldn't open <%s>\n", FindConfig($2)); 856 msyslog(LOG_ERR, "getconfig: Couldn't open <%s>", FindConfig($2)); 857 } 858 else 859 ip_file = fp[++curr_include_level]; 860 } 861 } 862 | T_End 863 { 864 while (curr_include_level != -1) 865 FCLOSE(fp[curr_include_level--]); 866 } 867 868 | T_Broadcastdelay number 869 { enqueue(cfgt.vars, create_attr_dval($1, $2)); } 870 | T_Calldelay T_Integer 871 { enqueue(cfgt.vars, create_attr_ival($1, $2)); } 872 | T_Tick number 873 { enqueue(cfgt.vars, create_attr_dval($1, $2)); } 874 | T_Driftfile drift_parm 875 { /* Null action, possibly all null parms */ } 876 | T_Leapfile T_String 877 { enqueue(cfgt.vars, create_attr_sval($1, $2)); } 878 879 | T_Pidfile T_String 880 { enqueue(cfgt.vars, create_attr_sval($1, $2)); } 881 | T_Logfile T_String 882 { 883 if (input_from_file) 884 enqueue(cfgt.vars, 885 create_attr_sval($1, $2)); 886 else { 887 free($2); 888 yyerror("logfile remote configuration ignored"); 889 } 890 } 891 892 | T_Logconfig log_config_list 893 { append_queue(cfgt.logconfig, $2); } 894 | T_Phone string_list 895 { append_queue(cfgt.phone, $2); } 896 | T_Saveconfigdir T_String 897 { 898 if (input_from_file) 899 enqueue(cfgt.vars, 900 create_attr_sval($1, $2)); 901 else { 902 free($2); 903 yyerror("saveconfigdir remote configuration ignored"); 904 } 905 } 906 | T_Setvar variable_assign 907 { enqueue(cfgt.setvar, $2); } 908 | T_Trap ip_address 909 { enqueue(cfgt.trap, create_addr_opts_node($2, NULL)); } 910 | T_Trap ip_address trap_option_list 911 { enqueue(cfgt.trap, create_addr_opts_node($2, $3)); } 912 | T_Ttl integer_list 913 { append_queue(cfgt.ttl, $2); } 914 | T_Qos T_String 915 { enqueue(cfgt.qos, create_attr_sval($1, $2)); } 916 ; 917 918 drift_parm 919 : T_String 920 { enqueue(cfgt.vars, create_attr_sval(T_Driftfile, $1)); } 921 | T_String T_Double 922 { enqueue(cfgt.vars, create_attr_dval(T_WanderThreshold, $2)); 923 enqueue(cfgt.vars, create_attr_sval(T_Driftfile, $1)); } 924 | /* Null driftfile */ 925 { enqueue(cfgt.vars, create_attr_sval(T_Driftfile, NULL)); } 926 ; 927 928 variable_assign 929 : T_String '=' T_String T_Default 930 { $$ = create_setvar_node($1, $3, $4); } 931 | T_String '=' T_String 932 { $$ = create_setvar_node($1, $3, 0); } 933 ; 934 935 trap_option_list 936 : trap_option_list trap_option 937 { $$ = enqueue($1, $2); } 938 | trap_option { $$ = enqueue_in_new_queue($1); } 939 ; 940 941 trap_option 942 : T_Port T_Integer { $$ = create_attr_ival($1, $2); } 943 | T_Interface ip_address { $$ = create_attr_pval($1, $2); } 944 ; 945 946 log_config_list 947 : log_config_list log_config_command { $$ = enqueue($1, $2); } 948 | log_config_command { $$ = enqueue_in_new_queue($1); } 949 ; 950 951 log_config_command 952 : T_String 953 { 954 char prefix = $1[0]; 955 char *type = $1 + 1; 956 957 if (prefix != '+' && prefix != '-' && prefix != '=') { 958 yyerror("Logconfig prefix is not '+', '-' or '='\n"); 959 } 960 else 961 $$ = create_attr_sval(prefix, estrdup(type)); 962 YYFREE($1); 963 } 964 ; 965 966 interface_command 967 : interface_nic nic_rule_action nic_rule_class 968 { 969 enqueue(cfgt.nic_rules, 970 create_nic_rule_node($3, NULL, $2)); 971 } 972 | interface_nic nic_rule_action T_String 973 { 974 enqueue(cfgt.nic_rules, 975 create_nic_rule_node(0, $3, $2)); 976 } 977 ; 978 979 interface_nic 980 : T_Interface 981 | T_Nic 982 ; 983 984 nic_rule_class 985 : T_All 986 | T_Ipv4 987 | T_Ipv6 988 | T_Wildcard 989 ; 990 991 nic_rule_action 992 : T_Listen 993 | T_Ignore 994 | T_Drop 995 ; 996 997 998 999 /* Miscellaneous Rules 1000 * ------------------- 1001 */ 1002 1003 integer_list 1004 : integer_list T_Integer { $$ = enqueue($1, create_ival($2)); } 1005 | T_Integer { $$ = enqueue_in_new_queue(create_ival($1)); } 1006 ; 1007 1008 string_list 1009 : string_list T_String { $$ = enqueue($1, create_pval($2)); } 1010 | T_String { $$ = enqueue_in_new_queue(create_pval($1)); } 1011 ; 1012 1013 address_list 1014 : address_list address { $$ = enqueue($1, $2); } 1015 | address { $$ = enqueue_in_new_queue($1); } 1016 ; 1017 1018 boolean 1019 : T_Integer 1020 { 1021 if ($1 != 0 && $1 != 1) { 1022 yyerror("Integer value is not boolean (0 or 1). Assuming 1"); 1023 $$ = 1; 1024 } 1025 else 1026 $$ = $1; 1027 } 1028 | T_True { $$ = 1; } 1029 | T_False { $$ = 0; } 1030 ; 1031 1032 number 1033 : T_Integer { $$ = (double)$1; } 1034 | T_Double 1035 ; 1036 1037 1038 /* Simulator Configuration Commands 1039 * -------------------------------- 1040 */ 1041 1042 simulate_command 1043 : sim_conf_start '{' sim_init_statement_list sim_server_list '}' 1044 { 1045 cfgt.sim_details = create_sim_node($3, $4); 1046 1047 /* Reset the old_config_style variable */ 1048 old_config_style = 1; 1049 } 1050 ; 1051 1052 /* The following is a terrible hack to get the configuration file to 1053 * treat newlines as whitespace characters within the simulation. 1054 * This is needed because newlines are significant in the rest of the 1055 * configuration file. 1056 */ 1057 sim_conf_start 1058 : T_Simulate { old_config_style = 0; } 1059 ; 1060 1061 sim_init_statement_list 1062 : sim_init_statement_list sim_init_statement T_EOC { $$ = enqueue($1, $2); } 1063 | sim_init_statement T_EOC { $$ = enqueue_in_new_queue($1); } 1064 ; 1065 1066 sim_init_statement 1067 : T_Beep_Delay '=' number { $$ = create_attr_dval($1, $3); } 1068 | T_Sim_Duration '=' number { $$ = create_attr_dval($1, $3); } 1069 ; 1070 1071 sim_server_list 1072 : sim_server_list sim_server { $$ = enqueue($1, $2); } 1073 | sim_server { $$ = enqueue_in_new_queue($1); } 1074 ; 1075 1076 sim_server 1077 : sim_server_name '{' sim_server_offset sim_act_list '}' 1078 { $$ = create_sim_server($1, $3, $4); } 1079 ; 1080 1081 sim_server_offset 1082 : T_Server_Offset '=' number T_EOC { $$ = $3; } 1083 ; 1084 1085 sim_server_name 1086 : T_Server '=' address { $$ = $3; } 1087 ; 1088 1089 sim_act_list 1090 : sim_act_list sim_act { $$ = enqueue($1, $2); } 1091 | sim_act { $$ = enqueue_in_new_queue($1); } 1092 ; 1093 1094 sim_act 1095 : T_Duration '=' number '{' sim_act_stmt_list '}' 1096 { $$ = create_sim_script_info($3, $5); } 1097 ; 1098 1099 sim_act_stmt_list 1100 : sim_act_stmt_list sim_act_stmt T_EOC { $$ = enqueue($1, $2); } 1101 | sim_act_stmt T_EOC { $$ = enqueue_in_new_queue($1); } 1102 ; 1103 1104 sim_act_stmt 1105 : T_Freq_Offset '=' number 1106 { $$ = create_attr_dval($1, $3); } 1107 | T_Wander '=' number 1108 { $$ = create_attr_dval($1, $3); } 1109 | T_Jitter '=' number 1110 { $$ = create_attr_dval($1, $3); } 1111 | T_Prop_Delay '=' number 1112 { $$ = create_attr_dval($1, $3); } 1113 | T_Proc_Delay '=' number 1114 { $$ = create_attr_dval($1, $3); } 1115 ; 1116 1117 1118 %% 1119 1120 void yyerror (const char *msg) 1121 { 1122 int retval; 1123 1124 ip_file->err_line_no = ip_file->prev_token_line_no; 1125 ip_file->err_col_no = ip_file->prev_token_col_no; 1126 1127 msyslog(LOG_ERR, 1128 "line %d column %d %s", 1129 ip_file->err_line_no, 1130 ip_file->err_col_no, 1131 msg); 1132 if (!input_from_file) { 1133 /* Save the error message in the correct buffer */ 1134 retval = snprintf(remote_config.err_msg + remote_config.err_pos, 1135 MAXLINE - remote_config.err_pos, 1136 "column %d %s", 1137 ip_file->err_col_no, msg); 1138 1139 /* Increment the value of err_pos */ 1140 if (retval > 0) 1141 remote_config.err_pos += retval; 1142 1143 /* Increment the number of errors */ 1144 ++remote_config.no_errors; 1145 } 1146 } 1147 1148 1149 /* 1150 * token_name - convert T_ token integers to text 1151 * example: token_name(T_Server) returns "T_Server" 1152 */ 1153 const char * 1154 token_name( 1155 int token 1156 ) 1157 { 1158 return yytname[YYTRANSLATE(token)]; 1159 } 1160 1161 1162 /* Initial Testing function -- ignore 1163 int main(int argc, char *argv[]) 1164 { 1165 ip_file = FOPEN(argv[1], "r"); 1166 if (!ip_file) { 1167 fprintf(stderr, "ERROR!! Could not open file: %s\n", argv[1]); 1168 } 1169 key_scanner = create_keyword_scanner(keyword_list); 1170 print_keyword_scanner(key_scanner, 0); 1171 yyparse(); 1172 return 0; 1173 } 1174 */ 1175 1176