Ejemplo n.º 1
0
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]));
	}
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
Archivo: mnlg.c Proyecto: dtaht/tc-adv
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;
}
Ejemplo n.º 4
0
int resolve_genladdr(const char *name, struct tcpe_client* cl)
{
	struct mnl_socket *sock = cl->mnl_sock;
	char buf[MNL_SOCKET_BUFFER_SIZE];

	struct nlmsghdr *nlh;
	struct genlmsghdr *genl;
	int ret;
	unsigned int seq, portid;
	struct nlattr *tb[CTRL_ATTR_MAX+1] = {};
        int fmly_id = 0;
        const char *mcast_grp_name;
	int mcast_grp_id = 0;
	struct nlattr *pos;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= GENL_ID_CTRL;
	nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
	nlh->nlmsg_seq = seq = time(NULL);

	genl = mnl_nlmsg_put_extra_header(nlh, sizeof(struct genlmsghdr));
	genl->cmd = CTRL_CMD_GETFAMILY;
	genl->version = 0;

	mnl_attr_put_strz(nlh, CTRL_ATTR_FAMILY_NAME, name);
	portid = mnl_socket_get_portid(sock);

	if (mnl_socket_sendto(sock, nlh, nlh->nlmsg_len) < 0) {
		dbgprintf("mnl_socket_send");
		return -1;
	}

	while (1) {
		ret = mnl_socket_recvfrom(sock, buf, sizeof(buf));
		if (ret == -1) {
			dbgprintf("mnl_socket_recvfrom");
			break;
		}
		ret = mnl_cb_run(buf, ret, seq, portid, data_cb, tb);
		if (ret == -1) {
			dbgprintf("mnl_cb_run");
			break;
		} else if (ret == 0)
			break;
	}
	if (tb[CTRL_ATTR_FAMILY_ID]) {
                fmly_id = mnl_attr_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
	}

	cl->fam_id = fmly_id;

	return 0;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
static int
nftnl_expr_queue_parse(struct nftnl_expr *e, struct nlattr *attr)
{
	struct nftnl_expr_queue *queue = nftnl_expr_data(e);
	struct nlattr *tb[NFTA_QUEUE_MAX+1] = {};

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

	if (tb[NFTA_QUEUE_NUM]) {
		queue->queuenum = ntohs(mnl_attr_get_u16(tb[NFTA_QUEUE_NUM]));
		e->flags |= (1 << NFTNL_EXPR_QUEUE_NUM);
	}
	if (tb[NFTA_QUEUE_TOTAL]) {
		queue->queues_total = ntohs(mnl_attr_get_u16(tb[NFTA_QUEUE_TOTAL]));
		e->flags |= (1 << NFTNL_EXPR_QUEUE_TOTAL);
	}
	if (tb[NFTA_QUEUE_FLAGS]) {
		queue->flags = ntohs(mnl_attr_get_u16(tb[NFTA_QUEUE_FLAGS]));
		e->flags |= (1 << NFTNL_EXPR_QUEUE_FLAGS);
	}

	return 0;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
int
nfct_payload_parse(const void *payload, size_t payload_len,
		   uint16_t l3num, struct nf_conntrack *ct)
{
	struct nlattr *tb[CTA_MAX+1] = {};

	if (mnl_attr_parse_payload(payload, payload_len,
				   nfct_parse_conntrack_attr_cb, tb) < 0)
		return -1;

	if (tb[CTA_TUPLE_ORIG]) {
		ct->head.orig.l3protonum = l3num;
		set_bit(ATTR_ORIG_L3PROTO, ct->head.set);

		if (nfct_parse_tuple(tb[CTA_TUPLE_ORIG], &ct->head.orig,
				     __DIR_ORIG, ct->head.set) < 0)
			return -1;
	}

	if (tb[CTA_TUPLE_REPLY]) {
		ct->repl.l3protonum = l3num;
		set_bit(ATTR_REPL_L3PROTO, ct->head.set);

		if (nfct_parse_tuple(tb[CTA_TUPLE_REPLY], &ct->repl,
				     __DIR_REPL, ct->head.set) < 0)
			return -1;
	}

	if (tb[CTA_TUPLE_MASTER]) {
		ct->master.l3protonum = l3num;
		set_bit(ATTR_MASTER_L3PROTO, ct->head.set);

		if (nfct_parse_tuple(tb[CTA_TUPLE_MASTER], &ct->master,
				     __DIR_MASTER, ct->head.set) < 0)
			return -1;
	}

	if (tb[CTA_NAT_SEQ_ADJ_ORIG]) {
		if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_ORIG],
					ct, __DIR_ORIG) < 0)
			return -1;
	}

	if (tb[CTA_NAT_SEQ_ADJ_REPLY]) {
		if (nfct_parse_nat_seq(tb[CTA_NAT_SEQ_ADJ_REPLY],
					ct, __DIR_REPL) < 0)
			return -1;
	}

	if (tb[CTA_STATUS]) {
		ct->status = ntohl(mnl_attr_get_u32(tb[CTA_STATUS]));
		set_bit(ATTR_STATUS, ct->head.set);
	}

	if (tb[CTA_PROTOINFO]) {
		if (nfct_parse_protoinfo(tb[CTA_PROTOINFO], ct) < 0)
			return -1;
	}

	if (tb[CTA_TIMEOUT]) {
		ct->timeout = ntohl(mnl_attr_get_u32(tb[CTA_TIMEOUT]));
		set_bit(ATTR_TIMEOUT, ct->head.set);
	}

	if (tb[CTA_MARK]) {
		ct->mark = ntohl(mnl_attr_get_u32(tb[CTA_MARK]));
		set_bit(ATTR_MARK, ct->head.set);
	}

	if (tb[CTA_SECMARK]) {
		ct->secmark = ntohl(mnl_attr_get_u32(tb[CTA_SECMARK]));
		set_bit(ATTR_SECMARK, ct->head.set);
	}

	if (tb[CTA_COUNTERS_ORIG]) {
		if (nfct_parse_counters(tb[CTA_COUNTERS_ORIG],
					ct, __DIR_ORIG) < 0)
			return -1;
	}

	if (tb[CTA_COUNTERS_REPLY]) {
		if (nfct_parse_counters(tb[CTA_COUNTERS_REPLY],
					ct, __DIR_REPL) < 0)
			return -1;
	}

	if (tb[CTA_USE]) {
		ct->use = ntohl(mnl_attr_get_u32(tb[CTA_USE]));
		set_bit(ATTR_USE, ct->head.set);
	}

	if (tb[CTA_ID]) {
		ct->id = ntohl(mnl_attr_get_u32(tb[CTA_ID]));
		set_bit(ATTR_ID, ct->head.set);
	}

	if (tb[CTA_HELP]) {
		if (nfct_parse_helper(tb[CTA_HELP], ct) < 0)
			return -1;
	}

	if (tb[CTA_ZONE]) {
		ct->zone = ntohs(mnl_attr_get_u16(tb[CTA_ZONE]));
		set_bit(ATTR_ZONE, ct->head.set);
	}

	if (tb[CTA_SECCTX]) {
		if (nfct_parse_secctx(tb[CTA_SECCTX], ct) < 0)
			return -1;
	}

	if (tb[CTA_TIMESTAMP]) {
		if (nfct_parse_timestamp(tb[CTA_TIMESTAMP], ct) < 0)
			return -1;
	}

	if (tb[CTA_LABELS]) {
		if (nfct_parse_labels(tb[CTA_LABELS], ct) < 0)
			return -1;
	}
	/* CTA_LABELS_MASK: never sent by kernel */

	return 0;
}
Ejemplo n.º 10
0
static int
nfct_parse_proto(const struct nlattr *attr, struct __nfct_tuple *tuple,
		const int dir, u_int32_t *set)
{
	struct nlattr *tb[CTA_PROTO_MAX+1] = {};

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

	if (tb[CTA_PROTO_NUM]) {
		tuple->protonum = mnl_attr_get_u8(tb[CTA_PROTO_NUM]);
		switch(dir) {
		case __DIR_ORIG:
			set_bit(ATTR_ORIG_L4PROTO, set);
			break;
		case __DIR_REPL:
			set_bit(ATTR_REPL_L4PROTO, set);
			break;
		case __DIR_MASTER:
			set_bit(ATTR_MASTER_L4PROTO, set);
			break;
		}
	}

	if (tb[CTA_PROTO_SRC_PORT]) {
		tuple->l4src.tcp.port =
			mnl_attr_get_u16(tb[CTA_PROTO_SRC_PORT]);
		switch(dir) {
		case __DIR_ORIG:
			set_bit(ATTR_ORIG_PORT_SRC, set);
			break;
		case __DIR_REPL:
			set_bit(ATTR_REPL_PORT_SRC, set);
			break;
		case __DIR_MASTER:
			set_bit(ATTR_MASTER_PORT_SRC, set);
			break;
		}
	}

	if (tb[CTA_PROTO_DST_PORT]) {
		tuple->l4dst.tcp.port =
			mnl_attr_get_u16(tb[CTA_PROTO_DST_PORT]);
		switch(dir) {
		case __DIR_ORIG:
			set_bit(ATTR_ORIG_PORT_DST, set);
			break;
		case __DIR_REPL:
			set_bit(ATTR_REPL_PORT_DST, set);
			break;
		case __DIR_MASTER:
			set_bit(ATTR_MASTER_PORT_DST, set);
			break;
		}
	}

	if (tb[CTA_PROTO_ICMP_TYPE]) {
		tuple->l4dst.icmp.type =
			mnl_attr_get_u8(tb[CTA_PROTO_ICMP_TYPE]);
		set_bit(ATTR_ICMP_TYPE, set);
	}

	if (tb[CTA_PROTO_ICMP_CODE]) {
		tuple->l4dst.icmp.code =
			mnl_attr_get_u8(tb[CTA_PROTO_ICMP_CODE]);
		set_bit(ATTR_ICMP_CODE, set);
	}

	if (tb[CTA_PROTO_ICMP_ID]) {
		tuple->l4src.icmp.id =
			mnl_attr_get_u16(tb[CTA_PROTO_ICMP_ID]);
		set_bit(ATTR_ICMP_ID, set);
	}

	if (tb[CTA_PROTO_ICMPV6_TYPE]) {
		tuple->l4dst.icmp.type =
			mnl_attr_get_u8(tb[CTA_PROTO_ICMPV6_TYPE]);
		set_bit(ATTR_ICMP_TYPE, set);
	}

	if (tb[CTA_PROTO_ICMPV6_CODE]) {
		tuple->l4dst.icmp.code =
			mnl_attr_get_u8(tb[CTA_PROTO_ICMPV6_CODE]);
		set_bit(ATTR_ICMP_CODE, set);
	}

	if (tb[CTA_PROTO_ICMPV6_ID]) {
		tuple->l4src.icmp.id =
			mnl_attr_get_u16(tb[CTA_PROTO_ICMPV6_ID]);
		set_bit(ATTR_ICMP_ID, set);
	}

	return 0;
}
Ejemplo n.º 11
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;
}