static int
nfct_build_tuple_ip(struct nlmsghdr *nlh, const struct __nfct_tuple *t)
{
	struct nlattr *nest;

	nest = mnl_attr_nest_start(nlh, CTA_TUPLE_IP);
	if (nest == NULL)
		return -1;

	switch(t->l3protonum) {
	case AF_INET:
		mnl_attr_put_u32(nlh, CTA_IP_V4_SRC, t->src.v4);
		mnl_attr_put_u32(nlh, CTA_IP_V4_DST, t->dst.v4);
		break;
	case AF_INET6:
		mnl_attr_put(nlh, CTA_IP_V6_SRC, sizeof(struct in6_addr),
				&t->src.v6);
		mnl_attr_put(nlh, CTA_IP_V6_DST, sizeof(struct in6_addr),
				&t->dst.v6);
		break;
	default:
		mnl_attr_nest_cancel(nlh, nest);
		return -1;
	}
	mnl_attr_nest_end(nlh, nest);
	return 0;
}
Exemple #2
0
static void
nft_rule_expr_bitwise_build(struct nlmsghdr *nlh, struct nft_rule_expr *e)
{
	struct nft_expr_bitwise *bitwise = nft_expr_data(e);

	if (e->flags & (1 << NFT_EXPR_BITWISE_SREG))
		mnl_attr_put_u32(nlh, NFTA_BITWISE_SREG, htonl(bitwise->sreg));
	if (e->flags & (1 << NFT_EXPR_BITWISE_DREG))
		mnl_attr_put_u32(nlh, NFTA_BITWISE_DREG, htonl(bitwise->dreg));
	if (e->flags & (1 << NFT_EXPR_BITWISE_LEN))
		mnl_attr_put_u32(nlh, NFTA_BITWISE_LEN, htonl(bitwise->len));
	if (e->flags & (1 << NFT_EXPR_BITWISE_MASK)) {
		struct nlattr *nest;

		nest = mnl_attr_nest_start(nlh, NFTA_BITWISE_MASK);
		mnl_attr_put(nlh, NFTA_DATA_VALUE, bitwise->mask.len,
				bitwise->mask.val);
		mnl_attr_nest_end(nlh, nest);
	}
	if (e->flags & (1 << NFT_EXPR_BITWISE_XOR)) {
		struct nlattr *nest;

		nest = mnl_attr_nest_start(nlh, NFTA_BITWISE_XOR);
		mnl_attr_put(nlh, NFTA_DATA_VALUE, bitwise->xor.len,
				bitwise->xor.val);
		mnl_attr_nest_end(nlh, nest);
	}
}
static void
nfct_build_labels(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
{
	struct nfct_bitmask *b = ct->connlabels;
	unsigned int size = b->words * sizeof(b->bits[0]);
	mnl_attr_put(nlh, CTA_LABELS, size, b->bits);

	if (test_bit(ATTR_CONNLABELS_MASK, ct->head.set)) {
		b = ct->connlabels_mask;
		if (size == (b->words * sizeof(b->bits[0])))
			mnl_attr_put(nlh, CTA_LABELS_MASK, size, b->bits);
	}
}
Exemple #4
0
void nfq_nlmsg_cfg_put_params(struct nlmsghdr *nlh, uint8_t mode, int range)
{
	struct nfqnl_msg_config_params params = {
		.copy_range = htonl(range),
		.copy_mode = mode,
	};
	mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), &params);
}
Exemple #5
0
/**
 * nfq_nlmsg_cfg_build_request- build netlink config message
 * \param buf Buffer where netlink message is going to be written.
 * \param cfg Structure that contains the config parameters.
 * \param command nfqueue nfnetlink command.
 *
 * This function returns a pointer to the netlink message. If something goes
 * wrong it returns NULL.
 *
 * Possible commands are:
 *
 * - NFQNL_CFG_CMD_NONE: Do nothing. It can be useful to know if the queue
 *   subsystem is working.
 * - NFQNL_CFG_CMD_BIND: Binds the program to a specific queue.
 * - NFQNL_CFG_CMD_UNBIND: Unbinds the program to a specifiq queue.
 * - NFQNL_CFG_CMD_PF_BIND: Binds to process packets belonging to the given
 *   protocol family (ie. PF_INET, PF_INET6, etc).
 * - NFQNL_CFG_CMD_PF_UNBIND: Unbinds from processing packets belonging to the
 *   given protocol family.
 */
