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