#!/usr/bin/perl
#
# $Copyright$
#
# $TAHI: ct/icmp/Pkt_Too_Big.seq,v 1.3 2003/10/20 02:42:55 masaxmasa Exp $

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

# Interface 
$IF = "Link0";
$IF1 = "Link1";

checkNUT(router);

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

vCapture($IF);
vCapture($IF1);

#----------------------------------------------------------------------
# create neighbor cache entries for link0
#----------------------------------------------------------------------
$ret = mkNCE_Link();
if ($ret != 0) {
	vLog("NUT can not be initialized !!");
	goto error;
}
else {
	vLog("*** TN can make TN's link local address NCE in TN ***");
};

$ret = mkNCE_Global();
if ($ret != 0) {
	vLog("NUT can not be initialized !!");
	goto error;
}
else {
	vLog("*** TN can make TN's global address NCE in TN ***");
};

#----------------------------------------------------------------------
# create neighbor cache entries for link1
#----------------------------------------------------------------------
$ret = mkNCE_Link1();
if ($ret != 0) {
	vLog("NUT can not be initialized !!");
	goto error;
}
else {
	vLog("*** TN can make TN's link local address NCE in TN ***");
};

#----------------------------------------------------------------------
# set route
#----------------------------------------------------------------------
$ret = set_routes();
if ($ret != 0) {
	vLog("NUT can not be initialized !!");
	goto error;
};

#----------------------------------------------------------------------
# Configuration Test -- Forwarding --
#----------------------------------------------------------------------
vLog("Check NUT configuration");
if (check_fwd() != 0) {
	vLog("NUT's configuration was incorrect!!");
	goto error;
};

%pktdesc = (
	ns_local		=> 'Receive Neighbor Solicitation (Link0)',
	ns_local_sll		=> 'Receive Neighbor Solicitation (Link0)',
	na_local		=> 'Send Neighbor Advertisement (Link0)',
	ns_global		=> 'Receive Neighbor Solicitation (Link0)',
	ns_global_sll		=> 'Receive Neighbor Solicitation (Link0)',
	na_global		=> 'Send Neighbor Advertisement (Link0)',
	echo_request_1500_link0	=> 'Send Echo Request w/ 1500 bytes (Link0)',
	pkt_too_big_link0	=> 'Receive Packet Too Big Message (MTU = 1300)',
	pkt_too_big_link1	=> 'Receive Packet Too Big Message (MTU = 1300)'
);

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

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

#----------------------------------------------------------------------
# reduce Link MTU of LINK1 Interface from 1500 to 1300
#----------------------------------------------------------------------
if (set_mtu($IF1, 1300)) {
	vLog("set mtu failed.");
	goto error;
};

%ret1 = vSend($IF, echo_request_1500_link0);

again:
%ret = vRecv($IF, 5, $ret1{sentTime1}, 0, pkt_too_big_link0, pkt_too_big_link1,
	     ns_global, ns_global_sll, ns_local, ns_local_sll);

if ($ret{status} != 0) {
	vLog("TN can not receive Packet Too Big Message.");
	goto error;
}
elsif ($ret{recvFrame} eq 'pkt_too_big_link0' ||
       $ret{recvFrame} eq 'pkt_too_big_link1') {
	vLog("TN received Packet Too Big Message.");
}
elsif ($ret{recvFrame} eq 'ns_global' || $ret{recvFrame} eq 'ns_global_sll' ||
       $ret{recvFrame} eq 'ns_local' || $ret{recvFrame} eq 'ns_local_sll') {

	if ($ret{recvFrame} eq 'ns_global' ||
	    $ret{recvFrame} eq 'ns_global_sll') {
		vSend($IF, na_global);
	}
	else {
		vSend($IF, na_local);
	};

	goto again;
}
else {
	vLog("TN received unexpected packet");
	goto error;
};

#----------------------------------------------------------------------
# remove configurations
#----------------------------------------------------------------------
vLog("clear configurations");
set_mtu($IF1, 1500);
delete_routes();

vLog("OK");
exit($V6evalTool::exitPass);

error:
	vLogHTML("FAIL");
	vLogHTML("clear configurations");
	delete_routes();
	set_mtu($IF1, 1500);
	exit($V6evalTool::exitFail);

########################################################################
__END__

=head1 NAME

	Pkt_Too_Big - Verify that the NUT sends Packet Too Big Message

=head1 TARGET

	Router

=head1 SYNOPSIS

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

=head1 NETWORK CONFIGURATION

	This test is OFFLINK Network Configuration test.
	In this test, TN play a Roll of the Router.
	
	Physical Network configuration
	
	Link0	
	--------+---------------+--------------
		|		|
		NUT		TN
		|		|
	--------+---------------+--------------
	Link1


	Logical Network Configuration

			Host A (TN-Link0)
			|					Link0
	--------+-------+-----------------
		| 
		NUT (globaladdress:B)
		|
	--------+-------+-----------------
			|					Link1
			Router(TN-Link1)
			|
	----------------+-------+---------
				|
				HOST B (OFFLINK_LINK1_GLOBAL_ADDRESS)

	In this configuration, Packets are send and received. 

	for example,
		In Logical
			HOST B           -- Echo Reply --> NUT
		Actually, in physical
			TN (as Router)   -- Echo Reply --> NUT

=head1 INITIALIZATION

	TN attempt to execute remote command 'vRemote(route.rmt)'.
	'route add -inet6 OFFLINK_LINK1_GLOBAL_ADDRESS TN-LINK1-address' 

	And status of Neighbor Cache Entry for TN's addresses are reachable.

=head1 TEST PROCEDURE

	This test verifies that the node sends a Packet Too Big Message 
	in response to a packet that it can not forward because the packet 
	is larger than the MTU of the outgoing link.

	TN			NUT

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

	1.
	After NUT is initialized (set static route) , NUT sets 
	the Link MTU of LINK1 Interface to 1300 .

	2.
	TN send Echo Request to Host B.

	 === echo request  ===>

	3.
	NUT send Packet Too Big Message 

	 <=== Packet Too Big Message ===

=head1 JUDGMENT

	
	<< PASS >>
		NUT send a Packet Too Big Message.

	<< FAIL >>	
		NUT do not send a Packet Too Big Message.

=head1 REFERENCE

RFC2463
3.2 Packet Too Big 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             |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                             MTU                               |
      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
      |                    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><br>
                  <b>Copied from the Source Address field of the invoking
                  packet.</b>
</pre>

=end html

   ICMPv6 Fields:

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

=end html

=begin html
<pre>
   <b>Code</b>           <b>Set to 0 (zero) by the sender and ignored by the</b>
                  <b>receiver</b>
</pre>

=end html

   MTU            The Maximum Transmission Unit of the next-hop link.

  Description

=begin html
<pre>
   <b>A Packet Too Big MUST be sent by a router in response to a packet
   that it cannot forward because the packet is larger than the MTU of
   the outgoing link.</b>  The information in this message is used as part
   of the Path MTU Discovery process [PMTU].
</pre>

=end html

   Sending a Packet Too Big Message makes an exception to one of the
   rules of when to send an ICMPv6 error message, in that unlike other
   messages, it is sent in response to a packet received with an IPv6
   multicast destination address, or a link-layer multicast or link-
   layer broadcast address.

=head1 SEE ALSO

	  perldoc V6evalTool
	  perldoc V6evalRemote

=cut
