CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Advanced:
Post deleted by yanivr78

 



yanivr78
Novice

Mar 8, 2013, 4:59 AM

Post #1 of 10 (3117 views)
Post deleted by yanivr78

 


FishMonger
Veteran / Moderator

Mar 8, 2013, 4:44 PM

Post #2 of 10 (3104 views)
Re: [yanivr78] Regex source -> destination line matches... [In reply to] Can't Post


Quote
if you can see, there are 3 IP's within these lines,

Those sample lines have 2 IP addresses each. I'm not sure where you're getting 3 IP's. So, which IP's do you want to capture?

A couple side comments.

Please use the code tags around your code to retain the code formatting which makes it easier for us to read your script.

You should add the warnings and strict pragmas, which should be in every Perl script you write.


Code
#!/usr/bin/perl 

use warnings;
use strcit;


The strict pragma will require you to declare your vars, which is normally done by adding the 'my' keyword.

Code
my %arguments=@ARGV;


Your script would be improved by using the Getopts::Long module for handling the parsing of the command line args.
http://search.cpan.org/~jv/Getopt-Long-2.38/lib/Getopt/Long.pm

Add to that the use of Pod::Usage module to handle the output of the usage statement and additional help documentation.
http://search.cpan.org/~marekr/Pod-Usage-1.61/lib/Pod/Usage.pm

Don't use bareword filehandles. Instead, use a lexical var for the handle. Also, use the 3 arg form of open and include the reason it failed in the die statement (i.e., include the $! var in the statement).

Don't use '&' when calling a sub unless you know and understand its side effects and want/need those side effects.


(This post was edited by FishMonger on Mar 8, 2013, 4:46 PM)


Kenosis
User

Mar 8, 2013, 5:01 PM

Post #3 of 10 (3099 views)
Re: [yanivr78] Regex source -> destination line matches... [In reply to] Can't Post

Solutions for capturing the last two of the three IPs have been given in this forum.


yanivr78
Novice

Mar 8, 2013, 9:46 PM

Post #4 of 10 (3086 views)
Re: [FishMonger] Regex source -> destination line matches... [In reply to] Can't Post

Thanks alot !
1) if you look at the source lines you will see 3 IP's,
the first one just right after the date and time (starting from charachter 16).
following that IP comes two others which are the real source and destination IP's (which the code fails to fetch via regex),
I tried using :
if (index ($line,$arguments {"-src"}) < index($line,$arguments {"-dst"})){

but when I print the lines I see a strange phenomenon, if the user use -src 10.(no matter what goes here) , the search pattern gets tackled on charachter 16 - weird ha ?

regarding your other remarks, I will definitely use them, thank you so much for that !

I have 2 questions in regards :

1) "use the 3 arg form of open and include the reason it failed in the die statement (i.e., include the $! var in the statement)."

Will it be alright if you take out the example from my code and show here what you mean ? (I need to see it in order to understand)

2) "Don't use '&' when calling a sub unless you know and understand its side effects and want/need those side effects."

a. my interpreter fails to read the call for the subroutine if I will not use '&'...:/
b. what are the side effects (sorry I am new to perl) ?

Many thanks for all the help guys !


Laurent_R
Veteran / Moderator

Mar 9, 2013, 4:54 AM

Post #5 of 10 (3081 views)
Re: [yanivr78] Regex source -> destination line matches... [In reply to] Can't Post

Just one simplified solution:


Code
my $line = "Dec 4 20:25:21 10.85.254.10 %ASA-6-106100: access-list inside permitted tcp inside/10.80.20.25(42940) -> pscdmz/155.16.61.33(3181) hit-cnt 1 first hit"; 
my $ip = qr/\d+\.\d+\.\d+\.\d+/; #IP regex should be made much more selective, for instance by replacing + by {1,3}, this is just a quick thing for the example
my ($source, $dest) = ($2, $3) if $line =~ /($ip).+\D($ip).+\D($ip)/;
print $source, " ", $dest; # prints 10.80.20.25 155.16.61.33


This was just a quick demonstration to show you how to pick up the second and the third IP addresses in the line. I would probably not write my code this way.

A less trivial solution could be to replace the relevant line by:


Code
my ($source, $dest) =  ($line =~ /($ip).+\D($ip).+\D($ip)/)[1, 2];


Or:

Code
my ($source, $dest) =  ($line =~ /$ip.+\D($ip).+\D($ip)/)[0, 1];


Or, yet simpler:

Code
my ($source, $dest) =  ($line =~ /$ip.+\D($ip).+\D($ip)/);


And, as said in the comment, the IP regex should be much more elaborated, this was just a quick fix.


In Reply To
1) "use the 3 arg form of open and include the reason it failed in the die statement (i.e., include the $! var in the statement)."