void nfq_nlmsg_cfg_put_cmd(struct nlmsghdr *nlh, uint16_t pf, uint8_t cmd)
{
	struct nfqnl_msg_config_cmd command = {
		.command = cmd,
		.pf = htons(pf),
	};
	mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(command), &command);
}
Exemple #6
0
void nfq_nlmsg_verdict_put(struct nlmsghdr *nlh, int id, int verdict)
{
	struct nfqnl_msg_verdict_hdr vh = {
		.verdict	= htonl(verdict),
		.id		= htonl(id),
	};
	mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);
}
Exemple #7
0
/**
 * mnl_attr_put_check - add an attribute to netlink message
 * \param nlh pointer to the netlink message
 * \param buflen size of buffer which stores the message
 * \param type netlink attribute type that you want to add
 * \param len netlink attribute payload length
 * \param data pointer to the data that will be stored by the new attribute
 *
 * This function first checks that the data can be added to the message
 * (fits into the buffer) and then updates the length field of the Netlink
 * message (nlmsg_len) by adding the size (header + payload) of the new
 * attribute. The function returns true if the attribute could be added
 * to the message, otherwise false is returned.
 */
bool
mnl_attr_put_check(struct nlmsghdr *nlh, size_t buflen,
		   uint16_t type, size_t len, const void *data)
{
	if (nlh->nlmsg_len + MNL_ATTR_HDRLEN + MNL_ALIGN(len) > buflen)
		return false;
	mnl_attr_put(nlh, type, len, data);
	return true;
}
Exemple #8
0
/**
 * nflog_attr_put_cfg_cmd - add a cmd attribute to nflog netlink message
 * \param nlh pointer to the netlink message
 * \param cmd command one of the enum nfulnl_msg_config_cmds
 *
 * this function returns -1 and errno is explicitly set on error.
 *  On success, this function returns 1.
 */
int nflog_attr_put_cfg_cmd(struct nlmsghdr *nlh, uint8_t cmd)
{
	struct nfulnl_msg_config_cmd nfcmd = {
		.command = cmd
	};

	mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(nfcmd), &nfcmd);

	/* it may returns -1 in future */
	return 0;
}
Exemple #9
0
/**
 * nflog_attr_put_cfg_mode - add a mode attribute to nflog netlink message
 * \param nlh pointer to the netlink message
 * \param mode copy mode defined in linux/netfilter/nfnetlink_log.h
 * \param range copy range
 *
 * this function returns -1 and errno is explicitly set on error.
 * On success, this function returns 1.
 */
int nflog_attr_put_cfg_mode(struct nlmsghdr *nlh, uint8_t mode, uint32_t range)
{
	struct nfulnl_msg_config_mode nfmode = {
		.copy_mode = mode,
		.copy_range = htonl(range)
	};

	mnl_attr_put(nlh, NFULA_CFG_MODE, sizeof(nfmode), &nfmode);

	/* it may returns -1 in future */
	return 0;
}
Exemple #10
0
static void
nftnl_expr_target_build(struct nlmsghdr *nlh, const struct nftnl_expr *e)
{
	struct nftnl_expr_target *tg = nftnl_expr_data(e);

	if (e->flags & (1 << NFTNL_EXPR_TG_NAME))
		mnl_attr_put_strz(nlh, NFTA_TARGET_NAME, tg->name);
	if (e->flags & (1 << NFTNL_EXPR_TG_REV))
		mnl_attr_put_u32(nlh, NFTA_TARGET_REV, htonl(tg->rev));
	if (e->flags & (1 << NFTNL_EXPR_TG_INFO))
		mnl_attr_put(nlh, NFTA_TARGET_INFO, tg->data_len, tg->data);
}
Exemple #11
0
static void
nft_rule_expr_match_build(struct nlmsghdr *nlh, struct nft_rule_expr *e)
{
	struct nft_expr_match *mt = nft_expr_data(e);

	if (e->flags & (1 << NFT_EXPR_MT_NAME))
		mnl_attr_put_strz(nlh, NFTA_MATCH_NAME, mt->name);
	if (e->flags & (1 << NFT_EXPR_MT_REV))
		mnl_attr_put_u32(nlh, NFTA_MATCH_REV, htonl(mt->rev));
	if (e->flags & (1 << NFT_EXPR_MT_INFO))
		mnl_attr_put(nlh, NFTA_MATCH_INFO, mt->data_len, mt->data);
}
static int
nfct_build_helper_name(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
{
	struct nlattr *nest;

	nest = mnl_attr_nest_start(nlh, CTA_HELP);
	mnl_attr_put_strz(nlh, CTA_HELP_NAME, ct->helper_name);

	if (ct->helper_info != NULL) {
		mnl_attr_put(nlh, CTA_HELP_INFO, ct->helper_info_len,
				ct->helper_info);
	}
	mnl_attr_nest_end(nlh, nest);
	return 0;
}
Exemple #13
0
    static struct nlmsghdr *
nflog_build_cfg_pf_request(char *buf, uint8_t command)
{
    struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
    nlh->nlmsg_type	= (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_CONFIG;
    nlh->nlmsg_flags = NLM_F_REQUEST;

    struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
    nfg->nfgen_family = AF_INET;
    nfg->version = NFNETLINK_V0;

    struct nfulnl_msg_config_cmd cmd = {
        .command = command,
    };
    mnl_attr_put(nlh, NFULA_CFG_CMD, sizeof(cmd), &cmd);

    return nlh;
}
Exemple #14
0
static struct nlmsghdr *
nfq_build_cfg_request(char *buf, uint8_t command, int queue_num)
{
	struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
	nlh->nlmsg_flags = NLM_F_REQUEST;

	struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_UNSPEC;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(queue_num);

	struct nfqnl_msg_config_cmd cmd = {
		.command = command,
		.pf = htons(AF_INET),
	};
	mnl_attr_put(nlh, NFQA_CFG_CMD, sizeof(cmd), &cmd);

	return nlh;
}
Exemple #15
0
static struct nlmsghdr *
nfq_build_cfg_params(char *buf, uint8_t mode, int range, int queue_num)
{
	struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type	= (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_CONFIG;
	nlh->nlmsg_flags = NLM_F_REQUEST;

	struct nfgenmsg *nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_UNSPEC;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(queue_num);

	struct nfqnl_msg_config_params params = {
		.copy_range = htonl(range),
		.copy_mode = mode,
	};
	mnl_attr_put(nlh, NFQA_CFG_PARAMS, sizeof(params), &params);

	return nlh;
}
Exemple #16
0
static struct nlmsghdr *
nfq_build_verdict(char *buf, int id, int queue_num, int verd)
{
	struct nlmsghdr *nlh;
	struct nfgenmsg *nfg;

	nlh = mnl_nlmsg_put_header(buf);
	nlh->nlmsg_type = (NFNL_SUBSYS_QUEUE << 8) | NFQNL_MSG_VERDICT;
	nlh->nlmsg_flags = NLM_F_REQUEST;
	nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
	nfg->nfgen_family = AF_UNSPEC;
	nfg->version = NFNETLINK_V0;
	nfg->res_id = htons(queue_num);

	struct nfqnl_msg_verdict_hdr vh = {
		.verdict = htonl(verd),
		.id = htonl(id),
	};
	mnl_attr_put(nlh, NFQA_VERDICT_HDR, sizeof(vh), &vh);

	return nlh;
}
Exemple #17
0
/**
 * mnl_attr_put_u32 - add 32-bit unsigned integer attribute to netlink message
 * \param nlh pointer to the netlink message
 * \param type netlink attribute type
 * \param data 32-bit unsigned integer data that is stored by the new attribute
 *
 * This function updates the length field of the Netlink message (nlmsg_len)
 * by adding the size (header + payload) of the new attribute.
 */
EXPORT_SYMBOL void
mnl_attr_put_u32(struct nlmsghdr *nlh, uint16_t type, uint32_t data)
{
	mnl_attr_put(nlh, type, sizeof(uint32_t), &data);
}
Exemple #18
0
static struct nlmsghdr *pack_nlmsg(void *buf, int len, const char *format, va_list ap)
{
	struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf);
	void *p;
	char *s;
	size_t slen;
	int remains;

	while (*format != '\0') {
		remains = len - (int)nlh->nlmsg_len
			- MY_ATTR_ALIGN(sizeof(struct nlattr));
		switch (*format) {
		case 'B': /* byte */
			if (MY_ATTR_ALIGN(sizeof(uint8_t)) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			/* gcc warning: 'uint8_t' is promoted
			 * to 'int' when passed through '...' */
			mnl_attr_put_u8(nlh, MNL_TYPE_U8,
					(uint8_t)va_arg(ap, int));
			break;
		case 'H': /* 2byte */
			if (MY_ATTR_ALIGN(sizeof(uint16_t)) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			/* gcc warning: 'uint16_t' is promoted
			 * to 'int' when passed through '...' */
			mnl_attr_put_u16(nlh, MNL_TYPE_U16,
					 (uint16_t)va_arg(ap, int));
			break;
		case 'I': /* 4byte */
			if (MY_ATTR_ALIGN(sizeof(uint32_t)) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			mnl_attr_put_u32(nlh, MNL_TYPE_U32,
					 va_arg(ap, uint32_t));
			break;
		case 'K': /* 8byte */
			if (MY_ATTR_ALIGN(sizeof(uint64_t)) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			mnl_attr_put_u64(nlh, MNL_TYPE_U64,
					 va_arg(ap, uint64_t));
			break;
		case 'p': /* pointer */
			if (MY_ATTR_ALIGN(sizeof(void *)) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			p = va_arg(ap, void *);
			mnl_attr_put(nlh, MNL_TYPE_BINARY, sizeof(void *), &p);
			break;
		case 'z': /* null string */
			s = va_arg(ap, char *);
			slen = strlen(s);
			if (MY_ATTR_ALIGN(slen + 1) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			mnl_attr_put(nlh, MNL_TYPE_NUL_STRING, slen + 1, s);
			break;
		case 'y': /* bytes with size */
			format++;
			if (*format != '#') {
				errno = EINVAL;
				return NULL;
			}
			p = va_arg(ap, void *);
			slen = va_arg(ap, size_t);
			if (MY_ATTR_ALIGN(slen) > remains) {
				errno = EOVERFLOW;
				return NULL;
			}

			mnl_attr_put(nlh, MNL_TYPE_STRING, slen, p);
			break;
		default:
			errno = EINVAL;
			return NULL;

		}
		format++;
	}

	return nlh;
}
Exemple #19
0
/**
 * mnl_attr_put_str - add string attribute to netlink message
 * \param nlh  pointer to the netlink message
 * \param type netlink attribute type
 * \param data pointer to string data that is stored by the new attribute
 *
 * This function updates the length field of the Netlink message (nlmsg_len)
 * by adding the size (header + payload) of the new attribute.
 */
EXPORT_SYMBOL void
mnl_attr_put_str(struct nlmsghdr *nlh, uint16_t type, const char *data)
{
	mnl_attr_put(nlh, type, strlen(data), data);
}
Exemple #20
0
void
nfq_nlmsg_verdict_put_pkt(struct nlmsghdr *nlh, const void *pkt, uint32_t plen)
{
	mnl_attr_put(nlh, NFQA_PAYLOAD, plen, pkt);
}
static int
nfct_build_protoinfo(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
{
	struct nlattr *nest, *nest_proto;

	switch(ct->head.orig.protonum) {
	case IPPROTO_TCP:
		/* Preliminary attribute check to avoid sending an empty
		 * CTA_PROTOINFO_TCP nest, which results in EINVAL in
		 * Linux kernel <= 2.6.25. */
		if (!(test_bit(ATTR_TCP_STATE, ct->head.set) ||
		      test_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set) ||
		      test_bit(ATTR_TCP_FLAGS_REPL, ct->head.set) ||
		      test_bit(ATTR_TCP_MASK_ORIG, ct->head.set) ||
		      test_bit(ATTR_TCP_MASK_REPL, ct->head.set) ||
		      test_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set) ||
		      test_bit(ATTR_TCP_WSCALE_REPL, ct->head.set))) {
			break;
		}
		nest = mnl_attr_nest_start(nlh, CTA_PROTOINFO);
		nest_proto = mnl_attr_nest_start(nlh, CTA_PROTOINFO_TCP);
		if (test_bit(ATTR_TCP_STATE, ct->head.set)) {
			mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_STATE,
					ct->protoinfo.tcp.state);
		}
		if (test_bit(ATTR_TCP_FLAGS_ORIG, ct->head.set) &&
		    test_bit(ATTR_TCP_MASK_ORIG, ct->head.set)) {
			mnl_attr_put(nlh, CTA_PROTOINFO_TCP_FLAGS_ORIGINAL,
				     sizeof(struct nf_ct_tcp_flags),
				     &ct->protoinfo.tcp.flags[0]);
		}
		if (test_bit(ATTR_TCP_FLAGS_REPL, ct->head.set) &&
		    test_bit(ATTR_TCP_MASK_REPL, ct->head.set)) {
			mnl_attr_put(nlh, CTA_PROTOINFO_TCP_FLAGS_REPLY,
				     sizeof(struct nf_ct_tcp_flags),
				     &ct->protoinfo.tcp.flags[1]);
		}
		if (test_bit(ATTR_TCP_WSCALE_ORIG, ct->head.set)) {
			mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_WSCALE_ORIGINAL,
					ct->protoinfo.tcp.wscale[__DIR_ORIG]);
		}
		if (test_bit(ATTR_TCP_WSCALE_REPL, ct->head.set)) {
			mnl_attr_put_u8(nlh, CTA_PROTOINFO_TCP_WSCALE_REPLY,
					ct->protoinfo.tcp.wscale[__DIR_REPL]);
		}
		mnl_attr_nest_end(nlh, nest_proto);
		mnl_attr_nest_end(nlh, nest);
		break;
	case IPPROTO_SCTP:
		/* See comment above on TCP. */
		if (!(test_bit(ATTR_SCTP_STATE, ct->head.set) ||
		      test_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set) ||
		      test_bit(ATTR_SCTP_VTAG_REPL, ct->head.set))) {
			break;
		}
		nest = mnl_attr_nest_start(nlh, CTA_PROTOINFO);
		nest_proto = mnl_attr_nest_start(nlh, CTA_PROTOINFO_SCTP);

		if (test_bit(ATTR_SCTP_STATE, ct->head.set)) {
			mnl_attr_put_u8(nlh, CTA_PROTOINFO_SCTP_STATE,
					ct->protoinfo.sctp.state);
		}
		if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->head.set)) {
			mnl_attr_put_u32(nlh, CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
				htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG]));
		}
		if (test_bit(ATTR_SCTP_VTAG_REPL, ct->head.set)) {
			mnl_attr_put_u32(nlh, CTA_PROTOINFO_SCTP_VTAG_REPLY,
				htonl(ct->protoinfo.sctp.vtag[__DIR_REPL]));
		}
		mnl_attr_nest_end(nlh, nest_proto);
		mnl_attr_nest_end(nlh, nest);
		break;
	case IPPROTO_DCCP:
		/* See comment above on TCP. */
		if (!(test_bit(ATTR_DCCP_STATE, ct->head.set) ||
		      test_bit(ATTR_DCCP_ROLE, ct->head.set) ||
		      test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set))) {
			break;
		}
		nest = mnl_attr_nest_start(nlh, CTA_PROTOINFO);
		nest_proto = mnl_attr_nest_start(nlh, CTA_PROTOINFO_DCCP);
		if (test_bit(ATTR_DCCP_STATE, ct->head.set)) {
			mnl_attr_put_u8(nlh, CTA_PROTOINFO_DCCP_STATE,
					ct->protoinfo.dccp.state);
		}
		if (test_bit(ATTR_DCCP_ROLE, ct->head.set)) {
			mnl_attr_put_u8(nlh, CTA_PROTOINFO_DCCP_ROLE,
					ct->protoinfo.dccp.role);
		}
		if (test_bit(ATTR_DCCP_HANDSHAKE_SEQ, ct->head.set)) {
			uint64_t handshake_seq =
				be64toh(ct->protoinfo.dccp.handshake_seq);

			mnl_attr_put_u64(nlh, CTA_PROTOINFO_DCCP_HANDSHAKE_SEQ,
					 handshake_seq);
		}
		mnl_attr_nest_end(nlh, nest_proto);
		mnl_attr_nest_end(nlh, nest);
	default:
		break;
	}
	return 0;
}
Exemple #22
0
/**
 * mnl_attr_put_u64 - add 64-bit unsigned integer attribute to netlink message
 * \param nlh pointer to the netlink message
 * \param type netlink attribute type
 * \param data 64-bit unsigned integer data that is stored by the new attribute
 *
 * This function updates the length field of the Netlink message (nlmsg_len)
 * by adding the size (header + payload) of the new attribute.
 */
void mnl_attr_put_u64(struct nlmsghdr *nlh, uint16_t type, uint64_t data)
{
	mnl_attr_put(nlh, type, sizeof(uint64_t), &data);
}
Exemple #23
0
/**
 * mnl_attr_put_strz - add string attribute to netlink message
 * \param nlh pointer to the netlink message
 * \param type netlink attribute type
 * \param data pointer to string data that is stored by the new attribute
 *
 * This function is similar to mnl_attr_put_str, but it includes the
 * NUL/zero ('\0') terminator at the end of the string.
 *
 * This function updates the length field of the Netlink message (nlmsg_len)
 * by adding the size (header + payload) of the new attribute.
 */
void mnl_attr_put_strz(struct nlmsghdr *nlh, uint16_t type, const char *data)
{
	mnl_attr_put(nlh, type, strlen(data)+1, data);
}