13 #include <sys/socket.h>
14 #include <linux/netlink.h>
24 #define MNL_SOCKET_AUTOPID 0
25 #define MNL_SOCKET_BUFFER_SIZE (getpagesize() < 8192L ? getpagesize() : 8192L)
44 #define MNL_ALIGN(len) (((len)+MNL_ALIGNTO-1) & ~(MNL_ALIGNTO-1))
45 #define MNL_NLMSG_HDRLEN MNL_ALIGN(sizeof(struct nlmsghdr))
55 extern bool mnl_nlmsg_ok(
const struct nlmsghdr *nlh,
int len);
56 extern struct nlmsghdr *
mnl_nlmsg_next(
const struct nlmsghdr *nlh,
int *len);
70 extern void mnl_nlmsg_fprintf(FILE *fd,
const void *data,
size_t datalen,
size_t extra_header_size);
86 #define MNL_ATTR_HDRLEN MNL_ALIGN(sizeof(struct nlattr))
100 extern void mnl_attr_put(
struct nlmsghdr *nlh, uint16_t type,
size_t len,
const void *data);
101 extern void mnl_attr_put_u8(
struct nlmsghdr *nlh, uint16_t type, uint8_t data);
102 extern void mnl_attr_put_u16(
struct nlmsghdr *nlh, uint16_t type, uint16_t data);
103 extern void mnl_attr_put_u32(
struct nlmsghdr *nlh, uint16_t type, uint32_t data);
104 extern void mnl_attr_put_u64(
struct nlmsghdr *nlh, uint16_t type, uint64_t data);
105 extern void mnl_attr_put_str(
struct nlmsghdr *nlh, uint16_t type,
const char *data);
106 extern void mnl_attr_put_strz(
struct nlmsghdr *nlh, uint16_t type,
const char *data);
109 extern bool mnl_attr_put_check(
struct nlmsghdr *nlh,
size_t buflen, uint16_t type,
size_t len,
const void *data);
126 enum mnl_attr_data_type {
136 MNL_TYPE_NESTED_COMPAT,
142 extern int mnl_attr_validate(
const struct nlattr *attr,
enum mnl_attr_data_type type);
143 extern int mnl_attr_validate2(
const struct nlattr *attr,
enum mnl_attr_data_type type,
size_t len);
146 extern bool mnl_attr_ok(
const struct nlattr *attr,
int len);
147 extern struct nlattr *
mnl_attr_next(
const struct nlattr *attr);
149 #define mnl_attr_for_each(attr, nlh, offset) \
150 for ((attr) = mnl_nlmsg_get_payload_offset((nlh), (offset)); \
151 mnl_attr_ok((attr), (char *)mnl_nlmsg_get_payload_tail(nlh) - (char *)(attr)); \
152 (attr) = mnl_attr_next(attr))
154 #define mnl_attr_for_each_nested(attr, nest) \
155 for ((attr) = mnl_attr_get_payload(nest); \
156 mnl_attr_ok((attr), (char *)mnl_attr_get_payload(nest) + mnl_attr_get_payload_len(nest) - (char *)(attr)); \
157 (attr) = mnl_attr_next(attr))
159 #define mnl_attr_for_each_payload(payload, payload_size) \
160 for ((attr) = (payload); \
161 mnl_attr_ok((attr), (char *)(payload) + payload_size - (char *)(attr)); \
162 (attr) = mnl_attr_next(attr))
165 typedef int (*mnl_attr_cb_t)(
const struct nlattr *attr,
void *data);
167 extern int mnl_attr_parse(
const struct nlmsghdr *nlh,
unsigned int offset, mnl_attr_cb_t cb,
void *data);
174 #define MNL_CB_ERROR -1
175 #define MNL_CB_STOP 0
178 typedef int (*mnl_cb_t)(
const struct nlmsghdr *nlh,
void *data);
180 extern int mnl_cb_run(
const void *buf,
size_t numbytes,
unsigned int seq,
181 unsigned int portid, mnl_cb_t cb_data,
void *data);
183 extern int mnl_cb_run2(
const void *buf,
size_t numbytes,
unsigned int seq,
184 unsigned int portid, mnl_cb_t cb_data,
void *data,
185 mnl_cb_t *cb_ctl_array,
unsigned int cb_ctl_array_len);
192 #define SOL_NETLINK 270
195 #ifndef MNL_ARRAY_SIZE
196 #define MNL_ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0]))
bool mnl_attr_ok(const struct nlattr *attr, int len)
int mnl_attr_validate2(const struct nlattr *attr, enum mnl_attr_data_type type, size_t len)
size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b)
int mnl_attr_parse(const struct nlmsghdr *nlh, unsigned int offset, mnl_attr_cb_t cb, void *data)
void * mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
uint16_t mnl_attr_get_type(const struct nlattr *attr)
struct mnl_socket * mnl_socket_open(int type)
bool mnl_attr_put_strz_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data)
bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b)
unsigned int mnl_socket_get_portid(const struct mnl_socket *nl)
struct nlattr * mnl_attr_next(const struct nlattr *attr)
bool mnl_attr_put_u16_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint16_t data)
void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size)
void mnl_attr_nest_end(struct nlmsghdr *nlh, struct nlattr *start)
void * mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b)
struct nlmsghdr * mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len)
ssize_t mnl_socket_recvfrom(const struct mnl_socket *nl, void *buf, size_t siz)
void mnl_attr_put(struct nlmsghdr *nlh, uint16_t type, size_t len, const void *data)
void * mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b)
void * mnl_attr_get_payload(const struct nlattr *attr)
uint16_t mnl_attr_get_u16(const struct nlattr *attr)
size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh)
int mnl_cb_run(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data)
uint16_t mnl_attr_get_len(const struct nlattr *attr)
int mnl_attr_parse_nested(const struct nlattr *attr, mnl_attr_cb_t cb, void *data)
int mnl_socket_bind(struct mnl_socket *nl, unsigned int groups, pid_t pid)
int mnl_socket_close(struct mnl_socket *nl)
bool mnl_attr_put_str_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, const char *data)
void mnl_attr_put_u8(struct nlmsghdr *nlh, uint16_t type, uint8_t data)
struct mnl_nlmsg_batch * mnl_nlmsg_batch_start(void *buf, size_t bufsiz)
bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
uint16_t mnl_attr_get_payload_len(const struct nlattr *attr)
bool mnl_attr_put_u8_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint8_t data)
void * mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)
int mnl_socket_getsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t *len)
bool mnl_attr_put_u32_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint32_t data)
bool mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, size_t len, const void *data)
int mnl_attr_type_valid(const struct nlattr *attr, uint16_t maxtype)
void mnl_attr_nest_cancel(struct nlmsghdr *nlh, struct nlattr *start)
struct nlmsghdr * mnl_nlmsg_put_header(void *buf)
uint8_t mnl_attr_get_u8(const struct nlattr *attr)
bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid)
int mnl_attr_parse_payload(const void *payload, size_t payload_len, mnl_attr_cb_t cb, void *data)
void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
uint64_t mnl_attr_get_u64(const struct nlattr *attr)
ssize_t mnl_socket_sendto(const struct mnl_socket *nl, const void *req, size_t siz)
int mnl_socket_get_fd(const struct mnl_socket *nl)
bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b)
int mnl_cb_run2(const void *buf, size_t numbytes, unsigned int seq, unsigned int portid, mnl_cb_t cb_data, void *data, mnl_cb_t *cb_ctl_array, unsigned int cb_ctl_array_len)
void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data)
void * mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset)
int mnl_socket_setsockopt(const struct mnl_socket *nl, int type, void *buf, socklen_t len)
const char * mnl_attr_get_str(const struct nlattr *attr)
struct nlattr * mnl_attr_nest_start_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type)
size_t mnl_nlmsg_size(size_t len)
void mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data)
struct nlattr * mnl_attr_nest_start(struct nlmsghdr *nlh, uint16_t type)
bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq)
uint32_t mnl_attr_get_u32(const struct nlattr *attr)
int mnl_attr_validate(const struct nlattr *attr, enum mnl_attr_data_type type)
void * mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
bool mnl_attr_put_u64_check(struct nlmsghdr *nlh, size_t buflen, uint16_t type, uint64_t data)
void mnl_attr_put_u16(struct nlmsghdr *nlh, uint16_t type, uint16_t data)
void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
void mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data)