1#!/usr/bin/perl
2# $Id: 05-IPSECKEY.t 1815 2020-10-14 21:55:18Z willem $	-*-perl-*-
3#
4
5use strict;
6use warnings;
7use Test::More;
8
9use Net::DNS;
10
11my @prerequisite = qw(
12		MIME::Base64
13		);
14
15foreach my $package (@prerequisite) {
16	next if eval "require $package";## no critic
17	plan skip_all => "$package not installed";
18	exit;
19}
20
21plan tests => 39;
22
23
24my $name = '38.2.0.192.in-addr.arpa';
25my $type = 'IPSECKEY';
26my $code = 45;
27my @attr = qw( precedence gatetype algorithm gateway key );
28my @data = qw( 10 3 2 gateway.example.com AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== );
29my @also = qw( pubkey keybin );
30
31my $wire =
32'0a03020767617465776179076578616d706c6503636f6d00010351537986ed35533b6064478eeeb27b5bd74dae149b6e81ba3a0521af82ab7801';
33
34
35{
36	my $typecode = unpack 'xn', Net::DNS::RR->new(". $type")->encode;
37	is( $typecode, $code, "$type RR type code = $code" );
38
39	my $hash = {};
40	@{$hash}{@attr} = @data;
41
42	my $rr = Net::DNS::RR->new(
43		name => $name,
44		type => $type,
45		%$hash
46		);
47
48	my $string = $rr->string;
49	my $rr2	   = Net::DNS::RR->new($string);
50	is( $rr2->string, $string, 'new/string transparent' );
51
52	is( $rr2->encode, $rr->encode, 'new($string) and new(%hash) equivalent' );
53
54	foreach (@attr) {
55		is( $rr->$_, $hash->{$_}, "expected result from rr->$_()" );
56	}
57
58	foreach (@also) {
59		is( $rr2->$_, $rr->$_, "additional attribute rr->$_()" );
60	}
61
62
63	my $null    = Net::DNS::RR->new("$name NULL")->encode;
64	my $empty   = Net::DNS::RR->new("$name $type")->encode;
65	my $rxbin   = Net::DNS::RR->decode( \$empty )->encode;
66	my $txtext  = Net::DNS::RR->new("$name $type")->string;
67	my $rxtext  = Net::DNS::RR->new($txtext)->encode;
68	my $encoded = $rr->encode;
69	my $decoded = Net::DNS::RR->decode( \$encoded );
70	my $hex1    = unpack 'H*', $encoded;
71	my $hex2    = unpack 'H*', $decoded->encode;
72	my $hex3    = unpack 'H*', substr( $encoded, length $null );
73	is( $hex2,	     $hex1,	    'encode/decode transparent' );
74	is( $hex3,	     $wire,	    'encoded RDATA matches example' );
75	is( length($empty),  length($null), 'encoded RDATA can be empty' );
76	is( length($rxbin),  length($null), 'decoded RDATA can be empty' );
77	is( length($rxtext), length($null), 'string RDATA can be empty' );
78}
79
80
81{
82	my $lc		= Net::DNS::RR->new( lc ". $type @data" );
83	my $rr		= Net::DNS::RR->new( uc ". $type @data" );
84	my $hash	= {};
85	my $predecessor = $rr->encode( 0,		    $hash );
86	my $compressed	= $rr->encode( length $predecessor, $hash );
87	ok( length $compressed == length $predecessor, 'encoded RDATA not compressible' );
88	isnt( $rr->encode,    $lc->encode, 'encoded RDATA names not downcased' );
89	isnt( $rr->canonical, $lc->encode, 'canonical RDATA names not downcased' );
90}
91
92
93{
94	my $rr = Net::DNS::RR->new("$name $type @data");
95	foreach ( undef, qw(192.0.2.38 2001:db8:0:8002:0:0:2000:1 gateway.example.com) ) {
96		my $gateway = $_ || '.';
97		$rr->gateway($gateway);
98		is( scalar( $rr->gateway ), $_, "rr->gateway( '$gateway' )" );
99		my $rr2 = Net::DNS::RR->new( $rr->string );
100		is( $rr2->rdstring, $rr->rdstring, 'new/string transparent' );
101		my $encoded = $rr->encode;
102		my $decoded = Net::DNS::RR->decode( \$encoded );
103		is( $decoded->rdstring, $rr->rdstring, 'encode/decode transparent' );
104	}
105}
106
107
108{
109	my $rr = eval { Net::DNS::RR->new( type => $type, gateway => 'X' ); };
110	my ($exception) = split /\n/, "$@\n";
111	ok( $exception, "unrecognised gateway type\t[$exception]" );
112}
113
114
115{
116	my $rr = eval { Net::DNS::RR->new(". $type \\# 3 01ff05"); };
117	my ($exception) = split /\n/, "$@\n";
118	ok( $exception, "exception raised in decode\t[$exception]" );
119}
120
121
122{
123	my $rr = Net::DNS::RR->new(". $type @data");
124	$rr->{gatetype} = 255;
125	eval { $rr->encode };
126	my ($exception) = split /\n/, "$@\n";
127	ok( $exception, "exception raised in encode\t[$exception]" );
128}
129
130
131{
132	my $rr = Net::DNS::RR->new(". $type @data");
133	$rr->{gatetype} = 255;
134	eval { my $gateway = $rr->gateway; };
135	my ($exception) = split /\n/, "$@\n";
136	ok( $exception, "exception raised in gateway\t[$exception]" );
137}
138
139
140{
141	my $rr = Net::DNS::RR->new(". $type");
142	foreach (@attr) {
143		ok( !$rr->$_(), "$_ attribute of empty RR undefined" );
144	}
145}
146
147
148{
149	my $rr = Net::DNS::RR->new("$name $type @data");
150	$rr->print;
151}
152
153exit;
154
155
156