]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 828] Fix IPv4/IPv6 address parsing
authorHarlan Stenn <stenn@ntp.org>
Sun, 31 Aug 2008 06:06:36 +0000 (02:06 -0400)
committerHarlan Stenn <stenn@ntp.org>
Sun, 31 Aug 2008 06:06:36 +0000 (02:06 -0400)
bk: 48ba34ecBJy5mzxy4KpitKN0s86heQ

ChangeLog
ntpd/ntp_config.c
ntpd/ntp_parser.y
ntpd/ntp_scanner.c

index 988b50a89447c5442056256cfc093ae01368a580..ec01f51de6715c9568dcb462ed768484d574453e 100644 (file)
--- 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.
index 80ba65eb280bd9b4d4448c8d25f95d24cb905402..881dbc34dd2dd39a174f9f2e576fefda80aab17e 100644 (file)
@@ -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;
 }
 
index c95197a4b0b17fa55ca1c933b4505a8cf57f3588..9edde55d5fdd376db8e70c070ef7d5dff7486592 100644 (file)
 %token         T_Fudge
 %token         T_Host
 %token         T_Huffpuff
-%token <String> T_IPv4_address
-%token <String> 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 <Integer> T_Integer
 %token         T_Interface
 %token         T_Kernel
 %token         T_Key
 %token         T_Week
 %token         T_Xleave
 %token         T_Year
-%token <Integer> T_Integer
 %token          T_Flag     /* Not an actual token */
 %token          T_Void     /* Not an actual token */
 %token          T_EOC
 %type  <Address_node>  ip_address
 %type  <Attr_val>      log_config_command
 %type  <Queue>         log_config_list
-%type  <Integer>       log_config_prefix
 %type  <Double>        number
 %type  <Attr_val>      option
 %type  <Queue>         option_list
 %type   <Sim_server>    sim_server
 %type   <Double>        sim_server_offset
 %type   <Address_node>  sim_server_name
-%type   <Address_node>  sim_address
 %type   <Queue>         sim_act_list
 %type   <Sim_script>    sim_act
 %type   <Queue>         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
index dd8bfbeb1df0e635db2394be8675023cfa56d592..862f1a14e3fee74f45409ca3f5a3d10cbad66e83 100644 (file)
@@ -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;
 }