Showing posts with label ping. Show all posts
Showing posts with label ping. Show all posts

Wednesday, June 18, 2008

Pinging And Checking Port Status With Perl CGI On Linux And Unix

Greetings,

To change things up a bit today, we're going to go back to some Perl scripting. It seems like it's been a while, but that may just be my distorted sense of space and time. In any event, since this blog covers many many things related to Linux and Unix (which my probable life-span wouldn't allow me to script out or write about ;), today seems a good a day as any to get back to putting out some script work.

Today's Perl script is very simply written and, although a bit lengthy, fairly limited in what it does. Of course, it should also be fairly simple to expand upon and make do much more work than would normally be commensurate with a general breakdown of the keystroke/output-usefulness ratio.

This script closely echoes previous scripts we put out to check on web server status and check on network server port-health insofar as the end result is concerned. It should run fairly simply, too (you'll probably just need to change the target host, target port and, possibly, the location of the ping command, and its arguments, to suit your taste - or have those all fed to the script from the command line using the @ARGV array):

host # ./portpinger.pl

This version, however, is a bit more complex (or convoluted, depending on how you look at it ;) to highlight a few other concept-based posts that we've put out in the interim. For instance, this Perl script (while it's not absolutely necessary, given the abundance of variable names we could have used to get-around) makes use of variable scoping within subroutines. This is something, actually, that we're building toward in our ever-expanding series on porting code between shell, Perl and awk. And the final thing we highlight, somewhat, in this particular script (that my green-screen-addled brain can still discern ;) is signal trapping and handling with Perl.

Whether or not you have any use for it, I hope you can find something in its over-production that sparks some interest or gets you thinking more about the many different ways you can use Perl to do many different things. Basically, this script does a ping, a port check and then puts up a CGI web page. But, sometimes, the lessons (good or bad) are found more in the context than in the message :)

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# portpinger.pl - Ping a Port and Check Another One Just for kicks.
#
# 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

use Socket;
use CGI;

$socketpinger = new CGI;
$pingee = "www.xyz.com";
system("ping $pingee 1 1 2>/dev/null 1>/dev/null");
$pingyn = $? >> 8;

print $socketpinger->header();
print "<html><head><title>Caps Checker</title></head>\n";
print "<body>\n";
if ( $pingyn ) {
print "<center><h3>Result of ping to $pingee:</3></center> <center><h2>N
o Answer</h2></center>\n";
} else {
print "<center><h3>Result of ping to $pingee:</h3></center> <center><h2>
$pingee is alive!</h2></center>\n";
}

print "<center><h3>Result of tcp connect to port 443:</h3></center>\n";
&checkhost($pingee,443);

print $socketpinger->end_html();
sub Timer { die "Alarm Clock\n"; }

sub checkhost {
local($host,$port) = @_;
local($t,$cnt,@var,$ip,$down);
undef @fdata;
$AF_INET=2; $PF_INET=$AF_INET; $SOCK_STREAM=1; $IPPROTO_TCP=6;
$sockaddr = 'S n a4 x8';
($t,$t,$t,$t,@var) = gethostbyname($host);
$ip = $var[0];

$down = 0;
$this = pack($sockaddr, $AF_INET, 0, "\0\0\0\0");
$serveraddr = pack($sockaddr, $AF_INET, $port, $ip);
eval 'socket(RS, $PF_INET, $SOCK_STREAM, $IPPROTO_TCP)|| die "socket: $!"';
if ($@) {
$SOCK_STREAM=2;
socket(RS, $PF_INET, $SOCK_STREAM, $IPPROTO_TCP) || die print "socket: $
!";
}
bind(RS, $this) || ($down = 1);
if ($down) {
print "<center><h2>$host at port $port is down.</h2></center>\n";
shutdown(RS,2);
close(RS);
return;
}
$SIG{'ALRM'} = 'Timer';
eval {
alarm(5);
connect(RS, $serveraddr) || die ($down = 1);
};
alarm(0);
if ($down || $@ =~ /Alarm Clock/) {
print "<center><h2>$host at port $port is down.</h2></center>\n";
shutdown(RS,2);
close(RS);
return;
}
$up[$num] = 1;
print "<center><h2>Connection to $host at port $port successful.</h2></cente
r>\n";
shutdown(RS,2);
close(RS);
}

, Mike

Wednesday, January 2, 2008

A Simple CGI Script To Check Network Hosts' Status

Today, I thought I'd put out another script that might be helpful to at least a few of us out there. As you may recall, in an earlier post we went over a script that checked network hosts' ports non-maliciously. This is a combination of that with a little something extra.

