#!/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/nd/ncStateByNs4Incomplete.seq,v 1.40 2004/08/19 09:04:45 akisada Exp $
   
########################################################################
BEGIN { $V6evalTool::TestVersion = '$Name: V6PC_P1_1_3_3 $ '; }
 
use V6evalTool;
use nd;

my $wait_readout = $nd::DELAY_FIRST_PROBE_TIME +
    $nd::RETRANS_TIMER * $nd::MAX_UNICAST_SOLICIT + 1;

ndOptions(@ARGV);

# The following generate debugging messages.
$nd::debug=$ndOpt_v|$ndOpt_vv;

# You can specifies debug options to a remote control program.
# If you want to know more detail, please see the following:
# - V6evalTool.pm: perldoc V6evalTool
# - V6evalRemote.pm: perldoc V6evalRemote
$nd::remote_debug="-o1" if $ndOpt_vv;

$IF=Link0;
$exit_rtn=$V6evalTool::exitPass;

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

#
# sub test definition:
# - sending pattern,
# - SLLA vs cached LLA
# - expected state
# - message
#
$idx_ptn=0;
$idx_lla=1;
$idx_exp=2;
$idx_explla=3;
$idx_msg=4;
$idx_inc_ip=5;
$idx_prb_ip=6;
$idx_rpy_ip=7;
$idx_ign_ip=8;
$idx_non_n=9;
$idx_rpy_n=10;
$idx_ign_n=11;
$idx_stl_sr=12;
$idx_ign_sr=13;
@null=();

#
@def_unicast_ns_tn2nut
    =(
      unicast_ns_tn2nut,
      same,
      '(INCOMPLETE|NONCE)',
      unchanged,
      'unicast NS w/o SLL',
      \@null, \@null, \@null, \@null,
      \@null, \@null, \@null,
      \@null, \@null
      );

#
if($type eq 'host') {
	@reply_unicast_ns_tn2nut_sll=
		(unicast_na_nut2tn_rSo, unicast_na_nut2tn_rSO_tll);
} elsif($type eq 'router') {
	@reply_unicast_ns_tn2nut_sll=
		(unicast_na_nut2tn_RSo, unicast_na_nut2tn_RSO_tll);
} else {
	@reply_unicast_ns_tn2nut_sll=
		(unicast_na_nut2tn_rSo, unicast_na_nut2tn_rSO_tll,
		 unicast_na_nut2tn_RSo, unicast_na_nut2tn_RSO_tll);
}
@ignore_unicast_ns_tn2nut_sll=
    (nd_echo_reply);

@def_unicast_ns_tn2nut_sll =
    (
     unicast_ns_tn2nut_sll,
     same,
     STALE,
     unchanged,
     'unicast NS w/ SLL',
     \@null, \@null, \@reply_unicast_ns_tn2nut_sll, \@ignore_unicast_ns_tn2nut_sll,
     \@null, \@null, \@null,
     \@null, \@ignore_unicast_ns_tn2nut_sll
     );

#
if($type eq 'host') {
	@reply_multicast_ns_tn2nut_sll=
		(unicast_na_nut2tn_rSo, unicast_na_nut2tn_rSO_tll);
} elsif($type eq 'router') {
	@reply_multicast_ns_tn2nut_sll=
		(unicast_na_nut2tn_RSo, unicast_na_nut2tn_RSO_tll);
} else {
	@reply_multicast_ns_tn2nut_sll=
		(unicast_na_nut2tn_rSo, unicast_na_nut2tn_rSO_tll,
		 unicast_na_nut2tn_RSo, unicast_na_nut2tn_RSO_tll);
}
@ignore_multicast_ns_tn2nut_sll=
    (nd_echo_reply);
@def_multicast_ns_tn2nut_sll =
    (
     multicast_ns_tn2nut_sll,
     same,
     STALE,
     unchanged,
     'multicast NS w/ SLL',
     \@null, \@null, \@reply_multicast_ns_tn2nut_sll, \@ignore_multicast_ns_tn2nut_sll,
     \@null, \@null, \@null,
     \@null, \@ignore_multicast_ns_tn2nut_sll
     );

#
@defs=
    (
#     \@def_unicast_ns_tn2nut,
     \@def_unicast_ns_tn2nut_sll,
     \@def_multicast_ns_tn2nut_sll,
     );

#
#
#
vCapture($IF);

#
#
#
$idx=0;
foreach(@defs) {
    $exp=@$_[$idx_exp];
    $explla=@$_[$idx_explla];
    $msg=@$_[$idx_msg];
    vLogHTML("<HR>");
    vLogHTML("<FONT SIZE=\"+2\">*** INCOMPLETE vs. $msg ***</FONT><BR>");
    $s=checkState($_);
    $c=ndCachedLLA($explla);
    if($s =~ /$exp/ && $c eq $explla) {
        $result{$idx}=$V6evalTool::exitPass;
        vLogHTML("<A NAME=\"T$idx\">OK: The target was $s/$c</A><BR>");
    } else {
        $exit_rtn=$V6evalTool::exitFail;
        $result{$idx}=$exit_rtn;
        vLogHTML("<A NAME=\"T$idx\">".
		 ndErrmsg("NG: The target was $s/$c")."</A><BR>");
	readout($IF, $wait_readout);
    }
    $title{$idx}="<TD>$msg</TD><TD>exp:$exp/$explla</TD><TD>result:$s/$c</TD>";
    $idx++;
}
$idx--;

