#!/usr/bin/perl
#
# $Copyright_v6PC$
#
# $Intap$
# $TINY: RA_wHL254.seq,v 1.7 2002/03/05 17:13:56 miyata Exp $
# 

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

#------------------------------------------------------
#----- get sequence arguments
#------------------------------------------------------
$howto_initNUT="none";
$send = "ok";
foreach (@ARGV) {
# How to configure address of NUT?
# sample: boot, ra, manual+_GLOBAL0A0N_UCAST
    /^addrconf=(\S+)/ && do {$SAA::howto_addrconf=$1; next; };

# How to initialize NUT?
# sample: none, DADSuccess_boot, DADFail_boot
    /^init=(\S+)/     && do {$howto_initNUT=$1; next; };

# "none" if send no pakcet to NUT in state DADPostSendNS
# sample: ok, none
    /^send=(\S+)/     && do {$send=$1; next; };

# sequence debug options
# sample: qR
    /^sd=(\S+)/       && do {$seqdebugopt=$1; next; };
    seqERROR("Unknown sequence option '$_'");
}
#------------------------------------------------------

#----- test condition
$IF=Link0;                 # network interface

$max_retry_count = 10;     # retry if NUT state becomes DADPostSendNS
$max_retry_count = 2 if $SAA::sd =~ /q/;    # quick retry
$send_interval  = 1;
	       # 1[sec] time between DAD NS and DAD NS, send to NUT
               #     (RandomDelay is 0-1sec  e.g. default RetransTimer 1000msec)


$DAD_GA = $SAA::DADTransmitsGA ;
$DAD_GA =~ tr/a-z/A-Z/ ;

##########################################################
#----- Check Target Type

$type=$V6evalTool::NutDef{Type};
if($type eq router) {
    vLogHTML("This test is for the host only<BR>");
    exit $V6evalTool::exitHostOnly;
}

if($type ne host) {
    vLogHTML(ndErrmsg("ERROR: $V6evalTool::NutDef{Type}: ".
		      "Unknown target type<BR>"));
    exit $V6evalTool::exitFail;
}


##########################################################
#----- initialize NUT
vLog("*** Target initialization phase ***");
if($V6evalTool::NutDef{System} ne "manual"){ vSleep($SAA::test_interval); }
$rret=vRemote("reboot_async.rmt","","timeout=$SAA::wait_rebootcmd");
vLog("reboot_async.rmt returned status $rret");

#----- start Capturing
vLog("*** Target testing phase ***");
vCapture($IF);

#----- LLA PHASE
#----- Wait DAD NS from NUT or timeout
vLog("TN wait DAD NS(DADNS_from_NUT) from NUT for $SAA::wait_dadns{$SAA::howto_addrconf} [sec],");

%ret1=vRecv($IF,$SAA::wait_dadns{$SAA::howto_addrconf},0,0,DADNS_from_NUT);

if ($ret1{status} != 0){
    vLog("TN wait DAD NS from NUT for $SAA::wait_dadns{$SAA::howto_addrconf}, but NUT had not transmit DAD NS");
    seqNG();
}

#----- RA PHASE
vLog("TN received DAD NS from NUT.");
vLog("OK! Let's go ahead!");
%ret2=vRecv($IF,$SAA::wait_rs,0,0,RS_from_NUT,RS_from_NUT_wSLL);

if ($ret2{status} != 0){
    vLog("Though TN had waited RS from NUT for $SAA::wait_rs,");
    vLog(" NUT seems not to send RS.");
    vLog(" Anyway TN is sending Unsolicited RA (Prefix=Global)");
}else{
    vLog("TN received RS from NUT.");
    vLog("TN is sending RA (Prefix=Global)");
}

vSend($IF, RA_GA0_HL254);

#----- Wait DAD NS from NUT or timeout
vLog("TN wait DAD NS for Global address from NUT for $SAA::wait_dadns{ra} [sec],");

%ret3=vRecv($IF,$SAA::wait_dadns{ra},0,0,DADNS_from_NUT_GA0Tgt);

if ($ret3{status} == 0){
    vLog("NUT had transmitted DAD NS for its Global address");
    vLog("by receiving RA (Hoplimit==254).");
#----- check if NUT's address is configured
    vSleep($SAA::wait_addrconf_with_RA);

    if (seqCheckNUTAddrConfiguredGA($IF,
	SOLNS_from_TN_GA0Tgt, 
	NA_from_NUT_GA0Tgt, 
	NA_from_NUT_GA0Tgt_woTLL, 
	NA_from_GA0NUT_GA0Tgt, 
	NA_from_GA0NUT_GA0Tgt_woTLL) eq TRUE) {
       	vLog("NUT assigned Global address to the interface.");
        if ($DAD_GA eq "NO") {
            vLog("NUT transmit DAD NS though DADTransmitsGA == NO");
    	}
        seqNG();
    }else{
        vLog(" NUT had not assign Global address.");
       	seqNG();
    }
} elsif ($ret3{status} != 0){
    vLog("NUT had not transmitted DAD NS for Global address");
    vLog("by receiving RA with PrefixOption (Hoplimit==254).");
#----- check if NUT's address is configured
    if (seqCheckNUTAddrConfiguredGA($IF,
	SOLNS_from_TN_GA0Tgt, 
	NA_from_NUT_GA0Tgt, 
	NA_from_NUT_GA0Tgt_woTLL, 
	NA_from_GA0NUT_GA0Tgt, 
	NA_from_GA0NUT_GA0Tgt_woTLL) eq TRUE) {
       	vLog("NUT assigned Global address to the interface.");
        if ($DAD_GA eq "YES") {
            vLog("NUT did not transmit DAD NS though DADTransmitsGA == YES");
    	}
        seqNG();
    }else{
        vLog("NUT did not assign Global address.");
       	seqOK();
    }
}

##########################################################


#end
########################################################################
__END__

=head1 NAME

RA_wHL254 - check the process when NUT receives invalid RA(Hoplimit=254) which contains one global prefix. (NOT Assigning Global address)

=head1 TARGET

All Node

=head1 SYNOPSIS

RA_wHL254.seq [-tooloption ...] -pkt <packetdef> [addrconf=<addrconfname>] 

  -tooloption   : v6eval tool option
  <packetdef>   : packet definition file (v6eval tool option)
  <addrconfname>: how to configure address on NUT; boot/reboot

=begin html
<PRE>
 detail of v6eval tool option: see perldoc V6evalTool.pm, perldoc V6evalRemote.pm
</PRE>

=end html


=head1 INITIALIZATION

=begin html
<PRE>
 Reboot NUT or Initialize interface of NUT or Initialize IPv6 stack of NUT.
</PRE>

=end html

=head1 TEST PROCEDURE

=over 1

=item Test for Unicast address autoconfiguration

The following tests are prepared in this test package. See INDEX file.

B<Test for all node>

   When NUT receives invalid RA which contains Global Prefix but Hoplimit 
   of the RA is 254, NUT MUST NOT assign autoconfigured address. 

B<Test sequence>

  TN                            NUT
  ---------------------------------
  Initialize NUT

  Configure address of NUT (reboot or interface initialization etc...)

  TN wait the DAD NS sent from NUT
  <=== Judgement #1: DAD NS =======
        name: DADNS_from_NUT

  <=== Judgement #2: RS ===========
        name: RS_from_NUT, RS_from_NUT_wSLL

  ==== Action #1: RA =============>
        name: RA_GA0_HL254

  X<== Judgement #3: DAD NS =======
        name: DADNS_from_NUT_GA0Tgt

  Wait for 5+DupAddrDetectTransmits*(RetransTimer/1000)[sec]

  Check if NUT's address is configured
  ==== Action #2: SOL NS =========>
        name: SOLNS_from_TN_GA0Tgt

  X<== Judgement #4: SOL NA =======
        name: 
	      NA_from_NUT_GA0Tgt, 
	      NA_from_NUT_GA0Tgt_woTLL, 
	      NA_from_GA0NUT_GA0Tgt, 
	      NA_from_GA0NUT_GA0Tgt_woTLL


=back 1

=head1 JUDGEMENT

=over 1

=item Test for Unicast address autoconfiguration

