Using Net::DNS to write your own recursor.

Here’s a bit of code I wrote for work that I thought was kind of neat; it uses a recursive function and Net::DNS to recurse DNS.


#!/usr/bin/perl
use strict;
use warnings;

use Net::DNS;

my $domain = 'schwer.us';
my $sonicrns= 'ns2.sonic.net';
my @root_ns = map $_ . '.root-servers.net', 'a'..'m';

&recurse($domain);

sub recurse($)
{
	my $domain = shift;
	my $rns = $root_ns[int(rand(@root_ns))];
	&_recurse($domain,$rns);
}

sub _recurse($$)
{
	my $domain = shift;
	my $ns     = shift;

	print "Asking $ns about $domain.\n";

	my $res = Net::DNS::Resolver->new('nameservers'=>[$ns]);
	my $que = $res->send("$domain.",'NS');

	if ( $que )
	{
		my @ns = $que->authority;
		# check headers for 'aa' bit
		my $header = $que->header;
		print "answer is ", $header->aa ? "" : "non-", "authoritative\n";

		if ( $header->aa ) # stop recursing when we have an authoritative answer.
		{
			my @authns = $que->answer;
			foreach my $authns ( @authns )
			{
				$authns->print;
			}
		}
		else # keep recursing no authoritative answer yet.
		{
			my $nsname = '';

			# my host is IPv4 only, so I can only ask IPv4 name servers.
			# this finds the first IPv4 name server and asks it.
			foreach my $ns ( @ns )
			{
				$nsname = $ns->nsdname;
				my $r = Net::DNS::Resolver->new('nameservers'=>[$sonicrns]);
				my $q = $r->query($nsname,'A');
				if ( $q )
				{
					my @answer = $q->answer;
					if ( $answer[0]->type eq 'A' )
					{
						last;
					}
				}
				$nsname = ''; # in-case we reach the end of the list and can't find an 'A' record.
			}
			if ( $nsname )
			{
				print "$nsname answers for $domain.\n";;
				&_recurse($domain,$nsname);
			}
			else
			{
				print "No IPv4 name servers to query for $domain.\n";
			}
		}
	}
	else
	{
		print "Could not find NS records for $domain.\n";
	}
}
This entry was posted in work. Bookmark the permalink.

One Response to Using Net::DNS to write your own recursor.

  1. Tom says:

    Nice one! I might play around with this!

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>