#!/usr/bin/perl
#
# $Copyright_v6PC$
#
# $Intap$
# $TINY: RA_GA_Success.seq,v 1.14 2002/03/05 17:13:55 miyata Exp $
# 

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

#------------------------------------------------------
#----- get sequence arguments
#------------------------------------------------------
$howto_initNUT="none";
$send = "ok";

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


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)
$recvVLT=30;

##########################################################
#----- 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)");
}

#--------------------------
# Send RA
#--------------------------

vSend($IF, RA_GA0);
#--- VLT=30/PLT=15

$t0 = time();

#----- 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){
#----- check if NUT's address is configured
    vLog("NUT had transmitted DAD NS for its Global address.");

    $t0 = time();  #-- Here is the better posiotion for t0
    vLog("DAD complete time= $t0");
    vSleep($SAA::wait_addrconf_with_RA);

    if (seqCheckNUTAddrConfiguredGADAD($IF,
	DADNS_from_TN_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt_woTLL, 
	DADNA_from_GA0NUT_GA0Tgt, 
	DADNA_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 == 0");
            seqNG();
    	}else{
       	    vLog("OK! Let's go ahead.");
    	}
    }else{
        vLog(" NUT had not assign Global address.");
       	seqNG();
    }
} elsif ($ret3{status} != 0){
    vLog("NUT had not transmitted DAD NS for Global address.");
    if (seqCheckNUTAddrConfiguredGADAD($IF,
	DADNS_from_TN_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt_woTLL, 
	DADNA_from_GA0NUT_GA0Tgt, 
	DADNA_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 != 0");
            seqNG();
    	}else{
       	    vLog("But it is OK if Global address consists of MAC address as LLA.");
       	    vLog("OK! Let's go ahead.");
    	}
    }else{
        vLog("NUT did not assign Global address.");
       	seqNG();
    }
}


#--------------------------
# Sleep until 3 sec before expiration of VLT in the RA since receiving it.
#--------------------------

$t1 = time();
vSleep($t0+$recvVLT-$t1-3);

vLog("It is 3 sec before the expiration of VLT in the RA.");
vLog("Confirming whether assinged address is available.");
if (seqCheckNUTAddrConfiguredGADAD($IF,
	DADNS_from_TN_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt_woTLL, 
	DADNA_from_GA0NUT_GA0Tgt, 
	DADNA_from_GA0NUT_GA0Tgt_woTLL) eq TRUE) {
    vLog("The address is still available.");
}else{
    vLog("The address is not available.");
    seqNG();
}

#--------------------------
# Sleep until 3 sec after expiration of VLT in the RA since receiving it. 
#--------------------------

vSleep(6);

vLog("It is 3 sec after the expiration of VLT in the RA.");
vLog("Confirming whether assinged address is available.");
if (seqCheckNUTAddrConfiguredGADAD($IF,
	DADNS_from_TN_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt, 
	DADNA_from_NUT_GA0Tgt_woTLL, 
	DADNA_from_GA0NUT_GA0Tgt, 
	DADNA_from_GA0NUT_GA0Tgt_woTLL) eq TRUE) {
    vLog("The address is still available.");
    seqNG();
}else{
    vLog("The address is not available.");
    seqOK();
}


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


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

=head1 NAME

RA_GA_Success - check the process when NUT receives RA which contains one Global Prefix.(Assigning and Expiring Global address)

=head1 TARGET

All Node

=head1 SYNOPSIS

RA_GA_Success.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 configuration

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

