#!/usr/bin/perl
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation.
# All rights reserved.
# 
# Redistribution and use of this software in source and binary
# forms, with or without modification, are permitted provided that
# the following conditions and disclaimer are agreed and accepted
# by the user:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with
#    the distribution.
# 
# 3. Neither the names of the copyrighters, the name of the project
#    which is related to this software (hereinafter referred to as
#    "project") nor the names of the contributors may be used to
#    endorse or promote products derived from this software without
#    specific prior written permission.
# 
# 4. No merchantable use may be permitted without prior written
#    notification to the copyrighters.
# 
# 5. The copyrighters, the project and the contributors may prohibit
#    the use of this software at any time.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
# BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.  IN NO EVENT SHALL THE
# COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation.
# All rights reserved.
# 
# Redistribution and use of this software in source and binary
# forms, with or without modification, are permitted provided that
# the following conditions and disclaimer are agreed and accepted
# by the user:
# 
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in
#    the documentation and/or other materials provided with
#    the distribution.
# 
# 3. Neither the names of the copyrighters, the name of the project
#    which is related to this software (hereinafter referred to as
#    "project") nor the names of the contributors may be used to
#    endorse or promote products derived from this software without
#    specific prior written permission.
# 
# 4. No merchantable use may be permitted without prior written
#    notification to the copyrighters.
# 
# 5. The copyrighters, the project and the contributors may prohibit
#    the use of this software at any time.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHTERS, THE PROJECT AND
# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING
# BUT NOT LIMITED THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE, ARE DISCLAIMED.  IN NO EVENT SHALL THE
# COPYRIGHTERS, THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# $TAHI: ct/icmp/Pkt_Too_Big.seq,v 1.5 2004/08/19 09:04:33 akisada Exp $

########################################################################
BEGIN { $V6evalTool::TestVersion = '$Name: V6PC_P1_1_3_3 $'; }
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 JUDGEMENT

	
	<< 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
