From: Harlan Stenn Date: Sun, 31 Aug 2008 06:06:36 +0000 (-0400) Subject: [Bug 828] Fix IPv4/IPv6 address parsing X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fb7d8015ecf5b3d3929122d69f23daafc20d7f25;p=thirdparty%2Fntp.git [Bug 828] Fix IPv4/IPv6 address parsing bk: 48ba34ecBJy5mzxy4KpitKN0s86heQ --- diff --git a/ChangeLog b/ChangeLog index 988b50a894..ec01f51de6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* [Bug 828] Fix IPv4/IPv6 address parsing. * Changes from Dave Mills: Documentation updates. Fix a corner case where a frequency update was reported but not set. diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 80ba65eb28..881dbc34dd 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -434,11 +434,20 @@ create_address_node( int type ) { - struct address_node *my_node = (struct address_node *) - get_node(sizeof(struct address_node)); + struct address_node *my_node = + (struct address_node *) get_node(sizeof(struct address_node)); + struct isc_netaddr temp_isc_netaddr; my_node->address = addr; + if (type == 0) { + if (is_ip_address(addr, &temp_isc_netaddr)) + my_node->type = temp_isc_netaddr.family; + else + my_node->type = default_ai_family; + } + else { my_node->type = type; + } return my_node; } diff --git a/ntpd/ntp_parser.y b/ntpd/ntp_parser.y index c95197a4b0..9edde55d5f 100644 --- a/ntpd/ntp_parser.y +++ b/ntpd/ntp_parser.y @@ -106,13 +106,13 @@ %token T_Fudge %token T_Host %token T_Huffpuff -%token T_IPv4_address -%token T_IPv6_address +%token T_IPv4_address +%token T_IPv6_address %token T_Iburst %token T_Ident %token T_Ignore %token T_Includefile -%token T_Integer +%token T_Integer %token T_Interface %token T_Kernel %token T_Key @@ -201,7 +201,6 @@ %token T_Week %token T_Xleave %token T_Year -%token T_Integer %token T_Flag /* Not an actual token */ %token T_Void /* Not an actual token */ %token T_EOC @@ -242,7 +241,6 @@ %type ip_address %type log_config_command %type log_config_list -%type log_config_prefix %type number %type option %type option_list @@ -266,7 +264,6 @@ %type sim_server %type sim_server_offset %type sim_server_name -%type sim_address %type sim_act_list %type sim_act %type sim_act_stmt_list @@ -344,25 +341,12 @@ client_type address : ip_address { $$ = $1; } - | T_String { $$ = create_address_node($1, default_ai_family); } - | T_Integer T_String - { - if ($1 == -4) - $$ = create_address_node($2, AF_INET); - else if ($1 == -6) - $$ = create_address_node($2, AF_INET6); - else { - yyerror("Invalid address type specified. Assuming default.\n"); - $$ = create_address_node($2, default_ai_family); - } - } - - + | T_IPv4_address T_String { $$ = create_address_node($2, AF_INET); } + | T_IPv6_address T_String { $$ = create_address_node($2, AF_INET6); } ; ip_address - : T_IPv4_address { $$ = create_address_node($1, AF_INET); } - | T_IPv6_address { $$ = create_address_node($1, AF_INET6); } + : T_String { $$ = create_address_node($1, 0); } ; option_list @@ -796,16 +780,11 @@ log_config_list ; log_config_command - : log_config_prefix T_String { $$ = create_attr_sval($1, $2); } - | T_String + : T_String { - /* YUCK!! This is needed because '+' and '-' are not special characters - * while '=' is. - * We really need a better way of defining strings - */ char prefix = $1[0]; char *type = &($1[1]); - if (prefix != '+' && prefix != '-') { + if (prefix != '+' && prefix != '-' && prefix != '=') { yyerror("Logconfig prefix is not '+', '-' or '='\n"); } else @@ -813,13 +792,6 @@ log_config_command } ; -log_config_prefix - : '+' { $$ = '+'; } - | '-' { $$ = '-'; } - | '=' { $$ = '='; } - ; - - /* Miscellaneous Rules * ------------------- */ @@ -906,12 +878,7 @@ sim_server_offset ; sim_server_name - : T_Server '=' sim_address { $$ = $3; } - ; - -sim_address - : ip_address { $$ = $1; } - | T_String { $$ = create_address_node($1, T_String); } + : T_Server '=' address { $$ = $3; } ; sim_act_list diff --git a/ntpd/ntp_scanner.c b/ntpd/ntp_scanner.c index dd8bfbeb1d..862f1a14e3 100644 --- a/ntpd/ntp_scanner.c +++ b/ntpd/ntp_scanner.c @@ -48,7 +48,6 @@ char yytext[MAX_LEXEME]; /* Buffer for storing the input text/lexeme */ struct state *key_scanner; /* A FSA for recognizing keywords */ extern int input_from_file; - /* CONSTANTS * --------- */ @@ -447,6 +446,20 @@ is_EOC(char ch) return 0; } +static int +create_string_token(char *lexeme) +{ + errno = 0; + if ((yylval.String = strdup(lexeme)) == NULL && + errno == ENOMEM) { + fprintf(stderr, "Could not allocate memory for: %s\n", + lexeme); + exit(1); + } + else + return T_String; +} + /* Define a function that does the actual scanning * Bison expects this function to be called yylex and for it to take no @@ -459,7 +472,6 @@ yylex() int i, instring = 0; int token; /* The return value/the recognized token */ int ch; - struct isc_netaddr temp_isc_netaddr; static int expect_string = NO_ARG; do { @@ -486,7 +498,7 @@ yylex() /* Check if the next character is a special character. * If yes, return the special character */ - else if (is_special(ch)) + else if ((expect_string == NO_ARG) && is_special(ch)) return ch; else push_back_char(ch); @@ -496,7 +508,8 @@ yylex() (yytext[i] = get_next_char()) != EOF; ++i) { /* Break on reading in whitespace or a special character */ - if (isspace(yytext[i]) || is_special(yytext[i]) + if (isspace(yytext[i]) + || ((expect_string == NO_ARG) && is_special(yytext[i])) || is_EOC(ch) || yytext[i] == '"') break; @@ -539,10 +552,16 @@ yylex() #endif /* Now return the desired token */ - if ((expect_string == NO_ARG) && (!instring) && - (token = is_keyword(yytext, &expect_string))) + + /* First make sure that the parser is *not* expecting a string as the + * next token (based on the previous token that was returned) and + * that we haven't read a string + */ + + if ((expect_string == NO_ARG) && (!instring)) { + if (token = is_keyword(yytext, &expect_string)) return token; - else if (is_integer(yytext) && (!instring) ) { + else if (is_integer(yytext)) { errno = 0; if ((yylval.Integer = strtol(yytext,(char **) NULL, 10)) == 0 && ((errno == EINVAL) || (errno == ERANGE))) { @@ -553,7 +572,7 @@ yylex() else return T_Integer; } - else if (is_double(yytext) && (!instring)) { + else if (is_double(yytext)) { errno = 0; if ((yylval.Double = atof(yytext)) == 0 && errno == ERANGE) { fprintf(stderr, "Double too large to represent: %s\n", @@ -563,34 +582,27 @@ yylex() else return T_Double; } - else if ((is_ip_address(yytext, &temp_isc_netaddr)) && (!instring)) { - if (expect_string == SINGLE_ARG) - expect_string = NO_ARG; - errno = 0; - if ((yylval.String = strdup(yytext)) == NULL && - errno == ENOMEM) { - fprintf(stderr, "Could not allocate memory for: %s\n", - yytext); - exit(1); - } - else return - (temp_isc_netaddr.family == AF_INET) - ? T_IPv4_address - : T_IPv6_address ; + else /* Default: Everything is a string */ + return create_string_token(yytext); } - else { /* Default: Everything is a string */ + else { + /* Either expect_string is 1 or this lexeme is part of a string. + Hence, we need to return T_String. + + ONLY EXCEPTION (sic), we might have a -4 or -6 flag. + This is a terrible hack, but the grammar is ambiguous so + we don't have a choice + */ + if (strcmp(yytext, "-4") == 0) + return T_IPv4_address; + else if (strcmp(yytext, "-6") == 0) + return T_IPv6_address; + else { instring = 0; if (expect_string == SINGLE_ARG) expect_string = NO_ARG; - errno = 0; - if ((yylval.String = strdup(yytext)) == NULL && - errno == ENOMEM) { - fprintf(stderr, "Could not allocate memory for: %s\n", - yytext); - exit(1); + return create_string_token(yytext); } - else - return T_String; } return 1; }