add support for explicit helper assignment
Pablo Neira Ayuso
maintainerPATCH 1/1 add support for explicit helper assignment
This patch adds support for the explicit helper assignment to libnetfilter_conntrack. You can use it to test the load-on-demand helper
modules via ctnetlink.
Signature · 1 line
"Los honestos son inadaptados sociales" -- Les Luthiers
[PATCH][libnetfilter_conntrack] add support for explicit helper assignment
This patch adds support for explicit helper assignment.
include/internal/extern.h +2 -0
@@ -9,4 +9,6 @@ extern filter_attr filter_attr_array[];extern set_exp_attr set_exp_attr_array[];extern get_exp_attr get_exp_attr_array[]; +extern const char *helper_id_to_name[]; +#endif
include/internal/object.h +1 -0
@@ -137,6 +137,7 @@ struct nf_conntrack {u_int32_t status;u_int32_t use;u_int32_t id; +u_int32_t helper_id;union __nfct_protoinfo protoinfo;struct __nfct_counters counters[__DIR_MAX];
include/libnetfilter_conntrack/libnetfilter_conntrack.h +17 -0
@@ -120,9 +120,26 @@ enum nf_conntrack_attr {ATTR_SCTP_STATE =52 ,/* u8 bits */ ATTR_SCTP_VTAG_ORIG ,/* u32 bits */ ATTR_SCTP_VTAG_REPL ,/* u32 bits */ +ATTR_HELPER_ID ,/* u32 bits */ ATTR_MAX }; +/* helper id's */ + +enum nf_conntrack_helper_id { +NFCT_HELPER_UNSPEC =0 , +NFCT_HELPER_AMANDA , +NFCT_HELPER_FTP , +NFCT_HELPER_H323 , +NFCT_HELPER_IRC =4 , +NFCT_HELPER_NETBIOS_NS , +NFCT_HELPER_PPTP , +NFCT_HELPER_SANE , +NFCT_HELPER_SIP =8 , +NFCT_HELPER_TFTP , +NFCT_HELPER_MAX +}; +/* message type */ enum nf_conntrack_msg_type { NFCT_T_UNKNOWN = 0,
src/conntrack/build.c +35 -0
@@ -308,6 +308,38 @@ void __build_secmark(struct nfnlhdr *req,nfnl_addattr32 (&req->nlh, size,CTA_SECMARK ,htonl (ct->secmark)); } +const char *helper_id_to_name[] = { + [NFCT_HELPER_UNSPEC ] ="unknown-helper" , + [NFCT_HELPER_AMANDA ] ="amanda" , + [NFCT_HELPER_FTP ] ="ftp" , + [NFCT_HELPER_H323 ] ="h323" , + [NFCT_HELPER_IRC ] ="irc" , + [NFCT_HELPER_NETBIOS_NS ] ="netbios_ns" , + [NFCT_HELPER_PPTP ] ="pptp" , + [NFCT_HELPER_SANE ] ="sane" , + [NFCT_HELPER_SIP ] ="sip" , + [NFCT_HELPER_TFTP ] ="tftp" , +}; + +void __build_helper_name (struct nfnlhdr *req, +size_t size, +const struct nf_conntrack *ct) +{ +struct nfattr *nest; + +/* helper set, but probably unsupported */ +if (ct->helper_id ==0 ) +return ; + + nest =nfnl_nest (&req->nlh, size,CTA_HELP ); +nfnl_addattr_l (&req->nlh, + size, +CTA_HELP_NAME , + helper_id_to_name[ct->helper_id], +strlen (helper_id_to_name[ct->helper_id])); +nfnl_nest_end (&req->nlh, nest); +} + int __build_conntrack(struct nfnl_subsys_handle *ssh, struct nfnlhdr *req, size_t size,
@@ -417,5 +449,8 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh, test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->set))__build_nat_seq_adj (req, size, ct, __DIR_REPL); +if (test_bit (ATTR_HELPER_ID , ct->set)) +__build_helper_name (req, size, ct); +return 0 ; }
src/conntrack/getter.c +6 -0
@@ -282,6 +282,11 @@ static const void *get_attr_repl_off_aft(const struct nf_conntrack *ct)return &ct->tuple[__DIR_REPL].natseq.offset_after; } +static const void *get_attr_helper_id (const struct nf_conntrack *ct) +{ +return &ct->helper_id; +} +get_attr get_attr_array[] = { [ATTR_ORIG_IPV4_SRC ] = get_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST ] = get_attr_orig_ipv4_dst,
@@ -338,4 +343,5 @@ get_attr get_attr_array[] = { [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, + [ATTR_HELPER_ID] = get_attr_helper_id, };
src/conntrack/parse.c +28 -0
@@ -356,6 +356,31 @@ __parse_nat_seq(const struct nfattr *attr, struct nf_conntrack *ct, int dir) } } +static void +__parse_helper (const struct nfattr *attr,struct nf_conntrack *ct) +{ +int i, found =0 ; +struct nfattr *tb[CTA_NAT_SEQ_MAX ]; + +nfnl_parse_nested (tb,CTA_NAT_SEQ_MAX , attr); +if (!tb[CTA_HELP_NAME -1 ]) +return ; + +for (i=0 ; i<NFCT_HELPER_MAX ; i++) { +if (strcmp (NFA_DATA (tb[CTA_HELP_NAME -1 ]), + helper_id_to_name[i]) ==0 ) { + found =1 ; +break ; + } + } + +if (!found) +return ; + + ct->helper_id = i; +set_bit (ATTR_HELPER_ID , ct->set); +} +int __parse_message_type (const struct nlmsghdr *nlh) {u_int16_t type =NFNL_MSG_TYPE (nlh->nlmsg_type);
@@ -447,4 +472,7 @@ void __parse_conntrack(const struct nlmsghdr *nlh, ct->id =ntohl (*(u_int32_t *)NFA_DATA (cda[CTA_ID -1 ]));set_bit (ATTR_ID , ct->set); } + +if (cda[CTA_HELP -1 ]) +__parse_helper (cda[CTA_HELP -1 ], ct); }
src/conntrack/setter.c +11 -0
@@ -308,6 +308,16 @@ static void set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value) ct->tuple[__DIR_REPL].natseq.offset_after = *((u_int32_t *) value); } +static void set_attr_helper_id (struct nf_conntrack *ct,const void *value) +{ +u_int32_t val = *((u_int32_t *)value); + +if (val >=NFCT_HELPER_MAX ) + val =0 ; + + ct->helper_id = val; +} +static void set_attr_do_nothing (struct nf_conntrack *ct,const void *value) {}set_attr set_attr_array[] = {
@@ -366,4 +376,5 @@ set_attr set_attr_array[] = { [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, + [ATTR_HELPER_ID] = set_attr_helper_id, };
utils/conntrack_create.c +1 -0
@@ -29,6 +29,7 @@ int main()nfct_set_attr_u8 (ct,ATTR_TCP_STATE ,TCP_CONNTRACK_LISTEN );nfct_set_attr_u32 (ct,ATTR_TIMEOUT ,100 ); +nfct_set_attr_u32 (ct,ATTR_HELPER_ID ,NFCT_HELPER_FTP ); h =nfct_open (CONNTRACK ,0 );if (!h) {
Quoted 3 lines · Pablo Neira Ayuso
This patch adds support for the explicit helper assignment to
libnetfilter_conntrack. You can use it to test the load-on-demand helper modules via ctnetlink.
<CUT>
Quoted 28 lines
include/libnetfilter_conntrack/libnetfilter_conntrack.h +14
-0+enum nf_conntrack_helper_id { +NFCT_HELPER_UNSPEC =0 , +NFCT_HELPER_AMANDA , +NFCT_HELPER_FTP , +NFCT_HELPER_H323 , +NFCT_HELPER_IRC =4 , +NFCT_HELPER_NETBIOS_NS , +NFCT_HELPER_PPTP , +NFCT_HELPER_SANE , +NFCT_HELPER_SIP =8 , +NFCT_HELPER_TFTP , +NFCT_HELPER_MAX +}; +/* message type */ enum nf_conntrack_msg_type {NFCT_T_UNKNOWN =0 ,src/conntrack/build.c +3
-0@@ -308,6 +308,38 @@ void __build_secmark(struct nfnlhdr *req,nfnl_addattr32 (&req->nlh, size,CTA_SECMARK ,htonl (ct->secmark)); } +const char *helper_id_to_name[] = { + [NFCT_HELPER_UNSPEC ] ="unknown-helper" , + [NFCT_HELPER_AMANDA ] ="amanda" ,
src/conntrack/build.c void __build_secmark(struct nfnlhdr *req, · line 323
Quoted 10 lines
src/conntrack/build.c +10
-0+ [NFCT_HELPER_FTP] = "ftp", + [NFCT_HELPER_H323] = "h323", + [NFCT_HELPER_IRC] = "irc", + [NFCT_HELPER_NETBIOS_NS] = "netbios_ns", + [NFCT_HELPER_PPTP] = "pptp", + [NFCT_HELPER_SANE] = "sane", + [NFCT_HELPER_SIP] = "sip", + [NFCT_HELPER_TFTP] = "tftp", +}; +
Any chances to make it more frendly to new helpers and compatible with out-of-tree helpers by registering a name directly from a helper and using it? We may for example introduce something like /proc/net/nf_helpers.
Best regards,
Krzysztof Olędzki
Pablo Neira Ayuso
maintainerQuoted 17 lines · Krzysztof Oledzki
Quoted 17 lines
src/conntrack/build.c +9
-0@@ -308,6 +308,38 @@ void __build_secmark(struct nfnlhdr *req,nfnl_addattr32 (&req->nlh, size,CTA_SECMARK ,htonl (ct->secmark)); } +const char *helper_id_to_name[] = { + [NFCT_HELPER_UNSPEC ] ="unknown-helper" , + [NFCT_HELPER_AMANDA ] ="amanda" , + [NFCT_HELPER_FTP ] ="ftp" , + [NFCT_HELPER_H323 ] ="h323" , + [NFCT_HELPER_IRC ] ="irc" , + [NFCT_HELPER_NETBIOS_NS ] ="netbios_ns" , + [NFCT_HELPER_PPTP ] ="pptp" , + [NFCT_HELPER_SANE ] ="sane" ,
Quoted 8 lines
src/conntrack/build.c void __build_secmark(struct nfnlhdr *req, · line 323
Quoted 4 lines
src/conntrack/build.c +4
-0+ [NFCT_HELPER_SIP] = "sip", + [NFCT_HELPER_TFTP] = "tftp", +}; +Any chances to make it more frendly to new helpers and compatible with out-of-tree helpers by registering a name directly from a helper and using it? We may for example introduce something like
/proc/net/nf_helpers.
We may directly set the name of the helper using the string that identifies it instead of this id. However, this means more memory consumption but more flexibility. I have another patch here that uses strings to do so. The problem is that helpers doesn't have a limitation in the name length and I don't like the idea of having a field "helper_name" with variable length inside the nf_conntrack object. We could make some reasonable assumptions, like considering that the helper name would not be larger than 32 bytes.
Using this patch, the new helpers would need a new version of the library as you have said. However, the argument of supporting out-of-tree helpers doesn't convince me, what out-of-tree helpers are you refering to?
BTW, the patch is not yet applied anyway.
Signature · 1 line
"Los honestos son inadaptados sociales" -- Les Luthiers
Quoted 27 lines · Pablo Neira Ayuso
Quoted 17 lines · Krzysztof Oledzki
Quoted 17 lines
src/conntrack/build.c +9
-0@@ -308,6 +308,38 @@ void __build_secmark(struct nfnlhdr *req,nfnl_addattr32 (&req->nlh, size,CTA_SECMARK ,htonl (ct->secmark)); } +const char *helper_id_to_name[] = { + [NFCT_HELPER_UNSPEC ] ="unknown-helper" , + [NFCT_HELPER_AMANDA ] ="amanda" , + [NFCT_HELPER_FTP ] ="ftp" , + [NFCT_HELPER_H323 ] ="h323" , + [NFCT_HELPER_IRC ] ="irc" , + [NFCT_HELPER_NETBIOS_NS ] ="netbios_ns" , + [NFCT_HELPER_PPTP ] ="pptp" , + [NFCT_HELPER_SANE ] ="sane" ,Quoted 8 lines
src/conntrack/build.c void __build_secmark(struct nfnlhdr *req, · line 323
Quoted 4 lines
src/conntrack/build.c +4
-0+ [NFCT_HELPER_SIP] = "sip", + [NFCT_HELPER_TFTP] = "tftp", +}; +Any chances to make it more frendly to new helpers and compatible with out-of-tree helpers by registering a name directly from a helper and using it? We may for example introduce something like
/proc/net/nf_helpers.
Quoted 8 lines
We may directly set the name of the helper using the string that identifies it instead of this id. However, this means more memory consumption but more flexibility. I have another patch here that uses strings to do so. The problem is that helpers doesn't have a limitation in the name length and I don't like the idea of having a field "
helper_name" with variable length inside thenf_conntrackobject. We could make some reasonable assumptions, like considering that the helper name would not be larger than 32 bytes.
Yep, 32 bytes seems to be a good compromise.
Quoted 4 lines
Using this patch, the new helpers would need a new version of the library as you have said. However, the argument of supporting out-of-tree helpers doesn't convince me, what out-of-tree helpers are you refering to?
nf_conntrack_rtsp for example
Best regards,
Krzysztof Olędzki
Quoted 8 lines · Krzysztof Oledzki
Quoted 5 lines
Using this patch, the new helpers would need a new version of the library as you have said. However, the argument of supporting out-of-tree helpers doesn't convince me, what out-of-tree helpers are you refering to?
nf_conntrack_rtspfor example
And whatever is lingering in crapomatic, eh? ;-)
Quoted 5 lines · Pablo Neira Ayuso
Quoted 3 lines · Krzysztof Oledzki
Any chances to make it more frendly to new helpers and compatible with out-of-tree helpers by registering a name directly from a helper and using it? We may for example introduce something like
/proc/net/nf_helpers.
Quoted 8 lines
We may directly set the name of the helper using the string that identifies it instead of this id. However, this means more memory consumption but more flexibility. I have another patch here that uses strings to do so. The problem is that helpers doesn't have a limitation in the name length and I don't like the idea of having a field "
helper_name" with variable length inside thenf_conntrackobject. We could make some reasonable assumptions, like considering that the helper name would not be larger than 32 bytes.
Limiting the name makes sense. The helper match can only match on I think 16 bytes, and that seems big enough.
Pablo Neira Ayuso
maintainerQuoted 16 lines · Patrick McHardy
Quoted 6 lines · Pablo Neira Ayuso
Quoted 4 lines · Krzysztof Oledzki
Any chances to make it more frendly to new helpers and compatible with out-of-tree helpers by registering a name directly from a helper and using it? We may for example introduce something like
/proc/net/nf_helpers.Quoted 8 lines
We may directly set the name of the helper using the string that identifies it instead of this id. However, this means more memory consumption but more flexibility. I have another patch here that uses strings to do so. The problem is that helpers doesn't have a limitation in the name length and I don't like the idea of having a field "
helper_name" with variable length inside thenf_conntrackobject. We could make some reasonable assumptions, like considering that the helper name would not be larger than 32 bytes.
Quoted 2 lines
Limiting the name makes sense. The helper match can only match on I think 16 bytes, and that seems big enough.
Fine, I have set it to the same size used in xt_helper (30 bytes, that seems a lot to me, I actually prefer 16 bytes as you said).
BTW, the helper name support for libnetfilter_conntrack looks like the patch attached.
Signature · 1 line
"Los honestos son inadaptados sociales" -- Les Luthiers
include/internal/object.h +3 -0
@@ -138,6 +138,9 @@ struct nf_conntrack {u_int32_t use;u_int32_t id; +#define __NFCT_HELPER_NAMELEN 30/* same length in xt_helper */ +char helper_name[__NFCT_HELPER_NAMELEN]; +union __nfct_protoinfo protoinfo;struct __nfct_counters counters[__DIR_MAX];struct __nfct_nat snat;
include/libnetfilter_conntrack/libnetfilter_conntrack.h +1 -0
@@ -120,6 +120,7 @@ enum nf_conntrack_attr {ATTR_SCTP_STATE =52 ,/* u8 bits */ ATTR_SCTP_VTAG_ORIG ,/* u32 bits */ ATTR_SCTP_VTAG_REPL ,/* u32 bits */ +ATTR_HELPER_NAME ,/* string (30 bytes max) */ ATTR_MAX };
src/conntrack/build.c +18 -0
@@ -308,6 +308,21 @@ void __build_secmark(struct nfnlhdr *req,nfnl_addattr32 (&req->nlh, size,CTA_SECMARK ,htonl (ct->secmark)); } +void __build_helper_name (struct nfnlhdr *req, +size_t size, +const struct nf_conntrack *ct) +{ +struct nfattr *nest; + + nest =nfnl_nest (&req->nlh, size,CTA_HELP ); +nfnl_addattr_l (&req->nlh, + size, +CTA_HELP_NAME , + ct->helper_name, +strlen (ct->helper_name)); +nfnl_nest_end (&req->nlh, nest); +} + int __build_conntrack(struct nfnl_subsys_handle *ssh, struct nfnlhdr *req, size_t size,
@@ -417,5 +432,8 @@ int __build_conntrack(struct nfnl_subsys_handle *ssh, test_bit(ATTR_REPL_NAT_SEQ_OFFSET_AFTER, ct->set))__build_nat_seq_adj (req, size, ct, __DIR_REPL); +if (test_bit (ATTR_HELPER_NAME , ct->set)) +__build_helper_name (req, size, ct); +return 0 ; }
src/conntrack/getter.c +6 -0
@@ -282,6 +282,11 @@ static const void *get_attr_repl_off_aft(const struct nf_conntrack *ct)return &ct->tuple[__DIR_REPL].natseq.offset_after; } +static const void *get_attr_helper_name (const struct nf_conntrack *ct) +{ +return ct->helper_name; +} +get_attr get_attr_array[] = { [ATTR_ORIG_IPV4_SRC ] = get_attr_orig_ipv4_src, [ATTR_ORIG_IPV4_DST ] = get_attr_orig_ipv4_dst,
@@ -338,4 +343,5 @@ get_attr get_attr_array[] = { [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, + [ATTR_HELPER_NAME] = get_attr_helper_name, };
src/conntrack/parse.c +19 -0
@@ -356,6 +356,22 @@ __parse_nat_seq(const struct nfattr *attr, struct nf_conntrack *ct, int dir) } } +static void +__parse_helper (const struct nfattr *attr,struct nf_conntrack *ct) +{ +struct nfattr *tb[CTA_HELP_MAX ]; + +nfnl_parse_nested (tb,CTA_HELP_MAX , attr); +if (!tb[CTA_HELP_NAME -1 ]) +return ; + +strncpy (ct->helper_name, +NFA_DATA (tb[CTA_HELP_NAME -1 ]), + __NFCT_HELPER_NAMELEN); + ct->helper_name[__NFCT_HELPER_NAMELEN-1 ] ='\0' ; +set_bit (ATTR_HELPER_NAME , ct->set); +} +int __parse_message_type (const struct nlmsghdr *nlh) {u_int16_t type =NFNL_MSG_TYPE (nlh->nlmsg_type);
@@ -447,4 +463,7 @@ void __parse_conntrack(const struct nlmsghdr *nlh, ct->id =ntohl (*(u_int32_t *)NFA_DATA (cda[CTA_ID -1 ]));set_bit (ATTR_ID , ct->set); } + +if (cda[CTA_HELP -1 ]) +__parse_helper (cda[CTA_HELP -1 ], ct); }
src/conntrack/setter.c +7 -0
@@ -308,6 +308,12 @@ static void set_attr_repl_off_aft(struct nf_conntrack *ct, const void *value) ct->tuple[__DIR_REPL].natseq.offset_after = *((u_int32_t *) value); } +static void set_attr_helper_name (struct nf_conntrack *ct,const void *value) +{ +strncpy (ct->helper_name, value, __NFCT_HELPER_NAMELEN); + ct->helper_name[__NFCT_HELPER_NAMELEN-1 ] ='\0' ; +} +static void set_attr_do_nothing (struct nf_conntrack *ct,const void *value) {}set_attr set_attr_array[] = {
@@ -366,4 +372,5 @@ set_attr set_attr_array[] = { [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, + [ATTR_HELPER_NAME] = set_attr_helper_name, };
utils/conntrack_create.c +1 -0
@@ -29,6 +29,7 @@ int main()nfct_set_attr_u8 (ct,ATTR_TCP_STATE ,TCP_CONNTRACK_LISTEN );nfct_set_attr_u32 (ct,ATTR_TIMEOUT ,100 ); +nfct_set_attr (ct,ATTR_HELPER_NAME ,"ftp" ); h =nfct_open (CONNTRACK ,0 );if (!h) {