Monday, January 5, 2009

PERL: Using return type of System(“ping…”)

** Before starting, I am not responsible for the ramifications you face after running the below mentioned scripts...So be contemplative before trying these out!! **

Problem Statement:

I had taken up an initiative of scripting an application that required me to ping a certain host that is keyed in by the user and if the host was PING able (that is if I could get a reply to my ICMP request), I had to start some tests on the same host.

Approach #1:
As you would know, after a PING command we have two kinds of outputs:
a. Reply from : bytes=32 time<1ms TTL=128 – PING successful, host reachable
b. Request timed out. – Unreachable host, PING unsuccessful
So my plan was to ping the host in the script and redirect the output of the ping request on to a file. If the redirected file contents happen to be one of these, that is either it matched “Reply from” or it matched “Request timed out”, then the host is PING able or not. Looks easy! But while implementing this logic, you need to open up a file (containing the redirected output), search for contents, match the lines with certain keywords (Reply from or Request timed out) and then decide further. It works, but at the same time it’s painful! I bet you would agree. So I thought of looking out for other options.

Approach #2:
Here’s what struck to me. How about using the return-type of PING? Actually, if you browse through some websites, you would understand that there are 3 return-types of PING.
a. 0 for successful ping
b. 1 if there is any fault in the way the ping request was sent i.e., corrupted packets
c. 2 for unreachable host
Actually, when I devised the trick that I am going to reveal now, I wasn’t thinking about these 3 return types. I simply tried this code:
Code:
use strict;
my $ping = system "ping hostname"; #replace hostname with your IP or Computer name
if(!$ping)
{
print "PING returned: $ping...Host Reachable!!";
}
else
{
print "PING returned: $ping...Host Unreachable!!";
}
#Line 3: if the host is reachable $ping has value of “0”. So using “!$ping”
Execution of the script:
When I ran this code snippet on WinXP and Win2k3 servers, I got the following results:
1. For Reachable IPs: PING returned: 0...Host Reachable!!
2. For Unreachable IPs: PING returned: 256...Host Unreachable!!
You would have realized that, if the host is contactable, the variable $ping contains a value 0 and if not then it stores value of 256. This is the trick secret!!

Approach #3:
This approach is the easiest one and an orthodox one. But you don’t learn anything here. Try using Net::Ping module available in PERL to check if the host is ping able. But again it involves 2 lines of code to understand if the host is reachable unlike 2nd approach!
Code:
$p = Net::Ping->new();
print "$host is alive.\n" if $p->ping($host);


Epilogue:
Out of the 3 approaches, I would go in for the second one; of course as I found it. But I am unsure at this point of time that, whether the return type was of PING or of System function? Anyhow, this consistently works in PERL code run on Windows platform that I mentioned. Let me know your thoughts!!

No comments: