10 #include <libmnl/libmnl.h>
38 EXPORT_SYMBOL(mnl_attr_get_type);
39 uint16_t mnl_attr_get_type(
const struct nlattr *attr)
41 return attr->nla_type & NLA_TYPE_MASK;
51 EXPORT_SYMBOL(mnl_attr_get_len);
52 uint16_t mnl_attr_get_len(
const struct nlattr *attr)
63 EXPORT_SYMBOL(mnl_attr_get_payload_len);
64 uint16_t mnl_attr_get_payload_len(
const struct nlattr *attr)
66 return attr->nla_len - MNL_ATTR_HDRLEN;
75 EXPORT_SYMBOL(mnl_attr_get_payload);
76 void *mnl_attr_get_payload(
const struct nlattr *attr)
78 return (
void *)attr + MNL_ATTR_HDRLEN;
97 EXPORT_SYMBOL(mnl_attr_ok);
98 bool mnl_attr_ok(
const struct nlattr *attr,
int len)
100 return len >= (int)
sizeof(
struct nlattr) &&
101 attr->nla_len >=
sizeof(
struct nlattr) &&
102 (int)attr->nla_len <= len;
113 EXPORT_SYMBOL(mnl_attr_next);
114 struct nlattr *mnl_attr_next(
const struct nlattr *attr)
116 return (
struct nlattr *)((
void *)attr + MNL_ALIGN(attr->nla_len));
133 EXPORT_SYMBOL(mnl_attr_type_valid);
134 int mnl_attr_type_valid(
const struct nlattr *attr, uint16_t max)
136 if (mnl_attr_get_type(attr) > max) {
143 static int __mnl_attr_validate(
const struct nlattr *attr,
144 enum mnl_attr_data_type type,
size_t exp_len)
146 uint16_t attr_len = mnl_attr_get_payload_len(attr);
147 const char *attr_data = mnl_attr_get_payload(attr);
149 if (attr_len < exp_len) {
160 case MNL_TYPE_NUL_STRING:
165 if (attr_data[attr_len-1] !=
'\0') {
170 case MNL_TYPE_STRING:
176 case MNL_TYPE_NESTED:
181 if (attr_len < MNL_ATTR_HDRLEN) {
190 if (exp_len && attr_len > exp_len) {
197 static const size_t mnl_attr_data_type_len[MNL_TYPE_MAX] = {
198 [MNL_TYPE_U8] =
sizeof(uint8_t),
199 [MNL_TYPE_U16] =
sizeof(uint16_t),
200 [MNL_TYPE_U32] =
sizeof(uint32_t),
201 [MNL_TYPE_U64] =
sizeof(uint64_t),
202 [MNL_TYPE_MSECS] =
sizeof(uint64_t),
214 EXPORT_SYMBOL(mnl_attr_validate);
215 int mnl_attr_validate(
const struct nlattr *attr,
enum mnl_attr_data_type type)
219 if (type >= MNL_TYPE_MAX) {
223 exp_len = mnl_attr_data_type_len[type];
224 return __mnl_attr_validate(attr, type, exp_len);
237 EXPORT_SYMBOL(mnl_attr_validate2);
238 int mnl_attr_validate2(
const struct nlattr *attr,
enum mnl_attr_data_type type,
241 if (type >= MNL_TYPE_MAX) {
245 return __mnl_attr_validate(attr, type, exp_len);
263 EXPORT_SYMBOL(mnl_attr_parse);
264 int mnl_attr_parse(
const struct nlmsghdr *nlh,
unsigned int offset,
265 mnl_attr_cb_t cb,
void *data)
268 const struct nlattr *attr;
270 mnl_attr_for_each(attr, nlh, offset)
271 if ((ret = cb(attr, data)) <= MNL_CB_STOP)
290 EXPORT_SYMBOL(mnl_attr_parse_nested);
291 int mnl_attr_parse_nested(const struct nlattr *nested, mnl_attr_cb_t cb,
295 const struct nlattr *attr;
297 mnl_attr_for_each_nested(attr, nested)
298 if ((ret = cb(attr, data)) <= MNL_CB_STOP)
322 EXPORT_SYMBOL(mnl_attr_parse_payload);
323 int mnl_attr_parse_payload(const
void *payload,
size_t payload_len,
324 mnl_attr_cb_t cb,
void *data)
327 const struct nlattr *attr;
329 mnl_attr_for_each_payload(payload, payload_len)
330 if ((ret = cb(attr, data)) <= MNL_CB_STOP)
341 EXPORT_SYMBOL(mnl_attr_get_u8);
342 uint8_t mnl_attr_get_u8(const struct nlattr *attr)
344 return *((uint8_t *)mnl_attr_get_payload(attr));
353 EXPORT_SYMBOL(mnl_attr_get_u16);
354 uint16_t mnl_attr_get_u16(
const struct nlattr *attr)
356 return *((uint16_t *)mnl_attr_get_payload(attr));
365 EXPORT_SYMBOL(mnl_attr_get_u32);
366 uint32_t mnl_attr_get_u32(
const struct nlattr *attr)
368 return *((uint32_t *)mnl_attr_get_payload(attr));
379 EXPORT_SYMBOL(mnl_attr_get_u64);
380 uint64_t mnl_attr_get_u64(
const struct nlattr *attr)
383 memcpy(&tmp, mnl_attr_get_payload(attr),
sizeof(tmp));
393 EXPORT_SYMBOL(mnl_attr_get_str);
394 const char *mnl_attr_get_str(
const struct nlattr *attr)
396 return mnl_attr_get_payload(attr);
409 EXPORT_SYMBOL(mnl_attr_put);
410 void mnl_attr_put(
struct nlmsghdr *nlh, uint16_t type,
size_t len,
413 struct nlattr *attr = mnl_nlmsg_get_payload_tail(nlh);
414 uint16_t payload_len = MNL_ALIGN(
sizeof(
struct nlattr)) + len;
416 attr->nla_type = type;
417 attr->nla_len = payload_len;
418 memcpy(mnl_attr_get_payload(attr), data, len);
419 nlh->nlmsg_len += MNL_ALIGN(payload_len);
431 EXPORT_SYMBOL(mnl_attr_put_u8);
432 void mnl_attr_put_u8(
struct nlmsghdr *nlh, uint16_t type, uint8_t data)
434 mnl_attr_put(nlh, type,
sizeof(uint8_t), &data);
446 EXPORT_SYMBOL(mnl_attr_put_u16);
447 void mnl_attr_put_u16(
struct nlmsghdr *nlh, uint16_t type, uint16_t data)
449 mnl_attr_put(nlh, type,
sizeof(uint16_t), &data);
461 EXPORT_SYMBOL(mnl_attr_put_u32);
462 void mnl_attr_put_u32(
struct nlmsghdr *nlh, uint16_t type, uint32_t data)
464 mnl_attr_put(nlh, type,
sizeof(uint32_t), &data);
476 EXPORT_SYMBOL(mnl_attr_put_u64);
477 void mnl_attr_put_u64(
struct nlmsghdr *nlh, uint16_t type, uint64_t data)
479 mnl_attr_put(nlh, type,
sizeof(uint64_t), &data);
491 EXPORT_SYMBOL(mnl_attr_put_str);
492 void mnl_attr_put_str(
struct nlmsghdr *nlh, uint16_t type,
const char *data)
494 mnl_attr_put(nlh, type, strlen(data), data);
509 EXPORT_SYMBOL(mnl_attr_put_strz);
510 void mnl_attr_put_strz(
struct nlmsghdr *nlh, uint16_t type,
const char *data)
512 mnl_attr_put(nlh, type, strlen(data)+1, data);
524 EXPORT_SYMBOL(mnl_attr_nest_start);
525 struct nlattr *mnl_attr_nest_start(
struct nlmsghdr *nlh, uint16_t type)
527 struct nlattr *start = mnl_nlmsg_get_payload_tail(nlh);
530 start->nla_type = NLA_F_NESTED | type;
531 nlh->nlmsg_len += MNL_ALIGN(
sizeof(
struct nlattr));
550 EXPORT_SYMBOL(mnl_attr_put_check);
551 bool mnl_attr_put_check(
struct nlmsghdr *nlh,
size_t buflen,
552 uint16_t type,
size_t len,
const void *data)
554 if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
556 mnl_attr_put(nlh, type, len, data);
573 EXPORT_SYMBOL(mnl_attr_put_u8_check);
574 bool mnl_attr_put_u8_check(
struct nlmsghdr *nlh,
size_t buflen,
575 uint16_t type, uint8_t data)
577 return mnl_attr_put_check(nlh, buflen, type,
sizeof(uint8_t), &data);
595 EXPORT_SYMBOL(mnl_attr_put_u16_check);
596 bool mnl_attr_put_u16_check(
struct nlmsghdr *nlh,
size_t buflen,
597 uint16_t type, uint16_t data)
599 return mnl_attr_put_check(nlh, buflen, type,
sizeof(uint16_t), &data);
617 EXPORT_SYMBOL(mnl_attr_put_u32_check);
618 bool mnl_attr_put_u32_check(
struct nlmsghdr *nlh,
size_t buflen,
619 uint16_t type, uint32_t data)
621 return mnl_attr_put_check(nlh, buflen, type,
sizeof(uint32_t), &data);
639 EXPORT_SYMBOL(mnl_attr_put_u64_check);
640 bool mnl_attr_put_u64_check(
struct nlmsghdr *nlh,
size_t buflen,
641 uint16_t type, uint64_t data)
643 return mnl_attr_put_check(nlh, buflen, type,
sizeof(uint64_t), &data);
661 EXPORT_SYMBOL(mnl_attr_put_str_check);
662 bool mnl_attr_put_str_check(
struct nlmsghdr *nlh,
size_t buflen,
663 uint16_t type,
const char *data)
665 return mnl_attr_put_check(nlh, buflen, type, strlen(data), data);
684 EXPORT_SYMBOL(mnl_attr_put_strz_check);
685 bool mnl_attr_put_strz_check(
struct nlmsghdr *nlh,
size_t buflen,
686 uint16_t type,
const char *data)
688 return mnl_attr_put_check(nlh, buflen, type, strlen(data)+1, data);
701 EXPORT_SYMBOL(mnl_attr_nest_start_check);
702 struct nlattr *mnl_attr_nest_start_check(
struct nlmsghdr *nlh,
size_t buflen,
705 if (nlh->nlmsg_len + MNL_ATTR_HDRLEN > buflen)
707 return mnl_attr_nest_start(nlh, type);
717 EXPORT_SYMBOL(mnl_attr_nest_end);
718 void mnl_attr_nest_end(
struct nlmsghdr *nlh,
struct nlattr *start)
720 start->nla_len = mnl_nlmsg_get_payload_tail(nlh) - (
void *)start;
730 EXPORT_SYMBOL(mnl_attr_nest_cancel);
731 void mnl_attr_nest_cancel(
struct nlmsghdr *nlh,
struct nlattr *start)
733 nlh->nlmsg_len -= mnl_nlmsg_get_payload_tail(nlh) - (
void *)start;