H.323: implement a "real" H.245 parser
cover H.323: implement a "real" H.245 parser
Hi,
the following patchset replaces Jozsef's "brute force" parser with a real H.245 parser. It adds a very simple ASN.1/PER parsing library, and parses very few H.245 structures (enough for all H.323 software I tested).
My next task will be the rewrite of the H.225 parser using my ASN.1/PER library.
Max
PATCH 1/6 H.323: remove struct ip_ct_h225_master
h323-01-remove_ip_ct_h225_master.patch
- remove struct ip_ct_h225_master
Tue Apr 19 21:28:07 CEST 2005 [email protected]
* removed dummy struct ip_ct_h225_master
h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack.h.ladd +0 -2
@@ -1,2 +0,0 @@ - /* insert conntrack helper private data (master) here */ - struct ip_ct_h225_master ct_h225_info;
h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack.h.ladd_2 +0 -2
@@ -1,2 +0,0 @@ -/* Add protocol helper include file here */ -#include <linux/netfilter_ipv4/ip_conntrack_h323.h>
h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_h323.h +0 -5
@@ -7,11 +7,6 @@/* Default H.225 port */ #define H225_PORT 1720 -/* This structure exists only once per master */ -struct ip_ct_h225_master { -int dummy; -}; -struct ip_conntrack_expect ;struct ip_conntrack ;
PATCH 2/6 add ip_nat_h245()
In reply to Max Kellermannh323-02-add_ip_nat_h245.patch
- add ip_nat_h245(), separate fro ip_nat_h225()
Tue Apr 19 22:45:33 CEST 2005 [email protected]
* ip_nat_h245_hook has its own implementation, ip_nat_h245()
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_nat_h323.c +49 -1
@@ -126,6 +126,54 @@return NF_ACCEPT ; } +static int ip_nat_h245 (struct sk_buff **pskb, +enum ip_conntrack_info ctinfo, +unsigned int offset, +struct ip_conntrack_expect *exp) +{ +u_int16_t port; +struct { +u_int32_t ip; +u_int16_t port; + } __attribute__ ((__packed__ )) newdata; +int dir =CTINFO2DIR (ctinfo); +struct ip_conntrack *ct = exp->master; +int ret; + +/* Connection will come from wherever this packet goes, hence !dir */ + newdata.ip = ct->tuplehash[!dir].tuple.dst.ip; + exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port; + exp->dir = !dir; + +/* When you see the packet, we need to NAT it the same as the +* this one. */ + exp->expectfn = ip_nat_follow_master; + +/* Try to get same port: if not, try to change it. */ +for (port =ntohs (exp->saved_proto.tcp.port); port !=0 ; port++) { + exp->tuple.dst.u.tcp.port =htons (port); +if (ip_conntrack_expect_related (exp) ==0 ) +break ; + } + +if (port ==0 ) { +ip_conntrack_expect_free (exp); +return NF_DROP ; + } + + newdata.port =htons (port); + +/* now mangle packet */ + ret =ip_nat_mangle_tcp_packet (pskb, ct, ctinfo, + offset, +sizeof (newdata), + (const char *)&newdata,sizeof (newdata)); +if (!ret) +return NF_DROP ; + +return NF_ACCEPT ; +} +static int __init init (void ) {BUG_ON (ip_nat_h225_hook !=NULL );
@@ -133,7 +181,7 @@ ip_nat_h225_hook = ip_nat_h225; ip_nat_h225_signal_hook = ip_nat_h225_signal; - ip_nat_h245_hook = ip_nat_h225; + ip_nat_h245_hook = ip_nat_h245;return 0 ; }
PATCH 3/6 H.323: minor code style fixes
In reply to Max Kellermannh323-03-code_style.patch
- minor code style fixes
Tue Apr 19 22:46:24 CEST 2005 [email protected]
* minor code style fixes
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c +4 -2
@@ -160,7 +160,8 @@ }/* H.245 helper is not registered! */ -static struct ip_conntrack_helper h245 = { +static struct ip_conntrack_helper h245 = +{ .name ="H.245" , .max_expected =8 , .timeout =240 ,
@@ -419,7 +420,8 @@return ret; } -static struct ip_conntrack_helper h225 = { +static struct ip_conntrack_helper h225 = +{ .name ="H.225" , .me =THIS_MODULE , .max_expected =2 ,
PATCH 4/6 H.323: splitted ip_conntrack_h323.c into 3 sources
In reply to Max Kellermannh323-04-split_conntrack_into_3.patch
- splitted ip_conntrack_h323.c into 3 sources
Tue May 10 23:26:46 CEST 2005 [email protected]
* splitted ip_conntrack_h323.c into 3 sources IV
h323-conntrack-nat/linux-2.6.11/include/linux/netfilter_ipv4/ip_conntrack_h323.h +3 -0
@@ -9,6 +9,7 @@struct ip_conntrack_expect ;struct ip_conntrack ; +struct ip_conntrack_helper ; extern int (*ip_nat_h245_hook)(struct sk_buff **pskb, enum ip_conntrack_info ctinfo,
@@ -27,6 +28,8 @@int dir, int orig_dir); +extern struct ip_conntrack_helper ip_conntrack_helper_h225; +void ip_conntrack_h245_expect (struct ip_conntrack *new,struct ip_conntrack_expect *this);
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/Makefile.ladd +1 -0
@@ -2,5 +2,6 @@ # H.323 support obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o +ip_conntrack_h323-objs := ip_conntrack_h323_core.o ip_conntrack_h323_h225.o ip_conntrack_h323_h245.o obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323.c +0 -448
448 lines not on this page · raw message
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.c +38 -0
@@ -0,0 +1,38 @@ +/* +* H.323 connection tracking helper +* (c) 2005 Max Kellermann <[email protected]> +* +* Based on the 'brute force' H.323 connection tracking module by +* Jozsef Kadlecsik <[email protected]> +*/ + + +#include <linux/module.h> +#include <linux/netfilter.h> +#include <linux/ip.h> +#include <net/checksum.h> +#include <net/tcp.h> + +#include <linux/netfilter_ipv4/lockhelp.h> +#include <linux/netfilter_ipv4/ip_conntrack.h> +#include <linux/netfilter_ipv4/ip_conntrack_core.h> +#include <linux/netfilter_ipv4/ip_conntrack_helper.h> +#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> +#include <linux/netfilter_ipv4/ip_conntrack_h323.h> + +MODULE_AUTHOR ("Max Kellermann <[email protected]>" ); +MODULE_DESCRIPTION ("H.323 connection tracking helper" ); +MODULE_LICENSE ("GPL" ); + +static int __init init (void ) +{ +return ip_conntrack_helper_register (&ip_conntrack_helper_h225); +} + +static void __exit fini(void) +{ +ip_conntrack_helper_unregister (&ip_conntrack_helper_h225); +} + +module_init (init); +module_exit (fini);
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_h225.c +299 -0
299 lines not on this page · raw message
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_h245.c +161 -0
161 lines not on this page · raw message
Re: [PATCH pom-ng 4/6] H.323: splitted ip_conntrack_h323.c into 3 sources
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.c
Quoted 6 lines · Max Kellermann
h323-04-split_conntrack_into_3.patch
- splittedip_conntrack_h323.cinto 3 sourcesdiff -rN -u
old-h323-4/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.cnew-h323-4/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.ch323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.c +0
-0
This file looks a bit unnecessary, I suggest to put register/unregister in ip_conntrack_h323_h225.c.
Regards
Patrick
Re: [PATCH pom-ng 4/6] H.323: splitted ip_conntrack_h323.c into 3 sources
Quoted 10 lines · Patrick McHardy
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.c
Quoted 6 lines · Max Kellermann
h323-04-split_conntrack_into_3.patch
- splittedip_conntrack_h323.cinto 3 sourcesdiff -rN -u
old-h323-4/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.cnew-h323-4/h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.ch323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_core.c +0
-0This file looks a bit unnecessary, I suggest to put register/unregister in
ip_conntrack_h323_h225.c.
I splitted the file because it became very large (I dislike sources > 500 lines). I decided to make a _core.c because this way, the _h225.c and _h245.c contain only protocol parser code, and nothing else - still having the option to add more "common" code to _core.c (whatever happens in further development).
In the compiled binary, there is no advantage of merging _core and _h225.c.
A matter of personal taste. If you vote me down on this one, I'll change it.
Max
Re: [PATCH pom-ng 4/6] H.323: splitted ip_conntrack_h323.c into 3 sources
Quoted 11 lines · Max Kellermann
Quoted 2 lines · Patrick McHardy
This file looks a bit unnecessary, I suggest to put register/unregister in
ip_conntrack_h323_h225.c.I splitted the file because it became very large (I dislike sources > 500 lines). I decided to make a
_core.cbecause this way, the_h225.cand_h245.ccontain only protocol parser code, and nothing else - still having the option to add more "common" code to_core.c(whatever happens in further development).
Quoted 5 lines
In the compiled binary, there is no advantage of merging
_coreand_h225.c.A matter of personal taste. If you vote me down on this one, I'll change it.
Well, lets keep it this way for now and wait if something else is added. If we decide to merge it some day we can still change it.
Regards
Patrick
PATCH 5/6 H.323: ASN.1/PER parser
In reply to Max Kellermannh323-05-simple_asn1_per_parser.patch
- added an ASN.1/PER parser
Tue May 10 23:28:17 CEST 2005 [email protected]
* added an ASN.1/PER parser IV
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/Makefile.ladd +1 -1
@@ -2,6 +2,6 @@ # H.323 support obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o -ip_conntrack_h323-objs := ip_conntrack_h323_core.o ip_conntrack_h323_h225.o ip_conntrack_h323_h245.o +ip_conntrack_h323-objs := ip_conntrack_h323_core.o ip_conntrack_h323_h225.o ip_conntrack_h323_h245.o asn1_per.o obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/asn1_per.c +353 -0
353 lines not on this page · raw message
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/asn1_per.h +83 -0
83 lines not on this page · raw message
PATCH 6/6 H.323: H.245/ASN.1 parser
In reply to Max Kellermannh323-06-replace_bruteforce_with_h245_parser.patch
- implement a real H.245 parser
Tue May 10 23:35:13 CEST 2005 [email protected]
* H.245/ASN.1 parser VII
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_h245.c +852 -56
@@ -20,6 +20,8 @@#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> #include <linux/netfilter_ipv4/ip_conntrack_h323.h> +#include "asn1_per.h" +/* This is slow, but it's simple. --RR */ static char h245_buffer[65536 ];
@@ -39,20 +41,861 @@ #define DEBUGP(format, args...)#endif -/* FIXME: This should be in userspace. Later. */ +/** +* Skip an H.245 NonStandardIdentifier, discarding its value. +*/ +static void h245_skip_nonstandard_id (struct asn1_per_buffer *bb) { +unsigned choice; + + choice =asn1_per_read_bits (bb,1 ); +switch (choice) { +case 0 : +asn1_per_skip_object_id (bb); +break ; + +case 1 : +asn1_per_read_unsigned (bb,0 ,255 ); +asn1_per_read_unsigned (bb,0 ,255 ); +asn1_per_read_unsigned (bb,0 ,65535 ); +break ; + } +} + +/** +* Skip an H.245 NonStandardParameter, discarding its value. +*/ +static void h245_skip_nonstandard_param (struct asn1_per_buffer *bb) { +h245_skip_nonstandard_id (bb); +asn1_per_skip_octet_string (bb); +} + +/** +* Skip an H.245 VideoCapability, discarding its value. +*/ +static void h245_skip_video_capability (struct asn1_per_buffer *bb) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,5 , &after); +DEBUGP ("video_capability: choice=%u after=%u error=%d\n" , + choice, after, bb->error); + +if (bb->error) +return ; + +/* XXX support the rest */ +switch (choice) { +case 0 :/* nonStandard */ +h245_skip_nonstandard_param (bb); +break ; + +default : +if (after ==0 ) { +DEBUGP ("unsupported audio_capability %u\n" , choice); + bb->error =1 ; + } + } + +if (after >0 ) + bb->i = after; +} + +/** +* Skip an H.245 AudioCapability, discarding its value. +*/ +static void h245_skip_audio_capability (struct asn1_per_buffer *bb) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,14 , &after); +DEBUGP ("audio_capability: audio_capability=%u after=%u error=%d\n" , choice, after, bb->error); + +if (bb->error) +return ; + +/* XXX support the rest */ +switch (choice) { +unsigned value; + +case 0 :/* nonStandard */ +h245_skip_nonstandard_param (bb); +break ; + +case 1 : +case 2 : +case 3 : +case 4 : +case 5 : +case 6 : +case 7 : +case 9 : +case 10 : +case 11 : +case 14 : +case 17 : + value =asn1_per_read_unsigned (bb,1 ,256 ); +DEBUGP ("value %u = %u\n" , choice, value); +break ; +default : +if (after ==0 ) { +DEBUGP ("unsupported audio_capability %u\n" , choice); + bb->error =1 ; + } + } + +if (after >0 ) + bb->i = after; +} + +/** +* Skip an H.245 DataType, discarding its value. +*/ +static void h245_skip_data_type (struct asn1_per_buffer *bb) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,6 , &after); + +if (bb->error) +return ; + +/* XXX support the rest */ +switch (choice) { +case 0 :/* nonStandard */ +h245_skip_nonstandard_param (bb); +break ; + +case 1 :/* nullData */ +break ; + +case 2 :/* videoData */ +h245_skip_video_capability (bb); +break ; + +case 3 :/* audioData */ +h245_skip_audio_capability (bb); +break ; + +default : +if (after ==0 ) { +DEBUGP ("unsupported data_type %u\n" , choice); + bb->error =1 ; + } + } + +if (after >0 ) + bb->i = after; +} + +/** +* Parse an H.245 UnicastAddress and return the position of the IP +* address (if present). Returns 1 on success. +*/ +static int h245_parse_unicast_address (struct asn1_per_buffer *bb,unsigned *i, +u_int32_t *ip,u_int16_t *port) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,5 , &after); +DEBUGP ("Parsing UnicastAddress choice=%u after=%u\n" , choice, after); +switch (choice) { +case 0 :/* iPAddress */ +asn1_per_read_bit (bb);/* XXX use this bit */ +asn1_per_byte_align (bb); + *i = bb->i; +asn1_per_read_bytes (bb, ip,sizeof (*ip)); +asn1_per_read_bytes (bb, port,sizeof (*port)); +return !bb->error; +default : +if (after ==0 ) { +DEBUGP ("UnicastAddress %u not yet supported\n" , choice); + bb->error =1 ; + }else { + bb->i = after; + } +return 0 ; + } +} + +/** +* Parse an H.245 TransportAddress and return the position of the +* Unicast IP address (if present). Returns 1 on success. +*/ +static int h245_parse_transport_address (struct asn1_per_buffer *bb,unsigned *i, +u_int32_t *ip,u_int16_t *port) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,2 , &after); +switch (choice) { +case 0 :/* UnicastAddress */ +return h245_parse_unicast_address (bb, i, ip, port); +case 1 :/* MulticastAddress */ +/* XXX */ +DEBUGP ("MulticastAddress not yet supported\n" ); + bb->error =1 ; +return 0 ; +default : +if (after ==0 ) { +DEBUGP ("ERROR7\n" ); + bb->error =1 ; + }else { + bb->i = after; + } +return 0 ; + } +} + +/** +* Skip an H.245 TerminalLabel, discarding its value. +*/ +static void h245_skip_terminal_label (struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; + +asn1_per_read_sequence_header (bb,1 ,0 , &hdr); + +/* mcuNumber */ +asn1_per_read_unsigned (bb,0 ,192 ); +/* terminalNumber */ +asn1_per_read_unsigned (bb,0 ,192 ); + +asn1_per_skip_sequence_extension (bb, &hdr); +} + +/** +* Parse an H.245 H2250LogicalChannelParameters request packet and +* handle NAT/expectations for the logical channel address. +*/ +static int h245_parse_h2250_lchannel_params (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; +unsigned session_id; + +asn1_per_read_sequence_header (bb,1 ,10 , &hdr); + +/* nonStandard */ +if (asn1_per_bitmap_get (&hdr.present,0 )) +h245_skip_nonstandard_param (bb); + +/* sessionID */ + session_id =asn1_per_read_unsigned (bb,0 ,255 ); + +/* associatedSessionID */ +if (asn1_per_bitmap_get (&hdr.present,1 )) +asn1_per_read_unsigned (bb,1 ,255 ); + +/* mediaChannel */ +DEBUGP ("lchannel_params mediaChannel: i=%u bit=%u\n" , bb->i, bb->bit); +if (asn1_per_bitmap_get (&hdr.present,2 )) { +int dir =CTINFO2DIR (ctinfo); +struct ip_conntrack_expect *exp; +int ret; +unsigned i; +u_int32_t ip; +u_int16_t port; + + ret =h245_parse_transport_address (bb, &i, &ip, &port); +if (ret) +DEBUGP ("mediaChannel IPv4 address: %u.%u.%u.%u:%u\n" , +NIPQUAD (ip),ntohs (port)); +if (ret && ip == ct->tuplehash[dir].tuple.src.ip) { +/* match found: create an expectation */ + exp =ip_conntrack_expect_alloc (); +if (exp ==NULL ) +return NF_ACCEPT ; + + exp->tuple = ((struct ip_conntrack_tuple ) + { { ct->tuplehash[!dir].tuple.src.ip, + {0 } }, + { ct->tuplehash[!dir].tuple.dst.ip, + { .udp = { port } }, +IPPROTO_UDP }}); + exp->mask = ((struct ip_conntrack_tuple ) + { {0xFFFFFFFF , {0 } }, + {0xFFFFFFFF , { .udp = {0xFFFF } },0xFF }}); + + exp->master = ct; + +/* call NAT hook and register expectation */ +if (ip_nat_h245_hook !=NULL ) { +return ip_nat_h245_hook (pskb, ctinfo, i, + exp); + }else { +/* Can't expect this? Best to drop packet now. */ +if (ip_conntrack_expect_related (exp) !=0 ) { +ip_conntrack_expect_free (exp); +return NF_DROP ; + }else { +return NF_ACCEPT ; + } + } + } + } + +/* mediaGuaranteedDelivery */ +if (asn1_per_bitmap_get (&hdr.present,3 )) +asn1_per_read_bit (bb); + +/* mediaControlChannel */ +DEBUGP ("lchannel_params controlChannel: i=%u bit=%u\n" , bb->i, bb->bit); +if (asn1_per_bitmap_get (&hdr.present,4 )) { +int dir =CTINFO2DIR (ctinfo); +struct ip_conntrack_expect *exp; +int ret; +unsigned i; +u_int32_t ip; +u_int16_t port; + + ret =h245_parse_transport_address (bb, &i, &ip, &port); +if (ret) +DEBUGP ("mediaControlChannel IPv4 address: %u.%u.%u.%u:%u\n" , +NIPQUAD (ip),ntohs (port)); +if (ret && ip == ct->tuplehash[dir].tuple.src.ip) { +/* match found: create an expectation */ + exp =ip_conntrack_expect_alloc (); +if (exp ==NULL ) +return NF_ACCEPT ; + + exp->tuple = ((struct ip_conntrack_tuple ) + { { ct->tuplehash[!dir].tuple.src.ip, + {0 } }, + { ct->tuplehash[!dir].tuple.dst.ip, + { .udp = { port } }, +IPPROTO_UDP }}); + exp->mask = ((struct ip_conntrack_tuple ) + { {0xFFFFFFFF , {0 } }, + {0xFFFFFFFF , { .udp = {0xFFFF } },0xFF }}); + + exp->master = ct; + +/* call NAT hook and register expectation */ +if (ip_nat_h245_hook !=NULL ) { +return ip_nat_h245_hook (pskb, ctinfo, i, + exp); + }else { +/* Can't expect this? Best to drop packet now. */ +if (ip_conntrack_expect_related (exp) !=0 ) { +ip_conntrack_expect_free (exp); +return NF_DROP ; + }else { +return NF_ACCEPT ; + } + } + } + } + +/* mediaControlGuaranteedDelivery */ +if (asn1_per_bitmap_get (&hdr.present,5 )) +asn1_per_read_bit (bb); + +/* silenceSuppression */ +if (asn1_per_bitmap_get (&hdr.present,6 )) +asn1_per_read_bit (bb); + +/* destination */ +if (asn1_per_bitmap_get (&hdr.present,7 )) +h245_skip_terminal_label (bb); + +/* dynamicRTPPayloadType */ +if (asn1_per_bitmap_get (&hdr.present,8 )) +asn1_per_read_unsigned (bb,96 ,127 ); + +/* mediaPacketization */ +if (asn1_per_bitmap_get (&hdr.present,9 )) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,1 , &after); +switch (choice) { +case 0 :/* h261aVideoPacketization */ +break ; + +default : +if (after ==0 ) { +DEBUGP ("ERROR7\n" ); + bb->error =1 ; +return NF_ACCEPT ; + } + + bb->i = after; + } + } + +/* XXX */ + +asn1_per_skip_sequence_extension (bb, &hdr); + +return NF_ACCEPT ; +} + +/** +* Parse an H.245 OpenLogicalChannel request packet and handle +* NAT/expectations for the logical channel address. +*/ +static int h245_parse_open_lchannel (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr, hdr2; +unsigned forwardLogicalChannelNumber; +unsigned choice, after; + +asn1_per_read_sequence_header (bb,1 ,1 , &hdr); + + forwardLogicalChannelNumber =asn1_per_read_unsigned (bb,1 ,65535 ); + +/* entering forwardLogicalChannelParameters */ +asn1_per_read_sequence_header (bb,1 ,1 , &hdr2); +if (asn1_per_bitmap_get (&hdr2.present,0 )) +asn1_per_read_unsigned (bb,0 ,65535 ); + +h245_skip_data_type (bb); + +/* multiplexParameters */ + choice =asn1_per_read_choice_header (bb,1 ,3 , &after); +if (bb->error) +return NF_ACCEPT ; + +switch (choice) { +case 3 :/* h2250LogicalChannelParameters */ +h245_parse_h2250_lchannel_params (pskb, ct, ctinfo, bb); +break ; +default : +if (after ==0 ) { +DEBUGP ("unsupported multiplex_parameter %u\n" , choice); + bb->error =1 ; +return NF_ACCEPT ; + } + } + +if (bb->error) +return NF_ACCEPT ; + +if (after >0 ) + bb->i = after; + +asn1_per_skip_sequence_extension (bb, &hdr2); + +/* leaving multiplexParameters, forwardLogicalChannelParameters */ + +/* reverseLogicalChannelParameters */ +if (asn1_per_bitmap_get (&hdr.present,0 )) { +asn1_per_read_sequence_header (bb,1 ,1 , &hdr2); + +h245_skip_data_type (bb); + +/* multiplexParameters */ +if (asn1_per_bitmap_get (&hdr2.present,0 )) { + choice =asn1_per_read_choice_header (bb,1 ,2 , &after); +if (bb->error) +return NF_ACCEPT ; + +DEBUGP ("reverse_parameter multiplex=%u after=%u\n" , choice, after); + +switch (choice) { +case 2 :/* h2250LogicalChannelParameters */ +h245_parse_h2250_lchannel_params (pskb, ct, ctinfo, bb); +break ; +default : +if (after ==0 ) { +DEBUGP ("unsupported multiplex_parameter %u\n" , choice); + bb->error =1 ; +return NF_ACCEPT ; + } + } + +if (bb->error) +return NF_ACCEPT ; + +if (after >0 ) + bb->i = after; + } + +asn1_per_skip_sequence_extension (bb, &hdr2); + } + +asn1_per_skip_sequence_extension (bb, &hdr); + +/* XXX */ +return NF_ACCEPT ; +} + +/** +* Parse an H.245 request packet and handle NAT/expectations for the +* logical channel address. +*/ +static int h245_parse_request (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,11 , &after); +DEBUGP ("H.245: message_type=%u\n" , choice); +switch (choice) { +case 3 : +return h245_parse_open_lchannel (pskb, ct, ctinfo, bb); +default : +return NF_ACCEPT ; + } +} + +/** +* Parse an H.245 H222LogicalChannelParameters response packet and +* handle NAT/expectations for the logical channel address. +*/ +static int h245_parse_h222_lchannel_params (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; + +asn1_per_read_sequence_header (bb,1 ,3 , &hdr); + +if (bb->error) +return NF_ACCEPT ; + +/* resourceID */ +asn1_per_read_unsigned (bb,0 ,65535 ); + +/* subChannelID */ +asn1_per_read_unsigned (bb,0 ,8191 ); + +/* pcr-pid */ +if (asn1_per_bitmap_get (&hdr.present,0 )) +asn1_per_read_unsigned (bb,0 ,8191 ); + +/* programDescriptors */ +if (asn1_per_bitmap_get (&hdr.present,1 )) +asn1_per_skip_octet_string (bb); + +/* streamDescriptors */ +if (asn1_per_bitmap_get (&hdr.present,2 )) +asn1_per_skip_octet_string (bb); + +asn1_per_skip_sequence_extension (bb, &hdr); + +return NF_ACCEPT ; +} + +/** +* Parse an H.245 H2250LogicalChannelAckParameters response packet and +* handle NAT/expectations for the logical channel address. +*/ +static int h245_parse_h2250_lchannel_ack_params (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; +unsigned count; + +DEBUGP ("entering h245_parse_h2250_lchannel_ack_params\n" ); + +asn1_per_read_sequence_header (bb,1 ,5 , &hdr); + +/* nonStandard */ +if (asn1_per_bitmap_get (&hdr.present,0 )) { + count =asn1_per_read_length (bb,0 ,UINT_MAX ); +while (count >0 ) { +h245_skip_nonstandard_param (bb); +if (bb->error) +return NF_ACCEPT ; + } + } + +/* sessionID */ +if (asn1_per_bitmap_get (&hdr.present,1 )) +asn1_per_read_unsigned (bb,1 ,255 ); + +/* mediaChannel */ +if (asn1_per_bitmap_get (&hdr.present,2 )) { +int ret; +unsigned i; +u_int32_t ip; +u_int16_t port; +int dir =CTINFO2DIR (ctinfo); +struct ip_conntrack_expect *exp; + + ret =h245_parse_transport_address (bb, &i, &ip, &port); +DEBUGP ("entering mediaChannel ret=%d i=%u ip=%x port=%u\n" , + ret, i, ip, port); +if (ret && ip == ct->tuplehash[dir].tuple.src.ip) { +/* match found: create an expectation */ + exp =ip_conntrack_expect_alloc (); +if (exp ==NULL ) +return NF_ACCEPT ; + + exp->tuple = ((struct ip_conntrack_tuple ) + { { ct->tuplehash[!dir].tuple.src.ip, + {0 } }, + { ct->tuplehash[!dir].tuple.dst.ip, + { .udp = { port } }, +IPPROTO_UDP }}); + exp->mask = ((struct ip_conntrack_tuple ) + { {0xFFFFFFFF , {0 } }, + {0xFFFFFFFF , { .udp = {0xFFFF } },0xFF }}); + + exp->master = ct; + +/* call NAT hook and register expectation */ +if (ip_nat_h245_hook !=NULL ) { + ret =ip_nat_h245_hook (pskb, ctinfo, i, exp); +if (ret !=NF_ACCEPT ) +return ret; + }else { +/* Can't expect this? Best to drop packet now. */ +if (ip_conntrack_expect_related (exp) !=0 ) { +ip_conntrack_expect_free (exp); +return NF_DROP ; + }else { +return NF_ACCEPT ; + } + } + } + } + +/* mediaControlChannel */ +if (asn1_per_bitmap_get (&hdr.present,3 )) { +int ret; +unsigned i; +u_int32_t ip; +u_int16_t port; +int dir =CTINFO2DIR (ctinfo); +struct ip_conntrack_expect *exp; + + ret =h245_parse_transport_address (bb, &i, &ip, &port); +DEBUGP ("entering mediaControlChannel ret=%d i=%u ip=%x port=%u\n" , + ret, i, ip, port); +if (ret && ip == ct->tuplehash[dir].tuple.src.ip) { +/* match found: create an expectation */ + exp =ip_conntrack_expect_alloc (); +if (exp ==NULL ) +return NF_ACCEPT ; + + exp->tuple = ((struct ip_conntrack_tuple ) + { { ct->tuplehash[!dir].tuple.src.ip, + {0 } }, + { ct->tuplehash[!dir].tuple.dst.ip, + { .udp = { port } }, +IPPROTO_UDP }}); + exp->mask = ((struct ip_conntrack_tuple ) + { {0xFFFFFFFF , {0 } }, + {0xFFFFFFFF , { .udp = {0xFFFF } },0xFF }}); + + exp->master = ct; + +/* call NAT hook and register expectation */ +if (ip_nat_h245_hook !=NULL ) { + ret =ip_nat_h245_hook (pskb, ctinfo, i, exp); +if (ret !=NF_ACCEPT ) +return ret; + }else { +/* Can't expect this? Best to drop packet now. */ +if (ip_conntrack_expect_related (exp) !=0 ) { +ip_conntrack_expect_free (exp); +return NF_DROP ; + }else { +return NF_ACCEPT ; + } + } + } + } + +/* dynamicRTPPayloadType */ +if (asn1_per_bitmap_get (&hdr.present,1 )) +asn1_per_read_unsigned (bb,96 ,127 ); + +asn1_per_skip_sequence_extension (bb, &hdr); + +return NF_ACCEPT ; +} + +/** +* Parse an H.245 OpenLogicalChannelAck response packet and handle +* NAT/expectations for the logical channel address. +*/ +static int h245_parse_open_lchannel_ack (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr, hdr2; +struct asn1_per_sequence_extension_header ext; +unsigned forwardLogicalChannelNumber; +unsigned choice, after, after2, i; + +asn1_per_read_sequence_header (bb,1 ,1 , &hdr); + + forwardLogicalChannelNumber =asn1_per_read_unsigned (bb,1 ,65535 ); +DEBUGP ("forwardLogicalChannelNumber=%u\n" , forwardLogicalChannelNumber); + +/* reverseLogicalChannelParameters */ +if (asn1_per_bitmap_get (&hdr.present,0 )) { +DEBUGP ("reverseLogicalChannelParameters present\n" ); +asn1_per_read_sequence_header (bb,1 ,2 , &hdr2); + +/* reverseLogicalChannelNumber */ +asn1_per_read_unsigned (bb,1 ,65535 ); + +/* portNumber */ +if (asn1_per_bitmap_get (&hdr.present,0 )) +asn1_per_read_unsigned (bb,0 ,65535 ); + +/* multiplexParameters */ +if (asn1_per_bitmap_get (&hdr2.present,1 )) { + choice =asn1_per_read_choice_header (bb,1 ,1 , &after); +if (bb->error) +return NF_ACCEPT ; + +switch (choice) { +case 0 :/* h222LogicalChannelParameters */ +h245_parse_h222_lchannel_params (pskb, ct, + ctinfo, bb); +break ; +case 1 :/* h2250LogicalChannelParameters */ +h245_parse_h2250_lchannel_params (pskb, ct, + ctinfo, bb); +break ; +default : +if (after ==0 ) { +DEBUGP ("unsupported multiplex_parameter %u\n" , choice); + bb->error =1 ; +return NF_ACCEPT ; + } + } + +if (bb->error) +return NF_ACCEPT ; + +if (after >0 ) + bb->i = after; + } + +asn1_per_skip_sequence_extension (bb, &hdr2); + } + +asn1_per_read_sequence_extension_header (bb, &hdr, &ext); +if (bb->error) +return NF_ACCEPT ; + +/* separateStack */ +if (asn1_per_bitmap_get (&ext.present,0 )) +asn1_per_skip_octet_string (bb); + +/* forwardMultiplexAckParameters */ +if (asn1_per_bitmap_get (&ext.present,1 )) { +DEBUGP ("forwardMultiplexAckParameters present\n" ); + + after =asn1_per_read_octet_string_header (bb); +DEBUGP ("forwardMultiplexAckParameters present length=%u i=%u after=%u end=%u\n" , + after, bb->i, bb->i + after, bb->length); + after += bb->i; + + choice =asn1_per_read_choice_header (bb,1 ,1 , &after2); +if (bb->error) +return NF_ACCEPT ; + +DEBUGP ("entering forwardMultiplexAckParameters choice=%u after=%u\n" , choice, after2); + +switch (choice) { +case 0 :/* h2250LogicalChannelAckParameters */ +h245_parse_h2250_lchannel_ack_params (pskb, ct, + ctinfo, bb); +break ; + } + +if (bb->error) +return NF_ACCEPT ; + + bb->i = after; + } + +for (i =2 ; i < ext.count; i++) +if (asn1_per_bitmap_get (&ext.present, i)) +asn1_per_skip_octet_string (bb); + +return NF_ACCEPT ; +} + +/** +* Parse an H.245 response packet and handle NAT/expectations for the +* logical channel address. +*/ +static int h245_parse_response (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,19 , &after); +DEBUGP ("H.245: response type=%u\n" , choice); +switch (choice) { +case 5 :/* openLogicalChannelAck */ +return h245_parse_open_lchannel_ack (pskb, ct, ctinfo, bb); + +default : +return NF_ACCEPT ; + } +} + +/** +* Parse an H.245 packet and handle NAT/expectations for the logical +* channel address. +*/ +static int h245_parse (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,4 , &after); +DEBUGP ("H.245: message_class=%u\n" , choice); +switch (choice) { +case 0 : +return h245_parse_request (pskb, ct, ctinfo, bb); +case 1 : +return h245_parse_response (pskb, ct, ctinfo, bb); +default : +return NF_ACCEPT ; + } +} + +/** +* Parse a TPKT/H.245 packet and handle NAT/expectations for the +* logical channel transport address (if applicable). +*/ +static int h245_parse_tpkt (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +const unsigned char *data, +unsigned datalen) { +unsigned int i =0 ; +u_int16_t tpkt_len; +struct asn1_per_buffer bb; + +/* expect TPKT header, see RFC 1006 */ +if (data[0 ] !=0x03 || data[1 ] !=0x00 ) +return NF_ACCEPT ; + + i +=2 ; + + tpkt_len =ntohs (*(u_int16_t *)(data + i)); +if (tpkt_len <16 ) +return NF_ACCEPT ; + +if (tpkt_len < datalen) + datalen = tpkt_len; + + i +=2 ; + +/* parse H.245 packet (ASN.1 PER) */ +asn1_per_initialize (&bb, data, datalen, i); + +return h245_parse (pskb, ct, ctinfo, &bb); +} +static int h245_help (struct sk_buff **pskb,struct ip_conntrack *ct,enum ip_conntrack_info ctinfo) {struct tcphdr _tcph, *tcph;unsigned char *data; -unsigned char *data_limit;unsigned dataoff, datalen; -int dir =CTINFO2DIR (ctinfo); -struct ip_conntrack_expect *exp; -u_int16_t data_port; -u_int32_t data_ip; -unsigned int i;int ret;/* Until there's been traffic both ways, don't look in packets. */
@@ -84,56 +927,9 @@ datalen, h245_buffer);BUG_ON (data ==NULL ); - data_limit = data + datalen -6 ; -/* bytes: 0123 45 -ipadrr port */ -for (i =0 ; data <= data_limit; data++, i++) { - data_ip = *((u_int32_t *)data); -if (data_ip == ct->tuplehash[dir].tuple.src.ip) { - data_port = *((u_int16_t *)(data +4 )); - -/* update the H.225 info */ -DEBUGP ("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n" , -NIPQUAD (ct->tuplehash[!dir].tuple.src.ip), -NIPQUAD ((*pskb)->nh.iph->saddr),ntohs (data_port)); - - exp =ip_conntrack_expect_alloc (); -if (exp ==NULL ) { - ret =NF_ACCEPT ; - goto out; - } - - exp->tuple = ((struct ip_conntrack_tuple ) - { { ct->tuplehash[!dir].tuple.src.ip, - {0 } }, - { data_ip, - { .tcp = { data_port } }, -IPPROTO_UDP }}); - exp->mask = ((struct ip_conntrack_tuple ) - { {0xFFFFFFFF , {0 } }, - {0xFFFFFFFF , { .tcp = {0xFFFF } },0xFF }}); - - exp->expectfn =NULL ; - exp->master = ct; - -if (ip_nat_h245_hook !=NULL ) { - ret =ip_nat_h245_hook (pskb, ctinfo, i, - exp); - }else { -/* Can't expect this? Best to drop packet now. */ -if (ip_conntrack_expect_related (exp) !=0 ) { -ip_conntrack_expect_free (exp); - ret =NF_DROP ; - }else - ret =NF_ACCEPT ; - } - -break ; - } - } + ret =h245_parse_tpkt (pskb, ct, ctinfo, + data, datalen); - ret =NF_ACCEPT ; - out:UNLOCK_BH (&ip_h245_lock);return ret; }
Quoted 6 lines · Max Kellermann
Hi,
the following patchset replaces Jozsef's "brute force" parser with a real H.245 parser. It adds a very simple ASN.1/PER parsing library, and parses very few H.245 structures (enough for all H.323 software I tested).
Thanks, this is great news. Including the list of tested h.323 software somwhere in the 'info' or 'help' file would definitely be a good idea.
I'd happily apply your patches but leave it up to Jozsef, since he's more familiar with the protocol and the helper he wrote.
Signature · 5 lines
- Harald Welte <[email protected]> http://netfilter.org/ ============================================================================ "Fragmentation is like classful addressing -- an interesting early architectural error that shows how much experimentation was going on while IP was being designed." -- Paul Vixie
[PATCH pom-ng 7/6] H.323: reimplement the H.225 parser using the ASN.1/PER library
In reply to Max KellermannAn additional patch to this patch series, which I developed today:
h323-07-reimplement_h225_parser_with_asn1_per.patch
- reimplement the H.225 parser using the ASN.1/PER library
Wed May 11 11:35:03 CEST 2005 [email protected]
* reimplement the H.225 parser using the ASN.1/PER library
h323-conntrack-nat/linux-2.6.11/net/ipv4/netfilter/ip_conntrack_h323_h225.c +160 -58
@@ -20,6 +20,8 @@#include <linux/netfilter_ipv4/ip_conntrack_tuple.h> #include <linux/netfilter_ipv4/ip_conntrack_h323.h> +#include "asn1_per.h" +/* This is slow, but it's simple. --RR */ static char h225_buffer[65536 ];
@@ -46,6 +48,161 @@#endif /** +* Parse an H.225 TransportAddress and return the position of the IP +* address (if present). Returns 1 on success. +*/ +static int h225_parse_transport_address (struct asn1_per_buffer *bb,unsigned *i, +u_int32_t *ip,u_int16_t *port) { +unsigned choice, after; + + choice =asn1_per_read_choice_header (bb,1 ,7 , &after); +if (bb->error) +return 0 ; + +switch (choice) { +case 0 :/* ipAddress */ +asn1_per_byte_align (bb); + *i = bb->i; +asn1_per_read_bytes (bb, ip,sizeof (*ip)); +asn1_per_read_bytes (bb, port,sizeof (*port)); +return !bb->error; + +default : +if (after ==0 ) { +DEBUGP ("TransportAddress %u not yet supported\n" , choice); + bb->error =1 ; + }else { + bb->i = after; + } +return 0 ; + } +} + +/** +* Parse a H.225 Connect-UUIE packet and handle NAT/expectations for +* the H.245 transport address. +*/ +static int h225_parse_connect_uuie (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; + +asn1_per_read_sequence_header (bb,1 ,1 , &hdr); + +/* protocolIdentifier */ +asn1_per_skip_object_id (bb); + +/* h245Address */ +if (asn1_per_bitmap_get (&hdr.present,0 )) { +int dir =CTINFO2DIR (ctinfo); +struct ip_conntrack_expect *exp; +int ret; +unsigned i; +u_int32_t ip; +u_int16_t port; + + ret =h225_parse_transport_address (bb, &i, &ip, &port); +if (ret) { +DEBUGP ("H.245 transportAddress: %u.%u.%u.%u:%u\n" , +NIPQUAD (ip),ntohs (port)); + } +if (ret && ip == ct->tuplehash[dir].tuple.src.ip) { +/* match found: create an expectation */ + exp =ip_conntrack_expect_alloc (); +if (exp ==NULL ) +return NF_ACCEPT ; + + exp->tuple = ((struct ip_conntrack_tuple ) + { { ct->tuplehash[!dir].tuple.src.ip, + {0 } }, + { ct->tuplehash[!dir].tuple.dst.ip, + { .tcp = { port } }, +IPPROTO_TCP }}); + exp->mask = ((struct ip_conntrack_tuple ) + { {0xFFFFFFFF , {0 } }, + {0xFFFFFFFF , { .tcp = {0xFFFF } },0xFF }}); + + exp->expectfn = ip_conntrack_h245_expect; + exp->master = ct; + +/* call NAT hook and register expectation */ +if (ip_nat_h225_hook !=NULL ) { +return ip_nat_h225_hook (pskb, ctinfo, i, + exp); + }else { +/* Can't expect this? Best to drop packet now. */ +if (ip_conntrack_expect_related (exp) !=0 ) { +ip_conntrack_expect_free (exp); +return NF_DROP ; + }else { +return NF_ACCEPT ; + } + } + } + } + +/* XXX */ + bb->error =1 ; + +asn1_per_skip_sequence_extension (bb, &hdr); + +return NF_ACCEPT ; +} + +/** +* Parse a H.225 H323-UU-PDU packet and handle NAT/expectations for +* the H.245 transport address. +*/ +static int h225_parse_uu_pdu (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; +unsigned choice, after; +int ret; + +asn1_per_read_sequence_header (bb,1 ,1 , &hdr); + +/* h323-message-body */ + choice =asn1_per_read_choice_header (bb,1 ,7 , &after); +switch (choice) { +case 2 :/* connect */ + ret =h225_parse_connect_uuie (pskb, ct, ctinfo, bb); +if (ret !=NF_ACCEPT ) +return ret; +break ; + +default : +if (after ==0 ) { + bb->error =1 ; +return NF_ACCEPT ; + } + + bb->i = after; + } + +asn1_per_skip_sequence_extension (bb, &hdr); + +return NF_ACCEPT ; +} + +/** +* Parse a H.225 packet and handle NAT/expectations for the H.245 +* transport address. +*/ +static int h225_parse (struct sk_buff **pskb, +struct ip_conntrack *ct, +enum ip_conntrack_info ctinfo, +struct asn1_per_buffer *bb) { +struct asn1_per_sequence_header hdr; + +asn1_per_read_sequence_header (bb,1 ,1 , &hdr); + +return h225_parse_uu_pdu (pskb, ct, ctinfo, bb); +} + +/** * Parse a Q.931 CONNECT packet and handle NAT/expectations for the * H.245 transport address. */
@@ -55,10 +212,7 @@const unsigned char *data, unsigned i, unsigned length) { - int dir = CTINFO2DIR(ctinfo); -u_int32_t data_ip; -u_int16_t data_port; -struct ip_conntrack_expect *exp; + struct asn1_per_buffer bb;/* protocol(1) + header(3) + protocolIdentifier(6) + h245ipAddress(1) + h245ipv4(4) + h245ipv4port(2) */
@@ -68,61 +222,9 @@if (data[i++] !=0x05 )/* X.208 / X.209 */ return NF_ACCEPT ; -/* XXX: h225 header connect? */ -if (data[i++] !=0x22 || data[i++] !=0xc0 || data[i++] !=0x06 ) -return NF_ACCEPT ; +asn1_per_initialize (&bb, data, length, i); -/* protocolIdentifier, ignore the last 2 bytes (minor -version) */ -if (memcmp (data + i,"\x00\x08\x91\x4a" ,4 ) !=0 ) -return NF_ACCEPT ; - - i +=6 ; - -if (data[i++] !=0x00 )/* h245ipAddress? */ -return NF_ACCEPT ; - -/* compare the IP address - this is only a valid H.245 -transport address, if it equals the source address of the -packet */ - data_ip = *(u_int32_t *)(data + i); -if (data_ip != ct->tuplehash[dir].tuple.src.ip) -return NF_ACCEPT ; - - - data_port = *((u_int16_t *)(data + i +4 )); - -/* match found: create an expectation */ - exp =ip_conntrack_expect_alloc (); -if (exp ==NULL ) -return NF_ACCEPT ; - - exp->tuple = ((struct ip_conntrack_tuple ) - { { ct->tuplehash[!dir].tuple.src.ip, - {0 } }, - { ct->tuplehash[!dir].tuple.dst.ip, - { .tcp = { data_port } }, -IPPROTO_TCP }}); - exp->mask = ((struct ip_conntrack_tuple ) - { {0xFFFFFFFF , {0 } }, - {0xFFFFFFFF , { .tcp = {0xFFFF } },0xFF }}); - - exp->expectfn = ip_conntrack_h245_expect; - exp->master = ct; - -/* call NAT hook and register expectation */ -if (ip_nat_h225_hook !=NULL ) { -return ip_nat_h225_hook (pskb, ctinfo, i, - exp); - }else { -/* Can't expect this? Best to drop packet now. */ -if (ip_conntrack_expect_related (exp) !=0 ) { -ip_conntrack_expect_free (exp); -return NF_DROP ; - }else { -return NF_ACCEPT ; - } - } +return h225_parse (pskb, ct, ctinfo, &bb); }/**
Re: [PATCH pom-ng 7/6] H.323: reimplement the H.225 parser using the ASN.1/PER library
Quoted 4 lines · Max Kellermann
An additional patch to this patch series, which I developed today:
h323-07-reimplement_h225_parser_with_asn1_per.patch
- reimplement the H.225 parser using the ASN.1/PER library
All applied, great work Max.