in reply to Replicating Net::DNS::Packet

So i found this:
use IO::Socket; $hostname = $ARGV[0]; $defdomain = ".oog.org"; # default domain if not present @servers = qw(nameserver1 nameserver2 nameserver3); # name of the name + servers foreach $server (@servers) { &lookupaddress($hostname,$server); # populates %resul +ts } %inv = reverse %results; # invert the result hash if (scalar(keys %inv) > 1) { # see how many elements it has print "There is a discrepancy between DNS servers:\n"; use Data::Dumper; print Data::Dumper->Dump([\%results],["results"]),"\n"; } sub lookupaddress{ my($hostname,$server) = @_; my($qname,$rname,$header,$question,$lformat,@labels,$count); local($position,$buf); ### ### Construct the packet header ### $header = pack("n C2 n4", ++$id, # query id 1, # qr, opcode, aa, tc, rd fields (only rd set) 0, # rd, ra 1, # one question (qdcount) 0, # no answers (ancount) 0, # no ns records in authority section (nscount) 0); # no addtl rr's (arcount) # if we do not have any separators in the name of the host, # append the default domain if (index($hostname,'.') == -1) { $hostname .= $defdomain; } # construct the qname section of a packet (domain name in question +) for (split(/\./,$hostname)) { $lformat .= "C a* "; $labels[$count++]=length; $labels[$count++]=$_; } ### ### construct the packet question section ### $question = pack($lformat."C n2", @labels, 0, # end of labels 1, # qtype of A 1); # qclass of IN ### ### send the packet to the server and read the response ### $sock = new IO::Socket::INET(PeerAddr => $server, PeerPort => "domain", Proto => "udp"); $sock->send($header.$question); # we're using UDP, so we know the max packet size $sock->recv($buf,512); close($sock); # get the size of the response, since we're going to have to keep # track of where we are in the packet as we parse it (via $positio +n) $respsize = length($buf); ### ### unpack the header section ### ($id, $qr_opcode_aa_tc_rd, $rd_ra, $qdcount, $ancount, $nscount, $arcount) = unpack("n C2 n4",$buf); if (!$ancount) { warn "Unable to lookup data for $hostname from $server!\n"; return; } ### ### unpack the question section ### # question section starts 12 bytes in ($position,$qname) = &decompress(12); ($qtype,$qclass)=unpack('@'.$position.'n2',$buf); # move us forward in the packet to end of question section $position += 4; ### ### unpack all of the resource record sections ### for ( ;$ancount;$ancount--){ ($position,$rname) = &decompress($position); ($rtype,$rclass,$rttl,$rdlength)= unpack('@'.$position.'n2 N n',$buf); $position +=10; # this next line could be changed to use a more sophisticated # data structure, it currently picks the last rr returned + $results{$server}= join('.',unpack('@'.$position.'C'.$rdlength,$buf)); $position +=$rdlength; } } # handle domain information that is "compressed" as per RFC1035 # we take in the starting position of our packet parse and return # the name we found (after dealing with the compressed format pointer) # and the place we left off in the packet at the end of the name we fo +und sub decompress { my($start) = $_[0]; my($domain,$i,$lenoct); for ($i=$start;$i<=$respsize;) { $lenoct=unpack('@'.$i.'C', $buf); # get the length of label if (!$lenoct){ # 0 signals we are done with this sectio +n $i++; last; } if ($lenoct == 192) { # we've been handed a pointer, so recurs +e $domain.=(&decompress((unpack('@'.$i.'n',$buf) & 1023)))[1 +]; $i+=2; last } else { # otherwise, we have a plain label $domain.=unpack('@'.++$i.'a'.$lenoct,$buf).'.'; $i += $lenoct; } } return($i,$domain); }
That looks perfect for what i need, but how would i actually set this up to print out the packet? I don't have enough networking knowledge to understand this to be honest. So if anyone can modify it for me, it would be greatly appreciated and save me ALOT of time.

Replies are listed 'Best First'.
Re^2: Replicating Net::DNS::Packet
by taint (Chaplain) on Jun 07, 2014 at 06:53 UTC
    Greetings, AM.

    This looks like something that's w-a-y over your head -- no offence intended.

    Problem with something like that, is that you're attempting to use code/scripts you have no knowledge of. THIS IS A DANGEROUS POLICY. You should never adopt such a policy, as you have no knowledge of the potential consequences. Which can be substantial.

    Did you intend to put this script on a (your) web site? Yes? Do you know what can happen if somebody puts something in one of the form fields that wasn't what it was intended for? Very bad things WILL happen if they do. Wipe your (hard) drive, hijack your computer, lift your sensitive data. Ever buy something online with a credit card? Have any idea how much of that information, still resides on your computer? More than you probably realize.

    Sure. I've made a pretty big deal out of this, and you're probably thinking that I'm just exaggerating. Truth is; I am NOT. Everything I just stated, is ABSOLUTE FACT.

    Logistically speaking; if you don't know much about networks. This script is not for you. You probably can't set it up to work on your system w/o a great deal of trouble. I'm quite sure you're not running a local DNS. So you'll have to try your upstream's DNS. They might have provisions that prevent you from obtaining the data you're trying to retrieve. DNS managers have strict policies where their zones, and data management are concerned. They almost never permit recursive queries. Else they become a DNS server for the entire internet -- gratis. It also leads to potential cache-poisoning. Which means all their zones get hijacked. So without a fair amount of knowledge, where the DNS is concerned, and Networking, in general. Your efforts will likely be in vain.

    Best wishes.

    --Chris

    P.S.

    That script is a bit dated. For example, headers haven't had a 512k limit since ~2000.

    ¡λɐp ʇɑəɹ⅁ ɐ əʌɐɥ puɐ ʻꜱdləɥ ꜱᴉɥʇ ədoH