Operating System - Linux
1819504 Members
3054 Online
109603 Solutions
New Discussion юеВ

Perl script to find the MX records for a given domain

 
Arun Kumar Rajamari
Frequent Advisor

Perl script to find the MX records for a given domain

Hi,

I need to find the MX record for a given domain,say

H:\>nslookup -type=mx google.com

Non-authoritative answer:
google.com MX preference = 10, mail exchanger = smtp3.google.com
google.com MX preference = 10, mail exchanger = smtp4.google.com
google.com MX preference = 10, mail exchanger = smtp1.google.com
google.com MX preference = 10, mail exchanger = smtp2.google.com

smtp3.google.com internet address = 64.233.183.25
smtp4.google.com internet address = 72.14.215.25
smtp1.google.com internet address = 216.239.57.25
smtp2.google.com internet address = 64.233.167.25

Instead using Net::DNS module to find,is there anyother way to implement in Perl script.
I would also like to know about the same in Shell script.

Could you please help me in this

Thanks in advance,
Arun
5 REPLIES 5
Ralph Grothe
Honored Contributor

Re: Perl script to find the MX records for a given domain

Hi Arun,

I wonder what's so bad about using Net::DNS
(maybe apart from that it requires a few other, but not exotic modules)?

Of course you could reimplement the Domain protocol yourself, but I would consider this far from being easier than using Net::DNS ;-)

For instance my ISP is the dreaded German dinosaur, and it provided me with this mail domain 't-online.de.'.
So I could query our caching Internet nameserver (with bogus 123.123.123.123) to get me all t-online mail exchangers.


$ cat mx.pl
#!/usr/bin/perl

use strict;
use warnings;

use Net::DNS;

my $res = Net::DNS::Resolver->new(nameservers => [qw(123.123.123.123)]);

my $rr = $res->query('t-online.de' => 'MX');

my @exchangers = map $_->{exchange}, @{$rr->{answer}};

print join "\n", @exchangers, q{};



That would print this
(you could sort better by priority etc.)

$ ./mx.pl
mailin07.sul.t-online.de
mailin00.sul.t-online.de
mailin01.sul.t-online.de
mailin02.sul.t-online.de
mailin03.sul.t-online.de
mailin04.sul.t-online.de
mailin05.sul.t-online.de
mailin06.sul.t-online.de

Madness, thy name is system administration
Arun Kumar Rajamari
Frequent Advisor

Re: Perl script to find the MX records for a given domain

Hi,

As Net::DNS requires modules linked to it to be installed like Socket6,IPV6 and more, the problem occurs in installing all the modules.

I used gethostbyname function which could get only few of the IP addresses for a given domain.

So without Net::DNS and to avoid sequential installation of modules,would need a solution to find the MX records.

Hope you could understand.

Thanks,
Arun
Ralph Grothe
Honored Contributor

Re: Perl script to find the MX records for a given domain

Hi Arun,

I understand your problems with Net::DNS.
Yes, it comes with an XS interface and needs some linking.
But it doesn't require IPv6 modules.
Our network is still IPv4 (I wonder who already made the transition?).
From the README in my ~/.cpan/build/Net-DNS-0.59 directory I see that they claim these prerequisites

Test::More
IO::Socket
MIME::Base64
Digest::MD5
Digest::HMAC_MD5
Net::IP

If you have a build platform somewhere with an ANSI compliant C compiler the easiest way of installation there would be to

# perl -MCPAN -e 'install Net::DNS'

If this isn't possible for you
then you could just fork to the HP-UX implementation of nslookup and simply parse its output (though nslookup is quite a controversial tool while others like dig or host are probably to be preferred).

Just to give you an (untested) idea how this could look like (plrease, refer to perldoc perlipc to find correct examples).

e.g.

my $nameserver = '123.123.123.123';
my $maildom = 'google.com.';
my $querytype = 'mx';

my $pid = open NSPIPE, '-|';
die "Couldn't open pipe: $!" unless defined $pid;
if ($pid) {
while () {
# parse here whatever feasible
# from output of nslookup
}
close NSPIPE;
} else {
exec '/usr/bin/nslookup', "-q=$querytype", $maildom, $nameserver;
die "Couldn't exec nslookup: $!";
}

Madness, thy name is system administration
Arun Kumar Rajamari
Frequent Advisor

Re: Perl script to find the MX records for a given domain

Hi,

I used the system command in perl for executing the nslookup with MX option and working fine.
While doing nslookup in the command prompt,I am geting the following errors.

Can't find server name for address
Non-existent host/domain

In an assumption that the nslookup resolver/configuration file is not updated with the details,would like to transfer the nslookup query to alternative DNS server and get the result.

Also how to do the same using Perl script

default command in perl script is as follows
system(nslookup -type=MX google.com)

So have to transfer the same to alternaive DNS server.

Thanks,
Arun

Ralph Grothe
Honored Contributor

Re: Perl script to find the MX records for a given domain

I'm not sure what you want to achieve.
But if it's the output of the nslookup command that you wish to capture, system() is most likely to be the wrong call,
unless you run it as a forked child to whom you set up a pipe to either stdin or stdout in advance (bidirectional communication would yet be another story).
But in this case one would fork and exec anyway, I would say.
The most simple way to capture a subprocess's output is by using the backticks or the qx delimiter.
e.g.

my $nslookup_said = qw(/usr/bin/nslookup -q=mx google.com.);

But beware, that this way you cannot avoid that Perl passes the qx() or backticked expression to the shell for expanding any meta characters.
This is inherently insecure, especially if the expression contains any user input.

A better way would be to use a forked open and execute system() or exec() in the child's copy of the code.
This way you can pass any command and options or arguments as a list, thereby totally avoiding any shell execution.

e.g.

local *PH;
my $pid = open(PH, '-|');
die "Cannot open pipe to nslookup: $!\n" unless defined $pid;
my $nslookup_said;
if ($pid) {
# let the parent read output from the child
# assume moderate amount of output, and slurp
local $/;
$nslookup_said = ;
# parent will block until we close the pipe
# note Perl will automatically fetch child's exit code
# and place it in $?
# releiving us from installing SIGCHLD handler
close PH;
} else {
exec qw(/usr/bin/nslookup -q=mx google.com.);
# die is the only statement
# that may follow an exec
die "Cannot fork nslookup: $!\n";
}
Madness, thy name is system administration