ttcp.exe

まだまだ書きかけ。

概要

ttcp.exe はネットワークパフォーマンスを測定するツール。マイクロソフトが作っている。

この文書の対象範囲

この手のパフォーマンス測定プログラムは多く存在する(別のttcp, netperf, PCATTCP, WSTTCP, 他)が存在するが、ここで取り上げるのはマイクロソフトが作成している ttcp.exe についてである。

入手方法

Windows2000の場合

Microsoft IPv6 Technology Preview for Windows 2000 に入っている。これをインストールすればいいらしい。なお、このプログラムは他のOSにはインストールできない。

Windows2003の場合
  • OSのCD-ROMの\VALUEADD\MSFT\NET\TOOLSというフォルダにTTCP.EXEが存在するらしい
Windows XP Professionalの場合
  • OSのCD-ROMの\VALUEADD\MSFT\NET\TOOLSというフォルダにTTCP.EXEが存在するらしい
  • Windows XPService Pack 1のCD-ROMなどにも含まれているらしい

他の方法を調査中。

使用方法

調査中。

sniffer.pl

かつて作ったものをアップロード。実行結果は http://d.hatena.ne.jp/wabix/20030923#p1 を参照されたし。

#!/usr/bin/perl
# Author: Takuma WABIKO
# All copyrights reserved.

use strict;
use warnings;
use Net::PcapUtils;
use NetPacket::Ethernet qw(:types);
use NetPacket::ARP qw(:opcodes);
use NetPacket::IP qw(:protos);
use NetPacket::ICMP qw(:ALL);
use NetPacket::TCP;
use NetPacket::UDP;
use Socket;

my $debug = 1;

sub debug_print { print STDERR shift if $debug }

sub hexdump {
        my $binary = shift;

        my $address = 0;
        while ( $binary ) {

                my $hex;
                ( $hex, $binary ) = unpack 'H32a*', $binary;

                my @columns = $hex =~ /../g;

                my $readable;
                for ( @columns ) { $readable .= pack( 'H2', $_ ) }
                $readable =~ s/[^[:print:] ]/./g;

                for ( 1 .. 15 ) { $columns[$_] ||= '  ' }

                printf '%07x0  '. '%s ' x 8 . '- '. '%s ' x 8 .' %s'. "\n",
                        $address, @columns, $readable;

                $address++;
        }
}

sub process_icmp {
        my ( $user_data, $header, $raw_pkt, $payload ) = @_;

        my %icmp_types = (
                ICMP_ECHOREPLY, 'echoreply',
                ICMP_UNREACH, 'unreach',
                ICMP_SOURCEQUENCH, 'sourcequench',
                ICMP_REDIRECT, 'redirect',
                ICMP_ECHO, 'echo',
                ICMP_ROUTERADVERT, 'routeradvert',
                ICMP_ROUTERSOLICIT, 'routersolicit',
                ICMP_TIMXCEED, 'timxceed',
                ICMP_PARAMPROB, 'paramprob',
                ICMP_TSTAMP, 'tstamp',
                ICMP_TSTAMPREPLY, 'tstampreply',
                ICMP_IREQ, 'ireq',
                ICMP_IREQREPLY, 'ireqreply',
                ICMP_MASKREQ, 'masreq',
                ICMP_MASKREPLY, 'maskreply',
        );

        my $icmp_obj = NetPacket::ICMP->decode( $payload );
        print "[ICMP]\n";
        print "type: ", $icmp_types{ $icmp_obj->{type} } || $icmp_obj->{type}, "\n";
        print "code: $icmp_obj->{code}\n";
        print "cksum: $icmp_obj->{cksum}\n";
        hexdump( $icmp_obj->{data} );
        print "\n";
}

sub process_tcp {
        my ( $user_data, $header, $raw_pkt, $payload ) = @_;

        my $tcp_obj = NetPacket::TCP->decode( $payload );
        print "[TCP]\n";
        print "src_port: $tcp_obj->{src_port}\n";
        print "dest_port: $tcp_obj->{dest_port}\n";
        print "seqnum: $tcp_obj->{seqnum}\n";
        print "acknum: $tcp_obj->{acknum}\n";
        print "urg: $tcp_obj->{urg}\n";
        print "cksum: $tcp_obj->{cksum}\n";
        hexdump( $tcp_obj->{data} );
        print "\n";
}

