12 #include <netlink-local.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>
110 return NLA_HDRLEN + payload;
144 return nla->nla_type & NLA_TYPE_MASK;
153 return (
char *) nla + NLA_HDRLEN;
162 return nla->nla_len - NLA_HDRLEN;
177 int nla_ok(
const struct nlattr *nla,
int remaining)
179 return remaining >=
sizeof(*nla) &&
180 nla->nla_len >=
sizeof(*nla) &&
181 nla->nla_len <= remaining;
192 struct nlattr *
nla_next(
const struct nlattr *nla,
int *remaining)
194 int totlen = NLA_ALIGN(nla->nla_len);
196 *remaining -= totlen;
197 return (
struct nlattr *) ((
char *) nla + totlen);
201 [
NLA_U8] =
sizeof(uint8_t),
209 static int validate_nla(
struct nlattr *nla,
int maxtype,
215 if (type <= 0 || type > maxtype)
226 minlen = nla_attr_minlen[pt->
type];
229 return nl_errno(ERANGE);
232 return nl_errno(ERANGE);
235 return nl_errno(ERANGE);
239 if (data[
nla_len(nla) - 1] !=
'\0')
240 return nl_errno(EINVAL);
262 int nla_parse(
struct nlattr *tb[],
int maxtype,
struct nlattr *head,
int len,
268 memset(tb, 0,
sizeof(
struct nlattr *) * (maxtype + 1));
274 fprintf(stderr,
"Illegal nla->nla_type == 0\n");
278 if (type <= maxtype) {
280 err = validate_nla(nla, maxtype, policy);
290 fprintf(stderr,
"netlink: %d bytes leftover after parsing "
291 "attributes.\n", rem);
335 err = validate_nla(nla, maxtype, policy);
353 struct nlattr *
nla_find(
struct nlattr *head,
int len,
int attrtype)
390 minlen = min_t(
int, count,
nla_len(src));
391 memcpy(dest,
nla_data(src), minlen);
408 size_t nla_strlcpy(
char *dst,
const struct nlattr *nla,
size_t dstsize)
413 if (srclen > 0 && src[srclen - 1] ==
'\0')
417 size_t len = (srclen >= dstsize) ? dstsize - 1 : srclen;
419 memset(dst, 0, dstsize);
420 memcpy(dst, src, len);
438 d = memcmp(
nla_data(nla), data, size);
450 int len = strlen(str) + 1;
454 d = memcmp(
nla_data(nla), str, len);
475 struct nlattr *
nla_reserve(
struct nl_msg *n,
int attrtype,
int attrlen)
480 tlen = NLMSG_ALIGN(n->nm_nlh->nlmsg_len) +
nla_total_size(attrlen);
482 if ((tlen + n->nm_nlh->nlmsg_len) > n->nm_size) {
487 nla = (
struct nlattr *) nlmsg_tail(n->nm_nlh);
488 nla->nla_type = attrtype;
491 memset((
unsigned char *) nla + nla->nla_len, 0,
nla_padlen(attrlen));
492 n->nm_nlh->nlmsg_len = tlen;
494 NL_DBG(2,
"msg %p: Reserved %d bytes at offset +%td for attr %d "
495 "nlmsg_len=%d\n", n, attrlen,
497 attrtype, n->nm_nlh->nlmsg_len);
512 int nla_put(
struct nl_msg *n,
int attrtype,
int attrlen,
const void *data)
518 return nl_errno(ENOMEM);
520 memcpy(
nla_data(nla), data, attrlen);
521 NL_DBG(2,
"msg %p: Wrote %d bytes at offset +%td for attr %d\n",
522 n, attrlen, (
void *) nla -
nlmsg_data(n->nm_nlh), attrtype);
548 int nla_put_u8(
struct nl_msg *n,
int attrtype, uint8_t value)
550 return nla_put(n, attrtype,
sizeof(uint8_t), &value);
561 return nla_put(n, attrtype,
sizeof(uint16_t), &value);
572 return nla_put(n, attrtype,
sizeof(uint32_t), &value);
583 return nla_put(n, attrtype,
sizeof(uint64_t), &value);
594 return nla_put(n, attrtype, strlen(str) + 1, str);
604 return nla_put(n, attrtype, 0, NULL);
658 struct nlattr *start = (
struct nlattr *) nlmsg_tail(n->nm_nlh);
660 if (
nla_put(n, attrtype, 0, NULL) < 0)
678 start->nla_len = (
unsigned char *) nlmsg_tail(n->nm_nlh) -
679 (
unsigned char *) start;
int nla_validate(struct nlattr *head, int len, int maxtype, struct nla_policy *policy)
Validate a stream of attributes.
int nla_put_flag(struct nl_msg *n, int attrtype)
Add a flag netlink attribute to a netlink message.
uint16_t nla_get_u16(struct nlattr *nla)
Return payload of u16 attribute.
int nla_ok(const struct nlattr *nla, int remaining)
check if the netlink attribute fits into the remaining bytes
int nla_put_u64(struct nl_msg *n, int attrtype, uint64_t value)
Add a u64 netlink attribute to a netlink message.
int nla_padlen(int payload)
length of padding at the tail of the attribute
int nla_get_flag(struct nlattr *nla)
Return payload of flag attribute.
void * nlmsg_data(const struct nlmsghdr *nlh)
head of message payload
attribute validation policy
int nla_strcmp(const struct nlattr *nla, const char *str)
Compare a string attribute against a string.
int nla_nest_end(struct nl_msg *n, struct nlattr *start)
Finalize nesting of attributes.
int nla_total_size(int payload)
total length of attribute including padding
int nla_memcpy(void *dest, struct nlattr *src, int count)
Copy a netlink attribute into another memory area.
unsigned int nl_addr_get_len(struct nl_addr *addr)
Get length of binary address of abstract address object.
int nla_put_u8(struct nl_msg *n, int attrtype, uint8_t value)
Add a u16 netlink attribute to a netlink message.
struct nlattr * nla_next(const struct nlattr *nla, int *remaining)
next netlink attribte in attribute stream
int nla_put_data(struct nl_msg *n, int attrtype, struct nl_data *data)
Add an abstract data netlink attribute to a netlink message.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, struct nla_policy *policy)
parse nested attributes
uint8_t nla_get_u8(struct nlattr *nla)
Return payload of u8 attribute.
int nla_type(const struct nlattr *nla)
attribute type
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)
length of attribute not including padding
void * nl_addr_get_binary_addr(struct nl_addr *addr)
Get binary address of abstract address object.
void * nla_data(const struct nlattr *nla)
head of payload
uint16_t maxlen
Maximal length of payload required to be available.
int nla_len(const struct nlattr *nla)
length of payload
struct nl_addr * nla_get_addr(struct nlattr *nla, int family)
Return payload of address attribute.
int nla_parse(struct nlattr *tb[], int maxtype, struct nlattr *head, int len, struct nla_policy *policy)
Parse a stream of attributes into a tb buffer.
struct nlattr * nla_find(struct nlattr *head, int len, int attrtype)
Find a specific attribute in a stream of attributes.
struct nl_data * nl_data_alloc(void *buf, size_t size)
Allocate a new abstract data object.
#define NLA_TYPE_MAX
Maximum netlink validation policy type.
uint16_t minlen
Minimal length of payload required to be available.
char * nla_get_string(struct nlattr *nla)
return payload of string attribute
int nla_put_string(struct nl_msg *n, int attrtype, const char *str)
Add a string netlink attribute to a netlink message.
int nla_put(struct nl_msg *n, int attrtype, int attrlen, const void *data)
Add a netlink attribute to a netlink message.
uint64_t nla_get_u64(struct nlattr *nla)
Return payload of u64 attribute.
int nla_put_u16(struct nl_msg *n, int attrtype, uint16_t value)
Add a u16 netlink attribute to a netlink message.
uint16_t type
Type of attribute or NLA_UNSPEC.
int nla_memcmp(const struct nlattr *nla, const void *data, size_t size)
Compare an attribute with sized memory area.
int nlmsg_len(const struct nlmsghdr *nlh)
length of message payload
struct nlattr * nla_reserve(struct nl_msg *n, int attrtype, int attrlen)
reserve room for attribute on the skb
int nla_put_nested(struct nl_msg *n, int attrtype, struct nl_msg *nested)
Add a nested netlink attribute to a netlink message.
struct nl_data * nla_get_data(struct nlattr *nla)
Return payload of abstract data attribute.
size_t nl_data_get_size(struct nl_data *data)
Get size of data buffer of abstract data object.
struct nlattr * nla_nest_start(struct nl_msg *n, int attrtype)
Start a new level of nested attributes.
uint32_t nla_get_u32(struct nlattr *nla)
Return payload of u32 attribute.
int nla_put_u32(struct nl_msg *n, int attrtype, uint32_t value)
Add a u32 netlink attribute to a netlink message.
void * nl_data_get(struct nl_data *data)
Get data buffer of abstract data object.
int nla_put_addr(struct nl_msg *n, int attrtype, struct nl_addr *addr)
Add an abstract address netlink attribute to a netlink message.
struct nl_addr * nl_addr_build(int family, void *buf, size_t size)
Allocate new abstract address object based on a binary address.
unsigned long nla_get_msecs(struct nlattr *nla)
Return payload of msecs attribute.
size_t nla_strlcpy(char *dst, const struct nlattr *nla, size_t dstsize)
Copy string attribute payload into a sized buffer.
#define nla_for_each_attr(pos, head, len, rem)
iterate over a stream of attributes