Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Using Perl to ping specific port eg SMTP 4

Status
Not open for further replies.

Guest_imported

New member
Jan 1, 1970
0
0
0
Hi all

I am wanting to create a web page that show the status of our server services ie etc. I cannot find any examples or anyhing on the subject.

If anyone know i would really appreciate the help

Cheers
 
This may be what you want...
Code:
use IO::Socket;
$| = 1;  # auto buffer flush

$host = "[URL unfurl="true"]www.yourserver.com";[/URL] # or an IP address
# use localhost if testing local machine

@ports = qw/80 25 12/;  # a list of port numbers
# which correspond to your services

foreach $port(@ports){
print "Attempting to connect to port $port on $host\n";

%host = (LocalAddr => $host, LocalPort => $port) if $host eq "localhost";
%host = (PeerAddr => $host, PeerPort => $port) if $host ne "localhost";

if($socket = IO::Socket::INET->new(%host)){
print "Connected to $host on port $port\n";
}
else{
print "Could not connect to $host on port $port\n";
}

}

Hope this helps...
--jim
 
That looks like the one. Thank you very much.

I have found a few multi ftp scanner scripts but i don't know enough about PERL to reverse-engineer to what i want.

You seem in the know so i have one more quick one for you.

This is so i can have a web page on our Intranet showing the status of our server services IMAP UP etc. If i call this PERL from an html page do you think it is fast enough to ir real time or is the delay/load too much and should i just schedule it to create a page every hour or so?

Just in case you have done anything like this before

Many thanks
 
It's probably quick enough to do real time, however, depending on your needs, it probably would be better just to set up a recurring run of the script to generate a static HTML page, like you said. Especially if you are testing many ports. I would probably run it every 15 minutes, and put a little caveat on the page saying:

This page was last updated at X o'clock, Eastern time
Updates every 15 minutes.

Something like that not to confuse the users.

--jim
 
Excellenty, the code you gave me is in place and it works perfect.

Many thanks for your help.
 
How would you do the same thing in checking several IP addresses??

I tried putting the $host variable in an array but couldnt get it to work.

@host = "111.111.111.111 454.333.335.333 334.333.334.333"; # or an IP address
 
Put the whole thing in a big loop. You were on the right track:
Code:
#========== CODE

use IO::Socket;
$| = 1;  # auto buffer flush

@hosts = ('111.111.111.111',
         '454.333.335.333',
         '334.333.334.333');

foreach $host(@hosts) {

# use localhost if testing local machine

@ports = qw/80 25 12/;  # a list of port numbers
# which correspond to your services

foreach $port(@ports){
print "Attempting to connect to port $port on $host\n";

%host = (LocalAddr => $host, LocalPort => $port) if $host eq "localhost";
%host = (PeerAddr => $host, PeerPort => $port) if $host ne "localhost";

if($socket = IO::Socket::INET->new(%host)){
   print "Connected to $host on port $port\n";
   }
else{
   print "Could not connect to $host on port $port\n";
   }
}  # loops on port

}  # loops on host

#========= END CODE
This will loop over each port, for each host.

--jim
 
I see that you changed $host to @host, but you need to quote each host something like this;


@host = ("111.111.111.111", "454.333.335.333", "334.333.334.333"); # or an IP address

and then I added another line after
foreach $port(@ports){
# like this;
foreach $host(@host){

This will look for each $host for each $port

It's not perfect, but I'm still trying to work out the details when I have time which isn't much.

The above works for me, but Iwould like it to skip a $host if it has been found on another $port.

eg. if 111.111.111.111 has been found on port 80 then don't try it again on other ports.

Hope this helps, and I hope someone can help me refine mine.

tgus

____________________________
Families can be together forever...
 
tgus: If you'd like to skip to the next host on the first port that doesn't answer, you could change this line (in my example anyways):
Code:
else{
   print "Could not connect to $host on port $port\n";
   }

To this:

else{
   print "Could not connect to $host on port $port\n";
   print "Moving onto next host in list\n";
   last;
   }

Hope this helps...

--jim
 
Coderifous,
I think what your saying is; if the port doesn't answer then move to the next host.
Is that right?

What I'm hoping to do is, remember which hosts have pinged successfully and then don't try to ping them on another port.

Maybe I need to do it differently. Maybe put all the hosts to ping on port 80 in @host80, all the hosts to ping on port 12 in @host12 etc.. and then just do loops on each of those. But that doesn't seem as efficient.

What do you think?

tgus

____________________________
Families can be together forever...
 
Maybe this could perform your desired function:
Code:
#========== CODE

use IO::Socket;
$| = 1;  # auto buffer flush

@hosts = ('111.111.111.111',
         '454.333.335.333',
         '334.333.334.333');

foreach $host(@hosts) {

# use localhost if testing local machine

@ports = qw/80 25 12/;  # a list of port numbers
# which correspond to your services

foreach $port(@ports){
print "Attempting to connect to port $port on $host\n";

%host = (LocalAddr => $host, LocalPort => $port) if $host eq "localhost";
%host = (PeerAddr => $host, PeerPort => $port) if $host ne "localhost";

if($socket = IO::Socket::INET->new(%host)){
   print "Connected to $host on port $port\n";
   print "Saving ${host}:${port} in 'good' list...\n";
   push @good_hosts, "${host}:${port}";
   print "Moving onto next host...\n";
   last;
   }
else{
   print "Could not connect to $host on port $port\n";
   }
}  # loops on port

}  # loops on host

print "The hosts that we could connect to were:\n";
$" = "\n";
print "@hosts";

#========= END CODE

Hope this helps.

--jim
 
Oops. Change the last line to:

print "@good_hosts";

--jim
 
thanks, now I am not clear on how this part works?


What is the $socket=IO::Socket::INET ->new(%host) part doing??
And what does ${host}:${port} represent??, Are these aliases??
[tt]
if($socket = IO::Socket::INET->new(%host)){
print "Connected to $host on port $port\n";
print "Saving ${host}:${port} in 'good' list...\n";
push @good_hosts, "${host}:${port}";
print "Moving onto next host...\n";
last;
[/tt]
 
Coderifous,

Thanks, that was just was I was trying to do.

I just realized that I was trying to respond to "three's" first post at the same time as you did. I never knew you had responded. Or I would have tried that bit of code of yours before I asked my question. Sorry!!!

I'm going to give you a star. [idea] You make it look soooo easy!

tgus

____________________________
Families can be together forever...
 
tgus:

Thanks for the kind words, I'm glad I could help. And just in case it DIDN'T go without saying: anytime. ;)

--jim

three:

You said:

What is the $socket=IO::Socket::INET ->new(%host) part doing??

My Response:

That's the code that tries to create a socket connection. If it fails, then that means that it could not connect.

You said:

And what does ${host}:${port} represent??, Are these aliases??

My Response:

I'm guessing your referring to this line:

push @good_hosts, "${host}:${port}";

What it's doing is creating a string, and then pushing that string into the array @good_hosts. It's equivelent to this code which may make the intent more obvious:

$new_value = $host . ":" . $port;
push @good_hosts, $new_value;

The braces are there (in the original line) to make sure that perl new what variables I was trying to say. Look at this:

$verb = "run";
print "I was $verbing";

This won't work becuase perl is looking for a variable called $verbing. It doesn't know I meant $verb followed by ing. So I have to 'disambiguate' with the braces:

print "I was ${verb}ing";

Hope that helps.

--jim
 
thanks for taking the time to explain your script!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top