15#include <libmnl/libmnl.h>
56 return len + MNL_NLMSG_HDRLEN;
68 return nlh->nlmsg_len - MNL_NLMSG_HDRLEN;
82 int len = MNL_ALIGN(
sizeof(
struct nlmsghdr));
83 struct nlmsghdr *nlh = buf;
104 char *ptr = (
char *)nlh + nlh->nlmsg_len;
105 size_t len = MNL_ALIGN(size);
106 nlh->nlmsg_len += len;
119 return (
void *)nlh + MNL_NLMSG_HDRLEN;
133 return (
void *)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
154 return len >= (int)
sizeof(
struct nlmsghdr) &&
155 nlh->nlmsg_len >=
sizeof(
struct nlmsghdr) &&
156 (int)nlh->nlmsg_len <= len;
175 *len -= MNL_ALIGN(nlh->nlmsg_len);
176 return (
struct nlmsghdr *)((
void *)nlh + MNL_ALIGN(nlh->nlmsg_len));
189 return (
void *)nlh + MNL_ALIGN(nlh->nlmsg_len);
209 return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq :
true;
229 return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid :
true;
232static void mnl_nlmsg_fprintf_header(FILE *fd,
const struct nlmsghdr *nlh)
234 fprintf(fd,
"----------------\t------------------\n");
235 fprintf(fd,
"| %.010u |\t| message length |\n", nlh->nlmsg_len);
236 fprintf(fd,
"| %.05u | %c%c%c%c |\t| type | flags |\n",
238 nlh->nlmsg_flags & NLM_F_REQUEST ?
'R' :
'-',
239 nlh->nlmsg_flags & NLM_F_MULTI ?
'M' :
'-',
240 nlh->nlmsg_flags & NLM_F_ACK ?
'A' :
'-',
241 nlh->nlmsg_flags & NLM_F_ECHO ?
'E' :
'-');
242 fprintf(fd,
"| %.010u |\t| sequence number|\n", nlh->nlmsg_seq);
243 fprintf(fd,
"| %.010u |\t| port ID |\n", nlh->nlmsg_pid);
244 fprintf(fd,
"----------------\t------------------\n");
247static void mnl_nlmsg_fprintf_payload(FILE *fd,
const struct nlmsghdr *nlh,
248 size_t extra_header_size)
253 for (i=
sizeof(
struct nlmsghdr); i<nlh->nlmsg_len; i+=4) {
254 char *b = (
char *) nlh;
255 struct nlattr *attr = (
struct nlattr *) (b+i);
258 if (nlh->nlmsg_type < NLMSG_MIN_TYPE) {
259 fprintf(fd,
"| %.2x %.2x %.2x %.2x |\t",
260 0xff & b[i], 0xff & b[i+1],
261 0xff & b[i+2], 0xff & b[i+3]);
262 fprintf(fd,
"| |\n");
264 }
else if (extra_header_size > 0) {
265 extra_header_size -= 4;
266 fprintf(fd,
"| %.2x %.2x %.2x %.2x |\t",
267 0xff & b[i], 0xff & b[i+1],
268 0xff & b[i+2], 0xff & b[i+3]);
269 fprintf(fd,
"| extra header |\n");
271 }
else if (rem == 0 && (attr->nla_type & NLA_TYPE_MASK) != 0) {
272 fprintf(fd,
"|%c[%d;%dm"
287 attr->nla_type & NLA_F_NESTED ?
'N' :
'-',
289 NLA_F_NET_BYTEORDER ?
'B' :
'-',
292 attr->nla_type & NLA_TYPE_MASK,
294 fprintf(fd,
"|len |flags| type|\n");
296 if (!(attr->nla_type & NLA_F_NESTED)) {
297 rem = NLA_ALIGN(attr->nla_len) -
298 sizeof(
struct nlattr);
301 }
else if (rem > 0) {
303 fprintf(fd,
"| %.2x %.2x %.2x %.2x |\t",
304 0xff & b[i], 0xff & b[i+1],
305 0xff & b[i+2], 0xff & b[i+3]);
306 fprintf(fd,
"| data |");
307 fprintf(fd,
"\t %c %c %c %c\n",
308 isprint(b[i]) ? b[i] :
' ',
309 isprint(b[i+1]) ? b[i+1] :
' ',
310 isprint(b[i+2]) ? b[i+2] :
' ',
311 isprint(b[i+3]) ? b[i+3] :
' ');
314 fprintf(fd,
"----------------\t------------------\n");
361 size_t extra_header_size)
363 const struct nlmsghdr *nlh = data;
367 mnl_nlmsg_fprintf_header(fd, nlh);
368 mnl_nlmsg_fprintf_payload(fd, nlh, extra_header_size);
411struct mnl_nlmsg_batch {
437 struct mnl_nlmsg_batch *b;
439 b = malloc(
sizeof(
struct mnl_nlmsg_batch));
476 struct nlmsghdr *nlh = b->cur;
478 if (b->buflen + nlh->nlmsg_len > b->limit) {
482 b->cur = b->buf + b->buflen + nlh->nlmsg_len;
483 b->buflen += nlh->nlmsg_len;
498 struct nlmsghdr *nlh = b->cur;
499 memcpy(b->buf, b->cur, nlh->nlmsg_len);
500 b->buflen = nlh->nlmsg_len;
501 b->cur = b->buf + b->buflen;
552 return b->buflen == 0;
void * mnl_nlmsg_batch_current(struct mnl_nlmsg_batch *b)
bool mnl_nlmsg_batch_next(struct mnl_nlmsg_batch *b)
size_t mnl_nlmsg_batch_size(struct mnl_nlmsg_batch *b)
void * mnl_nlmsg_batch_head(struct mnl_nlmsg_batch *b)
void mnl_nlmsg_batch_reset(struct mnl_nlmsg_batch *b)
struct mnl_nlmsg_batch * mnl_nlmsg_batch_start(void *buf, size_t limit)
bool mnl_nlmsg_batch_is_empty(struct mnl_nlmsg_batch *b)
void mnl_nlmsg_batch_stop(struct mnl_nlmsg_batch *b)
void * mnl_nlmsg_get_payload_offset(const struct nlmsghdr *nlh, size_t offset)
size_t mnl_nlmsg_size(size_t len)
bool mnl_nlmsg_seq_ok(const struct nlmsghdr *nlh, unsigned int seq)
void * mnl_nlmsg_get_payload(const struct nlmsghdr *nlh)
struct nlmsghdr * mnl_nlmsg_next(const struct nlmsghdr *nlh, int *len)
struct nlmsghdr * mnl_nlmsg_put_header(void *buf)
void mnl_nlmsg_fprintf(FILE *fd, const void *data, size_t datalen, size_t extra_header_size)
bool mnl_nlmsg_ok(const struct nlmsghdr *nlh, int len)
void * mnl_nlmsg_put_extra_header(struct nlmsghdr *nlh, size_t size)
size_t mnl_nlmsg_get_payload_len(const struct nlmsghdr *nlh)
bool mnl_nlmsg_portid_ok(const struct nlmsghdr *nlh, unsigned int portid)
void * mnl_nlmsg_get_payload_tail(const struct nlmsghdr *nlh)