B<Test for all node>

   When NUT receives RA which contains Global Prefix, NUT assignes 
   autoconfigured address. NUT MAY perform DAD for its Global address prior 
   to assigning it.
   Because received Prefix has Valid Life Time(VLT), the Global address
   MUST expire when VLT expired. 

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

  <=== 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: DAD NS =========>
        name: DADNS_from_TN_GA0Tgt

  <=== Judgement #4: DAD NA =======
        name: 
	      DADNA_from_NUT_GA0Tgt, 
	      DADNA_from_NUT_GA0Tgt_woTLL, 
	      DADNA_from_GA0NUT_GA0Tgt, 
	      DADNA_from_GA0NUT_GA0Tgt_woTLL

  Wait until 3[sec] before expiration of VLT

  Check if NUT's address is available
  ==== Action #3: DAD NS =========>
        name: DADNS_from_TN_GA0Tgt

  <=== Judgement #5: DAD NA =======
        name: 
	      DADNA_from_NUT_GA0Tgt, 
	      DADNA_from_NUT_GA0Tgt_woTLL, 
	      DADNA_from_GA0NUT_GA0Tgt, 
	      DADNA_from_GA0NUT_GA0Tgt_woTLL

  Wait until 3[sec] after expiration of VLT

  ==== Action #4: DAD NS =========>
        name: DADNS_from_TN_GA0Tgt

 X <== Judgement #6: DAD NA =======
        name: 
	      DADNA_from_NUT_GA0Tgt, 
	      DADNA_from_NUT_GA0Tgt_woTLL, 
	      DADNA_from_GA0NUT_GA0Tgt, 
	      DADNA_from_GA0NUT_GA0Tgt_woTLL



=back 1

=head1 JUDGEMENT

=over 1

=item Test for Global 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
	src: TN's Link-local
	dst: allnode
	PXOPT: Global0

   Judgement #3. NUT MUST 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 DAD NS to check if NUT's address is configured.
        name: DADNS_from_TN_GA0Tgt
        src: ::0
	dst: solnode[NUT's Global0]
        TargetAddress: NUT's Global0

   Judgement #4. NUT MUST transmit DAD NA for its autoconfigured  Global address.
        name: DADNA_from_NUT_GA0Tgt, DADNA_from_NUT_GA0Tgt_woTLL
	src: NUT's Link-local
	dst: allnode
        TargetAddress: NUT's Global0
        RFlag: 0
        SFlag: 0
        OFlag: 1
	TLLOPT: NUT's MAC address
	(* TLLOPT may be omitted)

   Action #3. TN transmits DAD NS to check if NUT's address is configured.
              (3 [sec] before expiration)
        name: DADNS_from_TN_GA0Tgt
        src: ::0
	dst: solnode[NUT's Global0]
        TargetAddress: NUT's Global0

   Judgement #5. NUT MUST transmit DAD NA for its autoconfigured  Global address.
        name: DADNA_from_NUT_GA0Tgt, DADNA_from_NUT_GA0Tgt_woTLL
	src: NUT's Link-local
	dst: allnode
        TargetAddress: NUT's Global0
        RFlag: 0
        SFlag: 0
        OFlag: 1
	TLLOPT: NUT's MAC address
	(* TLLOPT may be omitted)

   Action #4. TN transmits DAD NS to check if NUT's address is configured.
              (3 [sec] after expiration)
        name: DADNS_from_TN_GA0Tgt
        src: ::0
	dst: solnode[NUT's Global0]
        TargetAddress: NUT's Global0

   Judgement #6. NUT MUST NOT transmit DAD NA for its autoconfigured  Global address.
        name: DADNA_from_NUT_GA0Tgt, DADNA_from_NUT_GA0Tgt_woTLL
	src: NUT's Link-local
	dst: allnode
        TargetAddress: NUT's Global0
        RFlag: 0
        SFlag: 0
        OFlag: 1
	TLLOPT: NUT's MAC address
	(* TLLOPT may be omitted)

=back 1

=head1 REFERENCE

=begin html
<PRE>
RFC2462
<HR>
   (omit)
<BR>
5.5.  Creation of Global and Site-Local Addresses
<BR>
   <B>Global and site-local addresses are formed by appending an interface
   identifier to a prefix of appropriate length. Prefixes are obtained
   from Prefix Information options contained in Router Advertisements.</B>
   Creation of global and site-local addresses and configuration of
   other parameters as described in this section SHOULD be locally
   configurable. However, the processing described below MUST be enabled
   by default.
<BR>
   (omit)
<BR>
5.5.3.  Router Advertisement Processing
<BR>
   (omit)
<BR>
   For each Prefix-Information option in the Router Advertisement:
<BR>
    a) If the Autonomous flag is not set, silently ignore the
       Prefix Information
       option.
<BR>
    b) If the prefix is the link-local prefix, silently ignore the
       Prefix Information option.
<BR>
    c) If the preferred lifetime is greater than the valid lifetime,
       silently ignore the Prefix Information option. A node MAY wish to
       log a system management error in this case.