B<Test for all NODE>

B<NUT performs Stateless Address Autoconfiguration(Global) on its interface>

   Judgement #1. NUT MUST transmit DAD NS for its autoconfigured Link-local address.
        name: DADNS_from_NUT
	src: ::0
	dst: solnode[NUT's tentative Link-local]
        TargetAddress: NUT's tentative Link-local

   Judgement #2. NUT SHOULD transmit RS.
        name: RS_from_NUT
	src: NUT's Link-local
	dst: allrouter

   Action #1. TN transmits RA which contains Global Prefix.
        name: RA_GA0_AF0
	src: TN's Link-local
	dst: allnode
	Hoplimit:254
	PXOPT: Global0

   Judgement #3. NUT MUST NOT transmit DAD NS for its autoconfigured Global address.
		 (* If the address is consisits of EUI64, as same as Link-local
		 address, This DAD MAY be omitted.)
        name: DADNS_from_NUT_GA0Tgt
        src: ::0
	dst: solnode[NUT's tentative Global0]
        TargetAddress: NUT's tentative Global0

   Action #2. TN transmits SOL NS to check if NUT's address is configured.
        name: SOLNS_from_TN_GA0Tgt
        src: TN's Link-local
	dst: solnode[NUT's Global0]
        TargetAddress: NUT's Global0

   Judgement #4. NUT MUST NOT transmit DAD NA for its autoconfigured  Global address.
        name: 
	      NA_from_NUT_GA0Tgt, 
	      NA_from_NUT_GA0Tgt_woTLL, 
	      NA_from_GA0NUT_GA0Tgt, 
	      NA_from_GA0NUT_GA0Tgt_woTLL
	src: NUT's any Unicast Address
	dst: TN's Link-local
        TargetAddress: NUT's Global0
        RFlag: 0
        SFlag: 1
        OFlag: 1
	TLLOPT: NUT's MAC address
	(* TLLOPT may be omitted)


=back 1

=head1 REFERENCE

=begin html
<PRE>
RFC2462
<HR>
   (omit)
<BR>
5.5.3.  Router Advertisement Processing
<BR>
<A NAME="REF"><B>
   On receipt of a valid Router Advertisement (as defined in
   [DISCOVERY])</B>, a host copies the value of the advertisement's M bit
   into ManagedFlag. If the value of ManagedFlag changes from FALSE to
   TRUE, and the host is not already running the stateful address
   autoconfiguration protocol, the host should invoke the stateful
   address autoconfiguration protocol, requesting both address
   information and other information.  If the value of the ManagedFlag
   changes from TRUE to FALSE, the host should continue running the
   stateful address autoconfiguration, i.e., the change in the value of
   the ManagedFlag has no effect.  If the value of the flag stays
   unchanged, no special action takes place. In particular, a host MUST
   NOT reinvoke stateful address configuration if it is already
   participating in the stateful protocol as a result of an earlier
   advertisement.
<BR>
   (omit)
</PRE>
<BR>
<HR>
<PRE>
RFC2461
<HR>
   (omit)
<BR>
6.1.2.  Validation of Router Advertisement Messages
<BR>
   A node MUST silently discard any received Router Advertisement
   messages that do not satisfy all of the following validity checks:
<BR>
      - IP Source Address is a link-local address.  Routers must use
        their link-local address as the source for Router Advertisement
        and Redirect messages so that hosts can uniquely identify
        routers.
<BR>
<A NAME="REF"><B>
      - The IP Hop Limit field has a value of 255</B>, i.e., the packet
        could not possibly have been forwarded by a router.
<BR>
      - If the message includes an IP Authentication Header, the message
        authenticates correctly.
<BR>
      - ICMP Checksum is valid.
<BR>
      - ICMP Code is 0.
<BR>
      - ICMP length (derived from the IP length) is 16 or more octets.
<BR>
      - All included options have a length that is greater than zero.
<BR>
   (omit)
</PRE>

=end html

=head1 SEE ALSO

=begin html
<PRE>
 detail of v6eval tool option: see perldoc V6evalTool.pm, perldoc V6evalRemote.pm
</PRE>

=end html

=cut

