Hello Monks, I just recently started trying to learn IO::Socket and networking in Perl stuff. I did this simple port scanner (for security purposes only), I would would be most grateful if you could give me suggestions on parts of the code that need improving. Thanks!

Code below...
#!/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


In reply to Suggestions & Improvements on a portscanner using IO::Socket by czarfred

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.