#include <stdlib.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include <libmnl/libmnl.h>
#define EXPORT_SYMBOL(x)
EXPORT_SYMBOL(mnl_nlmsg_put_header_check);
struct nlmsghdr *mnl_nlmsg_put_header_check(void *buf, size_t buflen)
{
if (buflen < MNL_NLMSG_HDRLEN) {
errno = EINVAL;
return NULL;
}
return mnl_nlmsg_put_header(buf);
}
EXPORT_SYMBOL(mnl_nlmsg_put_extra_header_check);
void *mnl_nlmsg_put_extra_header_check(struct nlmsghdr *nlh, size_t buflen, size_t size)
{
if (nlh->nlmsg_len + MNL_ALIGN(size) > buflen) {
errno = EINVAL;
return NULL;
}
return mnl_nlmsg_put_extra_header(nlh, size);
}
struct mnl_nlmsg_batch {
void *buf;
size_t limit;
size_t buflen;
void *cur;
bool overflow;
};
EXPORT_SYMBOL(mnl_nlmsg_batch_rest);
size_t mnl_nlmsg_batch_rest(const struct mnl_nlmsg_batch *b)
{
return b->limit - b->buflen;
}
struct nlmsghdr *rsmnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
{
struct nlmsghdr *nlh = b->cur;
if (b->buflen + nlh->nlmsg_len + MNL_NLMSG_HDRLEN > b->limit)
return NULL;
b->cur = b->buf + b->buflen + nlh->nlmsg_len;
b->buflen += nlh->nlmsg_len;
return (struct nlmsghdr *)b->cur;
}
struct mnl_nlmsg_batch *rsmnl_nlmsg_batch_start(void *buf, size_t limit)
{
struct mnl_nlmsg_batch *b;
b = malloc(sizeof(struct mnl_nlmsg_batch));
if (b == NULL)
return NULL;
b->buf = buf;
b->limit = limit;
b->buflen = 0;
b->cur = buf;
b->overflow = false;
memset(b->buf, 0, b->limit);
return b;
}
struct nlmsghdr *rsmnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
{
if (b->overflow) {
struct nlmsghdr *nlh = b->cur;
memcpy(b->buf, b->cur, nlh->nlmsg_len);
b->buflen = nlh->nlmsg_len;
b->cur = b->buf + b->buflen;
b->overflow = false;
memset(b->buf + b->buflen, 0, b->limit - b->buflen);
} else {
b->buflen = 0;
b->cur = b->buf;
memset(b->buf, 0, b->limit);
}
}
bool rsmnl_nlmsg_batch_cap(struct mnl_nlmsg_batch *b)
{
struct nlmsghdr *nlh = b->cur;
if (b->buflen + nlh->nlmsg_len > b->limit)
return;
b->cur = b->buf + b->buflen + nlh->nlmsg_len;
b->buflen += nlh->nlmsg_len;
}
void rsmnl_nlmsg_batch_put_back(struct mnl_nlmsg_batch *b)
{
struct nlmsghdr *nlh = b->cur;
nlh->nlmsg_len = 0;
}