8
\$\begingroup\$

Write the shortest program that will attempt to connect to open ports on a remote computer and check if they are open. (It's called a Port Scanner)

Take input from command line arguments.

your-port-scanner host_ip startPort endPort

Assume, startPort < endPort (and endPort - startPort < 1000)

Output: All the open ports between that range should space or comma seperated.

\$\endgroup\$
  • \$\begingroup\$ Are there any legal reasons to go about using port scanners? Except to stop other people hacking into your network by closing unnecessary ports? \$\endgroup\$ – Alexander Craggs Aug 23 '14 at 18:50
5
\$\begingroup\$

sh/netcat, 39

nc -vz $1 $2-$3 2>&1|cut -f3 -d\ |xargs

Netcat does the scanning and returns results in this form on standard error:

localhost [127.0.0.1] 22 (ssh) open
localhost [127.0.0.1] 25 (smtp) open

cut and xargs extract the port number and make a single line out of it.

Remind me to shut SMTP down on that node.

\$\endgroup\$
3
\$\begingroup\$

Perl, 92

$_='use I;$h=shift;grep I->new("$h:$_"),shift..shift';
s/I/IO::Socket::INET/g;@_=eval;say"@_"

Perl 5.10 or later, run with perl -E 'code here'.

Uses regexes to compress that long IO::Socket::INET, then eval; final formatting done with array interpolation.

By request, a more detailed explanation. To ungolf, let's first respace:

$_ = << 'EOC';
  use I;
  $h = shift;
  grep I->new("$h:$_"), shift..shift;
EOC
s/I/IO::Socket::INET/g;
@_ = eval;
say "@_";

The line before the eval replaces all (two) occurences of 'I' with 'IO::Socket::INET', that's a standard Perl golfing trick to reduce the impact of unavoidable long identifiers. Naming a few of the temporaries, the code is then equivalent to this:

use IO::Socket::INET;
$h = shift;
$p1 = shift;
$p2 = shift;
@_ = grep IO::Socket::INET->new("$h:$_"), ($p1 .. $p2);
say "@_";

In a nutshell: read host and port range arguments from the command line; attempt a connection to all of them in sequence (IO::Socket::INET->new()); keep a list of those who succeeded (grep); display the result nicely (say).

\$\endgroup\$
  • \$\begingroup\$ cant understand somehow :( looks like deepest black magic for me :P but still a +1 for weirdness \$\endgroup\$ – masterX244 Mar 4 '14 at 19:36
  • \$\begingroup\$ @masterX244 I've detailed the innards a bit. HTH \$\endgroup\$ – J B Mar 5 '14 at 9:53
1
\$\begingroup\$

sh/nmap/GNU grep/xargs - 36

nmap -p$2-$3 $1|grep -Po '^\d+'|xargs

Follows input and output specs:

$ sh 1109.sh 127.0.0.1 1 80
22 25 80
\$\endgroup\$
  • 2
    \$\begingroup\$ I don't know if nmap counts as a valid answer here, but it is definitely not sh :) \$\endgroup\$ – Eelvex Feb 21 '11 at 15:15
  • \$\begingroup\$ The output format could also use a little polishing. \$\endgroup\$ – J B Feb 21 '11 at 16:26
  • 2
    \$\begingroup\$ @Eelvex that's a sh script, with a your-port-scanner host_ip startPort endPort interface, calling nmap ;-) \$\endgroup\$ – Arnaud Le Blanc Feb 21 '11 at 16:41
  • \$\begingroup\$ @J B, done :-) __ \$\endgroup\$ – Arnaud Le Blanc Feb 21 '11 at 16:50
  • \$\begingroup\$ does nmap come bundled with linux? :-\ i didn't know that... :( \$\endgroup\$ – st0le Feb 22 '11 at 5:10
1
\$\begingroup\$

Ruby - 85

require"socket"
h,p,e=$*
p.upto(e){|p|begin
TCPSocket.new h,p
$><<"#{p} "
rescue
end}
\$\endgroup\$
1
\$\begingroup\$

BASH - 105

In pure BASH (i.e no nmap or netcat).

exec 2>&- && exec 2<> /dev/null
for p in $(seq $2 $3); do
    > /dev/tcp/$1/$p &&
    echo -n "$p "
done

When using with an address other than localhost the timeout is quite long (in the order of minutes) when encountering a closed port so some sort of timeout/alarm function would be required in all likelihood.

\$\endgroup\$
0
\$\begingroup\$

PHP - 70

<?for(list(,$h,$p,$e)=$argv;$p<=$e;++$p)@fsockopen($h,$p)&&print"$p ";
\$\endgroup\$
  • \$\begingroup\$ i'm sure you can squeeze the $p++ in other mention of $p, will save one char... \$\endgroup\$ – st0le Feb 22 '11 at 5:16
0
\$\begingroup\$

Perl, 178

I'm new to Perl, any advice on shortening is appreciated!

use IO::Socket::INET;for($x=$ARGV[1];$x<$ARGV[2]+1;$x++){if(fork()){if($sock=new IO::Socket::INET(PeerAddr=>$ARGV[0],PeerPort=>$x,Proto=>'tcp')){print"$x ";}close($sock);exit;}} 
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.