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)