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