Beispiel #1
1
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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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
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_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;
}
Beispiel #8
0
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;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
0
//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);
}
Beispiel #12
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 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;
}
Beispiel #14
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;
}
Beispiel #15
0
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;
}
Beispiel #16
0
static int
nft_rule_expr_log_parse(struct nft_rule_expr *e, struct nlattr *attr)
{
	struct nft_expr_log *log = nft_expr_data(e);
	struct nlattr *tb[NFTA_LOG_MAX+1] = {};

	if (mnl_attr_parse_nested(attr, nft_rule_expr_log_cb, tb) < 0)
		return -1;

	if (tb[NFTA_LOG_PREFIX]) {
		if (log->prefix)
			xfree(log->prefix);

		log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX]));
		e->flags |= (1 << NFT_EXPR_LOG_PREFIX);
	}
	if (tb[NFTA_LOG_GROUP]) {
		log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP]));
		e->flags |= (1 << NFT_EXPR_LOG_GROUP);
	}
	if (tb[NFTA_LOG_SNAPLEN]) {
		log->snaplen = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_SNAPLEN]));
		e->flags |= (1 << NFT_EXPR_LOG_SNAPLEN);
	}
	if (tb[NFTA_LOG_QTHRESHOLD]) {
		log->qthreshold = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_QTHRESHOLD]));
		e->flags |= (1 << NFT_EXPR_LOG_QTHRESHOLD);
	}
	if (tb[NFTA_LOG_LEVEL]) {
		log->level = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_LEVEL]));
		e->flags |= (1 << NFT_EXPR_LOG_LEVEL);
	}
	if (tb[NFTA_LOG_FLAGS]) {
		log->flags = ntohl(mnl_attr_get_u32(tb[NFTA_LOG_FLAGS]));
		e->flags |= (1 << NFT_EXPR_LOG_FLAGS);
	}

	return 0;
}
Beispiel #17
0
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;
}
Beispiel #18
0
static int
nft_rule_expr_byteorder_parse(struct nft_rule_expr *e, struct nlattr *attr)
{
	struct nft_expr_byteorder *byteorder = nft_expr_data(e);
	struct nlattr *tb[NFTA_BYTEORDER_MAX+1] = {};
	int ret = 0;

	if (mnl_attr_parse_nested(attr, nft_rule_expr_byteorder_cb, tb) < 0)
		return -1;

	if (tb[NFTA_BYTEORDER_SREG]) {
		byteorder->sreg =
			ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_SREG]));
		e->flags |= (1 << NFT_EXPR_BYTEORDER_SREG);
	}
	if (tb[NFTA_BYTEORDER_DREG]) {
		byteorder->dreg =
			ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_DREG]));
		e->flags |= (1 << NFT_EXPR_BYTEORDER_DREG);
	}
	if (tb[NFTA_BYTEORDER_OP]) {
		byteorder->op =
			ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_OP]));
		e->flags |= (1 << NFT_EXPR_BYTEORDER_OP);
	}
	if (tb[NFTA_BYTEORDER_LEN]) {
		byteorder->len =
			ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_LEN]));
		e->flags |= (1 << NFT_EXPR_BYTEORDER_LEN);
	}
	if (tb[NFTA_BYTEORDER_SIZE]) {
		byteorder->size =
			ntohl(mnl_attr_get_u32(tb[NFTA_BYTEORDER_SIZE]));
		e->flags |= (1 << NFT_EXPR_BYTEORDER_SIZE);
	}

	return ret;
}
Beispiel #19
0
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;
}
Beispiel #20
0
//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);
}
Beispiel #21
0
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);
}
Beispiel #22
0
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;
}
Beispiel #23
0
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");
	}
}
Beispiel #24
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");
	}
}
Beispiel #25
0
static int nft_rule_expr_match_parse(struct nft_rule_expr *e, struct nlattr *attr)
{
	struct nft_expr_match *match = nft_expr_data(e);
	struct nlattr *tb[NFTA_MATCH_MAX+1] = {};

	if (mnl_attr_parse_nested(attr, nft_rule_expr_match_cb, tb) < 0)
		return -1;

	if (tb[NFTA_MATCH_NAME]) {
		snprintf(match->name, XT_EXTENSION_MAXNAMELEN, "%s",
			 mnl_attr_get_str(tb[NFTA_MATCH_NAME]));

		match->name[XT_EXTENSION_MAXNAMELEN-1] = '\0';
		e->flags |= (1 << NFT_EXPR_MT_NAME);
	}

	if (tb[NFTA_MATCH_REV]) {
		match->rev = ntohl(mnl_attr_get_u32(tb[NFTA_MATCH_REV]));
		e->flags |= (1 << NFT_EXPR_MT_REV);
	}

	if (tb[NFTA_MATCH_INFO]) {
		uint32_t len = mnl_attr_get_payload_len(tb[NFTA_MATCH_INFO]);
		void *match_data;

		if (match->data)
			xfree(match->data);

		match_data = calloc(1, len);
		if (match_data == NULL)
			return -1;

		memcpy(match_data, mnl_attr_get_payload(tb[NFTA_MATCH_INFO]), len);

		match->data = match_data;
		match->data_len = len;

		e->flags |= (1 << NFT_EXPR_MT_INFO);
	}

	return 0;
}
Beispiel #26
0
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;
}
Beispiel #27
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;
}
Beispiel #28
0
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;
}
Beispiel #29
0
static void parse_genl_mc_grps(struct nlattr *nested,
			       struct group_info *group_info)
{
	struct nlattr *pos;
	const char *name;

	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_NAME] ||
		    !tb[CTRL_ATTR_MCAST_GRP_ID])
			continue;

		name = mnl_attr_get_str(tb[CTRL_ATTR_MCAST_GRP_NAME]);
		if (strcmp(name, group_info->name) != 0)
			continue;

		group_info->id = mnl_attr_get_u32(tb[CTRL_ATTR_MCAST_GRP_ID]);
		group_info->found = true;
	}
}
Beispiel #30
0
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_SREG]) {
		payload->sreg = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_SREG]));
		e->flags |= (1 << NFT_EXPR_PAYLOAD_SREG);
	}
	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);
	}
	if (tb[NFTA_PAYLOAD_CSUM_TYPE]) {
		payload->csum_type = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_CSUM_TYPE]));
		e->flags |= (1 << NFTNL_EXPR_PAYLOAD_CSUM_TYPE);
	}
	if (tb[NFTA_PAYLOAD_CSUM_OFFSET]) {
		payload->csum_offset = ntohl(mnl_attr_get_u32(tb[NFTA_PAYLOAD_CSUM_OFFSET]));
		e->flags |= (1 << NFTNL_EXPR_PAYLOAD_CSUM_OFFSET);
	}
	return 0;
}