Alex
Alex

Reputation: 53

ip matching in perl

I have an ip address 129.115.50.255

I have tcpdump file that I am trying to print out all lines except ones that contain the ip address.

my code is simply

open(IN, "$ARGV[0]");
while($line = <IN>){
   next if /129\.115\.50\.255/;
   print $line, "\n";
}
close(IN1);

I can't get it to print out the expected result. Can anyone help me understand what the proper syntax or method would be?

Upvotes: 0

Views: 139

Answers (4)

pajaja
pajaja

Reputation: 2212

You already got enough answers on how to fix the perl code but if you have a binary file generated by tcpdump you can't filter it like a plain text. You need an application that knows how to read pcap file format. You can use tcpdump to read the packet capture and filter the ip:

tcpdump -nr your_file.pcap host not 129.115.50.255

Upvotes: 0

elcaro
elcaro

Reputation: 2317

If you want to match an "exact" string, then regex isn't really needed. Instead you can use index to determine if your string is a substring of the line.

while (<>) {
    print unless (index $_, "129.115.50.255") != -1;
}

index will return a 0 or a positive integer if the second argument provided is part of the first... otherwise it returns a -1... So this is saying is print every line unless "129.115.50.255" is part of the line. As an added bonus, index is typically faster than a regex match as it uses less resources.

The downside of using index is you have to be careful of the last octet in your IP address, because it's looking for any substring. Say you were trying to filter out 129.115.50.2, you would also filter out 129.115.50.200 or .212, or .255, etc. You could combat this by appending a space (or whatever delimeter appears in the log file) after the IP address, eg. index $_, "129.115.50.2 "

IF you want to use regex, manually escaping dots is annoying. Let perl do it for you and print $line unless $line =~ quotemeta("129.115.50.255")

P.S. while (<>) is essentially short hand for open File, $ARGV[0]; while (<File>)

Upvotes: 2

schtever
schtever

Reputation: 3250

The problem is that you assigned the input to $line, so your test has to also be done against $line.

open(IN, "$ARGV[0]");
while($line = <IN>){
    chomp($line);
    next if $line =~ /129\.115\.50\.255/;
    print $line, "\n";
}
close(IN);

Fixed the close at the end, you had close(IN1) not close(IN). Also added a chomp on the input to eliminate the extra newline on output.

Upvotes: 3

vks
vks

Reputation: 67998

^(?!.*\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}).*$

You can simply use this.This uses lookahead to make sure line has no ip address.See demo.Do match with each line.

https://www.regex101.com/r/bC8aZ4/19

Upvotes: 0

Related Questions