#!/usr/bin/perl
#
# $Copyright$
#
# $TAHI: ct/spec/RH_SegmentsLeftBig.seq,v 1.18 2003/06/09 06:29:28 ozoe Exp $
#
######################################################################
BEGIN {
	$V6evalTool::TestVersion = '$Name:  $';
}

use V6evalTool;

if ($V6evalTool::NutDef{Type} ne 'router') {
    vLogHTML("This test is for the router only<BR>");
    exit $V6evalTool::exitRouterOnly;
}

%pktdesc = (
	packet_to_link0		=> 'Send Packet to Link0 (Segments Left is bigger than Address Table Size)',

	na_to_link0		=> 'Send Neighbor Advertisement to Link0 (Global Address)',
	na_to_link0_ll		=> 'Send Neighbor Advertisement to Link0 (Link Local Address)',

	ns_from_link0		=> 'Recv Neighbor Solicitation from Link0 (Global Address)',
	ns_from_link0_ll	=> 'Recv Neighbor Solicitation from Link0 (Link Local Address)',

	icmp_type4_code0	=> 'Recv ICMP Error (Parameter Problem, erroneous header field encountered)',
);

$IF0 = Link0;

vCapture($IF0);

#======================================================================

vSend($IF0, packet_to_link0);

%ret = vRecv($IF0, 5, 0, 0, ns_from_link0, ns_from_link0_ll, icmp_type4_code0);
if ($ret{status} != 0) {
	vLogHTML('<FONT COLOR="#FF0000">NG</FONT>');
	exit $V6evalTool::exitFail;
}

if ($ret{recvFrame} eq 'ns_from_link0') {
	vSend($IF0, na_to_link0);
	%ret = vRecv($IF0, 5, 0, 0, icmp_type4_code0);
	if ($ret{status} != 0) {
		vLogHTML('<FONT COLOR="#FF0000">NG</FONT>');
		exit $V6evalTool::exitFail;
	}
}
if ($ret{recvFrame} eq 'ns_from_link0_ll') {
	vSend($IF0, na_to_link0_ll);
	%ret = vRecv($IF0, 5, 0, 0, icmp_type4_code0);
	if ($ret{status} != 0) {
		vLogHTML('<FONT COLOR="#FF0000">NG</FONT>');
		exit $V6evalTool::exitFail;
	}
}

if ($ret{recvFrame} ne 'icmp_type4_code0') {
	vLogHTML('<FONT COLOR="#FF0000">NG</FONT>');
	exit $V6evalTool::exitFail;
}

vLogHTML('OK');
exit $V6evalTool::exitPass;

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

=head1 NAME

  RH_SegmentsLeftBig - check Segments Left is bigger than Address Table Size

=head1 TARGET

  Router

=head1 SYNOPSIS

=begin html
<PRE>
  <A HREF="./RH_SegmentsLeftBig.seq">RH_SegmentsLeftBig.seq</A> [-tooloption ...] -pkt <A HREF="./RH_SegmentsLeftBig.def">RH_SegmentsLeftBig.def</A>
    -tooloption : v6eval tool option
  See also <A HREF="./RH.def">RH.def</A>
</PRE>

=end html

=head1 INITIALIZATION

  None

=head1 TEST PROCEDURE

  Tester                      Target                      Tester
              (Link0)                     (Link1)
    |                           |                           |
    |-------------------------->|                           |
    |   Packet to Link0         |                           |
    |                           |     (no forwarding)       |
    |                           |                           |
    |<--------------------------|                           |
    |   Neighbor Solicitation   |                           |
    |                           |                           |
    |-------------------------->|                           |
    |   Neighbor Advertisement  |                           |
    |                           |                           |
    |<--------------------------|                           |
    |   ICMP Error from Link0   |                           |
    |                           |                           |
    v                           v                           v

  1. Send Packet to Link0
  2. Wait ICMP Error from Link0 or NS from Link0
  3. If NS received then send NA to Link0, and wait ICMP Error form Link0 again
  4. Receive ICMP Error from Link0

  Network topology

          (Link0)        (Link1)
    Tester       Target         Tester
    Host1 ------ Router1 ------ Router2 ------ Router3 ------ Host2
         Global 0       Global 1       Global 3       Global 5

  Packet to Link0 is:

        IPv6 Header
            Version            = 6
            Traffic Class      = 0
            FlowLabel          = 0
            PayloadLength      = 56
            NextHeader         = 43 (Routing Header)
            SourceAddress      = Global 0 Address (Host1)
            DestinationAddress = Global 0 Address (Router1)

        Routing Header
            NextHeader      = 59 (No Next Header)
            HeaderExtLength = 6 
            RoutingType     = 0 
            SegmentsLeft    = 3 
            Address[1]      = Global 1 Address (Router2)
            Address[2]      = Global 3 Address (Router3)
            Address[3]      = Global 5 Address (Host2)

=head1 JUDGMENT

  PASS: ICMP Error Received from Link0

        IPv6 Header
            Version             = 6
            Traffic Class       = 0
            FlowLabel           = 0
            PayloadLength       = 104
            NextHeader          = 58 (ICMP)
            SourceAddress      = Global 0 Address (Router1)
            DestinationAddress = Global 0 Address (Host1)

        ICMP Error
            Type           = 4 (Parameter Problem)
            Code           = 0 (erroneous header field encountered)
            Checksum       = (auto)
            Pointer        = 43 (Offset to Segments Left)
            PayloadData    = (Sent Packet)

