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

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

sub checkDefaultRouter($);

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;

$wait_dad = 3;
$wait_echo = 2;

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

#
#
#
vLogHTML("<HR><FONT SIZE=\"+1\">Initialization</FONT><BR>");

#
# reset NUT first
#
vLogHTML("Trying to reboot NUT<BR>");
goto error if ndReboot() != 0;

vCapture($IF);

#
# 
#
$pktdesc{ra_tn2allnode_sll} = 'Router TN Send RA w/ SLL';
%ret = vSend($IF, ra_tn2allnode_sll);
goto error if $ret{status} != 0;

vLogHTML("Wait for DAD NSs<BR>");
vRecv($IF, $wait_dad, 0, 0);

$i = 0;
$tn_done=0;
vLogHTML("<HR><FONT SIZE=\"+1\">Test</FONT><BR>");
while (1) {
	$s = checkDefaultRouter($p);
	if ($s eq echo_reply_nut2x_via_tn) {
		if ($tn_done) {
			vLogHTML(ndErrmsg("ERROR: NUT doesn't recognize RA ".
				 "(RouterLifetime=0)<BR>"));
			goto error;
		}
		$pktdesc{ra_tn2allnode_sll_clear} =
			'Router TN send RA w/ RouterLifetime=0';
		$p = 'ra_tn2allnode_sll_clear';
		$tn_done=1;
	}
	else {
		last;
	}
	$i++;
}

#
#
#
if ($i != 1) {
	vLogHTML("*** NG ***<BR>");
	readout($IF, $wait_readout);
	exit($V6evalTool::exitFail);
}
elsif ($i == 1) {
	vLogHTML("*** OK ***<BR>");
	exit($V6evalTool::exitPass);
}

error:
	clear();
	vLogHTML(vErrmsg(%ret)."<BR>");
	vLogHTML(ndErrmsg("*** NG ***<BR>"));
	readout($IF, $wait_readout);
	exit($V6evalTool::exitFail);

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

sub clear()
{
    vLogHTML("<HR><FONT SIZE=\"+1\">Termination</FONT><BR>");
    $pktdesc{ra_tn2allnode_sll_clear}=
        'Clear Router TN form the Default Router List';
    vSend($IF,
          ra_tn2allnode_sll_clear,
          );
}

sub checkDefaultRouter($)
{
	my($ra) = @_;

	if (! ($ra =~ /^\s*$/)) {
		vSend($IF, $ra);
	}

	$pktdesc{echo_request_x2nut_via_w} = 'Send off-link echo-requests';
	%ret = vSend($IF, echo_request_x2nut_via_w);

	$pktdesc{echo_reply_nut2x_via_tn} =
		'Got echo-reply thrown to Router TN';
	$pktdesc{echo_reply_nut2x_via_y} =
		'Got echo-reply thrown to Router Y';
	$pktdesc{echo_reply_nut2x_via_z} =
		'Got echo-reply thrown to Router Z';
	$pktdesc{multicast_ns_nut2wsolnode} =
		'Got multicast NS for neighbor discovery';

RecvAgain:
	%ret = vRecv($IF, $wait_echo, $ret{sentTime1}, 1,
		     echo_reply_nut2x_via_tn,
		     multicast_ns_nut2wsolnode,
		     nd_multicast_ns,
		     nd_unicast_ns);

	if ($ret{status} == 0) {
		if ($ret{recvFrame} eq nd_multicast_ns ||
		    $ret{recvFrame} eq nd_unicast_ns) {
			vSend($IF, unicast_na_tn2nut_RSO_tll);
		}
		else {
			return($ret{recvFrame});
		}

		goto RecvAgain;
	}
	elsif ($ret{status} == 1) {
		vLogHTML("Got nothing<BR>");
		return('');
	}

error:
	clear();
	vLogHTML(vErrmsg(%ret)."<BR>");
	vLogHTML(ndErrmsg("*** NG ***<BR>"));
	readout($IF, $wait_readout);
	exit($V6evalTool::exitFail);
}

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

