#!/usr/bin/perl # # $Copyright$ # # $TAHI: ct/nd/adrsolvQueuMulti.seq,v 1.21 2003/10/15 15:57:28 masaxmasa 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; $wait_reachable=$nd::REACHABLE_TIME * $nd::MAX_RANDOM_FACTOR + 1; $wait_probe=$nd::DELAY_FIRST_PROBE_TIME + 1 + $nd::RETRANS_TIMER * $nd::MAX_UNICAST_SOLICIT + 1; $wait_time=$nd::RETRANS_TIMER * $nd::MAX_MULTICAST_SOLICIT; $max_multicast_solicit=$nd::MAX_MULTICAST_SOLICIT; # # Start capture buffer # vLogHTML("Initialization
"); vCapture($IF); # # Need to clear neighbor cache entries of the target. # goto error if nd2NoNce($IF) != 0; clearX(); # # # vLogHTML("Test
"); # # Send an echo-request from TN (src:tn's link, dst:nut's link) # $pktdesc{ echo_request_from_tn}="Send echo-request (TN ==> NUT)"; vSend($IF, echo_request_from_tn); # # Send an echo-request from X (src:x's link, dst:nut's link) # $pktdesc{echo_request_from_x}="Send an echo-request (X ==> NUT)"; vSend($IF, echo_request_from_x); # # Send a solicited NA if getting a multicast NS. # Or, Got echo-reply's # $pktdesc{echo_reply_to_tn}= "Got an echo-reply (TN <== NUT), then REACHABLE"; $pktdesc{echo_reply_to_x}= "Got an echo-reply (X <== NUT), then REACHABLE"; $pktdesc{multicast_ns_to_tn}= "Got a multicast NS (TN <== NUT), then INCOMPLETE"; $pktdesc{multicast_ns_to_x}= "Got a multicast NS (X <== NUT), then INCOMPLETE"; $ns_from_tn=0; $ns_from_x=0; $echo_from_tn=0; $echo_from_x=0; while(1) { # # Got a multicast NS or an echo-reply # vLogHTML("Wait for multicast NS or echo-reply
"); %ret=vRecv($IF, $wait_time, 0, 1, echo_reply_to_tn, echo_reply_to_x, multicast_ns_to_tn, multicast_ns_to_x, ); last if $ret{status} != 0; $packet=$ret{recvFrame}; if($packet eq multicast_ns_to_tn) { # # Got a NS (src:nut's link, dst:solnode[tn's link]) # Then, send solicited NA (src:tn's link, dst:nut's link) # $ns_from_tn++; $pktdesc{na_from_tn}="Send NA (TN ==> NUT)"; vSend($IF, na_from_tn); } elsif($packet eq multicast_ns_to_x) { # # Got a NS (src:nut's link, dst:solnode[x's link]) # Then, send solicited NA (src:x's link, dst:nut's link) # $ns_from_x++; $pktdesc{na_from_x}="Send NA (X ==> NUT)"; vSend($IF, na_from_x); } elsif($packet eq echo_reply_to_tn) { # # Got an echo-reply from TN (src:nut's link, dst:tn's link) # $echo_from_tn++; } elsif($packet eq echo_reply_to_x) { # # Got an echo-reply from X (src:nut's link, dst:x's link) # $echo_from_x++; } } vLogHTML("NS from TN to TN: $ns_from_tn packets
"); vLogHTML("NS from TN to X: $ns_from_x packets
"); vLogHTML("echo-reply from TN to TN: $echo_from_tn packets
"); vLogHTML("echo-reply from TN to X: $echo_from_x packets
"); if(!$ns_from_tn || !$ns_from_x || !$echo_from_tn || !$echo_from_x) { # # Some packets to be captured were missed. # vLogHTML(ndErrmsg("ERROR: Some packet(s) were missed
")); goto error; } if($ns_from_tn > $max_multicast_solicit || $ns_from_x > $max_multicast_solicit) { # # The number of NSs > MAX_MULTICAST_SOLICIT # vLogHTML(ndErrmsg("ERROR: Too many multicast NS
")); goto error; } if($echo_from_tn > 1 || $echo_from_x > 1) { # # Echo-reply was duplicated. # vLogHTML(ndErrmsg("ERROR: Too many echo-reply
")); } vLogHTML("OK
"); exit $V6evalTool::exitPass; error: vLogHTML(vErrmsg(%ret)."
"); vLogHTML(ndErrmsg("NG
")); exit $V6evalTool::exitFail; sub clearX() { vLogHTML("Make X's state REACHABLE with echo & NA
"); $pktdesc{echo_request_from_x}="Send echo-request (X ==> NUT)"; vSend($IF, echo_request_from_x); vLogHTML("Want NS if any
"); vSleep(1); $pktdesc{na_from_x}="Send NA (X ==> NUT), then REACHABLE"; vSend($IF, na_from_x); vLogHTML("Wait for STALE
"); vRecv($IF, $wait_reachable, 0, 0); vLogHTML("Then, STALE
"); $pktdesc{echo_request_from_x}="Send echo-request, Then DELAY"; vSend($IF, echo_request_from_x); vRecv($IF, $wait_probe, 0, 0); vLogHTML("Clear X's link-local
"); } ######################################################################## __END__ =head1 NAME adrsolvQueuMulti - Verifying address resolution queues =head1 TARGET Host and Router =head1 SYNOPSIS adrsolvQueuMulti.seq [-tooloption ...] -p adrsolvQueuMulti.def =head1 INITIALIZATION Clear a neighbor cache entry for TN and X =head1 TEST PROCEDURE B verifies that a NUT queues at least one packet for an address whose LLA is not resolved. =begin html
  TN                 NUT
  ----------------------

