tg.pl


#!/usr/bin/perl -w
# ---------------------------------------------------------
# tg.pl (v 0.1) : Traffic Generator;
# based on Loris Degioanni's Tg program in C
# (see the Packet Capture Driver Developer's Pack).
# This simple example shows how to send raw packets
# to the network using Win32::NetPacket.
# This program is free software; you can redistribute it
# and/or modify it under the same terms as Perl itself.
# (c) 2003 J-L Morel jlmorel@cpan.org
# ---------------------------------------------------------

use strict;
use Win32::NetPacket qw/ GetAdapterNames  /;
use Getopt::Std;

print "Traffic Generator v 0.1\n";
print "Sends a set of packets to the network.\n";
if ( !@ARGV ) {
  print "Usage: tg [-i adapter] -n npacks -s size\n";
  print "size is between 60 and 1514\n\n";
  exit;
}

# get options
getopts("i:n:s:");
our ( $opt_i, $opt_n, $opt_s );
my @adpts = GetAdapterNames();
@adpts > 0 or die "No adapter installed !\n";
my $i = 1;
if ($opt_i) {
  unless ( $opt_i =~ /^(\d)+$/ and 0 < $opt_i and $opt_i <= @adpts ) {
    print "No adapter #$opt_i\n";
    exit -1;
  }
  $i = $opt_i;
}
else {
  if ( @adpts > 1 ) {
    print "Adapters installed:\n\n";
    print $i++, " - $_\n" foreach @adpts;
    do {
      print "\nSelect the number of the adapter to open : ";
      $i = <STDIN>;
      chomp $i;
    } until ( $i =~ /^(\d)+$/ and 0 < $i and $i <= @adpts );
  }
}

if ($opt_n) {
  unless ( $opt_n =~ /^(\d)+$/ ) {
    print "Bad value \"$opt_n\" for option -n\n";
    exit -1;
  }
}
$opt_n ||= 1;

if ($opt_s) {
  unless ( $opt_s =~ /^(\d)+$/ ) {
    print "Bad value \"$opt_n\" for option -s\n";
    exit -1;
  }
}
$opt_s ||= 60;

# open the selected adapter
my $nic = Win32::NetPacket->new( adapter_name => $adpts[ $i - 1 ], )
  or die $@;

# set the number of times the write must be repeated.
$nic->SetNumWrites($opt_n);

# set Packet buffer
my $Packet = pack "C6C6C$opt_s", 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
  map { $_ % 256 } ( 12 .. $opt_s + 11 );

# send packets
my $cpu_time = Win32::GetTickCount();
if ( not $nic->SendPacket($Packet) ) {
  print "Error sending the packets!\n";
  exit -1;
}

# compute elapsed time in seconds
$cpu_time = ( Win32::GetTickCount() - $cpu_time ) / 1000;

# Resolution is limited to about 10ms on WinNT and 55ms on Win9X
$cpu_time = Win32::IsWinNT() ? 0.01 : 0.055 unless $cpu_time;

# print report
printf "\n\nElapsed time: %5.3f s\n", $cpu_time;
printf "\nTotal packets generated = $opt_n";
printf "\nTotal bytes generated = %d", ( $opt_s + 24 ) * $opt_n;
printf "\nTotal bits generated = %d",  ( $opt_s + 24 ) * $opt_n * 8;
printf "\nAverage packets per second = %d", $opt_n / $cpu_time;
printf "\nAverage bytes per second = %d",
  ( $opt_s + 24 ) * $opt_n / $cpu_time;
printf "\nAverage bits per second = %d\n",
  ( $opt_s + 24 ) * $opt_n * 8 / $cpu_time;