=head1 NAME

hostRecvRaRLifetime0_ume - Verifying that a host recognize RouterLifetime=0

=head1 TARGET

Host only

=head1 SYNOPSIS

  hostRecvRaRLifetime0_ume.seq [-tooloption ...] -p hostRecvRaRLifetime0.def

=head1 INITIALIZATION

=begin html
<OL>
  <LI>Create neighbor cache entries for TN
  <LI>Give a global prefix, 3ffe:501:ffff:100::/64
</OL>
<PRE>
  TN                 NUT
  ----------------------
<BR>
  State: No neighbor cache entry
<BR>
  ==== unsolicited RA ===>
       src=TN's link-local
       dst=all-node
       M=0, O=0
       RouterLifetime=600
       ReachableTime=0
       RetransTimer=0
       w/ SLLA
       Prefix Option:
           L=1, A=1
           ValidLifetime=2592000
           PreferredLifetime=604800
           Prefix=3ffe:501:ffff:100::/64
<BR>
  <=== Ns for DAD ====
       src=unspecified
       dst=solicited-node[NUT's global, prefix=3ffe:501:ffff:100::/64]
       target=NUT's global
<BR>
  Wait (3 sec)
</PRE>

=end html

=head1 TEST PROCEDURE

=begin html
<BR>
<B>hostRecvRaRLifetime0_ume</B> verifies that
<UL>
  <LI>a host recognizes RouterLifetime=0.
  <LI>a host updates the Default Router List if its entry is expires.
</UL>
<PRE>
  TN               NUT
  ----------------------
<BR>
  ==== echo-request ===>
       src=off-link global, but LLA is the W's one
       dst=NUT's global
<BR>
  <=== <A HREF="#JDG1">Judgment #1</A>: echo-reply ====
       src=NUT's global
       dst=off-link global, but LLA is one of the routers(TN, Y, Z)
<BR>
  ==== unsolicited RA ===>
       src=TN's link-local
       dst=all-node
       M=0, O=0
       <B>RouterLifetime=0</B>
       ReachableTime=0
       RetransTimer=0
       w/ SLLA
<BR>
  ==== echo-request ===>
       src=off-link global, but LLA is the W's one
       dst=NUT's global
<BR>
  <=== <A HREF="#JDG2">Judgment #2</A>: multicast NS (if any) ====
       src=NUT's link-local or global
       dst=solicited-node[off-link global]
       w/ SLLA
</PRE>

=end html

=head1 JUDGMENT

=for html <A NAME="JDG1"></A>

  1. NUT must throw an echo-reply to the default router

=for html <A NAME="JDG2"></A>

  2. NUT must not throw an echo-reply to any routers.
     NUT may throw multicast NS for onlink determination.

=head1 TERMINATION

  Send RAs to clear the Default Router List:
  - RA (src=TN) with RouterLifetime=0

=head1 NOTE

  The test does not invoke any remote command.

=head1 REFERENCE

=begin html
<pre>
RFC2461
<hr>
6.3.4.  Processing Received Router Advertisements<br>
      <b>- If the address is already present in the host's Default Router
        List and the received Router Lifetime value is zero, immediately
        time-out the entry as specified in Section 6.3.5.</b>
<br>
6.3.5.  Timing out Prefixes and Default Routers<br>
   Whenever the invalidation timer expires for a Prefix List entry, that
   entry is discarded.  No existing Destination Cache entries need be
   updated, however.  Should a reachability problem arise with an
   existing Neighbor Cache entry, Neighbor Unreachability Detection will
   perform any needed recovery.<br>
   <b>Whenever the Lifetime of an entry in the Default Router List expires,
   that entry is discarded.  When removing a router from the Default
   Router list, the node MUST update the Destination Cache in such a way
   that all entries using the router perform next-hop determination
   again rather than continue sending traffic to the (deleted) router.</b>
</pre>

=end html

=head1 SEE ALSO

  perldoc V6evalTool
  perldoc V6evalRemote

=cut
