Richard Bagshaw wrote:
Peeps,


Hi Richard.

I'm very new to perl and I have been trying to solve a problem for a few days now, I am reading a file that I use to setup my firewall rules on a Linux box, the file contains many lines, but as an example I will show just two here :-

iptables -A INPUT -p tcp -s 123.45.678.90 --dport 22 -j ACCEPT

and ...

iptables -A INPUT -p tcp --dport 25 -j ACCEPT

As you can see, the main difference is that line one has the "source ip" listed, where as line 2 doesn't. I am writing a regex to basically pull all of the pertinent parts from the lines. The below expression works perfectly for the first line, but for the 2nd line it does not work. I know "why" it doesn't work, but cannot find the correct syntax for alternation to make the 2nd line work.

if (/(INPUT) -p (...) -s ([0-9\.]*) --dport ([0-9]+) -j ([A-Za-z].*)/gi) {

The "-s ([0-9\.]*)" should be made optional with the '?' character like so:
(?:-s ([.\d]+))?

Notice the '?' on the end.

 ... code here ...
}

$1 = INPUT
$2 = UDP or TCP
$3 = <IP of SOURCE>
$4 = <PORT>
$5 = ACCEPT or REJECT or DROP

Any help would be appreciated.

Thanks,

Richard

Try something like this:

use strict;
use Data::Dumper;

$var = '
iptables -A INPUT -p tcp -s 123.45.678.90 --dport 22 -j ACCEPT

and ...

iptables -A INPUT -p tcp --dport 25 -j ACCEPT
';

open (FH, '<', \$var)
    or die ("Couldn't open in memory string: $!\n");

# Important spaces have to be backslashed because I'm using
# the /x option to make this regex readable.
my $rx = q{
    (INPUT)                     # chain name
    \ -p\ (\w+)                 # protocol name
    \ (?:-s\ ([.\d]+))?         # source ip optional (?)
    \ ?                         # extra space, optional (?)
    --dport\ (\d+)              # destintation port
    \ -j\ (\w+)                 # target
    };

my $expand = sub {
    my @fields = qw(chain proto sport dport target);
    my $fi = 0;
    my %hash = map +($fields[$fi++], $_), @_;
    return %hash;
};

while (<FH>) {
    chomp;
    next unless m/^iptables/;
    s/\s+/ /g;
    if (m/$rx/ixo) {
        my %hash = $expand->($1,$2,$3,$4,$5);
        print Dumper(\%hash);
    }
}

close (FH);



--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to