#!/usr/bin/perl
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003 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/sendNsBasicGlobGlob.seq,v 1.31 2003/02/21 12:22:10 akisada Exp $
########################################################################
BEGIN { $V6evalTool::TestVersion = '$Name: REL_2_1_1 $ '; }
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;
$wait_dad=3;
$wait_ns=$nd::RETRANS_TIMER * $nd::MAX_MULTICAST_SOLICIT;
$wait_echo=2;
$wait_stale=$nd::REACHABLE_TIME * $nd::MAX_RANDOM_FACTOR+1;
$wait_probe=$nd::DELAY_FIRST_PROBE_TIME + 1;
#
#
#
$type=$V6evalTool::NutDef{Type};
if($type ne host && $type ne router) {
vLogHTML(ndErrmsg("ERROR: $V6evalTool::NutDef{Type}: ".
"Unknown target type
"));
exit $V6evalTool::exitFail;
}
#
# Start capture buffer
#
vLogHTML("Test
");
vCapture($IF);
#
#
#
if($type eq router) {
#
# A target router should be pre-configured:
# Link0: 3ffe:501:ffff:100 prefixlen 64
#
} else {
#
# Send an unsolicited RA w/ SLLA (src:x's link, dst:all-node)
# to advertise a global prefix to the target.
# SLLA makes sure that the target is in STALE state where
# the target doesn't send a NA for the address.
#
$pktdesc{unsol_ra}="Send unsolicited RA
";
vSend($IF, unsol_ra);
vLogHTML("Ignore DAD packets for $wait_dad sec.
");
vRecv($IF, $wait_dad, 0, 0);
}
#
# Set NC to REACHABLE
#
$pktdesc{echo_request}=
"Send an echo-request (global ==> global)";
vSend($IF, echo_request);
vLogHTML("Wait NS if any
");
vSleep(1);
$pktdesc{na}=
"Send unicast NA (global ==> global)";
vSend($IF, na);
$pktdesc{unicast_ns_from_global}=
'Got unicast NS (global <== global)';
$pktdesc{unicast_ns_sll_from_global}=
'Got unicast NS (global <== global)';
$pktdesc{unicast_ns_from_local}=
'Got unicast NS (global <== link-local)';
$pktdesc{unicast_ns_sll_from_local}=
'Got unicast NS (global <== link-local)';
$pktdesc{multicast_ns_from_global}=
'Got multicast NS (multicast <== global)';
$pktdesc{multicast_ns_from_local}=
'Got multicast NS (multicast <== link-local)';
$pktdesc{echo_reply}=
'Got echo-reply (global <== global)';
$count=0;
while(1) {
$s=check($wait_echo, 0, 1);
if($s eq ECHO_REPLY) {
last;
} elsif($s eq TIMEOUT) {
vLogHTML(ndErrmsg("ERROR: Never got echo-reply
"));
goto error;
}
$count++;
if($count > $nd::MAX_MULTICAST_SOLICIT) {
vLogHTML(ndErrmsg("ERROR: Never got echo-reply
"));
goto error;
}
}
vLogHTML("Then REACHABLE
");
#
# Wait for being STALE state.
#
vLogHTML("Wait for being STALE ($wait_stale sec.)
");
vSleep($wait_stale);
vLogHTML("Then STALE
");
#
#
#
$pktdesc{echo_request}="Send an echo-request (global ==> global)";
%ret=vSend($IF, echo_request);
$pktdesc{unicast_ns_from_global}=
ndErrmsg('ERROR: Got unicast NS (global <== global)');
$pktdesc{unicast_ns_sll_from_global}=
ndErrmsg('ERROR: Got unicast NS (global <== global)');
$pktdesc{unicast_ns_from_local}=
ndErrmsg('ERROR: Got unicast NS (global <== link-local)');
$pktdesc{unicast_ns_sll_from_local}=
ndErrmsg('ERROR: Got unicast NS (global <== link-local)');
$pktdesc{multicast_ns_from_global}=
ndErrmsg('ERROR: Got multicast NS (multicast <== global)');
$pktdesc{multicast_ns_from_local}=
ndErrmsg('ERROR: Got multicast NS (multicast <== link-local)');
$pktdesc{echo_reply}=
'Got echo-reply (global <== global), Then DELAY';
$s=check($wait_echo, $ret{sentTime1}, 1);
if($s ne ECHO_REPLY) {
vLogHTML(ndErrmsg("ERROR: Never got echo-reply
"));
goto error;
}
#
# Should capture an unicast NS (src:nut's global, dst:tn's global)
# that should be sent in PROBE state.
#
vLogHTML("Wait for being PROBE ($wait_probe sec.)
");
$pktdesc{unicast_ns_from_global}=
'Got unicast NS (global <== global), then PROBE';
$pktdesc{unicast_ns_sll_from_global}=
'Got unicast NS (global <== global), then PROBE';
$pktdesc{unicast_ns_from_local}=
'Got unicast NS (global <== link-local), then PROBE';
$pktdesc{unicast_ns_sll_from_local}=
'Got unicast NS (global <== link-local), then PROBE';
$pktdesc{multicast_ns_from_global}=
ndErrmsg('ERROR: Got multicast NS (multicast <== global)');
$pktdesc{multicast_ns_from_local}=
ndErrmsg('ERROR: Got multicast NS (multicast <== link-local)');
$pktdesc{echo_reply}=
ndErrmsg('ERROR: Got echo-reply (global <== global)');
$count=0;
while(1) {
$s=check($wait_probe, 0, 1);
if($s eq UNICAST_NS_G2G || $s eq UNICAST_NS_L2G) {
$count++;
if($count > $nd::MAX_MULTICAST_SOLICIT) {
vLogHTML("Too many unicast NS (> $nd::MAX_UNICAST_SOLICIT)");
$exit_rtn=$V6evalTool::exitFail;
last;
}
} elsif($s eq TIMEOUT) {
last;
} else {
$exit_rtn=$V6evalTool::exitFail;
}
}
if($count==0) {
vLogHTML(ndErrmsg("ERROR: Never got unicast NS
"));
goto error;
}
vLogHTML("Then, NONCE
");
#
#
#
$pktdesc{echo_request}="Send an echo-request (global ==> global)";
%ret=vSend($IF, echo_request);
vLogHTML("Wait for a multicast NS
");
$pktdesc{unicast_ns_from_global}=
ndErrmsg('ERROR: Got unicast NS (global <== global)');
$pktdesc{unicast_ns_sll_from_global}=
ndErrmsg('ERROR: Got unicast NS (global <== global)');
$pktdesc{unicast_ns_from_local}=
ndErrmsg('ERROR: Got unicast NS (global <== link-local)');
$pktdesc{unicast_ns_sll_from_local}=
ndErrmsg('ERROR: Got unicast NS (global <== link-local)');
$pktdesc{multicast_ns_from_global}=
'Got multicast NS (multicast <== global), then INCOMPLETE';
$pktdesc{multicast_ns_from_local}=
ndErrmsg('ERROR: Got multicast NS (multicast <== link-local), '.
'then INCOMPLETE');
$pktdesc{echo_reply}=
ndErrmsg('ERROR: Got echo-reply (global <== global)');
$count=0;
while(1) {
$s=check($wait_ns, $ret{sentTime1}, 1);
if($s eq TIMEOUT) {
last;
} elsif($s eq MULTICAST_NS_G2G || $s eq MULTICAST_NS_L2G) {
$count++;
if($s eq MULTICAST_NS_L2G) {
vLogHTML(ndErrmsg("ERROR: NS's source address ".
"should be global.
"));
$exit_rtn=$V6evalTool::exitFail;
}
if($count > $nd::MAX_MULTICAST_SOLICIT) {
vLogHTML("Too many unicast NS (> $nd::MAX_MULTICAST_SOLICIT)");
$exit_rtn=$V6evalTool::exitFail;
last;
}
} else {
$exit_rtn=$V6evalTool::exitFail;
}
}
if($count==0) {
vLogHTML(ndErrmsg("ERROR: Never got multicast NS
"));
goto error;
}
vLogHTML("Then NONCE
");
#
#
#
vLogHTML("Termination
");
clear();
#
#
#
if($exit_rtn == $V6evalTool::exitPass) {
vLogHTML("OK
");
} else {
vLogHTML("NG
");
}
exit $exit_rtn;
error:
vLogHTML("Termination
");
clear();
vLogHTML(vErrmsg(%ret)."
");
vLogHTML(ndErrmsg("NG
"));
exit $V6evalTool::exitFail;
#
#
#
sub clear()
{
return if $type eq router;
$pktdesc{unsol_ra_clrrtr}="Clear the Default Router List";
vSend($IF, unsol_ra_clrrtr);
}
#
#
#
sub check($$$)
{
my($timeout, $recvtime, $count)=@_;
my(%ret)=vRecv($IF, $timeout, $recvtime, $count,
unicast_ns_from_global,
unicast_ns_sll_from_global,
unicast_ns_from_local,
unicast_ns_sll_from_local,
multicast_ns_from_global,
multicast_ns_from_local,
echo_reply,
);
if($ret{status} == 1) {
return TIMEOUT;
} elsif($ret{status} == 0) {
if($ret{recvFrame} eq unicast_ns_from_global ||
$ret{recvFrame} eq unicast_ns_sll_from_global) {
return UNICAST_NS_G2G;
} elsif($ret{recvFrame} eq unicast_ns_from_local ||
$ret{recvFrame} eq unicast_ns_sll_from_local) {
return UNICAST_NS_L2G;
} elsif($ret{recvFrame} eq multicast_ns_from_global) {
return MULTICAST_NS_G2G;
} elsif($ret{recvFrame} eq multicast_ns_from_local) {
return MULTICAST_NS_L2G;
} else {
return ECHO_REPLY;
}
} else {
vLogHTML(vErrmsg(%ret)."
");
return ERROR;
}
}
########################################################################
__END__
=head1 NAME
sendNsBasicGlobGlob - Verify that NUT send NSs (global ==> global)
=head1 TARGET
Host and Router
=head1 SYNOPSIS
sendNsBasicGlobGlob.seq [-tooloption ...] -p sendNsBasicGlobGlob.def
=head1 INITIALIZATION
=head2 A CASE OF A HOST
=begin html
TN NUT ----------------------------------=end html =head1 JUDGMENT =begin html
State: REACHABLE (for TN)
Wait (REACHABLE_TIME * MAX_RANDOM_FACTOR)
State: STALE (for TN)
==== echo-request ===> src=TN's global dst=NUT's global
<=== Judgment #1: echo-reply ==== src=NUT's global dst=TN's global timeout: 2 sec
State: DELAY (for TN)
Wait (DELAY_FIRST_PROBE_TIME)
State: PROBE (for TN)
<=== Judgment #2: unicast NS ==== src=NUT's global or link-local dst=TN's global w/ or w/o SLLA timeout: RETRANS_TIMER * MAX_UNICAST_SOLICIT
State: NONCE (for TN)
==== echo-request ===> src=TN's global dst=NUT's global
State: INCOMPLETE (for TN)
<=== Judgment #3: multicast NS ==== src=NUT's global dst=TN's sol-node w/ SLLA timeout: RETRANS_TIMER * MAX_MULTICAST_SOLICIT
State: NONCE (for TN)
1. NUT must send one echo-reply: src: global, dst: global 2. NUT must send at the most three unicast NSs: src: global or link-local, dst: global, w/ or w/o TLLA 3. NUT must send at the most three multicast NSs: src:global(SHOULD), dst: sol-node[global], w/ SLLA=end html =head1 TERMINATION Send RA with RouterLifetime=0 to clear the Default Router List. =head1 NOTE The test dose not invoke any remote command. =head1 REFERENCE =begin html
RFC2461=end html =head1 SEE ALSO perldoc V6evalTool perldoc V6evalRemote =cut
7.2.2. Sending Neighbor Solicitations
When a node has a unicast packet to send to a neighbor, but does not know the neighbor's link-layer address, it performs address resolution. For multicast-capable interfaces this entails creating a Neighbor Cache entry in the INCOMPLETE state and transmitting a Neighbor Solicitation message targeted at the neighbor. The solicitation is sent to the solicited-node multicast address corresponding to the target address.
If the source address of the packet prompting the solicitation is the same as one of the addresses assigned to the outgoing interface, that address SHOULD be placed in the IP Source Address of the outgoing solicitation. Otherwise, any one of the addresses assigned to the interface should be used. Using the prompting packet's source address when possible insures that the recipient of the Neighbor Solicitation installs in its Neighbor Cache the IP address that is highly likely to be used in subsequent return traffic belonging to the prompting packet's "connection".