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); }
static void print_proto(const struct nlattr *nest) { struct nlattr *tb[CTA_PROTO_MAX+1] = {}; mnl_attr_parse_nested(nest, parse_proto_cb, tb); if (tb[CTA_PROTO_NUM]) { printf("proto=%u ", mnl_attr_get_u8(tb[CTA_PROTO_NUM])); } if (tb[CTA_PROTO_SRC_PORT]) { printf("sport=%u ", ntohs(mnl_attr_get_u16(tb[CTA_PROTO_SRC_PORT]))); } if (tb[CTA_PROTO_DST_PORT]) { printf("dport=%u ", ntohs(mnl_attr_get_u16(tb[CTA_PROTO_DST_PORT]))); } if (tb[CTA_PROTO_ICMP_ID]) { printf("id=%u ", ntohs(mnl_attr_get_u16(tb[CTA_PROTO_ICMP_ID]))); } if (tb[CTA_PROTO_ICMP_TYPE]) { printf("type=%u ", mnl_attr_get_u8(tb[CTA_PROTO_ICMP_TYPE])); } if (tb[CTA_PROTO_ICMP_CODE]) { printf("code=%u ", mnl_attr_get_u8(tb[CTA_PROTO_ICMP_CODE])); } }
static int nftnl_expr_lookup_parse(struct nftnl_expr *e, struct nlattr *attr) { struct nftnl_expr_lookup *lookup = nftnl_expr_data(e); struct nlattr *tb[NFTA_LOOKUP_MAX+1] = {}; int ret = 0; if (mnl_attr_parse_nested(attr, nftnl_expr_lookup_cb, tb) < 0) return -1; if (tb[NFTA_LOOKUP_SREG]) { lookup->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SREG])); e->flags |= (1 << NFTNL_EXPR_LOOKUP_SREG); } if (tb[NFTA_LOOKUP_DREG]) { lookup->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_DREG])); e->flags |= (1 << NFTNL_EXPR_LOOKUP_DREG); } if (tb[NFTA_LOOKUP_SET]) { strcpy(lookup->set_name, mnl_attr_get_str(tb[NFTA_LOOKUP_SET])); e->flags |= (1 << NFTNL_EXPR_LOOKUP_SET); } if (tb[NFTA_LOOKUP_SET_ID]) { lookup->set_id = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID])); e->flags |= (1 << NFTNL_EXPR_LOOKUP_SET_ID); } return ret; }
static int nfct_parse_helper(const struct nlattr *attr, struct nf_conntrack *ct) { struct nlattr *tb[CTA_HELP_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_helper_attr_cb, tb) < 0) return -1; if (!tb[CTA_HELP_NAME]) return 0; strncpy(ct->helper_name, mnl_attr_get_str(tb[CTA_HELP_NAME]), NFCT_HELPER_NAME_MAX); ct->helper_name[NFCT_HELPER_NAME_MAX-1] = '\0'; set_bit(ATTR_HELPER_NAME, ct->head.set); if (!tb[CTA_HELP_INFO]) return 0; ct->helper_info_len = mnl_attr_get_payload_len(tb[CTA_HELP_INFO]); ct->helper_info = calloc(1, ct->helper_info_len); if (ct->helper_info == NULL) return -1; memcpy(ct->helper_info, mnl_attr_get_payload(tb[CTA_HELP_INFO]), ct->helper_info_len); set_bit(ATTR_HELPER_INFO, ct->head.set); return 0; }
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 nft_rule_expr_ct_parse(struct nft_rule_expr *e, struct nlattr *attr) { struct nft_expr_ct *ct = nft_expr_data(e); struct nlattr *tb[NFTA_CT_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nft_rule_expr_ct_cb, tb) < 0) return -1; if (tb[NFTA_CT_KEY]) { ct->key = ntohl(mnl_attr_get_u32(tb[NFTA_CT_KEY])); e->flags |= (1 << NFT_EXPR_CT_KEY); } if (tb[NFTA_CT_DREG]) { ct->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_CT_DREG])); e->flags |= (1 << NFT_EXPR_CT_DREG); } if (tb[NFTA_CT_SREG]) { ct->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_CT_SREG])); e->flags |= (1 << NFT_EXPR_CT_SREG); } if (tb[NFTA_CT_DIRECTION]) { ct->dir = mnl_attr_get_u8(tb[NFTA_CT_DIRECTION]); e->flags |= (1 << NFT_EXPR_CT_DIR); } return 0; }
static void print_ip(const struct nlattr *nest) { struct nlattr *tb[CTA_IP_MAX+1] = {}; mnl_attr_parse_nested(nest, parse_ip_cb, tb); if (tb[CTA_IP_V4_SRC]) { struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_SRC]); printf("src=%s ", inet_ntoa(*in)); } if (tb[CTA_IP_V4_DST]) { struct in_addr *in = mnl_attr_get_payload(tb[CTA_IP_V4_DST]); printf("dst=%s ", inet_ntoa(*in)); } if (tb[CTA_IP_V6_SRC]) { struct in6_addr *in = mnl_attr_get_payload(tb[CTA_IP_V6_SRC]); char out[INET6_ADDRSTRLEN]; if (!inet_ntop(AF_INET6, in, out, sizeof(out))) printf("src=%s ", out); } if (tb[CTA_IP_V6_DST]) { struct in6_addr *in = mnl_attr_get_payload(tb[CTA_IP_V6_DST]); char out[INET6_ADDRSTRLEN]; if (!inet_ntop(AF_INET6, in, out, sizeof(out))) printf("dst=%s ", out); } }
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 nfct_parse_protoinfo_sctp(const struct nlattr *attr, struct nf_conntrack *ct) { struct nlattr *tb[CTA_PROTOINFO_SCTP_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_sctp_attr_cb, tb) < 0) return -1; if (tb[CTA_PROTOINFO_SCTP_STATE]) { ct->protoinfo.sctp.state = mnl_attr_get_u8(tb[CTA_PROTOINFO_SCTP_STATE]); set_bit(ATTR_SCTP_STATE, ct->head.set); } if (tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL]) { ct->protoinfo.sctp.vtag[__DIR_ORIG] = ntohl(mnl_attr_get_u32(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL])); set_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set); } if (tb[CTA_PROTOINFO_SCTP_VTAG_REPLY]) { ct->protoinfo.sctp.vtag[__DIR_REPL] = ntohl(mnl_attr_get_u32(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY])); set_bit(ATTR_SCTP_VTAG_REPL, ct->head.set); } return 0; }
static int nft_rule_expr_bitwise_parse(struct nft_rule_expr *e, struct nlattr *attr) { struct nft_expr_bitwise *bitwise = nft_expr_data(e); struct nlattr *tb[NFTA_BITWISE_MAX+1] = {}; int ret = 0; if (mnl_attr_parse_nested(attr, nft_rule_expr_bitwise_cb, tb) < 0) return -1; if (tb[NFTA_BITWISE_SREG]) { bitwise->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_BITWISE_SREG])); e->flags |= (1 << NFT_EXPR_BITWISE_SREG); } if (tb[NFTA_BITWISE_DREG]) { bitwise->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_BITWISE_DREG])); e->flags |= (1 << NFT_EXPR_BITWISE_DREG); } if (tb[NFTA_BITWISE_LEN]) { bitwise->len = ntohl(mnl_attr_get_u32(tb[NFTA_BITWISE_LEN])); e->flags |= (1 << NFT_EXPR_BITWISE_LEN); } if (tb[NFTA_BITWISE_MASK]) { ret = nft_parse_data(&bitwise->mask, tb[NFTA_BITWISE_MASK], NULL); e->flags |= (1 << NFTA_BITWISE_MASK); } if (tb[NFTA_BITWISE_XOR]) { ret = nft_parse_data(&bitwise->xor, tb[NFTA_BITWISE_XOR], NULL); e->flags |= (1 << NFTA_BITWISE_XOR); } return ret; }
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 nftnl_expr_payload_parse(struct nftnl_expr *e, struct nlattr *attr) { struct nftnl_expr_payload *payload = nftnl_expr_data(e); struct nlattr *tb[NFTA_PAYLOAD_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nftnl_expr_payload_cb, tb) < 0) return -1; if (tb[NFTA_PAYLOAD_DREG]) { payload->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_DREG])); e->flags |= (1 << NFTNL_EXPR_PAYLOAD_DREG); } if (tb[NFTA_PAYLOAD_BASE]) { payload->base = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_BASE])); e->flags |= (1 << NFTNL_EXPR_PAYLOAD_BASE); } if (tb[NFTA_PAYLOAD_OFFSET]) { payload->offset = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_OFFSET])); e->flags |= (1 << NFTNL_EXPR_PAYLOAD_OFFSET); } if (tb[NFTA_PAYLOAD_LEN]) { payload->len = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_LEN])); e->flags |= (1 << NFTNL_EXPR_PAYLOAD_LEN); } return 0; }
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; }
static int res_print_summary(struct rd *rd, struct nlattr **tb) { struct nlattr *nla_table = tb[RDMA_NLDEV_ATTR_RES_SUMMARY]; struct nlattr *nla_entry; const char *name; uint64_t curr; int err; mnl_attr_for_each_nested(nla_entry, nla_table) { struct nlattr *nla_line[RDMA_NLDEV_ATTR_MAX] = {}; char json_name[32]; err = mnl_attr_parse_nested(nla_entry, rd_attr_cb, nla_line); if (err != MNL_CB_OK) return -EINVAL; if (!nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME] || !nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]) { return -EINVAL; } name = mnl_attr_get_str(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_NAME]); curr = mnl_attr_get_u64(nla_line[RDMA_NLDEV_ATTR_RES_SUMMARY_ENTRY_CURR]); if (rd->json_output) { snprintf(json_name, 32, "%s", name); jsonw_lluint_field(rd->jw, json_name, curr); } else { pr_out("%s %"PRId64 " ", name, curr); } } return 0; }
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 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; }
static void print_tuple(const struct nlattr *nest) { struct nlattr *tb[CTA_TUPLE_MAX+1] = {}; mnl_attr_parse_nested(nest, parse_tuple_cb, tb); if (tb[CTA_TUPLE_IP]) { print_ip(tb[CTA_TUPLE_IP]); } if (tb[CTA_TUPLE_PROTO]) { print_proto(tb[CTA_TUPLE_PROTO]); } }
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 void print_counters(const struct nlattr *nest) { struct nlattr *tb[CTA_COUNTERS_MAX+1] = {}; mnl_attr_parse_nested(nest, parse_counters_cb, tb); if (tb[CTA_COUNTERS_PACKETS]) { printf("packets=%"PRIu64" ", be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS]))); } if (tb[CTA_COUNTERS_BYTES]) { printf("bytes=%"PRIu64" ", be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES]))); } }
static int nfct_parse_nat_seq(const struct nlattr *attr, struct nf_conntrack *ct, int dir) { struct nlattr *tb[CTA_NAT_SEQ_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_nat_seq_attr_cb, tb) < 0) return -1; if (tb[CTA_NAT_SEQ_CORRECTION_POS]) { ct->natseq[dir].correction_pos = ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_CORRECTION_POS])); switch(dir) { case __DIR_ORIG: set_bit(ATTR_ORIG_NAT_SEQ_CORRECTION_POS, ct->head.set); break; case __DIR_REPL: set_bit(ATTR_REPL_NAT_SEQ_CORRECTION_POS, ct->head.set); break; } } if (tb[CTA_NAT_SEQ_OFFSET_BEFORE]) { ct->natseq[dir].offset_before = ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_OFFSET_BEFORE])); switch(dir) { case __DIR_ORIG: set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_BEFORE, ct->head.set); break; case __DIR_REPL: set_bit(ATTR_REPL_NAT_SEQ_OFFSET_BEFORE, ct->head.set); break; } } if (tb[CTA_NAT_SEQ_OFFSET_AFTER]) { ct->natseq[dir].offset_after = ntohl(mnl_attr_get_u32(tb[CTA_NAT_SEQ_OFFSET_AFTER])); switch(dir) { case __DIR_ORIG: set_bit(ATTR_ORIG_NAT_SEQ_OFFSET_AFTER, ct->head.set); break; case __DIR_REPL: set_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->head.set); break; } } return 0; }
static int nfct_parse_counters(const struct nlattr *attr, struct nf_conntrack *ct, int dir) { struct nlattr *tb[CTA_COUNTERS_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_counters_attr_cb, tb) < 0) return -1; if (tb[CTA_COUNTERS_PACKETS] || tb[CTA_COUNTERS32_PACKETS]) { if (tb[CTA_COUNTERS32_PACKETS]) { ct->counters[dir].packets = ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_PACKETS])); } if (tb[CTA_COUNTERS_PACKETS]) { ct->counters[dir].packets = be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_PACKETS])); } switch(dir) { case __DIR_ORIG: set_bit(ATTR_ORIG_COUNTER_PACKETS, ct->head.set); break; case __DIR_REPL: set_bit(ATTR_REPL_COUNTER_PACKETS, ct->head.set); break; } } if (tb[CTA_COUNTERS_BYTES] || tb[CTA_COUNTERS32_BYTES]) { if (tb[CTA_COUNTERS32_BYTES]) { ct->counters[dir].bytes = ntohl(mnl_attr_get_u32(tb[CTA_COUNTERS32_BYTES])); } if (tb[CTA_COUNTERS_BYTES]) { ct->counters[dir].bytes = be64toh(mnl_attr_get_u64(tb[CTA_COUNTERS_BYTES])); } switch(dir) { case __DIR_ORIG: set_bit(ATTR_ORIG_COUNTER_BYTES, ct->head.set); break; case __DIR_REPL: set_bit(ATTR_REPL_COUNTER_BYTES, ct->head.set); break; } } return 0; }
static int nfct_parse_secctx(const struct nlattr *attr, struct nf_conntrack *ct) { struct nlattr *tb[CTA_SECCTX_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_secctx_attr_cb, tb) < 0) return -1; if (!tb[CTA_SECCTX_NAME]) return 0; ct->secctx = strdup(NFA_DATA(tb[CTA_SECCTX_NAME])); if (ct->secctx) set_bit(ATTR_SECCTX, ct->head.set); return 0; }
static int nfct_parse_protoinfo_tcp(const struct nlattr *attr, struct nf_conntrack *ct) { struct nlattr *tb[CTA_PROTOINFO_TCP_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_pinfo_tcp_attr_cb, tb) < 0) return -1; if (tb[CTA_PROTOINFO_TCP_STATE]) { ct->protoinfo.tcp.state = mnl_attr_get_u8(tb[CTA_PROTOINFO_TCP_STATE]); set_bit(ATTR_TCP_STATE, ct->head.set); } if (tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]) { memcpy(&ct->protoinfo.tcp.wscale[__DIR_ORIG], mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_WSCALE_ORIGINAL]), sizeof(uint8_t)); set_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set); } if (tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]) { memcpy(&ct->protoinfo.tcp.wscale[__DIR_REPL], mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_WSCALE_REPLY]), sizeof(uint8_t)); set_bit(ATTR_TCP_WSCALE_REPL, ct->head.set); } if (tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]) { memcpy(&ct->protoinfo.tcp.flags[0], mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_FLAGS_ORIGINAL]), sizeof(struct nf_ct_tcp_flags)); set_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set); set_bit(ATTR_TCP_MASK_ORIG, ct->head.set); } if (tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]) { memcpy(&ct->protoinfo.tcp.flags[1], mnl_attr_get_payload(tb[CTA_PROTOINFO_TCP_FLAGS_REPLY]), sizeof(struct nf_ct_tcp_flags)); set_bit(ATTR_TCP_FLAGS_REPL, ct->head.set); set_bit(ATTR_TCP_MASK_REPL, ct->head.set); } return 0; }
static void attributes_show_ipv4(struct nlattr *tb[]) { if (tb[RTA_TABLE]) { printf("table=%u ", mnl_attr_get_u32(tb[RTA_TABLE])); } if (tb[RTA_DST]) { struct in_addr *addr = mnl_attr_get_payload(tb[RTA_DST]); printf("dst=%s ", inet_ntoa(*addr)); } if (tb[RTA_SRC]) { struct in_addr *addr = mnl_attr_get_payload(tb[RTA_SRC]); printf("src=%s ", inet_ntoa(*addr)); } if (tb[RTA_OIF]) { printf("oif=%u ", mnl_attr_get_u32(tb[RTA_OIF])); } if (tb[RTA_FLOW]) { printf("flow=%u ", mnl_attr_get_u32(tb[RTA_FLOW])); } if (tb[RTA_PREFSRC]) { struct in_addr *addr = mnl_attr_get_payload(tb[RTA_PREFSRC]); printf("prefsrc=%s ", inet_ntoa(*addr)); } if (tb[RTA_GATEWAY]) { struct in_addr *addr = mnl_attr_get_payload(tb[RTA_GATEWAY]); printf("gw=%s ", inet_ntoa(*addr)); } if (tb[RTA_PRIORITY]) { printf("prio=%u ", mnl_attr_get_u32(tb[RTA_PRIORITY])); } if (tb[RTA_METRICS]) { int i; struct nlattr *tbx[RTAX_MAX+1] = {}; mnl_attr_parse_nested(tb[RTA_METRICS], data_attr_cb2, tbx); for (i=0; i<RTAX_MAX; i++) { if (tbx[i]) { printf("metrics[%d]=%u ", i, mnl_attr_get_u32(tbx[i])); } } } printf("\n"); }
static void parse_genl_family_ops(struct nlattr *nested) { struct nlattr *pos; mnl_attr_for_each_nested(pos, nested) { struct nlattr *tb[CTRL_ATTR_OP_MAX+1] = {}; mnl_attr_parse_nested(pos, parse_family_ops_cb, tb); if (tb[CTRL_ATTR_OP_ID]) { printf("id-0x%x ", mnl_attr_get_u32(tb[CTRL_ATTR_OP_ID])); } if (tb[CTRL_ATTR_OP_MAX]) { printf("flags "); } printf("\n"); } }
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; }
static int nft_rule_expr_nat_parse(struct nft_rule_expr *e, struct nlattr *attr) { struct nft_expr_nat *nat = nft_expr_data(e); struct nlattr *tb[NFTA_NAT_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nft_rule_expr_nat_cb, tb) < 0) return -1; if (tb[NFTA_NAT_TYPE]) { nat->type = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_TYPE])); e->flags |= (1 << NFT_EXPR_NAT_TYPE); } if (tb[NFTA_NAT_FAMILY]) { nat->family = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_FAMILY])); e->flags |= (1 << NFT_EXPR_NAT_FAMILY); } if (tb[NFTA_NAT_REG_ADDR_MIN]) { nat->sreg_addr_min = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_REG_ADDR_MIN])); e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MIN); } if (tb[NFTA_NAT_REG_ADDR_MAX]) { nat->sreg_addr_max = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_REG_ADDR_MAX])); e->flags |= (1 << NFT_EXPR_NAT_REG_ADDR_MAX); } if (tb[NFTA_NAT_REG_PROTO_MIN]) { nat->sreg_proto_min = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_REG_PROTO_MIN])); e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MIN); } if (tb[NFTA_NAT_REG_PROTO_MAX]) { nat->sreg_proto_max = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_REG_PROTO_MAX])); e->flags |= (1 << NFT_EXPR_NAT_REG_PROTO_MAX); } if (tb[NFTA_NAT_FLAGS]) { nat->flags = ntohl(mnl_attr_get_u32(tb[NFTA_NAT_FLAGS])); e->flags |= (1 << NFT_EXPR_NAT_FLAGS); } return 0; }
static void parse_genl_mc_grps(struct nlattr *nested) { struct nlattr *pos; mnl_attr_for_each_nested(pos, nested) { struct nlattr *tb[CTRL_ATTR_MCAST_GRP_MAX+1] = {}; mnl_attr_parse_nested(pos, parse_mc_grps_cb, tb); if (tb[CTRL_ATTR_MCAST_GRP_ID]) { printf("id-0x%x ", mnl_attr_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID])); } if (tb[CTRL_ATTR_MCAST_GRP_NAME]) { printf("name: %s ", mnl_attr_get_str(tb[CTRL_ATTR_MCAST_GRP_NAME])); } printf("\n"); } }
static int nfct_parse_protoinfo(const struct nlattr *attr, struct nf_conntrack *ct) { struct nlattr *tb[CTA_PROTOINFO_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nfct_parse_protoinfo_attr_cb, tb) < 0) return -1; if (tb[CTA_PROTOINFO_TCP]) nfct_parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP], ct); if (tb[CTA_PROTOINFO_SCTP]) nfct_parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP], ct); if (tb[CTA_PROTOINFO_DCCP]) nfct_parse_protoinfo_dccp(tb[CTA_PROTOINFO_DCCP], ct); return 0; }
static int nftnl_expr_target_parse(struct nftnl_expr *e, struct nlattr *attr) { struct nftnl_expr_target *target = nftnl_expr_data(e); struct nlattr *tb[NFTA_TARGET_MAX+1] = {}; if (mnl_attr_parse_nested(attr, nftnl_expr_target_cb, tb) < 0) return -1; if (tb[NFTA_TARGET_NAME]) { snprintf(target->name, XT_EXTENSION_MAXNAMELEN, "%s", mnl_attr_get_str(tb[NFTA_TARGET_NAME])); target->name[XT_EXTENSION_MAXNAMELEN-1] = '\0'; e->flags |= (1 << NFTNL_EXPR_TG_NAME); } if (tb[NFTA_TARGET_REV]) { target->rev = ntohl(mnl_attr_get_u32(tb[NFTA_TARGET_REV])); e->flags |= (1 << NFTNL_EXPR_TG_REV); } if (tb[NFTA_TARGET_INFO]) { uint32_t len = mnl_attr_get_payload_len(tb[NFTA_TARGET_INFO]); void *target_data; if (target->data) xfree(target->data); target_data = calloc(1, len); if (target_data == NULL) return -1; memcpy(target_data, mnl_attr_get_payload(tb[NFTA_TARGET_INFO]), len); target->data = target_data; target->data_len = len; e->flags |= (1 << NFTNL_EXPR_TG_INFO); } return 0; }