<BR>
    d) <B>If the prefix advertised does not match the prefix of an address
       already in the list, and the Valid Lifetime is not 0, form an
       address (and add it to the list) by combining the advertised
       prefix with the link's interface identifier as follows</B>:
<BR>
   |            128 - N bits               |       N bits           |
   +---------------------------------------+------------------------+
   |            link prefix                |  interface identifier  |
   +----------------------------------------------------------------+
<BR>
<BR>
       If the sum of the prefix length and interface identifier length
       does not equal 128 bits, the Prefix Information option MUST be
       ignored.  An implementation MAY wish to log a system management
       error in this case. It is the responsibility of the system
       administrator to insure that the lengths of prefixes contained in
       Router Advertisements are consistent with the length of interface
       identifiers for that link type. Note that interface identifiers
       will typically be 64-bits long and based on EUI-64 identifiers as
       described in [ADDR-ARCH].
<BR>
       <B>If an address is formed successfully, the host adds it to the
       list of addresses assigned to the interface, initializing its
       preferred and valid lifetime values from the Prefix Information
       option.</B>
<BR>
   (omit)
<BR>
5.5.4.  Address Lifetime Expiry
<BR>
   A preferred address becomes deprecated when its preferred lifetime
   expires.  <B>A deprecated address SHOULD continue to be used as a source
   address in existing communications, but SHOULD NOT be used in new
   communications if an alternate (non-deprecated) address is available
   and has sufficient scope.  IP and higher layers (e.g., TCP, UDP) MUST
   continue to accept datagrams destined to a deprecated address since a
   deprecated address is still a valid address for the interface.</B> An
   implementation MAY prevent any new communication from using a
   deprecated address, but system management MUST have the ability to
   disable such a facility, and the facility MUST be disabled by
   default.
<BR>
   <B>An address (and its association with an interface) becomes invalid
   when its valid lifetime expires.  An invalid address MUST NOT be used
   as a source address in outgoing communications and MUST NOT be
   recognized as a destination on a receiving interface.</B>
<HR>
RFC2461
<HR>
<BR>
   (omit)
<BR>
7.2.4.  Sending Solicited Neighbor Advertisements
<BR>
   A node sends a Neighbor Advertisement in response to a valid Neighbor
   Solicitation targeting one of the node's assigned addresses.  The
   Target Address of the advertisement is copied from the Target Address
   of the solicitation.  If the solicitation's IP Destination Address is
   not a multicast address, the Target Link-Layer Address option MAY be
   omitted; the neighboring node's cached value must already be current
   in order for the solicitation to have been received.  If the
   solicitation's IP Destination Address is a multicast address, the
   Target Link-Layer option MUST be included in the advertisement.
   Furthermore, if the node is a router, it MUST set the Router flag to
   one; otherwise it MUST set the flag to zero.
<BR>
   If the Target Address is either an anycast address or a unicast
   address for which the node is providing proxy service, or the Target
   Link-Layer Address option is not included, the Override flag SHOULD
   be set to zero.  Otherwise, the Override flag SHOULD be set to one.
   Proper setting of the Override flag ensures that nodes give
   preference to non-proxy advertisements, even when received after
   proxy advertisements, and also ensures that the first advertisement
   for an anycast address "wins".
<BR>
   <B>If the source of the solicitation is the unspecified address, the
   node MUST set the Solicited flag to zero and multicast the
   advertisement to the all-nodes address.</B>  Otherwise, the node MUST set
   the Solicited flag to one and unicast the advertisement to the Source
   Address of the solicitation.
<BR>
   If the Target Address is an anycast address the sender SHOULD delay
   sending a response for a random time between 0 and
   MAX_ANYCAST_DELAY_TIME seconds.
   Because unicast Neighbor Solicitations are not required to include a
   Source Link-Layer Address, it is possible that a node sending a
   solicited Neighbor Advertisement does not have a corresponding link-
   layer address for its neighbor in its Neighbor Cache.  In such
   situations, a node will first have to use Neighbor Discovery to
   determine the link-layer address of its neighbor (i.e, send out a
   multicast Neighbor Solicitation).
<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

