#!/usr/bin/perl

use Getopt::Std;
use threads;
use strict;
use warnings;

my $nb_threads = $ARGV[0];
my $nb_requests_per_thread = $ARGV[1];

die "Radius calls: please specify the number of threads and the number of requests per thread on the command line" if (!($nb_threads && $nb_requests_per_thread));

print "about to launch $nb_threads threads sending each $nb_requests_per_thread radius calls...\n";

# worker launcher
my @threads;
for (my $i = 0; $i<$nb_threads; $i++) {

  # create the thread
  push @threads, threads->create( \&radius_requests, $i);
}

# wait for everyone
foreach my $thread (@threads) {
  $thread->join();
}

sub radius_requests {

  my ($tid) = @_;
  my $fun_factor = int(rand(10000));
  my $fake_mac_for_thread = sprintf("%04x", $fun_factor % 65536);

  for(my $i=0; $i<$nb_requests_per_thread; $i++) {
  
    my $fake_client_mac = sprintf("%04x", $i % 65536); # generates fake last 4 digit of a MAC address based on $i
    my $fake_nas_port = ($fun_factor + $i) % 65536;

    print "thread $tid connection #$i: about to launch radius call with mac aabb.$fake_mac_for_thread.$fake_client_mac NAS-Port: $fake_nas_port\n";
    
    my $cmd = "echo \"User-Name = aabb$fake_mac_for_thread$fake_client_mac, Calling-Station-Id = aabb.$fake_mac_for_thread.$fake_client_mac, Cisco-AVPair=\\\"ssid=Inverse-Invite\\\", NAS-Port-Type = Wireless-802.11, NAS-Port = $fake_nas_port\" | radclient 192.168.1.60 auth sunglassesatnight 2>&1";

    eval {
      my $result = `$cmd`;
      if ($? != 0 || $result =~ /no response/) {
        print ("warning thread $tid connection #$i: something went wrong with the radius call. cmd: $cmd / result: $result");
      }
    };
    if ($@) {
      print ("warning thread $tid connection #$i mac aabb.ccdd.$fake_client_mac NOT successful: $@\n");
      next;
    }

  }
}

=head1 AUTHOR

Inverse inc. <info@inverse.ca>

=head1 COPYRIGHT

Copyright (C) 2005-2021 Inverse inc.

=head1 LICENSE

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
USA.

=cut

