~ubuntu-branches/ubuntu/wily/libiptables-chainmgr-perl/wily

« back to all changes in this revision

Viewing changes to lib/IPTables/ChainMgr.pm

  • Committer: Package Import Robot
  • Author(s): Fabrizio Regalli, Franck Joncourt, gregor herrmann, Ansgar Burchardt, Fabrizio Regalli
  • Date: 2012-02-27 16:54:38 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20120227165438-qnie2z6hrkqwadka
Tags: 0.9.9-1
[ Franck Joncourt ]
* Swith to dh 7
  Updated d.{control,compat,rules}
* Bumped up Standards-Version to 3.8.3:
  + Removed old versionned perl BD.
* Refreshed both d.control and d.copyright with my new email address.
* Switch to dpkg-source 3.0 (quilt) format.

[ gregor herrmann ]
* Set Standards-Version to 3.9.1; replace Conflicts with Breaks.

[ Ansgar Burchardt ]
* debian/control: Convert Vcs-* fields to Git.

[ Fabrizio Regalli ]
* Imported Upstream version 0.9.9
* d/copyright:
  + Updated using copyright-format 1.0
  + Changed Upstream-Maintainer in Upstream-Contact
  + Changed Upstream-Source in Source
  + Updated both licenses text
  + Added Martín Ferrari to debian/* copyright files
  + Changed "|" with "or" in license type
  + Added myself to debian/* copyright files
  + Updated year
* Updated d/compat to 8
* Updated debhelper to (>= 8)
* Bump Standards-Version to 3.9.3
* Added myself to Uploaders
* Changed Homepage in d/control using default search.cpan.org
* Added libnetaddr-ip-perl in B-D-I and Depends
* Removed {Breaks,Replaces} psad (<= 2.1.2-1) in d/control

[ gregor herrmann ]
* debian/watch: fix CPAN URL, and drop the other location.
* Drop (build) dependency on libnetwork-ipv4addr-perl.

Show diffs side-by-side

added added

removed removed

Lines of Context:
10
10
#
11
11
# Author: Michael Rash (mbr@cipherdyne.org)
12
12
#
13
 
# Version: 0.9
 
13
# Version: 0.9.9
14
14
#
15
15
##############################################################################
16
16
#
17
 
# $Id: ChainMgr.pm 990 2008-02-02 19:01:21Z mbr $
18
 
#
19
17
 
20
18
package IPTables::ChainMgr;
21
19
 
23
21
use POSIX ':sys_wait_h';
24
22
use Carp;
25
23
use IPTables::Parse;
26
 
use Net::IPv4Addr 'ipv4_network';
 
24
use NetAddr::IP;
27
25
use strict;
28
26
use warnings;
29
27
use vars qw($VERSION);
30
28
 
31
 
$VERSION = '0.9';
 
29
$VERSION = '0.9.9';
32
30
 
33
31
sub new() {
34
32
    my $class = shift;
49
47
        unless -e $self->{'_iptables'};
50
48
    croak "[*] $self->{'_iptables'} not executable.\n"
51
49
        unless -x $self->{'_iptables'};
 
50
 
 
51
    $self->{'_ipt_bin_name'} = 'iptables';
 
52
    $self->{'_ipt_bin_name'} = $1 if $self->{'_iptables'} =~ m|.*/(\S+)|;
 
53
 
52
54
    bless $self, $class;
53
55
}
54
56
 
