}
if (keys %$extended_hr) {
- $ipt_cmd .= "-p $extended_hr->{'protocol'} "
+
+ my ($ipt_tmp_str, $msg_tmp_str) = $self->build_ipt_matches(
+ $extended_hr, $normalized_src, $normalized_dst);
+
+ $msg = "Table: $table, chain: $chain, added $normalized_src " .
+ "-> $normalized_dst ";
+
+ ### always add the target at the end
+ $ipt_cmd .= "$ipt_tmp_str -j $target";
+
+ $msg .= $msg_tmp_str;
+ $msg =~ s/\s*$//;
+
+ } else {
+ $ipt_cmd .= "-s $normalized_src -d $normalized_dst -j $target";
+ $msg = "Table: $table, chain: $chain, added $normalized_src " .
+ "-> $normalized_dst";
+ }
+ my ($rv, $out_ar, $err_ar) = $self->run_ipt_cmd($ipt_cmd);
+ if ($rv) {
+ push @$out_ar, $msg if $msg;
+ }
+ push @$err_ar, $idx_err if $idx_err;
+ return $rv, $out_ar, $err_ar;
+}
+
+sub build_ipt_matches() {
+ my $self = shift;
+ my $extended_hr = shift;
+ my $normalized_src = shift || '';
+ my $normalized_dst = shift || '';
+
+ my $ipt_matches = '';
+ my $msg = '';
+
+ if ($IPTables::Parse::VERSION > 1.1) {
+
+ ### get the information about how to build the match part of the
+ ### iptables command from the IPTables::Parse module
+ my $ipt_parse = new IPTables::Parse(
+ 'iptables' => $self->{'_iptables'},
+ 'iptout' => $self->{'_iptout'},
+ 'ipterr' => $self->{'_ipterr'},
+ 'debug' => $self->{'_debug'},
+ 'verbose' => $self->{'_verbose'},
+ 'ipt_alarm' => $self->{'_ipt_alarm'},
+ 'ipt_exec_style' => $self->{'_ipt_exec_style'},
+ 'ipt_exec_sleep' => $self->{'_ipt_exec_sleep'},
+ 'sigchld_handler' => $self->{'_sigchld_handler'},
+ ) or croak "[*] Could not acquire IPTables::Parse object";
+
+ ### src and dst
+ if ($normalized_src ne '') {
+ $ipt_matches .= "$ipt_parse->{'parse_keys'}->{'regular'}->{'src'}->{'ipt_match'} " .
+ "$normalized_src ";
+ }
+
+ if ($normalized_src ne '') {
+ $ipt_matches .= "$ipt_parse->{'parse_keys'}->{'regular'}->{'dst'}->{'ipt_match'} " .
+ "$normalized_dst ";
+ }
+
+ ### handle 'regular' keys first
+ for my $key (keys %$extended_hr) {
+ if (defined $ipt_parse->{'parse_keys'}->{'regular'}->{$key}) {
+ $ipt_matches .= "$ipt_parse->{'parse_keys'}->{'regular'}->{$key}->{'ipt_match'} " .
+ "$extended_hr->{$key} ";
+ }
+ }
+
+ ### special case for port values (handle them now)
+ for my $key (qw/sport s_dport dport d_port/) {
+ next unless defined $extended_hr->{$key};
+ if ($extended_hr->{$key}) {
+ $ipt_matches .= "$ipt_parse->{'parse_keys'}->{'extended'}->{$key}->{'ipt_match'} " .
+ qq|$extended_hr->{$key} |;
+ }
+ }
+
+ ### now handle 'match' keys
+ for my $key (keys %$extended_hr) {
+ my $parse_hr = $ipt_parse->{'parse_keys'}->{'extended'};
+ if (defined $parse_hr->{$key}) {
+ next if $key =~ /s_?port$/ or $key =~ /d_?port$/;
+ if (defined $parse_hr->{$key}->{'use_quotes'}
+ and $parse_hr->{$key}->{'use_quotes'}) {
+ $ipt_matches .= "$parse_hr->{$key}->{'ipt_match'} " .
+ qq|"$extended_hr->{$key}" |;
+ } else {
+ $ipt_matches .= "$parse_hr->{$key}->{'ipt_match'} " .
+ "$extended_hr->{$key} ";
+ }
+ }
+ }
+
+ } else {
+ $ipt_matches .= "-p $extended_hr->{'protocol'} "
if defined $extended_hr->{'protocol'};
- $ipt_cmd .= "-s $normalized_src ";
- $ipt_cmd .= "--sport $extended_hr->{'s_port'} "
+ $ipt_matches .= "-s $normalized_src ";
+ $ipt_matches .= "--sport $extended_hr->{'s_port'} "
if defined $extended_hr->{'s_port'};
- $ipt_cmd .= "-d $normalized_dst ";
- $ipt_cmd .= "--dport $extended_hr->{'d_port'} "
+ $ipt_matches .= "-d $normalized_dst ";
+ $ipt_matches .= "--dport $extended_hr->{'d_port'} "
if defined $extended_hr->{'d_port'};
- $ipt_cmd .= "-m mac --mac-source $extended_hr->{'mac_source'} "
+ $ipt_matches .= "-m mac --mac-source $extended_hr->{'mac_source'} "
if defined $extended_hr->{'mac_source'};
- $ipt_cmd .= "-m state --state $extended_hr->{'state'} "
+ $ipt_matches .= "-m state --state $extended_hr->{'state'} "
if defined $extended_hr->{'state'};
- $ipt_cmd .= "-m conntrack --ctstate $extended_hr->{'ctstate'} "
+ $ipt_matches .= "-m conntrack --ctstate $extended_hr->{'ctstate'} "
if defined $extended_hr->{'ctstate'};
- $ipt_cmd .= "-j $target";
- $msg = "Table: $table, chain: $chain, added $normalized_src " .
- "-> $normalized_dst ";
for my $key (keys %$extended_hr) {
$msg .= "$key $extended_hr->{$key} "
if defined $extended_hr->{$key};
### for NAT
if (defined $extended_hr->{'to_ip'} and
defined $extended_hr->{'to_port'}) {
- $ipt_cmd .= " --to $extended_hr->{'to_ip'}:" .
+ $ipt_matches .= " --to $extended_hr->{'to_ip'}:" .
"$extended_hr->{'to_port'}";
$msg .= "$extended_hr->{'to_ip'}:$extended_hr->{'to_port'}";
}
-
- $msg =~ s/\s*$//;
- } else {
- $ipt_cmd .= "-s $normalized_src -d $normalized_dst -j $target";
- $msg = "Table: $table, chain: $chain, added $normalized_src " .
- "-> $normalized_dst";
}
- my ($rv, $out_ar, $err_ar) = $self->run_ipt_cmd($ipt_cmd);
- if ($rv) {
- push @$out_ar, $msg if $msg;
- }
- push @$err_ar, $idx_err if $idx_err;
- return $rv, $out_ar, $err_ar;
+
+ $ipt_matches =~ s/\s*$//;
+
+ return ($ipt_matches, $msg);
}
sub delete_ip_rule() {
if ($IPTables::Parse::VERSION > 1.1) {
@parse_keys = ();
+
### get the keys list from the IPTables::Parse module
for my $key (keys %{$ipt_parse->{'parse_keys'}->{'regular'}}) {
push @parse_keys, $key;
for my $target (qw/LOG ACCEPT RETURN/) {
### TCP
- &dots_print("add_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target ");
+ &dots_print("add_ext_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target ");
my ($rv, $out_ar, $err_ar) = $ipt_obj->add_ip_rule($src_ip,
$dst_ip, $chain_past_end, $test_table, $test_chain, $target,
{'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
&pass_fail($rv, " Could not add TCP $src_ip(0) -> $dst_ip(80) $target rule");
### TCP + state tracking
- &dots_print("add_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) state ESTABLISHED,RELATED $target ");
+ &dots_print("add_ext_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) state ESTABLISHED,RELATED $target ");
($rv, $out_ar, $err_ar) = $ipt_obj->add_ip_rule($src_ip,
$dst_ip, $chain_past_end, $test_table, $test_chain, $target,
{'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80, 'state' => 'ESTABLISHED,RELATED'});
&pass_fail($rv, " Could not add TCP $src_ip(0) -> $dst_ip(80) state ESTABLISHED,RELATED $target rule");
### TCP + ctstate tracking
- &dots_print("add_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) ctstate ESTABLISHED,RELATED $target ");
+ &dots_print("add_ext_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) ctstate ESTABLISHED,RELATED $target ");
($rv, $out_ar, $err_ar) = $ipt_obj->add_ip_rule($src_ip,
$dst_ip, $chain_past_end, $test_table, $test_chain, $target,
{'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80, 'ctstate' => 'ESTABLISHED,RELATED'});
&pass_fail($rv, " Could not add TCP $src_ip(0) -> $dst_ip(80) ctstate ESTABLISHED,RELATED $target rule");
### TCP + mac source
- &dots_print("add_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target mac_source $mac_source ");
+ &dots_print("add_ext_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target mac_source $mac_source ");
($rv, $out_ar, $err_ar) = $ipt_obj->add_ip_rule($src_ip,
$dst_ip, $chain_past_end, $test_table, $test_chain, $target,
{'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80, 'mac_source' => $mac_source});
&pass_fail($rv, " Could not add TCP $src_ip(0) -> $dst_ip(80) $target mac_source $mac_source");
+ ### TCP + comment
+ &dots_print("add_ext_ip_rules(): $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target comment 'test comment' ");
+ ($rv, $out_ar, $err_ar) = $ipt_obj->add_ip_rule($src_ip,
+ $dst_ip, $chain_past_end, $test_table, $test_chain, $target,
+ {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80, 'comment' => 'test comment'});
+ &pass_fail($rv, " Could not add TCP $src_ip(0) -> $dst_ip(80) $target comment 'test comment'");
+
### UDP
- &dots_print("add_ip_rules(): $test_table $test_chain UDP $src_ip(0) -> $dst_ip(53) $target ");
+ &dots_print("add_ext_ip_rules(): $test_table $test_chain UDP $src_ip(0) -> $dst_ip(53) $target ");
($rv, $out_ar, $err_ar) = $ipt_obj->add_ip_rule($src_ip,
$dst_ip, $chain_past_end, $test_table, $test_chain, $target,
{'protocol' => 'udp', 's_port' => 0, 'd_port' => 53});
}
for my $target (qw/LOG ACCEPT RETURN/) {
- &dots_print("find rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target ");
+ &dots_print("find ext rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target ");
my ($rule_position, $num_chain_rules) = $ipt_obj->find_ip_rule($src_ip,
$dst_ip, $test_table, $test_chain, $target,
{'normalize' => 1, 'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80});
&pass_fail($rule_position, " Could not find TCP $src_ip(0) -> $dst_ip(80) $target rule");
- &dots_print("find rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) state ESTABLISHED,RELATED $target ");
+ &dots_print("find ext rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) state ESTABLISHED,RELATED $target ");
($rule_position, $num_chain_rules) = $ipt_obj->find_ip_rule($src_ip,
$dst_ip, $test_table, $test_chain, $target,
{'normalize' => 1, 'protocol' => 'tcp', 's_port' => 0,
'd_port' => 80, 'state' => 'ESTABLISHED,RELATED'});
&pass_fail($rule_position, " Could not find TCP $src_ip(0) -> $dst_ip(80) state ESTABLISHED,RELATED $target rule");
- &dots_print("find rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) ctstate ESTABLISHED,RELATED $target ");
+ &dots_print("find ext rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) ctstate ESTABLISHED,RELATED $target ");
($rule_position, $num_chain_rules) = $ipt_obj->find_ip_rule($src_ip,
$dst_ip, $test_table, $test_chain, $target,
{'normalize' => 1, 'protocol' => 'tcp', 's_port' => 0,
'd_port' => 80, 'ctstate' => 'ESTABLISHED,RELATED'});
&pass_fail($rule_position, " Could not find TCP $src_ip(0) -> $dst_ip(80) ctstate ESTABLISHED,RELATED $target rule");
- &dots_print("find rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target mac_source $mac_source ");
+ &dots_print("find ext rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target mac_source $mac_source ");
($rule_position, $num_chain_rules) = $ipt_obj->find_ip_rule($src_ip,
$dst_ip, $test_table, $test_chain, $target,
{'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80,
'mac_source' => $mac_source});
&pass_fail($rule_position, " Could not find TCP $src_ip(0) -> $dst_ip(80) $target mac_source $mac_source");
- &dots_print("find rule: $test_table $test_chain UDP $src_ip(0) -> $dst_ip(53) $target ");
+ ### TCP + comment
+ &dots_print("find ext rule: $test_table $test_chain TCP $src_ip(0) -> $dst_ip(80) $target comment 'test comment' ");
+ ($rule_position, $num_chain_rules) = $ipt_obj->find_ip_rule($src_ip,
+ $dst_ip, $test_table, $test_chain, $target,
+ {'protocol' => 'tcp', 's_port' => 0, 'd_port' => 80, 'comment' => 'test comment'});
+ &pass_fail($rule_position, " Could not find TCP $src_ip(0) -> $dst_ip(80) $target comment 'test comment'");
+
+ &dots_print("find ext rule: $test_table $test_chain UDP $src_ip(0) -> $dst_ip(53) $target ");
($rule_position, $num_chain_rules) = $ipt_obj->find_ip_rule($src_ip,
$dst_ip, $test_table, $test_chain, $target,
{'normalize' => 1, 'protocol' => 'udp', 's_port' => 0, 'd_port' => 53});