| Net-DNS documentation | Contained in the Net-DNS distribution. |
Net::DNS::Question - DNS question class
use Net::DNS::Question
A Net::DNS::Question object represents a record in the
question section of a DNS packet.
$question = Net::DNS::Question->new("example.com", "MX", "IN");
Creates a question object from the domain, type, and class passed as arguments.
RFC4291 and RFC4632 IP address/prefix notation is supported for queries in in-addr.arpa and ip6.arpa subdomains.
($question, $offset) = Net::DNS::Question->parse(\$data, $offset);
Parses a question section record at the specified location within a DNS packet. The first argument is a reference to the packet data. The second argument is the offset within the packet where the question record begins.
Returns a Net::DNS::Question object and the offset of the next location in the packet.
Parsing is aborted if the question object cannot be created (e.g., corrupt or insufficient data).
print "qname = ", $question->qname, "\n";
print "zname = ", $question->zname, "\n";
Returns the domain name. In dynamic update packets, this field is
known as zname and refers to the zone name.
print "qtype = ", $question->qtype, "\n";
print "ztype = ", $question->ztype, "\n";
Returns the record type. In dymamic update packets, this field is
known as ztype and refers to the zone type (must be SOA).
print "qclass = ", $question->qclass, "\n";
print "zclass = ", $question->zclass, "\n";
Returns the record class. In dynamic update packets, this field is
known as zclass and refers to the zone's class.
$question->print;
Prints the question record on the standard output.
print $qr->string, "\n";
Returns a string representation of the question record.
$qdata = $question->data($packet, $offset);
Returns the question record in binary format suitable for inclusion in a DNS packet.
Arguments are a Net::DNS::Packet object and the offset within
that packet's data where the Net::DNS::Question record is to
be stored. This information is necessary for using compressed
domain names.
Copyright (c) 1997-2002 Michael Fuhr.
Portions Copyright (c) 2002-2004 Chris Reinhardt.
Portions Copyright (c) 2003,2006-2009 Dick Franks.
All rights reserved.
This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.
perl(1), Net::DNS, Net::DNS::Resolver, Net::DNS::Packet, Net::DNS::Update, Net::DNS::Header, Net::DNS::RR, RFC 1035 Section 4.1.2
| Net-DNS documentation | Contained in the Net-DNS distribution. |
package Net::DNS::Question; # # $Id: Question.pm 836 2009-12-30 09:41:53Z olaf $ # use strict; BEGIN { eval { require bytes; } } use vars qw($VERSION $AUTOLOAD); use Carp; use Net::DNS; $VERSION = (qw$LastChangedRevision: 800$)[1];
sub new { my $self = bless {}, shift; my $qname = shift; my $qtype = uc (shift || ''); my $qclass = uc (shift || ''); $qname = '' unless defined $qname; # || ''; is NOT same! $qname =~ s/\.+$//o; # strip gratuitous trailing dot # tolerate (possibly unknown) type and class in zone file order unless ( exists $Net::DNS::classesbyname{$qclass} ) { ( $qtype, $qclass ) = ( $qclass, $qtype ) if exists $Net::DNS::classesbyname{$qtype}; ( $qtype, $qclass ) = ( $qclass, $qtype ) if $qtype =~ /CLASS/; } unless ( exists $Net::DNS::typesbyname{$qtype} ) { ( $qtype, $qclass ) = ( $qclass, $qtype ) if exists $Net::DNS::typesbyname{$qclass}; ( $qtype, $qclass ) = ( $qclass, $qtype ) if $qclass =~ /TYPE/; } # if argument is an IP address, do appropriate reverse lookup my $reverse = _dns_addr($qname) if $qname =~ m/:|\d$/o; if ( $reverse ) { $qname = $reverse; $qtype ||= 'PTR'; } $self->{qname} = $qname; $self->{qtype} = ( $qtype || 'A' ); $self->{qclass} = ( $qclass || 'IN' ); return $self; } sub _dns_addr { my $arg = shift; # name or IP address # IP address must contain address characters only return undef if $arg =~ m#[^a-fA-F0-9:./]#o; # if arg looks like IPv4 address then map to in-addr.arpa space if ( $arg =~ m#(^|:.*:)((^|\d+\.)+\d+)(/(\d+))?$#o ) { my @parse = split /\./, $2; my $prefx = $5 || @parse<<3; my $last = $prefx > 24 ? 3 : ($prefx-1)>>3; return join '.', reverse( (@parse,(0)x3)[0 .. $last] ), 'in-addr.arpa'; } # if arg looks like IPv6 address then map to ip6.arpa space if ( $arg =~ m#^((\w*:)+)(\w*)(/(\d+))?$#o ) { my @parse = split /:/, (reverse "0${1}0${3}"), 9; my @xpand = map{/./ ? $_ : ('0')x(9-@parse)} @parse; # expand :: my $prefx = $5 || @xpand<<4; # implicit length if unspecified my $hex = pack 'A4'x8, map{$_.'000'} ('0')x(8-@xpand), @xpand; my $len = $prefx > 124 ? 32 : ($prefx+3)>>2; return join '.', split(//, substr($hex,-$len) ), 'ip6.arpa'; } return undef; }
use constant PACKED_LENGTH => length pack 'n2', (0)x2; sub parse { my ($class, $data, $offset) = @_; my ($qname, $index) = Net::DNS::Packet::dn_expand($data, $offset); die 'Exception: corrupt or incomplete data' unless $index; my $next = $index + PACKED_LENGTH; die 'Exception: incomplete data' if length $$data < $next; my ($qtype, $qclass) = unpack("\@$index n2", $$data); my $self = { qname => $qname, qtype => Net::DNS::typesbyval($qtype), qclass => Net::DNS::classesbyval($qclass) }; bless $self, $class; return wantarray ? ($self, $next) : $self; } # # Some people have reported that Net::DNS dies because AUTOLOAD picks up # calls to DESTROY. # sub DESTROY {}
sub zname { &qname; } sub ztype { &qtype; } sub zclass { &qclass; } sub AUTOLOAD { my $self = shift; my $name = $AUTOLOAD; $name =~ s/.*://o; croak "$AUTOLOAD: no such method" unless exists $self->{$name}; return $self->{$name} unless @_; my $value = shift; $value =~ s/\.+$//o if defined $value; # strip gratuitous trailing dot $self->{$name} = $value; }
sub print { print &string, "\n"; }
sub string { my $self = shift; return "$self->{qname}.\t$self->{qclass}\t$self->{qtype}"; }
sub data { my ($self, $packet, $offset) = @_; my $data = $packet->dn_comp($self->{qname}, $offset); $data .= pack('n2', Net::DNS::typesbyname(uc $self->{qtype}), Net::DNS::classesbyname(uc $self->{qclass}) ); return $data; } 1; __END__