#$Id: 03.cases.t,v 1.6 2004/11/29 09:17:09 olaf Exp $							-*-perl-*-

use Test::More tests => 17;
use strict;

BEGIN { 
    use_ok('Net::DNS::SEC::NSECepsilon'); 

}

use Net::DNS qw(name2labels); 


my $in;
my $out;
my $apex="example.com";

sub uncruft_name {
    # since we copied and past the examples directly from the draft we
    # need to turn them in a proper name.
    my $out=shift;
    $out=~s/\\\n//g;        # remove newlines
    $out=~s/\s//g;          # remove spaces
    $out=~s/\\377/\\255/g;  #silly mistake in draft
    return $out;
}

# 5.1  Examples of Immediate Predecessors
#   Typical case:
# This example hat one octed to many...
$in='foo.example.com.';
$out='
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377.\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377.\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377.fon\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377.exa\
           mple.com.
';

name2labels(uncruft_name($out));
my $result=is (name_min_epsilon($in,$apex),uncruft_name($out),"Matching 5.1 case 1");
if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_min_epsilon($in,$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_min_epsilon($in,$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}

#
#   Least significant (left-most) label of DNS name consists of a single
#   octet of the minimum sort value:


$in  = '\000.foo.example.com.';
$out = 'foo.example.com.';
is (name_min_epsilon($in,$apex),($out),"Matching 5.1 case 2");

#   Least significant (right-most) octet of least significant (left-most)
#   label has the minimum sort value:


$in  = 'foo\000.example.com.';

$out = '   \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377.\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377.\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377.\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377.foo.exa\
           mple.com.


';
$result=is (name_min_epsilon($in,$apex),uncruft_name($out),"Matching 5.1 case 3");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_min_epsilon($in,$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_min_epsilon($in,$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}



#   DNS name is the owner name of the apex, and consequently wraps to the
#   DNS name with the maximum possible sort order in the zone.

$in='example.com.';

$out='
          \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377.\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377.\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377.\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377.example.com.
';


$result=is (name_min_epsilon($in,$apex),uncruft_name($out),"Matching 5.1 case 4");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_min_epsilon($in,$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_min_epsilon($in,$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}


# 5.2  Examples of Immediate Successors
#
#
#   Typical case:


$in  = 'foo.example.com.';


$out = '\000.foo.example.com.';


$result=is (name_plus_epsilon($in,$apex),uncruft_name($out),"Matching 5.2 case 1");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon($in,$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon($in,$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}


# In the NXDOMAIN case

$in  = 'foo.example.com.';


$out = 'foo\000.example.com.';


$result=is (name_plus_epsilon($in,$apex,1),uncruft_name($out),"Matching 5.2 case 1");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon($in,$apex,1)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon($in,$apex,1))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}



#   DNS name is one octet short of the maximum DNS name length:
#   I had to shorten the number of characters by one!


$in  = '
           fooooooooooooooooooooooooooooooooooooooooooooooo.oooooooooo\
           ooooooooooooooooooooooooooooooooooooooooooooooooooooo.oooooo\
           ooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.oo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           o.example.com.
';


$out = '
           fooooooooooooooooooooooooooooooooooooooooooooooo\000.oooooo\
           ooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.oo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           o.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           ooooo.example.com.
';


$result=is (name_plus_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.3 case 2");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon((uncruft_name($in),$apex))))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon((uncruft_name($in),$apex)))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}

#   DNS name is the maximum DNS name length:
#  Stripped one label to make DNS name 255 octeds.

   $in  = '
           fooooooooooooooooooooooooooooooooooooooooooooooooo.ooooooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooo.ooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.o\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           o.example.com.
';

$out = ' 
           foooooooooooooooooooooooooooooooooooooooooooooooop.ooooooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooo.ooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.o\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           o.example.com.
';




$result=is (name_plus_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.2 case 3");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}



#   DNS name is the maximum DNS name length and the least significant
#   (left-most) label has the maximum sort value:

$in='
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377.ooooooooooooooooooooooooooooooooooooooo\
           oooooooooooooooooooooooo.ooooooooooooooooooooooooooooooooooo\
           oooooooooooooooooooooooooooo.ooooooooooooooooooooooooooooooo\
           ooooooooooooooooooooooooooooooo.example.com.
';
$out='
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           oop.oooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           ooooooo.oooooooooooooooooooooooooooooooooooooooooooooooooooo\
           oooooooooo.example.com.

';



$result=is (name_plus_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.2 case 4");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}





#   DNS name is the maximum DNS name length and the eight least
#   significant (right-most) octets of the least significant (left-most)
#   label have the maximum sort value:


$in =     'fooooooooooooooooooooooooooooooooooooooooo\377\377\377\377\
           \377\377\377\377.ooooooooooooooooooooooooooooooooooooooooooo\
           oooooooooooooooooooo.ooooooooooooooooooooooooooooooooooooooo\
           oooooooooooooooooooooooo.ooooooooooooooooooooooooooooooooooo\
           ooooooooooooooooooooooooooo.example.com.';


$out=     'foooooooooooooooooooooooooooooooooooooooop.ooooooooooooooooo\
           oooooooooooooooooooooooooooooooooooooooooooooo.ooooooooooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooo.ooooooooo\
           ooooooooooooooooooooooooooooooooooooooooooooooooooooo.examp\
           le.com.';






$result=is (name_plus_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.2 case 5");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}





#   DNS name has the maximum possible sort order in the zone, and
#   consequently wraps to the owner name of the apex:



      $in  ='\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377.\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377.\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377.\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377.example.com.
';

$out = 'example.com.';



$result=is (name_plus_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.2 case 6");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}







   $in  = '
           foooooooooooooooooooooooooooooooooooooooooooooooo\@.ooooooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooo.ooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.o\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           o.example.com.
';

$out = ' 
           foooooooooooooooooooooooooooooooooooooooooooooooo[.ooooooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooo.ooooo\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooo.o\
           oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\
           o.example.com.
';



$result=is (name_plus_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.2 case (extra 2)");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}




$in='fo[.example.com.';
$out='
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377.\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377.\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377.fo\@\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377.exa\
           mple.com.
';


$result=is (name_min_epsilon(uncruft_name($in),$apex),uncruft_name($out),"Matching 5.2 case (extra 3)");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_min_epsilon(uncruft_name($in),$apex)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_min_epsilon(uncruft_name($in),$apex))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}







$in='fo[.example.com.';
$out=' fo[\000.example.com.
';

$result=is (name_plus_epsilon(uncruft_name($in),$apex,1),uncruft_name($out),"Next available not creating empty non terminals labellength < 63");

if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex,1)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex,1))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}



   $in  = '
           fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\@.example.com.
';

$out = ' 
           fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo[.example.com.
';



$result=is (name_plus_epsilon(uncruft_name($in),$apex,1),uncruft_name($out),"Next available not creating empty non terminals labellength ==63");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex,1)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex,1))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}




   $in  = '
           \377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377.foo.example.com.

';

$out = ' 
           fop.example.com.
    ';


$result=is (name_plus_epsilon(uncruft_name($in),$apex,1),uncruft_name($out),"Next available not creating empty non terminals labellength==63 and \255");


if (!$result){
    diag "Failure. Follows hexdump and length of in and out";
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex,1)))
	 );
    diag(
	 unpack("H*",Net::DNS::RR->_name2wire( uncruft_name($out)))
	 );
    diag(length(Net::DNS::RR->_name2wire(name_plus_epsilon(uncruft_name($in),$apex,1))));
    diag(length(Net::DNS::RR->_name2wire( uncruft_name($out))));
}


