static int node_list_cb(const struct nlmsghdr *nlh, void *data) { uint32_t addr; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_NODE]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_NODE], parse_attrs, attrs); if (!attrs[TIPC_NLA_NODE_ADDR]) return MNL_CB_ERROR; addr = mnl_attr_get_u32(attrs[TIPC_NLA_NODE_ADDR]); printf("<%u.%u.%u>: ", tipc_zone(addr), tipc_cluster(addr), tipc_node(addr)); if (attrs[TIPC_NLA_NODE_UP]) printf("up\n"); else printf("down\n"); return MNL_CB_OK; }
static int link_mon_summary_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); open_json_object(NULL); print_string(PRINT_ANY, "bearer", "\nbearer %s\n", mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME])); print_uint(PRINT_ANY, "table_generation", " table_generation %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_LISTGEN])); print_uint(PRINT_ANY, "cluster_size", " cluster_size %u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT])); print_string(PRINT_ANY, "algorithm", " algorithm %s\n", attrs[TIPC_NLA_MON_ACTIVE] ? "overlapping-ring" : "full-mesh"); close_json_object(); return MNL_CB_OK; }
static int res_no_args_parse_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; struct rd *rd = data; const char *name; uint32_t idx; mnl_attr_parse(nlh, 0, rd_attr_cb, tb); if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_RES_SUMMARY]) return MNL_CB_ERROR; idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); if (rd->json_output) { jsonw_uint_field(rd->jw, "ifindex", idx); jsonw_string_field(rd->jw, "ifname", name); } else { pr_out("%u: %s: ", idx, name); } res_print_summary(rd, tb); if (!rd->json_output) pr_out("\n"); return MNL_CB_OK; }
static int data_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[CTA_MAX+1] = {}; struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*nfg), data_attr_cb, tb); if (tb[CTA_TUPLE_ORIG]) print_tuple(tb[CTA_TUPLE_ORIG]); if (tb[CTA_MARK]) printf("mark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_MARK]))); if (tb[CTA_SECMARK]) printf("secmark=%u ", ntohl(mnl_attr_get_u32(tb[CTA_SECMARK]))); if (tb[CTA_COUNTERS_ORIG]) { printf("original "); print_counters(tb[CTA_COUNTERS_ORIG]); } if (tb[CTA_COUNTERS_REPLY]) { printf("reply "); print_counters(tb[CTA_COUNTERS_REPLY]); } printf("\n"); return MNL_CB_OK; }
static int link_mon_list_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {}; char *req_bearer = data; const char *bname; const char title[] = "node status monitored generation applied_node_status [non_applied_node:status]"; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); bname = mnl_attr_get_str(attrs[TIPC_NLA_MON_BEARER_NAME]); if (*req_bearer && (strcmp(req_bearer, bname) != 0)) return MNL_CB_OK; open_json_object(NULL); print_string(PRINT_ANY, "bearer", "\nbearer %s\n", bname); print_string(PRINT_FP, NULL, "%s\n", title); open_json_array(PRINT_JSON, bname); if (mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEERCNT])) link_mon_peer_list(mnl_attr_get_u32(attrs[TIPC_NLA_MON_REF])); close_json_array(PRINT_JSON, bname); close_json_object(); return MNL_CB_OK; }
static int link_stat_show_cb(const struct nlmsghdr *nlh, void *data) { const char *name; const char *link = data; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; struct nlattr *prop[TIPC_NLA_PROP_MAX + 1] = {}; struct nlattr *stats[TIPC_NLA_STATS_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_LINK]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); if (!attrs[TIPC_NLA_LINK_NAME] || !attrs[TIPC_NLA_LINK_PROP] || !attrs[TIPC_NLA_LINK_STATS]) return MNL_CB_ERROR; mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, prop); mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_STATS], parse_attrs, stats); name = mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]); /* If a link is passed, skip all but that link */ if (link && (strcmp(name, link) != 0)) return MNL_CB_OK; if (attrs[TIPC_NLA_LINK_BROADCAST]) { return _show_bc_link_stat(name, prop, stats); } return _show_link_stat(name, attrs, prop, stats); }
int res_pd_parse_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; struct nlattr *nla_table, *nla_entry; struct rd *rd = data; int ret = MNL_CB_OK; const char *name; uint32_t idx; mnl_attr_parse(nlh, 0, rd_attr_cb, tb); if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME] || !tb[RDMA_NLDEV_ATTR_RES_PD]) return MNL_CB_ERROR; name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); nla_table = tb[RDMA_NLDEV_ATTR_RES_PD]; mnl_attr_for_each_nested(nla_entry, nla_table) { struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; ret = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); if (ret != MNL_CB_OK) break; ret = res_pd_line(rd, name, idx, nla_line); if (ret != MNL_CB_OK) break; } return ret; }
//Function which parses the netlink message (*ADDR) we have received and extract //relevant information, which is parsed to OS-independent //neat_addr_update_src_list static void neat_linux_handle_addr(struct neat_ctx *nc, struct nlmsghdr *nl_hdr) { struct ifaddrmsg *ifm = (struct ifaddrmsg*) mnl_nlmsg_get_payload(nl_hdr); const struct nlattr *attr_table[IFA_MAX+1]; //IFA_MAX is the largest index I can store in my array. Since arrays are //zero-indexed, this is IFA_MAX and not IFA_MAX + 1. However, array has to //be of size IFA_MAX + 1. DOH! struct nlattr_storage tb_storage = {attr_table, IFA_MAX}; struct sockaddr_storage src_addr; struct sockaddr_in *src_addr4; struct sockaddr_in6 *src_addr6; struct ifa_cacheinfo *ci; uint32_t *addr6_ptr, ifa_pref = 0, ifa_valid = 0; uint8_t i; //On Linux, lo has a fixed index. We have no interest in that interface //TODO: Consider other filters - bridges, ifb, ... if (ifm->ifa_index == LO_DEV_IDX) return; if (ifm->ifa_scope == RT_SCOPE_LINK) return; memset(attr_table, 0, sizeof(attr_table)); memset(&src_addr, 0, sizeof(src_addr)); if (mnl_attr_parse(nl_hdr, sizeof(struct ifaddrmsg), neat_linux_parse_nlattr, &tb_storage) != MNL_CB_OK) { fprintf(stderr, "Failed to parse nlattr for msg of type %d\n", nl_hdr->nlmsg_type); return; } //v4 and v6 has to be handled differently, both due to address size and //available information if (ifm->ifa_family == AF_INET) { src_addr4 = (struct sockaddr_in*) &src_addr; src_addr4->sin_family = AF_INET; src_addr4->sin_addr.s_addr = mnl_attr_get_u32(attr_table[IFA_LOCAL]); } else { src_addr6 = (struct sockaddr_in6*) &src_addr; src_addr6->sin6_family = AF_INET6; addr6_ptr = (uint32_t*) mnl_attr_get_payload(attr_table[IFA_ADDRESS]); for (i=0; i<4; i++) src_addr6->sin6_addr.s6_addr32[i] = *(addr6_ptr + i); ci = (struct ifa_cacheinfo*) mnl_attr_get_payload(attr_table[IFA_CACHEINFO]); ifa_pref = ci->ifa_prefered; ifa_valid = ci->ifa_valid; } //TODO: Should this function be a callback instead? Will we have multiple //addresses handlers/types of context? neat_addr_update_src_list(nc, &src_addr, ifm->ifa_index, nl_hdr->nlmsg_type == RTM_NEWADDR, ifa_pref, ifa_valid); }
static int data_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr **tb = (struct nlattr **)data; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*genl), parse_attr_cb, tb); return MNL_CB_OK; }
static int link_mon_peer_list_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *attrs[TIPC_NLA_MON_PEER_MAX + 1] = {}; struct nlattr *info[TIPC_NLA_MAX + 1] = {}; uint16_t member_cnt; uint32_t applied; uint32_t dom_gen; uint64_t up_map; char status[16]; char monitored[16]; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON_PEER]) return MNL_CB_ERROR; open_json_object(NULL); mnl_attr_parse_nested(info[TIPC_NLA_MON_PEER], parse_attrs, attrs); (attrs[TIPC_NLA_MON_PEER_LOCAL] || attrs[TIPC_NLA_MON_PEER_HEAD]) ? strcpy(monitored, "direct") : strcpy(monitored, "indirect"); attrs[TIPC_NLA_MON_PEER_UP] ? strcpy(status, "up") : strcpy(status, "down"); dom_gen = attrs[TIPC_NLA_MON_PEER_DOMGEN] ? mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_DOMGEN]) : 0; link_mon_print_peer_state(mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_ADDR]), status, monitored, dom_gen); applied = mnl_attr_get_u32(attrs[TIPC_NLA_MON_PEER_APPLIED]); if (!applied) goto exit; up_map = mnl_attr_get_u64(attrs[TIPC_NLA_MON_PEER_UPMAP]); member_cnt = mnl_attr_get_payload_len(attrs[TIPC_NLA_MON_PEER_MEMBERS]); /* each tipc address occupies 4 bytes of payload, hence compensate it */ member_cnt /= sizeof(uint32_t); link_mon_print_applied(applied, up_map); link_mon_print_non_applied(applied, member_cnt, up_map, mnl_attr_get_payload(attrs[TIPC_NLA_MON_PEER_MEMBERS])); exit: print_string(PRINT_FP, NULL, "\n", ""); close_json_object(); return MNL_CB_OK; }
int nfexp_nlmsg_parse(const struct nlmsghdr *nlh, struct nf_expect *exp) { struct nlattr *tb[CTA_EXPECT_MAX+1] = {}; struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(struct nfgenmsg), nlmsg_parse_expection_attr_cb, tb); if (tb[CTA_EXPECT_MASTER]) { exp->expected.orig.l3protonum = nfg->nfgen_family; set_bit(ATTR_ORIG_L3PROTO, exp->expected.set); nfct_parse_tuple(tb[CTA_EXPECT_MASTER], &exp->master.orig, __DIR_ORIG, exp->master.set); set_bit(ATTR_EXP_MASTER, exp->set); } if (tb[CTA_EXPECT_TUPLE]) { exp->mask.orig.l3protonum = nfg->nfgen_family; set_bit(ATTR_ORIG_L3PROTO, exp->mask.set); nfct_parse_tuple(tb[CTA_EXPECT_TUPLE], &exp->expected.orig, __DIR_ORIG, exp->expected.set); set_bit(ATTR_EXP_EXPECTED, exp->set); } if (tb[CTA_EXPECT_MASK]) { exp->master.orig.l3protonum = nfg->nfgen_family; set_bit(ATTR_ORIG_L3PROTO, exp->master.set); nfct_parse_tuple(tb[CTA_EXPECT_MASK], &exp->mask.orig, __DIR_ORIG, exp->mask.set); set_bit(ATTR_EXP_MASK, exp->set); } if (tb[CTA_EXPECT_TIMEOUT]) { exp->timeout = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_TIMEOUT])); set_bit(ATTR_EXP_TIMEOUT, exp->set); } if (tb[CTA_EXPECT_ZONE]) { exp->zone = ntohs(mnl_attr_get_u16(tb[CTA_EXPECT_ZONE])); set_bit(ATTR_EXP_ZONE, exp->set); } if (tb[CTA_EXPECT_FLAGS]) { exp->flags = ntohl(mnl_attr_get_u32(tb[CTA_EXPECT_FLAGS])); set_bit(ATTR_EXP_FLAGS, exp->set); } if (tb[CTA_EXPECT_HELP_NAME]) { strncpy(exp->helper_name, mnl_attr_get_str(tb[CTA_EXPECT_HELP_NAME]), NFCT_HELPER_NAME_MAX); set_bit(ATTR_EXP_HELPER_NAME, exp->set); } return 0; }
static int cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[NLE_MAX]; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb); if (tb[NLE_MYVAR]) printf("myvar=%d\n", mnl_attr_get_u32(tb[NLE_MYVAR])); return MNL_CB_OK; }
static int get_group_id_cb(const struct nlmsghdr *nlh, void *data) { struct group_info *group_info = data; struct nlattr *tb[CTRL_ATTR_MAX + 1] = {}; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*genl), get_group_id_attr_cb, tb); if (!tb[CTRL_ATTR_MCAST_GROUPS]) return MNL_CB_ERROR; parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS], group_info); return MNL_CB_OK; }
static int get_family_id_cb(const struct nlmsghdr *nlh, void *data) { uint32_t *p_id = data; struct nlattr *tb[CTRL_ATTR_MAX + 1] = {}; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*genl), get_family_id_attr_cb, tb); if (!tb[CTRL_ATTR_FAMILY_ID]) return MNL_CB_ERROR; *p_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]); return MNL_CB_OK; }
//Function which parses the netlink message (*ADDR) we have received and extract //relevant information, which is parsed to OS-independent //neat_addr_update_src_list static neat_error_code nt_linux_handle_addr(struct neat_ctx *ctx, struct nlmsghdr *nl_hdr) { struct ifaddrmsg *ifm = (struct ifaddrmsg*) mnl_nlmsg_get_payload(nl_hdr); const struct nlattr *attr_table[IFA_MAX+1]; //IFA_MAX is the largest index I can store in my array. Since arrays are //zero-indexed, this is IFA_MAX and not IFA_MAX + 1. However, array has to //be of size IFA_MAX + 1. DOH! struct nlattr_storage tb_storage = {attr_table, IFA_MAX}; struct sockaddr_storage src_addr; struct sockaddr_in *src_addr4; struct sockaddr_in6 *src_addr6; struct ifa_cacheinfo *ci; uint32_t ifa_pref = 0, ifa_valid = 0; if (ifm->ifa_scope == RT_SCOPE_LINK) return NEAT_ERROR_OK; memset(attr_table, 0, sizeof(attr_table)); memset(&src_addr, 0, sizeof(src_addr)); if (mnl_attr_parse(nl_hdr, sizeof(struct ifaddrmsg), neat_linux_parse_nlattr, &tb_storage) != MNL_CB_OK) { nt_log(ctx, NEAT_LOG_ERROR, "Failed to parse nlattr for msg of type %d", __func__, nl_hdr->nlmsg_type); return NEAT_ERROR_OK; } //v4 and v6 has to be handled differently, both due to address size and //available information if (ifm->ifa_family == AF_INET) { src_addr4 = (struct sockaddr_in*) &src_addr; src_addr4->sin_family = AF_INET; src_addr4->sin_addr.s_addr = mnl_attr_get_u32(attr_table[IFA_LOCAL]); } else { src_addr6 = (struct sockaddr_in6*) &src_addr; src_addr6->sin6_family = AF_INET6; memcpy(&src_addr6->sin6_addr, mnl_attr_get_payload(attr_table[IFA_ADDRESS]), sizeof(struct in6_addr)); ci = (struct ifa_cacheinfo*) mnl_attr_get_payload(attr_table[IFA_CACHEINFO]); ifa_pref = ci->ifa_prefered; ifa_valid = ci->ifa_valid; } //TODO: Should this function be a callback instead? Will we have multiple //addresses handlers/types of context? return nt_addr_update_src_list(ctx, (struct sockaddr*) &src_addr, ifm->ifa_index, nl_hdr->nlmsg_type == RTM_NEWADDR, ifm->ifa_prefixlen, ifa_pref, ifa_valid); }
int nftnl_gen_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_gen *gen) { struct nlattr *tb[NFTA_GEN_MAX + 1] = {}; struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_gen_parse_attr_cb, tb) < 0) return -1; if (tb[NFTA_GEN_ID]) { gen->id = ntohl(mnl_attr_get_u32(tb[NFTA_GEN_ID])); gen->flags |= (1 << NFTNL_GEN_ID); } return 0; }
static int genl_ctrl_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[CTRL_ATTR_MAX + 1] = {}; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); int32_t *genl_id = data; mnl_attr_parse(nlh, sizeof(*genl), genl_ctrl_validate_cb, tb); if (tb[CTRL_ATTR_FAMILY_ID]) *genl_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]); else *genl_id = -1; return MNL_CB_OK; }
static int queue_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[NFQA_MAX+1] = {}; struct nfqnl_msg_packet_hdr *ph = NULL; uint32_t id = 0; mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb); if (tb[NFQA_PACKET_HDR]) { ph = mnl_attr_get_payload(tb[NFQA_PACKET_HDR]); id = ntohl(ph->packet_id); } printf("packet received (id=%u hw=0x%04x hook=%u)\n", id, ntohs(ph->hw_protocol), ph->hook); return MNL_CB_OK + id; }
int res_pd_idx_parse_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[RDMA_NLDEV_ATTR_MAX] = {}; struct rd *rd = data; const char *name; uint32_t idx; mnl_attr_parse(nlh, 0, rd_attr_cb, tb); if (!tb[RDMA_NLDEV_ATTR_DEV_INDEX] || !tb[RDMA_NLDEV_ATTR_DEV_NAME]) return MNL_CB_ERROR; name = mnl_attr_get_str(tb[RDMA_NLDEV_ATTR_DEV_NAME]); idx = mnl_attr_get_u32(tb[RDMA_NLDEV_ATTR_DEV_INDEX]); return res_pd_line(rd, name, idx, tb); }
static int data_cb(const struct nlmsghdr *nlh, void *data) { struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh); printf("index=%d type=%d flags=%d family=%d ", ifm->ifi_index, ifm->ifi_type, ifm->ifi_flags, ifm->ifi_family); if (ifm->ifi_flags & IFF_RUNNING) printf("[RUNNING] "); else printf("[NOT RUNNING] "); mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, NULL); printf("\n"); return MNL_CB_OK; }
static int nametable_show_cb(const struct nlmsghdr *nlh, void *data) { int *iteration = data; char port_id[PORTID_STR_LEN]; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_NAME_TABLE_MAX + 1] = {}; struct nlattr *publ[TIPC_NLA_PUBL_MAX + 1] = {}; const char *scope[] = { "", "zone", "cluster", "node" }; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_NAME_TABLE]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_NAME_TABLE], parse_attrs, attrs); if (!attrs[TIPC_NLA_NAME_TABLE_PUBL]) return MNL_CB_ERROR; mnl_attr_parse_nested(attrs[TIPC_NLA_NAME_TABLE_PUBL], parse_attrs, publ); if (!publ[TIPC_NLA_NAME_TABLE_PUBL]) return MNL_CB_ERROR; if (!*iteration) printf("%-10s %-10s %-10s %-26s %-10s\n", "Type", "Lower", "Upper", "Port Identity", "Publication Scope"); (*iteration)++; snprintf(port_id, sizeof(port_id), "<%u.%u.%u:%u>", tipc_zone(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])), tipc_cluster(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])), tipc_node(mnl_attr_get_u32(publ[TIPC_NLA_PUBL_NODE])), mnl_attr_get_u32(publ[TIPC_NLA_PUBL_REF])); printf("%-10u %-10u %-10u %-26s %-12u", mnl_attr_get_u32(publ[TIPC_NLA_PUBL_TYPE]), mnl_attr_get_u32(publ[TIPC_NLA_PUBL_LOWER]), mnl_attr_get_u32(publ[TIPC_NLA_PUBL_UPPER]), port_id, mnl_attr_get_u32(publ[TIPC_NLA_PUBL_KEY])); printf("%s\n", scope[mnl_attr_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]); return MNL_CB_OK; }
static int netid_get_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_NET_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_NET]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_NET], parse_attrs, attrs); if (!attrs[TIPC_NLA_NET_ID]) return MNL_CB_ERROR; printf("%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_NET_ID])); return MNL_CB_OK; }
/** * nfacct_nlmsg_parse_payload - set accounting object attributes from message * \param nlh: netlink message that you want to use to add the payload. * \param nfacct: pointer to a accounting object * * This function returns -1 in case that some mandatory attributes are * missing. On sucess, it returns 0. */ int nfacct_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfacct *nfacct) { struct nlattr *tb[NFACCT_MAX+1] = {}; struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*nfg), nfacct_nlmsg_parse_attr_cb, tb); if (!tb[NFACCT_NAME] && !tb[NFACCT_PKTS] && !tb[NFACCT_BYTES]) return -1; nfacct_attr_set_str(nfacct, NFACCT_ATTR_NAME, mnl_attr_get_str(tb[NFACCT_NAME])); nfacct_attr_set_u64(nfacct, NFACCT_ATTR_PKTS, be64toh(mnl_attr_get_u64(tb[NFACCT_PKTS]))); nfacct_attr_set_u64(nfacct, NFACCT_ATTR_BYTES, be64toh(mnl_attr_get_u64(tb[NFACCT_BYTES]))); return 0; }
static int link_mon_get_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_MON_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_MON]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_MON], parse_attrs, attrs); if (!attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD]) return MNL_CB_ERROR; new_json_obj(json); print_uint(PRINT_ANY, "threshold", "%u\n", mnl_attr_get_u32(attrs[TIPC_NLA_MON_ACTIVATION_THRESHOLD])); delete_json_obj(); return MNL_CB_OK; }
static int log_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[NFULA_MAX+1] = {}; struct nfulnl_msg_packet_hdr *ph = NULL; const char *prefix = NULL; uint32_t mark = 0; mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb); if (tb[NFULA_PACKET_HDR]) ph = mnl_attr_get_payload(tb[NFULA_PACKET_HDR]); if (tb[NFULA_PREFIX]) prefix = mnl_attr_get_str(tb[NFULA_PREFIX]); if (tb[NFULA_MARK]) mark = ntohl(mnl_attr_get_u32(tb[NFULA_MARK])); printf("log received (prefix=\"%s\" hw=0x%04x hook=%u mark=%u)\n", prefix ? prefix : "", ntohs(ph->hw_protocol), ph->hook, mark); return MNL_CB_OK; }
static int link_get_cb(const struct nlmsghdr *nlh, void *data) { int *prop = data; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; struct nlattr *props[TIPC_NLA_PROP_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_LINK]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); if (!attrs[TIPC_NLA_LINK_PROP]) return MNL_CB_ERROR; mnl_attr_parse_nested(attrs[TIPC_NLA_LINK_PROP], parse_attrs, props); if (!props[*prop]) return MNL_CB_ERROR; new_json_obj(json); open_json_object(NULL); switch (*prop) { case TIPC_NLA_PROP_PRIO: print_uint(PRINT_ANY, PRIORITY_STR, "%u\n", mnl_attr_get_u32(props[*prop])); break; case TIPC_NLA_PROP_TOL: print_uint(PRINT_ANY, TOLERANCE_STR, "%u\n", mnl_attr_get_u32(props[*prop])); break; case TIPC_NLA_PROP_WIN: print_uint(PRINT_ANY, WINDOW_STR, "%u\n", mnl_attr_get_u32(props[*prop])); break; default: break; } close_json_object(); delete_json_obj(); return MNL_CB_OK; }
static int data_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[CTRL_ATTR_MAX+1] = {}; struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); mnl_attr_parse(nlh, sizeof(*genl), data_attr_cb, tb); if (tb[CTRL_ATTR_FAMILY_NAME]) { printf("name=%s\t", mnl_attr_get_str(tb[CTRL_ATTR_FAMILY_NAME])); } if (tb[CTRL_ATTR_FAMILY_ID]) { printf("id=%u\t", mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID])); } if (tb[CTRL_ATTR_VERSION]) { printf("version=%u\t", mnl_attr_get_u32(tb[CTRL_ATTR_VERSION])); } if (tb[CTRL_ATTR_HDRSIZE]) { printf("hdrsize=%u\t", mnl_attr_get_u32(tb[CTRL_ATTR_HDRSIZE])); } if (tb[CTRL_ATTR_MAXATTR]) { printf("maxattr=%u\t", mnl_attr_get_u32(tb[CTRL_ATTR_MAXATTR])); } printf("\n"); if (tb[CTRL_ATTR_OPS]) { printf("ops:\n"); parse_genl_family_ops(tb[CTRL_ATTR_OPS]); } if (tb[CTRL_ATTR_MCAST_GROUPS]) { printf("grps:\n"); parse_genl_mc_grps(tb[CTRL_ATTR_MCAST_GROUPS]); } printf("\n"); return MNL_CB_OK; }
static int data_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[IFLA_MAX+1] = {}; struct ifinfomsg *ifm = mnl_nlmsg_get_payload(nlh); printf("index=%d type=%d flags=%d family=%d ", ifm->ifi_index, ifm->ifi_type, ifm->ifi_flags, ifm->ifi_family); if (ifm->ifi_flags & IFF_RUNNING) printf("[RUNNING] "); else printf("[NOT RUNNING] "); mnl_attr_parse(nlh, sizeof(*ifm), data_attr_cb, tb); if (tb[IFLA_MTU]) { printf("mtu=%d ", mnl_attr_get_u32(tb[IFLA_MTU])); } if (tb[IFLA_IFNAME]) { printf("name=%s", mnl_attr_get_str(tb[IFLA_IFNAME])); } printf("\n"); return MNL_CB_OK; }
static int link_list_cb(const struct nlmsghdr *nlh, void *data) { struct genlmsghdr *genl = mnl_nlmsg_get_payload(nlh); struct nlattr *info[TIPC_NLA_MAX + 1] = {}; struct nlattr *attrs[TIPC_NLA_LINK_MAX + 1] = {}; mnl_attr_parse(nlh, sizeof(*genl), parse_attrs, info); if (!info[TIPC_NLA_LINK]) return MNL_CB_ERROR; mnl_attr_parse_nested(info[TIPC_NLA_LINK], parse_attrs, attrs); if (!attrs[TIPC_NLA_LINK_NAME]) return MNL_CB_ERROR; print_string(PRINT_FP, NULL, "%s: ", mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME])); if (attrs[TIPC_NLA_LINK_UP]) print_string(PRINT_ANY, mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]),"%s\n", "up"); else print_string(PRINT_ANY, mnl_attr_get_str(attrs[TIPC_NLA_LINK_NAME]), "%s\n", "down"); return MNL_CB_OK; }
static int log_cb(const struct nlmsghdr *nlh, void *data) { struct nlattr *tb[NFULA_MAX+1] = {}; mnl_attr_parse(nlh, sizeof(struct nfgenmsg), parse_attr_cb, tb); if (tb[NFULA_PREFIX]) { const char *prefix = mnl_attr_get_str(tb[NFULA_PREFIX]); printf("%s ", prefix); } if (tb[NFULA_IFINDEX_INDEV]) { uint32_t indev = ntohl(mnl_attr_get_u32(tb[NFULA_IFINDEX_INDEV])); char *instr = get_net_device_name_by_index(indev); printf("IN=%s ", instr ? instr : ""); } else { printf("IN= "); } if (tb[NFULA_IFINDEX_OUTDEV]) { uint32_t outdev = ntohl(mnl_attr_get_u32(tb[NFULA_IFINDEX_OUTDEV])); char *outstr = get_net_device_name_by_index(outdev); printf("OUT=%s ", outstr ? outstr : ""); } else { printf("OUT= "); } if (tb[NFULA_PAYLOAD]) { struct iphdr *iph = (struct iphdr *) mnl_attr_get_payload(tb[NFULA_PAYLOAD]); printf("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ", ((unsigned char *)&iph->saddr)[0], ((unsigned char *)&iph->saddr)[1], ((unsigned char *)&iph->saddr)[2], ((unsigned char *)&iph->saddr)[3], ((unsigned char *)&iph->daddr)[0], ((unsigned char *)&iph->daddr)[1], ((unsigned char *)&iph->daddr)[2], ((unsigned char *)&iph->daddr)[3]); printf("LEN=%u ", ntohs(iph->tot_len)); switch(iph->protocol) { case IPPROTO_TCP: { struct tcphdr *th = (struct tcphdr *) ((__u32 *) iph + iph->ihl); printf("PROTO=TCP SPT=%u DPT=%u ", ntohs(th->source), ntohs(th->dest)); break; } case IPPROTO_UDP: { struct udphdr *uh = (struct udphdr *) ((__u32 *) iph + iph->ihl); printf("PROTO=UDP SPT=%u DPT=%u LEN=%u ", ntohs(uh->source), ntohs(uh->dest), ntohs(uh->len)); break; } case IPPROTO_ICMP: { struct icmphdr *ich = (struct icmphdr *) ((__u32 *) iph + iph->ihl); printf("PROTO=ICMP TYPE=%u CODE=%u ", ich->type, ich->code); break; } default: { printf("PROTO=%u ", iph->protocol); } } } if (tb[NFULA_UID]) { uint32_t uid = ntohl(mnl_attr_get_u32(tb[NFULA_UID])); printf("UID=%u ", uid); } puts(""); return MNL_CB_OK; }