#!/usr/bin/perl
#
# $Copyright$
#
# $TAHI: ct/icmp/Time_Exc_Global.seq,v 1.4 2003/10/15 08:06:31 masaxmasa Exp $
#----------------------------------------------------------------------

BEGIN { $V6evalTool::TestVersion = '$Name:  $'; }
use V6evalTool;
use icmp;

$IF = Link0;

#----------------------------------------------------------------------
# Initialization
#----------------------------------------------------------------------

vLogHTML("<FONT SIZE=\"+1\">Initialization</FONT><BR>");

vCapture($IF);

if ($V6evalTool::NutDef{Type} eq 'host') {
	sendRA();
};

$ret = mkNCE_Global();

if ($ret != 0) {
	vLog("*** NUT can not be initialized !! ***");
	goto error;
}
else {
	vLog("TN created the entry of TN's global address to Neighbor cache of  NUT.");
}

#----------------------------------------------------------------------
# Check fragment reassembly.
#----------------------------------------------------------------------
%pktdesc = (
    echo_request_1st_global	=> 'Send 1st Fragmented Echo Request (Global address)',
    echo_request_2nd_global	=> 'Send 2nd Fragmented Echo Request (Global address)',
    echo_reply_global_1024	=> 'Receive Echo Reply (Global address)',
    echo_request_1st		=> 'Send 1st Fragmented Echo Request (Global address)',
    time_exceeded		=> 'Receive Time Exceeded (fragment reassembly)',
    ns_global			=> 'Receive Neighbor Solicitation',
    ns_global_sll		=> 'Receive Neighbor Solicitation',
    na_global			=> 'Send Neighbor Advertisement'
);

vLogHTML('<B>Begin check fragment reassembly</B>');

vSend($IF, echo_request_1st_global);
vSend($IF, echo_request_2nd_global);

#%ret = vRecv($IF, 5, 0, 0, echo_reply_global_1024);
%ret = icmp_vRecv($IF, 5, 0, 0, echo_reply_global_1024);
if ($ret{status} == 0 && $ret{recvFrame} eq 'echo_reply_global_1024') {
	vLogHTML('OK<BR>');
}
else {
	vLogHTML('Not replied.');
	goto error;
};
vLogHTML('<B>End check</B><P>');

#----------------------------------------------------------------------
# Test
#----------------------------------------------------------------------

vLogHTML("<FONT SIZE=\"+1\">Test</FONT><BR>");

vSend($IF, echo_request_1st);

#%ret = vRecv($IF, 65, 0, 0, time_exceeded, ns_global, ns_global_sll);
%ret = icmp_vRecv($IF, 65, 0, 0, time_exceeded);

if ($ret{status} != 0) {
	vLog("TN can not receive ICMPv6 error message from NUT");
	goto error;
}
elsif ($ret{recvFrame} eq 'time_exceeded') {
	vLog("TN can receive ICMPv6 Time Exceeded message from NUT");
	vLog("OK");
	exit($V6evalTool::exitPass);
}
elsif ($ret{recvFrame} eq 'ns_global' || $ret{recvFrame} eq 'ns_global_sll') {
	vSend($IF, na_global);

	%ret = vRecv($IF, 65, 0, 0, time_exceeded);
	if ($ret{recvFrame} eq 'time_exceeded') {
		vLog("TN can receive ICMPv6 Time Exceeded message from NUT");
		vLog("OK");
		exit($V6evalTool::exitPass);
	}
	else {
		vLog("TN can not receive ICMPv6 error message from NUT");
		goto error;
	}
}
else {
	vLog("TN receive unexpected packets from NUT");
	goto error;
}   

error:

vLog("FAIL");
exit($V6evalTool::exitFail);

#----------------------------------------------------------------------

__END__

=head1 NAME

	Time_Exc_Global.seq - check Time Exceeded 1 (global address)

=head1 TARGET

	Host/Router

=head1 SYNOPSIS

	Time_Exc_Global.seq [-tooloption ...] -p Time_Exc_Global.def

=head1 INITIALIZATION

	Before starting test, check NUT's fragment reassembly function.
	When test starts, states of Neighbor Cache Entry for TN's 
	addresses are reachable.

=head1 TEST PROCEDURE

	This test verifies that NUT sends valid ICMPv6 Time Exceeded (code 1)
	in response to a packet which can not be reassemble.
	And this test verifies that the message processing rule ,
	
	If the message is a response to a message sent to one of the
	node's unicast addresses, the Source Address of the reply must
	be that same address.


	TN			NUT

	---------------------------

	1.
	 === fragmented (1st) packet  ===>
		src address : TN global address
		dst address : NUT global address             
	
	2.
	<< JUDGMENT >>

	 <=== ICMPv6  Time Exceeded ===
		src address : NUT global address
		dst address : TN global address             
             Code is 1

=head1 JUDGMENT

	<< PASS >>
		NUT send ICMPv6 Time Exceeded.
		

	<< FAIL >>	
		NUT do not send ICMPv6 Time Exceeded.

=head1 REFERENCE

RFC2463
3.3 Time Exceeded Message

       0                   1                   2                   3
       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |     Type      |     Code      |          Checksum             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                             Unused                            |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                    As much of invoking packet                 |
      +               as will fit without the ICMPv6 packet           +
      |               exceeding the minimum IPv6 MTU [IPv6]           |

   IPv6 Fields:

=begin html
<pre>
   <b>Destination Address</b>
                  <b>Copied from the Source Address field of the invoking
                  packet.</b>
</pre>

=end html

   ICMPv6 Fields:

=begin html
<pre>
   <b>Type           3</b>
</pre>

=end html

=begin html
<pre>
   <b>Code</b>           0 - hop limit exceeded in transit<br>
                  <b>1 - fragment reassembly time exceeded</b>
</pre>

=end html

   Unused         This field is unused for all code values.
                  It must be initialized to zero by the sender
                  and ignored by the receiver.

   Description

   If a router receives a packet with a Hop Limit of zero, or a router
   decrements a packet's Hop Limit to zero, it MUST discard the packet
   and send an ICMPv6 Time Exceeded message with Code 0 to the source of
   the packet.  This indicates either a routing loop or too small an
   initial Hop Limit value.

   The rules for selecting the Source Address of this message are
   defined in section 2.2.


=head1 SEE ALSO

	  perldoc V6evalTool

=cut
