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