55
57
sub chain_exists() {
56
58
    my $self = shift;
57
59
    my $table = shift || croak '[*] Must specify a table, e.g. "filter".';
58
 
    my $chain = shift || croak '[*] Must specify a chain to create.';
 
60
    my $chain = shift || croak '[*] Must specify a chain to check.';
59
61
    my $iptables = $self->{'_iptables'};
60
62
 
61
63
    ### see if the chain exists
110
112
    ### could not flush the chain
111
113
    return 0, $out_aref, $err_aref unless $rv;
112
114
 
 
115
    my $ip_any_net = '0.0.0.0/0';
 
116
    $ip_any_net = '::/0' if $self->{'_ipt_bin_name'} eq 'ip6tables';
 
117
 
113
118
    ### find and delete jump rules to this chain (we can't delete
114
119
    ### the chain until there are no references to it)
115
120
    my ($rulenum, $num_chain_rules)
116
 
        = $self->find_ip_rule('0.0.0.0/0',
117
 
            '0.0.0.0/0', $table, $jump_from_chain, $del_chain, {});
 
121
        = $self->find_ip_rule($ip_any_net, $ip_any_net,
 
122
            $table, $jump_from_chain, $del_chain, {});
118
123
 
119
124
    if ($rulenum) {
120
125
        $self->run_ipt_cmd(
152
157
 
153
158
    if ($rule_position) {
154
159
        my $msg = '';
155
 
        if ($extended_href) {
 
160
        if (keys %$extended_href) {
156
161
            $msg = "Table: $table, chain: $chain, $normalized_src -> " .
157
162
                "$normalized_dst ";
158
 
            for my $key qw(protocol s_port d_port mac_source) {
 
163
            for my $key (qw(protocol s_port d_port mac_source)) {
159
164
                $msg .= "$key $extended_href->{$key} "
160
165
                    if defined $extended_href->{$key};
161
166
            }
172
177
    my $msg     = '';
173
178
    my $idx_err = '';
174
179
 
175
 
    if ($extended_href) {
 
180
    if (keys %$extended_href) {
176
181
        $ipt_cmd = "$iptables -t $table -A $chain ";
177
182
        $ipt_cmd .= "-p $extended_href->{'protocol'} "
178
183
            if defined $extended_href->{'protocol'};
188
193
 
189
194
        $msg = "Table: $table, chain: $chain, added $normalized_src " .
190
195
            "-> $normalized_dst ";
191
 
        for my $key qw(protocol s_port d_port mac_source) {
 
196
        for my $key (qw(protocol s_port d_port mac_source)) {
192
197
            $msg .= "$key $extended_href->{$key} "
193
198
                if defined $extended_href->{$key};
194
199
        }
241
246
 
242
247
    if ($rule_position) {
243
248
        my $msg = '';
244
 
        if ($extended_href) {
 
249
        if (keys %$extended_href) {
245
250
            $msg = "Table: $table, chain: $chain, $normalized_src -> " .
246
251
                "$normalized_dst ";
247
 
            for my $key qw(protocol s_port d_port mac_source) {
 
252
            for my $key (qw(protocol s_port d_port mac_source)) {
248
253
                $msg .= "$key $extended_href->{$key} "
249
254
                    if defined $extended_href->{$key};
250
255
            }
271
276
    }
272
277
    $rulenum = 1 if $rulenum == 0;
273
278
 
274
 
    if ($extended_href) {
 
279
    if (keys %$extended_href) {
275
280
        $ipt_cmd = "$iptables -t $table -I $chain $rulenum ";
276
281
        $ipt_cmd .= "-p $extended_href->{'protocol'} "
277
282
            if defined $extended_href->{'protocol'};
287
292
 
288
293
        $msg = "Table: $table, chain: $chain, added $normalized_src " .
289
294
            "-> $normalized_dst ";
290
 
        for my $key qw(protocol s_port d_port mac_source) {
 
295
        for my $key (qw(protocol s_port d_port mac_source)) {
291
296
            $msg .= "$key $extended_href->{$key} "
292
297
                if defined $extended_href->{$key};
293
298
        }
343
348
    }
344
349
 
345
350
    my $extended_msg = '';
346
 
    if ($extended_href) {
347
 
        for my $key qw(protocol s_port d_port mac_source) {
 
351
    if (keys %$extended_href) {
 
352
        for my $key (qw(protocol s_port d_port mac_source)) {
348
353
            $extended_msg .= "$key: $extended_href->{$key} "
349
354
                if defined $extended_href->{$key};
350
355
        }
370
375
    my $chain = shift || croak '[*] Must specify iptables chain.';
371
376
    my $target = shift ||
372
377
        croak '[*] Must specify iptables target (this may be a chain).';
 
378
 
373
379
    ### optionally add port numbers and protocols, etc.
374
380
    my $extended_href = shift || {};
375
381
    my $iptables = $self->{'_iptables'};
396
402
 
397
403
    my $chain_aref = $ipt_parse->chain_rules($table, $chain);
398
404
 
 
405
    $src = $self->normalize_net($src) if defined $extended_href->{'normalize'}
 
406
        and $extended_href->{'normalize'};
 
407
    $dst = $self->normalize_net($dst) if defined $extended_href->{'normalize'}
 
408
        and $extended_href->{'normalize'};
 
409
 
399
410
    my $rulenum = 1;
400
411
    for my $rule_href (@$chain_aref) {
401
412
        if ($rule_href->{'target'} eq $target
402
413
                and $rule_href->{'src'} eq $src
403
414
                and $rule_href->{'dst'} eq $dst) {
404
 
            if ($extended_href) {
 
415
            if (keys %$extended_href) {
405
416
                my $found = 1;
406
 
                for my $key qw(
 
417
                for my $key (qw(
407
418
                    protocol
408
419
                    s_port
409
420
                    d_port
410
421
                    to_ip
411
422
                    to_port
412
 
                ) {
 
423
                )) {
413
424
                    if (defined $extended_href->{$key}) {
414
425
                        unless ($extended_href->{$key}
415
426
                                eq $rule_href->{$key}) {
442
453
    my $self = shift;
443
454
    my $net  = shift || croak '[*] Must specify net.';
444
455
 
445
 
    ### regex to match an IP address
446
 
    my $ip_re = '(?:\d{1,3}\.){3}\d{1,3}';
447
 
 
448
 
    my $normalized_net = '';
449
 
    if ($net =~ m|($ip_re)/($ip_re)|) {
450
 
        my ($net_addr, $cidr) = ipv4_network($1, $2);
451
 
        $normalized_net = "$net_addr/$cidr";
452
 
    } elsif ($net =~ m|($ip_re)/(\d+)|) {
453
 
        my ($net_addr, $cidr) = ipv4_network($1, $2);
454
 
        $normalized_net = "$net_addr/$cidr";
455
 
    } else {
456
 
        ### it is a hostname or an individual IP
457
 
        $normalized_net = $net;
 
456
    my $normalized_net = $net;  ### establish default
 
457
 
 
458
    ### regex to match an IPv4 address
 
459
    my $ipv4_re = qr/(?:\d{1,3}\.){3}\d{1,3}/;
 
460
 
 
461
    if ($net =~ m|/| and $net =~ $ipv4_re or $net =~ m|:|) {
 
462
        if ($net =~ m|:|) {  ### an IPv6 address
 
463
            my $n = new6 NetAddr::IP $net
 
464
                or croak "[*] Could not acquire NetAddr::IP object for $net";
 
465
            $normalized_net = lc($n->network()->short()) . '/' . $n->masklen();
 
466
        } else {
 
467
            my $n = new NetAddr::IP $net
 
468
                or croak "[*] Could not acquire NetAddr::IP object for $net";
 
469
            $normalized_net = $n->network()->cidr();
 
470
        }
458
471
    }
459
472
    return $normalized_net;
460
473
}
473
486
            "not allowed."], [];
474
487
    }
475
488
 
 
489
    my $ip_any_net = '0.0.0.0/0';
 
490
    $ip_any_net = '::/0' if $self->{'_ipt_bin_name'} eq 'ip6tables';
 
491
 
476
492
    ### first check to see if the jump rule already exists
477
493
    my ($rule_position, $num_chain_rules)
478
 
        = $self->find_ip_rule('0.0.0.0/0', '0.0.0.0/0', $table,
 
494
        = $self->find_ip_rule($ip_any_net, $ip_any_net, $table,
479
495
            $from_chain, $to_chain, {});
480
496
 
481
497
    ### check to see if the insertion index ($rulenum) is too big
523
539
    my $ipt_exec_sleep = $self->{'_ipt_exec_sleep'};
524
540
    my $sigchld_handler = $self->{'_sigchld_handler'};
525
541
 
 
542
 
526
543
    croak "[*] $cmd does not look like an iptables command."
527
 
        unless $cmd =~ m|^\s*iptables| or $cmd =~ m|^\S+/iptables|;
 
544
        unless $cmd =~ m|^\s*iptables| or $cmd =~ m|^\S+/iptables|
 
545
            or $cmd =~ m|^\s*ip6tables| or $cmd =~ m|^\S+/ip6tables|;
528
546
 
529
547
    my $rv = 1;
530
548
    my @stdout = ();
633
651
 
634
652
=head1 NAME
635
653
 
636
 
IPTables::ChainMgr - Perl extension for manipulating iptables policies
 
654
IPTables::ChainMgr - Perl extension for manipulating iptables and ip6tables policies
637
655
 
638
656
=head1 SYNOPSIS
639
657
 
640
658
  use IPTables::ChainMgr;
641
659
 
 
660
  my $ipt_bin = '/sbin/iptables'; # can set this to /sbin/ip6tables
 
661
 
642
662
  my %opts = (
643
 
      'iptables' => '/sbin/iptables',
 
663
      'iptables' => $ipt_bin,
644
664
      'iptout'   => '/tmp/iptables.out',
645
665
      'ipterr'   => '/tmp/iptables.err',
646
666
      'debug'    => 0,
677
697
  # create new iptables chain in the 'filter' table
678
698
  $ipt_obj->create_chain('filter', 'CUSTOM');
679
699
 
 
700
  # translate a network into the same representation that iptables or
 
701
  # ip6tables uses (e.g. '10.1.2.3/24' is properly represented as '10.1.2.0/24',
 
702
  # and '0000:0000:00AA:0000:0000:AA00:0000:0001/64' = '0:0:aa::/64')
 
703
  $normalized_net = $ipt_obj->normalize_net('10.1.2.3/24');
 
704
 
680
705
  # add rule to jump packets from the INPUT chain into CUSTOM at the
681
706
  # 4th rule position
682
707
  $ipt_obj->add_jump_rule('filter', 'INPUT', 4, 'CUSTOM');
683
708
 
684
 
  # find rule that allows all traffic from 10.1.2.3 to 192.168.1.2
685
 
  ($rv, $rule_num) = $ipt_obj->find_ip_rule('10.1.2.3', '192.168.1.2',
686
 
      'filter', 'INPUT', 'ACCEPT', {});
 
709
  # find rule that allows all traffic from 10.1.2.0/24 to 192.168.1.2
 
710
  ($rv, $rule_num) = $ipt_obj->find_ip_rule('10.1.2.0/24', '192.168.1.2',
 
711
      'filter', 'INPUT', 'ACCEPT', {'normalize' => 1});
687
712
 
688
 
  # find rule that allows all TCP port 80 traffic from 10.1.2.3 to
 
713
  # find rule that allows all TCP port 80 traffic from 10.1.2.0/24 to
689
714
  # 192.168.1.1
690
 
  ($rv, $rule_num) = $ipt_obj->find_ip_rule('10.1.2.3', '192.168.1.2',
691
 
      'filter', 'INPUT', 'ACCEPT', {'protocol' => 'tcp', 's_port' => 0,
692
 
      'd_port' => 80});
 
715
  ($rv, $rule_num) = $ipt_obj->find_ip_rule('10.1.2.0/24', '192.168.1.2',
 
716
      'filter', 'INPUT', 'ACCEPT', {'normalize' => 1, 'protocol' => 'tcp',
 
717
      's_port' => 0, 'd_port' => 80});
693
718
 
694
719
  # add rule at the 5th rule position to allow all traffic from
695
 
  # 10.1.2.3 to 192.168.1.2 via the INPUT chain in the filter table
696
 
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_ip_rule('10.1.2.3',
 
720
  # 10.1.2.0/24 to 192.168.1.2 via the INPUT chain in the filter table
 
721
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_ip_rule('10.1.2.0/24',
697
722
      '192.168.1.2', 5, 'filter', 'INPUT', 'ACCEPT', {});
698
723
 
699
724
  # add rule at the 4th rule position to allow all traffic from
700
 
  # 10.1.2.3 to 192.168.1.2 over TCP port 80 via the CUSTOM chain
 
725
  # 10.1.2.0/24 to 192.168.1.2 over TCP port 80 via the CUSTOM chain
701
726
  # in the filter table
702
 
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_ip_rule('10.1.2.3',
 
727
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_ip_rule('10.1.2.0/24',
703
728
      '192.168.1.2', 4, 'filter', 'CUSTOM', 'ACCEPT',
704
729
      {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
705
730
 
706
731
  # append rule at the end of the CUSTOM chain in the filter table to
707
 
  # allow all traffic from 10.1.2.3 to 192.168.1.2 via port 80
708
 
  ($rv, $out_ar, $errs_ar) = $ipt_obj->append_ip_rule('10.1.2.3',
 
732
  # allow all traffic from 10.1.2.0/24 to 192.168.1.2 via port 80
 
733
  ($rv, $out_ar, $errs_ar) = $ipt_obj->append_ip_rule('10.1.2.0/24',
709
734
      '192.168.1.2', 'filter', 'CUSTOM', 'ACCEPT',
710
735
      {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
711
736
 
 
737
  # for each of the examples above, here are ip6tables analogs
 
738
  # (requires instantiating the IPTables::ChainMgr object with
 
739
  # /sbin/ip6tables): find rule that allows all traffic from fe80::200:f8ff:fe21:67cf
 
740
  # to 0:0:aa::/64
 
741
  ($rv, $rule_num) = $ipt_obj->find_ip_rule('fe80::200:f8ff:fe21:67cf', '0:0:aa::/64',
 
742
      'filter', 'INPUT', 'ACCEPT', {'normalize' => 1});
 
743
 
 
744
  # find rule that allows all TCP port 80 traffic from fe80::200:f8ff:fe21:67c to 0:0:aa::/64
 
745
  ($rv, $rule_num) = $ipt_obj->find_ip_rule('fe80::200:f8ff:fe21:67cf', '0:0:aa::/64',
 
746
      'filter', 'INPUT', 'ACCEPT', {'normalize' => 1, 'protocol' => 'tcp',
 
747
      's_port' => 0, 'd_port' => 80});
 
748
 
 
749
  # add rule at the 5th rule position to allow all traffic from
 
750
  # fe80::200:f8ff:fe21:67c to 0:0:aa::/64 via the INPUT chain in the filter table
 
751
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_ip_rule('fe80::200:f8ff:fe21:67cf',
 
752
      '0:0:aa::/64', 5, 'filter', 'INPUT', 'ACCEPT', {});
 
753
 
 
754
  # add rule at the 4th rule position to allow all traffic from
 
755
  # fe80::200:f8ff:fe21:67c to 0:0:aa::/64 over TCP port 80 via the CUSTOM chain
 
756
  # in the filter table
 
757
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_ip_rule('fe80::200:f8ff:fe21:67cf',
 
758
      '0:0:aa::/64', 4, 'filter', 'CUSTOM', 'ACCEPT',
 
759
      {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
 
760
 
 
761
  # append rule at the end of the CUSTOM chain in the filter table to
 
762
  # allow all traffic from fe80::200:f8ff:fe21:67c to 0:0:aa::/64 via port 80
 
763
  ($rv, $out_ar, $errs_ar) = $ipt_obj->append_ip_rule('fe80::200:f8ff:fe21:67cf',
 
764
      '0:0:aa::/64', 'filter', 'CUSTOM', 'ACCEPT',
 
765
      {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
 
766
 
712
767
  # run an arbitrary iptables command and collect the output
713
768
  ($rv, $out_ar, $errs_ar) = $ipt_obj->run_ipt_cmd(
714
769
          '/sbin/iptables -v -n -L');
715
770
 
716
771
=head1 DESCRIPTION
717
772
 
718
 
The C<IPTables::ChainMgr> package provide an interface to manipulate iptables
719
 
policies on Linux systems through the direct execution of iptables commands.
720
 
Although making a perl extension of libiptc provided by the iptables project is
721
 
possible (and has been done by the IPTables::libiptc module available from CPAN),
722
 
it is also easy enough to just execute iptables commands directly in order to
723
 
both parse and change the configuration of the policy.  Further, this simplifies
724
 
installation since the only external requirement is (in the spirit of scripting)
725
 
to be able to point IPTables::ChainMgr at an installed iptables binary instead
 
773
The C<IPTables::ChainMgr> package provides an interface to manipulate iptables
 
774
and ip6tables policies on Linux systems through the direct execution of
 
775
iptables/ip6tables commands.  Although making a perl extension of libiptc
 
776
provided by the iptables project is possible (and has been done by the
 
777
IPTables::libiptc module available from CPAN), it is also easy enough to just
 
778
execute iptables/ip6tables commands directly in order to both parse and change
 
779
the configuration of the policy.  Further, this simplifies installation since
 
780
the only external requirement is (in the spirit of scripting) to be able to
 
781
point IPTables::ChainMgr at an installed iptables or ip6tables binary instead
726
782
of having to compile against a library.
727
783
 
728
784
=head1 FUNCTIONS
736
792
 
737
793
This function tests whether or not a chain (e.g. 'INPUT') exists within the
738
794
specified table (e.g. 'filter').  This is most useful to test whether
739
 
a custom chain has been added to the running iptables policy.  The return values
740
 
are (as with many IPTables::ChainMgr functions) an array of three things: a
741
 
numeric value, and both the stdout and stderr of the iptables command in the
742
 
form of array references.  So, an example invocation of the chain_exists()
743
 
function would be:
 
795
a custom chain has been added to the running iptables/ip6tables policy.  The
 
796
return values are (as with many IPTables::ChainMgr functions) an array of
 
797
three things: a numeric value, and both the stdout and stderr of the iptables
 
798
or ip6tables command in the form of array references.  So, an example
 
799
invocation of the chain_exists() function would be:
744
800
 
745
801
  ($rv, $out_ar, $errs_ar) = $ipt_obj->chain_exists('filter', 'CUSTOM');
746
802
 
747
803
If $rv is 1, then the CUSTOM chain exists in the filter table, and 0 otherwise.
748
804
The $out_ar array reference contains the output of the command "/sbin/iptables -t filter -v -n -L CUSTOM",
749
805
which will contain the rules in the CUSTOM chain (if it exists) or nothing (if not).
750
 
The $errs_ar array reference contains the stderr of the iptables command.
 
806
The $errs_ar array reference contains the stderr of the iptables command.  As
 
807
with all IPTables::ChainMgr functions, if the IPTables::ChainMgr object was
 
808
instantiated with the ip6tables binary path, then the above command would
 
809
become "/sbin/ip6tables -t filter -v -n -L CUSTOM".
751
810
 
752
811
=item create_chain($table, $chain)
753
812
 
757
816
  ($rv, $out_ar, $errs_ar) = $ipt_obj->create_chain('filter', 'CUSTOM');
758
817
 
759
818
Behind the scenes, the create_chain() function in the example above runs the
760
 
iptables command "/sbin/iptables -t filter -N CUSTOM".
 
819
iptables command "/sbin/iptables -t filter -N CUSTOM", or for ip6tables
 
820
"/sbin/ip6tables -t filter -N CUSTOM".
761
821
 
762
822
=item flush_chain($table, $chain)
763
823
 
767
827
  ($rv, $out_ar, $errs_ar) = $ipt_obj->flush_chain('filter', 'CUSTOM');
768
828
 
769
829
The flush_chain() function in the example above executes the iptables command
770
 
"/sbin/iptables -t filter -F CUSTOM"
 
830
"/sbin/iptables -t filter -F CUSTOM" or "/sbin/ip6tables -t filter -F CUSTOM".
771
831
 
772
832
=item delete_chain($table, $jump_from_chain, $chain)
773
833
 
788
848
matches the $src, $dst, $target, and (optionally) any %extended_info
789
849
criteria.  The return values are the rule number in the chain (or zero
790
850
if it doesn't exist), and the total number of rules in the chain.  Below
791
 
are two examples; the first is to find an ACCEPT rule for 10.1.2.3 to
 
851
are four examples; the first is to find an ACCEPT rule for 10.1.2.0/24 to
792
852
communicate with 192.168.1.2 in the INPUT chain, and the second is the
793
 
same except that the rule is restricted to TCP port 80:
 
853
same except that the rule is restricted to TCP port 80.  The third and
 
854
forth examples illustrate ip6tables analogs of the first two examples
 
855
with source IP fe80::200:f8ff:fe21:67cf/128 and destination network: 0:0:aa::/64
794
856
 
795
 
  ($rulenum, $chain_rules) = $ipt_obj->find_ip_rule('10.1.2.3',
796
 
      '192.168.1.2', 'filter', 'INPUT', 'ACCEPT', {});
 
857
  ($rulenum, $chain_rules) = $ipt_obj->find_ip_rule('10.1.2.0/24',
 
858
      '192.168.1.2', 'filter', 'INPUT', 'ACCEPT', {'normalize' => 1});
797
859
  if ($rulenum) {
798
860
      print "matched rule $rulenum out of $chain_rules rules\n";
799
861
  }
800
862
 
801
 
  ($rulenum, $chain_rules) = $ipt_obj->find_ip_rule('10.1.2.3',
 
863
  ($rulenum, $chain_rules) = $ipt_obj->find_ip_rule('10.1.2.0/24',
802
864
      '192.168.1.2', 'filter', 'INPUT', 'ACCEPT',
803
 
      {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
 
865
      {'normalize' => 1, 'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
 
866
  if ($rulenum) {
 
867
      print "matched rule $rulenum out of $chain_rules rules\n";
 
868
  }
 
869
 
 
870
  ($rulenum, $chain_rules) = $ipt_obj->find_ip_rule('fe80::200:f8ff:fe21:67cf/128',
 
871
    '0:0:aa::/64', 'filter', 'INPUT', 'ACCEPT', {'normalize' => 1});
 
872
  if ($rulenum) {
 
873
      print "matched rule $rulenum out of $chain_rules rules\n";
 
874
  }
 
875
 
 
876
  ($rulenum, $chain_rules) = $ipt_obj->find_ip_rule('fe80::200:f8ff:fe21:67cf/128',
 
877
      '0:0:aa::/64', 'filter', 'INPUT', 'ACCEPT',
 
878
      {'normalize' => 1, 'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
804
879
  if ($rulenum) {
805
880
      print "matched rule $rulenum out of $chain_rules rules\n";
806
881
  }
833
908
 
834
909
  ($rv, $out_ar, $errs_ar) = $ipt_obj->add_jump_rule('filter', 'INPUT', 4, 'CUSTOM');
835
910
 
 
911
=item normalize_net($net)
 
912
 
 
913
This function translates an IP/network into the same representation that iptables
 
914
or ip6tables uses upon listing a policy.  The first example shows an IPv4 network
 
915
and how iptables lists it, and the second is an IPv6 network:
 
916
 
 
917
  print $ipt_obj->normalize_net('10.1.2.3/24'), "\n" # prints '10.1.2.0/24'
 
918
  print $ipt_obj->normalize_net('0000:0000:00AA:0000:0000:AA00:0000:0001/64'), "\n" # prints '0:0:aa::/64'
 
919
 
836
920
=item run_ipt_cmd($cmd)
837
921
 
838
922
This function is a generic work horse function for executing iptables commands,
856
940
=head1 SEE ALSO
857
941
 
858
942
The IPTables::ChainMgr extension is closely associated with the IPTables::Parse
859
 
extension, and both are heavily used by the psad, fwsnort, and fwknop projects
860
 
to manipulate iptables policies based on various criteria (see the psad(8),
861
 
fwsnort(8), and fwknop(8) man pages).  As always, the iptables(8) man page
862
 
provides the best information on command line execution and theory behind
863
 
iptables.
 
943
extension, and both are heavily used by the psad and fwsnort projects to
 
944
manipulate iptables policies based on various criteria (see the psad(8) and
 
945
fwsnort(8) man pages).  As always, the iptables(8) man page provides the best
 
946
information on command line execution and theory behind iptables.
864
947
 
865
948
Although there is no mailing that is devoted specifically to the IPTables::ChainMgr
866
949
extension, questions about the extension will be answered on the following
867
950
lists:
868
951
 
869
952
  The psad mailing list: http://lists.sourceforge.net/lists/listinfo/psad-discuss
870
 
  The fwknop mailing list: http://lists.sourceforge.net/lists/listinfo/fwknop-discuss
871
953
  The fwsnort mailing list: http://lists.sourceforge.net/lists/listinfo/fwsnort-discuss
872
954
 
873
955
The latest version of the IPTables::ChainMgr extension can be found at:
885
967
=head1 AUTHOR
886
968
 
887
969
The IPTables::ChainMgr extension was written by Michael Rash F<E<lt>mbr@cipherdyne.orgE<gt>>
888
 
to support the psad, fwknop, and fwsnort projects.  Please send email to
889
 
this address if there are any questions, comments, or bug reports.
 
970
to support the psad and fwsnort projects.  Please send email to this address if
 
971
there are any questions, comments, or bug reports.
890
972
 
891
973
=head1 COPYRIGHT AND LICENSE
892
974
 
893
 
Copyright (C) 2005-2008 by Michael Rash
 
975
Copyright (C) 2005-2012 by Michael Rash
894
976
 
895
977
This library is free software; you can redistribute it and/or modify
896
978
it under the same terms as Perl itself, either Perl version 5.8.5 or,