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