#!/usr/bin/perl # # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation, # IPA (Information-technology Promotion Agency, Japan). # 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. However, using this software for the # purpose of testing or evaluating any products including merchantable # products may be permitted without any notification to the copyrighters. # # # # 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/hostRecvRaURD.seq,v 1.30 2002/02/27 01:08:25 masaxmasa Exp $ ######################################################################## BEGIN { $V6evalTool::TestVersion = '$Name: REL_2_1_2 $ '; } 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::exitHostPass; $wait_dad=3; $wait_echo=2; $wait_incomplete=($nd::RETRANS_TIMER * $nd::MAX_MULTICAST_SOLICIT) + 1; $wait_stale=($nd::REACHABLE_TIME * $nd::MAX_RANDOM_FACTOR) + 1; $wait_probe=$nd::DELAY_FIRST_PROBE_TIME + ($nd::RETRANS_TIMER * $nd::MAX_UNICAST_SOLICIT) + 1; # # # $type=$V6evalTool::NutDef{Type}; if($type eq router) { vLogHTML("This test is for the host only
"); exit $V6evalTool::exitHostOnly; } $type=$V6evalTool::NutDef{Type}; if($type ne host) { vLogHTML(ndErrmsg("ERROR: $V6evalTool::NutDef{Type}: ". "Unknown target type
")); exit $V6evalTool::exitFail; } # # # vLogHTML("
Initialization
"); vCapture($IF); # # # #goto error if ndClearPrefix() != 0; #goto error if nd2NoNce($IF) != 0; # # # $pktdesc{ra_tn2allnode_sll}='Router TN Send RA w/ SLL, NC[TN]=STALE'; $pktdesc{ra_y2allnode_sll}='Router Y Send RA w/ SLL, NC[Y]=STALE'; $pktdesc{ra_z2allnode_sll}='Router Z Send RA w/ SLL, NC[Y]=STALE'; vSend($IF, ra_tn2allnode_sll, ra_y2allnode_sll, ra_z2allnode_sll, ); vLogHTML("Wait for DAD NSs
"); vRecv($IF, $wait_dad, 0, 0); $pktdesc{unicast_na_tn2nut_RSO_tll}='Router TN send NA, NC[TN]=REACHABLE'; $pktdesc{unicast_na_y2nut_RSO_tll}='Router Y send NA, NC[Y]=REACHABLE'; $pktdesc{unicast_na_z2nut_RSO_tll}='Router Z send NA, NC[Z]=REACHABLE'; vSend($IF, unicast_na_tn2nut_RSO_tll, unicast_na_y2nut_RSO_tll, unicast_na_z2nut_RSO_tll, ); vSleep($wait_stale); vLogHTML("STALE state
"); # # # $i=0; $done_tn=0; $done_y=0; $done_z=0; vLogHTML("
Test
"); vLogHTML("*** Router TN, Y and Z are REACHABLE ". "in the Default Router List ***
"); while(1) { if($done_tn && $done_y && $done_z) { last; } my($r)=checkURD(); if($r eq echo_reply_nut2x_via_tn) { if($done_tn) { last; } $done_tn=1; vLogHTML("*** Router TN was NOT REACHABLE ***
"); } elsif($r eq echo_reply_nut2x_via_y) { if($done_y) { last; } $done_y=1; vLogHTML("*** Router Y was NOT REACHABLE ***
"); } elsif($r eq echo_reply_nut2x_via_z) { if($done_z) { last; } $done_z=1; vLogHTML("*** Router Z was NOT REACHABLE ***
"); } elsif($r eq "") { vLogHTML(ndErrmsg("ERROR: Never got an expected packet
")); last; } else { vLogHTML(ndErrmsg("ERROR: Got an unknown packet
")); $exit_rtn=$V6evalTool::exitFail; goto end; } $i++; } if($i < 2) { vLogHTML(ndErrmsg("ERROR: NUT must retain at least two router address ". "in the Default Router List
")); $exit_rtn=$V6evalTool::exitFail; } elsif($i == 2) { vLogHTML("NUT retains two router addresses " . "in the Default Router List
"); } elsif($i > 2) { vLogHTML("Well done: NUT retains more than two router addresses " . "in the Default Router List
"); } # # # if($done_tn && $done_y && $done_z) { vLogHTML("Routers that were reachable or probably reachable were ". "preferred over routers whose reachability was unknown or ". "suspect.
"); } else { vLogHTML(ndErrmsg("ERROR: Routers that are reachable or probably ". "reachable should be preferred over routers ". "whose reachability is unknown or suspect.". "
")); $exit_rtn=$V6evalTool::exitFail; } # # # $done_tn=0; $done_y=0; $done_z=0; vLogHTML("*** Nothing is reachable in the Default Router List ***
"); for($i=0; $i<3; $i++) { my($r)=checkURD2(); if($r eq multicast_ns_nut2tnsolnode) { $done_tn=1; } elsif($r eq multicast_ns_nut2ysolnode) { $done_y=1; } elsif($r eq multicast_ns_nut2zsolnode) { $done_z=1; } elsif($r eq "") { vLogHTML(ndErrmsg("ERROR: Never got an expected packet
")); last; } else { vLogHTML(ndErrmsg("ERROR: Got an unknown packet
")); $exit_rtn=$V6evalTool::exitFail; goto end; } } if($done_tn && $done_y && $done_z) { vLogHTML("When no routers on the Default Router List ". "were known to be reachable or probably reachable, ". "routers were selected in a round-robin fashion.". "
"); } else { vLogHTML(ndErrmsg("ERROR: When no routers on the Default Router List ". "are known to be reachable or probably reachable, ". "routers should be selected in a round-robin fashion.". "
")); $exit_rtn=$V6evalTool::exitFail; } # # # end: clear(); if($exit_rtn == $V6evalTool::exitPass) { vLogHTML("*** OK ***
"); } else { vLogHTML(vErrmsg(%ret)."
"); vLogHTML(ndErrmsg("*** NG ***
")); } exit $exit_rtn; sub checkURD() { my(%ret); $pktdesc{echo_request_x2nut_via_w}='Send off-link echo-requests'; %ret=vSend($IF, echo_request_x2nut_via_w); %ret=vSend($IF, echo_request_x2nut_via_w) if $V6evalTool::NutDef{System} =~ /solaris/ ; # patch for solaris bug $pktdesc{echo_reply_nut2x_via_tn}= 'Got echo-reply thrown to Router TN, then DELAY->PROBE'; $pktdesc{echo_reply_nut2x_via_y}= 'Got echo-reply thrown to Router Y, then DELAY->PROBE'; $pktdesc{echo_reply_nut2x_via_z}= 'Got echo-reply thrown to Router Z, then DELAY->PROBE'; %ret=vRecv($IF, $wait_echo, $ret{sentTime1}, 1, echo_reply_nut2x_via_tn, echo_reply_nut2x_via_y, echo_reply_nut2x_via_z, ); if($ret{status} == 0) { vLogHTML("Wait for NONCE
"); vRecv($IF, $wait_probe, 0, 0); my($t)=$wait_probe; $t*=2 if $V6evalTool::NutDef{System} =~ /solaris/ ; # patch for solaris vRecv($IF, $t, 0, 0); vLogHTML("then NONCE
"); return($ret{recvFrame}); } elsif($ret{status} == 1) { # timeout return(""); } error: clear(); vLogHTML(vErrmsg(%ret)."
"); vLogHTML(ndErrmsg("*** NG ***
")); exit $V6evalTool::exitFail; } sub checkURD2() { my(%ret); $pktdesc{echo_request_x2nut_via_w}='Send off-link echo-requests'; %ret=vSend($IF, echo_request_x2nut_via_w); $pktdesc{multicast_ns_nut2tnsolnode}= 'NUT sent multicast NS for Router TN'; $pktdesc{multicast_ns_nut2ysolnode}= 'NUT sent multicast NS for Router Y'; $pktdesc{multicast_ns_nut2zsolnode}= 'NUT sent multicast NS for Router Z'; %ret=vRecv($IF, $wait_echo, $ret{sentTime1}, 1, multicast_ns_nut2tnsolnode, multicast_ns_nut2ysolnode, multicast_ns_nut2zsolnode, ); if($ret{status} == 0) { vLogHTML("Wait for NONCE
"); vRecv($IF, $wait_probe, 0, 0); vLogHTML("then NONCE
"); return($ret{recvFrame}); } elsif($ret{status} == 1) { # timeout return(""); } error: clear(); vLogHTML(vErrmsg(%ret)."
"); vLogHTML(ndErrmsg("*** NG ***
")); exit $V6evalTool::exitFail; } # # # sub clear() { vLogHTML("
Termination
"); $pktdesc{ra_tn2allnode_clrrtr}= 'Clear Router TN form the Default Router List'; $pktdesc{ra_y2allnode_clrrtr}= 'Clear Router Y form the Default Router List'; $pktdesc{ra_z2allnode_clrrtr}= 'Clear Router Z form the Default Router List'; vSend($IF, ra_tn2allnode_clrrtr, ra_y2allnode_clrrtr, ra_z2allnode_clrrtr, ); } ######################################################################## __END__ =head1 NAME hostRecvRaURD - Verifying that NUD updates DRL =head1 TARGET Host only =head1 SYNOPSIS hostRecvRaURD.seq [-tooloption ...] -p hostRecvRaURD.def =head1 INITIALIZATION =begin html
  1. Set NC state for TN, Y and Z to STALEs.
  2. Give a global prefix, 3ffe:501:ffff:100::/64 with their RAs
  TN                 NUT
  ----------------------