=head1 REFERENCE

RFC2460

4.4  Routing Header

=begin html
<PRE>
   <B>The Routing header is used by an IPv6 source to list one or more
   intermediate nodes to be "visited" on the way to a packet's
   destination.  This function is very similar to IPv4's Loose Source
   and Record Route option.  The Routing header is identified by a Next
   Header value of 43 in the immediately preceding header, and has the
   following format:</B>
</PRE>

=end html

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  Next Header  |  Hdr Ext Len  |  Routing Type | Segments Left |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    .                                                               .
    .                       type-specific data                      .
    .                                                               .
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   Next Header          8-bit selector.  Identifies the type of header
                        immediately following the Routing header.  Uses
                        the same values as the IPv4 Protocol field
                        [RFC-1700 et seq.].

   Hdr Ext Len          8-bit unsigned integer.  Length of the Routing
                        header in 8-octet units, not including the first
                        8 octets.

   Routing Type         8-bit identifier of a particular Routing header
                        variant.

   Segments Left        8-bit unsigned integer.  Number of route
                        segments remaining, i.e., number of explicitly
                        listed intermediate nodes still to be visited
                        before reaching the final destination.

   type-specific data   Variable-length field, of format determined by
                        the Routing Type, and of length such that the
                        complete Routing header is an integer multiple
                        of 8 octets long.

   If, while processing a received packet, a node encounters a Routing
   header with an unrecognized Routing Type value, the required behavior
   of the node depends on the value of the Segments Left field, as
   follows:

      If Segments Left is zero, the node must ignore the Routing header
      and proceed to process the next header in the packet, whose type
      is identified by the Next Header field in the Routing header.

      If Segments Left is non-zero, the node must discard the packet and
      send an ICMP Parameter Problem, Code 0, message to the packet's
      Source Address, pointing to the unrecognized Routing Type.

   If, after processing a Routing header of a received packet, an
   intermediate node determines that the packet is to be forwarded onto
   a link whose link MTU is less than the size of the packet, the node
   must discard the packet and send an ICMP Packet Too Big message to
   the packet's Source Address.

=begin html
<PRE>
   <B>The Type 0 Routing header has the following format:</B>
</PRE>

=end html

    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |  Next Header  |  Hdr Ext Len  | Routing Type=0| Segments Left |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                            Reserved                           |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +                                                               +
    |                                                               |
    +                           Address[1]                          +
    |                                                               |
    +                                                               +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +                                                               +
    |                                                               |
    +                           Address[2]                          +
    |                                                               |
    +                                                               +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    .                               .                               .
    .                               .                               .
    .                               .                               .
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    |                                                               |
    +                                                               +
    |                                                               |
    +                           Address[n]                          +
    |                                                               |
    +                                                               +
    |                                                               |
    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   Next Header          8-bit selector.  Identifies the type of header
                        immediately following the Routing header.  Uses
                        the same values as the IPv4 Protocol field
                        [RFC-1700 et seq.].

   Hdr Ext Len          8-bit unsigned integer.  Length of the Routing
                        header in 8-octet units, not including the first
                        8 octets.  For the Type 0 Routing header, Hdr
                        Ext Len is equal to two times the number of
                        addresses in the header.

   Routing Type         0.

   Segments Left        8-bit unsigned integer.  Number of route
                        segments remaining, i.e., number of explicitly
                        listed intermediate nodes still to be visited
                        before reaching the final destination.

   Reserved             32-bit reserved field.  Initialized to zero for
                        transmission; ignored on reception.

   Address[1..n]        Vector of 128-bit addresses, numbered 1 to n.</B>

   Multicast addresses must not appear in a Routing header of Type 0, or
   in the IPv6 Destination Address field of a packet carrying a Routing
   header of Type 0.

=begin html
<PRE>
   <B>A Routing header is not examined or processed until it reaches the
   node identified in the Destination Address field of the IPv6 header.
   In that node, dispatching on the Next Header field of the immediately
   preceding header causes the Routing header module to be invoked,
   which, in the case of Routing Type 0, performs the following
   algorithm:</B>
</PRE>

=end html

   if Segments Left = 0 {
      proceed to process the next header in the packet, whose type is
      identified by the Next Header field in the Routing header
   }
   else if Hdr Ext Len is odd {
         send an ICMP Parameter Problem, Code 0, message to the Source
         Address, pointing to the Hdr Ext Len field, and discard the
         packet
   }
   else {
      compute n, the number of addresses in the Routing header, by
      dividing Hdr Ext Len by 2

=begin html
<PRE>
      <B>if Segments Left is greater than n {
         send an ICMP Parameter Problem, Code 0, message to the Source
         Address, pointing to the Segments Left field, and discard the
         packet
      }</B>
</PRE>

=end html

      else {
         decrement Segments Left by 1;
         compute i, the index of the next address to be visited in
         the address vector, by subtracting Segments Left from n

         if Address [i] or the IPv6 Destination Address is multicast {
            discard the packet
         }
         else {
            swap the IPv6 Destination Address and Address[i]

            if the IPv6 Hop Limit is less than or equal to 1 {
               send an ICMP Time Exceeded -- Hop Limit Exceeded in
               Transit message to the Source Address and discard the
               packet
            }
            else {
               decrement the Hop Limit by 1

               resubmit the packet to the IPv6 module for transmission
               to the new destination
            }
         }
      }
   }


=head1 SEE ALSO

  perldoc V6evalTool

=cut

