czarfred has asked for the wisdom of the Perl Monks concerning the following question:
#!/usr/bin/perl -w # 5/6/02 # David Aslanian # nightelf@cableone.net use Getopt::Long; use IO::Socket::INET; use strict; ## options config my($port,$host,$proto,$help) = ('', '', 'tcp',''); ## proto defaults +to tcp GetOptions('ports|port=s' => \$port, 'host=s' => \$host, 'proto=s' => \$proto, 'help' => \$help) or die $!; die usage() if($help); ## validate and expand the port listing(s) in the --port option my @ports = expand_ports($port); ## validate options validate_opts($host, $proto); ######################################### ## main ######################################### my $sock; my @openports = (); my $i = -1; print "Scanning $host for open ports.....\n\n"; foreach my $cport (@ports) { $sock = IO::Socket::INET->new(PeerAddr => $host, PeerPort => $cport, Proto => $proto); if($sock) { $i++; $openports[$i] = $cport; } } print "Open ports on $host (using $proto):\n\t", join("\n\t", @openpor +ts), "\n"; ######################################### ## subs ######################################### sub validate_opts { my($host, $proto) = (shift, shift); ## validate $host ## no ports, proto spec, or file path in the hostname allowed ## below: this is not right #if(($host =~ /^(\w+\.)?\w+\.\w+$/i) || ($host =~ /^(\d{1,3}\.){3}(\d +{1,3})$/) || ($host =~ /^[a-z-]+$/) { # ## we're fine #} else { # die usage("Bad host specification."); #} ## validate protocol die usage("Bad protocol specification.") unless($proto =~ /^tcp$| +^udp$/); } sub expand_ports { ## input: string containing port information, c +ommas and ranges (1-10) can be used. ## output: a expanded, unique list of sorted ports ready t +o be used for scanning. my $port = shift; my @ports = (); my($from, $to); ## used for ranges (1-10) if($port =~ /^(\d+)$/) { ## just a plain port number alone $ports[0] = $1; return(@ports); } if($port =~ /^(\d+)-(\d+)$/) { ## a range of ports alone (not in +a comma-seperated list) return(@ports = ($1 .. $2)); } if($port =~ /^([\d-]+,)+([\d-]+),?$/) { ## a list possibly contai +ning ranges of ports my @splitted = split(',', $port); foreach my $splitted (@splitted) { if($splitted =~ /^(\d+)-(\d+)$/) { ## if it is a range of + ports push(@ports, ($1 .. $2)); next; } if($splitted =~ /^(\d+)$/) { push(@ports, $1); next; } ## if we get to this point in the iteration something went + wrong... die "bad port spec.\n"; } ### take out duplicate values from @ports my %seen = (); my @uniq = (); foreach my $item (@ports) { unless($seen{$item}) { ##if we get here we haven't seen it before $seen{$item} = 1; push(@uniq, $item); } } @ports = @uniq; ### sort the ports @ports = sort { $a <=> $b } @ports; ### .. and finally return the expanded, unique, sorted ports t +o the caller return @ports; } die usage("Bad or no port specification.\n"); } sub usage { my $message = shift; print "Fatal error: $message\n\n" if($message); ## only print an +error if there was one print <<ENDUSAGE; Usage: perlscan --host=<host> --ports=<ports> [--proto=tcp|udp] Options: --host, -h (ie --host=localhost) The hostname or ip adress to be scanned. --port, --ports, -po (ie --ports=1,2,3-30) The ports to be scanned. A single port can be specified (ie --port=1), or a single +range of ports can be specified (ie --ports=1-1024), or a list o +f ports and/or ranges can be specified (ie --ports=1,2,3-30). --proto, -pr (ie --proto=tcp) The protocol to use for the scan. This can be either tcp o +r udp, this option is optionable and can be omitted, in which cas +e the default protocol will be used (tcp). --help, -h (ie --help) Display this usage information. ENDUSAGE }
Edit kudra, 2002-05-07 Changed title
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Suggestions & Improvements
by rbc (Curate) on May 07, 2002 at 18:11 UTC | |
|
Re: Suggestions & Improvements
by ferrency (Deacon) on May 07, 2002 at 19:34 UTC | |
|
Re: Suggestions & Improvements
by Joost (Canon) on May 07, 2002 at 16:27 UTC | |
|
Re: Suggestions & Improvements
by Freddo (Acolyte) on May 08, 2002 at 09:04 UTC | |
by Anonymous Monk on May 08, 2002 at 09:43 UTC | |
by roboslug (Sexton) on May 08, 2002 at 13:27 UTC | |
by elwarren (Priest) on May 08, 2002 at 20:50 UTC | |
|
Re: Suggestions & Improvements on a portscanner using IO::Socket
by ChOas (Curate) on May 08, 2002 at 12:40 UTC | |
|
Re: Suggestions & Improvements
by czarfred (Beadle) on May 07, 2002 at 20:10 UTC | |
by roboslug (Sexton) on May 08, 2002 at 05:24 UTC |