Reputation: 247
I have a local DNS script that I've inherited from a past employee that needs to compare some values to see if they match specific MX records and IP addresses.
The MX part I have down okay:
120 $doug = doug.local
139 if ($mx_record =~ /$doug/) {
140 print ("Mail on doug.\n");
141 }
142 else {
143 print ("Not on doug.\n");
144 }
$mx_record
is a line from an mx query that would look like this:
thomas. 302 IN MX 10 doug.local.
Now I need to see if the A record matches.
The $a_record
variable from the query looks like this.
thomas. 300 IN A 10.0.0.47
How do I do a conditional statement to match an IP address?
I need to define the IP in a variable and then see if the $a_record
variable contains that defined IP.
Upvotes: 1
Views: 6259
Reputation: 165456
If you just want to match an IPv4 regex, use Regexp::Common::net.
Rather than running a regex over the whole line, its safer to tokenize them and match individual parts as necessary.
use strict;
use warnings;
use Data::Dumper;
sub parse_record {
my $line = shift;
# special rules for parsing different types
my %More4Type = (
MX => sub { return( priority => $_[0], provider => $_[1] ) },
default => sub { return( provider => $_[0] ) }
);
my(%record, @more);
(@record{qw(host uhh class type)}, @more) = split /\s+/, $line;
my $more_func = $More4Type{$record{type}} || $More4Type{default};
%record = (%record, $more_func->(@more));
return \%record;
}
while(my $line = <DATA>) {
print Dumper parse_record($line);
}
__END__
thomas. 302 IN MX 10 doug.local.
thomas. 300 IN A 10.0.0.47
google.com. 24103 IN NS ns2.google.com.
Now that you've parsed the line, its a simple matter of looking at $record{type}
and $record{provider}
or whatever you need. For a little bit of effort this is far more flexible and less bug prone.
Though there's probably something on CPAN to do the parsing for you.
Upvotes: 3
Reputation: 339985
Since the IP address might not be in its most compact decimal notation, I suggest you should use the inet_aton()
function from the Socket
module:
use Socket;
my $ip_to_match = inet_aton('10.0.0.47');
...
if (inet_aton($field) == $ip_to_match) {
...
}
NB: assumes that the DNS record has already been split down to its component parts
Upvotes: 0
Reputation: 580
try this:
if ($mx_record =~ /A\w+(<record_ip>(?:/[0-9]{1,3}.){4})/ {
print $record_ip
}
This will check for A followed by whitespace, followed by a dotted quad. The quad is saved in the variable $record_ip
Upvotes: 1
Reputation: 14669
I'm sure there's a better way, but this will get you pretty close:
if($a_record =~ /((?:\d{1,3}\.){3}\d{1,3})/) {
warn "IP was: $1";
}
# IP was: 10.0.0.47
This matches 10.0.0.
then the final 47
.
Upvotes: 2
Reputation: 8406
my $a_record = 'thomas. 300 IN A 10.0.0.47';
my $ip = '10.0.0.47';
if ($a_record =~ /\b(\Q$ip\E)$/) {
print "Matches: $1\n";
}
Upvotes: 0
Reputation: 40152
This will match a entry that looks like a ip address, but will also match 999.999.999.999. Make sure to validate the matched address before using it.
if ($mx_record =~ /(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})/) {...}
Upvotes: 1