#!/usr/bin/perl
#
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Yokogawa Electric Corporation,
# YDC 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: v6eval/sample_stddef/tcp_handshake/tcp_handshake.seq,v 1.5 2003/10/10 10:19:59 akisada Exp $
#
BEGIN {$V6evalTool::TestVersion = '$Name: REL_3_0_1 $';}
use V6evalTool;
srand();
#--------------------------------------------------------------#
# internal configuration #
#--------------------------------------------------------------#
my $Link = 'Link0';
my $local_port = int(rand(0xffff));
my $remote_port = 9;
my $initial_seq = int(rand(0xffffffff));
#--------------------------------------------------------------#
# internal values #
#--------------------------------------------------------------#
%pktdesc = (
'send_ereq' => 'Send Echo Request: TN -> NUT',
'recv_erep' => 'Recv Echo Reply: NUT-> TN',
'recv_ns_multi' => 'Recv NS (multicast): NUT-> TN',
'recv_ns_uni' => 'Recv NS (unicast) w/o SLL: NUT-> TN',
'recv_ns_uni_sll' => 'Recv NS (unicast) w/ SLL: NUT-> TN',
'send_na' => 'Send NA: TN -> NUT',
'send_tcp' => 'Send TCP: TN -> NUT',
'recv_tcp' => 'Recv TCP: NUT-> TN',
);
my %nd = (
'recv_ns_multi' => 'send_na',
'recv_ns_uni' => 'send_na',
'recv_ns_uni_sll' => 'send_na',
);
my $cpp =
"-DCPP_LOCAL_PRT=$local_port ".
"-DCPP_RMT_PRT=$remote_port ";
my %vsend = ();
my %vrecv = ();
my $vrecv_wait = 1;
my $vrecv_loop = 3;
my $seq_no = 0;
my $ack_no = 0;
my $seektime = 0;
my $html = '';
#--------------------------------------------------------------#
# INITIALIZATION: Echo Reqest/Reply #
#--------------------------------------------------------------#
vCapture($Link);
vLogHTML('<FONT COLOR="#FF0000" SIZE="5"><U><B>INITIALIZATION'.
'</B></U></FONT><BR>');
%vsend = vSend($Link, 'send_ereq');
$seektime = $vsend{'sentTime1'};
for(my $d = 0; $d < $vrecv_loop; $d ++) {
# verify packets since last vSend(Echo Request/NS)
%vrecv = vRecv($Link, $vrecv_wait, $seektime, 0,
sort(keys(%nd)), 'recv_erep');
# if vRecv() get NS, send back NA
while(my ($recv, $send) = each(%nd)) {
if($vrecv{'recvFrame'} eq $recv) {
%vsend = vSend($Link, $send);
$seektime = $vsend{'sentTime1'};
$d --;
last;
}
}
# if vRecv() get an expected packet, exit from for() loop
if($vrecv{'recvFrame'} eq 'recv_erep') {
last;
}
}
if($vrecv{'recvFrame'} ne 'recv_erep') {
vLogHTML('<FONT COLOR="#FF0000">Can\'t get '.
'Echo Reply</FONT><BR>');
vLogHTML('<B><FONT COLOR="#FF0000">FAIL</FONT></B><BR>');
exit($V6evalTool::exitFail);
}
#--------------------------------------------------------------#
# TEST PROCEDURE: #
# Basic 3-Way Handshake for Connection Synchronization #
#--------------------------------------------------------------#
vLogHTML('<FONT COLOR="#FF0000" SIZE="5"><U><B>TEST PROCEDURE: '.
'Basic 3-Way Handshake for Connection Synchronization'.
'</B></U></FONT><BR>');
#------------------------------#
# Send SYN #
#------------------------------#
$pktdesc{'send_tcp'} = 'Send SYN: TN -> NUT';
# override CPP_SEQ_NO and CPP_SYN_SEND value in packet.def
vCPP($cpp . "-DCPP_SEQ_NO=$initial_seq -DCPP_SYN_SEND=1");
%vsend = vSend($Link, 'send_tcp');
$seektime = $vsend{'sentTime1'};
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | -----------> | " .
"<SEQ=$initial_seq>" .
"<CTL=SYN>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
#------------------------------#
# Recv SYN,ACK #
#------------------------------#
$pktdesc{'recv_tcp'} = 'Recv SYN,ACK: NUT -> TN';
# override CPP_ACK_RECV and CPP_SYN_RECV value in packet.def
vCPP($cpp . "-DCPP_ACK_RECV=1 -DCPP_SYN_RECV=1");
for(my $d = 0; $d < $vrecv_loop; $d ++) {
# verify packets since last vSend(SYN/NS) time
%vrecv = vRecv($Link, $vrecv_wait, $seektime, 0,
sort(keys(%nd)), 'recv_tcp');
# if vRecv() get NS, send back NA
while(my ($recv, $send) = each(%nd)) {
if($vrecv{'recvFrame'} eq $recv) {
%vsend = vSend($Link, $send);
$seektime = $vsend{'sentTime1'};
$d --;
last;
}
}
# if vRecv() get an expected packet, exit from for() loop
if($vrecv{'recvFrame'} eq 'recv_tcp') {
($seq_no, $ack_no) = get_tcp_value(%vrecv);
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | <----------- | ".
"<SEQ=$seq_no>".
"<ACK=$ack_no>".
"<CTL=SYN,ACK>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
last;
}
}
if($vrecv{'recvFrame'} ne 'recv_tcp') {
vLogHTML('<FONT COLOR="#FF0000">Can\'t get SYN,ACK</FONT><BR>');
vLogHTML('<B><FONT COLOR="#FF0000">FAIL</FONT></B><BR>');
exit($V6evalTool::exitFail);
}
#------------------------------#
# Send ACK #
#------------------------------#
$pktdesc{'send_tcp'} = 'Send ACK: TN -> NUT';
$seq_no ++;
# override CPP_SEQ_NO, CPP_ACK_NO and CPP_ACK_SEND value in packet.def
vCPP($cpp . "-DCPP_SEQ_NO=$ack_no -DCPP_ACK_NO=$seq_no -DCPP_ACK_SEND=1");
%vsend = vSend($Link, 'send_tcp');
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | -----------> | ".
"<SEQ=$ack_no>".
"<ACK=$seq_no>".
"<CTL=ACK>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
#--------------------------------------------------------------#
# TEST PROCEDURE: Normal Close Sequence #
#--------------------------------------------------------------#
vLogHTML('<FONT COLOR="#FF0000" SIZE="5"><U><B>TEST PROCEDURE: '.
'Normal Close Sequence</B></U></FONT><BR>');
#------------------------------#
# Send FIN,ACK #
#------------------------------#
$pktdesc{'send_tcp'} = 'Send FIN,ACK: TN -> NUT';
# override CPP_SEQ_NO, CPP_ACK_NO, CPP_FIN_SEND and CPP_ACK_SEND value
# in packet.def
vCPP($cpp . "-DCPP_SEQ_NO=$ack_no -DCPP_ACK_NO=$seq_no " .
"-DCPP_FIN_SEND=1 -DCPP_ACK_SEND=1");
%vsend = vSend($Link, 'send_tcp');
$seektime = $vsend{'sentTime1'};
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | -----------> | ".
"<SEQ=$ack_no>".
"<ACK=$seq_no>".
"<CTL=FIN,ACK>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
#------------------------------#
# Recv ACK #
#------------------------------#
$pktdesc{'recv_tcp'} = 'Recv ACK: NUT -> TN';
# override CPP_ACK_RECV value in packet.def
vCPP($cpp . "-DCPP_ACK_RECV=1");
for(my $d = 0; $d < $vrecv_loop; $d ++) {
# verify packets since last vSend(FIN,ACK/NS) time
%vrecv = vRecv($Link, $vrecv_wait, $seektime, 0,
sort(keys(%nd)), 'recv_tcp');
# if vRecv() get NS, send back NA
while(my ($recv, $send) = each(%nd)) {
if($vrecv{'recvFrame'} eq $recv) {
%vsend = vSend($Link, $send);
$seektime = $vsend{'sentTime1'};
$d --;
last;
}
}
# if vRecv() get an expected packet, exit from for() loop
if($vrecv{'recvFrame'} eq 'recv_tcp') {
($seq_no, $ack_no) = get_tcp_value(%vrecv);
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | <----------- | ".
"<SEQ=$seq_no>".
"<ACK=$ack_no>".
"<CTL=ACK>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
$seektime = $vrecv{'recvTime1'};
last;
}
}
if($vrecv{'recvFrame'} ne 'recv_tcp') {
vLogHTML('<FONT COLOR="#FF0000">Can\'t get ACK</FONT><BR>');
vLogHTML('<B><FONT COLOR="#FF0000">FAIL</FONT></B><BR>');
exit($V6evalTool::exitFail);
}
#------------------------------#
# Recv FIN,ACK #
#------------------------------#
$pktdesc{'recv_tcp'} = 'Recv FIN,ACK: NUT -> TN';
# override CPP_FIN_RECV and CPP_ACK_RECV value in packet.def
vCPP($cpp . "-DCPP_FIN_RECV=1 -DCPP_ACK_RECV=1");
for(my $d = 0; $d < $vrecv_loop; $d ++) {
# verify packets since last vRecv(ACK)/vSend(NS) time
%vrecv = vRecv($Link, $vrecv_wait, $seektime, 0,
sort(keys(%nd)), 'recv_tcp');
# if vRecv() get NS, send back NA
while(my ($recv, $send) = each(%nd)) {
if($vrecv{'recvFrame'} eq $recv) {
%vsend = vSend($Link, $send);
$seektime = $vsend{'sentTime1'};
$d --;
last;
}
}
# if vRecv() get an expected packet, exit from for() loop
if($vrecv{'recvFrame'} eq 'recv_tcp') {
($seq_no, $ack_no) = get_tcp_value(%vrecv);
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | <----------- | ".
"<SEQ=$seq_no>".
"<ACK=$ack_no>".
"<CTL=FIN,ACK>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
last;
}
}
if($vrecv{'recvFrame'} ne 'recv_tcp') {
vLogHTML('<FONT COLOR="#FF0000">Can\'t get FIN,ACK</FONT><BR>');
vLogHTML('<B><FONT COLOR="#FF0000">FAIL</FONT></B><BR>');
exit($V6evalTool::exitFail);
}
#------------------------------#
# Send ACK #
#------------------------------#
$pktdesc{'send_tcp'} = 'Send ACK: TN -> NUT';
$seq_no ++;
# override CPP_SEQ_NO, CPP_ACK_NO and CPP_ACK_SEND value in packet.def
vCPP($cpp . "-DCPP_SEQ_NO=$ack_no -DCPP_ACK_NO=$seq_no -DCPP_ACK_SEND=1");
%vsend = vSend($Link, 'send_tcp');
$html = " <PRE>\n";
$html .= " TN NUT\n";
$html .= " | |\n";
$html .= " | -----------> | ".
"<SEQ=$ack_no>".
"<ACK=$seq_no>".
"<CTL=ACK>\n";
$html .= " | |\n";
$html .= " </PRE>\n";
vLogHTML($html);
vStop($Link);
vLogHTML('<B>PASS</B><BR>');
exit($V6evalTool::exitPass);
################################################################
# #
# get_tcp_value() #
# #
# - get Sequence Number and Acknowledgment Number #
# from received packet #
# #
################################################################
sub get_tcp_value(%) {
my %vrecv = @_;
my $base = 'Frame_Ether.Packet_IPv6.Upp_TCP.Hdr_TCP';
# while(my ($key, $value) = each(%vrecv)) {
# print "$key\t$value\n";
# }
unless(defined($vrecv{$base . '.SequenceNumber'}) &&
defined($vrecv{$base . '.AcknowledgmentNumber'})) {
vLogHTML('<B><FONT COLOR="#FF0000">Internal error'.
'</FONT></B><BR>');
exit($V6evalTool::exitFatal);
}
my $seq_no = $vrecv{$base . '.SequenceNumber'};
my $ack_no = $vrecv{$base . '.AcknowledgmentNumber'};
return($seq_no, $ack_no);
}
syntax highlighted by Code2HTML, v. 0.9.1