#!/usr/bin/perl
#
# $Copyright_v6PC$
#
# $Copyright$
#
# $TAHI: ct/nd/hostRecvRaInvalid.seq,v 1.19 2004/04/02 02:28:22 akisada Exp $

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

use V6evalTool;
use nd;

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;
$idx=0;

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

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

#
$idx_ptn=0;
$idx_lla=1;
$idx_exp=2;
$idx_msg=3;
$idx_inc_ip=4;
$idx_prb_ip=5;
$idx_rpy_ip=6;
$idx_ign_ip=7;
$idx_non_n=8;
$idx_rpy_n=9;
$idx_ign_n=10;
$idx_stl_sr=11;
$idx_ign_sr=12;
@null=();

#
@def_ra_tn2allnode_sll_invalid_src=
    (
     ra_tn2allnode_sll_invalid_src,
     same,
     NONCE,
     'RA w/ SLL, src!=link-local (INVALID)',
     \@null, \@null, \@null, \@null,
     \@null, \@null, \@null,
     \@null, \@null
     );

#
@def_ra_tn2allnode_sll_invalid_hoplimit=
    (
     ra_tn2allnode_sll_invalid_hoplimit,
     same,
     NONCE,
     'RA w/ SLL, hop limit!=255 (INVALID)',
     \@null, \@null, \@null, \@null,
     \@null, \@null, \@null,
     \@null, \@null
     );

#
@def_ra_tn2allnode_sll_invalid_chksum=
    (
     ra_tn2allnode_sll_invalid_chksum,
     same,
     NONCE,
     'RA w/ SLL, check sum!=valid (INVALID)',
     \@null, \@null, \@null, \@null,
     \@null, \@null, \@null,
     \@null, \@null
     );

#
@def_ra_tn2allnode_sll_invalid_icmpcode=
    (
     ra_tn2allnode_sll_invalid_icmpcode,
     same,
     NONCE,
     'RA w/ SLL, icmp code!=0 (INVALID)',
     \@null, \@null, \@null, \@null,
     \@null, \@null, \@null,
     \@null, \@null
     );

#
@defs=
    (
     \@def_ra_tn2allnode_sll_invalid_src,
     \@def_ra_tn2allnode_sll_invalid_hoplimit,
     \@def_ra_tn2allnode_sll_invalid_chksum,
     \@def_ra_tn2allnode_sll_invalid_icmpcode,
     );

#
#
#
vCapture($IF);

#
#
#
$idx=0;
foreach(@defs) {
    $exp=@$_[$idx_exp];
    $msg=@$_[$idx_msg];
    vLogHTML("<HR><BR>");
    vLogHTML("<FONT SIZE=\"+2\">*** No neighbor cache entry vs. $msg ***</FONT><BR>");
    $s=checkState($_);
    if($s =~ /$exp/) {
        $result{$idx}=$V6evalTool::exitPass;
        vLogHTML("<A NAME=\"T$idx\">OK: The target was in $s state</A><BR>");
    } else {
        $exit_rtn=$V6evalTool::exitFail;
        $result{$idx}=$exit_rtn;
        vLogHTML("<A NAME=\"T$idx\">".
		 ndErrmsg("NG: The target was in $s state")."</A><BR>");
    }
    $title{$idx}="<TD>$msg</TD><TD>exp:$exp</TD><TD>result:$s</TD>";
    $idx++;
}
$idx--;

#
#
#
@col=('PTN', 'EXP', 'RESULT');
ndPrintSummaryHTML("*** Test Summary: No neighbor cache entry vs. RA ***", @col,
                   %title, %result, $idx);

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

error:
    vLogHTML(vErrmsg(%ret)."<BR>");
    exit $V6evalTool::exitFail;

#
#
#
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 nd2NoNce($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:
    vLogHTML(vErrmsg(%ret)."<BR>");
    exit $V6evalTool::exitFail;
}

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

=head1 NAME

hostRecvRaInvalid - Verifying that NUT discard invalid RAs

=head1 TARGET

Host only

=head1 SYNOPSIS

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

=head1 INITIALIZATION

  Clear a neighbor cache entry for TN.

=head1 TEST PROCEDURE

B<hostRecvRaInvalid> verifies that NUT discard invalid RAs.

=begin html
<PRE>
  TN               NUT
  ----------------------
<BR>
  State: No neighbor cache entry (for TN)
<BR>
  ==== <A HREF="#JDG1">invalid RA</A> ===>
<BR>
  <A HREF="#JDG1">Judgment</A>: <A HREF="nd.html">Examining NUT's neighbor cache state</A>
</PRE>

=end html

=head1 JUDGMENT

=begin html
<A NAME="JDG1"></A>
<PRE>
  ==================================================+====================
  Invalid RA                                        | The Neighbor Cache
  -----------+----------+-------+-------------------+---------+----------
  Src        | Dst      | SLLA  | Other             | Current | New
  ===========+==========+=======+===================+=========+==========
  <A HREF="#INVALID_A">*global</A>    | all-node | exist | N/A               | none    | unchanged
  -----------+----------+-------+-------------------+---------+----------
  link-local | all-node | exist | <A HREF="#INVALID_B">*hop limit=2</A>      | none    | unchanged
  -----------+----------+-------+-------------------+---------+----------
  link-local | all-node | exist | <A HREF="#INVALID_C">*invalid checksum</A> | none    | unchanged
  -----------+----------+-------+-------------------+---------+----------
  link-local | all-node | exist | <A HREF="#INVALID_D">*icmp code=1</A>      | none    | unchanged
  ===========+==========+=======+===================+=========+==========
</PRE>

=end html

=head1 TERMINATION

  N/A

=head1 NOTE

  The test does not invoke any remote command.

=head1 REFERENCE

=begin html
<pre>
RFC2461
<hr>
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>
     - <A NAME="INVALID_A"><B>IP Source Address is a link-local address.</A></B>  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="INVALID_B"><B>The IP Hop Limit field has a value of 255</A></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>
     - <A NAME="INVALID_C"><B>ICMP Checksum is valid.</A></B><BR>
     - <A NAME="INVALID_D"><B>ICMP Code is 0.</A></B><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.
</pre>

=end html

=head1 SEE ALSO

  perldoc V6evalTool
  perldoc V6evalRemote

=cut