State: NONCE (for TN, Y, Z)
==== 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
==== unsolicited RA ===> src=Y'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
==== unsolicited RA ===> src=Z'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
State: STALE (for TN, Y, Z)
<=== Ns for DAD (if any) ==== src=unspecified dst=solicited-node[NUT's global, prefix=3ffe:501:ffff:100::/64] target=NUT's global Wait (3 sec)
==== solicited NA ===> src=TN's link-local dst=NUT's link-local R=1, S=1, O=1 target=TN's link-local TLLA=TN's LLA
==== solicited NA ===> src=Y's link-local dst=NUT's link-local R=1, S=1, O=1 target=Y's link-local TLLA=Y's LLA
==== solicited NA ===> src=Z's link-local dst=NUT's link-local R=1, S=1, O=1 target=Z's link-local TLLA=Z's LLA
State: REACHABLE (for TN, Y, Z)
Wait (REACHABLE_TIME * MAX_RANDOM_FACTOR)
State: STALE (for TN, Y, Z)
=end html =head1 TEST PROCEDURE =begin html
hostRecvRaURD verifies the followings:
  TN               NUT
  ----------------------

State: STALE (for TN, Y, Z)
==== echo-request ===> src=off-link global, but LLA is the W's one dst=NUT's global
<=== Judgment #1: echo-reply ==== src=NUT's global dst=off-link global, but LLA is TN's one
State: DELAY (for TN), STALE (for Y, Z)
Wait (DELAY_FIRST_PROBE_TIME + (RETRANS_TIMER * $MAX_UNICAST_SOLICIT)) for the entry of the Default Router List to be unreachable.
State: NONCE (for TN), STALE (for Y, Z)
==== echo-request ===> src=off-link global, but LLA is the W's one dst=NUT's global
<=== Judgment #2: echo-reply ==== src=NUT's global dst=off-link global, but LLA is Y's one
State: NONCE (for TN), DELAY (for Y), STALE (for Z)
Wait (DELAY_FIRST_PROBE_TIME + (RETRANS_TIMER * $MAX_UNICAST_SOLICIT)) for the entry of the Default Router List to be unreachable.
State: NONCE (for TN, Y), STALE (for Z)
==== echo-request ===> src=off-link global, but LLA is the W's one dst=NUT's global
<=== Judgment #3: echo-reply ==== src=NUT's global dst=off-link global, but LLA is Z's one
State: NONCE (for TN, Y), DELAY (for Z)
Wait (DELAY_FIRST_PROBE_TIME + (RETRANS_TIMER * $MAX_UNICAST_SOLICIT)) for the entry of the Default Router List to be unreachable.
State: NONCE (for all)
==== echo-request ===> src=off-link global, but LLA is the W's one dst=NUT's global
State: INCOMPLETE (for TN), NONCE (for Y, Z)
<=== Judgment #4: multicast NS ==== src=NUT's global dst=solicited-node[TN's link-local] target=TN's link-local w/ SLLA
Wait (RETRANS_TIMER * $MAX_MULTICAST_SOLICIT)
State: NONCE (for all)
==== echo-request ===> src=off-link global, but LLA is the W's one dst=NUT's global
State: INCOMPLETE (for Y), NONCE (for TN, Z)
<=== Judgment #4: multicast NS ==== src=NUT's global dst=solicited-node[Y's link-local] target=Y's link-local w/ SLLA
Wait (RETRANS_TIMER * $MAX_MULTICAST_SOLICIT)
State: NONCE (for all)
==== echo-request ===> src=off-link global, but LLA is the W's one dst=NUT's global
State: INCOMPLETE (for Z), NONCE (for TN, Y)
<=== Judgment #4: multicast NS ==== src=NUT's global dst=solicited-node[Z's link-local] target=Z's link-local w/ SLLA
Wait (RETRANS_TIMER * $MAX_MULTICAST_SOLICIT)
State: NONCE (for all)
=end html =head1 JUDGMENT =for html 1. NUT must throw an echo-reply to the default router (i.e. NUT). =for html 2. NUT must throw an echo-reply to the default router (i.e. Y). =for html 3. NUT must throw an echo-reply to the default router (i.e. Z). =for html 4. Routers should be selected in a round-robin fashion. =head1 TERMINATION Send RAs to clear the Default Router List: - RA (src=TN) with RouterLifetime=0 - RA (src=Y) with RouterLifetime=0 - RA (src=Z) with RouterLifetime=0 =head1 NOTE 1. The test does not invoke any remote command: =head1 REFERENCE =begin html RFC2461
6.3.4.  Processing Received Router Advertisements

To limit the storage needed for the Default Router List, a host MAY choose not to store all of the router addresses discovered via advertisements. However, a host MUST retain at least two router addresses and SHOULD retain more. Default router selections are made whenever communication to a destination appears to be failing. Thus, the more routers on the list, the more likely an alternative working router can be found quickly (e.g., without having to wait for the next advertisement to arrive).
6.3.6. Default Router Selection
The policy for selecting routers from the Default Router List is as follows:
1) Routers that are reachable or probably reachable (i.e., in any state other than INCOMPLETE) SHOULD be preferred over routers whose reachability is unknown or suspect (i.e., in the INCOMPLETE state, or for which no Neighbor Cache entry exists). An implementation may choose to always return the same router or cycle through the router list in a round-robin fashion as long as it always returns a reachable or a probably reachable router when one is available.
2) When no routers on the list are known to be reachable or probably reachable, routers SHOULD be selected in a round-robin fashion, so that subsequent requests for a default router do not return the same router until all other routers have been selected.
Cycling through the router list in this case ensures that all available routers are actively probed by the Neighbor Unreachability Detection algorithm. A request for a default router is made in conjunction with the sending of a packet to a router, and the selected router will be probed for reachability as a side effect.
3) If the Default Router List is empty, assume that all destinations are on-link as specified in Section 5.2.
=end html =head1 SEE ALSO perldoc V6evalTool perldoc V6evalRemote =cut