sub process_udp {
        my ( $user_data, $header, $raw_pkt, $payload ) = @_;

        my $udp_obj = NetPacket::UDP->decode( $payload );
        print "[UDP]\n";
        print "src_port: $udp_obj->{src_port}\n";
        print "dest_port: $udp_obj->{dest_port}\n";
        print "len: $udp_obj->{len}\n";
        print "cksum: $udp_obj->{cksum}\n";
        hexdump( $udp_obj->{data} );
        print "\n";
}

sub process_ip {
        my ( $user_data, $header, $raw_pkt, $payload ) = @_;

        my $ip_obj = NetPacket::IP->decode( $payload );
        print "[IP]\n";
        print "len: $ip_obj->{len}\n";
        print "ttl: $ip_obj->{ttl}\n";
        print "proto: $ip_obj->{proto}\n";
        print "cksum: $ip_obj->{cksum}\n";
        print "src_ip: $ip_obj->{src_ip}\n";
        print "dest_ip: $ip_obj->{dest_ip}\n";
        print "\n";

        if ( $ip_obj->{proto} eq IP_PROTO_ICMP ) {
                process_icmp( $user_data, $header, $raw_pkt, $ip_obj->{data} );
        } elsif ( $ip_obj->{proto} eq IP_PROTO_TCP ) {
                process_tcp( $user_data, $header, $raw_pkt, $ip_obj->{data} );
        } elsif ( $ip_obj->{proto} eq IP_PROTO_UDP ) {
                process_udp( $user_data, $header, $raw_pkt, $ip_obj->{data} );
        } else {
                hexdump( $ip_obj->{data} );
        }
}

sub process_arp {
        my ( $user_data, $header, $raw_pkt, $payload ) = @_;

        my %opcodes = (
                ARP_OPCODE_REQUEST, 'arp opcode request',
                ARP_OPCODE_REPLY, 'arp opcode reply',
                RARP_OPCODE_REQUEST, 'rarp opcode request',
                RARP_OPCODE_REPLY, 'rarp opcode reply',
        );

        my $arp_obj = NetPacket::ARP->decode( $payload );
        print "[ARP]";
        print "htype: $arp_obj->{htype}\n";
        print "proto: $arp_obj->{proto}\n";
        print "hlen: $arp_obj->{hlen}\n";
        print "plen: $arp_obj->{plen}\n";
        print "opcode: ", $opcodes{ $arp_obj->{opcode} } || $arp_obj->{opcode}, "\n";
        print "sha: $arp_obj->{sha}\n";
        print "spa: $arp_obj->{spa}\n";
        print "tha: $arp_obj->{tha}\n";
        print "tpa: $arp_obj->{tpa}\n";
        print "\n";
}

sub process_ethernet {
        my ( $user_data, $header, $raw_pkt, $payload ) = @_;

        my $eth_obj = NetPacket::Ethernet->decode( $payload );
        print "[Ethernet]\n";
        print "src_mac: ", join( ':', $eth_obj->{src_mac} =~ /../g) ,"\n";
        print "dest_mac: ", join( ':', $eth_obj->{dest_mac} =~ /../g) ,"\n";
        print "type: $eth_obj->{type}\n";
        print "\n";

        if ( $eth_obj->{type} eq ETH_TYPE_IP ) {
                process_ip( $user_data, $header, $raw_pkt, $eth_obj->{data} );
        } elsif ( $eth_obj->{type} eq ETH_TYPE_ARP ) {
                process_arp( $user_data, $header, $raw_pkt, $eth_obj->{data} );
        } else {
                hexdump( $eth_obj->{data} );
        }

        print "\n";
};

sub process_pkt {
        print '-'x20, "\n";
        process_ethernet( @_, $_[2] );
}

######################################################################
# Main program

#my $device = 'rl1';
my $device = 'rl2';
Net::PcapUtils::loop( \&process_pkt, DEV => $device ) or die;

__END__