static void genl_print_ctrl_family(struct nlmsghdr *hdr) { struct genlmsghdr *genl = NLMSG_DATA(hdr); struct nlattr *attr = GEN_NLA(genl); uint32_t attrs_len = NLMSG_PAYLOAD(hdr, sizeof(struct genlmsghdr)); for (; NLA_OK(attr, attrs_len); attr = NLA_NEXT(attr, attrs_len)) { switch (attr->nla_type) { case CTRL_ATTR_FAMILY_ID: nla_fmt(attr, "Family Id 0x%x", NLA_UINT16(attr)); break; case CTRL_ATTR_FAMILY_NAME: nla_fmt(attr, "Family Name %s", NLA_STR(attr)); break; case CTRL_ATTR_VERSION: nla_fmt(attr, "Version %u", NLA_UINT32(attr)); break; case CTRL_ATTR_HDRSIZE: nla_fmt(attr, "Header size %u", NLA_UINT32(attr)); break; case CTRL_ATTR_MAXATTR: nla_fmt(attr, "Max attr value 0x%x", NLA_UINT32(attr)); break; default: nla_fmt(attr, "0x%x", attr->nla_type); break; } } }
static void test_nfacct_dump_callback(unsigned int error, uint16_t type, const void *data, uint32_t len, void *user_data) { const struct nfgenmsg *msg = data; const struct nlattr *attr; uint64_t packets = 0 , bytes = 0; char *name = NULL; int attrlen; if (error == EINVAL) printf("nfnetlink_acct not loaded\n"); g_assert_cmpuint(error, ==, 0); attrlen = len - NLMSG_ALIGN(sizeof(struct nfgenmsg)); for (attr = NFGEN_DATA(msg); NLA_OK(attr, attrlen); attr = NLA_NEXT(attr, attrlen)) { switch (attr->nla_type) { case NFACCT_NAME: name = NLA_DATA(attr); break; case NFACCT_PKTS: packets = be64toh(*(uint64_t *) NLA_DATA(attr)); break; case NFACCT_BYTES: bytes = be64toh(*(uint64_t *) NLA_DATA(attr)); break; case NFACCT_USE: break; } } printf("%s packets %" PRIu64 " bytes %" PRIu64 "\n", name, packets, bytes); g_main_loop_quit(mainloop); }