summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2012-04-26 19:37:03 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2012-06-26 17:26:30 +0200
commit20cd0222c910e96c378e091e64b71d26e48916fe (patch)
tree377a770f8d42fb9fcab12cd9e3db7fe8212592f6
parentc69752e3dbf757aac336f4287eca11afef62a85c (diff)
conntrack: add nfct_set_attr_l and ATTR_HELPER_INFO
This adds the ATTR_HELPER_INFO that can be used to send binary data that will be attached to the conntrack. This is useful for the user-space connection tracking support. This patch also adds a new interface: nfct_set_attr_l(attr, type, value, length); that is used to set the variable length helper information. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--include/internal/object.h3
-rw-r--r--include/internal/types.h2
-rw-r--r--include/libnetfilter_conntrack/libnetfilter_conntrack.h6
-rw-r--r--include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h1
-rw-r--r--src/conntrack/api.c45
-rw-r--r--src/conntrack/build_mnl.c5
-rw-r--r--src/conntrack/copy.c17
-rw-r--r--src/conntrack/getter.c6
-rw-r--r--src/conntrack/parse_mnl.c12
-rw-r--r--src/conntrack/setter.c191
10 files changed, 215 insertions, 73 deletions
diff --git a/include/internal/object.h b/include/internal/object.h
index 55fa4f5..443e800 100644
--- a/include/internal/object.h
+++ b/include/internal/object.h
@@ -186,6 +186,9 @@ struct nf_conntrack {
u_int64_t start;
u_int64_t stop;
} timestamp;
+
+ void *helper_info;
+ size_t helper_info_len;
};
/*
diff --git a/include/internal/types.h b/include/internal/types.h
index 3459200..49bac2e 100644
--- a/include/internal/types.h
+++ b/include/internal/types.h
@@ -7,7 +7,7 @@
/*
* conntrack types
*/
-typedef void (*set_attr)(struct nf_conntrack *ct, const void *value);
+typedef void (*set_attr)(struct nf_conntrack *ct, const void *value, size_t len);
typedef const void *(*get_attr)(const struct nf_conntrack *ct);
typedef void (*copy_attr)(struct nf_conntrack *d, const struct nf_conntrack *o);
typedef void (*filter_attr)(struct nfct_filter *filter, const void *value);
diff --git a/include/libnetfilter_conntrack/libnetfilter_conntrack.h b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
index fbd67ef..12f61d1 100644
--- a/include/libnetfilter_conntrack/libnetfilter_conntrack.h
+++ b/include/libnetfilter_conntrack/libnetfilter_conntrack.h
@@ -132,6 +132,7 @@ enum nf_conntrack_attr {
ATTR_SECCTX, /* string */
ATTR_TIMESTAMP_START, /* u64 bits, linux >= 2.6.38 */
ATTR_TIMESTAMP_STOP = 64, /* u64 bits, linux >= 2.6.38 */
+ ATTR_HELPER_INFO, /* variable length */
ATTR_MAX
};
@@ -293,6 +294,11 @@ extern void nfct_set_attr_u64(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
u_int64_t value);
+extern void nfct_set_attr_l(struct nf_conntrack *ct,
+ const enum nf_conntrack_attr type,
+ const void *value,
+ size_t len);
+
/* getter */
extern const void *nfct_get_attr(const struct nf_conntrack *ct,
const enum nf_conntrack_attr type);
diff --git a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
index 1cf938b..e927699 100644
--- a/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
+++ b/include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h
@@ -195,6 +195,7 @@ enum ctattr_expect_nat {
enum ctattr_help {
CTA_HELP_UNSPEC,
CTA_HELP_NAME,
+ CTA_HELP_INFO,
__CTA_HELP_MAX
};
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
diff --git a/src/conntrack/api.c b/src/conntrack/api.c
index 202b85d..000571f 100644
--- a/src/conntrack/api.c
+++ b/src/conntrack/api.c
@@ -93,6 +93,8 @@ void nfct_destroy(struct nf_conntrack *ct)
assert(ct != NULL);
if (ct->secctx)
free(ct->secctx);
+ if (ct->helper_info)
+ free(ct->helper_info);
free(ct);
ct = NULL; /* bugtrap */
}
@@ -352,6 +354,29 @@ void nfct_callback_unregister2(struct nfct_handle *h)
*/
/**
+ * nfct_set_attr_l - set the value of a certain conntrack attribute
+ * \param ct pointer to a valid conntrack
+ * \param type attribute type
+ * \param pointer to attribute value
+ * \param length of attribute value (in bytes)
+ */
+void
+nfct_set_attr_l(struct nf_conntrack *ct, const enum nf_conntrack_attr type,
+ const void *value, size_t len)
+{
+ assert(ct != NULL);
+ assert(value != NULL);
+
+ if (unlikely(type >= ATTR_MAX))
+ return;
+
+ if (set_attr_array[type]) {
+ set_attr_array[type](ct, value, len);
+ set_bit(type, ct->head.set);
+ }
+}
+
+/**
* nfct_set_attr - set the value of a certain conntrack attribute
* \param ct pointer to a valid conntrack
* \param type attribute type
@@ -369,16 +394,8 @@ void nfct_set_attr(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
const void *value)
{
- assert(ct != NULL);
- assert(value != NULL);
-
- if (unlikely(type >= ATTR_MAX))
- return;
-
- if (set_attr_array[type]) {
- set_attr_array[type](ct, value);
- set_bit(type, ct->head.set);
- }
+ /* We assume the setter knows the size of the passed pointer. */
+ nfct_set_attr_l(ct, type, value, 0);
}
/**
@@ -391,7 +408,7 @@ void nfct_set_attr_u8(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
u_int8_t value)
{
- nfct_set_attr(ct, type, &value);
+ nfct_set_attr_l(ct, type, &value, sizeof(u_int8_t));
}
/**
@@ -404,7 +421,7 @@ void nfct_set_attr_u16(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
u_int16_t value)
{
- nfct_set_attr(ct, type, &value);
+ nfct_set_attr_l(ct, type, &value, sizeof(u_int16_t));
}
/**
@@ -417,7 +434,7 @@ void nfct_set_attr_u32(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
u_int32_t value)
{
- nfct_set_attr(ct, type, &value);
+ nfct_set_attr_l(ct, type, &value, sizeof(u_int32_t));
}
/**
@@ -430,7 +447,7 @@ void nfct_set_attr_u64(struct nf_conntrack *ct,
const enum nf_conntrack_attr type,
u_int64_t value)
{
- nfct_set_attr(ct, type, &value);
+ nfct_set_attr_l(ct, type, &value, sizeof(u_int64_t));
}
/**
diff --git a/src/conntrack/build_mnl.c b/src/conntrack/build_mnl.c
index 997c2c9..46aec8a 100644
--- a/src/conntrack/build_mnl.c
+++ b/src/conntrack/build_mnl.c
@@ -363,6 +363,11 @@ nfct_build_helper_name(struct nlmsghdr *nlh, const struct nf_conntrack *ct)
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;
}
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index 3c47b15..a6aa9f7 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -434,6 +434,22 @@ static void copy_attr_timestamp_stop(struct nf_conntrack *dest,
dest->timestamp.stop = orig->timestamp.stop;
}
+static void copy_attr_help_info(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ if (orig->helper_info == NULL)
+ return;
+
+ if (dest->helper_info != NULL)
+ free(dest->helper_info);
+
+ dest->helper_info = calloc(1, orig->helper_info_len);
+ if (dest->helper_info == NULL)
+ return;
+
+ memcpy(dest->helper_info, orig->helper_info, orig->helper_info_len);
+}
+
const copy_attr copy_attr_array[ATTR_MAX] = {
[ATTR_ORIG_IPV4_SRC] = copy_attr_orig_ipv4_src,
[ATTR_ORIG_IPV4_DST] = copy_attr_orig_ipv4_dst,
@@ -500,6 +516,7 @@ const copy_attr copy_attr_array[ATTR_MAX] = {
[ATTR_SECCTX] = copy_attr_secctx,
[ATTR_TIMESTAMP_START] = copy_attr_timestamp_start,
[ATTR_TIMESTAMP_STOP] = copy_attr_timestamp_stop,
+ [ATTR_HELPER_INFO] = copy_attr_help_info,
};
/* this is used by nfct_copy() with the NFCT_CP_OVERRIDE flag set. */
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index 5e0a450..e7ab048 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -334,6 +334,11 @@ static const void *get_attr_timestamp_stop(const struct nf_conntrack *ct)
return &ct->timestamp.stop;
}
+static const void *get_attr_helper_info(const struct nf_conntrack *ct)
+{
+ return ct->helper_info;
+}
+
const get_attr get_attr_array[ATTR_MAX] = {
[ATTR_ORIG_IPV4_SRC] = get_attr_orig_ipv4_src,
[ATTR_ORIG_IPV4_DST] = get_attr_orig_ipv4_dst,
@@ -400,4 +405,5 @@ const get_attr get_attr_array[ATTR_MAX] = {
[ATTR_SECCTX] = get_attr_secctx,
[ATTR_TIMESTAMP_START] = get_attr_timestamp_start,
[ATTR_TIMESTAMP_STOP] = get_attr_timestamp_stop,
+ [ATTR_HELPER_INFO] = get_attr_helper_info,
};
diff --git a/src/conntrack/parse_mnl.c b/src/conntrack/parse_mnl.c
index 86d9c54..93f6681 100644
--- a/src/conntrack/parse_mnl.c
+++ b/src/conntrack/parse_mnl.c
@@ -678,6 +678,18 @@ nfct_parse_helper(const struct nlattr *attr, struct nf_conntrack *ct)
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;
}
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index afab94f..dbcd68e 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -37,67 +37,80 @@ static const u_int8_t invmap_icmpv6[] = {
[ICMPV6_NI_REPLY - 128] = ICMPV6_NI_REPLY + 1
};
-static void set_attr_orig_ipv4_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_ipv4_src(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.src.v4 = *((u_int32_t *) value);
}
-static void set_attr_orig_ipv4_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_ipv4_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.dst.v4 = *((u_int32_t *) value);
}
-static void set_attr_repl_ipv4_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_ipv4_src(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->repl.src.v4 = *((u_int32_t *) value);
}
-static void set_attr_repl_ipv4_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_ipv4_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->repl.dst.v4 = *((u_int32_t *) value);
}
-static void set_attr_orig_ipv6_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_ipv6_src(struct nf_conntrack *ct, const void *value, size_t len)
{
memcpy(&ct->head.orig.src.v6, value, sizeof(u_int32_t)*4);
}
-static void set_attr_orig_ipv6_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_ipv6_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
memcpy(&ct->head.orig.dst.v6, value, sizeof(u_int32_t)*4);
}
-static void set_attr_repl_ipv6_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_ipv6_src(struct nf_conntrack *ct, const void *value, size_t len)
{
memcpy(&ct->repl.src.v6, value, sizeof(u_int32_t)*4);
}
-static void set_attr_repl_ipv6_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_ipv6_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
memcpy(&ct->repl.dst.v6, value, sizeof(u_int32_t)*4);
}
-static void set_attr_orig_port_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_port_src(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.l4src.all = *((u_int16_t *) value);
}
-static void set_attr_orig_port_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_port_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.l4dst.all = *((u_int16_t *) value);
}
-static void set_attr_repl_port_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_port_src(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->repl.l4src.all = *((u_int16_t *) value);
}
-static void set_attr_repl_port_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_port_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->repl.l4dst.all = *((u_int16_t *) value);
}
-static void set_attr_icmp_type(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_icmp_type(struct nf_conntrack *ct, const void *value, size_t len)
{
u_int8_t rtype;
@@ -123,231 +136,292 @@ static void set_attr_icmp_type(struct nf_conntrack *ct, const void *value)
}
-static void set_attr_icmp_code(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_icmp_code(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.l4dst.icmp.code = *((u_int8_t *) value);
ct->repl.l4dst.icmp.code = *((u_int8_t *) value);
}
-static void set_attr_icmp_id(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_icmp_id(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.l4src.icmp.id = *((u_int16_t *) value);
ct->repl.l4src.icmp.id = *((u_int16_t *) value);
}
-static void set_attr_orig_l3proto(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_l3proto(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.l3protonum = *((u_int8_t *) value);
}
-static void set_attr_repl_l3proto(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_l3proto(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->repl.l3protonum = *((u_int8_t *) value);
}
-static void set_attr_orig_l4proto(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_l4proto(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->head.orig.protonum = *((u_int8_t *) value);
}
-static void set_attr_repl_l4proto(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_l4proto(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->repl.protonum = *((u_int8_t *) value);
}
-static void set_attr_tcp_state(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_state(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.state = *((u_int8_t *) value);
}
-static void set_attr_tcp_flags_orig(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_flags_orig(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.flags[__DIR_ORIG].value = *((u_int8_t *) value);
}
-static void set_attr_tcp_mask_orig(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_mask_orig(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.flags[__DIR_ORIG].mask = *((u_int8_t *) value);
}
-static void set_attr_tcp_flags_repl(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_flags_repl(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.flags[__DIR_REPL].value = *((u_int8_t *) value);
}
-static void set_attr_tcp_mask_repl(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_mask_repl(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.flags[__DIR_REPL].mask = *((u_int8_t *) value);
}
-static void set_attr_sctp_state(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_sctp_state(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.sctp.state = *((u_int8_t *) value);
}
-static void set_attr_sctp_vtag_orig(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_sctp_vtag_orig(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.sctp.vtag[__DIR_ORIG] = *((u_int32_t *) value);
}
-static void set_attr_sctp_vtag_repl(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_sctp_vtag_repl(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.sctp.vtag[__DIR_REPL] = *((u_int32_t *) value);
}
-static void set_attr_snat_ipv4(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_snat_ipv4(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->snat.min_ip = ct->snat.max_ip = *((u_int32_t *) value);
}
-static void set_attr_dnat_ipv4(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_dnat_ipv4(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->dnat.min_ip = ct->snat.max_ip = *((u_int32_t *) value);
}
-static void set_attr_snat_port(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_snat_port(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->snat.l4min.all = ct->snat.l4max.all = *((u_int16_t *) value);
}
-static void set_attr_dnat_port(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_dnat_port(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->dnat.l4min.all = ct->dnat.l4max.all = *((u_int16_t *) value);
}
-static void set_attr_timeout(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_timeout(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->timeout = *((u_int32_t *) value);
}
-static void set_attr_mark(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_mark(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->mark = *((u_int32_t *) value);
}
-static void set_attr_secmark(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_secmark(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->secmark = *((u_int32_t *) value);
}
-static void set_attr_status(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_status(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->status = *((u_int32_t *) value);
}
-static void set_attr_id(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_id(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->id = *((u_int32_t *) value);
}
-static void set_attr_master_ipv4_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_ipv4_src(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->master.src.v4 = *((u_int32_t *) value);
}
-static void set_attr_master_ipv4_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_ipv4_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->master.dst.v4 = *((u_int32_t *) value);
}
-static void set_attr_master_ipv6_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_ipv6_src(struct nf_conntrack *ct, const void *value, size_t len)
{
memcpy(&ct->master.src.v6, value, sizeof(u_int32_t)*4);
}
-static void set_attr_master_ipv6_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_ipv6_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
memcpy(&ct->master.dst.v6, value, sizeof(u_int32_t)*4);
}
-static void set_attr_master_port_src(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_port_src(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->master.l4src.all = *((u_int16_t *) value);
}
-static void set_attr_master_port_dst(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_port_dst(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->master.l4dst.all = *((u_int16_t *) value);
}
-static void set_attr_master_l3proto(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_l3proto(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->master.l3protonum = *((u_int8_t *) value);
}
-static void set_attr_master_l4proto(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_master_l4proto(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->master.protonum = *((u_int8_t *) value);
}
-static void set_attr_orig_cor_pos(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_cor_pos(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->natseq[__DIR_ORIG].correction_pos = *((u_int32_t *) value);
}
-static void set_attr_orig_off_bfr(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_off_bfr(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->natseq[__DIR_ORIG].offset_before = *((u_int32_t *) value);
}
-static void set_attr_orig_off_aft(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_orig_off_aft(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->natseq[__DIR_ORIG].offset_after = *((u_int32_t *) value);
}
-static void set_attr_repl_cor_pos(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_cor_pos(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->natseq[__DIR_REPL].correction_pos = *((u_int32_t *) value);
}
-static void set_attr_repl_off_bfr(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_off_bfr(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->natseq[__DIR_REPL].offset_before = *((u_int32_t *) value);
}
-static void set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->natseq[__DIR_REPL].offset_after = *((u_int32_t *) value);
}
-static void set_attr_helper_name(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_helper_name(struct nf_conntrack *ct, const void *value, size_t len)
{
strncpy(ct->helper_name, value, NFCT_HELPER_NAME_MAX);
ct->helper_name[NFCT_HELPER_NAME_MAX-1] = '\0';
}
-static void set_attr_dccp_state(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_dccp_state(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.dccp.state = *((u_int8_t *) value);
}
-static void set_attr_dccp_role(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_dccp_role(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.dccp.role = *((u_int8_t *) value);
}
static void
-set_attr_dccp_handshake_seq(struct nf_conntrack *ct, const void *value)
+set_attr_dccp_handshake_seq(struct nf_conntrack *ct, const void *value,
+ size_t len)
{
ct->protoinfo.dccp.handshake_seq = *((u_int64_t *) value);
}
-static void set_attr_tcp_wscale_orig(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_wscale_orig(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.wscale[__DIR_ORIG] = *((u_int8_t *) value);
}
-static void set_attr_tcp_wscale_repl(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_tcp_wscale_repl(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->protoinfo.tcp.wscale[__DIR_REPL] = *((u_int8_t *) value);
}
-static void set_attr_zone(struct nf_conntrack *ct, const void *value)
+static void
+set_attr_zone(struct nf_conntrack *ct, const void *value, size_t len)
{
ct->zone = *((u_int16_t *) value);
}
-static void set_attr_do_nothing(struct nf_conntrack *ct, const void *value) {}
+static void
+set_attr_helper_info(struct nf_conntrack *ct, const void *value, size_t len)
+{
+ if (ct->helper_info == NULL) {
+retry:
+ ct->helper_info = calloc(1, len);
+ if (ct->helper_info == NULL)
+ return;
+
+ memcpy(ct->helper_info, value, len);
+ } else {
+ free(ct->helper_info);
+ goto retry;
+ }
+}
+
+static void
+set_attr_do_nothing(struct nf_conntrack *ct, const void *value, size_t len) {}
const set_attr set_attr_array[ATTR_MAX] = {
[ATTR_ORIG_IPV4_SRC] = set_attr_orig_ipv4_src,
@@ -415,4 +489,5 @@ const set_attr set_attr_array[ATTR_MAX] = {
[ATTR_SECCTX] = set_attr_do_nothing,
[ATTR_TIMESTAMP_START] = set_attr_do_nothing,
[ATTR_TIMESTAMP_STOP] = set_attr_do_nothing,
+ [ATTR_HELPER_INFO] = set_attr_helper_info,
};