NetBSD/sbin/ifconfig/parse.h
dyoung aa9db6efb2 Add to the string parse object (pstr), and its constructors, a flag that
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'.
2010-07-01 16:44:05 +00:00

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 */