summaryrefslogtreecommitdiff
path: root/lib/Vyatta/IpTables/Mgr.pm
blob: 9247a44fd241222b4f4f27bc9239fd109fc9ac9f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#
# Module: Vyatta::IpTables::Mgr.pm
# 
# **** License ****
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
# 
# This code was originally developed by Vyatta, Inc.
# Portions created by Vyatta are Copyright (C) 2010 Vyatta, Inc.
# All Rights Reserved.
# 
# Author: Stig Thormodsrud
# Date: June 2010
# Description: common iptables routines
# 
# **** End License ****
#

package Vyatta::IpTables::Mgr;

use strict;
use warnings;

use base 'Exporter';
our @EXPORT = qw(ipt_find_chain_rule ipt_enable_conntrack
                 ipt_disable_conntrack);


sub ipt_find_chain_rule {
  my ($iptables_cmd, $table, $chain, $search) = @_;
  
  my ($num, $chain2) = (undef, undef);
  my $cmd = "$iptables_cmd -t $table -L $chain -vn --line";
  my @lines = `$cmd 2> /dev/null | egrep ^[0-9]`;
  if (scalar(@lines) < 1) {
    return;
  }
  foreach my $line (@lines) {
    ($num, undef, undef, $chain2) = split /\s+/, $line;
    last if $chain2 eq $search;
    ($num, $chain2) = (undef, undef);
  }

  return $num if defined $num;
  return;
}

my %conntrack_hook_hash = 
   ('PREROUTING' => 'VYATTA_CT_PREROUTING_HOOK',
    'OUTPUT'     => 'VYATTA_CT_OUTPUT_HOOK',
   );

sub ipt_enable_conntrack {
    my ($iptables_cmd, $chain) = @_;

    system("$iptables_cmd -t raw -L $chain -n >& /dev/null");
    
    if ($? >> 8) {
	# chain does not exist yet. set up conntrack.
	system("$iptables_cmd -t raw -N $chain");
	system("$iptables_cmd -t raw -A $chain -j ACCEPT");
        
        foreach my $label ('PREROUTING', 'OUTPUT') {
            my $index;
            my $conntrack_hook = $conntrack_hook_hash{$label};
            $index = ipt_find_chain_rule($iptables_cmd, 'raw',
                                         $label, $conntrack_hook);
            if (! defined($index)) {
                print "Error: unable to find [$label] [$conntrack_hook]\n";
                return 1;
            }
            $index++;
            system("$iptables_cmd -t raw -I $label $index -j $chain");
        }
    }
    return 0;
}

sub ipt_disable_conntrack {
    my ($iptables_cmd, $chain) = @_;

    my @lines;
    foreach my $label ('PREROUTING', 'OUTPUT') {
        my $index;
        my $conntrack_hook = $conntrack_hook_hash{$label};
        $index = ipt_find_chain_rule($iptables_cmd, 'raw',
                                     $label, $chain);
        if (! defined($index)) {
            print "Error: ipt_disable_conntrack failed to find "
                  . "[$label][$chain]\n";
            return 1;
        }
        system("$iptables_cmd -t raw -D $label $index");
    }
    
    system("$iptables_cmd -t raw -F $chain >& /dev/null");
    system("$iptables_cmd -t raw -X $chain >& /dev/null");
    return 0;
}

1;