1 /* $NetBSD: parse.h,v 1.9 2019/08/16 10:33:17 msaitoh Exp $ */
2
3 #ifndef _IFCONFIG_PARSE_H
4 #define _IFCONFIG_PARSE_H
5
6 #include <inttypes.h>
7 #include <stdbool.h>
8 #include <stddef.h>
9 #include <sys/queue.h>
10 #include <prop/proplib.h>
11 #include <sys/socket.h>
12
13 struct match;
14 struct parser;
15
16 extern struct pbranch command_root;
17
18 typedef int (*parser_exec_t)(prop_dictionary_t, prop_dictionary_t);
19 typedef int (*parser_match_t)(const struct parser *, const struct match *,
20 struct match *, int, const char *);
21 typedef int (*parser_init_t)(struct parser *);
22
23 struct match {
24 prop_dictionary_t m_env;
25 const struct parser *m_nextparser;
26 const struct parser *m_parser;
27 int m_argidx;
28 parser_exec_t m_exec;
29 };
30
31 /* method table */
32 struct parser_methods {
33 parser_match_t pm_match;
34 parser_init_t pm_init;
35 };
36
37 struct parser {
38 const struct parser_methods *p_methods;
39 parser_exec_t p_exec;
40 const char *p_name;
41 struct parser *p_nextparser;
42 bool p_initialized;
43 };
44
45 struct branch {
46 SIMPLEQ_ENTRY(branch) b_next;
47 struct parser *b_nextparser;
48 };
49
50 struct pbranch {
51 struct parser pb_parser;
52 SIMPLEQ_HEAD(, branch) pb_branches;
53 bool pb_match_first;
54 const struct branch *pb_brinit;
55 size_t pb_nbrinit;
56 };
57
58 struct pterm {
59 struct parser pt_parser;
60 const char *pt_key;
61 };
62
63 extern const struct parser_methods paddr_methods;
64 extern const struct parser_methods pbranch_methods;
65 extern const struct parser_methods piface_methods;
66 extern const struct parser_methods pinteger_methods;
67 extern const struct parser_methods pstr_methods;
68 extern const struct parser_methods pkw_methods;
69 extern const struct parser_methods pterm_methods;
70
71 #define PTERM_INITIALIZER(__pt, __name, __exec, __key) \
72 { \
73 .pt_parser = {.p_name = (__name), .p_methods = &pterm_methods, \
74 .p_exec = (__exec)}, \
75 .pt_key = (__key) \
76 }
77
78 #define PBRANCH_INITIALIZER(__pb, __name, __brs, __nbr, __match_first) \
79 { \
80 .pb_parser = {.p_name = (__name), .p_methods = &pbranch_methods},\
81 .pb_branches = SIMPLEQ_HEAD_INITIALIZER((__pb)->pb_branches), \
82 .pb_brinit = (__brs), \
83 .pb_nbrinit = (__nbr), \
84 .pb_match_first = (__match_first) \
85 }
86
87 #define PSTR_INITIALIZER(__ps, __name, __defexec, __defkey, __defnext) \
88 PSTR_INITIALIZER1((__ps), (__name), (__defexec), (__defkey), \
89 true, (__defnext))
90
91 #define PSTR_INITIALIZER1(__ps, __name, __defexec, __defkey, __defhexok,\
92 __defnext) \
93 { \
94 .ps_parser = {.p_name = (__name), .p_methods = &pstr_methods, \
95 .p_exec = (__defexec), \
96 .p_nextparser = (__defnext)}, \
97 .ps_key = (__defkey), \
98 .ps_hexok = (__defhexok) \
99 }
100
101 #define PADDR_INITIALIZER(__pa, __name, __defexec, __addrkey, \
102 __maskkey, __activator, __deactivator, __defnext) \
103 { \
104 .pa_parser = {.p_name = (__name), .p_methods = &paddr_methods, \
105 .p_exec = (__defexec), \
106 .p_nextparser = (__defnext)}, \
107 .pa_addrkey = (__addrkey), \
108 .pa_maskkey = (__maskkey), \
109 .pa_activator = (__activator), \
110 .pa_deactivator = (__deactivator), \
111 }
112
113 #define PIFACE_INITIALIZER(__pif, __name, __defexec, __defkey, __defnext)\
114 { \
115 .pif_parser = {.p_name = (__name), .p_methods = &piface_methods,\
116 .p_exec = (__defexec), \
117 .p_nextparser = (__defnext)}, \
118 .pif_key = (__defkey) \
119 }
120
121 #define PINTEGER_INITIALIZER1(__pi, __name, __min, __max, __base, \
122 __defexec, __defkey, __defnext) \
123 { \
124 .pi_parser = {.p_name = (__name), .p_methods = &pinteger_methods,\
125 .p_exec = (__defexec), \
126 .p_nextparser = (__defnext), \
127 .p_initialized = false}, \
128 .pi_min = (__min), \
129 .pi_max = (__max), \
130 .pi_base = (__base), \
131 .pi_key = (__defkey) \
132 }
133
134 #define PINTEGER_INITIALIZER(__pi, __name, __base, __defexec, __defkey, \
135 __defnext) \
136 PINTEGER_INITIALIZER1(__pi, __name, INTMAX_MIN, INTMAX_MAX, \
137 __base, __defexec, __defkey, __defnext)
138
139 #define PKW_INITIALIZER(__pk, __name, __defexec, __defkey, __kws, __nkw,\
140 __defnext) \
141 { \
142 .pk_parser = {.p_name = (__name), \
143 .p_exec = (__defexec), \
144 .p_methods = &pkw_methods, \
145 .p_initialized = false}, \
146 .pk_keywords = SIMPLEQ_HEAD_INITIALIZER((__pk)->pk_keywords), \
147 .pk_kwinit = (__kws), \
148 .pk_nkwinit = (__nkw), \
149 .pk_keyinit = (__defkey), \
150 .pk_nextinit = (__defnext) \
151 }
152
153 #define IFKW(__word, __flag) \
154 { \
155 .k_word = (__word), .k_neg = true, .k_type = KW_T_INT, \
156 .k_int = (__flag), \
157 .k_negint = -(__flag) \
158 }
159
160 #define KW_T_NONE 0
161 #define KW_T_OBJ 1
162 #define KW_T_INT 2
163 #define KW_T_STR 3
164 #define KW_T_BOOL 4
165 #define KW_T_UINT 5
166
167 struct kwinst {
168 SIMPLEQ_ENTRY(kwinst) k_next;
169 int k_type;
170 const char *k_word;
171 const char *k_key;
172 const char *k_act;
173 const char *k_deact;
174 const char *k_altdeact;
175 parser_exec_t k_exec;
176 union kwval {
177 int64_t u_sint;
178 uint64_t u_uint;
179 const char *u_str;
180 prop_object_t u_obj;
181 bool u_bool;
182 } k_u, k_negu;
183 #define k_int k_u.u_sint
184 #define k_uint k_u.u_uint
185 #define k_str k_u.u_str
186 #define k_obj k_u.u_obj
187 #define k_bool k_u.u_bool
188
189 #define k_negint k_negu.u_sint
190 #define k_neguint k_negu.u_uint
191 #define k_negstr k_negu.u_str
192 #define k_negobj k_negu.u_obj
193 #define k_negbool k_negu.u_bool
194
195 bool k_neg; /* allow negative form, -keyword */
196 struct parser *k_nextparser;
197 };
198
199 struct pkw {
200 struct parser pk_parser;
201 const char *pk_key;
202 const char *pk_keyinit;
203 const struct kwinst *pk_kwinit;
204 size_t pk_nkwinit;
205 SIMPLEQ_HEAD(, kwinst) pk_keywords;
206 };
207
208 #define pk_nextinit pk_parser.p_nextparser
209 #define pk_execinit pk_parser.p_exec
210
211 struct pstr {
212 struct parser ps_parser;
213 const char *ps_key;
214 bool ps_hexok;
215 };
216
217 struct pinteger {
218 struct parser pi_parser;
219 int64_t pi_min;
220 int64_t pi_max;
221 int pi_base;
222 const char *pi_key;
223 };
224
225 struct intrange {
226 SIMPLEQ_ENTRY(intrange) r_next;
227 int64_t r_bottom;
228 int64_t r_top;
229 struct parser *r_nextparser;
230 };
231
232 struct pranges {
233 struct parser pr_parser;
234 SIMPLEQ_HEAD(, intrange) pr_ranges;
235 };
236
237 struct paddr_prefix {
238 int16_t pfx_len;
239 struct sockaddr pfx_addr;
240 };
241
242 static inline size_t
paddr_prefix_size(const struct paddr_prefix * pfx)243 paddr_prefix_size(const struct paddr_prefix *pfx)
244 {
245 return offsetof(struct paddr_prefix, pfx_addr) + pfx->pfx_addr.sa_len;
246 }
247
248 struct paddr {
249 struct parser pa_parser;
250 const char *pa_addrkey;
251 const char *pa_maskkey;
252 const char *pa_activator;
253 const char *pa_deactivator;
254 };
255
256 struct piface {
257 struct parser pif_parser;
258 const char *pif_key;
259 };
260
261 struct prest {
262 struct parser pr_parser;
263 };
264
265 struct prest *prest_create(const char *);
266 struct paddr *paddr_create(const char *, parser_exec_t, const char *,
267 const char *, struct parser *);
268 struct pstr *pstr_create(const char *, parser_exec_t, const char *,
269 bool, struct parser *);
270 struct piface *piface_create(const char *, parser_exec_t, const char *,
271 struct parser *);
272 struct pkw *pkw_create(const char *, parser_exec_t,
273 const char *, const struct kwinst *, size_t, struct parser *);
274 struct pranges *pranges_create(const char *, parser_exec_t, const char *,
275 const struct intrange *, size_t, struct parser *);
276 struct pbranch *pbranch_create(const char *, const struct branch *, size_t,
277 bool);
278 int pbranch_addbranch(struct pbranch *, struct parser *);
279 int pbranch_setbranches(struct pbranch *, const struct branch *, size_t);
280
281 int parse(int, char **, const struct parser *, struct match *, size_t *, int *);
282
283 int matches_exec(const struct match *, prop_dictionary_t, size_t);
284 int parser_init(struct parser *);
285
286 #endif /* _IFCONFIG_PARSE_H */
287