diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2016-07-27 19:39:45 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetwroks.com> | 2016-07-24 09:47:04 +0200 |
commit | fbfa8891688004bc6f554b759accee9ed917c5df (patch) | |
tree | ddc12ae24788cafb669cab5de8531ccbc11572ef /lib | |
parent | *: fixup snmp support (diff) | |
download | frr-fbfa8891688004bc6f554b759accee9ed917c5df.tar.xz frr-fbfa8891688004bc6f554b759accee9ed917c5df.zip |
Revert "lib: Rewrite ipv4 address and prefix validator"
This reverts commit d4dc41b6a23d5156b0d9068006a1eeb3ba32e301.
The rewritten parser fails to recognise "1.2." as partial input for an
IPv4 address, which causes "make check" to fail.
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/command.c | 144 |
1 files changed, 108 insertions, 36 deletions
diff --git a/lib/command.c b/lib/command.c index b3819048e..4896c8a95 100644 --- a/lib/command.c +++ b/lib/command.c @@ -865,29 +865,59 @@ enum match_type exact_match }; -#define IPV4_ADDR_STR "0123456789." -#define IPV4_PREFIX_STR "0123456789./" - -/** - * Determines whether a string is a valid ipv4 token. - * - * @param[in] str the string to match - * @return exact_match if the string is an exact match, no_match/partly_match - * otherwise - */ static enum match_type cmd_ipv4_match (const char *str) { - struct sockaddr_in sin_dummy; + const char *sp; + int dots = 0, nums = 0; + char buf[4]; if (str == NULL) return partly_match; - if (strspn (str, IPV4_ADDR_STR) != strlen (str)) - return no_match; + for (;;) + { + memset (buf, 0, sizeof (buf)); + sp = str; + while (*str != '\0') + { + if (*str == '.') + { + if (dots >= 3) + return no_match; - if (inet_pton(AF_INET, str, &sin_dummy.sin_addr) != 1) - return no_match; + if (*(str + 1) == '.') + return no_match; + + if (*(str + 1) == '\0') + return partly_match; + + dots++; + break; + } + if (!isdigit ((int) *str)) + return no_match; + + str++; + } + + if (str - sp > 3) + return no_match; + + strncpy (buf, sp, str - sp); + if (atoi (buf) > 255) + return no_match; + + nums++; + + if (*str == '\0') + break; + + str++; + } + + if (nums < 4) + return partly_match; return exact_match; } @@ -895,36 +925,78 @@ cmd_ipv4_match (const char *str) static enum match_type cmd_ipv4_prefix_match (const char *str) { - struct sockaddr_in sin_dummy; - const char *delim = "/\0"; - char *dupe, *prefix, *mask, *context, *endptr; - int nmask = -1; + const char *sp; + int dots = 0; + char buf[4]; if (str == NULL) return partly_match; - if (strspn (str, IPV4_PREFIX_STR) != strlen (str)) - return no_match; + for (;;) + { + memset (buf, 0, sizeof (buf)); + sp = str; + while (*str != '\0' && *str != '/') + { + if (*str == '.') + { + if (dots == 3) + return no_match; - /* tokenize to address + mask */ - dupe = XMALLOC(MTYPE_TMP, strlen(str)+1); - strncpy(dupe, str, strlen(str)+1); - prefix = strtok_r(dupe, delim, &context); - mask = strtok_r(NULL, delim, &context); + if (*(str + 1) == '.' || *(str + 1) == '/') + return no_match; - if (!mask) - return partly_match; + if (*(str + 1) == '\0') + return partly_match; - /* validate prefix */ - if (inet_pton(AF_INET, prefix, &sin_dummy.sin_addr) != 1) - return no_match; + dots++; + break; + } - /* validate mask */ - nmask = strtol (mask, &endptr, 10); - if (*endptr != '\0' || nmask < 0 || nmask > 32) - return no_match; + if (!isdigit ((int) *str)) + return no_match; - XFREE(MTYPE_TMP, dupe); + str++; + } + + if (str - sp > 3) + return no_match; + + strncpy (buf, sp, str - sp); + if (atoi (buf) > 255) + return no_match; + + if (dots == 3) + { + if (*str == '/') + { + if (*(str + 1) == '\0') + return partly_match; + + str++; + break; + } + else if (*str == '\0') + return partly_match; + } + + if (*str == '\0') + return partly_match; + + str++; + } + + sp = str; + while (*str != '\0') + { + if (!isdigit ((int) *str)) + return no_match; + + str++; + } + + if (atoi (sp) > 32) + return no_match; return exact_match; } |