]> git.proxmox.com Git - mirror_frr.git/blob - lib/command_match.c
lib: Break up functions, begin matcher
[mirror_frr.git] / lib / command_match.c
1 #include <zebra.h>
2 #include "memory.h"
3 #include "command_match.h"
4
5 enum match_type
6 match_command (struct graph_node *start, enum filter_type filter, const char *input)
7 {
8 // match input on DFA
9 return exact_match;
10 }
11
12
13 #define IPV4_ADDR_STR "0123456789."
14 #define IPV4_PREFIX_STR "0123456789./"
15
16 enum match_type
17 cmd_ipv4_match (const char *str)
18 {
19 struct sockaddr_in sin_dummy;
20
21 if (str == NULL)
22 return partly_match;
23
24 if (strspn (str, IPV4_ADDR_STR) != strlen (str))
25 return no_match;
26
27 if (inet_pton(AF_INET, str, &sin_dummy.sin_addr) != 1)
28 return no_match;
29
30 return exact_match;
31 }
32
33 enum match_type
34 cmd_ipv4_prefix_match (const char *str)
35 {
36 struct sockaddr_in sin_dummy;
37 const char *delim = "/\0";
38 char *dupe, *prefix, *mask, *context, *endptr;
39 int nmask = -1;
40
41 if (str == NULL)
42 return partly_match;
43
44 if (strspn (str, IPV4_PREFIX_STR) != strlen (str))
45 return no_match;
46
47 /* tokenize to address + mask */
48 dupe = XMALLOC(MTYPE_TMP, strlen(str)+1);
49 strncpy(dupe, str, strlen(str)+1);
50 prefix = strtok_r(dupe, delim, &context);
51 mask = strtok_r(NULL, delim, &context);
52
53 if (!mask)
54 return partly_match;
55
56 /* validate prefix */
57 if (inet_pton(AF_INET, prefix, &sin_dummy.sin_addr) != 1)
58 return no_match;
59
60 /* validate mask */
61 nmask = strtol (mask, &endptr, 10);
62 if (*endptr != '\0' || nmask < 0 || nmask > 32)
63 return no_match;
64
65 XFREE(MTYPE_TMP, dupe);
66
67 return exact_match;
68 }
69
70 #define IPV6_ADDR_STR "0123456789abcdefABCDEF:."
71 #define IPV6_PREFIX_STR "0123456789abcdefABCDEF:./"
72
73 #ifdef HAVE_IPV6
74 enum match_type
75 cmd_ipv6_match (const char *str)
76 {
77 struct sockaddr_in6 sin6_dummy;
78 int ret;
79
80 if (str == NULL)
81 return partly_match;
82
83 if (strspn (str, IPV6_ADDR_STR) != strlen (str))
84 return no_match;
85
86 ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr);
87
88 if (ret == 1)
89 return exact_match;
90
91 return no_match;
92 }
93
94 enum match_type
95 cmd_ipv6_prefix_match (const char *str)
96 {
97 struct sockaddr_in6 sin6_dummy;
98 const char *delim = "/\0";
99 char *dupe, *prefix, *mask, *context, *endptr;
100 int nmask = -1;
101
102 if (str == NULL)
103 return partly_match;
104
105 if (strspn (str, IPV6_PREFIX_STR) != strlen (str))
106 return no_match;
107
108 /* tokenize to address + mask */
109 dupe = XMALLOC(MTYPE_TMP, strlen(str)+1);
110 strncpy(dupe, str, strlen(str)+1);
111 prefix = strtok_r(dupe, delim, &context);
112 mask = strtok_r(NULL, delim, &context);
113
114 if (!mask)
115 return partly_match;
116
117 /* validate prefix */
118 if (inet_pton(AF_INET6, prefix, &sin6_dummy.sin6_addr) != 1)
119 return no_match;
120
121 /* validate mask */
122 nmask = strtol (mask, &endptr, 10);
123 if (*endptr != '\0' || nmask < 0 || nmask > 128)
124 return no_match;
125
126 XFREE(MTYPE_TMP, dupe);
127
128 return exact_match;
129 }
130 #endif
131
132 enum match_type
133 cmd_range_match (struct graph_node *rangenode, const char *str)
134 {
135 char *endptr = NULL;
136 signed long long val;
137
138 if (str == NULL)
139 return 1;
140
141 val = strtoll (str, &endptr, 10);
142 if (*endptr != '\0')
143 return 0;
144 val = llabs(val);
145
146 if (val < rangenode->min || val > rangenode->max)
147 return no_match;
148 else
149 return exact_match;
150 }
151
152 enum match_type
153 cmd_word_match(struct graph_node *wordnode,
154 enum filter_type filter,
155 const char *word)
156 {
157 if (filter == FILTER_RELAXED)
158 if (!word || !strlen(word))
159 return partly_match;
160
161 if (!word)
162 return no_match;
163
164 if (filter == FILTER_RELAXED && !strncmp(wordnode->text, word, strlen(word)))
165 {
166 if (!strcmp(wordnode->text, word))
167 return exact_match;
168 return partly_match;
169 }
170 if (filter == FILTER_STRICT && !strcmp(wordnode->text, word))
171 return exact_match;
172
173 return no_match;
174 }