15 #include <libmnl/libmnl.h>
54 EXPORT_SYMBOL(mnl_nlmsg_size);
55 size_t mnl_nlmsg_size(
size_t len)
57 return len + MNL_NLMSG_HDRLEN;
67 EXPORT_SYMBOL(mnl_nlmsg_get_payload_len);
68 size_t mnl_nlmsg_get_payload_len(
const struct nlmsghdr *nlh)
70 return nlh->nlmsg_len - MNL_NLMSG_HDRLEN;
82 EXPORT_SYMBOL(mnl_nlmsg_put_header);
83 struct nlmsghdr *mnl_nlmsg_put_header(
void *buf)
85 int len = MNL_ALIGN(
sizeof(
struct nlmsghdr));
86 struct nlmsghdr *nlh = buf;
104 EXPORT_SYMBOL(mnl_nlmsg_put_extra_header);
105 void *mnl_nlmsg_put_extra_header(
struct nlmsghdr *nlh,
size_t size)
107 char *ptr = (
char *)nlh + nlh->nlmsg_len;
108 size_t len = MNL_ALIGN(size);
109 nlh->nlmsg_len += len;
120 EXPORT_SYMBOL(mnl_nlmsg_get_payload);
121 void *mnl_nlmsg_get_payload(
const struct nlmsghdr *nlh)
123 return (
void *)nlh + MNL_NLMSG_HDRLEN;
134 EXPORT_SYMBOL(mnl_nlmsg_get_payload_offset);
135 void *mnl_nlmsg_get_payload_offset(
const struct nlmsghdr *nlh,
size_t offset)
137 return (
void *)nlh + MNL_NLMSG_HDRLEN + MNL_ALIGN(offset);
156 EXPORT_SYMBOL(mnl_nlmsg_ok);
157 bool mnl_nlmsg_ok(
const struct nlmsghdr *nlh,
int len)
159 return len >= (int)
sizeof(
struct nlmsghdr) &&
160 nlh->nlmsg_len >=
sizeof(
struct nlmsghdr) &&
161 (int)nlh->nlmsg_len <= len;
177 EXPORT_SYMBOL(mnl_nlmsg_next);
178 struct nlmsghdr *mnl_nlmsg_next(
const struct nlmsghdr *nlh,
int *len)
180 *len -= MNL_ALIGN(nlh->nlmsg_len);
181 return (
struct nlmsghdr *)((
void *)nlh + MNL_ALIGN(nlh->nlmsg_len));
192 EXPORT_SYMBOL(mnl_nlmsg_get_payload_tail);
193 void *mnl_nlmsg_get_payload_tail(
const struct nlmsghdr *nlh)
195 return (
void *)nlh + MNL_ALIGN(nlh->nlmsg_len);
212 EXPORT_SYMBOL(mnl_nlmsg_seq_ok);
213 bool mnl_nlmsg_seq_ok(
const struct nlmsghdr *nlh,
unsigned int seq)
215 return nlh->nlmsg_seq && seq ? nlh->nlmsg_seq == seq :
true;
232 EXPORT_SYMBOL(mnl_nlmsg_portid_ok);
233 bool mnl_nlmsg_portid_ok(
const struct nlmsghdr *nlh,
unsigned int portid)
235 return nlh->nlmsg_pid && portid ? nlh->nlmsg_pid == portid :
true;
238 static void mnl_nlmsg_fprintf_header(FILE *fd,
const struct nlmsghdr *nlh)
240 fprintf(fd,
"----------------\t------------------\n");
241 fprintf(fd,
"| %.010u |\t| message length |\n", nlh->nlmsg_len);
242 fprintf(fd,
"| %.05u | %c%c%c%c |\t| type | flags |\n",
244 nlh->nlmsg_flags & NLM_F_REQUEST ?
'R' :
'-',
245 nlh->nlmsg_flags & NLM_F_MULTI ?
'M' :
'-',
246 nlh->nlmsg_flags & NLM_F_ACK ?
'A' :
'-',
247 nlh->nlmsg_flags & NLM_F_ECHO ?
'E' :
'-');
248 fprintf(fd,
"| %.010u |\t| sequence number|\n", nlh->nlmsg_seq);
249 fprintf(fd,
"| %.010u |\t| port ID |\n", nlh->nlmsg_pid);
250 fprintf(fd,
"----------------\t------------------\n");
253 static void mnl_nlmsg_fprintf_payload(FILE *fd,
const struct nlmsghdr *nlh,
254 size_t extra_header_size)
259 for (i=
sizeof(
struct nlmsghdr); i<nlh->nlmsg_len; i+=4) {
260 char *b = (
char *) nlh;
261 struct nlattr *attr = (
struct nlattr *) (b+i);
264 if (nlh->nlmsg_type < NLMSG_MIN_TYPE) {
265 fprintf(fd,
"| %.2x %.2x %.2x %.2x |\t",
266 0xff & b[i], 0xff & b[i+1],
267 0xff & b[i+2], 0xff & b[i+3]);
268 fprintf(fd,
"| |\n");
270 }
else if (extra_header_size > 0) {
271 extra_header_size -= 4;
272 fprintf(fd,
"| %.2x %.2x %.2x %.2x |\t",
273 0xff & b[i], 0xff & b[i+1],
274 0xff & b[i+2], 0xff & b[i+3]);
275 fprintf(fd,
"| extra header |\n");
277 }
else if (rem == 0 && (attr->nla_type & NLA_TYPE_MASK) != 0) {
278 fprintf(fd,
"|%c[%d;%dm"
293 attr->nla_type & NLA_F_NESTED ?
'N' :
'-',
295 NLA_F_NET_BYTEORDER ?
'B' :
'-',
298 attr->nla_type & NLA_TYPE_MASK,
300 fprintf(fd,
"|len |flags| type|\n");
302 if (!(attr->nla_type & NLA_F_NESTED)) {
303 rem = NLA_ALIGN(attr->nla_len) -
304 sizeof(
struct nlattr);
307 }
else if (rem > 0) {
309 fprintf(fd,
"| %.2x %.2x %.2x %.2x |\t",
310 0xff & b[i], 0xff & b[i+1],
311 0xff & b[i+2], 0xff & b[i+3]);
312 fprintf(fd,
"| data |");
313 fprintf(fd,
"\t %c %c %c %c\n",
314 isprint(b[i]) ? b[i] :
' ',
315 isprint(b[i+1]) ? b[i+1] :
' ',
316 isprint(b[i+2]) ? b[i+2] :
' ',
317 isprint(b[i+3]) ? b[i+3] :
' ');
320 fprintf(fd,
"----------------\t------------------\n");
366 EXPORT_SYMBOL(mnl_nlmsg_fprintf);
367 void mnl_nlmsg_fprintf(FILE *fd,
const void *data,
size_t datalen,
368 size_t extra_header_size)
370 const struct nlmsghdr *nlh = data;
373 while (mnl_nlmsg_ok(nlh, len)) {
374 mnl_nlmsg_fprintf_header(fd, nlh);
375 mnl_nlmsg_fprintf_payload(fd, nlh, extra_header_size);
376 nlh = mnl_nlmsg_next(nlh, &len);
436 EXPORT_SYMBOL(mnl_nlmsg_batch_start);
460 EXPORT_SYMBOL(mnl_nlmsg_batch_stop);
477 EXPORT_SYMBOL(mnl_nlmsg_batch_next);
480 struct nlmsghdr *nlh = b->cur;
482 if (b->buflen + nlh->nlmsg_len > b->limit) {
486 b->cur = b->buf + b->buflen + nlh->nlmsg_len;
487 b->buflen += nlh->nlmsg_len;
499 EXPORT_SYMBOL(mnl_nlmsg_batch_reset);
503 struct nlmsghdr *nlh = b->cur;
504 memcpy(b->buf, b->cur, nlh->nlmsg_len);
505 b->buflen = nlh->nlmsg_len;
506 b->cur = b->buf + b->buflen;
520 EXPORT_SYMBOL(mnl_nlmsg_batch_size);
533 EXPORT_SYMBOL(mnl_nlmsg_batch_head);
546 EXPORT_SYMBOL(mnl_nlmsg_batch_current);
558 EXPORT_SYMBOL(mnl_nlmsg_batch_is_empty);
561 return b->buflen == 0;