aa9db6efb2
tells whether it should detect and convert to binary a hexadecimal octet string of the form 0x0123ABab, or leave those strings undecoded. If the argument for a 'media', 'mediamode', 'mediaopt', '-mediaopt', 'nwkey', or 'bssid' keyword is a hexadecimal octet string, do not detect and decode it. (Note that setifnwkey decodes hexadecimal strings on its own.) This fixes a bug noticed by Jim Miller where the trailing zero-octets were discarded from hexadecimal octet-string arguments for 'nwkey'.
285 lines
7.4 KiB
C
285 lines
7.4 KiB
C
#ifndef _IFCONFIG_PARSE_H
|
|
#define _IFCONFIG_PARSE_H
|
|
|
|
#include <inttypes.h>
|
|
#include <stdbool.h>
|
|
#include <stddef.h>
|
|
#include <sys/queue.h>
|
|
#include <prop/proplib.h>
|
|
#include <sys/socket.h>
|
|
|
|
struct match;
|
|
struct parser;
|
|
|
|
extern struct pbranch command_root;
|
|
|
|
typedef int (*parser_exec_t)(prop_dictionary_t, prop_dictionary_t);
|
|
typedef int (*parser_match_t)(const struct parser *, const struct match *,
|
|
struct match *, int, const char *);
|
|
typedef int (*parser_init_t)(struct parser *);
|
|
|
|
struct match {
|
|
prop_dictionary_t m_env;
|
|
const struct parser *m_nextparser;
|
|
const struct parser *m_parser;
|
|
int m_argidx;
|
|
parser_exec_t m_exec;
|
|
};
|
|
|
|
/* method table */
|
|
struct parser_methods {
|
|
parser_match_t pm_match;
|
|
parser_init_t pm_init;
|
|
};
|
|
|
|
struct parser {
|
|
const struct parser_methods *p_methods;
|
|
parser_exec_t p_exec;
|
|
const char *p_name;
|
|
struct parser *p_nextparser;
|
|
bool p_initialized;
|
|
};
|
|
|
|
struct branch {
|
|
SIMPLEQ_ENTRY(branch) b_next;
|
|
struct parser *b_nextparser;
|
|
};
|
|
|
|
struct pbranch {
|
|
struct parser pb_parser;
|
|
SIMPLEQ_HEAD(, branch) pb_branches;
|
|
bool pb_match_first;
|
|
const struct branch *pb_brinit;
|
|
size_t pb_nbrinit;
|
|
};
|
|
|
|
struct pterm {
|
|
struct parser pt_parser;
|
|
const char *pt_key;
|
|
};
|
|
|
|
extern const struct parser_methods paddr_methods;
|
|
extern const struct parser_methods pbranch_methods;
|
|
extern const struct parser_methods piface_methods;
|
|
extern const struct parser_methods pinteger_methods;
|
|
extern const struct parser_methods pstr_methods;
|
|
extern const struct parser_methods pkw_methods;
|
|
extern const struct parser_methods pterm_methods;
|
|
|
|
#define PTERM_INITIALIZER(__pt, __name, __exec, __key) \
|
|
{ \
|
|
.pt_parser = {.p_name = (__name), .p_methods = &pterm_methods, \
|
|
.p_exec = (__exec)}, \
|
|
.pt_key = (__key) \
|
|
}
|
|
|
|
#define PBRANCH_INITIALIZER(__pb, __name, __brs, __nbr, __match_first) \
|
|
{ \
|
|
.pb_parser = {.p_name = (__name), .p_methods = &pbranch_methods},\
|
|
.pb_branches = SIMPLEQ_HEAD_INITIALIZER((__pb)->pb_branches), \
|
|
.pb_brinit = (__brs), \
|
|
.pb_nbrinit = (__nbr), \
|
|
.pb_match_first = (__match_first) \
|
|
}
|
|
|
|
#define PSTR_INITIALIZER(__ps, __name, __defexec, __defkey, __defnext) \
|
|
PSTR_INITIALIZER1((__ps), (__name), (__defexec), (__defkey), \
|
|
true, (__defnext))
|
|
|
|
#define PSTR_INITIALIZER1(__ps, __name, __defexec, __defkey, __defhexok,\
|
|
__defnext) \
|
|
{ \
|
|
.ps_parser = {.p_name = (__name), .p_methods = &pstr_methods, \
|
|
.p_exec = (__defexec), \
|
|
.p_nextparser = (__defnext)}, \
|
|
.ps_key = (__defkey), \
|
|
.ps_hexok = (__defhexok) \
|
|
}
|
|
|
|
#define PADDR_INITIALIZER(__pa, __name, __defexec, __addrkey, \
|
|
__maskkey, __activator, __deactivator, __defnext) \
|
|
{ \
|
|
.pa_parser = {.p_name = (__name), .p_methods = &paddr_methods, \
|
|
.p_exec = (__defexec), \
|
|
.p_nextparser = (__defnext)}, \
|
|
.pa_addrkey = (__addrkey), \
|
|
.pa_maskkey = (__maskkey), \
|
|
.pa_activator = (__activator), \
|
|
.pa_deactivator = (__deactivator), \
|
|
}
|
|
|
|
#define PIFACE_INITIALIZER(__pif, __name, __defexec, __defkey, __defnext)\
|
|
{ \
|
|
.pif_parser = {.p_name = (__name), .p_methods = &piface_methods,\
|
|
.p_exec = (__defexec), \
|
|
.p_nextparser = (__defnext)}, \
|
|
.pif_key = (__defkey) \
|
|
}
|
|
|
|
#define PINTEGER_INITIALIZER1(__pi, __name, __min, __max, __base, \
|
|
__defexec, __defkey, __defnext) \
|
|
{ \
|
|
.pi_parser = {.p_name = (__name), .p_methods = &pinteger_methods,\
|
|
.p_exec = (__defexec), \
|
|
.p_nextparser = (__defnext), \
|
|
.p_initialized = false}, \
|
|
.pi_min = (__min), \
|
|
.pi_max = (__max), \
|
|
.pi_base = (__base), \
|
|
.pi_key = (__defkey) \
|
|
}
|
|
|
|
#define PINTEGER_INITIALIZER(__pi, __name, __base, __defexec, __defkey, \
|
|
__defnext) \
|
|
PINTEGER_INITIALIZER1(__pi, __name, INTMAX_MIN, INTMAX_MAX, \
|
|
__base, __defexec, __defkey, __defnext)
|
|
|
|
#define PKW_INITIALIZER(__pk, __name, __defexec, __defkey, __kws, __nkw,\
|
|
__defnext) \
|
|
{ \
|
|
.pk_parser = {.p_name = (__name), \
|
|
.p_exec = (__defexec), \
|
|
.p_methods = &pkw_methods, \
|
|
.p_initialized = false}, \
|
|
.pk_keywords = SIMPLEQ_HEAD_INITIALIZER((__pk)->pk_keywords), \
|
|
.pk_kwinit = (__kws), \
|
|
.pk_nkwinit = (__nkw), \
|
|
.pk_keyinit = (__defkey), \
|
|
.pk_nextinit = (__defnext) \
|
|
}
|
|
|
|
#define IFKW(__word, __flag) \
|
|
{ \
|
|
.k_word = (__word), .k_neg = true, .k_type = KW_T_INT, \
|
|
.k_int = (__flag), \
|
|
.k_negint = -(__flag) \
|
|
}
|
|
|
|
#define KW_T_NONE 0
|
|
#define KW_T_OBJ 1
|
|
#define KW_T_INT 2
|
|
#define KW_T_STR 3
|
|
#define KW_T_BOOL 4
|
|
#define KW_T_UINT 5
|
|
|
|
struct kwinst {
|
|
SIMPLEQ_ENTRY(kwinst) k_next;
|
|
int k_type;
|
|
const char *k_word;
|
|
const char *k_key;
|
|
const char *k_act;
|
|
const char *k_deact;
|
|
const char *k_altdeact;
|
|
parser_exec_t k_exec;
|
|
union kwval {
|
|
int64_t u_sint;
|
|
uint64_t u_uint;
|
|
const char *u_str;
|
|
prop_object_t u_obj;
|
|
bool u_bool;
|
|
} k_u, k_negu;
|
|
#define k_int k_u.u_sint
|
|
#define k_uint k_u.u_uint
|
|
#define k_str k_u.u_str
|
|
#define k_obj k_u.u_obj
|
|
#define k_bool k_u.u_bool
|
|
|
|
#define k_negint k_negu.u_sint
|
|
#define k_neguint k_negu.u_uint
|
|
#define k_negstr k_negu.u_str
|
|
#define k_negobj k_negu.u_obj
|
|
#define k_negbool k_negu.u_bool
|
|
|
|
bool k_neg; /* allow negative form, -keyword */
|
|
struct parser *k_nextparser;
|
|
};
|
|
|
|
struct pkw {
|
|
struct parser pk_parser;
|
|
const char *pk_key;
|
|
const char *pk_keyinit;
|
|
const struct kwinst *pk_kwinit;
|
|
size_t pk_nkwinit;
|
|
SIMPLEQ_HEAD(, kwinst) pk_keywords;
|
|
};
|
|
|
|
#define pk_nextinit pk_parser.p_nextparser
|
|
#define pk_execinit pk_parser.p_exec
|
|
|
|
struct pstr {
|
|
struct parser ps_parser;
|
|
const char *ps_key;
|
|
bool ps_hexok;
|
|
};
|
|
|
|
struct pinteger {
|
|
struct parser pi_parser;
|
|
int64_t pi_min;
|
|
int64_t pi_max;
|
|
int pi_base;
|
|
const char *pi_key;
|
|
};
|
|
|
|
struct intrange {
|
|
SIMPLEQ_ENTRY(intrange) r_next;
|
|
int64_t r_bottom;
|
|
int64_t r_top;
|
|
struct parser *r_nextparser;
|
|
};
|
|
|
|
struct pranges {
|
|
struct parser pr_parser;
|
|
SIMPLEQ_HEAD(, intrange) pr_ranges;
|
|
};
|
|
|
|
struct paddr_prefix {
|
|
int16_t pfx_len;
|
|
struct sockaddr pfx_addr;
|
|
};
|
|
|
|
static inline size_t
|
|
paddr_prefix_size(const struct paddr_prefix *pfx)
|
|
{
|
|
return offsetof(struct paddr_prefix, pfx_addr) + pfx->pfx_addr.sa_len;
|
|
}
|
|
|
|
struct paddr {
|
|
struct parser pa_parser;
|
|
const char *pa_addrkey;
|
|
const char *pa_maskkey;
|
|
const char *pa_activator;
|
|
const char *pa_deactivator;
|
|
};
|
|
|
|
struct piface {
|
|
struct parser pif_parser;
|
|
const char *pif_key;
|
|
};
|
|
|
|
struct prest {
|
|
struct parser pr_parser;
|
|
};
|
|
|
|
struct prest *prest_create(const char *);
|
|
struct paddr *paddr_create(const char *, parser_exec_t, const char *,
|
|
const char *, struct parser *);
|
|
struct pstr *pstr_create(const char *, parser_exec_t, const char *,
|
|
bool, struct parser *);
|
|
struct piface *piface_create(const char *, parser_exec_t, const char *,
|
|
struct parser *);
|
|
struct pkw *pkw_create(const char *, parser_exec_t,
|
|
const char *, const struct kwinst *, size_t, struct parser *);
|
|
struct pranges *pranges_create(const char *, parser_exec_t, const char *,
|
|
const struct intrange *, size_t, struct parser *);
|
|
struct pbranch *pbranch_create(const char *, const struct branch *, size_t,
|
|
bool);
|
|
int pbranch_addbranch(struct pbranch *, struct parser *);
|
|
int pbranch_setbranches(struct pbranch *, const struct branch *, size_t);
|
|
|
|
int parse(int, char **, const struct parser *, struct match *, size_t *, int *);
|
|
|
|
int matches_exec(const struct match *, prop_dictionary_t, size_t);
|
|
int parser_init(struct parser *);
|
|
|
|
#endif /* _IFCONFIG_PARSE_H */
|