Net::DNS::RR::HIP - DNS HIP resource record


Net-DNS documentation Contained in the Net-DNS distribution.

Index


Code Index:

NAME

Top

Net::DNS::RR::HIP - DNS HIP resource record

SYNOPSIS

Top

use Net::DNS::RR;

DESCRIPTION

Top

This class implements the HIP RR (RFC5205)

METHODS

Top

pkalgorithm

Returns or sets the public key algorithm field

hit

Returns or sets the hit in base16 representation.

hitbin

Returns or sets the binary representation of the the hit.

Using hit or hitbin to set the one of these attributes will update both attributes.

pubkey

Returns or sets the publick key in base64 representation.

pubkey

Returns or sets the binary representation of the the public key.

Using pubkey or pubkeybin to set the one of these attributes will update both attributes.

rendezvousservers



      my $rendezvousservers=$hip->rendezvousservers();

Returns a reference to an array of rendezvous servers. The representation is in Perl's internal storage format i.e. without trailing dot.

     $hip->rendezvousservers( [ qw|example.com  example.net| ] )

With a reference to an array as the argument this method will set the rendezvousservers.

NOTES

Top

Since (multiline) base64 encoded publik keys may contain spaces string parsing of the HIP RR depends on rendevous server names containing at least one . (dot) in their domain name. Failure of string parsing will return an 'undef'.

The rdatastr method (and hence the string and print methods) return the rendezvousservers as fully qualified domain names.

COPYRIGHT

Top

SEE ALSO

Top

perl(1), Net::DNS, Net::DNS::Resolver, Net::DNS::Packet, Net::DNS::Header, Net::DNS::Question, Net::DNS::RR, RFC 5205


Net-DNS documentation Contained in the Net-DNS distribution.

package Net::DNS::RR::HIP;
#
# $Id: HIP.pm 835 2009-12-29 20:20:38Z olaf $
#
# See RFC 5205 for the specification of this record.

use strict;
use MIME::Base64;
use Data::Dumper;

use vars qw(@ISA $VERSION);

@ISA     = qw(Net::DNS::RR);
$VERSION = (qw$LastChangedRevision: 718 $)[1];






sub new {
	my ($class, $self, $data, $offset) = @_;
	
        if ($self->{'rdlength'} > 0) {
                my $offset_pkalgorithm  = $offset+1;
                my $offset_pklength     = $offset+2;
                my $offset_hit          = $offset+4;
		
                $self->{'_hitlength'} = unpack('C', substr($$data, $offset, 1));
		my $offset_pubkey    = $offset_hit + $self->{'_hitlength'};
		
                $self->{'pkalgorithm'}    = unpack('C', substr($$data, $offset_pkalgorithm, 1));
                $self->{'_pklength'}    = unpack('n', substr($$data, $offset_pklength, 2));
		my $offset_rendezvous    = $offset_pubkey + $self->{'_pklength'};

                $self->{'hitbin'}    = substr($$data, $offset_hit, $self->{'_hitlength'});
		$self->{'hit'}=unpack("H*",$self->{'hitbin'});

		$self->{'pubkeybin'}= substr($$data,$offset_pubkey, $self->{'_pklength'});
		$self->{'pubkey'}=encode_base64($self->{'pubkeybin'},"");
                my $rsoffset    = $offset_pubkey + $self->{'_pklength'};
		$self->{'rendezvousservers'}= [];



		my $i=10;
		while( ($rsoffset-$offset)<$self->{'rdlength'}){
			exit unless $i--;
			my ($name, $nextoffset) = Net::DNS::Packet::dn_expand($data, $rsoffset);
			push (@{$self->{'rendezvousservers'}},$name);
			$rsoffset=$nextoffset;

		}
	}

	return bless $self, $class;
}



