summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2008-05-21 13:30:43 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2008-05-21 13:30:43 +0200
commit7e629bad0f752f6fb3e3a435666307992e74bee2 (patch)
treef9ed7c72fc0a86754d9e451ca86ed42cde6a34cf /src
parentff7d53ece9e73e0bda937ad8716482c8cc881fb3 (diff)
add full support of SCTP
Diffstat (limited to 'src')
-rw-r--r--src/conntrack/build.c19
-rw-r--r--src/conntrack/compare.c5
-rw-r--r--src/conntrack/copy.c23
-rw-r--r--src/conntrack/getter.c18
-rw-r--r--src/conntrack/parse.c34
-rw-r--r--src/conntrack/setter.c18
-rw-r--r--src/conntrack/snprintf_default.c22
7 files changed, 136 insertions, 3 deletions
diff --git a/src/conntrack/build.c b/src/conntrack/build.c
index 638fbe2..f11af42 100644
--- a/src/conntrack/build.c
+++ b/src/conntrack/build.c
@@ -123,6 +123,25 @@ void __build_protoinfo(struct nfnlhdr *req,
nfnl_nest_end(&req->nlh, nest_proto);
nfnl_nest_end(&req->nlh, nest);
break;
+ case IPPROTO_SCTP:
+ nest = nfnl_nest(&req->nlh, size, CTA_PROTOINFO);
+ nest_proto = nfnl_nest(&req->nlh, size, CTA_PROTOINFO_SCTP);
+ if (test_bit(ATTR_SCTP_STATE, ct->set))
+ nfnl_addattr_l(&req->nlh, size,
+ CTA_PROTOINFO_SCTP_STATE,
+ &ct->protoinfo.sctp.state,
+ sizeof(u_int8_t));
+ if (test_bit(ATTR_SCTP_VTAG_ORIG, ct->set))
+ nfnl_addattr32(&req->nlh, size,
+ CTA_PROTOINFO_SCTP_VTAG_ORIGINAL,
+ htonl(ct->protoinfo.sctp.vtag[__DIR_ORIG]));
+ if (test_bit(ATTR_SCTP_VTAG_REPL, ct->set))
+ nfnl_addattr32(&req->nlh, size,
+ CTA_PROTOINFO_SCTP_VTAG_REPLY,
+ htonl(ct->protoinfo.sctp.vtag[__DIR_REPL]));
+ nfnl_nest_end(&req->nlh, nest_proto);
+ nfnl_nest_end(&req->nlh, nest);
+ break;
default:
break;
}
diff --git a/src/conntrack/compare.c b/src/conntrack/compare.c
index cd51f9d..d30a902 100644
--- a/src/conntrack/compare.c
+++ b/src/conntrack/compare.c
@@ -222,6 +222,11 @@ static int cmp_meta(const struct nf_conntrack *ct1,
ct1->protoinfo.tcp.state != ct2->protoinfo.tcp.state)
return 0;
+ if (test_bit(ATTR_SCTP_STATE, ct1->set) &&
+ test_bit(ATTR_SCTP_STATE, ct2->set) &&
+ ct1->protoinfo.sctp.state != ct2->protoinfo.sctp.state)
+ return 0;
+
return 1;
}
diff --git a/src/conntrack/copy.c b/src/conntrack/copy.c
index 142f868..562f801 100644
--- a/src/conntrack/copy.c
+++ b/src/conntrack/copy.c
@@ -224,6 +224,26 @@ static void copy_attr_tcp_mask_repl(struct nf_conntrack *dest,
orig->protoinfo.tcp.flags[__DIR_REPL].mask;
}
+static void copy_attr_sctp_state(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->protoinfo.sctp.state = orig->protoinfo.sctp.state;
+}
+
+static void copy_attr_sctp_vtag_orig(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->protoinfo.sctp.vtag[__DIR_ORIG] =
+ orig->protoinfo.sctp.vtag[__DIR_ORIG];
+}
+
+static void copy_attr_sctp_vtag_repl(struct nf_conntrack *dest,
+ const struct nf_conntrack *orig)
+{
+ dest->protoinfo.sctp.vtag[__DIR_REPL] =
+ orig->protoinfo.sctp.vtag[__DIR_REPL];
+}
+
static void copy_attr_snat_ipv4(struct nf_conntrack *dest,
const struct nf_conntrack *orig)
{
@@ -403,4 +423,7 @@ copy_attr copy_attr_array[] = {
[ATTR_REPL_NAT_SEQ_CORRECTION_POS] = copy_attr_repl_cor_pos,
[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = copy_attr_repl_off_bfr,
[ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = copy_attr_repl_off_aft,
+ [ATTR_SCTP_STATE] = copy_attr_sctp_state,
+ [ATTR_SCTP_VTAG_ORIG] = copy_attr_sctp_vtag_orig,
+ [ATTR_SCTP_VTAG_REPL] = copy_attr_sctp_vtag_repl,
};
diff --git a/src/conntrack/getter.c b/src/conntrack/getter.c
index 48ba386..8591f88 100644
--- a/src/conntrack/getter.c
+++ b/src/conntrack/getter.c
@@ -167,6 +167,21 @@ static const void *get_attr_tcp_mask_repl(const struct nf_conntrack *ct)
return &ct->protoinfo.tcp.flags[__DIR_REPL].mask;
}
+static const void *get_attr_sctp_state(const struct nf_conntrack *ct)
+{
+ return &ct->protoinfo.sctp.state;
+}
+
+static const void *get_attr_sctp_vtag_orig(const struct nf_conntrack *ct)
+{
+ return &ct->protoinfo.sctp.vtag[__DIR_ORIG];
+}
+
+static const void *get_attr_sctp_vtag_repl(const struct nf_conntrack *ct)
+{
+ return &ct->protoinfo.sctp.vtag[__DIR_REPL];
+}
+
static const void *get_attr_snat_ipv4(const struct nf_conntrack *ct)
{
return &ct->snat.min_ip;
@@ -320,4 +335,7 @@ get_attr get_attr_array[] = {
[ATTR_REPL_NAT_SEQ_CORRECTION_POS] = get_attr_repl_cor_pos,
[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = get_attr_repl_off_bfr,
[ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = get_attr_repl_off_aft,
+ [ATTR_SCTP_STATE] = get_attr_sctp_state,
+ [ATTR_SCTP_VTAG_ORIG] = get_attr_sctp_vtag_orig,
+ [ATTR_SCTP_VTAG_REPL] = get_attr_sctp_vtag_repl,
};
diff --git a/src/conntrack/parse.c b/src/conntrack/parse.c
index c21f304..a18e3ad 100644
--- a/src/conntrack/parse.c
+++ b/src/conntrack/parse.c
@@ -217,6 +217,33 @@ static void __parse_protoinfo_tcp(const struct nfattr *attr,
}
}
+static void __parse_protoinfo_sctp(const struct nfattr *attr,
+ struct nf_conntrack *ct)
+{
+ struct nfattr *tb[CTA_PROTOINFO_SCTP_MAX];
+
+ nfnl_parse_nested(tb, CTA_PROTOINFO_SCTP_MAX, attr);
+
+ if (tb[CTA_PROTOINFO_SCTP_STATE-1]) {
+ ct->protoinfo.sctp.state =
+ *(u_int8_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_STATE-1]);
+ set_bit(ATTR_SCTP_STATE, ct->set);
+ }
+
+ if (tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL-1]) {
+ ct->protoinfo.sctp.vtag[__DIR_ORIG] =
+ ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_VTAG_ORIGINAL-1]));
+ set_bit(ATTR_SCTP_VTAG_ORIG, ct->set);
+ }
+
+ if (tb[CTA_PROTOINFO_SCTP_VTAG_REPLY-1]) {
+ ct->protoinfo.sctp.vtag[__DIR_ORIG] =
+ ntohl(*(u_int32_t *)NFA_DATA(tb[CTA_PROTOINFO_SCTP_VTAG_REPLY-1]));
+ set_bit(ATTR_SCTP_VTAG_ORIG, ct->set);
+ }
+
+}
+
static void __parse_protoinfo(const struct nfattr *attr,
struct nf_conntrack *ct)
{
@@ -224,10 +251,11 @@ static void __parse_protoinfo(const struct nfattr *attr,
nfnl_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
- if (!tb[CTA_PROTOINFO_TCP-1])
- return;
+ if (tb[CTA_PROTOINFO_TCP-1])
+ __parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP-1], ct);
- __parse_protoinfo_tcp(tb[CTA_PROTOINFO_TCP-1], ct);
+ if (tb[CTA_PROTOINFO_SCTP-1])
+ __parse_protoinfo_sctp(tb[CTA_PROTOINFO_SCTP-1], ct);
}
static void __parse_counters(const struct nfattr *attr,
diff --git a/src/conntrack/setter.c b/src/conntrack/setter.c
index 52a2aab..53698bf 100644
--- a/src/conntrack/setter.c
+++ b/src/conntrack/setter.c
@@ -170,6 +170,21 @@ static void set_attr_tcp_mask_repl(struct nf_conntrack *ct, const void *value)
ct->protoinfo.tcp.flags[__DIR_REPL].mask = *((u_int8_t *) value);
}
+static void set_attr_sctp_state(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.sctp.state = *((u_int8_t *) value);
+}
+
+static void set_attr_sctp_vtag_orig(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.sctp.vtag[__DIR_ORIG] = *((u_int32_t *) value);
+}
+
+static void set_attr_sctp_vtag_repl(struct nf_conntrack *ct, const void *value)
+{
+ ct->protoinfo.sctp.vtag[__DIR_REPL] = *((u_int32_t *) value);
+}
+
static void set_attr_snat_ipv4(struct nf_conntrack *ct, const void *value)
{
ct->snat.min_ip = ct->snat.max_ip = *((u_int32_t *) value);
@@ -340,4 +355,7 @@ set_attr set_attr_array[] = {
[ATTR_REPL_NAT_SEQ_CORRECTION_POS] = set_attr_repl_cor_pos,
[ATTR_REPL_NAT_SEQ_OFFSET_BEFORE] = set_attr_repl_off_aft,
[ATTR_REPL_NAT_SEQ_OFFSET_AFTER] = set_attr_repl_off_bfr,
+ [ATTR_SCTP_STATE] = set_attr_sctp_state,
+ [ATTR_SCTP_VTAG_ORIG] = set_attr_sctp_vtag_orig,
+ [ATTR_SCTP_VTAG_REPL] = set_attr_sctp_vtag_repl,
};
diff --git a/src/conntrack/snprintf_default.c b/src/conntrack/snprintf_default.c
index e2573df..e89f2f5 100644
--- a/src/conntrack/snprintf_default.c
+++ b/src/conntrack/snprintf_default.c
@@ -34,6 +34,17 @@ static const char *states[] = {
"LISTEN"
};
+static const char *sctp_states[] = {
+ "NONE",
+ "CLOSED",
+ "COOKIE_WAIT",
+ "COOKIE_ECHOED",
+ "ESTABLISHED",
+ "SHUTDOWN_SENT",
+ "SHUTDOWN_RECD",
+ "SHUTDOWN_ACK_SENT",
+};
+
static int __snprintf_l3protocol(char *buf,
unsigned int len,
const struct nf_conntrack *ct)
@@ -67,6 +78,12 @@ int __snprintf_protoinfo(char *buf,
{
return snprintf(buf, len, "%s ", states[ct->protoinfo.tcp.state]);
}
+int __snprintf_protoinfo_sctp(char *buf,
+ unsigned int len,
+ const struct nf_conntrack *ct)
+{
+ return snprintf(buf, len, "%s ", sctp_states[ct->protoinfo.sctp.state]);
+}
int __snprintf_address_ipv4(char *buf,
unsigned int len,
@@ -260,6 +277,11 @@ int __snprintf_conntrack_default(char *buf,
BUFFER_SIZE(ret, size, len, offset);
}
+ if (test_bit(ATTR_SCTP_STATE, ct->set)) {
+ ret = __snprintf_protoinfo_sctp(buf+offset, len, ct);
+ BUFFER_SIZE(ret, size, len, offset);
+ }
+
ret = __snprintf_address(buf+offset, len, &ct->tuple[__DIR_ORIG]);
BUFFER_SIZE(ret, size, len, offset);