On 3/5/11 7:44 AM, Tom Eastep wrote:
> On 3/5/11 4:18 AM, Evi1M4chine wrote:
>> Hello,
>>
>> I see that giving multiple ICMP types in rules.conf is now blocked, 
>> despite giving multiple ports still being allowed. What’s the reason for 
>> this inconsistency?
> 
> Netfilter supports multiple ports in a single rule -- it does not
> support multiple ICMP types. Shorewall-shell had a hack that allowed
> multiple ICMP types but it resulted in horrible code structure. I did
> not want that bad structure in Shorewall-perl.
> 

Actually, there is good news. I had originally taken a similar decision
with respect to port lists in that Shorewall-perl did not originally
support port lists with more than 15 ports, even though that was
supported by Shorewall-shell. I later came up with a way to post-process
rules with large port lists and break them into multiple rules.

The attached patch does the same for ICMP lists. It applies with offsets
to Shorewall 4.4.15 (which is what I believe Gentoo currently supports):

        patch /usr/share/shorewall/Shorewall/Chains < ICMPLISTS.patch

This patch will be included in Shorewall 4.4.19.

-Tom
-- 
Tom Eastep        \ When I die, I want to go like my Grandfather who
Shoreline,         \ died peacefully in his sleep. Not screaming like
Washington, USA     \ all of the passengers in his car
http://shorewall.net \________________________________________________
diff --git a/Shorewall/Perl/Shorewall/Chains.pm 
b/Shorewall/Perl/Shorewall/Chains.pm
index 42d6c64..dac5cf6 100644
--- a/Shorewall/Perl/Shorewall/Chains.pm
+++ b/Shorewall/Perl/Shorewall/Chains.pm
@@ -617,6 +617,16 @@ sub handle_port_list( $$$$$$ ) {
 }
 
 #
+# This much simpler function splits a rule with an icmp type list into 
discrete rules
+#
+
+sub handle_icmptype_list( $$$$ ) {
+    my ($chainref, $first, $types, $rest) = @_;
+    my @ports = split ',', $types;
+    push_rule ( $chainref, join ( '', $first, shift @ports, $rest ) ) while 
@ports;
+}
+
+#
 # Add a rule to a chain. Arguments are:
 #
 #    Chain reference , Rule [, Expand-long-port-lists ]
@@ -645,6 +655,17 @@ sub add_rule($$;$) {
            # Rule has a --sports specification
            #
            handle_port_list( $chainref, $rule, 0, $1, $2, $3 )
+       } elsif ( $rule =~ /^(.* --icmp(?:v6)?-type\s*)([^ ]+)(.*)$/ ) {
+           #
+           # ICMP rule -- split it up if necessary
+           #
+           my ( $first, $types, $rest ) = ($1, $2, $3 );
+
+           if ( $types =~ /,/ ) {
+               handle_icmptype_list( $chainref, $first, $types, $rest );
+           } else {
+               push_rule( $chainref, $rule );
+           }
        } else {
            push_rule ( $chainref, $rule );
        }
@@ -2203,7 +2224,15 @@ sub do_proto( $$$;$ )
                        if ( $ports =~ tr/,/,/ > 0 || $sports =~ tr/,/,/ > 0 || 
$proto == UDPLITE ) {
                            fatal_error "Port lists require Multiport support 
in your kernel/iptables" unless have_capability( 'MULTIPORT' );
                            fatal_error "Multiple ports not supported with 
SCTP" if $proto == SCTP;
-                           fatal_error "A port list in this file may only have 
up to 15 ports" if $restricted && port_count( $ports ) > 15;
+
+                           if ( port_count ( $ports ) > 15 ) {
+                               if ( $restricted ) {
+                                   fatal_error "A port list in this file may 
only have up to 15 ports";
+                               } elsif ( $invert ) {
+                                   fatal_error "An inverted port list may only 
have up to 15 ports";
+                               }
+                           }
+
                            $ports = validate_port_list $pname , $ports;
                            $output .= "-m multiport ${invert}--dports ${ports} 
";
                            $multiport = 1;
@@ -2218,7 +2247,15 @@ sub do_proto( $$$;$ )
                    if ( $sports ne '' ) {
                        $invert = $sports =~ s/^!// ? '! ' : '';
                        if ( $multiport ) {
-                           fatal_error "A port list in this file may only have 
up to 15 ports" if $restricted && port_count( $sports ) > 15;
+
+                           if ( port_count( $sports ) > 15 ) {
+                               if ( $restricted ) {
+                                   fatal_error "A port list in this file may 
only have up to 15 ports";
+                               } elsif ( $invert ) {
+                                   fatal_error "An inverted port list may only 
have up to 15 ports";
+                               }
+                           }
+
                            $sports = validate_port_list $pname , $sports;
                            $output .= "-m multiport ${invert}--sports 
${sports} ";
                        }  else {
@@ -2233,9 +2270,20 @@ sub do_proto( $$$;$ )
                    fatal_error "ICMP not permitted in an IPv6 configuration" 
if $family == F_IPV6; #User specified proto 1 rather than 'icmp'
                    if ( $ports ne '' ) {
                        $invert = $ports =~ s/^!// ? '! ' : '';
-                       fatal_error 'Multiple ICMP types are not permitted' if 
$ports =~ /,/;
-                       $ports = validate_icmp $ports;
-                       $output .= "${invert}--icmp-type ${ports} ";
+
+                       my $types;
+
+                       if ( $ports =~ /,/ ) {
+                           fatal_error "An inverted ICMP list may only contain 
a single type" if $invert;
+                           $types = '';
+                           for my $type ( split /,/, $ports ) {
+                               $types = $types ? join( ',', $types, 
validate_icmp( $type ) ) : $type;
+                           }
+                       } else {
+                           $types = validate_icmp $ports;
+                       }
+
+                       $output .= "${invert}--icmp-type ${types} ";
                    }
 
                    fatal_error 'SOURCE PORT(S) not permitted with ICMP' if 
$sports ne '';
@@ -2246,9 +2294,20 @@ sub do_proto( $$$;$ )
                    fatal_error "IPv6_ICMP not permitted in an IPv4 
configuration" if $family == F_IPV4;
                    if ( $ports ne '' ) {
                        $invert = $ports =~ s/^!// ? '! ' : '';
-                       fatal_error 'Multiple ICMP types are not permitted' if 
$ports =~ /,/;
-                       $ports = validate_icmp6 $ports;
-                       $output .= "${invert}--icmpv6-type ${ports} ";
+
+                       my $types;
+
+                       if ( $ports =~ /,/ ) {
+                           fatal_error "An inverted ICMP list may only contain 
a single type" if $invert;
+                           $types = '';
+                           for my $type ( split /,/, $ports ) {
+                               $types = $types ? join( ',', $types, 
validate_icmp6( $type ) ) : $type;
+                           }
+                       } else {
+                           $types = validate_icmp6 $ports;
+                       }
+
+                       $output .= "${invert}--icmpv6-type ${types} ";
                    }
 
                    fatal_error 'SOURCE PORT(S) not permitted with IPv6-ICMP' 
if $sports ne '';

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
What You Don't Know About Data Connectivity CAN Hurt You
This paper provides an overview of data connectivity, details
its effect on application quality, and explores various alternative
solutions. http://p.sf.net/sfu/progress-d2d
_______________________________________________
Shorewall-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/shorewall-users

Reply via email to