sub new_from_string {
	my ($class, $self, $string) = @_;
	# first turn multiline into single line
	$string =~ tr/()//d if $string;
	$string =~ s/\n//mg if $string;
	
	if ($string && ($string =~ /^\s*(\d+)\s+(\S+)\s+(.*)$/)) {
		@{$self}{qw(pkalgorithm hit)} = ($1, $2);
		$self->{'hitbin'}=pack("H*",$self->{'hit'});
		my $reststring=$3;
		# rest string are the space separated components of the base64 encoded public key 
		# appended by fully qualified domain names.
		# We'll chop off the FQDNs
		$self->{'rendezvousservers'}=[];
		while ($reststring =~ s/^(.*)(\s+((\S+\.)(\S+\.?)*))\s*$/$1/s){
			unshift (@{$self->{'rendezvousservers'}},$3);
		}
		$reststring=~s/\s//g;
		return () if (length($reststring) % 4); #base64 length should be mulitple of 4
		$self->{'pubkey'}=$reststring;
		$self->{'pubkeybin'} =  decode_base64( $self->{'pubkey'} );
      	}

	return bless $self, $class;
}




sub rr_rdata {
	my ($self, $packet, $offset) = @_;
	my $rdata = "";

	if (exists $self->{"pubkey"}) {
		# This is for consistency. 
		my $hitbin=$self->hitbin();
		my $pubkeybin=$self->pubkeybin();
		$rdata = pack("C", $self->{'_hitlength'});
		$rdata .= pack("C", $self->{'pkalgorithm'});
		$rdata .= pack("n", $self->{'_pklength'});
		$rdata .= $hitbin;
		$rdata .= $pubkeybin;
		foreach my $dname (@{$self->{'rendezvousservers'}}){
			$rdata .= $self->_name2wire ($dname);
		}
	}

	return $rdata;
}



sub rdatastr {
	my $self = shift;
	my $rdatastr='';

	if (exists $self->{"pubkey"}) {
		$rdatastr = $self->pkalgorithm       . ' '   .
		            $self->hit  . ' '  .
		            $self->pubkey       . ' ';
		
		foreach my $dname ( @{$self->rendezvousservers()} ) {
			$rdatastr .= $dname.". ";
		}
		chop $rdatastr;
		
	}

	return $rdatastr;
}


sub hitbin {
	my ($self, $new_val) = @_;
	if (defined $new_val) {
		$self->{'hitbin'} = $new_val;
		$self->{'hit'}=unpack("H*",$new_val);
	}
	$self->{'hitbin'}=pack("H*",$self->{'hit'}) unless defined ($self->{'hitbin'});
	$self->{'_hitlength'} =length($self->{'hitbin'});
	return ($self->{'hitbin'});
}	


sub hit {
	my ($self, $new_val) = @_;
	if (defined $new_val) {
		$self->{'hitbin'} = $new_val;
		$self->{'hitbin'}=pack("H*",$new_val);
	}
	$self->{'hit'}=unpack("H*",$self->{'hitbin'}) unless defined ($self->{'hit'});
	$self->{'_hitlength'} =length($self->{'hitbin'});
	return ($self->{'hit'});
}	




sub pubkeybin {
	my ($self, $new_val) = @_;
	if (defined $new_val) {
		$self->{'pubkeybin'} = $new_val;
		$self->{'pubkey'}=encode_base64($self->{'pubkeybin'},"");

	}
	$self->{'pubkeybin'}= decode_base64($self->{'pubkey'}) unless defined ($self->{'pubkeybin'});
	$self->{'_pklength'} =length($self->{'pubkeybin'});
	return ($self->{'pubkeybin'});
}	






sub pubkey {
	my ($self, $new_val) = @_;
	if (defined $new_val) {
		$self->{'pubkey'} = $new_val;
		$self->{'pubkeybin'}=decode_base64($self->{'pubkey'});

	}
	$self->{'pubkey'}= encode_base64($self->{'pubkeybin'},"") unless defined ($self->{'pubkey'});
	$self->{'_pklength'} =length($self->{'pubkeybin'});
	return ($self->{'pubkey'});
}	





sub _normalize_dnames {
	my $self=shift;
	$self->_normalize_ownername();
	my @dnames = @{$self->{'rendezvousservers'}};
	$self->{'rendezvousservers'}=[];
	foreach my $dname (@dnames){
		push (   @{$self->{'rendezvousservers'}},   Net::DNS::stripdot($dname) )
	}


}


sub rendezvousservers {
	my ($self, $new_val) = @_;

	if ($new_val) {
		$self->{'rendezvousservers'}= $new_val;
	}

	$self->_normalize_dnames();
	return $self->{'rendezvousservers'};

}













1;