line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package App::Iptables2Dot; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
# vim: set sw=4 ts=4 tw=78 et si filetype=perl: |
4
|
|
|
|
|
|
|
|
5
|
9
|
|
|
9
|
|
633626
|
use warnings; |
|
9
|
|
|
|
|
88
|
|
|
9
|
|
|
|
|
307
|
|
6
|
9
|
|
|
9
|
|
50
|
use strict; |
|
9
|
|
|
|
|
19
|
|
|
9
|
|
|
|
|
191
|
|
7
|
9
|
|
|
9
|
|
47
|
use Carp; |
|
9
|
|
|
|
|
17
|
|
|
9
|
|
|
|
|
500
|
|
8
|
9
|
|
|
9
|
|
7247
|
use Getopt::Long qw(GetOptionsFromString); |
|
9
|
|
|
|
|
119002
|
|
|
9
|
|
|
|
|
57
|
|
9
|
|
|
|
|
|
|
|
10
|
9
|
|
|
9
|
|
5348
|
use version; our $VERSION = qv('v0.3.3'); |
|
9
|
|
|
|
|
16661
|
|
|
9
|
|
|
|
|
56
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# Module implementation here |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
my @optdefs = qw( |
15
|
|
|
|
|
|
|
checksum-fill |
16
|
|
|
|
|
|
|
clamp-mss-to-pmtu |
17
|
|
|
|
|
|
|
comment=s |
18
|
|
|
|
|
|
|
ctstate=s |
19
|
|
|
|
|
|
|
destination|d=s |
20
|
|
|
|
|
|
|
destination-ports|dports=s |
21
|
|
|
|
|
|
|
dport=s |
22
|
|
|
|
|
|
|
dst-type=s |
23
|
|
|
|
|
|
|
gid-owner=s |
24
|
|
|
|
|
|
|
goto|g=s |
25
|
|
|
|
|
|
|
helper=s |
26
|
|
|
|
|
|
|
in-interface|i=s |
27
|
|
|
|
|
|
|
icmp-type=s |
28
|
|
|
|
|
|
|
jump|j=s |
29
|
|
|
|
|
|
|
limit=s |
30
|
|
|
|
|
|
|
limit-burst=s |
31
|
|
|
|
|
|
|
log-prefix=s |
32
|
|
|
|
|
|
|
m=s |
33
|
|
|
|
|
|
|
mac-source=s |
34
|
|
|
|
|
|
|
match-set=s |
35
|
|
|
|
|
|
|
mss=s |
36
|
|
|
|
|
|
|
notrack |
37
|
|
|
|
|
|
|
o=s |
38
|
|
|
|
|
|
|
physdev-in=s |
39
|
|
|
|
|
|
|
physdev-is-bridged |
40
|
|
|
|
|
|
|
physdev-is-in |
41
|
|
|
|
|
|
|
physdev-is-out |
42
|
|
|
|
|
|
|
physdev-out=s |
43
|
|
|
|
|
|
|
protocol|p=s |
44
|
|
|
|
|
|
|
reject-with |
45
|
|
|
|
|
|
|
socket-exists |
46
|
|
|
|
|
|
|
source|s=s |
47
|
|
|
|
|
|
|
sport=s |
48
|
|
|
|
|
|
|
state=s |
49
|
|
|
|
|
|
|
suppl-groups |
50
|
|
|
|
|
|
|
tcp-flags=s |
51
|
|
|
|
|
|
|
to-destination=s |
52
|
|
|
|
|
|
|
to-ports=s |
53
|
|
|
|
|
|
|
to-source |
54
|
|
|
|
|
|
|
uid-owner=s |
55
|
|
|
|
|
|
|
ulog-prefix=s |
56
|
|
|
|
|
|
|
); |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub new { |
59
|
8
|
|
|
8
|
1
|
726
|
my ($self) = @_; |
60
|
8
|
|
33
|
|
|
72
|
my $type = ref($self) || $self; |
61
|
|
|
|
|
|
|
|
62
|
8
|
|
|
|
|
46
|
$self = bless { nodemap => {}, nn => 0 }, $type; |
63
|
|
|
|
|
|
|
|
64
|
8
|
|
|
|
|
29
|
return $self; |
65
|
|
|
|
|
|
|
} # new() |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub add_optdef { |
68
|
1
|
|
|
1
|
1
|
862
|
my $optdef = shift; |
69
|
1
|
|
|
|
|
5
|
push @optdefs, $optdef; |
70
|
|
|
|
|
|
|
} # add_optdef() |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
# dot_graph($opt, @graphs) |
73
|
|
|
|
|
|
|
# |
74
|
|
|
|
|
|
|
# Creates a graph in the 'dot' language for all tables given in the list |
75
|
|
|
|
|
|
|
# @graphs. |
76
|
|
|
|
|
|
|
# |
77
|
|
|
|
|
|
|
# Returns the graph as string. |
78
|
|
|
|
|
|
|
# |
79
|
|
|
|
|
|
|
sub dot_graph { |
80
|
10
|
|
|
10
|
1
|
8078
|
my $self = shift; |
81
|
10
|
|
|
|
|
23
|
my $opt = shift; |
82
|
10
|
|
|
|
|
20
|
my $subgraphs = ''; |
83
|
10
|
|
|
|
|
27
|
foreach my $graph (@_) { |
84
|
10
|
|
|
|
|
40
|
$subgraphs .= $self->_dot_subgraph($opt,$graph); |
85
|
|
|
|
|
|
|
} |
86
|
10
|
|
|
|
|
45
|
my $ranks = join "; ", $self->_internal_nodes($opt,@_); # determine all internal chains |
87
|
10
|
|
|
|
|
130
|
my $graph = <<"EOGRAPH"; |
88
|
|
|
|
|
|
|
digraph iptables { |
89
|
|
|
|
|
|
|
{ rank = source; $ranks; } |
90
|
|
|
|
|
|
|
rankdir = LR; |
91
|
|
|
|
|
|
|
$subgraphs |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
EOGRAPH |
94
|
10
|
|
|
|
|
47
|
return $graph; |
95
|
|
|
|
|
|
|
} # dot_graph() |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
sub read_iptables { |
98
|
9
|
|
|
9
|
1
|
36
|
my ($self,$input) = @_; |
99
|
|
|
|
|
|
|
|
100
|
9
|
|
|
|
|
303
|
while (<$input>) { |
101
|
283
|
|
|
|
|
661
|
$self->_read_iptables_line($_); |
102
|
|
|
|
|
|
|
} |
103
|
|
|
|
|
|
|
} # read_iptables() |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
sub read_iptables_file { |
106
|
9
|
|
|
9
|
1
|
71
|
my ($self,$fname) = @_; |
107
|
|
|
|
|
|
|
|
108
|
9
|
50
|
|
|
|
443
|
if (open(my $input, '<', $fname)) { |
109
|
9
|
|
|
|
|
69
|
$self->read_iptables($input); |
110
|
8
|
|
|
|
|
148
|
close $input; |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
else { |
113
|
0
|
|
|
|
|
0
|
die "can't open file '$fname' to read iptables-save output"; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
} # read_iptables_file() |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
## internal functions only |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
# _dot_edges($table) |
120
|
|
|
|
|
|
|
# |
121
|
|
|
|
|
|
|
# Lists all jumps between chains in the given table as edge description in the |
122
|
|
|
|
|
|
|
# 'dot' language. |
123
|
|
|
|
|
|
|
# |
124
|
|
|
|
|
|
|
# Returns a list of edge descriptions. |
125
|
|
|
|
|
|
|
# |
126
|
|
|
|
|
|
|
sub _dot_edges { |
127
|
10
|
|
|
10
|
|
32
|
my ($self,$opt,$table) = @_; |
128
|
10
|
|
|
|
|
61
|
my @edges = (); |
129
|
10
|
|
|
|
|
19
|
my %seen = (); |
130
|
10
|
|
|
|
|
55
|
my $re_it = qr/^(MASQUERADE|RETURN|TCPMSS)$/; |
131
|
10
|
|
|
|
|
18
|
foreach my $edge (@{$self->{jumps}->{$table}}) { |
|
10
|
|
|
|
|
30
|
|
132
|
99
|
|
|
|
|
151
|
my $tp = ':w'; |
133
|
99
|
|
|
|
|
126
|
my $lbl = ''; |
134
|
99
|
0
|
33
|
|
|
180
|
if ($opt->{edgelabel} && $edge->[2]) { |
135
|
0
|
|
|
|
|
0
|
$lbl = " [label=\"$edge->[2]\"]"; |
136
|
|
|
|
|
|
|
} |
137
|
99
|
100
|
|
|
|
425
|
unless ($edge->[1] =~ $re_it) { |
138
|
94
|
|
|
|
|
154
|
$tp = ":name:w"; |
139
|
|
|
|
|
|
|
} |
140
|
99
|
|
|
|
|
144
|
my $e0 = $edge->[0]; |
141
|
99
|
|
|
|
|
146
|
my $e1 = $edge->[1]; |
142
|
99
|
100
|
|
|
|
180
|
if ($opt->{"use-numbered-nodes"}) { |
143
|
3
|
|
33
|
|
|
9
|
$e0 = $self->{nodemap}->{$edge->[0]} || $edge->[0]; |
144
|
3
|
|
66
|
|
|
12
|
$e1 = $self->{nodemap}->{$edge->[1]} || $edge->[1]; |
145
|
|
|
|
|
|
|
} |
146
|
99
|
100
|
|
|
|
165
|
if ($opt->{showrules}) { |
147
|
86
|
100
|
|
|
|
144
|
if (my $ot = $opt->{'omittargets'}) { |
148
|
3
|
|
|
|
|
8
|
my %omit = map { $_ => 1, } split(',',$ot); |
|
6
|
|
|
|
|
16
|
|
149
|
|
|
|
|
|
|
push @edges, "$e0:R$edge->[3]:e -> $e1$tp$lbl;" |
150
|
3
|
100
|
|
|
|
16
|
unless ($omit{$edge->[1]}); |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
else { |
153
|
83
|
|
|
|
|
314
|
push @edges, "$e0:R$edge->[3]:e -> $e1$tp$lbl;"; |
154
|
|
|
|
|
|
|
} |
155
|
|
|
|
|
|
|
} |
156
|
|
|
|
|
|
|
else { |
157
|
13
|
|
|
|
|
37
|
my $etext = "$e0:e -> $e1$tp$lbl"; |
158
|
13
|
100
|
|
|
|
40
|
unless ($seen{$etext} ++) { |
159
|
9
|
|
|
|
|
21
|
push @edges, $etext; |
160
|
|
|
|
|
|
|
} |
161
|
|
|
|
|
|
|
} |
162
|
|
|
|
|
|
|
} |
163
|
10
|
100
|
66
|
|
|
55
|
if ($opt->{showrules} || $opt->{edgelabel}) { |
164
|
7
|
|
|
|
|
67
|
return @edges; |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
else { |
167
|
|
|
|
|
|
|
my @le = map { |
168
|
3
|
100
|
|
|
|
8
|
1 < $seen{$_} ? qq($_ [label="($seen{$_})"];) : qq($_;); |
|
9
|
|
|
|
|
38
|
|
169
|
|
|
|
|
|
|
} @edges; |
170
|
3
|
|
|
|
|
18
|
return @le; |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
} # _dot_edges() |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
# _dot_nodes($table) |
175
|
|
|
|
|
|
|
# |
176
|
|
|
|
|
|
|
# Lists all chains in the given table as node descriptions in the 'dot' |
177
|
|
|
|
|
|
|
# language. |
178
|
|
|
|
|
|
|
# |
179
|
|
|
|
|
|
|
# Returns a list of node descriptions. |
180
|
|
|
|
|
|
|
# |
181
|
|
|
|
|
|
|
sub _dot_nodes { |
182
|
10
|
|
|
10
|
|
27
|
my ($self,$opt,$table) = @_; |
183
|
10
|
|
|
|
|
21
|
my @nodes = (); |
184
|
10
|
|
|
|
|
21
|
my %used = (); |
185
|
10
|
100
|
100
|
|
|
58
|
unless ($opt->{showunusednodes} || $opt->{"use-numbered-nodes"}) { |
186
|
8
|
|
|
|
|
15
|
%used = map { $_->[0] => 1, } @{$self->{jumps}->{$table}}; |
|
91
|
|
|
|
|
192
|
|
|
8
|
|
|
|
|
29
|
|
187
|
|
|
|
|
|
|
} |
188
|
10
|
|
|
|
|
30
|
foreach my $node (keys %{$self->{chains}->{$table}}) { |
|
10
|
|
|
|
|
63
|
|
189
|
|
|
|
|
|
|
next unless ($used{$node} |
190
|
|
|
|
|
|
|
|| $opt->{showunusednodes} |
191
|
97
|
100
|
100
|
|
|
309
|
|| $opt->{"use-numbered-nodes"}); |
|
|
|
100
|
|
|
|
|
192
|
56
|
|
|
|
|
83
|
my @rules = (); |
193
|
56
|
|
|
|
|
80
|
my $rn = 0; |
194
|
56
|
100
|
|
|
|
105
|
if ($opt->{showrules}) { |
195
|
47
|
|
|
|
|
63
|
foreach my $rule (@{$self->{chains}->{$table}->{$node}->{rules}}) { |
|
47
|
|
|
|
|
117
|
|
196
|
105
|
|
|
|
|
244
|
push @rules, qq( |
$rule |
);
197
|
105
|
|
|
|
|
156
|
$rn++; |
198
|
|
|
|
|
|
|
} |
199
|
|
|
|
|
|
|
} |
200
|
56
|
|
|
|
|
181
|
my $lbl = ""
201
|
|
|
|
|
|
|
. qq( | $node | \n)
202
|
|
|
|
|
|
|
. join("\n", @rules, " | "); |
203
|
56
|
100
|
|
|
|
109
|
if ($opt->{"use-numbered-nodes"}) { |
204
|
3
|
|
|
|
|
11
|
push @nodes, $self->{nodemap}->{$node} ." [shape=none,margin=0,label=<$lbl>];"; |
205
|
|
|
|
|
|
|
} |
206
|
|
|
|
|
|
|
else { |
207
|
53
|
|
|
|
|
188
|
push @nodes, "$node [shape=none,margin=0,label=<$lbl>];"; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
} |
210
|
10
|
|
|
|
|
104
|
return @nodes; |
211
|
|
|
|
|
|
|
} # _dot_nodes() |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# _dot_subgraph($opt, $table) |
214
|
|
|
|
|
|
|
# |
215
|
|
|
|
|
|
|
# Creates a subgraph in the 'dot' language for the table given in $table. |
216
|
|
|
|
|
|
|
# |
217
|
|
|
|
|
|
|
# Returns the subgraph as string. |
218
|
|
|
|
|
|
|
# |
219
|
|
|
|
|
|
|
sub _dot_subgraph { |
220
|
10
|
|
|
10
|
|
26
|
my ($self,$opt,$table) = @_; |
221
|
10
|
|
|
|
|
32
|
my $nodes = join "\n ", $self->_dot_nodes($opt,$table); |
222
|
10
|
|
|
|
|
48
|
my $edges = join "\n ", $self->_dot_edges($opt,$table); |
223
|
10
|
|
|
|
|
115
|
my $graph = <<"EOGRAPH"; |
224
|
|
|
|
|
|
|
subgraph $table { |
225
|
|
|
|
|
|
|
$nodes |
226
|
|
|
|
|
|
|
$edges |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
EOGRAPH |
229
|
10
|
|
|
|
|
76
|
return $graph; |
230
|
|
|
|
|
|
|
} # _dot_subgraph() |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# _internal_nodes(@tables) |
233
|
|
|
|
|
|
|
# |
234
|
|
|
|
|
|
|
# Lists all chains from all tables in @tables, that are internal chains. |
235
|
|
|
|
|
|
|
# |
236
|
|
|
|
|
|
|
# Returns a list of all internal tables. |
237
|
|
|
|
|
|
|
# |
238
|
|
|
|
|
|
|
sub _internal_nodes { |
239
|
10
|
|
|
10
|
|
20
|
my $self = shift; |
240
|
10
|
|
|
|
|
17
|
my $opt = shift; |
241
|
10
|
|
|
|
|
33
|
my $re_in = qr/^(PREROUTING|POSTROUTING|INPUT|FORWARD|OUTPUT)$/; |
242
|
10
|
|
|
|
|
22
|
my @nodes = (); |
243
|
10
|
|
|
|
|
20
|
my %have_node = (); |
244
|
10
|
|
|
|
|
18
|
my %used = (); |
245
|
10
|
|
|
|
|
25
|
foreach my $table (@_) { |
246
|
10
|
100
|
100
|
|
|
70
|
unless ($opt->{showunusednodes} || $opt->{"use-numbered-nodes"}) { |
247
|
8
|
|
|
|
|
20
|
%used = map { $_->[0] => 1, } @{$self->{jumps}->{$table}}; |
|
91
|
|
|
|
|
173
|
|
|
8
|
|
|
|
|
24
|
|
248
|
|
|
|
|
|
|
} |
249
|
10
|
|
|
|
|
25
|
foreach my $node (sort keys %{$self->{chains}->{$table}}) { |
|
10
|
|
|
|
|
78
|
|
250
|
|
|
|
|
|
|
next unless ($used{$node} |
251
|
|
|
|
|
|
|
|| $opt->{showunusednodes} |
252
|
97
|
100
|
100
|
|
|
313
|
|| $opt->{"use-numbered-nodes"}); |
|
|
|
100
|
|
|
|
|
253
|
56
|
100
|
66
|
|
|
326
|
if (!$have_node{$node} && $node =~ $re_in) { |
254
|
19
|
100
|
|
|
|
50
|
if ($opt->{"use-numbered-nodes"}) { |
255
|
1
|
|
33
|
|
|
15
|
push @nodes, $self->{nodemap}->{$node} || qq("$node"); |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
else { |
258
|
18
|
|
|
|
|
46
|
push @nodes, qq("$node"); |
259
|
|
|
|
|
|
|
} |
260
|
19
|
|
|
|
|
49
|
$have_node{$node} = 1; |
261
|
|
|
|
|
|
|
} |
262
|
|
|
|
|
|
|
} |
263
|
|
|
|
|
|
|
} |
264
|
10
|
|
|
|
|
61
|
return @nodes; |
265
|
|
|
|
|
|
|
} # _internal_nodes() |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
# _read_iptables_line($line) |
268
|
|
|
|
|
|
|
# |
269
|
|
|
|
|
|
|
# Reads the next line from iptables output and creates an entry in the rules |
270
|
|
|
|
|
|
|
# and or jump table for it. |
271
|
|
|
|
|
|
|
# |
272
|
|
|
|
|
|
|
# Returns nothing. |
273
|
|
|
|
|
|
|
# |
274
|
|
|
|
|
|
|
sub _read_iptables_line { |
275
|
283
|
|
|
283
|
|
595
|
my ($self,$line) = @_; |
276
|
283
|
100
|
|
|
|
733
|
return if ($line =~ /^#.*$/); |
277
|
269
|
100
|
|
|
|
570
|
return if ($line =~ /^COMMIT$/); |
278
|
257
|
|
|
|
|
409
|
chomp; |
279
|
257
|
100
|
|
|
|
1134
|
if ($line =~ /^\*(\S+)$/) { |
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
280
|
16
|
|
|
|
|
90
|
$self->{last_table} = $1; |
281
|
16
|
|
|
|
|
31
|
push @{$self->{tables}}, $1; |
|
16
|
|
|
|
|
61
|
|
282
|
16
|
|
|
|
|
68
|
$self->{chains}->{$1} = {}; |
283
|
16
|
|
|
|
|
225
|
$self->{jumps}->{$1} = []; |
284
|
|
|
|
|
|
|
} |
285
|
|
|
|
|
|
|
elsif ($line =~ /^:(\S+)\s.+$/) { |
286
|
110
|
|
|
|
|
435
|
$self->{chains}->{$self->{last_table}}->{$1} = { rules => [] }; |
287
|
110
|
100
|
|
|
|
280
|
unless ($self->{nodemap}->{$1}) { |
288
|
96
|
|
|
|
|
244
|
$self->{nodemap}->{$1} = "node" . $self->{nn}; |
289
|
96
|
|
|
|
|
164
|
$self->{nn} += 1; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
} |
292
|
|
|
|
|
|
|
elsif ($line =~ /^-A\s(\S+)\s(.+)$/) { |
293
|
131
|
|
|
|
|
315
|
my $chain = $1; |
294
|
131
|
|
|
|
|
293
|
my $rule = $2; |
295
|
131
|
|
|
|
|
205
|
my %opt; |
296
|
131
|
|
|
|
|
261
|
my $last_table = $self->{last_table}; |
297
|
131
|
|
|
|
|
477
|
my ($ret, $args) = GetOptionsFromString($rule,\%opt,@optdefs); |
298
|
131
|
100
|
|
|
|
405460
|
if ($ret) { |
299
|
130
|
|
100
|
|
|
524
|
my $iface = $opt{'in-interface'} || ''; |
300
|
130
|
|
0
|
|
|
402
|
my $target = $opt{'jump'} || $opt{'goto'} || ''; |
301
|
130
|
100
|
|
|
|
530
|
unless ($target =~ /^(ACCEPT|DROP|REJECT)$/) { |
302
|
94
|
50
|
|
|
|
337
|
unless ($self->{nodemap}->{$1}) { |
303
|
0
|
|
|
|
|
0
|
$self->{nodemap}->{$1} = "node" . $self->{nn}; |
304
|
0
|
|
|
|
|
0
|
$self->{nn} += 1; |
305
|
|
|
|
|
|
|
} |
306
|
94
|
|
|
|
|
132
|
my $rn = scalar @{$self->{chains}{$last_table}->{$chain}->{rules}}; |
|
94
|
|
|
|
|
240
|
|
307
|
94
|
|
|
|
|
206
|
push @{$self->{jumps}->{$last_table}}, [ $chain, $target, $iface, $rn ]; |
|
94
|
|
|
|
|
376
|
|
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
else { |
311
|
1
|
|
|
|
|
34
|
die "unknown argument in rule: $rule"; |
312
|
|
|
|
|
|
|
} |
313
|
130
|
|
|
|
|
205
|
push @{$self->{chains}->{$last_table}->{$chain}->{rules}}, $rule; |
|
130
|
|
|
|
|
558
|
|
314
|
|
|
|
|
|
|
} |
315
|
|
|
|
|
|
|
else { |
316
|
0
|
|
|
|
|
0
|
die "unrecognized line: $line"; |
317
|
|
|
|
|
|
|
} |
318
|
256
|
|
|
|
|
996
|
return; |
319
|
|
|
|
|
|
|
} # _read_iptables_line() |
320
|
|
|
|
|
|
|
|
321
|
|
|
|
|
|
|
1; # Magic true value required at end of module |
322
|
|
|
|
|
|
|
__END__ |