Home | History | Annotate | Line # | Download | only in ifconfig
      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
    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