M
Mark
Hello. I am attempting to write a simple program to scan ports to look for
Quake 3
servers. I adapted the code from the O'Reilly "Programming Perl" book.
The script is invoked with a starting and ending IP address and a port, as
follows:
perl q3_search.pl 207.210.230.5 207.210.230.10 27960
The script will usually scan a few addresses, and then it will hang.
The hangup occurs when attempting to read from the socket. This happens
whether
I treat the socket as a file handle (as in this example), or if I use the
recv() function.
Suggestions?
Thanks
-Mark
=======================================
#!/usr/bin/perl -w
# Q3_SEARCH.PL
#
# Based on "Programming Perl" p349
require 5.002;
use strict;
use Socket;
use Socket qwDEFAULT :crlf);
my ($ipfirst, $iplast, $remote, $port, $iaddr, $paddr, $proto, $line);
$ipfirst = shift;
if ($ipfirst !~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {die "Invalid IP
address as param #1";}
$iplast = shift;
if ($iplast !~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {die "Invalid IP
address as param #1";}
$port = shift || 27960; #Default Quake 3 Port
if ($port =~ /\D/) { $port = getserverbyname($port, 'udp')}
die "No port" unless $port;
$remote = $ipfirst;
my $exit_flag = 0;
while (1)
{
print "Testing $remote\.\.\.\n";
$iaddr = inet_aton($remote) or die "no host: $remote";
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('udp');
socket(SOCK, PF_INET, SOCK_DGRAM, $proto) or die "socket: $~";
connect(SOCK, $paddr) or die "connect: $~";
# Setting autoflush is supposed to help prevent blocking
# when attempting to read from the socket. . .
my $oldh = select(SOCK);$|=1;select($oldh);$|=1;
defined(send SOCK, "\xff\xff\xff\xffgetstatus", 0) || goto NEXT_IP;
# Select() is supposed to succeed if the socket has data,
# or else timeout and return FALSE.
if (!(select (SOCK, undef, undef, 10.0))) {goto NEXT_IP;}
# Script will eventually hang on the following line
if (!defined($line = <SOCK>)) {goto NEXT_IP;}
if ($line =~ "statusResponse")
{print " $remote:$port is active\n";
}
close (SOCK) or die "close: $~";
if ($exit_flag > 0) {last;}
NEXT_IP:
$remote = inc_ip_addr($remote);
if ($remote eq $iplast) {$exit_flag = 1;}
}
sub inc_ip_addr
{
my $ipaddr = shift;
my $newip = "";
$ipaddr =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
my $a = $1;
my $b = $2;
my $c = $3;
my $d = $4;
$d++;
if ($d > 255) {$d = 0; $c++;} else {goto INC_IP_EXIT;}
if ($c > 255) {$c = 0; $b++;} else {goto INC_IP_EXIT;}
if ($b > 255) {$b = 0; $a++;} else {goto INC_IP_EXIT;}
INC_IP_EXIT:
$newip = $a . "\." . $b . "\." . $c . "\." . $d; return $newip;
}
Quake 3
servers. I adapted the code from the O'Reilly "Programming Perl" book.
The script is invoked with a starting and ending IP address and a port, as
follows:
perl q3_search.pl 207.210.230.5 207.210.230.10 27960
The script will usually scan a few addresses, and then it will hang.
The hangup occurs when attempting to read from the socket. This happens
whether
I treat the socket as a file handle (as in this example), or if I use the
recv() function.
Suggestions?
Thanks
-Mark
=======================================
#!/usr/bin/perl -w
# Q3_SEARCH.PL
#
# Based on "Programming Perl" p349
require 5.002;
use strict;
use Socket;
use Socket qwDEFAULT :crlf);
my ($ipfirst, $iplast, $remote, $port, $iaddr, $paddr, $proto, $line);
$ipfirst = shift;
if ($ipfirst !~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {die "Invalid IP
address as param #1";}
$iplast = shift;
if ($iplast !~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/) {die "Invalid IP
address as param #1";}
$port = shift || 27960; #Default Quake 3 Port
if ($port =~ /\D/) { $port = getserverbyname($port, 'udp')}
die "No port" unless $port;
$remote = $ipfirst;
my $exit_flag = 0;
while (1)
{
print "Testing $remote\.\.\.\n";
$iaddr = inet_aton($remote) or die "no host: $remote";
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('udp');
socket(SOCK, PF_INET, SOCK_DGRAM, $proto) or die "socket: $~";
connect(SOCK, $paddr) or die "connect: $~";
# Setting autoflush is supposed to help prevent blocking
# when attempting to read from the socket. . .
my $oldh = select(SOCK);$|=1;select($oldh);$|=1;
defined(send SOCK, "\xff\xff\xff\xffgetstatus", 0) || goto NEXT_IP;
# Select() is supposed to succeed if the socket has data,
# or else timeout and return FALSE.
if (!(select (SOCK, undef, undef, 10.0))) {goto NEXT_IP;}
# Script will eventually hang on the following line
if (!defined($line = <SOCK>)) {goto NEXT_IP;}
if ($line =~ "statusResponse")
{print " $remote:$port is active\n";
}
close (SOCK) or die "close: $~";
if ($exit_flag > 0) {last;}
NEXT_IP:
$remote = inc_ip_addr($remote);
if ($remote eq $iplast) {$exit_flag = 1;}
}
sub inc_ip_addr
{
my $ipaddr = shift;
my $newip = "";
$ipaddr =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/;
my $a = $1;
my $b = $2;
my $c = $3;
my $d = $4;
$d++;
if ($d > 255) {$d = 0; $c++;} else {goto INC_IP_EXIT;}
if ($c > 255) {$c = 0; $b++;} else {goto INC_IP_EXIT;}
if ($b > 255) {$b = 0; $a++;} else {goto INC_IP_EXIT;}
INC_IP_EXIT:
$newip = $a . "\." . $b . "\." . $c . "\." . $d; return $newip;
}