12 #include <netlink-private/netlink.h> 13 #include <netlink/netlink.h> 14 #include <netlink/utils.h> 15 #include <netlink/addr.h> 16 #include <netlink/attr.h> 17 #include <netlink/msg.h> 18 #include <linux/socket.h> 57 return NLA_HDRLEN + payload;
111 return nla->nla_type & NLA_TYPE_MASK;
122 return (
char *) nla + NLA_HDRLEN;
133 return nla->nla_len - NLA_HDRLEN;
148 int nla_ok(
const struct nlattr *nla,
int remaining)
150 return remaining >=
sizeof(*nla) &&
151 nla->nla_len >=
sizeof(*nla) &&
152 nla->nla_len <= remaining;
171 struct nlattr *
nla_next(
const struct nlattr *nla,
int *remaining)
173 int totlen = NLA_ALIGN(nla->nla_len);
175 *remaining -= totlen;
176 return (
struct nlattr *) ((
char *) nla + totlen);
179 static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
180 [
NLA_U8] =
sizeof(uint8_t),
188 static int validate_nla(
const struct nlattr *nla,
int maxtype,
195 if (type < 0 || type > maxtype)
200 if (pt->
type > NLA_TYPE_MAX)
206 minlen = nla_attr_minlen[pt->
type];
216 if (data[
nla_len(nla) - 1] !=
'\0')
242 int nla_parse(
struct nlattr *tb[],
int maxtype,
struct nlattr *head,
int len,
248 memset(tb, 0,
sizeof(
struct nlattr *) * (maxtype + 1));
257 err = validate_nla(nla, maxtype, policy);
263 NL_DBG(1,
"Attribute of type %#x found multiple times in message, " 264 "previous attribute is being ignored.\n", type);
270 NL_DBG(1,
"netlink: %d bytes leftover after parsing " 271 "attributes.\n", rem);
297 const struct nlattr *nla;
301 err = validate_nla(nla, maxtype, policy);
323 struct nlattr *
nla_find(
const struct nlattr *head,
int len,
int attrtype)
325 const struct nlattr *nla;
330 return (
struct nlattr*)nla;
353 int nla_memcpy(
void *dest,
const struct nlattr *src,
int count)
360 minlen = min_t(
int, count,
nla_len(src));
361 memcpy(dest,
nla_data(src), minlen);
378 size_t nla_strlcpy(
char *dst,
const struct nlattr *nla,
size_t dstsize)
383 if (srclen > 0 && src[srclen - 1] ==
'\0')
387 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
389 memset(dst, 0, dstsize);
390 memcpy(dst, src, len);
405 int nla_memcmp(
const struct nlattr *nla,
const void *data,
size_t size)
410 d = memcmp(
nla_data(nla), data, size);
425 int len = strlen(str) + 1;
429 d = memcmp(
nla_data(nla), str, len);
456 struct nlattr *
nla_reserve(
struct nl_msg *msg,
int attrtype,
int attrlen)
464 tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) +
nla_total_size(attrlen);
466 if (tlen > msg->nm_size)
469 nla = (
struct nlattr *) nlmsg_tail(msg->nm_nlh);
470 nla->nla_type = attrtype;
474 memset((
unsigned char *) nla + nla->nla_len, 0,
nla_padlen(attrlen));
475 msg->nm_nlh->nlmsg_len = tlen;
477 NL_DBG(2,
"msg %p: attr <%p> %d: Reserved %d (%d) bytes at offset +%td " 478 "nlmsg_len=%d\n", msg, nla, nla->nla_type,
481 msg->nm_nlh->nlmsg_len);
500 int nla_put(
struct nl_msg *msg,
int attrtype,
int datalen,
const void *data)
513 memcpy(
nla_data(nla), data, datalen);
514 NL_DBG(2,
"msg %p: attr <%p> %d: Wrote %d bytes at offset +%td\n",
515 msg, nla, nla->nla_type, datalen,
534 int nla_put_data(
struct nl_msg *msg,
int attrtype,
const struct nl_data *data)
549 int nla_put_addr(
struct nl_msg *msg,
int attrtype,
struct nl_addr *addr)
570 int nla_put_s8(
struct nl_msg *msg,
int attrtype, int8_t value)
572 return nla_put(msg, attrtype,
sizeof(int8_t), &value);
583 return *(
const int8_t *)
nla_data(nla);
595 int nla_put_u8(
struct nl_msg *msg,
int attrtype, uint8_t value)
597 return nla_put(msg, attrtype,
sizeof(uint8_t), &value);
608 return *(
const uint8_t *)
nla_data(nla);
622 return nla_put(msg, attrtype,
sizeof(int16_t), &value);
633 return *(
const int16_t *)
nla_data(nla);
647 return nla_put(msg, attrtype,
sizeof(uint16_t), &value);
658 return *(
const uint16_t *)
nla_data(nla);
672 return nla_put(msg, attrtype,
sizeof(int32_t), &value);
683 return *(
const int32_t *)
nla_data(nla);
697 return nla_put(msg, attrtype,
sizeof(uint32_t), &value);
708 return *(
const uint32_t *)
nla_data(nla);
722 return nla_put(msg, attrtype,
sizeof(int64_t), &value);
735 if (nla &&
nla_len(nla) >=
sizeof(tmp))
736 memcpy(&tmp,
nla_data(nla),
sizeof(tmp));
752 return nla_put(msg, attrtype,
sizeof(uint64_t), &value);
765 if (nla &&
nla_len(nla) >=
sizeof(tmp))
766 memcpy(&tmp,
nla_data(nla),
sizeof(tmp));
788 return nla_put(msg, attrtype, strlen(str) + 1, str);
802 char *nla_strdup(
const struct nlattr *nla)
823 return nla_put(msg, attrtype, 0, NULL);
885 const struct nl_msg *nested)
887 NL_DBG(2,
"msg %p: attr <> %d: adding msg %p as nested attribute\n",
888 msg, attrtype, nested);
904 struct nlattr *start = (
struct nlattr *) nlmsg_tail(msg->nm_nlh);
906 if (
nla_put(msg, attrtype, 0, NULL) < 0)
909 NL_DBG(2,
"msg %p: attr <%p> %d: starting nesting\n",
910 msg, start, start->nla_type);
928 len = (
void *) nlmsg_tail(msg->nm_nlh) - (
void *) start;
930 if (len == NLA_HDRLEN || len > USHRT_MAX) {
938 return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE;
941 start->nla_len = len;
943 pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len;
954 NL_DBG(2,
"msg %p: attr <%p> %d: added %zu bytes of padding\n",
955 msg, start, start->nla_type, pad);
958 NL_DBG(2,
"msg %p: attr <%p> %d: closing nesting, len=%u\n",
959 msg, start, start->nla_type, start->nla_len);
977 len = (
void *) nlmsg_tail(msg->nm_nlh) - (
void *) attr;
981 msg->nm_nlh->nlmsg_len -= len;
982 memset(nlmsg_tail(msg->nm_nlh), 0, len);
1013 return !!(attr->nla_type & NLA_F_NESTED);
int nla_ok(const struct nlattr *nla, int remaining)
Check if the attribute header and payload can be accessed safely.
int32_t nla_get_s32(const struct nlattr *nla)
Return payload of 32 bit signed integer attribute.
int nla_padlen(int payload)
Return length of padding at the tail of the attribute.
int nla_put_u16(struct nl_msg *msg, int attrtype, uint16_t value)
Add 16 bit integer attribute to netlink message.
struct nlattr * nla_find(const struct nlattr *head, int len, int attrtype)
Find a single attribute in a stream of attributes.
void * nlmsg_data(const struct nlmsghdr *nlh)
Return pointer to message payload.
int nla_get_flag(const struct nlattr *nla)
Return true if flag attribute is set.
void * nl_data_get(const struct nl_data *data)
Get data buffer of abstract data object.
int16_t nla_get_s16(const struct nlattr *nla)
Return payload of 16 bit signed integer attribute.
int nla_put_addr(struct nl_msg *msg, int attrtype, struct nl_addr *addr)
Add abstract address as unspecific attribute to netlink message.
int nla_put_s8(struct nl_msg *msg, int attrtype, int8_t value)
Add 8 bit signed integer attribute to netlink message.
void * nlmsg_reserve(struct nl_msg *n, size_t len, int pad)
Reserve room for additional data in a netlink message.
Attribute validation policy.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
Unspecified type, binary data chunk.
int nla_strcmp(const struct nlattr *nla, const char *str)
Compare string attribute payload with string.
char * nla_get_string(const struct nlattr *nla)
Return payload of string attribute.
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
size_t nl_data_get_size(const struct nl_data *data)
Get size of data buffer of abstract data object.
struct nlattr * nla_reserve(struct nl_msg *msg, int attrtype, int attrlen)
Reserve space for a attribute.
int8_t nla_get_s8(const struct nlattr *nla)
Return value of 8 bit signed integer attribute.
int nla_put_s32(struct nl_msg *msg, int attrtype, int32_t value)
Add 32 bit signed integer attribute to netlink message.
NUL terminated character string.
int nla_is_nested(const struct nlattr *attr)
Return true if attribute has NLA_F_NESTED flag set.
int nla_total_size(int payload)
Return size of attribute including padding.
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
int nla_put_flag(struct nl_msg *msg, int attrtype)
Add flag netlink attribute to netlink message.
int64_t nla_get_s64(const struct nlattr *nla)
Return payload of s64 attribute.
struct nlattr * nla_next(const struct nlattr *nla, int *remaining)
Return next attribute in a stream of attributes.
int nlmsg_datalen(const struct nlmsghdr *nlh)
Return length of message payload.
int nla_put_data(struct nl_msg *msg, int attrtype, const struct nl_data *data)
Add abstract data as unspecific attribute to netlink message.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
Create attribute index based on nested attribute.
int nla_type(const struct nlattr *nla)
Return type of the attribute.
int nla_put_msecs(struct nl_msg *n, int attrtype, unsigned long msecs)
Add a msecs netlink attribute to a netlink message.
int nla_attr_size(int payload)
Return size of attribute whithout padding.
int nla_put_u64(struct nl_msg *msg, int attrtype, uint64_t value)
Add 64 bit integer attribute to netlink message.
int nla_put_nested(struct nl_msg *msg, int attrtype, const struct nl_msg *nested)
Add nested attributes to netlink message.
void * nla_data(const struct nlattr *nla)
Return pointer to the payload section.
uint16_t maxlen
Maximal length of payload allowed.
int nla_len(const struct nlattr *nla)
Return length of the payload .
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, struct nla_policy *policy)
Create attribute index based on a stream of attributes.
unsigned long nla_get_msecs(const struct nlattr *nla)
Return payload of msecs attribute.
uint16_t minlen
Minimal length of payload required.
int nla_put_s16(struct nl_msg *msg, int attrtype, int16_t value)
Add 16 bit signed integer attribute to netlink message.
void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr)
Cancel the addition of a nested attribute.
uint16_t type
Type of attribute or NLA_UNSPEC.
int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
Compare attribute payload with memory area.
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
int nla_put_u32(struct nl_msg *msg, int attrtype, uint32_t value)
Add 32 bit integer attribute to netlink message.
int nla_put_u8(struct nl_msg *msg, int attrtype, uint8_t value)
Add 8 bit integer attribute to netlink message.
uint64_t nla_get_u64(const struct nlattr *nla)
Return payload of u64 attribute.
int nla_put_string(struct nl_msg *msg, int attrtype, const char *str)
Add string attribute to netlink message.
int nla_put(struct nl_msg *msg, int attrtype, int datalen, const void *data)
Add a unspecific attribute to netlink message.
unsigned int nl_addr_get_len(const struct nl_addr *addr)
Get length of binary address of abstract address object.
int nla_put_s64(struct nl_msg *msg, int attrtype, int64_t value)
Add 64 bit signed integer attribute to netlink message.
void * nl_addr_get_binary_addr(const struct nl_addr *addr)
Get binary address of abstract address object.
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload to a buffer.
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
#define nla_for_each_attr(pos, head, len, rem)
Iterate over a stream of attributes.
int nla_validate(const struct nlattr *head, int len, int maxtype, const struct nla_policy *policy)
Validate a stream of attributes.