#
#
#
@col=('PTN', 'EXP(State/Cached LLA)', 'RESULT(State/Cached LLA)');
ndPrintSummaryHTML("*** Test Summary: INCOMPLETE vs. NS ***", @col,
                   %title, %result, $idx);

#
#
#
vLogHTML("*** EOT ***<BR>");
exit $exit_rtn;

sub readout($$) {
	my ($if, $timeout) = @_;
	return(vRecv($if, $timeout, 0, 0));
}

#
#
#
sub checkState(\@) {
    my($def)=@_;
    my($ptn)=@$def[$idx_ptn];
    my($lla)=@$def[$idx_lla];
    my($exp)=@$def[$idx_exp];
    my($msg)=@$def[$idx_msg];

    my($inc_ip)=@$def[$idx_inc_ip];
    my($prb_ip)=@$def[$idx_prb_ip];
    my($rpy_ip)=@$def[$idx_rpy_ip];
    my($ign_ip)=@$def[$idx_ign_ip];

    my($non_n)=@$def[$idx_non_n];
    my($rpy_n)=@$def[$idx_rpy_n];
    my($ign_n)=@$def[$idx_ign_n];

    my($stl_sr)=@$def[$idx_stl_sr];
    my($ign_sr)=@$def[$idx_ign_sr];

    vLogHTML("<FONT SIZE=\"+1\">Initialization</FONT><BR>");
    goto error if nd2Incomplete($IF) != 0;
    vClear($IF);

    vLogHTML("<FONT SIZE=\"+1\">Test</FONT><BR>");
    $pktdesc{$ptn}="Send $msg";
    my(%ret)=vSend($IF, $ptn);
    my($s)=ndStatusNum2Str(ndStatus(
                                    $IF, $ret{sentTime1},
                                    @$inc_ip, @$prb_ip, @$rpy_ip, @$ign_ip,
                                    @$non_n, @$rpy_n, @$ign_n,
                                    @$stl_sr, @$ign_sr,
                                    )
                       );
    return $s;

error:
    return("ERROR");
}

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

=head1 NAME

ncStateByNs4Incomplete - Verifying State Machine: NS vs. INCOMPLETE

=head1 TARGET

Host/Router/Special

=head1 SYNOPSIS

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

=head1 INITIALIZATION

Set the state of neighbor cache entry to INCOMPLETE.

  TN               NUT
  ----------------------

  State: No neighbor cache entry (for TN)

  ==== echo-request ===>
        src=TN's link-local
        dst=NUT's link-local

  State: INCOMPLETE (for TN)

=head1 TEST PROCEDURE

B<ncStateByNs4Incomplete> verifies that state transition for a NUT
in INCOMPLETE state when receiving a NS.

=begin html
<PRE>
  TN               NUT
  ----------------------
<BR>
  State: INCOMPLETE (for TN)
<BR>
  ==== <A HREF="#JDG1">NS</A> ===>
        src=TN's link-local
        dst=NUT's link-local/solicited-node[NUT's link-local]
        w/o or w/ SLLA
<BR>
  <A HREF="#JDG1">Judgment</A>: <A HREF="nd.html">Examining NUT's neighbor cache state</A>
</PRE>

=end html

=head1 JUDGEMENT

=begin html
<A NAME="JDG1"></A>
<PRE>
  ===============================+==========+=========+=================
  NS                             |New State |LLA       Comments
  ---------+-----------+---------+          |
  Source IP|Destination|SLLA     |          |
           |IP         |         |          |
  =========+===========+=========+==========+=========+=================
  TN's      Unicast     exist     STALE      updated
  link
  ---------+-----------+---------+----------+---------+-----------------
  TN's      Multicast   exist     STALE      updated
  link
  =========+===========+=========+==========+=========+=================
</PRE>

=end html

=head1 TERMINATION

  N/A

=head1 NOTE

  The test does not invoke any remote command.

=head1 REFERENCE

=begin html
<pre>
RFC2461
<hr>
7.2.3.  Receipt of Neighbor Solicitations<br>
   A valid Neighbor Solicitation that does not meet any the following
   requirements MUST be silently discarded:<br>
    - The Target Address is a "valid" unicast or anycast address
      assigned to the receiving interface [ADDRCONF],<br>
    - The Target Address is a unicast address for which the node is
      offering proxy service, or<br>
    - The Target Address is a "tentative" address on which Duplicate
      Address Detection is being performed [ADDRCONF].<br>
   If the Target Address is tentative, the Neighbor Solicitation should
   be processed as described in [ADDRCONF].  Otherwise, the following
   description applies.  If the Source Address is not the unspecified
   address and, on link layers that have addresses, the solicitation
   includes a Source Link-Layer Address option, then the recipient
   SHOULD create or update the Neighbor Cache entry for the IP Source
   Address of the solicitation.  If an entry does not already exist, the
   node SHOULD create a new one and set its reachability state to STALE
   as specified in Section 7.3.3.  <B>If an entry already exists, and the
   cached link-layer address differs from the one in the received Source
   Link-Layer option, the cached address should be replaced by the
   received address and the entry's reachability state MUST be set to
   STALE.</B>
</pre>

=end html

=head1 SEE ALSO

  perldoc V6evalTool
  perldoc V6evalRemote

=cut
