#!/usr/bin/perl
#!/usr/bin/perl -d
#!/usr/local/bin/perl
#!/usr/local/bin/perl -d

######################################################################
# DBS: Distributed Benchmark System
# Copyright (c) 1995, 1996 Yukio Murayama
# Copyright (c) 1995, 1996 Nara Institute of Science and Technology
# All rights reserved.
#
# Permission to use, copy, modify and distribute this software and its
# documentation is hereby granted, provided only with the following
# conditions are satisfied:
#
# 1. Both the copyright notice and this permission notice appear in
#    all copies of the software, derivative works or modified versions,
#    and any portions thereof, and that both notices appear in
#    supporting documentation.
# 2. All advertising materials mentioning features or use of this
#    software must display the following acknowledgement:
#      This product includes software developed by Nara Institute of 
#      Science and Technology and its contributors.
# 3. Neither the name of Nara Institute of Science and Technology nor 
#    the names of its contributors may be used to endorse or promote 
#    products derived from this software without specific prior written
#    permission.
#
# THIS SOFTWARE IS PROVIDED BY THE DEVELOPER ``AS IS'' AND NARA 
# INSTITUTE OF SCIENCE AND TECHNOLOGY DISCLAIMS ANY LIABILITY OF 
# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF 
# THIS SOFTWARE. ALSO, THERE IS NO WARRANTY IMPLIED OR OTHERWISE, 
# NOR IS SUPPORT PROVIDED.
#
# Feedback of the results generated from any improvements or
# extensions made to this software would be much appreciated.
# Any such feedback should be sent to:
#
#  Yukio Murayama
#  E-mail:  <yukio-m@is.aist-nara.ac.jp>
#  URL:     <http://shika.aist-nara.ac.jp/member/yukio-m/index.html>
#  Address: Graduate School of Information Science, 
#           Nara Institute of Science and Technology,
#           Takayama 8916-5, Ikoma, Nara, Japan
#
# Nara Institute of Science and Technology has the rights to 
# redistribute these changes.
######################################################################

######################################################################
# Distributed Benchmark System
# DBS Drawing Graph
# $Revision: 1.12 $
# $Date: 1997/07/11 00:53:57 $
# $Author: yukio-m $
######################################################################

######################################################################
# Definition of Global Variable
######################################################################

$debug         = 0;
$title_n       = 0;

$time          = 0.1; #Default Time Resolution

$process_flg   = "OFF";
$output_flg    = "ON";

$ps_flg        = "OFF";
$eps_flg       = "OFF";
$color_flg     = "OFF";

$area          = "";

$sq_flg        = "OFF";
$sd_flg        = "OFF";
$th_flg        = "OFF";
$dth_flg       = "OFF";
$delay_flg     = "OFF";
$jitter_flg    = "OFF";

$td_sq_flg     = "OFF";
$td_th_flg     = "OFF";
$td_win_flg    = "OFF";
$td_lost_flg   = "OFF";
$td_delay_flg  = "OFF";
$td_jitter_flg = "OFF";
$td_rtt_flg    = "OFF";

$u_lost_flg    = "OFF";
    
$record_ex             = "t";
$connect_ex            = "c";


$send_recv_ex          = "sr";
$send_throughput_ex    = "s_th";
$recv_throughput_ex    = "r_th";
$send_throughput_sum_ex= "s_th_sum";
$recv_throughput_sum_ex= "r_th_sum";
$delay_ex              = "delay";
$jitter_ex             = "jitter"; 
$u_lost_ex             = "u_lost";

$td_send_input_ex      = "td_s_0";
$td_send_output_ex     = "td_s_1";
$td_recv_input_ex      = "td_r_0";
$td_recv_output_ex     = "td_r_1";

$td_send_delay_ex      = "td_s_delay";
$td_recv_delay_ex      = "td_r_delay";
$td_send_lost_ex       = "td_s_lost";
$td_recv_lost_ex       = "td_r_lost";
$td_send_rrtt_ex       = "td_s_rrtt";
$td_recv_rrtt_ex       = "td_r_rrtt";
$td_send_mrtt_ex       = "td_s_mrtt";
$td_recv_mrtt_ex       = "td_r_mrtt";
$td_send_sequence_ex   = "td_s_sq";
$td_recv_sequence_ex   = "td_r_sq";
$td_send_throughput_ex = "td_s_th";
$td_recv_throughput_ex = "td_r_th";
$td_send_jitter_ex     = "td_r_jitter"; 
$td_recv_jitter_ex     = "td_r_jitter"; 

######################################################################
# Main
######################################################################

if ( $#ARGV >1) {
    &Argument_Check(@ARGV);
}
else {
    &help();
    exit;
}
&dprint(1, "debug mode");