State: No neighbor cache entry (for TN, X)
==== echo-request A ===> src=TN's link-local dst=NUT's link-local
State: INCOMPLETE (for TN), No neighbor cache entry (for X)
==== echo-request B ===> src=X's link-local dst=NUT's link-local
State: INCOMPLETE (for all)
<=== Judgment #1: multicast NS ==== src=NUT's link-local or global dst=solicited-node[TN's link-local] w/ SLLA timeout: $RETRANS_TIMER * $MAX_MULTICAST_SOLICIT ==== solicited NA ===> src=TN's link-local dst=NUT's link-local R=0, S=1, O=1 w/ TLLA
State: REACHABLE (for TN), INCOMPLETE (for X)
<=== Judgment #2: multicast NS ==== src=NUT's link-local or global dst=solicited-node[X's link-local] w/ SLLA timeout: $RETRANS_TIMER * $MAX_MULTICAST_SOLICIT
==== solicited NA ===> src=X's link-local dst=NUT's link-local R=0, S=1, O=1 w/ TLLA
State: REACHABLE (for TN, X)
<=== Judgment #3: echo-reply A ==== src=NUT's link-local dst=TN's link-local
<=== Judgment #4: echo-reply B ==== src=NUT's link-local dst=X's link-local
=end html =head1 JUDGMENT =begin html

  1. NUT must send at the least one multicast NS to TN.
     src=NUT's link-local or global, dst=solicited-node[TN's link-local], w/ SLLA

  2. NUT must send at the least one multicast NS to the X.
     src=NUT's link-local or global, dst=solicited-node[X's link-local], w/ SLLA

  3. NUT must send an echo-reply to TN.
     src=NUT's link-local, dst=TN's link-local

  4. NUT must send an echo-reply to the X.
     src=NUT's link-local, dst=X's link-local

  5. The order that the above packets (multicast NS and
     echo-reply) are captured in is not matter.
=end html =head1 TERMINATION N/A =head1 NOTE The test does not invoke any remote command. =head1 REFERENCE =begin html
RFC2461

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".
If the solicitation is being sent to a solicited-node multicast address, the sender MUST include its link-layer address (if it has one) as a Source Link-Layer Address option. Otherwise, the sender SHOULD include its link-layer address (if it has one) as a Source Link-Layer Address option. Including the source link-layer address in a multicast solicitation is required to give the target an address to which it can send the Neighbor Advertisement. On unicast solicitations, an implementation MAY omit the Source Link-Layer Address option. The assumption here is that if the sender has a peer's link-layer address in its cache, there is a high probability that the peer will also have an entry in its cache for the sender. Consequently, it need not be sent.
While waiting for address resolution to complete, the sender MUST, for each neighbor, retain a small queue of packets waiting for address resolution to complete. The queue MUST hold at least one packet, and MAY contain more. However, the number of queued packets per neighbor SHOULD be limited to some small value. When a queue overflows, the new arrival SHOULD replace the oldest entry. Once address resolution completes, the node transmits any queued packets.
=end html =head1 SEE ALSO perldoc V6evalTool perldoc V6evalRemote =cut