summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGaurav Sinha <gaurav.sinha@vyatta.com>2012-02-08 11:31:31 -0800
committerGaurav Sinha <gaurav.sinha@vyatta.com>2012-02-08 11:31:31 -0800
commit9f9a63cecdc6ac4f449d3eacda6c591f0de9fbf3 (patch)
tree18e6fef8b6e8640db261b6448eb7f25411139474
parent66da74b336fe66472f9b5d16f730e0261c5ef4af (diff)
parent167eb3e2028561ab2cc0f2b7b6ff9d24c56514f6 (diff)
downloadconntrack-tools-9f9a63cecdc6ac4f449d3eacda6c591f0de9fbf3.tar.gz
conntrack-tools-9f9a63cecdc6ac4f449d3eacda6c591f0de9fbf3.zip
Merge branch 'master' of git://git.netfilter.org/conntrack-tools into upstream
-rw-r--r--include/network.h8
-rw-r--r--src/build.c37
-rw-r--r--src/parse.c88
3 files changed, 130 insertions, 3 deletions
diff --git a/include/network.h b/include/network.h
index ab95499..41c35af 100644
--- a/include/network.h
+++ b/include/network.h
@@ -239,6 +239,7 @@ enum nta_attr {
NTA_ICMP_ID, /* uint16_t */
NTA_TCP_WSCALE_ORIG, /* uint8_t */
NTA_TCP_WSCALE_REPL, /* uint8_t */
+ NTA_HELPER_NAME, /* string (variable length) */
NTA_MAX
};
@@ -269,6 +270,13 @@ enum nta_exp_attr {
NTA_EXP_MASK_PORT, /* struct nfct_attr_grp_port */
NTA_EXP_TIMEOUT, /* uint32_t */
NTA_EXP_FLAGS, /* uint32_t */
+ NTA_EXP_CLASS, /* uint32_t */
+ NTA_EXP_NAT_IPV4, /* struct nfct_attr_grp_ipv4 */
+ NTA_EXP_NAT_PORT, /* struct nfct_attr_grp_port */
+ NTA_EXP_NAT_L4PROTO, /* uint8_t */
+ NTA_EXP_NAT_DIR, /* uint32_t */
+ NTA_EXP_HELPER_NAME, /* string (variable length) */
+ NTA_EXP_FN, /* string (variable length) */
NTA_EXP_MAX
};
diff --git a/src/build.c b/src/build.c
index 3193884..7d4ef12 100644
--- a/src/build.c
+++ b/src/build.c
@@ -65,6 +65,13 @@ ct_build_u32(const struct nf_conntrack *ct, int a, struct nethdr *n, int b)
addattr(n, b, &data, sizeof(uint32_t));
}
+static inline void
+ct_build_str(const struct nf_conntrack *ct, int a, struct nethdr *n, int b)
+{
+ const char *data = nfct_get_attr(ct, a);
+ addattr(n, b, data, strlen(data)+1);
+}
+
static inline void
ct_build_group(const struct nf_conntrack *ct, int a, struct nethdr *n,
int b, int size)
@@ -223,6 +230,9 @@ void ct2msg(const struct nf_conntrack *ct, struct nethdr *n)
/* NAT sequence adjustment */
if (nfct_attr_is_set_array(ct, nat_type, 6))
ct_build_natseqadj(ct, n);
+
+ if (nfct_attr_is_set(ct, ATTR_HELPER_NAME))
+ ct_build_str(ct, ATTR_HELPER_NAME, n, NTA_HELPER_NAME);
}
static void
@@ -270,6 +280,13 @@ exp_build_u32(const struct nf_expect *exp, int a, struct nethdr *n, int b)
addattr(n, b, &data, sizeof(uint32_t));
}
+static inline void
+exp_build_str(const struct nf_expect *exp, int a, struct nethdr *n, int b)
+{
+ const char *data = nfexp_get_attr(exp, a);
+ addattr(n, b, data, strlen(data)+1);
+}
+
void exp2msg(const struct nf_expect *exp, struct nethdr *n)
{
const struct nf_conntrack *ct = nfexp_get_attr(exp, ATTR_EXP_MASTER);
@@ -322,4 +339,24 @@ void exp2msg(const struct nf_expect *exp, struct nethdr *n)
exp_build_u32(exp, ATTR_EXP_TIMEOUT, n, NTA_EXP_TIMEOUT);
exp_build_u32(exp, ATTR_EXP_FLAGS, n, NTA_EXP_FLAGS);
+ if (nfexp_attr_is_set(exp, ATTR_EXP_CLASS))
+ exp_build_u32(exp, ATTR_EXP_CLASS, n, NTA_EXP_CLASS);
+
+ /* include NAT information, if any. */
+ ct = nfexp_get_attr(exp, ATTR_EXP_NAT_TUPLE);
+ if (ct != NULL) {
+ if (nfct_attr_grp_is_set(ct, ATTR_GRP_ORIG_IPV4)) {
+ ct_build_group(ct, ATTR_GRP_ORIG_IPV4, n,
+ NTA_EXP_NAT_IPV4,
+ sizeof(struct nfct_attr_grp_ipv4));
+ }
+ ct_build_u8(ct, ATTR_L4PROTO, n, NTA_EXP_NAT_L4PROTO);
+ if (exp_l4proto_fcn[l4proto].build)
+ exp_l4proto_fcn[l4proto].build(ct, n, NTA_EXP_NAT_PORT);
+
+ exp_build_u32(exp, ATTR_EXP_NAT_DIR, n, NTA_EXP_NAT_DIR);
+ }
+ exp_build_str(exp, ATTR_EXP_HELPER_NAME, n, NTA_EXP_HELPER_NAME);
+ if (nfexp_attr_is_set(exp, ATTR_EXP_FN))
+ exp_build_str(exp, ATTR_EXP_FN, n, NTA_EXP_FN);
}
diff --git a/src/parse.c b/src/parse.c
index 81e9c6b..732bc44 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -28,6 +28,7 @@
static void ct_parse_u8(struct nf_conntrack *ct, int attr, void *data);
static void ct_parse_u16(struct nf_conntrack *ct, int attr, void *data);
static void ct_parse_u32(struct nf_conntrack *ct, int attr, void *data);
+static void ct_parse_str(struct nf_conntrack *ct, int attr, void *data);
static void ct_parse_group(struct nf_conntrack *ct, int attr, void *data);
static void ct_parse_nat_seq_adj(struct nf_conntrack *ct, int attr, void *data);
@@ -35,6 +36,7 @@ struct ct_parser {
void (*parse)(struct nf_conntrack *ct, int attr, void *data);
int attr;
int size;
+ int max_size;
};
static struct ct_parser h[NTA_MAX] = {
@@ -172,6 +174,11 @@ static struct ct_parser h[NTA_MAX] = {
.attr = ATTR_TCP_WSCALE_REPL,
.size = NTA_SIZE(sizeof(uint8_t)),
},
+ [NTA_HELPER_NAME] = {
+ .parse = ct_parse_str,
+ .attr = ATTR_HELPER_NAME,
+ .max_size = NFCT_HELPER_NAME_MAX,
+ },
};
static void
@@ -196,6 +203,12 @@ ct_parse_u32(struct nf_conntrack *ct, int attr, void *data)
}
static void
+ct_parse_str(struct nf_conntrack *ct, int attr, void *data)
+{
+ nfct_set_attr(ct, h[attr].attr, data);
+}
+
+static void
ct_parse_group(struct nf_conntrack *ct, int attr, void *data)
{
nfct_set_attr_grp(ct, h[attr].attr, data);
@@ -236,7 +249,11 @@ int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain)
return -1;
if (attr->nta_attr > NTA_MAX)
return -1;
- if (attr->nta_len != h[attr->nta_attr].size)
+ if (h[attr->nta_attr].size &&
+ attr->nta_len != h[attr->nta_attr].size)
+ return -1;
+ if (h[attr->nta_attr].max_size &&
+ attr->nta_len > h[attr->nta_attr].max_size)
return -1;
if (h[attr->nta_attr].parse == NULL) {
attr = NTA_NEXT(attr, len);
@@ -252,12 +269,14 @@ int msg2ct(struct nf_conntrack *ct, struct nethdr *net, size_t remain)
static void exp_parse_ct_group(void *ct, int attr, void *data);
static void exp_parse_ct_u8(void *ct, int attr, void *data);
static void exp_parse_u32(void *exp, int attr, void *data);
+static void exp_parse_str(void *exp, int attr, void *data);
static struct exp_parser {
void (*parse)(void *obj, int attr, void *data);
int exp_attr;
int ct_attr;
int size;
+ int max_size;
} exp_h[NTA_EXP_MAX] = {
[NTA_EXP_MASTER_IPV4] = {
.parse = exp_parse_ct_group,
@@ -341,6 +360,44 @@ static struct exp_parser {
.exp_attr = ATTR_EXP_FLAGS,
.size = NTA_SIZE(sizeof(uint32_t)),
},
+ [NTA_EXP_CLASS] = {
+ .parse = exp_parse_u32,
+ .exp_attr = ATTR_EXP_CLASS,
+ .size = NTA_SIZE(sizeof(uint32_t)),
+ },
+ [NTA_EXP_NAT_IPV4] = {
+ .parse = exp_parse_ct_group,
+ .exp_attr = ATTR_EXP_NAT_TUPLE,
+ .ct_attr = ATTR_GRP_ORIG_IPV4,
+ .size = NTA_SIZE(sizeof(struct nfct_attr_grp_ipv4)),
+ },
+ [NTA_EXP_NAT_L4PROTO] = {
+ .parse = exp_parse_ct_u8,
+ .exp_attr = ATTR_EXP_NAT_TUPLE,
+ .ct_attr = ATTR_L4PROTO,
+ .size = NTA_SIZE(sizeof(uint8_t)),
+ },
+ [NTA_EXP_NAT_PORT] = {
+ .parse = exp_parse_ct_group,
+ .exp_attr = ATTR_EXP_NAT_TUPLE,
+ .ct_attr = ATTR_GRP_ORIG_PORT,
+ .size = NTA_SIZE(sizeof(struct nfct_attr_grp_port)),
+ },
+ [NTA_EXP_NAT_DIR] = {
+ .parse = exp_parse_u32,
+ .exp_attr = ATTR_EXP_NAT_DIR,
+ .size = NTA_SIZE(sizeof(uint32_t)),
+ },
+ [NTA_EXP_HELPER_NAME] = {
+ .parse = exp_parse_str,
+ .exp_attr = ATTR_EXP_HELPER_NAME,
+ .max_size = NFCT_HELPER_NAME_MAX,
+ },
+ [NTA_EXP_FN] = {
+ .parse = exp_parse_str,
+ .exp_attr = ATTR_EXP_FN,
+ .max_size = NFCT_HELPER_NAME_MAX,
+ },
};
static void exp_parse_ct_group(void *ct, int attr, void *data)
@@ -360,11 +417,16 @@ static void exp_parse_u32(void *exp, int attr, void *data)
nfexp_set_attr_u32(exp, exp_h[attr].exp_attr, ntohl(*value));
}
+static void exp_parse_str(void *exp, int attr, void *data)
+{
+ nfexp_set_attr(exp, exp_h[attr].exp_attr, data);
+}
+
int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)
{
int len;
struct netattr *attr;
- struct nf_conntrack *master, *expected, *mask;
+ struct nf_conntrack *master, *expected, *mask, *nat;
if (remain < net->len)
return -1;
@@ -384,13 +446,21 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)
if (mask == NULL)
goto err_mask;
+ nat = nfct_new();
+ if (nat == NULL)
+ goto err_nat;
+
while (len > ssizeof(struct netattr)) {
ATTR_NETWORK2HOST(attr);
if (attr->nta_len > len)
goto err;
if (attr->nta_attr > NTA_MAX)
goto err;
- if (attr->nta_len != exp_h[attr->nta_attr].size)
+ if (exp_h[attr->nta_attr].size &&
+ attr->nta_len != exp_h[attr->nta_attr].size)
+ goto err;
+ if (exp_h[attr->nta_attr].max_size &&
+ attr->nta_len > exp_h[attr->nta_attr].max_size)
goto err;
if (exp_h[attr->nta_attr].parse == NULL) {
attr = NTA_NEXT(attr, len);
@@ -407,8 +477,17 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)
exp_h[attr->nta_attr].parse(mask, attr->nta_attr,
NTA_DATA(attr));
break;
+ case ATTR_EXP_NAT_TUPLE:
+ exp_h[attr->nta_attr].parse(nat, attr->nta_attr,
+ NTA_DATA(attr));
+ nfexp_set_attr(exp, ATTR_EXP_NAT_TUPLE, nat);
+ break;
case ATTR_EXP_TIMEOUT:
case ATTR_EXP_FLAGS:
+ case ATTR_EXP_CLASS:
+ case ATTR_EXP_HELPER_NAME:
+ case ATTR_EXP_NAT_DIR:
+ case ATTR_EXP_FN:
exp_h[attr->nta_attr].parse(exp, attr->nta_attr,
NTA_DATA(attr));
break;
@@ -429,9 +508,12 @@ int msg2exp(struct nf_expect *exp, struct nethdr *net, size_t remain)
nfct_destroy(mask);
nfct_destroy(expected);
nfct_destroy(master);
+ nfct_destroy(nat);
return 0;
err:
+ nfct_destroy(nat);
+err_nat:
nfct_destroy(mask);
err_mask:
nfct_destroy(expected);