John W. Krahn am Sonntag, 14. Mai 2006 00.11:
> Richard Bagshaw wrote:
> > 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)
> > { ... 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.
>
> If $1 is always 'INPUT' then why capture it?  

> Case is usually important or do -s and -S do the same thing? 

oops, I missed this point (besides others) in my answer.

> If you want parsing similar to a shell 
> then all you need to do is parse on whitespace:
>
> if ( /INPUT -p (\S+) (?:-s (\S+))? --dport (\S+) -j (\S+)/ ) {
>
>
> If you are trying to use a regular expression to verify that the data is
> correct then something like this _may_ work:

It does when replacing the \s* with \s+ - at least my iptables complains if 
arguments are not separated with a space (tested with -p and -s).

> if ( /INPUT
>       \s*
>       -p \s* (udp|tcp)
>       \s*
>       (?: -s \s* (  (?: 0?\d?\d | 1\d\d | 2 (?: [0-4]\d | 5[0-5] ) )
>              (?: \. (?: 0?\d?\d | 1\d\d | 2 (?: [0-4]\d | 5[0-5] ) ) ){3} )
> )? \s*
>       --dport \s* (\d{1,5})
>       \s*
>       -j \s* ([A-Za-z]\S*)
>      /x ) {
>
> Or you could "cheat" and let Getopt::Long parse it for you:
>
> $ perl -MGetopt::Long -MData::Dumper -e'
> $_ = q[iptables -A INPUT -p tcp -s 123.45.678.90 --dport 22 -j ACCEPT];
> my %h;
> {   local @ARGV = split;
>     GetOptions( \%h, "A=s", "p=s", "s=s", "dport=i", "j=s" );
>     }
> print Dumper \%h;
> '
> $VAR1 = {
>           'A' => 'INPUT',
>           'p' => 'tcp',
>           's' => '123.45.678.90',
>           'j' => 'ACCEPT',
>           'dport' => 22
>         };

The disadvantage may be that it accepts wrong syntax like -ptcp (see remark 
above), but the idea is great!


Dani

-- 
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