#!/usr/bin/perl
##=========================================================================
# NOM         : scanport
# DESCRIPTION : scanne les ports ouverts
# CATEGORIE   : netutil
# LANGAGE     : perl
# AUTEUR      : Jean-Louis Bicquelet Salaün
# DATE        : 14/02/2022
# VERSION     : 1.0
#=========================================================================
#
# TCP Port scanner
# #
# Exemples: 
# 
#  1. scan si le port ssh du serveur 192.168.1.10 est ouvert
#
#  scanport 192.168.1.10
#  Port 22 on 192.168.1.10 is open
#
#  2. scan si le port vnc du serveur 192.168.1.24 est ouvert
#
#  scanport 192.168.1.24 5900
#  Port 192.168.1.24 on 5900 is NOT open
#
#  3. scan l'ordinateur local pour les ports ouverts jusqu'a 1024
#
#  scanport 127.0.0.1 1 1024 | grep -v NOT
#
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

#.........................................................................
# parametre modifiables
# TIMEOUT : timeout en seconde
# PORT_DEFAUT: port par defaut
#.........................................................................

$TIMEOUT=1;
$PORT_DEFAUT=22;
#$PORT_DEFAUT=9100;

#--------------------------------------------------------------
# recupere les variables passees en arguments pour generer
# un tableau @commands et recuperer le nombre d'arguments 
# passes dans count
#--------------------------------------------------------------
sub split_argv
{
   $count = 0;
   while($ARGV[$count])
   {
       push @commands, $ARGV[$count];
       $count++;
   }
}

#--------------------------------------------------------------
#
#--------------------------------------------------------------
sub usage
{
        print << '__HELP__';

usage:

  version 1.2, 14/02/2022

  scanport [-h|--help|-m|--man] [IP_adress] [port| port_mon port_max]

Options:
  -h,         --help                  usage
  -m,         --man                   man

__HELP__
;
   exit 0;
}

#--------------------------------------------------------------
#--------------------------------------------------------------
sub set_vars
{
   if (($ARGV[0] eq "-h") || ($ARGV[0] eq "--usage")) { usage(); exit ;}
   if($count==0) {   usage(); }

   if (($ARGV[0] eq "-m") || ($ARGV[0] eq "--man")) { system ("perldoc $0"); exit ;}

   $target=@commands[0];
   $port=$PORT_DEFAUT;
   $maxport=$PORT_DEFAUT;

   if($count==2)
   {
      $target=@commands[0];
      $port=@commands[1];
      $maxport=$port;
   }
   if($count==3)
   {
      $target=@commands[0];
      $port=@commands[1];
      $maxport=@commands[2];
   }
}

#==============================================================

#..............................................................
# utilise IO::Socket afin de permettre la gestion du timeout
#..............................................................
use IO::Socket;

#..............................................................
# prepare les variables en fonction des entrees
#..............................................................
split_argv();
set_vars();

#..............................................................
# scan des ports
#..............................................................
my ( $daddr );
{

  $daddr = inet_aton($target) || die("Failed to locate target host: $target");

   if($count<=2) {  
      print "Port $port on $target ";
   }
   
   if($count==3) {  
       print "================================================================\n";
       print "Scanning $target on ports $port-$maxport\n";
       print "================================================================\n";
  }

  foreach (; $port<=$maxport; $port++) {
	if( IO::Socket::INET->new(PeerAddr=>"$target:$port",Proto=>'tcp',Timeout=>$TIMEOUT))
        {
           if($count==3) {  
              print "Port $port is open\n" ;
           }
           if($count<=2) {  
              print "is open\n" ;
           }
        }
        else{
           if($count==3) {  
               print "Port $port is NOT open\n";
           }
           if($count<=2) {  
               print "is NOT open\n" ;
           }
       }
    }
}
__END__

=head1 NOM

  scanport - scan un port ou une plage de port pour un serveur

=head1 SYNOPSIS

  scanport [-h|--help|-m|--man] [IP_adress] [port| port_mon port_max]

=head1 DESCRIPTION

  scan si un port ou une plage de ports est ouvert[s] pour une adresse IP donnee

  Le port scanne  par defaut est 22 (ssh).

=head1 EXEMPLE

  1. scan si le port ssh du serveur 192.168.1.10 est ouvert

  scanport 192.168.1.10
  Port 22 on 192.168.1.10 is open

  2. scan si le port vnc du serveur 192.168.1.24 est ouvert

  scanport 192.168.1.24 5900
  Port 192.168.1.24 on 5900 is NOT open

  3. scan l'ordinateur local pour les ports ouverts jusqu'a 1024

  scanport 127.0.0.1 1 1024 | grep -v NOT

  ================================================================
  Scanning 127.0.0.1 on ports 1-1024
  ================================================================
  Port 22 is open
  Port 80 is open
  Port 631 is open

=head1 AUTEUR
 
  jean-Louis Bicquelet <jlbicquelet@free.fr>

  http://jlbicquelet.free.fr

=head1 VERSION

  version 1.2 14/02/2022

=head1 VOIR AUSSI

  /etc/services pour la liste des services

=cut
