($mname, $rname, unpack "NNNNN", substr $pkt, $ofs)
}, # soa
11 => sub { ((join ".", unpack "C4", $_), unpack "C a*", substr $_, 4) }, # wks
12 => sub { local $ofs = $ofs - length; _dec_name }, # ptr
13 => sub { unpack "C/a* C/a*", $_ }, # hinfo
15 => sub { local $ofs = $ofs + 2 - length; ((unpack "n", $_), _dec_name) }, # mx
16 => sub { unpack "(C/a*)*", $_ }, # txt
28 => sub { AnyEvent::Socket::format_address ($_) }, # aaaa
33 => sub { local $ofs = $ofs + 6 - length; ((unpack "nnn", $_), _dec_name) }, # srv
35 => sub { # naptr
# requires perl 5.10, sorry
my ($order, $preference, $flags, $service, $regexp, $offset) = unpack "nn C/a* C/a* C/a* .", $_;
local $ofs = $ofs + $offset - length;
($order, $preference, $flags, $service, $regexp, _dec_name)
},
99 => sub { unpack "(C/a*)*", $_ }, # spf
);
sub _dec_rr {
my $name = _dec_name;
my ($rt, $rc, $ttl, $rdlen) = unpack "nn N n", substr $pkt, $ofs; $ofs += 10;
local $_ = substr $pkt, $ofs, $rdlen; $ofs += $rdlen;
[
$name,
$type_str{$rt} || $rt,
$class_str{$rc} || $rc,
($dec_rr{$rt} || sub { $_ })->(),
]
}
=item $dns = AnyEvent::DNS::dns_unpack $pkt
Unpacks a DNS packet into a perl data structure.
Examples:
# an unsuccessful reply
{
'qd' => [
[ 'ruth.plan9.de.mach.uni-karlsruhe.de', '*', 'in' ]
],
'rc' => 'nxdomain',
'ar' => [],
'ns' => [
[
'uni-karlsruhe.de',
'soa',
'in',
'netserv.rz.uni-karlsruhe.de',
'hostmaster.rz.uni-karlsruhe.de',
2008052201, 10800, 1800, 2592000, 86400
]
],
'tc' => '',
'ra' => 1,
'qr' => 1,
'id' => 45915,
'aa' => '',
'an' => [],
'rd' => 1,
'op' => 'query'
}
# a successful reply
{
'qd' => [ [ 'www.google.de', 'a', 'in' ] ],
'rc' => 0,
'ar' => [
[ 'a.l.google.com', 'a', 'in', '209.85.139.9' ],
[ 'b.l.google.com', 'a', 'in', '64.233.179.9' ],
[ 'c.l.google.com', 'a', 'in', '64.233.161.9' ],
],
'ns' => [
[ 'l.google.com', 'ns', 'in', 'a.l.google.com' ],
[ 'l.google.com', 'ns', 'in', 'b.l.google.com' ],
],
'tc' => '',
'ra' => 1,
'qr' => 1,
'id' => 64265,
'aa' => '',
'an' => [
[ 'www.google.de', 'cname', 'in', 'www.google.com' ],
[ 'www.google.com', 'cname', 'in', 'www.l.google.com' ],
[ 'www.l.google.com', 'a', 'in', '66.249.93.104' ],
[ 'www.l.google.com', 'a', 'in', '66.249.93.147' ],
],
'rd' => 1,
'op' => 0
}
=cut
sub dns_unpack($) {
local $pkt = shift;
my ($id, $flags, $qd, $an, $ns, $ar)
= unpack "nn nnnn A*", $pkt;
=6= |