13 #include <netlink-private/netlink.h> 14 #include <netlink/netlink.h> 15 #include <netlink/utils.h> 16 #include <netlink/addr.h> 17 #include <netlink/attr.h> 18 #include <netlink/msg.h> 19 #include <linux/socket.h> 58 return NLA_HDRLEN + payload;
112 return nla->nla_type & NLA_TYPE_MASK;
123 return (
char *) nla + NLA_HDRLEN;
134 return nla->nla_len - NLA_HDRLEN;
149 int nla_ok(
const struct nlattr *nla,
int remaining)
151 return remaining >= (int)
sizeof(*nla) &&
152 nla->nla_len >=
sizeof(*nla) &&
153 nla->nla_len <= remaining;
172 struct nlattr *
nla_next(
const struct nlattr *nla,
int *remaining)
174 int totlen = NLA_ALIGN(nla->nla_len);
176 *remaining -= totlen;
177 return (
struct nlattr *) ((
char *) nla + totlen);
180 static uint16_t nla_attr_minlen[NLA_TYPE_MAX+1] = {
181 [
NLA_U8] =
sizeof(uint8_t),
189 static int validate_nla(
const struct nlattr *nla,
int maxtype,
196 if (type < 0 || type > maxtype)
201 if (pt->
type > NLA_TYPE_MAX)
217 if (data[
nla_len(nla) - 1] !=
'\0')
243 int nla_parse(
struct nlattr *tb[],
int maxtype,
struct nlattr *head,
int len,
249 memset(tb, 0,
sizeof(
struct nlattr *) * (maxtype + 1));
258 err = validate_nla(nla, maxtype, policy);
264 NL_DBG(1,
"Attribute of type %#x found multiple times in message, " 265 "previous attribute is being ignored.\n", type);
271 NL_DBG(1,
"netlink: %d bytes leftover after parsing " 272 "attributes.\n", rem);
298 const struct nlattr *nla;
302 err = validate_nla(nla, maxtype, policy);
324 struct nlattr *
nla_find(
const struct nlattr *head,
int len,
int attrtype)
326 const struct nlattr *nla;
331 return (
struct nlattr*)nla;
354 int nla_memcpy(
void *dest,
const struct nlattr *src,
int count)
361 minlen = min_t(
int, count,
nla_len(src));
362 memcpy(dest,
nla_data(src), minlen);
379 size_t nla_strlcpy(
char *dst,
const struct nlattr *nla,
size_t dstsize)
384 if (srclen > 0 && src[srclen - 1] ==
'\0')
388 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
390 memset(dst, 0, dstsize);
391 memcpy(dst, src, len);
406 int nla_memcmp(
const struct nlattr *nla,
const void *data,
size_t size)
411 d = memcmp(
nla_data(nla), data, size);
426 int len = strlen(str) + 1;
430 d = memcmp(
nla_data(nla), str, len);
457 struct nlattr *
nla_reserve(
struct nl_msg *msg,
int attrtype,
int attrlen)
465 tlen = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) +
nla_total_size(attrlen);
467 if (tlen > msg->nm_size)
470 nla = (
struct nlattr *) nlmsg_tail(msg->nm_nlh);
471 nla->nla_type = attrtype;
475 memset((
unsigned char *) nla + nla->nla_len, 0,
nla_padlen(attrlen));
476 msg->nm_nlh->nlmsg_len = tlen;
478 NL_DBG(2,
"msg %p: attr <%p> %d: Reserved %d (%d) bytes at offset +%td " 479 "nlmsg_len=%d\n", msg, nla, nla->nla_type,
481 (
char *) nla - (
char *)
nlmsg_data(msg->nm_nlh),
482 msg->nm_nlh->nlmsg_len);
501 int nla_put(
struct nl_msg *msg,
int attrtype,
int datalen,
const void *data)
514 memcpy(
nla_data(nla), data, datalen);
515 NL_DBG(2,
"msg %p: attr <%p> %d: Wrote %d bytes at offset +%td\n",
516 msg, nla, nla->nla_type, datalen,
517 (
char *) nla - (
char *)
nlmsg_data(msg->nm_nlh));
535 int nla_put_data(
struct nl_msg *msg,
int attrtype,
const struct nl_data *data)
550 int nla_put_addr(
struct nl_msg *msg,
int attrtype,
struct nl_addr *addr)
571 int nla_put_s8(
struct nl_msg *msg,
int attrtype, int8_t value)
573 return nla_put(msg, attrtype,
sizeof(int8_t), &value);
584 return *(
const int8_t *)
nla_data(nla);
596 int nla_put_u8(
struct nl_msg *msg,
int attrtype, uint8_t value)
598 return nla_put(msg, attrtype,
sizeof(uint8_t), &value);
609 return *(
const uint8_t *)
nla_data(nla);
623 return nla_put(msg, attrtype,
sizeof(int16_t), &value);
634 return *(
const int16_t *)
nla_data(nla);
648 return nla_put(msg, attrtype,
sizeof(uint16_t), &value);
659 return *(
const uint16_t *)
nla_data(nla);
673 return nla_put(msg, attrtype,
sizeof(int32_t), &value);
684 return *(
const int32_t *)
nla_data(nla);
698 return nla_put(msg, attrtype,
sizeof(uint32_t), &value);
709 return *(
const uint32_t *)
nla_data(nla);
723 return nla_put(msg, attrtype,
sizeof(int64_t), &value);
736 if (nla &&
nla_len(nla) >=
sizeof(tmp))
737 memcpy(&tmp,
nla_data(nla),
sizeof(tmp));
753 return nla_put(msg, attrtype,
sizeof(uint64_t), &value);
766 if (nla &&
nla_len(nla) >=
sizeof(tmp))
767 memcpy(&tmp,
nla_data(nla),
sizeof(tmp));
789 return nla_put(msg, attrtype, strlen(str) + 1, str);
803 char *nla_strdup(
const struct nlattr *nla)
824 return nla_put(msg, attrtype, 0, NULL);
886 const struct nl_msg *nested)
888 NL_DBG(2,
"msg %p: attr <> %d: adding msg %p as nested attribute\n",
889 msg, attrtype, nested);
905 struct nlattr *start = (
struct nlattr *) nlmsg_tail(msg->nm_nlh);
907 if (
nla_put(msg, NLA_F_NESTED | attrtype, 0, NULL) < 0)
910 NL_DBG(2,
"msg %p: attr <%p> %d: starting nesting\n",
911 msg, start, start->nla_type);
916 static int _nest_end(
struct nl_msg *msg,
struct nlattr *start,
int keep_empty)
920 len = (
char *) nlmsg_tail(msg->nm_nlh) - (
char *) start;
923 || (!keep_empty && len == NLA_HDRLEN)) {
931 return (len == NLA_HDRLEN) ? 0 : -NLE_ATTRSIZE;
934 start->nla_len = len;
936 pad = NLMSG_ALIGN(msg->nm_nlh->nlmsg_len) - msg->nm_nlh->nlmsg_len;
947 NL_DBG(2,
"msg %p: attr <%p> %d: added %zu bytes of padding\n",
948 msg, start, start->nla_type, pad);
951 NL_DBG(2,
"msg %p: attr <%p> %d: closing nesting, len=%u\n",
952 msg, start, start->nla_type, start->nla_len);
968 return _nest_end (msg, start, 0);
983 return _nest_end (msg, start, 1);
999 len = (
char *) nlmsg_tail(msg->nm_nlh) - (
char *) attr;
1003 msg->nm_nlh->nlmsg_len -= len;
1004 memset(nlmsg_tail(msg->nm_nlh), 0, len);
1035 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.
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, const struct nla_policy *policy)
Create attribute index based on a stream of attributes.
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.
int nla_nest_end_keep_empty(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes without stripping off empty attributes.
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_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
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_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 .
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.