xref: /netbsd/sbin/ifconfig/parse.h (revision 7fd429a8)
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