diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2016-07-19 21:14:27 +0000 |
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2016-07-19 21:14:27 +0000 |
| commit | 9d0662e009c0cf4532b88c9a1fb0f7c0dc174584 (patch) | |
| tree | ab301ab5ec4b58a249df43e09fbc21154e879499 /lib/command_match.c | |
| parent | 340a2b4ac0bcc737e24aa6c0e383f1188aaaaf61 (diff) | |
lib: Break up functions, begin matcher
Moved test hook out of command.c into vtysh.c,
renamed graph modules, added matching code
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'lib/command_match.c')
| -rw-r--r-- | lib/command_match.c | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/lib/command_match.c b/lib/command_match.c new file mode 100644 index 0000000000..bcc28bdc5b --- /dev/null +++ b/lib/command_match.c @@ -0,0 +1,174 @@ +#include <zebra.h> +#include "memory.h" +#include "command_match.h" + +enum match_type +match_command (struct graph_node *start, enum filter_type filter, const char *input) +{ + // match input on DFA + return exact_match; +} + + +#define IPV4_ADDR_STR "0123456789." +#define IPV4_PREFIX_STR "0123456789./" + +enum match_type +cmd_ipv4_match (const char *str) +{ + struct sockaddr_in sin_dummy; + + if (str == NULL) + return partly_match; + + if (strspn (str, IPV4_ADDR_STR) != strlen (str)) + return no_match; + + if (inet_pton(AF_INET, str, &sin_dummy.sin_addr) != 1) + return no_match; + + return exact_match; +} + +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; + + if (str == NULL) + return partly_match; + + if (strspn (str, IPV4_PREFIX_STR) != strlen (str)) + 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 (!mask) + return partly_match; + + /* validate prefix */ + if (inet_pton(AF_INET, prefix, &sin_dummy.sin_addr) != 1) + return no_match; + + /* validate mask */ + nmask = strtol (mask, &endptr, 10); + if (*endptr != '\0' || nmask < 0 || nmask > 32) + return no_match; + + XFREE(MTYPE_TMP, dupe); + + return exact_match; +} + +#define IPV6_ADDR_STR "0123456789abcdefABCDEF:." +#define IPV6_PREFIX_STR "0123456789abcdefABCDEF:./" + +#ifdef HAVE_IPV6 +enum match_type +cmd_ipv6_match (const char *str) +{ + struct sockaddr_in6 sin6_dummy; + int ret; + + if (str == NULL) + return partly_match; + + if (strspn (str, IPV6_ADDR_STR) != strlen (str)) + return no_match; + + ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr); + + if (ret == 1) + return exact_match; + + return no_match; +} + +enum match_type +cmd_ipv6_prefix_match (const char *str) +{ + struct sockaddr_in6 sin6_dummy; + const char *delim = "/\0"; + char *dupe, *prefix, *mask, *context, *endptr; + int nmask = -1; + + if (str == NULL) + return partly_match; + + if (strspn (str, IPV6_PREFIX_STR) != strlen (str)) + 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 (!mask) + return partly_match; + + /* validate prefix */ + if (inet_pton(AF_INET6, prefix, &sin6_dummy.sin6_addr) != 1) + return no_match; + + /* validate mask */ + nmask = strtol (mask, &endptr, 10); + if (*endptr != '\0' || nmask < 0 || nmask > 128) + return no_match; + + XFREE(MTYPE_TMP, dupe); + + return exact_match; +} +#endif + +enum match_type +cmd_range_match (struct graph_node *rangenode, const char *str) +{ + char *endptr = NULL; + signed long long val; + + if (str == NULL) + return 1; + + val = strtoll (str, &endptr, 10); + if (*endptr != '\0') + return 0; + val = llabs(val); + + if (val < rangenode->min || val > rangenode->max) + return no_match; + else + return exact_match; +} + +enum match_type +cmd_word_match(struct graph_node *wordnode, + enum filter_type filter, + const char *word) +{ + if (filter == FILTER_RELAXED) + if (!word || !strlen(word)) + return partly_match; + + if (!word) + return no_match; + + if (filter == FILTER_RELAXED && !strncmp(wordnode->text, word, strlen(word))) + { + if (!strcmp(wordnode->text, word)) + return exact_match; + return partly_match; + } + if (filter == FILTER_STRICT && !strcmp(wordnode->text, word)) + return exact_match; + + return no_match; +} |
