Exemplo n.º 1
0
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;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
static int __mnl_attr_validate(const struct nlattr *attr,
			       enum mnl_attr_data_type type, size_t exp_len)
{
	uint16_t attr_len = mnl_attr_get_payload_len(attr);
	const char *attr_data = mnl_attr_get_payload(attr);

	if (attr_len < exp_len) {
		errno = ERANGE;
		return -1;
	}
	switch(type) {
	case MNL_TYPE_FLAG:
		if (attr_len > 0) {
			errno = ERANGE;
			return -1;
		}
		break;
	case MNL_TYPE_NUL_STRING:
		if (attr_len == 0) {
			errno = ERANGE;
			return -1;
		}
		if (attr_data[attr_len-1] != '\0') {
			errno = EINVAL;
			return -1;
		}
		break;
	case MNL_TYPE_STRING:
		if (attr_len == 0) {
			errno = ERANGE;
			return -1;
		}
		break;
	case MNL_TYPE_NESTED:
		/* empty nested attributes are OK. */
		if (attr_len == 0)
			break;
		/* if not empty, they must contain one header, eg. flag */
		if (attr_len < MNL_ATTR_HDRLEN) {
			errno = ERANGE;
			return -1;
		}
		break;
	default:
		/* make gcc happy. */
		break;
	}
	if (exp_len && attr_len > exp_len) {
		errno = ERANGE;
		return -1;
	}
	return 0;
}
Exemplo n.º 4
0
static int nfct_parse_labels(const struct nlattr *attr, struct nf_conntrack *ct)
{
	uint16_t len = mnl_attr_get_payload_len(attr);
	struct nfct_bitmask *mask;
	uint32_t *bits;

	if (len == 0)
		return 0;

	mask = nfct_bitmask_new((len * CHAR_BIT) - 1);
	if (!mask)
		return -1;
	bits = mnl_attr_get_payload(attr);

	memcpy(mask->bits, bits, len);
	nfct_set_attr(ct, ATTR_CONNLABELS, mask);
	return 0;
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/* returns negative on error
 * or returns remainded nlmsghdr length */
static int _unpack_nlmsg(const struct nlmsghdr *nlh,
		  const char *format, va_list ap)
{
	struct nlattr *attr = mnl_nlmsg_get_payload(nlh);
	int remains = (int)mnl_nlmsg_get_payload_len(nlh);
	size_t len;
	uint16_t atype, alen;
	void *p;

	while (*format != '\0' ) {
		if (!mnl_attr_ok(attr, remains)) {
			errno = EOVERFLOW;
			return -1;
		}

		remains -= MY_NLATTR_HDRLEN;
		atype = mnl_attr_get_type(attr);
		alen = mnl_attr_get_payload_len(attr);

		switch (*format) {
		case 'B': /* byte */
			if (atype != MNL_TYPE_U8 ||
			    alen != sizeof(uint8_t)) {
				errno =EINVAL;
				return -1;
			}
			*(va_arg(ap, uint8_t *)) = mnl_attr_get_u8(attr);
			break;
		case 'H': /* 2byte */
			if (atype != MNL_TYPE_U16 ||
			    alen != sizeof(uint16_t)) {
				errno = EINVAL;
				return -1;
			}
			*(va_arg(ap, uint16_t *)) = mnl_attr_get_u16(attr);
			break;
		case 'I': /* 4byte */
			if (atype != MNL_TYPE_U32 ||
			    alen != sizeof(uint32_t)) {
				errno = EINVAL;
				return -1;
			}
			*(va_arg(ap, uint32_t *)) = mnl_attr_get_u32(attr);
			break;
		case 'K': /* 8byte */
			if (atype  != MNL_TYPE_U64 ||
			    alen != sizeof(uint64_t)) {
				errno = EINVAL;
				return -1;
			}
			*(va_arg(ap, uint64_t *)) = mnl_attr_get_u64(attr);
			break;
		case 'p': /* pointer */
			if (atype != MNL_TYPE_BINARY ||
			    alen != sizeof(void *)) {
				errno = EINVAL;
				return -1;
			}
			*(va_arg(ap, void **))
				= *((void **)mnl_attr_get_payload(attr));
			break;
		case 'z': /* null string */
			if (atype != MNL_TYPE_NUL_STRING) {
				errno = EINVAL;
				return -1;
			}
			p = va_arg(ap, void *);
			if (*(format + 1) == '#') {
				format++;
				len = va_arg(ap, size_t);
				if (alen > len) {
					errno = EINVAL;
					return -1;
				}
			}
			strncpy(p, mnl_attr_get_payload(attr), alen);
			break;
		case 'y': /* bytes with size */
			format++;
			if (*format != '#') {
				errno = EINVAL;
				return -1;
			}
			p = va_arg(ap, void *);
			len = va_arg(ap, size_t);
			if (alen > len)
				return -EINVAL;

			memcpy(p, mnl_attr_get_payload(attr), alen);
			break;
		default:
			errno =EINVAL;
			return -1;
		}
		remains -= MY_ATTR_ALIGN(alen);
		format++;
		attr = mnl_attr_next(attr);
	}

	if (remains) {
		errno = EMSGSIZE;
		nurs_log(NURS_NOTICE, "unpack remains: %d\n", remains);
	}
	return remains;
}