netlink: add attr parser utility functions
- nlattr_get_chara() to read a string into a char array, rather than to a char *
- nlattr_get_bytes() to read an arbitrary (fixed length) byte sequence
- nlattr_get_nested_ptr() to read a nested type to a struct foo *, rather than struct foo
Sponsored by: Rubicon Communications, LLC ("Netgate")
Differential Revision: https://reviews.freebsd.org/D42221
This commit is contained in:
@@ -428,6 +428,23 @@ nlattr_get_ifpz(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void
|
||||
return (nlattr_get_ifp_internal(nla, npt, target, true));
|
||||
}
|
||||
|
||||
int
|
||||
nlattr_get_chara(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
|
||||
{
|
||||
int maxlen = NLA_DATA_LEN(nla);
|
||||
int target_size = (size_t)arg;
|
||||
int len = strnlen((char *)NLA_DATA(nla), maxlen);
|
||||
|
||||
if (__predict_false(len >= maxlen) || __predict_false(len >= target_size)) {
|
||||
NLMSG_REPORT_ERR_MSG(npt, "nla type %d size(%u) is not NULL-terminated or longer than %u",
|
||||
nla->nla_type, maxlen, target_size);
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
strncpy((char *)target, (char *)NLA_DATA(nla), target_size);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
nlattr_get_string(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
|
||||
{
|
||||
@@ -457,6 +474,20 @@ nlattr_get_stringn(struct nlattr *nla, struct nl_pstate *npt, const void *arg, v
|
||||
*((char **)target) = buf;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
nlattr_get_bytes(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
|
||||
{
|
||||
size_t size = (size_t)arg;
|
||||
|
||||
if (NLA_DATA_LEN(nla) != size)
|
||||
return (EINVAL);
|
||||
|
||||
memcpy(target, NLA_DATA(nla), size);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
nlattr_get_nla(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
|
||||
{
|
||||
@@ -476,6 +507,17 @@ nlattr_get_nested(struct nlattr *nla, struct nl_pstate *npt, const void *arg, vo
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
nlattr_get_nested_ptr(struct nlattr *nla, struct nl_pstate *npt, const void *arg, void *target)
|
||||
{
|
||||
const struct nlhdr_parser *p = (const struct nlhdr_parser *)arg;
|
||||
int error;
|
||||
|
||||
/* Assumes target points to the beginning of the structure */
|
||||
error = nl_parse_header(NLA_DATA(nla), NLA_DATA_LEN(nla), p, npt, *(void **)target);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
nlf_get_ifp(void *src, struct nl_pstate *npt, void *target)
|
||||
{
|
||||
|
||||
@@ -187,14 +187,20 @@ int nlattr_get_ifpz(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_ipvia(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_chara(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_string(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_stringn(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_bytes(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_nla(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_nested(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
int nlattr_get_nested_ptr(struct nlattr *nla, struct nl_pstate *npt,
|
||||
const void *arg, void *target);
|
||||
|
||||
bool nlmsg_report_err_msg(struct nl_pstate *npt, const char *fmt, ...);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user