SCTP support
Pablo Neira Ayuso
maintainerPATCH 1/1 SCTP support
Attached SCTP support for libnetfilter_conntrack in case that you want to test the kernel [PATCH 2/4].
Signature · 1 line
"Los honestos son inadaptados sociales" -- Les Luthiers
include/internal.h +5 -0
@@ -130,6 +130,11 @@ union __nfct_protoinfo {u_int8_t mask; } flags[__DIR_MAX]; } tcp; +struct { +u_int8_t state; +u_int32_t vtag[__DIR_MAX]; + } sctp; + };struct __nfct_counters {
include/libnetfilter_conntrack/libnetfilter_conntrack.h +3 -0
@@ -117,6 +117,9 @@ enum nf_conntrack_attr {ATTR_REPL_NAT_SEQ_CORRECTION_POS ,/* u32 bits */ ATTR_REPL_NAT_SEQ_OFFSET_BEFORE ,/* u32 bits */ ATTR_REPL_NAT_SEQ_OFFSET_AFTER ,/* u32 bits */ +ATTR_SCTP_STATE =52 ,/* u8 bits */ +ATTR_SCTP_VTAG_ORIG ,/* u32 bits */ +ATTR_SCTP_VTAG_REPL ,/* u32 bits */ ATTR_MAX };
include/libnetfilter_conntrack/linux_nfnetlink_conntrack.h +18 -0
@@ -84,6 +84,8 @@ enum ctattr_l4proto {enum ctattr_protoinfo {CTA_PROTOINFO_UNSPEC ,CTA_PROTOINFO_TCP , +CTA_PROTOINFO_DCCP , +CTA_PROTOINFO_SCTP , __CTA_PROTOINFO_MAX };#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
@@ -99,6 +101,22 @@ enum ctattr_protoinfo_tcp { };#define CTA_PROTOINFO_TCP_MAX (__CTA_PROTOINFO_TCP_MAX - 1) +enum ctattr_protoinfo_dccp { +CTA_PROTOINFO_DCCP_UNSPEC , +CTA_PROTOINFO_DCCP_STATE , + __CTA_PROTOINFO_DCCP_MAX +}; +#define CTA_PROTOINFO_DCCP_MAX (__CTA_PROTOINFO_DCCP_MAX - 1) + +enum ctattr_protoinfo_sctp { +CTA_PROTOINFO_SCTP_UNSPEC , +CTA_PROTOINFO_SCTP_STATE , +CTA_PROTOINFO_SCTP_VTAG_ORIGINAL , +CTA_PROTOINFO_SCTP_VTAG_REPLY , + __CTA_PROTOINFO_SCTP_MAX +}; +#define CTA_PROTOINFO_SCTP_MAX (__CTA_PROTOINFO_SCTP_MAX - 1) +enum ctattr_counters {CTA_COUNTERS_UNSPEC ,CTA_COUNTERS_PACKETS ,/* old 64bit counters */
src/conntrack/build.c +19 -0
@@ -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 ; }
src/conntrack/compare.c +5 -0
@@ -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 ; }
src/conntrack/copy.c +23 -0
@@ -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, };
src/conntrack/getter.c +18 -0
@@ -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, };
src/conntrack/parse.c +31 -3
@@ -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,
src/conntrack/setter.c +18 -0
@@ -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, };
src/conntrack/snprintf_default.c +23 -0
@@ -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)
@@ -65,8 +76,15 @@ int __snprintf_protoinfo(char *buf,unsigned int len, const struct nf_conntrack *ct) { + 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 +278,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);