foreach $file (@files) {
    open(CMDFILE, "$file")    || die "Can't open $file: $!\n";
    select((select(stdin), $| = 1)[0]);
    select((select(stdout), $| = 1)[0]);
    
    @cmd=<CMDFILE>;
    close(CMDFILE);

    @tmp = grep(/^[^\#].*file/, @cmd);
    @file = (@file, grep(s/ |\t|file|=|;.*|\n//g,@tmp));

    @tmp = grep(/^[^\#].*protocol/, @cmd);
    @protocol = (@protocol, grep(s/ |\t|protocol|=|;.*|\n//g,@tmp));

#    @tmp = grep(/^[^\#].*tcp_trace/, @cmd);
#    @tcp_trace = (@tcp_trace, grep(s/ |\t|tcp_trace|=|;.*|\n//g,@tmp));
}

if ($process_flg eq "ON") {
    if ($u_lost_flg ne "OFF") {
	&dprint(1, "u_lost");
	&calc_u_lost(@file);
    }

    if ($td_lost_flg ne "OFF") {
	&dprint(1, "td_lost");
	&td_lost(@file);
    }
}

if ($th_flg ne "OFF" || $dth_flg ne "OFF") {
    if ($process_flg eq "ON") {
	$_ = "$th_flg$dth_flg";
	if (/s|S/) {
	    &dprint(1, "calc_send_throughput");
	    &calc_send_throughput(@file);
	}
	$_ = "$th_flg$dth_flg";
	if (/r|R|t|T/) {
	    &dprint(1, "calc_recv_throughput");
	    &calc_recv_throughput(@file);
	}
	if (/t|T/) {
	    &dprint(1, "calc_recv_throughput_sum");
	    &calc_recv_throughput_sum(@file);
	}
    }
    if ($output_flg eq "ON") {
	if ($th_flg ne "OFF") {
	    &dprint(1, "plot_throughput");
	    &plot_throughput();
	}
	if ($dth_flg ne "OFF") {
	    &dprint(1, "plot_d_throughput");
	    &plot_d_throughput();
	}
    }
}

if ($delay_flg ne "OFF") {
    if ($process_flg eq "ON") {
	&dprint(1, "calc_delay");
	&calc_delay(@file);
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_delay");
	&plot_delay();
    }
}

if ($jitter_flg ne "OFF") {
    if ($process_flg eq "ON") {
	&dprint(1, "calc_jitter");
	&calc_jitter(@file);
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_jitter");
	&plot_jitter();
    }
}

if ($td_th_flg ne "OFF") {
    if ($process_flg eq "ON") {
	$_ = $td_th_flg;
	if (/s|S/) {
	    &dprint(1, "calc_td_send_throughput");
	    &calc_td_send_throughput(@file);
	}
	$_ = $td_th_flg;
	if (/r|R/) {
	    &dprint(1, "calc_td_recv_throughput");
	    &calc_td_recv_throughput(@file);
	}
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_td_throughput");
	&plot_td_throughput();
    }
}

if ($sd_flg ne "OFF") {
    if ($process_flg eq "ON") {
	&dprint(1, "calc_send_recv");
	&calc_send_recv(@file);
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_send_recv");
	&plot_sequence_data();
    }
}

if ($td_delay_flg ne "OFF") {
    if ($process_flg eq "ON") {
	&dprint(1, "calc_td_delay");
	&calc_td_delay(@file);
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_td_delay");
	&plot_td_delay();
    }
}

if ($td_rtt_flg ne "OFF") {
    if ($process_flg eq "ON") {
	&dprint(1, "calc_td_rtt");
	&calc_td_rtt(@file);
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_td_rtt");
	&plot_td_rtt();
    }
}
    
if ($td_jitter_flg ne "OFF") {
    if ($process_flg eq "ON") {
	&dprint(1, "calc_td_jitter");
	&calc_td_jitter(@file);
    }
    if ($output_flg eq "ON") {
	&dprint(1, "plot_td_jitter");
	&plot_td_jitter();
    }
}

if ($output_flg eq "ON") {
    if ($sq_flg ne "OFF") {
	&dprint(1, "plot_sequence");
	&plot_sequence();
    }
    if ($td_sq_flg ne "OFF") {
	&dprint(1, "plot_td_sequence");
	&plot_td_sequence();
    }
    if ($td_win_flg ne "OFF") {
	&dprint(1, "plot_td_window_size");
	&plot_td_window_size();
    }

    if ($ps_flg eq "OFF" && $eps_flg eq "OFF") {
	print stderr "Hit Return Key\n";
	$tmp = <stdin>;
    }
}

if ($sq_flg eq "ON") {
    close(PLOT_S);
}

if ($th_flg eq "ON") {
    close(PLOT_T);
}

exit;

######################################################################
#    Subroutins
######################################################################
sub dprint {
    local($db, $msg)= @_;

    if ($debug >= $db) {
	printf stderr "*$db*$msg\n";
    }
}

sub get_title {
    local($_, $n) = @_;
    local($word, $i);

    $word = $_;

    if ($n > 0) {
        @a= split(/\//, $_);
        $word =splice(@a, $n-1, $n);
    }
    elsif ($n < 0) {
	$word = "";
    }

    $word;
}

sub get_column {
    local($ext) = @_;
    local($word, $i, $_);
    $i=1;
    
    open(IN_EX, "$file[0].$ext") || die "Can't open $file[0].$ext: $!\n";
    $_= <IN_EX>;
    chop;
    s/^ +//g;
    foreach $word (split(/ +/, $_)) {
	$col{$word}=$i;
	$i++;
    }
    close(IN_EX);
}

sub get_column2 {
    local($_) = @_;
    local($word, $i);
    $i=1;
    
    chop;
    s/^ +//g;
    foreach $word (split(/ +/, $_)) {
	$col2{$word}=$i;
	&dprint(3, "$word = $i");
	$i++;
    }
}

sub getword {
    local($_) = @_;
    local($number, $i);
    $i=1;
    
    chop;
    s/^ +//g;
    foreach $number (split(/ +/, $_)) {
	$word[$i++] = $number;
	#print "$word[$i-1] = $number\n";
    }		
}

sub getword2 {
    local($_) = @_;

    &getword($_);

#	$send_d = $word[$col2{"send_sequence"}];
#	$send_s = $word[$col2{"send_size"}];
#	$send_t = $word[$col2{"send_time"}];
#	$recv_d = $word[$col2{"recv_sequence"}];
#	$recv_s = $word[$col2{"recv_seize"}];
#	$recv_t = $word[$col2{"recv_time"}];

    $word[$col2{"send_sequence"}],
    $word[$col2{"send_size"}],
    $word[$col2{"send_time"}],
    $word[$col2{"recv_sequence"}],
    $word[$col2{"recv_size"}],
    $word[$col2{"recv_time"}];
}



######################################################################
# PLOT Mini SUB
######################################################################

sub init_plot {
    local($fd) = @_;

    $cont_plot_flg = 0;

    if ($ps_flg eq "ON") {
        if ($color_flg eq "ON") {
	    print $fd "set term postscript color\n";
	}
	else {
	    print $fd "set term postscript mono\n";
	}
    }
    elsif ($eps_flg eq "ON") {
        if ($color_flg eq "ON") {
#            print $fd "set term postscript eps color 20 \n";
#            print $fd "set size 1.00,1.00\n";
            print $fd "set term postscript eps color  8 \n";
            print $fd "set size 0.40,0.40\n";
        }
        else {
	    print $fd "set term postscript eps mono 10 \n";
            print $fd "set size 0.50,0.50\n";
        }
    }
    else {
	print $fd "set term x11\n";
    }

    if ($title_n <= -2) {
	print $fd "set nokey\n";
    }
}

sub set_label {
    local($fd, $xlabel, $ylabel) = @_;
    print $fd "set xlabel \"$xlabel\"\n";
    print $fd "set ylabel \"$ylabel\"\n";
}

sub begin_plot {
    local($a, $area) = @_;

    print $a "plot $area";
}

sub cont_plot {
    local($a) = @_;
    print $a ",";
}

sub end_plot {
    local($a) = @_;
    print $a "\n";
    $cont_plot_flg = 0;
}

sub plot_sub {
    local($a, $ext, $sx, $sy, $title, $style) = @_;
    local($_);
    
    if ($cont_plot_flg == 1) {
	&cont_plot($a);
    }
    else {
	$cont_plot_flg = 1;
    }

    $s = 0;

    $_=$title_n;
    if (/^0.+/) {
        $title="";
    }

    if ($ext eq $u_lost_ex) {
	for ($s=0; $s <= $#file && $protocol[$s] ne "UDP"; $s = $s + 1) {
	}

	if ($title_n <= -2) {
	    print $a " \"$file[$s].$ext\" using $sx:$sy with $style\\\n";
	    for ($i=$s+1; $i <= $#file; $i = $i + 1) {
		if ($protocol[$s] eq "UDP") {
		    $ttitle = &get_title($file[$i], $title_n);
		    print $a ",\"$file[$i].$ext\" using $sx:$sy with $style\\\n";
		}
	    }
	}
	else {
	    $ttitle = &get_title($file[$s], $title_n);
	    print $a " \"$file[$s].$ext\" using $sx:$sy title \'$ttitle $title\' with $style\\\n";
	    for ($i=$s+1; $i <= $#file; $i = $i + 1) {
		$ttitle = &get_title($file[$i], $title_n);
		if ($ext ne $u_lost_ex || $protocol[$i] eq "UDP") {
		    if ($protocol[$s] eq "UDP") {
			print $a ",\"$file[$i].$ext\" using $sx:$sy title \'$ttitle $title\' with $style\\\n";
		    }
		}
	    }
	}
    }
    elsif ($title_n <= -2) {
	print $a " \"$file[0].$ext\" using $sx:$sy with $style\\\n";
	for ($i=1; $i <= $#file; $i = $i + 1) {
	    $ttitle = &get_title($file[$i], $title_n);
	    print $a ",\"$file[$i].$ext\" using $sx:$sy with $style\\\n";
	}
    }
    else {
	$ttitle = &get_title($file[0], $title_n);
	print $a " \"$file[$s].$ext\" using $sx:$sy title \'$ttitle $title\' with $style\\\n";
	for ($i=1; $i <= $#file; $i = $i + 1) {
	    $ttitle = &get_title($file[$i], $title_n);
	    if ($ext ne $u_lost_ex || $protocol[$i] eq "UDP") {
		print $a ",\"$file[$i].$ext\" using $sx:$sy title \'$ttitle $title\' with $style\\\n";
	    }
	}
    }

}

sub plot_sub1 {
    local($a, $ext, $sx, $sy, $title, $style) = @_;
    local($_);
    
    if ($cont_plot_flg == 1) {
	&cont_plot($a);
    }
    else {
	$cont_plot_flg = 1;
    }

    if ($title_n <= -3) {
	print $a " \"$file[0].$ext\" using $sx:$sy with $style\\\n";
    }
    else {
	print $a " \"$file[0].$ext\" using $sx:$sy title \'$title\' with $style\\\n";
    }
}

######################################################################
# PLOT SUB
######################################################################
sub plot_sequence {
    open(PLOT_SQ, "| gnuplot -title 'Sequence Number'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_SQ), $| = 1)[0]);

    &init_plot(PLOT_SQ);
    &set_label(PLOT_SQ, "Time (s)", "Sequence Number");
    &begin_plot(PLOT_SQ, $area);

    $_ = $sq_flg;
    if (/s/) {&plot_sub(PLOT_SQ, $record_ex, 3,1, "send", "steps");}
    if (/S/) {&plot_sub(PLOT_SQ, $record_ex, 3,1, "send", "points");}
    if (/r/) {&plot_sub(PLOT_SQ, $record_ex, 6,4, "recv", "steps");}
    if (/R/) {&plot_sub(PLOT_SQ, $record_ex, 6,4, "recv", "points");}
    if (/u/) {&plot_sub(PLOT_SQ, $u_lost_ex, 1,2, "lost", "steps");}
    if (/U/) {&plot_sub(PLOT_SQ, $u_lost_ex, 1,2, "lost", "points");}

    &end_plot(PLOT_SQ);
}

sub plot_sequence_data {
    open(PLOT_SD, "| gnuplot -title 'Total Data'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_SD), $| = 1)[0]);

    &init_plot(PLOT_SD);
    &set_label(PLOT_SD, "Time (s)", "Total Data");
    &begin_plot(PLOT_SD, $area);

    $_ = $sd_flg;
    if (/s/) {&plot_sub(PLOT_SD, $send_recv_ex, 4,3, "send", "steps");}
    if (/S/) {&plot_sub(PLOT_SD, $send_recv_ex, 4,3, "send", "points");}
    if (/r/) {&plot_sub(PLOT_SD, $send_recv_ex, 8,7, "recv", "steps");}
    if (/R/) {&plot_sub(PLOT_SD, $send_recv_ex, 8,7, "recv", "points");}
    if (/u/) {&plot_sub(PLOT_SD, $u_lost_ex,    1,2, "lost", "steps");}
    if (/U/) {&plot_sub(PLOT_SD, $u_lost_ex,    1,2, "lost", "points");}

    &end_plot(PLOT_SD);
}

sub plot_throughput {
    open(PLOT_TH, "| gnuplot -title 'Throughput'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_TH), $| = 1)[0]);

    &init_plot(PLOT_TH);
    &set_label(PLOT_TH, "Time (s)", "Throughput (Mbps)");
    &begin_plot(PLOT_TH, $area);

    $_ = $th_flg;
    if (/s/) {&plot_sub (PLOT_TH, $send_throughput_ex,     1, 2, "send", "lines");}
    if (/S/) {&plot_sub (PLOT_TH, $send_throughput_ex,     1, 2, "send", "steps");}
    if (/r/) {&plot_sub (PLOT_TH, $recv_throughput_ex,     1, 2, "recv", "lines");}
    if (/R/) {&plot_sub (PLOT_TH, $recv_throughput_ex,     1, 2, "recv", "steps");}
    if (/t/) {&plot_sub1(PLOT_TH, $recv_throughput_sum_ex, 1, 2, "total","lines");}
    if (/T/) {&plot_sub1(PLOT_TH, $recv_throughput_sum_ex, 1, 2, "total","steps");}

    &end_plot(PLOT_TH);
}

sub plot_d_throughput {
    open(PLOT_DTH, "| gnuplot -title 'Throughput'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_DTH), $| = 1)[0]);

    &init_plot(PLOT_DTH);
    &set_label(PLOT_DTH, "Data Size(kbyte)", "Throughput (Mbps)");
    &begin_plot(PLOT_DTH, $area);

    $_ = $dth_flg;
    if (/s/) {&plot_sub(PLOT_DTH, $send_throughput_ex, 5, 6,"send", "lines");}
    if (/S/) {&plot_sub(PLOT_DTH, $send_throughput_ex, 5, 6,"send", "steps");}
    if (/r/) {&plot_sub(PLOT_DTH, $recv_throughput_ex, 5, 6,"recv", "lines");}
    if (/R/) {&plot_sub(PLOT_DTH, $recv_throughput_ex, 5, 6,"recv", "steps");}

#   if (/t/) {&plot_sub1(PLOT_DTH, $recv_throughput_sum_ex, 5, 6,"total", "lines"); }
#   if (/T/) {&plot_sub1(PLOT_DTH, $recv_throughput_sum_ex, 5, 6,"total", "steps"); }

    &end_plot(PLOT_DTH);
}

sub plot_delay {
    open(PLOT_D, "| gnuplot -title 'Delay Time'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_D), $| = 1)[0]);

    &init_plot(PLOT_D);
    &set_label(PLOT_D, "Time (s)", "Delay Time (s)");
    &begin_plot(PLOT_D, $area);

    &plot_sub(PLOT_D, $delay_ex, 1, 2,"delay", "steps");

    &end_plot(PLOT_D);
}

sub plot_jitter {
    $_ = $jitter_flg;
    if (/[rs]/) {
	open(PLOT_J1, "| gnuplot -title 'Jitter'") || die "Can't execute gnuplot: $!\n";
	select((select(PLOT_J1), $| = 1)[0]);
	
	&init_plot(PLOT_J1);
	&set_label(PLOT_J1, "Time (s)", "Time (s)");
	&begin_plot(PLOT_J1, $area);

	$_ = $jitter_flg;
	if (/s/) {&plot_sub(PLOT_J1, $jitter_ex, 1, 2, "send", "steps");}
	if (/r/) {&plot_sub(PLOT_J1, $jitter_ex, 4, 5, "recv", "steps");}

	&end_plot(PLOT_J1);
    }

    $_ = $jitter_flg;
    if (/[RS]/) {
	open(PLOT_J2, "| gnuplot -title 'Jitter'") || die "Can't execute gnuplot: $!\n";
	select((select(PLOT_J2), $| = 1)[0]);
	
	&init_plot(PLOT_J2);
	&set_label(PLOT_J2, "Sequence Number", "Time (s)");
	&begin_plot(PLOT_J2, $area);

	$_ = $jitter_flg;
	if (/S/) {&plot_sub(PLOT_J2, $jitter_ex, 3, 2, "send", "steps");}
	if (/R/) {&plot_sub(PLOT_J2, $jitter_ex, 6, 5, "recv", "steps");}
	&end_plot(PLOT_J2);
    }
}

######################################################################
# PLOT TCP Debug SUB
######################################################################

sub plot_td_rtt {
    open(PLOT_RTT, "| gnuplot -title 'RTT(tcp_debug)'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_RTT), $| = 1)[0]);

    
    &init_plot(PLOT_RTT);
    &set_label(PLOT_RTT, "Time (s)", "Time (s)");
    &begin_plot(PLOT_RTT, $area);

    $_ = $td_rtt_flg;
    if (/r/) {&plot_sub(PLOT_RTT, $td_send_rrtt_ex, 1, 2,"Real RTT", "steps");}
    if (/m/) {&plot_sub(PLOT_RTT, $td_send_mrtt_ex, 1, 2,"Measured RTT", "steps");}
    if (/o/) {&plot_sub(PLOT_RTT, $td_send_mrtt_ex, 1, 3,"RTO", "steps"); }
    &end_plot(PLOT_RTT);
}

sub plot_td_delay {
    open(PLOT_RTT, "| gnuplot -title 'Delay(tcp_debug)'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_RTT), $| = 1)[0]);

    &init_plot(PLOT_RTT);
    &set_label(PLOT_RTT, "Time (s)", "Time (s)");
    &begin_plot(PLOT_RTT, $area);

    $_ = $td_delay_flg;
    if (/s/) {&plot_sub(PLOT_RTT, $td_send_delay_ex, 3, 2,"Send Delay", "steps")};
    if (/a/) {&plot_sub(PLOT_RTT, $td_recv_delay_ex, 3, 2,"Ack Delay", "steps")}; 
    &end_plot(PLOT_RTT);
}



sub plot_td_sequence {
    local($sq_sub_flg);
    $seq="seq";
    $ack="ack"; 
    
    open(PLOT_TSQ, "| gnuplot -title 'Sequence(TCP Debug)'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_TSQ), $| = 1)[0]);

    &init_plot(PLOT_TSQ);
    &set_label(PLOT_TSQ, "Time (s)", "Sequence Number");
    &begin_plot(PLOT_TSQ, $area);
    
    $_ = $td_sq_flg;
    if (/s/) {
	&get_column($td_send_output_ex);
	if ($col{"seq"} eq "") {$seq = "th_seq";}
	&plot_sub(PLOT_TSQ, $td_send_output_ex, $col{"td_time"}, $col{$seq}, "send", "steps");
    }
    if (/S/) {
	&get_column($td_send_output_ex);
	if ($col{"seq"} eq "") {$seq = "th_seq";}
	&plot_sub(PLOT_TSQ, $td_send_output_ex, $col{"td_time"}, $col{$seq}, "send", "points");
    }
    if (/a/) {
	&get_column($td_send_input_ex);
	if ($col{"ack"} eq "") {$ack = "th_ack";}
	&plot_sub(PLOT_TSQ, $td_send_input_ex,  $col{"td_time"}, $col{$ack}, "ack", "steps");
    }
    if (/A/) {
	&get_column($td_send_input_ex);
	if ($col{"ack"} eq "") {$ack = "th_ack";}
	&plot_sub(PLOT_TSQ, $td_send_input_ex,  $col{"td_time"}, $col{$ack}, "ack", "points");
    }
    if (/r/) {
	&get_column($td_recv_input_ex);
	if ($col{"seq"} eq "") {$seq = "th_seq";}
	&plot_sub(PLOT_TSQ, $td_recv_input_ex,  $col{"td_time"}, $col{$seq}, "recv", "steps");
    }
    if (/R/) {
	&get_column($td_recv_input_ex);
	if ($col{"seq"} eq "") {$seq = "th_seq";}
	&plot_sub(PLOT_TSQ, $td_recv_input_ex,  $col{"td_time"}, $col{$seq}, "recv", "points");
    }
    if (/l/) {
	&plot_sub(PLOT_TSQ, $td_send_lost_ex, 1, 2, "lost/rexmt", "points");
    }

    &end_plot(PLOT_TSQ);
}

sub plot_td_throughput {
    open(PLOT_TD_TH, "| gnuplot -title 'Throughput(TCP Debug)'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_TD_TH), $| = 1)[0]);

    &init_plot(PLOT_TD_TH);
    &set_label(PLOT_TD_TH, "Time (s)", "Throughput (Mbps)");
    &begin_plot(PLOT_TD_TH, $area);

    $_ = $td_th_flg;
    if (/s/) {&plot_sub(PLOT_TD_TH, $td_send_throughput_ex, 1, 2, "send", "lines");}
    if (/r/) {&plot_sub(PLOT_TD_TH, $td_recv_throughput_ex, 1, 2, "recv", "lines");}

    &end_plot(PLOT_TD_TH);
}

sub plot_td_window_size {
    open(PLOT_WIN, "| gnuplot -title 'Window Size(TCP Debug)'") || die "Can't execute gnuplot: $!\n";
    select((select(PLOT_WIN), $| = 1)[0]);

    &init_plot(PLOT_WIN);
    &set_label(PLOT_WIN, "Time (s)", "Window Size (byte)");
    
    if ($td_win_flg eq "w") {
	&set_label(PLOT_WIN, "Time (s)", "Window Size (byte)");
	&begin_plot(PLOT_WIN, $area);
	&get_column($td_send_output_ex);
	&plot_sub(PLOT_WIN, $td_send_output_ex, $col{"td_time"}, $col{"snd_cwnd"}, "cwnd", "steps");
    }
    elsif ($td_win_flg eq "s") {
	&set_label(PLOT_WIN, "Time (s)", "Slow Start Threshold (byte)");
	&begin_plot(PLOT_WIN, $area);
	&get_column($td_send_output_ex);
	&plot_sub(PLOT_WIN, $td_send_output_ex, $col{"td_time"}, $col{"snd_ssthresh"},"ssthresh", "steps");
    }
    elsif ($td_win_flg eq "ws" || $td_win_flg eq "sw") {
	&set_label(PLOT_WIN, "Time (s)", "Size (byte)");
	&begin_plot(PLOT_WIN, $area);
	&get_column($td_send_output_ex);

	&plot_sub(PLOT_WIN,  $td_send_output_ex, $col{"td_time"}, $col{"snd_cwnd"}, "cwnd", "steps");
        &plot_sub(PLOT_WIN,  $td_send_output_ex, $col{"td_time"}, $col{"snd_ssthresh"},"ssthresh", "steps");
    }
    &end_plot(PLOT_WIN);
}

sub plot_td_jitter {
    $_ = $td_jitter_flg;
    if (/[rs]/) {
	open(PLOT_TD_J1, "| gnuplot -title 'Jitter(TCP Debug)'") || die "Can't execute gnuplot: $!\n";
	select((select(PLOT_TD_J1), $| = 1)[0]);
	
	&init_plot(PLOT_TD_J1);
	&set_label(PLOT_TD_J1, "Time (s)", "Time (s)");
	&begin_plot(PLOT_TD_J1, $area);

	$_ = $td_jitter_flg;
	if (/s/) {&plot_sub(PLOT_TD_J1, $td_send_jitter_ex, 1, 2, "send", "steps");}
	if (/r/) {&plot_sub(PLOT_TD_J1, $td_recv_jitter_ex, 1, 2, "recv", "steps");}

	&end_plot(PLOT_TD_J1);
    }

    $_ = $td_jitter_flg;
    if (/[RS]/) {
	open(PLOT_TD_J2, "| gnuplot -title 'Jitter(TCP Debug)'") || die "Can't execute gnuplot: $!\n";
	select((select(PLOT_TD_J2), $| = 1)[0]);
	
	&init_plot(PLOT_TD_J2);
	&set_label(PLOT_TD_J2, "Sequence Number", "Time (s)");
	&begin_plot(PLOT_TD_J2, $area);

	$_ = $td_jitter_flg;
	if (/S/) {&plot_sub(PLOT_TD_J2, $td_send_jitter_ex, 3, 2, "send", "steps");}
	if (/R/) {&plot_sub(PLOT_TD_J2, $td_recv_jitter_ex, 3, 2, "recv", "steps");}

	&end_plot(PLOT_TD_J2);
    }
}

######################################################################
# Calc Sub
######################################################################
sub calc_send_recv {
    local(@file1) = @_;
    foreach (@file1) {
	$file_name = $_;
	open(IN, "$_.$record_ex") || die "Can't open   $_.$record_ex: $!\n";
	open(OUT, "> $_.$send_recv_ex")  || die "Can't create $_.$send_recv_ex: $!\n";
	$_=<IN>;
	&get_column2($_);
	$_ = <IN>;

	($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);
	print OUT "$send_d $send_s $send_d $send_t $recv_d $recv_s $recv_d $recv_t\n";
	print OUT "$send_d $send_s ", $send_d+$send_s, " $send_t $recv_d $recv_s ", $recv_d+$recv_s, " $recv_t\n";

	while(<IN>) {
	    ($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);
	    print OUT "$send_d $send_s ", $send_d+$send_s, " $send_t $recv_d $recv_s ", $recv_d+$recv_s, " $recv_t\n";
	}
	close(IN);
	close(OUT);
    }
}

#total
sub calc_recv_throughput_sum {
    local(@file2) = @_;
    local($d, $t, $start_d, $netxt_t, $t_time);

    open(OUT, "> $file[0].$recv_throughput_sum_ex") || die "Can't create $_.$recv_throughput_ex: $!\n";

    $in='fh01';
    foreach $fn (@file2) {
	$in++;
	open($in, "$fn.$recv_throughput_ex")    || die "Can't open   $fn.$record_ex: $!\n";
	push(@file_handl, $in);
    }
    $flag =1;

    $tm = 100000000;
    foreach $fn (@file_handl) {
	($t_time{$fn}, $throughput{$fn}, $next_t, $t, $data_sum, $d_throughput) = split(/ +/, <$fn>);
	if ($tm > $t_time{$fn}) {
	    $tm = $t_time{$fn};
	}
    }

    $tm = int($tm / $time)*$time + $time /2;

    while($flag) {
	$sum  =0.0;
	$flag =0;
	foreach $fn (@file_handl) {
	    if (eof($fn) != 1) {
		$flag = 1;
	    }
	    if ($tm > $t_time{$fn}) {
		$sum += $throughput{$fn};
		($t_time{$fn}, $throughput{$fn}, $next_t, $t) = split(/ +/, <$fn>);
	    }
	}
	if ($flag == 1) {
	    print OUT $tm - $time/2, " $sum $next_t $t $data_sum $d_throughput";
	}
	$tm += $time;
    }

    foreach (@file2) {
	close($IN{$_});
    }
    close(OUT);
}

sub calc_send_throughput {
    local(@file2) = @_;
    local($d, $t, $start_d, $netxt_t, $t_time);

    foreach (@file2) {
	open(IN, "$_.$record_ex")              || die "Can't open   $_.$record_ex: $!\n";
	open(OUT, "> $_.$send_throughput_ex")  || die "Can't create $_.$send_throughput_ex: $!\n";
	$file_name = $_;

	$_=<IN>;
	&get_column2($_);

	$_=<IN>;
	($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);

	&dprint(2, "$send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t");
	
	$start_d = $d = $send_d;
	$start_t = $t = $send_t;
	$data    = $data_sum = $send_s;
	
	$next_t = int($send_t/$time + 1)*$time;
	while(<IN>) {
	    ($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);
            $data     = $data     + $send_s;
            $data_sum = $data_sum + $send_s;

	    &dprint(2, "$send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t");
	    
	    if ($send_t > $next_t && $send_t != $t) {
		if ($send_t > $next_t+$time) {
		    while($send_t > $next_t) {
			$throughput = 0.0;
			$d_throughput = ($data_sum / ($send_t - $start_t) * 8 / (1000 * 1000));
#		        $t_time = ($next_t + $t)/2.0;
			$t_time = $next_t;
			print OUT "$t_time $throughput $next_t $t $data_sum $d_throughput \n";
			$t = $next_t;
			$next_t = $next_t + $time;
		    }
		}
		else {
		    $throughput   = ($data / ($send_t - $t) * 8 / (1000 * 1000));
		    $d_throughput = ($data_sum / ($send_t - $start_t) * 8 / (1000 * 1000));
#		    $t_time = ($send_t + $t)/2.0;
		    $t_time = $next_t;
		    print OUT "$t_time $throughput $send_t $t $data_sum $d_throughput\n";
		    $d = $send_d;
		    $t = $send_t;
                    $data    = 0;
		    $next_t = $next_t + $time;
		}
	    }
	}
	if (($t - $start_t) != 0) {
#	    $throughput = (($send_d - $start_d) / ($send_t - $start_t) * 8 / (1000 * 1000));
	    $throughput = ($data_sum / ($send_t - $start_t) * 8 / (1000 * 1000));
	    printf stderr "$file_name Send: Mean Throughput %10.4f Mbps\n", $throughput;
	}
	else {
	    printf stderr "$file_name Send: Mean Throughput ERROR\n"
	}
	close(IN);
	close(OUT);
    }
}

sub calc_recv_throughput {
    local(@file2) = @_;
    local($d, $t, $start_d, $netxt_t, $t_time);
    
    foreach (@file2) {
	open(IN, "$_.$record_ex")             || die "Can't open   $_.$record_ex: $!\n";
	open(OUT, "> $_.$recv_throughput_ex") || die "Can't create $_.$recv_throughput_ex: $!\n";
	$file_name = $_;

	$_=<IN>;
	&get_column2($_);
	$_=<IN>;

	($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);

	$next_t = int($send_t/$time + 1)*$time;

	while($recv_t > $next_t) {
	    $throughput = $d_throughput = 0.0;
	    $data    = $data_sum = 0;
	    $t_time = $next_t;
	    print OUT "$t_time $throughput $next_t $t ", $data_sum/1024, " $d_throughput\n";
	    $t = $next_t;
	    $next_t = $next_t + $time;
	}
	
	$start_d = $d = $recv_d;          # XXX
	$start_t = $t = $recv_t;          # XXX
	$data    = $data_sum = $recv_s;

	$next_t = int($recv_t/$time + 1)*$time;
	while(<IN>) {
	    ($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);
            $data     = $data     + $recv_s;
            $data_sum = $data_sum + $recv_s;
	    
	    if ($next_t < $recv_t && $recv_t != $t) {
		if ($recv_t > $next_t + $time) {
		    while($recv_t > $next_t) {
			$throughput = 0.0;
			$d_throughput = ($data_sum / ($recv_t - $start_t) * 8 / (1000 * 1000));
#		        $t_time = ($next_t + $t)/2.0;
			$t_time = $next_t;
			print OUT "$t_time $throughput $next_t $t ", $data_sum/1024, " $d_throughput\n";
			$t = $next_t;
			$next_t = $next_t + $time;
		    }
		}
		else {
		    $throughput = ($data / ($recv_t - $t) * 8 / (1000 * 1000));
		    $d_throughput = ($data_sum / ($recv_t - $start_t) * 8 / (1000 * 1000));
#                   $t_time = ($recv_t + $t)/2.0;
#		    $t_time = $recv_t; #XXX
		    $t_time = $next_t;
		    print OUT "$t_time $throughput $next_t $t ", $data_sum/1024, " $d_throughput\n";
		    $d = $recv_d;
		    $t = $recv_t;
                    $data    = 0;
		    $next_t = $next_t + $time;
		}
	    }
	}
	if (($t - $start_t) !=0) {
#	    $throughput = (($d - $start_d) / ($t - $start_t) * 8 /(1000 * 1000));
	    $throughput = ($data_sum / ($t - $start_t) * 8 / (1000 * 1000));
	    printf stderr "$file_name Recv: Mean Throughput %10.4f Mbps\n", $throughput;
	}
	close(IN);
	close(OUT);
    }
}

sub calc_delay {
    local(@file1) = @_;
    foreach (@file1) {
	$file_name = $_;
	open(IN, "$_.$record_ex") || die "Can't open   $_.$record_ex: $!\n";
	open(OUT, "> $_.$delay_ex")  || die "Can't create $_.$delay_ex: $!\n";
	$n = 0;
	$alldelay = 0;
	$_=<IN>;
	&get_column2($_);

	while(<IN>) {
	    ($send_d, $send_s, $send_t, $recv_d, $recv_s, $recv_t) = &getword2($_);

	    $s_d[$n] = $send_d + $send_s;
	    $s_t[$n] = $send_t;
	    $r_d[$n] = $recv_d + $recv_s;
	    $r_t[$n] = $recv_t;
	    $n++;
	}

	for ($i1=0, $i2=0; ($i1 < $n) && ($i2 < $n); $i1++) {
	    while($s_d[$i1] > $r_d[$i2] && $i2 <= $n) {
		$i2++;
	    }
	    if ($s_d[$i1] <= $r_d[$i2] && $i2 <= $n) {
		$delay = ($r_t[$i2] - $s_t[$i1]);
		$alldelay = $alldelay + $delay;
		print OUT "$s_t[$i1] $delay $i1 $alldelay\n";
	    }
	}
	if ($n != 0) {
	    $delay = $alldelay/$n;
	    printf stderr "$file_name: Mean delay %10.6f s\n", $delay;
	}
	else {
	    printf stderr "calc_delay error\n", $delay;
	}
	close(IN);
	close(OUT);
    }
}

sub calc_jitter {
    local(@file1) = @_;
    local($jitter);
    
    foreach (@file1) {
	$file_name = $_;
	
	open(IN, "$_.$record_ex")   || die "Can't open   $_.$record_ex: $!\n";
	open(OUT, "> $_.$jitter_ex") || die "Can't create $_.$jitter_ex: $!\n";
	$n = 0;
	$alldelay = 0;
	$_=<IN>;
	&get_column2($_);
	$_=<IN>;
	($send_d1, $send_s1, $send_t1, $recv_d1, $recv_s1, $recv_t1) = &getword2($_);
	
	while(<IN>) {
	    ($send_d2, $send_s2, $send_t2, $recv_d2, $recv_s2, $recv_t2) = &getword2($_);
	    
	    $jitter_s = $send_t2 - $send_t1;
	    $jitter_r = $recv_t2 - $recv_t1;

	    if ($send_d2 eq "NA") {
		$send_t2 = $jitter_s = $send_d2 = "NA";
	    }
	    if ($recv_d2 eq "NA") {
		$recv_t2 = $jitter_r = $recv_t2 = "NA";
	    }
	    
	    print OUT "$send_t2 $jitter_s $send_d2 $recv_t2 $jitter_r $recv_d2\n";

	    $send_d1 = $send_d2;
	    $send_s1 = $send_s2;
	    $send_t1 = $send_t2;
	    $recv_d1 = $recv_d2;
	    $recv_s1 = $recv_s2;
	    $recv_t1 = $recv_t2;
	}
	close(IN);
	close(OUT);
    }
}

sub calc_u_lost {
    local(@file1) = @_;
    $i = 0;
    foreach  (@file1) {
        if ($protocol[$i] eq "UDP") {
	    $file_name = $_;
	    open(INS, "$_.$record_ex")   || die "Can't open   $_.$record_ex: $!\n";
	    open(INR, "$_.$record_ex")   || die "Can't open   $_.$record_ex: $!\n";
	    open(OUT, "> $_.$u_lost_ex") || die "Can't create $_.$u_lost_ex: $!\n";

	    $_=<INS>;
	    $_=<INR>;
	    &get_column2($_);

	    while(<INS>) {
		&getword($_);
		$t = $word[$col2{"send_time"}];
		$s = $word[$col2{"send_sequence"}];
		$d = $word[$col2{"send_size"}];

		$_=<INR>;
		&getword($_);
		$r = $word[$col2{"recv_sequence"}];

		while( $s < $r) {
		    print OUT "$t $s $d\n";

		    $_=<INS>;
		    &getword($_);
		    $t = $word[$col2{"send_time"}];
		    $s = $word[$col2{"send_sequence"}];
		    $d = $word[$col2{"send_size"}];
		}
	    }
	    close(INS);
	    close(INR);
	    close(OUT);
	}
	$i++;
    }
}

######################################################################
# tcp_trace sub
######################################################################

sub calc_td_send_throughput {
    local(@file2) = @_;
    local($d, $t, $start_d, $netxt_t, $t_time, $throughput);
    $seq="seq";
    $ack="ack";

    $i = 0;
    foreach (@file2) {
#	if ($tcp_trace[$i] eq "ON") {
	    open(IN, "$_.$td_send_output_ex")        || die "Can't open   $_.$td_send_output_ex: $!\n";
	    open(OUT, "> $_.$td_send_throughput_ex") || die "Can't create $_.$td_send_throughput_ex: $!\n";
	    $file_name = $_;

	    $_=<IN>;
	    &get_column2($_);
	    if ($col2{"seq"} eq "") {$seq = "th_seq";}
	    if ($col2{"ack"} eq "") {$ack = "th_ack";}

	    $_ = <IN>;
	    &getword($_);

	    $d       = $word[$col2{$seq}];
	    $t       = $word[$col2{"td_time"}];
	    $start_d = $word[$col2{$seq}];
	    $start_d = $word[$col2{"td_time"}];
	    &dprint(2, "$d\t$t");
	    &dprint(2, $word[$col2{"td_time"}]." > ".$next_t."&& , ".$word[$col2{"td_time"}]." , >= $t");

	    $next_t = int($word[$col2{"td_time"}]/$time + 1)*$time;
	    foreach $_ (<IN>) {
		&getword($_);
		&dprint(2, $word[$col2{"td_time"}]." > ".$next_t."&& , ".$word[$col2{"td_time"}]." , >= $t");
		if ($word[$col2{"td_time"}] > $next_t && $word[$col2{"td_time"}] != $t) {
		    if ($word[$col2{"td_time"}] > $next_t+$time) {
			while($word[$col2{"td_time"}] > $next_t) {
#		        $throughput = (($d - $d) / ($next_t - $t) * 8 / (1000 * 1000));
			    $throughput = 0.0;
#		        $t_time = ($next_t + $t)/2.0;
			    $t_time = $next_t;
			    print OUT "$t_time $throughput $next_t $t\n";
			    $t = $next_t;
			    $next_t = $next_t + $time;
			}
		    }
		    else {
			$throughput = (($word[$col2{$seq}] - $d) / ($word[$col2{"td_time"}] - $t) * 8 / (1000 * 1000));
#		    $t_time = ($word[$col2{"td_time"}] + $t)/2.0;
			$t_time = $next_t;
			if ($throughput >= 0) {     #not lost
			    print OUT "$t_time $throughput ", $word[$col2{"td_time"}], " $t\n";
			}
			$d = $word[$col2{$seq}];
			$t = $word[$col2{"td_time"}];
			$next_t = $next_t + $time;
		    }
		}
	    }
	    if (($t - $start_t) != 0) {
		$throughput = (($d - $start_d) / ($t - $start_t) * 8 / (1000 * 1000));
		printf stderr "$file_name Send: Mean Throughput %10.4f Mbps\n", $throughput;
	    }
	    else {
		printf stderr "$file_name Send: Mean Throughput ERROR\n";
	    }
	    close(IN);
	    close(OUT);
#	}
#	$i++;
    }
}

sub calc_td_recv_throughput {
    local(@file2) = @_;
    local($d, $t, $start_d, $next_t, $time, $t_time, $throughput);
    $seq="seq";
    $ack="ack";
    $i = 0;
    foreach (@file2) {
#	if ($tcp_trace[$i] eq "ON") {
	    open(IN, "$_.$td_recv_input_ex")         || die "Can't open   $_.$td_recv_input_ex: $!\n";
	    open(OUT, "> $_.$td_recv_throughput_ex") || die "Can't create $_.$td_recv_throughput_ex: $!\n";
	    $file_name = $_;

	    $_=<IN>;
	    &get_column2($_);
	    if ($col2{"seq"} eq "") {$seq = "th_seq";}
	    if ($col2{"ack"} eq "") {$ack = "th_ack";}

	    $_ = <IN>;
	    &getword($_);

	    $d       = $word[$col2{$seq}];
	    $t       = $word[$col2{"td_time"}];
	    $start_d = $word[$col2{$seq}];
	    $start_d = $word[$col2{"td_time"}];
	    &dprint(2, "$d\t$t");
	    &dprint(2, $word[$col2{$seq}].":".$word[$col2{"td_time"}]);

	    $next_t = int($word[$col2{"td_time"}]/$time + 1)*$time;
	    foreach $_ (<IN>) {
		&getword($_);
		&dprint(2, $word[$col2{$seq}].":".$word[$col2{"td_time"}]);
		
		if ($word[$col2{"td_time"}] > $next_t && $word[$col2{"td_time"}] > $t) {
		    if ($word[$col2{"td_time"}] > $next_t+$time) {
			while($word[$col2{"td_time"}] > $next_t) {
#		        $throughput = (($d - $d) / ($next_t - $t) * 8 / (1000 * 1000));
			    $throughput = 0.0;
#		        $t_time = ($next_t + $t)/2.0;
			    $t_time = $next_t;
			    print OUT "$t_time $throughput $next_t $t\n";
			    $t = $next_t;
			    $next_t = $next_t + $time;
			}
		    }
		    else {
			$throughput = (($word[$col2{$seq}] - $d) / ($word[$col2{"td_time"}] - $t) * 8 / (1000 * 1000));
#		    $t_time = ($word[$col2{"td_time"}] + $t)/2.0;
			$t_time = $next_t;
			if ($throughput >= 0) {    #not lost
			    print OUT "$t_time $throughput ", $word[$col2{"td_time"}], " $t\n";
			}
			$d = $word[$col2{$seq}];
			$t = $word[$col2{"td_time"}];
			$next_t = $next_t + $time;
		    }
		}
	    }
	    if (($t - $start_t) !=0) {
		$throughput = (($d - $start_d) / ($t - $start_t) * 8 / (1000 * 1000));
		printf stderr "$file_name Recv: Mean Throughput %10.4f Mbps\n", $throughput;
	    }
	    else {
		printf stderr "$file_name Recv: Mean Throughput ERROR\n";
	    }
	    close(IN);
	    close(OUT);
#	}
#	$i++;
    }
}

sub calc_td_rtt {
    local(@file1) = @_;
    local($n1, $n2, $i1, $i2, $allrtt, $allrto);
    $seq="seq";
    $ack="ack";
    $i = 0;
    foreach (@file1) {
#	if ($tcp_trace[$i] eq "ON") {
	    $file_name = $_;
	    open(INO, "$_.$td_send_output_ex")|| die "Can't open   $_.$td_send_output_ex: $!\n";
	    open(INI, "$_.$td_send_input_ex") || die "Can't open   $_.$td_send_input_ex: $!\n";
	    open(RRTT, "> $_.$td_send_rrtt_ex") || die "Can't create $_.$_td_send_rrtt_ex: $!\n";
	    open(MRTT, "> $_.$td_send_mrtt_ex") || die "Can't create $_.$_td_send_mrtt_ex: $!\n";

	    $allrtt = 0;
	    $allrto = 0;

	    $_=<INO>;
	    &get_column2($_);
	    if ($col2{"seq"} eq "") {$seq = "th_seq";}
	    if ($col2{"ack"} eq "") {$ack = "th_ack";}

	    $n1 = 0;

	    $_= <INO>;
	    &getword($_);

	    $seq0 = $word[$col2{$seq}];

	    $s_d[$n1] = $word[$col2{$seq}] - $seq0;
	    $s_t[$n1] = $word[$col2{"td_time"}];
	    $n1++;

	    foreach $_ (<INO>) {
		&getword($_);

		$s_d[$n1] = $word[$col2{$seq}] - $seq0;
		$s_t[$n1] = $word[$col2{"td_time"}];
		$n1++;
	    }

	    $_=<INI>;
	    &get_column2($_);
	    $n21 =0;

	    $_=<INI>;
	    &getword($_);
	    $ack0      = $word[$col2{$ack}];

	    $a_d[$n21] = $word[$col2{$ack}] - $ack0;
	    $a_t[$n21] = $word[$col2{"td_time"}];
	    $mrto      = $word[$col2{"t_rxtcur"}]/2.0;
	    $mrtt      = $word[$col2{"t_rtt"}]/2.0;
	    $allrto    = $allrto + $rto;
	    print MRTT "$a_t[$n21] ", $mrtt, " ", $mrto , "\n";
	    $n21++;

	    foreach $_ (<INI>) {
		&getword($_);

		$a_d[$n21] = $word[$col2{$ack}] - $ack0;
		$a_t[$n21] = $word[$col2{"td_time"}];
		$mrto      = $word[$col2{"t_rxtcur"}]/2.0;
		$mrtt      = $word[$col2{"t_rtt"}]/2.0;
		$allrto    = $allrto + $mrto;
		print MRTT "$a_t[$n21] ", $mrtt, " ", $mrto , "\n";
		$n21++;
	    }

	    $n22 =0;
	    for ($i1=0, $i2=0; ($i1 < $n1) && ($i2 < $n1); $i1++) {
		while ($s_d[$i1] > $a_d[$i2] && $i2 <= $n1) {
		    $i2++;
		}
		if ($s_d[$i1] <= $a_d[$i2] && $i2 <= $n1) {
		    $rrtt = ($a_t[$i2] - $s_t[$i1]);
		    if ($rrtt > 0) {
			$allrtt = $allrtt + $rrtt;
			$n22++;
			print RRTT "$s_t[$i1] $rrtt $i1 $allrtt\n";
		    }
		}
	    }
#	    print stderr "for ($i1=0, $i2=0; ($i1 < $n21) && ($i2 < $n21); $i1++)", $s_t[$i1-1], "\n";
	    
	    if ($n22 == 0) {
		$n22 = 0.0000000000001;
	    }
	    if ($n21 == 0) {
		$n21 = 0.0000000000001;
	    }
	    $allrtt = $allrtt/$n22;
	    $allrto = $allrto/$n21;
	    printf stderr "$file_name: Mean RTT %10.6f s\n", $allrtt;
	    printf stderr "$file_name: Mean RTO %10.6f s\n", $allrto;
	    
	    close(INO);
	    close(INI);
	    close(RRTT);
	    close(MRTT);
#	}
#	$i++;
    }
}

sub td_lost {
    local(@file1) = @_;
    $i = 0;
    foreach $file_name (@file1) {
#	if ($tcp_trace[$i] eq "ON") {
	    $_ = $td_lost_flg;
	    if (/s/) {
		open(IN,  "$file_name.$td_send_output_ex") || die "Can't open   $file_name.$td_send_output_ex: $!\n";
		open(IN2, "$file_name.$td_send_output_ex") || die "Can't open   $file_name.$td_send_output_ex: $!\n";
		open(OUT, "> $file_name.$td_send_lost_ex") || die "Can't create $file_name.$td_send_lost_ex: $!\n";	# 
		&td_lost_sub(IN, IN2, OUT);
		close(IN);
		close(IN2);
		close(OUT);
	    }

	    $_ = $td_lost_flg;
	    if (/a/) {
		open(IN,  "$file_name.$td_recv_output_ex") || die "Can't open   $file_name.$td_recv_output_ex: $!\n"; # 
		open(IN2, "$file_name.$td_recv_output_ex") || die "Can't open   $file_name.$td_recv_output_ex: $!\n";
		open(OUT, "> $file_name.$td_recv_lost_ex") || die "Can't create $file_name.$td_recv_lost_ex: $!\n";
		&td_lost_sub(IN, IN2, OUT);
		close(IN);
		close(IN2);
		close(OUT);
	    }
#	}
#	$i++;
    }
}

sub td_lost_sub {
    local($in, $in2, $out) = @_;
    local($n, $n2, $seq1, $seq2);
	
    $null = <$in>;
    $null = <$in2>;
    &get_column2($null);
    if ($col2{"seq"} eq "") {$seq = "th_seq";}
    if ($col2{"ack"} eq "") {$ack = "th_ack";}

    $n    = 0;
    $n2   = 0;
    $seq1 = 0;

    $seq="seq";
    $ack="ack"; 
	
    foreach $_ (<$in>) {
	&getword($_);

	$seq2 = $word[$col2{$seq}];

	if ($seq1 >= $seq2) {
	    for (  ; $n2 <= $n; $n2++) { #      XXX same TCP packet retransmit
		$_ = <$in2>;
		&getword($_);
		
		if ($word[$col2{$seq}] == $seq2) {
		    printf $out "%10.6f, %10d, %10d\n",
		    $word[$col2{"td_time"}],
		    $word[$col2{$seq}],
		    $word[$col2{$ack}];
		    &dprint(1, "!lost!");
		}
	    }
	}

	$seq1 = $seq2;
	$n++;
    }
}

sub calc_td_delay {
    local(@file1) = @_;

    $i = 0;
    foreach $file_name (@file1) {
#	if ($tcp_trace[$i] eq "ON") {
	    $_ = $td_delay_flg;
	    if (/[sS]/) {
		open(INS, "$file_name.$td_send_output_ex")  || die "Can't open   $file_name.$td_send_output_ex: $!\n";
		open(INR, "$file_name.$td_recv_input_ex")   || die "Can't open   $file_name.$td_recv_input_ex: $!\n";
		open(OUT, "> $file_name.$td_send_delay_ex") || die "Can't create $file_name.$td_send_delay_ex: $!\n";
		&calc_td_delay_sub(INS, INR, OUT, "seq");
		close(INS);
		close(INR);
		close(OUT);
	    }

	    $_ = $td_delay_flg;
	    if (/[aA]/) {
		open(INS, "$file_name.$td_recv_output_ex")  || die "Can't open   $file_name.$td_recv_output_ex: $!\n";
		open(INR, "$file_name.$td_send_input_ex")   || die "Can't open   $file_name.$td_send_input_ex: $!\n";
		open(OUT, "> $file_name.$td_recv_delay_ex") || die "Can't create $file_name.$td_recv_delay_ex: $!\n";
		&calc_td_delay_sub(INS, INR, OUT, "ack");
		close(INS);
		close(INR);
		close(OUT);
	    }
#	}
#	$i++;
    }
}

sub calc_td_delay_sub {
    local($ins, $inr, $out, $seq_ack) = @_;
    local($n, $n2, $seq1, $seq2);
	
    $next = 0;
    $r_seq= -1;
    $null = <$ins>;
    $null = <$inr>;
    &get_column2($null);

    if ($seq_ack eq "seq") {
	if ($col2{"seq"} eq "") {
	    $seq = "th_seq";
	}
	else {
	    $seq  = "seq";
	}
    }
    else {
	if ($col2{"ack"} eq "")	{
	    $seq = "th_ack";
	}
	else {
	    $seq  = "ack";
	}
    }

    while () {
	$_ =<$ins>;
	if ($_ == EOF) {
	    return;
	}
	&getword($_);
	$s_seq  = $word[$col2{$seq}];
	$s_time = $word[$col2{"td_time"}];

	$_ = <$inr>;
	if ($_ == EOF) {
	    return;
	}
	&getword($_);
	$r_seq  = $word[$col2{$seq}];
	$r_time = $word[$col2{"td_time"}];
	$r_len  = $word[$col2{"len"}];

	while ($s_seq < $next) {
	    $_=<$ins>;
	    if ($_ == EOF) {
		return;
	    }
	    &getword($_);
	    $s_seq  = $word[$col2{$seq}];
	    $s_time = $word[$col2{"td_time"}];
	}

	while ($s_seq > $r_seq){
	    $_ = <$inr>;
	    if ($_ == EOF) {
		return;
	    }
	    &getword($_);
	    $r_seq  = $word[$col2{$seq}];
	    $r_time = $word[$col2{"td_time"}];
	    $r_len  = $word[$col2{"len"}];
	    &dprint(1,"($r_seq $r_time $r_len)");
	}

	while ($s_seq > $r_seq) {
	    $_=<$ins>;
	    if ($_ == EOF) {
		return;
	    }
	    &getword($_);
	    $s_seq  = $word[$col2{$seq}];
	    $s_time = $word[$col2{"td_time"}];
	}

	$delay = $r_time - $s_time;
	printf $out "%10d %10.6f %10.6f %10.6f\n", $s_seq , $delay, $s_time, $r_time;
	&dprint(1, "$s_seq , $delay, $s_time, $r_time");
	$next = $r_seq + $r_len;
    }
}


sub calc_td_jitter {
    local(@file1) = @_;

    $i = 0;
    foreach $file_name (@file1) {
#	if ($tcp_trace[$i] eq "ON") {
	    $_ = $td_jitter_flg;
	    if (/[sS]/) {
		open(IN, "$file_name.$td_send_output_ex")    || die "Can't open   $file_name.$td_send_output_ex: $!\n";
		open(OUT, "> $file_name.$td_send_jitter_ex") || die "Can't create $file_name.$td_send_jitter_ex: $!\n";
		&calc_td_jitter_sub(IN, OUT);
		close(IN);
		close(OUT);
	    }

	    $_ = $td_jitter_flg;
	    if (/[rR]/) {
		open(IN, "$file_name.$td_recv_input_ex")     || die "Can't open   $file_name.$td_recv_input_ex: $!\n";
		open(OUT, "> $file_name.$td_recv_jitter_ex") || die "Can't create $file_name.$td_recv_jitter_ex: $!\n";
		&calc_td_jitter_sub(IN, OUT);
		close(IN);
		close(OUT);
	    }
#	}
#	$i++;
    }
}

sub calc_td_jitter_sub {
    local($in, $out) = @_;
    local($jitter, $n, $s2, $t1, $t2, $sum);

    $n = 0.00000001;
    $sum = 0;
    $_=<$in>;
    &get_column2($_);
	    
    $_ = <$in>;
    &getword($_);
    
    $t1 = $word[$col2{"td_time"}];
    $i = 0;
    foreach $_ (<$in>) {
#	if ($tcp_trace[$i] eq "ON") {
	    &getword($_);
	    $s2 = $word[$col2{"th_seq"}];
	    $t2 = $word[$col2{"td_time"}];
	    $jitter = $t2 - $t1;
	    $sum = $sum + $jitter;
	    $n++;
	    print $out "$t2 $jitter $s2\n";
	    $t1 = $t2;
#	}
	$mean = $sum / $n;

	print $out "Mean Jitter = $mean\n";
#	$i++
    }
}


######################################################################
# Argument
######################################################################
sub input_sub {
    local($inp) = @_;

    $tmp = "";
    $tmp = shift;
    print "tmp=$tmp\n";
    print "$tmp ne $inp";
    if ($tmp ne $inp) {
	print stderr "Argument Error $arg\n";
	exit;
    }
    $tmp;
}

sub Argument_Check {
    $i=0;
    while($arg = shift) {
#	print "$arg\n";
	if ($arg eq "-f") {
	    $flag = "ON";
	    $files[$i++] = shift;
        }
	elsif ($arg eq "-a") {
	    $area = shift;
	    $flag = "OFF";
	}
	elsif ($arg eq "-d") {
	    $debug++;
	    $flag = "OFF";
	}
	elsif ($arg eq "-t") {
	    $time = shift;
	    $flag = "OFF";
	}
	elsif ($arg eq "-p") {
	    $process_flg = "ON";
	    $flag = "OFF";
	}
	elsif ($arg eq "-pp") {
	    $process_flg = "ON";
	    $output_flg  = "OFF";
	    $flag = "OFF";
	}
	elsif ($arg eq "-sq") {
	    $_ = $sq_flg  = shift;
	    if (/[^srSRuU]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-sd") {
	    $_ = $sd_flg  = shift;
	    if (/[^srSRuU]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-th") {
	    $_ = $th_flg  = shift;
	    if (/[^srSRtT]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-dth") {
	    $_ = $dth_flg  = shift;
	    if (/[^srSRtT]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-delay") {
	    $delay_flg = "ON";
	    $flag = "OFF";
	}
	elsif ($arg eq "-jitter") {
	    $_ = $jitter_flg  = shift;
	    if (/[^srSR]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-tsq") {
	    $_ = $td_sq_flg = shift;
	    if (/[^sralSRAL]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-tth") {
	    $_ = $td_th_flg = shift;
	    if (/[^sr]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-twin") {
	    $_ = $td_win_flg = shift;
	    if (/[^ws]+/) {
		$flag = "OFF";
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";	    
	}
	elsif ($arg eq "-tlost") {
	    $_ = $td_lost_flg = shift;
	    if (/[^sa]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-trtt") {
	    $_ = $td_rtt_flg = shift;
	    if (/[^rmo]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-tdelay") {
	    $_ = $td_delay_flg = shift;
	    if (/[^sa]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-tjitter") {
	    $_ = $td_jitter_flg = shift;
	    if (/[^srSR]+/) {
		print stderr "Argument Error $arg $_\n";
		exit;
	    }
	    $flag = "OFF";
	}
	elsif ($arg eq "-ulost") {
	    $u_lost_flg = "ON";
	    $flag = "OFF";
	}
	elsif ($arg eq "-ps") {
	    $ps_flg  = ON;
	    $flag = "OFF";
	}
	elsif ($arg eq "-eps") {
	    $eps_flg  = ON;
	    $flag = "OFF";
	}	
	elsif ($arg eq "-color") {
	    $color_flg  = ON;
	    $flag = "OFF";
	}
	elsif ($arg eq "-title") {
	    $title_n = shift;
	    $flag = "OFF";
	}
	elsif ($flag eq "ON") {
	    $files[$i++] = $arg;
        }
	else {
	    print stderr "Argument Error $arg\n";
	    exit;
	}
    }
}

######################################################################
# help
######################################################################
sub help {
    print stderr "dbs_view Ver. 1.1.4\n";
    print stderr "              <yukio-m\@is.aist-nara.ac.jp>\n";
    print stderr "Options\n";
    print stderr "-f  file file ... : Command File Name\n";
    print stderr "-a       area      : Graph Area\n";
    print stderr "-sq      [s|r|u]   : Draw Sequence(Send, Receive, UDP Lost)\n";
    print stderr "-sd      [s|r|u]   : Draw Sequence + Data length(Send, Receive, UDP Lost)\n";
    print stderr "-th      [s|r|t]   : Draw Throughput(Send, Receive, Total)\n";
    print stderr "-dth     [s|r]     : Draw Throughput(bps/data)\n";
    print stderr "-delay             : Draw Delay time\n";
    print stderr "-jitter  [s|r|S|R] : Draw Jitter\n";
    print stderr "-tsq     [s|r|a|l] : Draw tcp_debug Sequence,(Send, Receive, Ack, Lost)\n";
    print stderr "-tth     [s|r]     : Draw tcp_debug Throughput,(Send, Receive)\n";
    print stderr "-twin    [w|s]     : Draw tcp_debug Wnidow,(Congestion Window, Shreshold)\n";
    print stderr "-tlost   [s|a]     : Draw tcp_debug Lost(Send, Ack)\n";
    print stderr "-trtt    [r|m|o]   : Draw Round Trip Time (Real RTT, Measured RTT, RTO)\n";
    print stderr "-tdelay  [s|a]     : Draw Delay Time\n";
    print stderr "-tjitter [s|r|S|R] : Draw Jitter\n";
    print stderr "-ulost             : Search UDP Lost\n";
    print stderr "-t      time(sec)  : Time Resolution of Throughput\n";
    print stderr "-p                 : Processing(Delay or Throughput)\n";
    print stderr "-ps                : Output PostScript\n";
    print stderr "-eps               : Output EPS\n";
    print stderr "-color             : Output Color PS or EPS\n";
    print stderr "-title #           : title #'th column\n";
}


syntax highlighted by Code2HTML, v. 0.9.1