Okay, there are a few extra elements here. The main function of the script is to check that all the servers in the @hostnames array are up and running. This is done as simply as possible, using ping. The second thing it checks is that FTP is up and running on all hosts (We're assuming that you're running this from a box on your network that has access - through firewalls, router acl's and whatnot - to all of the servers listed). Thirdly, it looks at a subset of servers that you define within the script, and tries to determine if HTTP is up and running.

This script is slightly more complicated than the other, as it uses the Perl Socket and CGI modules and also makes use of signal handling (Touched on in more detail in this previous post. Finally, we do some while loop tagging to control the flow.

Of course, this script can be modified easily to include other system checks. I wrote this to get a quick feel for the health of the network and get an easy read on any problems at whatever time I chose to open the page in my web browser.

Hopefully, you'll find this useful. I've commented the script near all the parts that can/should be edited (IN CAPITALS FOR EASE OF VIEWING). Otherwise, it's pretty much self explanatory.

Cheers,


Creative Commons License


This work is licensed under a
Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License

#!/usr/bin/perl

#
# whatup.cgi - 2008 - Mike Golvach - eggi@comcast.net
#
# Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License
#

use CGI;
use Socket;
require 5.002;

# FILL THIS ARRAY WITH ALL THE HOSTNAMES YOU WANT TO MONITOR

@hostnames = qw(host1 host2 host3 hosta hostb hostc hostn);

foreach $pingable_host (@hostnames) {
$answer=`/usr/sbin/ping $pingable_host 1 1`;
if ( $answer=~ /alive/ ) {
$is_it_up_or_not[$a] = 1;
$a++;
} else {
$is_it_up_or_not[$a] = 0;
$a++;
}
}

use CGI;

$whatup_cgi = new CGI;
@ports = qw(21 80);
$date = `date`;

print $whatup_cgi->header();
print "<html><head><meta HTTP-EQUIV=\"REFRESH\" CONTENT=\"300; URL=/whatup.cgi\"><title>What's Up?</title></head>\n";
print "<body BGCOLOR=\"#000000\" TEXT=\"#00FF00\" LINK=\"#FFFF00\" VLINK=\"#FF0000\" ALINK=\"#BECD8C\">\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";
print "<center><FONT COLOR=\"#FF0000\"><H3>Your Immediate Guide to What's Up On Our Network!</h3></FONT></center>\n";
print "<center><FONT COLOR=\"#BECD8C\"><H4>$date</h4></FONT></center>\n";
print "<p>\n";
print "<br><hr><br>\n";
print "<p>\n";

$b=0;
$c=0;

$SIG{'ALRM'} = 'next_goround';
OUTER: foreach $host (@hostnames) {
if ( $is_it_up_or_not[$b] ) {
print "<hr>\n";
print "<h3><font color=\"#BECD8C\">$host is Up!</font></h3>";
} else {
print "<hr>\n";
print "<h3><font color=\"#FF0000\">$host is Down!</font></h3>";
}
print "<ul>";
$CONNECTION_PORT = "NEXT_UP_IS${c}SOCK";

# IN THE BELOW IF STATEMENT, USE REGULAR EXPRESSIONS TO MATCH ALL HOST NAMES
# THAT YOU WANT TO BE CHECKED FOR HTTP. ALL HOSTS ARE CHECKED FOR FTP

if ( $host=~ /host[1-3]/ || $host=~ /host[ab]/ ) {
foreach $portno (@ports) {
$port = $portno;
if ($port =~ /\D/) {
$port = getservbyname($port, 'tcp');
}
$iaddr = inet_aton($host);
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket($CONNECTION_PORT, PF_INET, SOCK_STREAM, $proto);
if ( $is_it_up_or_not[$b] ) {
connect($CONNECTION_PORT, $paddr) unless alarm 10;
if ( $success_or_failure ) {
next;
}
alarm 0;
}
if ($port == 21 && ! $success_or_failure ) {
$portname = "FTP";
if ( $is_it_up_or_not[$b] ) {
$create_socket = send($CONNECTION_PORT, "user anonymous username\@xyz.com", 40) unless alarm 10;
alarm 0;
}
} else {
$portname = "HTTP";
if ( $is_it_up_or_not[$b] ) {
$create_socket = send($CONNECTION_PORT, "GET /index.html HTTP/1.0", 40) unless alarm 10;
alarm 0;
}
}
close($CONNECTION_PORT);
if ( ! $is_it_up_or_not[$b] && ! $success_or_failure ) {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font></ul>";
$b++;
next OUTER;
}
if ($create_socket) {
print "<li><h3><font color=\#FFFF00\">$portname is Up!</h3></font>";
} else {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font>";
}
$c++;
$success_or_failure = 0;
}
print "</ul>\n";
} else {
$port = 21;
if ($port =~ /\D/) {
$port = getservbyname($port, 'tcp');
}
$iaddr = inet_aton($host);
$paddr = sockaddr_in($port, $iaddr);
$proto = getprotobyname('tcp');
socket($CONNECTION_PORT, PF_INET, SOCK_STREAM, $proto);
if ( $is_it_up_or_not[$b] ) {
connect($CONNECTION_PORT, $paddr) unless alarm 10;
alarm 0;
}
if ( $is_it_up_or_not[$b] && ! $success_or_failure ) {
$create_socket = send($CONNECTION_PORT, "user anonymous username\@xyz.com", 40) unless alarm 10;
alarm 0;
}
$portname = "FTP";
close($CONNECTION_PORT);
if ( ! $is_it_up_or_not[$b] && ! $success_or_failure ) {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font></ul>";
$b++;
next OUTER;
}
if ($create_socket) {
print "<li><h3><FONT COLOR=\"#FFFF00\">$portname is Up!</h3></font>";
} else {
print "<li><h3><font color=\"#FF0000\">$portname is Down!</h3></font>";
}
print "</ul>\n";
$c++;
$success_or_failure = 0;
}
$b++;
}

$whatup_cgi->end_html();

sub next_goround {

close($CONNECTION_PORT);
return $success_or_failure = 1;
}


, Mike