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