Will it be alright if you take out the example from my code and show here what you mean ? (I need to see it in order to understand)


Something like this:


Code
my $in_file = "my_file.txt"; 
open my $FILE_HANDLER, "<", $in_file or die "Can't open $in_file $!\n";



(This post was edited by Laurent_R on Mar 9, 2013, 5:00 AM)


FishMonger
Veteran / Moderator

Mar 9, 2013, 6:51 AM

Post #6 of 10 (3074 views)
Re: [yanivr78] Regex source -> destination line matches... [In reply to] Can't Post


Quote
a. my interpreter fails to read the call for the subroutine if I will not use '&'...:/


The script you posted will work without using '&'. If it doesn't, then your perl installation is corrupt and should be reinstalled.



Quote
b. what are the side effects (sorry I am new to perl) ?


Answer found in perldoc perlsub

Quote
NAME(LIST); # & is optional with parentheses.
NAME LIST; # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME; # Makes current @_ visible to called subroutine.



yanivr78
Novice

Mar 9, 2013, 9:45 AM

Post #7 of 10 (3069 views)
Re: [FishMonger] Regex source -> destination line matches... [In reply to] Can't Post

Alright that's clear enough,
thank you very much for all the help !


Kenosis
User

Mar 9, 2013, 12:58 PM

Post #8 of 10 (3061 views)
Re: [Laurent_R] Regex source -> destination line matches... [In reply to] Can't Post

And you could even:

Code
( $line =~ /($ip)/g )[ 1, 2 ]


You made an excellent point: IP regex should be made much more selective...

And this is why I like using Regexp::Common for such a job. It also does some data integrity checks, but that could be handled as follows (using your regex):

Code
use strict; 
use warnings;

my $line = "Dec 4 20:25:21 10.85.254.10 %ASA-6-106100: access-list inside permitted tcp inside/10.80.20.25(42940) -> pscdmz/155.16.61.33(3181) hit-cnt 1 first hit";
my $ip = qr/\d+\.\d+\.\d+\.\d+/;

my ( $source, $dest ) = grep { ( grep { $_ > -1 and $_ < 256 } split /\./ ) == 4 } ( $line =~ /($ip)/g )[ 1, 2 ];

print +($source and $dest) ? "($source, $dest)\n" : "An out-of-range octet was found in an IP address.\n";



Laurent_R
Veteran / Moderator

Mar 9, 2013, 3:53 PM

Post #9 of 10 (3051 views)
Re: [Kenosis] Regex source -> destination line matches... [In reply to] Can't Post


In Reply To
And you could even:

Code
( $line =~ /($ip)/g )[ 1, 2 ]



I tried that, or something very similar to that, when I wrote my previous message, but it did not seem to work properly. I must have made a silly mistake somewhere when I tested it.

Anyway, what really seemed to puzzle the OP was how to pick up the second and third IP addresses and not the first one, so my examples really focussed on various ways to do that, and were hopefull progressively built for pedagogical purposes.


In Reply To
You made an excellent point: IP regex should be made much more selective...

And this is why I like using Regexp::Common for such a job.


I fully agree. My very simplistic IP regex was just for the purpose of demonstrating the code that followed, and I said it was too simplistic.

At the very least, I would check for the number of digits in each segment with something like this:


Code
my $ip = qr/(?:\d{1,3}\.){3}\d{1,3}/;


or, better, I would be trying to check at least to a certain extent the ranges of each octet one way or another.

But, then, of course, there may be a mistake in my code above or in whichever code I would try to add for checking the range (and I know for a fact it is not an easy task to get it really right), it is unlikely that I will have tested it nearly as thoroughly as the Regexp::Common module has been tested.

So, yes, agreed, using such a module is usually a better idea.

Having said that, the files I am working on are usually not free format files, I can usually get away with quite simpler validation rules.

But I also have had to try to validate URLs or e-mail addresses (or, I should rather say, I had to to try to detect improper URLs or e-mail addresses), that can easily become a real nightmare.


Kenosis
User

Mar 9, 2013, 6:41 PM

Post #10 of 10 (3047 views)
Re: [Laurent_R] Regex source -> destination line matches... [In reply to] Can't Post

...my examples really focussed on various ways to do that, and were hopefull progressively built for pedagogical purposes.

Yes, excellent! And these were well done...

...I am working on are usually not free format files, I can usually get away with quite simpler validation rules.

Another good point. In other forums (e.g., StackOverflow), I've seen solutions coded for such a wide range of unlikely exceptions. I can understand wanting to create exception-tolerant code, but if the dataset is consistent, I'm not too sure that extra effort's justified.

Email and URL validation opens up a whole new can of, um, perl/s ...

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives