summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/libnetfilter_cthelper/libnetfilter_cthelper.h31
-rw-r--r--include/linux/netfilter/nfnetlink_cthelper.h4
-rw-r--r--src/libnetfilter_cthelper.c336
-rw-r--r--src/libnetfilter_cthelper.map6
4 files changed, 297 insertions, 80 deletions
diff --git a/include/libnetfilter_cthelper/libnetfilter_cthelper.h b/include/libnetfilter_cthelper/libnetfilter_cthelper.h
index d0fcfa7..1b34e44 100644
--- a/include/libnetfilter_cthelper/libnetfilter_cthelper.h
+++ b/include/libnetfilter_cthelper/libnetfilter_cthelper.h
@@ -4,21 +4,40 @@
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_cthelper.h>
-struct nfct_helper;
+struct nfct_helper_policy;
+
+enum nfct_helper_policy_attr_type {
+ NFCTH_ATTR_POLICY_NAME = 0,
+ NFCTH_ATTR_POLICY_TIMEOUT,
+ NFCTH_ATTR_POLICY_MAX,
+};
+
+struct nfct_helper_policy *nfct_helper_policy_alloc(void);
+void nfct_helper_policy_free(struct nfct_helper_policy *p);
+
+void nfct_helper_policy_attr_set(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const void *data);
+void nfct_helper_policy_attr_set_str(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, const char *name);
+void nfct_helper_policy_attr_set_u32(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type, uint32_t value);
+void nfct_helper_policy_attr_unset(struct nfct_helper_policy *p, enum nfct_helper_policy_attr_type type);
enum nfct_helper_attr_type {
NFCTH_ATTR_NAME = 0,
NFCTH_ATTR_QUEUE_NUM,
NFCTH_ATTR_PROTO_L3NUM,
NFCTH_ATTR_PROTO_L4NUM,
- NFCTH_ATTR_EXP_POLICY_NAME,
- NFCTH_ATTR_EXP_POLICY_TIMEOUT,
- NFCTH_ATTR_EXP_POLICY_MAX,
NFCTH_ATTR_PRIV_DATA_LEN,
+ NFCTH_ATTR_POLICY,
+ NFCTH_ATTR_POLICY1 = NFCTH_ATTR_POLICY,
+ NFCTH_ATTR_POLICY2,
+ NFCTH_ATTR_POLICY3,
+ NFCTH_ATTR_POLICY4,
+ NFCTH_ATTR_STATUS,
};
+struct nfct_helper;
+
struct nfct_helper *nfct_helper_alloc(void);
-void nfct_helper_free(struct nfct_helper *nfct_helper);
+void nfct_helper_free(struct nfct_helper *h);
void nfct_helper_attr_set(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type, const void *data);
void nfct_helper_attr_set_str(struct nfct_helper *nfct_helper, enum nfct_helper_attr_type type, const char *name);
@@ -39,6 +58,6 @@ struct nlmsghdr *nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd, uint16_t fl
void nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *nfct_helper);
int nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh, struct nfct_helper *nfct_helper);
-int nfct_helper_snprintf(char *buf, size_t size, struct nfct_helper *nfct_helper, unsigned int flags);
+int nfct_helper_snprintf(char *buf, size_t size, struct nfct_helper *nfct_helper, unsigned int type, unsigned int flags);
#endif
diff --git a/include/linux/netfilter/nfnetlink_cthelper.h b/include/linux/netfilter/nfnetlink_cthelper.h
index 4676922..33659f6 100644
--- a/include/linux/netfilter/nfnetlink_cthelper.h
+++ b/include/linux/netfilter/nfnetlink_cthelper.h
@@ -1,6 +1,9 @@
#ifndef _NFNL_CTHELPER_H_
#define _NFNL_CTHELPER_H_
+#define NFCT_HELPER_STATUS_DISABLED 0
+#define NFCT_HELPER_STATUS_ENABLED 1
+
enum nfnl_acct_msg_types {
NFNL_MSG_CTHELPER_NEW,
NFNL_MSG_CTHELPER_GET,
@@ -15,6 +18,7 @@ enum nfnl_cthelper_type {
NFCTH_QUEUE_NUM,
NFCTH_POLICY,
NFCTH_PRIV_DATA_LEN,
+ NFCTH_STATUS,
__NFCTH_MAX
};
#define NFCTH_MAX (__NFCTH_MAX - 1)
diff --git a/src/libnetfilter_cthelper.c b/src/libnetfilter_cthelper.c
index 51f6cea..5f01fe4 100644
--- a/src/libnetfilter_cthelper.c
+++ b/src/libnetfilter_cthelper.c
@@ -1,11 +1,12 @@
/*
* (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
- * (C) 2012 by Vyatta Inc. <http://www.vyatta.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
+ *
+ * This code has been sponsored by Vyatta Inc. <http://www.vyatta.com>
*/
#include "internal.h"
@@ -64,21 +65,25 @@
#define NF_CT_HELPER_CLASS_MAX 4
#endif
+struct nfct_helper_policy {
+ char name[NF_CT_HELPER_NAME_MAX];
+ uint32_t expect_timeout;
+ uint32_t expect_max;
+ uint32_t bitset;
+};
+
struct nfct_helper {
char name[NF_CT_HELPER_NAME_MAX];
uint32_t priv_data_len;
uint32_t queue_num;
- uint32_t policy_num;
+ uint32_t status;
struct {
uint16_t l3num;
uint8_t l4num;
uint16_t port;
} tuple;
- struct {
- char name[NF_CT_HELPER_NAME_MAX];
- uint32_t expect_timeout;
- uint32_t expect_max;
- } expect_policy[NF_CT_HELPER_CLASS_MAX];
+ struct nfct_helper_policy *expect_policy[NF_CT_HELPER_CLASS_MAX];
+ uint32_t policy_num;
uint32_t bitset;
};
@@ -104,58 +109,144 @@ EXPORT_SYMBOL(nfct_helper_alloc);
* nfct_helper_free - release one helper object
* \param nfct_helper pointer to the helper object
*/
-void nfct_helper_free(struct nfct_helper *nfct_helper)
+void nfct_helper_free(struct nfct_helper *h)
{
- free(nfct_helper);
+ int i;
+
+ free(h);
+ for (i=0; i<NF_CT_HELPER_CLASS_MAX; i++) {
+ if (h->expect_policy[i])
+ free(h->expect_policy[i]);
+ }
}
EXPORT_SYMBOL(nfct_helper_free);
/**
+ * nfct_helper_policy_alloc - allocate a new helper policy object
+ *
+ * In case of success, this function returns a valid pointer, otherwise NULL
+ * s returned and errno is appropriately set.
+ */
+struct nfct_helper_policy *nfct_helper_policy_alloc(void)
+{
+ return calloc(1, sizeof(struct nfct_helper_policy));
+}
+EXPORT_SYMBOL(nfct_helper_policy_alloc);
+
+/**
+ * nfct_helper_free - release one helper policy object
+ * \param nfct_helper pointer to the helper object
+ */
+void nfct_helper_policy_free(struct nfct_helper_policy *p)
+{
+ free(p);
+}
+EXPORT_SYMBOL(nfct_helper_policy_free);
+
+/**
+ * nfct_helper_policy_attr_set - set one attribute of the helper object
+ * \param nfct_helper pointer to the helper object
+ * \param type attribute type you want to set
+ * \param data pointer to data that will be used to set this attribute
+ */
+void
+nfct_helper_policy_attr_set(struct nfct_helper_policy *p,
+ enum nfct_helper_policy_attr_type type,
+ const void *data)
+{
+ switch(type) {
+ case NFCTH_ATTR_POLICY_NAME:
+ strncpy(p->name, data, NF_CT_HELPER_NAME_MAX);
+ p->name[NF_CT_HELPER_NAME_MAX-1] = '\0';
+ p->bitset |= (1 << NFCTH_ATTR_POLICY_NAME);
+ break;
+ case NFCTH_ATTR_POLICY_TIMEOUT:
+ p->expect_timeout = *((uint32_t *) data);
+ p->bitset |= (1 << NFCTH_ATTR_POLICY_TIMEOUT);
+ break;
+ case NFCTH_ATTR_POLICY_MAX:
+ p->expect_max = *((uint32_t *) data);
+ p->bitset |= (1 << NFCTH_ATTR_POLICY_MAX);
+ break;
+ }
+}
+EXPORT_SYMBOL(nfct_helper_policy_attr_set);
+
+/**
+ * nfct_helper_attr_set_str - set one attribute the helper object
+ * \param nfct_helper pointer to the helper object
+ * \param type attribute type you want to set
+ * \param name string that will be used to set this attribute
+ */
+void
+nfct_helper_policy_attr_set_str(struct nfct_helper_policy *p,
+ enum nfct_helper_policy_attr_type type,
+ const char *name)
+{
+ nfct_helper_policy_attr_set(p, type, name);
+}
+EXPORT_SYMBOL(nfct_helper_policy_attr_set_str);
+
+void
+nfct_helper_policy_attr_set_u32(struct nfct_helper_policy *p,
+ enum nfct_helper_policy_attr_type type,
+ uint32_t value)
+{
+ nfct_helper_policy_attr_set(p, type, &value);
+}
+EXPORT_SYMBOL(nfct_helper_policy_attr_set_u32);
+
+/**
* nfct_helper_attr_set - set one attribute of the helper object
* \param nfct_helper pointer to the helper object
* \param type attribute type you want to set
* \param data pointer to data that will be used to set this attribute
*/
void
-nfct_helper_attr_set(struct nfct_helper *nfct_helper,
+nfct_helper_attr_set(struct nfct_helper *h,
enum nfct_helper_attr_type type, const void *data)
{
switch(type) {
case NFCTH_ATTR_NAME:
- strncpy(nfct_helper->name, data, NF_CT_HELPER_NAME_MAX);
- nfct_helper->name[NF_CT_HELPER_NAME_MAX-1] = '\0';
- nfct_helper->bitset |= (1 << NFCTH_ATTR_NAME);
+ strncpy(h->name, data, NF_CT_HELPER_NAME_MAX);
+ h->name[NF_CT_HELPER_NAME_MAX-1] = '\0';
+ h->bitset |= (1 << NFCTH_ATTR_NAME);
+ break;
+ case NFCTH_ATTR_QUEUE_NUM:
+ h->queue_num = *((uint32_t *) data);
+ h->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
break;
case NFCTH_ATTR_PROTO_L3NUM:
- nfct_helper->tuple.l3num = *((uint16_t *) data);
- nfct_helper->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
+ h->tuple.l3num = *((uint16_t *) data);
+ h->bitset |= (1 << NFCTH_ATTR_PROTO_L3NUM);
break;
case NFCTH_ATTR_PROTO_L4NUM:
- nfct_helper->tuple.l4num = *((uint8_t *) data);
- nfct_helper->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
+ h->tuple.l4num = *((uint8_t *) data);
+ h->bitset |= (1 << NFCTH_ATTR_PROTO_L4NUM);
break;
- case NFCTH_ATTR_QUEUE_NUM:
- nfct_helper->queue_num = *((uint32_t *) data);
- nfct_helper->bitset |= (1 << NFCTH_ATTR_QUEUE_NUM);
+ case NFCTH_ATTR_PRIV_DATA_LEN:
+ h->priv_data_len = *((uint32_t *) data);
+ h->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
break;
- case NFCTH_ATTR_EXP_POLICY_NAME:
- strncpy(nfct_helper->expect_policy[0].name,
- data, NF_CT_HELPER_NAME_MAX);
- nfct_helper->expect_policy[0].name[NF_CT_HELPER_NAME_MAX-1] = '\0';
- nfct_helper->bitset |= (1 << NFCTH_ATTR_EXP_POLICY_NAME);
+ case NFCTH_ATTR_POLICY1:
+ h->expect_policy[0] = (struct nfct_helper_policy *)data;
+ h->bitset |= (1 << NFCTH_ATTR_POLICY1);
break;
- case NFCTH_ATTR_EXP_POLICY_TIMEOUT:
- nfct_helper->expect_policy[0].expect_timeout =
- *((uint32_t *) data);
- nfct_helper->bitset |= (1 << NFCTH_ATTR_EXP_POLICY_TIMEOUT);
+ case NFCTH_ATTR_POLICY2:
+ h->expect_policy[1] = (struct nfct_helper_policy *)data;
+ h->bitset |= (1 << NFCTH_ATTR_POLICY2);
break;
- case NFCTH_ATTR_EXP_POLICY_MAX:
- nfct_helper->expect_policy[0].expect_max = *((uint32_t *) data);
- nfct_helper->bitset |= (1 << NFCTH_ATTR_EXP_POLICY_MAX);
+ case NFCTH_ATTR_POLICY3:
+ h->expect_policy[2] = (struct nfct_helper_policy *)data;
+ h->bitset |= (1 << NFCTH_ATTR_POLICY3);
break;
- case NFCTH_ATTR_PRIV_DATA_LEN:
- nfct_helper->priv_data_len = *((uint32_t *) data);
- nfct_helper->bitset |= (1 << NFCTH_ATTR_PRIV_DATA_LEN);
+ case NFCTH_ATTR_POLICY4:
+ h->expect_policy[3] = (struct nfct_helper_policy *)data;
+ h->bitset |= (1 << NFCTH_ATTR_POLICY4);
+ break;
+ case NFCTH_ATTR_STATUS:
+ h->status = *((uint32_t *) data);
+ h->bitset |= (1 << NFCTH_ATTR_STATUS);
break;
}
}
@@ -244,10 +335,26 @@ const void *nfct_helper_attr_get(struct nfct_helper *helper,
case NFCTH_ATTR_PROTO_L4NUM:
ret = &helper->tuple.l4num;
break;
- default:
- printf("boom\n");
- exit(EXIT_FAILURE);
+ case NFCTH_ATTR_PRIV_DATA_LEN:
+ ret = &helper->priv_data_len;
+ break;
+ case NFCTH_ATTR_POLICY1:
+ ret = helper->expect_policy[0];
break;
+ case NFCTH_ATTR_POLICY2:
+ ret = helper->expect_policy[1];
+ break;
+ case NFCTH_ATTR_POLICY3:
+ ret = helper->expect_policy[2];
+ break;
+ case NFCTH_ATTR_POLICY4:
+ ret = helper->expect_policy[3];
+ break;
+ case NFCTH_ATTR_STATUS:
+ ret = &helper->status;
+ break;
+ default:
+ ret = NULL;
}
return ret;
}
@@ -325,16 +432,25 @@ EXPORT_SYMBOL(nfct_helper_attr_get_u32);
* missing. On sucess, it returns 0.
*/
int nfct_helper_snprintf(char *buf, size_t size,
- struct nfct_helper *helper, unsigned int flags)
+ struct nfct_helper *helper,
+ unsigned int type, unsigned int flags)
{
int ret;
- ret = snprintf(buf, size, "{ name = %s, queuenum = %u,"
- " l3protonum = %u, l4protonum = %u };",
+ ret = snprintf(buf, size, "{\n"
+ "\t.name = %s,\n"
+ "\t.queuenum = %u,\n"
+ "\t.l3protonum = %u,\n"
+ "\t.l4protonum = %u,\n"
+ "\t.priv_data_len = %u,\n"
+ "\t.status = %s,\n};",
nfct_helper_attr_get_str(helper, NFCTH_ATTR_NAME),
nfct_helper_attr_get_u32(helper, NFCTH_ATTR_QUEUE_NUM),
nfct_helper_attr_get_u16(helper, NFCTH_ATTR_PROTO_L3NUM),
- nfct_helper_attr_get_u8(helper, NFCTH_ATTR_PROTO_L4NUM));
+ nfct_helper_attr_get_u8(helper, NFCTH_ATTR_PROTO_L4NUM),
+ nfct_helper_attr_get_u32(helper, NFCTH_ATTR_PRIV_DATA_LEN),
+ nfct_helper_attr_get_u32(helper, NFCTH_ATTR_STATUS) ?
+ "enabled" : "disabled");
return ret;
}
@@ -395,38 +511,87 @@ nfct_helper_nlmsg_build_hdr(char *buf, uint8_t cmd,
}
EXPORT_SYMBOL(nfct_helper_nlmsg_build_hdr);
+static void
+nfct_helper_nlmsg_build_policy(struct nlmsghdr *nlh,
+ struct nfct_helper_policy *p)
+{
+ struct nlattr *nest;
+
+ nest = mnl_attr_nest_start(nlh, NFCTH_POLICY_SET);
+ mnl_attr_put_strz(nlh, NFCTH_POLICY_NAME, p->name);
+ mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_MAX, htonl(p->expect_max));
+ mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_TIMEOUT,
+ htonl(p->expect_timeout));
+ mnl_attr_nest_end(nlh, nest);
+}
+
/**
* nfct_helper_nlmsg_build_payload - build payload from helper object
* \param nlh: netlink message that you want to use to add the payload.
* \param nfct_helper: pointer to a helper object
*/
-void nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh,
- struct nfct_helper *nfct_helper)
+void
+nfct_helper_nlmsg_build_payload(struct nlmsghdr *nlh, struct nfct_helper *h)
{
- struct nlattr *nest, *nest2;
+ struct nlattr *nest;
- mnl_attr_put_strz(nlh, NFCTH_NAME, nfct_helper->name);
- mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(nfct_helper->queue_num));
- mnl_attr_put_u32(nlh, NFCTH_PRIV_DATA_LEN,
- htonl(nfct_helper->priv_data_len));
- nest = mnl_attr_nest_start(nlh, NFCTH_TUPLE);
- mnl_attr_put_u16(nlh, NFCTH_TUPLE_L3PROTONUM, nfct_helper->tuple.l3num);
- mnl_attr_put_u8(nlh, NFCTH_TUPLE_L4PROTONUM, nfct_helper->tuple.l4num);
- mnl_attr_nest_end(nlh, nest);
+ if (h->bitset & (1 << NFCTH_ATTR_NAME))
+ mnl_attr_put_strz(nlh, NFCTH_NAME, h->name);
- nest = mnl_attr_nest_start(nlh, NFCTH_POLICY);
- mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM, htonl(1));
+ if (h->bitset & (1 << NFCTH_ATTR_QUEUE_NUM))
+ mnl_attr_put_u32(nlh, NFCTH_QUEUE_NUM, htonl(h->queue_num));
- nest2 = mnl_attr_nest_start(nlh, NFCTH_POLICY_SET);
- mnl_attr_put_strz(nlh, NFCTH_POLICY_NAME,
- nfct_helper->expect_policy[0].name);
- mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_MAX,
- htonl(nfct_helper->expect_policy[0].expect_max));
- mnl_attr_put_u32(nlh, NFCTH_POLICY_EXPECT_TIMEOUT,
- htonl(nfct_helper->expect_policy[0].expect_timeout));
- mnl_attr_nest_end(nlh, nest2);
- mnl_attr_nest_end(nlh, nest);
+ if (h->bitset & (1 << NFCTH_ATTR_PRIV_DATA_LEN)) {
+ mnl_attr_put_u32(nlh, NFCTH_PRIV_DATA_LEN,
+ htonl(h->priv_data_len));
+ }
+
+ if (h->bitset & (1 << NFCTH_ATTR_PROTO_L3NUM) ||
+ h->bitset & (1 << NFCTH_ATTR_PROTO_L4NUM)) {
+ nest = mnl_attr_nest_start(nlh, NFCTH_TUPLE);
+ mnl_attr_put_u16(nlh, NFCTH_TUPLE_L3PROTONUM,
+ htons(h->tuple.l3num));
+ mnl_attr_put_u8(nlh, NFCTH_TUPLE_L4PROTONUM, h->tuple.l4num);
+ mnl_attr_nest_end(nlh, nest);
+ }
+
+ if (h->bitset & (1 << NFCTH_ATTR_POLICY1) ||
+ h->bitset & (1 << NFCTH_ATTR_POLICY2) ||
+ h->bitset & (1 << NFCTH_ATTR_POLICY3) ||
+ h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
+ nest = mnl_attr_nest_start(nlh, NFCTH_POLICY);
+ int policy_set_num = 0;
+
+ if (h->bitset & (1 << NFCTH_ATTR_POLICY1)) {
+ nfct_helper_nlmsg_build_policy(nlh,
+ h->expect_policy[0]);
+ policy_set_num++;
+ }
+ if (h->bitset & (1 << NFCTH_ATTR_POLICY2)) {
+ nfct_helper_nlmsg_build_policy(nlh,
+ h->expect_policy[1]);
+ policy_set_num++;
+ }
+ if (h->bitset & (1 << NFCTH_ATTR_POLICY3)) {
+ nfct_helper_nlmsg_build_policy(nlh,
+ h->expect_policy[2]);
+ policy_set_num++;
+ }
+ if (h->bitset & (1 << NFCTH_ATTR_POLICY4)) {
+ nfct_helper_nlmsg_build_policy(nlh,
+ h->expect_policy[3]);
+ policy_set_num++;
+ }
+
+ mnl_attr_put_u32(nlh, NFCTH_POLICY_SET_NUM,
+ htonl(policy_set_num));
+
+ mnl_attr_nest_end(nlh, nest);
+ }
+
+ if (h->bitset & (1 << NFCTH_ATTR_STATUS))
+ mnl_attr_put_u32(nlh, NFCTH_STATUS, ntohl(h->status));
}
EXPORT_SYMBOL(nfct_helper_nlmsg_build_payload);
@@ -540,20 +705,27 @@ nfct_helper_nlmsg_parse_policy(const struct nlattr *attr,
struct nfct_helper *helper)
{
struct nlattr *tb[NFCTH_POLICY_MAX+1] = {};
+ struct nfct_helper_policy *p;
+
+ p = nfct_helper_policy_alloc();
+ if (p == NULL)
+ return;
mnl_attr_parse_nested(attr, nfct_helper_nlmsg_parse_policy_cb, tb);
if (tb[NFCTH_POLICY_NAME]) {
- nfct_helper_attr_set_str(helper, NFCTH_ATTR_EXP_POLICY_NAME,
+ nfct_helper_policy_attr_set_str(p, NFCTH_ATTR_POLICY_NAME,
mnl_attr_get_str(tb[NFCTH_POLICY_NAME]));
}
if (tb[NFCTH_POLICY_EXPECT_MAX]) {
- nfct_helper_attr_set_u32(helper, NFCTH_ATTR_EXP_POLICY_MAX,
+ nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_MAX,
ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_MAX])));
}
if (tb[NFCTH_POLICY_EXPECT_TIMEOUT]) {
- nfct_helper_attr_set_u32(helper, NFCTH_ATTR_EXP_POLICY_TIMEOUT,
+ nfct_helper_policy_attr_set_u32(p, NFCTH_ATTR_POLICY_TIMEOUT,
ntohl(mnl_attr_get_u32(tb[NFCTH_POLICY_EXPECT_TIMEOUT])));
}
+
+ helper->expect_policy[helper->policy_num++] = p;
}
static void
@@ -576,7 +748,8 @@ nfct_helper_nlmsg_parse_policy_set(const struct nlattr *attr,
}
}
-static int nfct_helper_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data)
+static int
+nfct_helper_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data)
{
const struct nlattr **tb = data;
int type = mnl_attr_get_type(attr);
@@ -624,24 +797,39 @@ static int nfct_helper_nlmsg_parse_attr_cb(const struct nlattr *attr, void *data
*/
int
nfct_helper_nlmsg_parse_payload(const struct nlmsghdr *nlh,
- struct nfct_helper *helper)
+ struct nfct_helper *h)
{
struct nlattr *tb[NFCTH_MAX+1] = {};
struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh);
mnl_attr_parse(nlh, sizeof(*nfg), nfct_helper_nlmsg_parse_attr_cb, tb);
if (!tb[NFCTH_NAME] || !tb[NFCTH_QUEUE_NUM] ||
- !tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY])
+ !tb[NFCTH_TUPLE] || !tb[NFCTH_POLICY] || !tb[NFCTH_STATUS])
return -1;
- nfct_helper_attr_set_str(helper, NFCTH_ATTR_NAME,
+ if (tb[NFCTH_NAME]) {
+ nfct_helper_attr_set_str(h, NFCTH_ATTR_NAME,
mnl_attr_get_str(tb[NFCTH_NAME]));
- nfct_helper_attr_set_u32(helper, NFCTH_ATTR_QUEUE_NUM,
+ }
+ if (tb[NFCTH_ATTR_QUEUE_NUM]) {
+ nfct_helper_attr_set_u32(h, NFCTH_ATTR_QUEUE_NUM,
ntohl(mnl_attr_get_u32(tb[NFCTH_QUEUE_NUM])));
+ }
+ if (tb[NFCTH_TUPLE])
+ nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], h);
- nfct_helper_nlmsg_parse_tuple(tb[NFCTH_TUPLE], helper);
- nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], helper);
+ if (tb[NFCTH_POLICY])
+ nfct_helper_nlmsg_parse_policy_set(tb[NFCTH_POLICY], h);
+ if (tb[NFCTH_PRIV_DATA_LEN]) {
+ nfct_helper_attr_set_u32(h, NFCTH_ATTR_PRIV_DATA_LEN,
+ ntohl(mnl_attr_get_u32(tb[NFCTH_PRIV_DATA_LEN])));
+ }
+
+ if (tb[NFCTH_STATUS]) {
+ nfct_helper_attr_set_u32(h, NFCTH_ATTR_STATUS,
+ ntohl(mnl_attr_get_u32(tb[NFCTH_STATUS])));
+ }
return 0;
}
EXPORT_SYMBOL(nfct_helper_nlmsg_parse_payload);
diff --git a/src/libnetfilter_cthelper.map b/src/libnetfilter_cthelper.map
index 199576b..34578de 100644
--- a/src/libnetfilter_cthelper.map
+++ b/src/libnetfilter_cthelper.map
@@ -18,6 +18,12 @@ global:
nfct_helper_nlmsg_parse_payload;
nfct_helper_snprintf;
+ nfct_helper_policy_alloc;
+ nfct_helper_policy_free;
+ nfct_helper_policy_attr_set;
+ nfct_helper_policy_attr_set_str;
+ nfct_helper_policy_attr_set_u32;
+
local: *;
};