#include <sys/param.h>
#include <netlink/netlink.h>
#include <stdio.h>
#include <stdbool.h>
#include <stddef.h>
#include "sysdecode.h"
bool
sysdecode_netlink(FILE *fp, const void *buf, size_t len)
{
const struct nlmsghdr *nl = buf;
size_t remaining = len;
bool first = true;
if (remaining < sizeof(struct nlmsghdr))
return (false);
if (nl->nlmsg_len < sizeof(struct nlmsghdr) || nl->nlmsg_len > remaining)
return (false);
fprintf(fp, "netlink{");
while (remaining >= sizeof(struct nlmsghdr)) {
if (!first)
fprintf(fp, ",");
if (nl->nlmsg_len < sizeof(struct nlmsghdr) ||
nl->nlmsg_len > remaining) {
fprintf(fp, "<truncated>");
break;
}
fprintf(fp, "len=%u,type=", nl->nlmsg_len);
switch (nl->nlmsg_type) {
case NLMSG_NOOP:
fprintf(fp, "NLMSG_NOOP");
break;
case NLMSG_ERROR:
fprintf(fp, "NLMSG_ERROR");
break;
case NLMSG_DONE:
fprintf(fp, "NLMSG_DONE");
break;
case NLMSG_OVERRUN:
fprintf(fp, "NLMSG_OVERRUN");
break;
default:
fprintf(fp, "%u", nl->nlmsg_type);
break;
}
fprintf(fp, ",flags=");
fprintf(fp, "0x%x", nl->nlmsg_flags);
fprintf(fp, ",seq=%u,pid=%u", nl->nlmsg_seq, nl->nlmsg_pid);
size_t aligned_len = NLMSG_ALIGN(nl->nlmsg_len);
if (aligned_len > remaining)
remaining = 0;
else
remaining -= aligned_len;
nl = (const struct nlmsghdr *)(const void *)((const char *)nl + aligned_len);
first = false;
}
fprintf(fp, "}");
return (true);
}