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 { \ 87 .ps_parser = {.p_name = (__name), .p_methods = &pstr_methods, \ 88 .p_exec = (__defexec), \ 89 .p_nextparser = (__defnext)}, \ 90 .ps_key = (__defkey) \ 91 } 92 93 #define PADDR_INITIALIZER(__pa, __name, __defexec, __addrkey, \ 94 __maskkey, __activator, __deactivator, __defnext) \ 95 { \ 96 .pa_parser = {.p_name = (__name), .p_methods = &paddr_methods, \ 97 .p_exec = (__defexec), \ 98 .p_nextparser = (__defnext)}, \ 99 .pa_addrkey = (__addrkey), \ 100 .pa_maskkey = (__maskkey), \ 101 .pa_activator = (__activator), \ 102 .pa_deactivator = (__deactivator), \ 103 } 104 105 #define PIFACE_INITIALIZER(__pif, __name, __defexec, __defkey, __defnext)\ 106 { \ 107 .pif_parser = {.p_name = (__name), .p_methods = &piface_methods,\ 108 .p_exec = (__defexec), \ 109 .p_nextparser = (__defnext)}, \ 110 .pif_key = (__defkey) \ 111 } 112 113 #define PINTEGER_INITIALIZER1(__pi, __name, __min, __max, __base, \ 114 __defexec, __defkey, __defnext) \ 115 { \ 116 .pi_parser = {.p_name = (__name), .p_methods = &pinteger_methods,\ 117 .p_exec = (__defexec), \ 118 .p_nextparser = (__defnext), \ 119 .p_initialized = false}, \ 120 .pi_min = (__min), \ 121 .pi_max = (__max), \ 122 .pi_base = (__base), \ 123 .pi_key = (__defkey) \ 124 } 125 126 #define PINTEGER_INITIALIZER(__pi, __name, __base, __defexec, __defkey, \ 127 __defnext) \ 128 PINTEGER_INITIALIZER1(__pi, __name, INTMAX_MIN, INTMAX_MAX, \ 129 __base, __defexec, __defkey, __defnext) 130 131 #define PKW_INITIALIZER(__pk, __name, __defexec, __defkey, __kws, __nkw,\ 132 __defnext) \ 133 { \ 134 .pk_parser = {.p_name = (__name), \ 135 .p_exec = (__defexec), \ 136 .p_methods = &pkw_methods, \ 137 .p_initialized = false}, \ 138 .pk_keywords = SIMPLEQ_HEAD_INITIALIZER((__pk)->pk_keywords), \ 139 .pk_kwinit = (__kws), \ 140 .pk_nkwinit = (__nkw), \ 141 .pk_keyinit = (__defkey), \ 142 .pk_nextinit = (__defnext) \ 143 } 144 145 #define IFKW(__word, __flag) \ 146 { \ 147 .k_word = (__word), .k_neg = true, .k_type = KW_T_INT, \ 148 .k_int = (__flag), \ 149 .k_negint = -(__flag) \ 150 } 151 152 #define KW_T_NONE 0 153 #define KW_T_OBJ 1 154 #define KW_T_INT 2 155 #define KW_T_STR 3 156 #define KW_T_BOOL 4 157 #define KW_T_UINT 5 158 159 struct kwinst { 160 SIMPLEQ_ENTRY(kwinst) k_next; 161 int k_type; 162 const char *k_word; 163 const char *k_key; 164 const char *k_act; 165 const char *k_deact; 166 const char *k_altdeact; 167 parser_exec_t k_exec; 168 union kwval { 169 int64_t u_sint; 170 uint64_t u_uint; 171 const char *u_str; 172 prop_object_t u_obj; 173 bool u_bool; 174 } k_u, k_negu; 175 #define k_int k_u.u_sint 176 #define k_uint k_u.u_uint 177 #define k_str k_u.u_str 178 #define k_obj k_u.u_obj 179 #define k_bool k_u.u_bool 180 181 #define k_negint k_negu.u_sint 182 #define k_neguint k_negu.u_uint 183 #define k_negstr k_negu.u_str 184 #define k_negobj k_negu.u_obj 185 #define k_negbool k_negu.u_bool 186 187 bool k_neg; /* allow negative form, -keyword */ 188 struct parser *k_nextparser; 189 }; 190 191 struct pkw { 192 struct parser pk_parser; 193 const char *pk_key; 194 const char *pk_keyinit; 195 const struct kwinst *pk_kwinit; 196 size_t pk_nkwinit; 197 SIMPLEQ_HEAD(, kwinst) pk_keywords; 198 }; 199 200 #define pk_nextinit pk_parser.p_nextparser 201 #define pk_execinit pk_parser.p_exec 202 203 struct pstr { 204 struct parser ps_parser; 205 const char *ps_key; 206 }; 207 208 struct pinteger { 209 struct parser pi_parser; 210 int64_t pi_min; 211 int64_t pi_max; 212 int pi_base; 213 const char *pi_key; 214 }; 215 216 struct intrange { 217 SIMPLEQ_ENTRY(intrange) r_next; 218 int64_t r_bottom; 219 int64_t r_top; 220 struct parser *r_nextparser; 221 }; 222 223 struct pranges { 224 struct parser pr_parser; 225 SIMPLEQ_HEAD(, intrange) pr_ranges; 226 }; 227 228 struct paddr_prefix { 229 int16_t pfx_len; 230 struct sockaddr pfx_addr; 231 }; 232 233 static inline size_t 234 paddr_prefix_size(const struct paddr_prefix *pfx) 235 { 236 return offsetof(struct paddr_prefix, pfx_addr) + pfx->pfx_addr.sa_len; 237 } 238 239 struct paddr { 240 struct parser pa_parser; 241 const char *pa_addrkey; 242 const char *pa_maskkey; 243 const char *pa_activator; 244 const char *pa_deactivator; 245 }; 246 247 struct piface { 248 struct parser pif_parser; 249 const char *pif_key; 250 }; 251 252 struct prest { 253 struct parser pr_parser; 254 }; 255 256 struct prest *prest_create(const char *); 257 struct paddr *paddr_create(const char *, parser_exec_t, const char *, 258 const char *, struct parser *); 259 struct pstr *pstr_create(const char *, parser_exec_t, const char *, 260 struct parser *); 261 struct piface *piface_create(const char *, parser_exec_t, const char *, 262 struct parser *); 263 struct pkw *pkw_create(const char *, parser_exec_t, 264 const char *, const struct kwinst *, size_t, struct parser *); 265 struct pranges *pranges_create(const char *, parser_exec_t, const char *, 266 const struct intrange *, size_t, struct parser *); 267 struct pbranch *pbranch_create(const char *, const struct branch *, size_t, 268 bool); 269 int pbranch_addbranch(struct pbranch *, struct parser *); 270 int pbranch_setbranches(struct pbranch *, const struct branch *, size_t); 271 272 int parse(int, char **, const struct parser *, struct match *, size_t *, int *); 273 274 int matches_exec(const struct match *, prop_dictionary_t, size_t); 275 int parser_init(struct parser *); 276 277 #endif /* _IFCONFIG_PARSE_H */ 278