1package Net::DNS::RR::IPSECKEY;
2
3
4#
5# $Id: IPSECKEY.pm 654 2007-06-20 15:02:50Z olaf $
6#
7use strict;
8BEGIN {
9    eval { require bytes; }
10}
11use vars qw(@ISA $VERSION );
12use Socket;
13
14use MIME::Base64;
15
16$VERSION = (qw$LastChangedRevision: 654 $)[1];
17
18@ISA = qw(Net::DNS::RR);
19
20
21#my %gatetype = (
22#    0 => "No gateway is present.",
23#    1 => "A 4-byte IPv4 address is present.",
24#    2 => "A 16-byte IPv6 address is present.",
25#    3 => "A wire-encoded domain name is present.",
26#    );
27
28#my %algtype = (
29#	RSA => 1,
30#	DSA => 2,
31#);
32
33#my %fingerprinttype = (
34#	'SHA-1' => 1,
35#);
36
37#my %fingerprinttypebyval = reverse %fingerprinttype;
38#my %gatetypebyval= reverse %gatetype;
39#my %algtypebyval	     = reverse %algtype;
40
41
42sub new {
43    my ($class, $self, $data, $offset) = @_;
44
45    my $offsettoprec    = $offset;
46    my $offsettogatetype = $offset+1;
47    my $offsettoalgor    = $offset+2;
48    my $offsettogateway  = $offset+3;
49    my $offsettopubkey;
50
51    $self->{'precedence'} = unpack('C', substr($$data, $offsettoprec, 1));
52    $self->{'gatetype'}    = unpack('C', substr($$data, $offsettogatetype, 1));
53    $self->{'algorithm'}    = unpack('C', substr($$data, $offsettoalgor, 1));
54
55    if ($self->{'gatetype'}==0){
56	$self->{'gateway'}='.';
57	$offsettopubkey= $offsettogateway;
58    }elsif($self->{'gatetype'}==1){
59	$self->{'gateway'} = inet_ntoa(substr($$data, $offsettogateway, 4));
60	$offsettopubkey= $offsettogateway+4;
61    }elsif($self->{'gatetype'}==2){
62	$offsettopubkey= $offsettogateway+16;
63	my @addr = unpack("\@$offsettogateway n8", $$data);
64	$self->{'gateway'} = sprintf("%x:%x:%x:%x:%x:%x:%x:%x", @addr);
65    }elsif($self->{'gatetype'}==3){
66	($self->{'gateway'}, $offsettopubkey) = Net::DNS::Packet::dn_expand($data, $offsettogateway);
67
68    }else{
69	die "Could not parse packet, no known gateway type (".$self->{'gatetype'}.")";
70    }
71    my($pubmaterial)=substr($$data, $offsettopubkey,
72			    ($self->{"rdlength"}-$offsettopubkey+$offset));
73
74    $self->{"pubbin"}=$pubmaterial;
75
76    return bless $self, $class;
77}
78
79
80
81sub new_from_string {
82	my ($class, $self, $string) = @_;
83	if ($string && ($string =~ /^(\d+)\s+(\d)\s+(\d)\s+(\S+)\s+(\S+)$/)) {
84		$self->{"precedence"} = $1;
85		$self->{"gatetype"} = $2;
86		$self->{"algorithm"} = $3;
87		if ($self->{"gatetype"}==2){
88			# Using the AAAA.pm parsing functionality.
89			my $AAAA=Net::DNS::RR->new("FOO AAAA ".$4);
90			$self->{"gateway"}=$AAAA->rdatastr;
91		}else
92		{
93			$self->{"gateway"}= $4;
94		}
95		$self->{"pubkey"}= $5;
96	}
97
98
99	return bless $self, $class;
100}
101
102
103sub pubkey {
104  my $self=shift;
105
106  $self->{"pubkey"}= encode_base64($self->{"pubbin"},"") unless defined $self->{"pubkey"};
107
108  return $self->{"pubkey"};
109}
110
111
112sub pubbin {
113  my $self=shift;
114  $self->{"pubbin"}= decode_base64($self->{"pubkey"}) unless defined $self->{"pubbin"};
115
116  return $self->{"pubbin"};
117}
118
119
120sub rdatastr {
121	my $self     = shift;
122	my $rdatastr = '';
123	return "" unless defined $self->{precedence};
124	$rdatastr .= $self->{"precedence"} . " ". $self->{"gatetype"} . " " .
125	  $self->{"algorithm"}. " ";
126	if ($self->{"gatetype"}==0){
127	  $rdatastr .= ". ";
128	}else{
129	  $rdatastr .= $self->{"gateway"}. " ";
130	}
131	$rdatastr .= $self->pubkey();
132
133	return $rdatastr;
134}
135
136sub rr_rdata {
137	my $self = shift;
138	my $rdata = "";
139	if (exists $self->{"precedence"}) {
140		$rdata .= pack("C", $self->{"precedence"});
141		$rdata .= pack("C", $self->{"gatetype"});
142		$rdata .= pack("C", $self->{"algorithm"});
143		if ($self->{"gatetype"}==1 ){
144			$rdata .= inet_aton($self->{"gateway"});
145		}elsif($self->{"gatetype"}==2){
146			my @addr = split(/:/, $self->{"gateway"});
147			$rdata .= pack("n8", map { hex $_ } @addr);
148		}elsif($self->{"gatetype"}==3){
149			# No Compression _name2wire will do.
150			$rdata .= $self->_name2wire($self->{"gateway"});
151		}
152		$rdata .= $self->pubbin();
153	}
154
155	return $rdata;
156
157}
158
159
160
161
162
1631;
164
165
166=head1 NAME
167
168Net::DNS::RR::IPSECKEY - DNS IPSECKEY resource record
169
170=head1 SYNOPSIS
171
172C<use Net::DNS::RR>;
173
174=head1 DESCRIPTION
175
176CLASS for the IPSECKEY RR.
177
178=head1 METHODS
179
180In addition to the regular methods
181
182
183=head2 algorithm
184
185Returns the RR's algorithm field in decimal representation
186
187    1 = RSA
188    2 = DSA
189
190=head2 precedence
191
192Returns the presedence
193
194=head2 	gatetype
195
196Returns the gatetype.
197
198   0  "No gateway is present.",
199   1  "A 4-byte IPv4 address is present.",
200   2  "A 16-byte IPv6 address is present.",
201   3  "A wire-encoded domain name is present.",
202
203=head2 gateway
204
205Returns the gateway in the relevant string notation.
206
207=head2 pubkey
208
209Returns the public key in base64 notation
210
211=head2 pubbin
212
213Returns the binary public key material in a string.
214
215=head1 TODO
216
217Check on validity of algorithm and gatetype.
218
219=head1 COPYRIGHT
220
221Copyright (c) 2007 NLnet LAbs, Olaf Kolkman.
222
223"All rights reserved, This program is free software; you may redistribute it
224and/or modify it under the same terms as Perl itself.
225
226=head1 SEE ALSO
227
228L<perl(1)>, L<Net::DNS>, L<Net::DNS::Resolver>, L<Net::DNS::Packet>,
229L<Net::DNS::Header>, L<Net::DNS::Question>, L<Net::DNS::RR>,
230draft-ietf-dnssext-delegation-signer
231
232=cut
233
234
235
236
237
238