Affichage des articles dont le libellé est perl. Afficher tous les articles
Affichage des articles dont le libellé est perl. Afficher tous les articles

Ping or die

So, we've got this computer that we use as a router... and since it probably eats electricity like crazy, compared to an ordinary router, every night when everyone goes off-line somebody has to turn it off. And since programmers are lazy, we've been kicking around the idea of making a program that turns the damn thing off by itself.

But since programmers are lazy, I only did it today, after a year of excuse finding (at which I am highly proficient).

Result: here's a little Perl script to run commands when some computers go off-line. It turned out quite simple. Enjoy!

#!/usr/bin/perl 
#
# Ping or die
#
# Pings all ip addresses and turns off the machine when 
# all of them are dead.
# If you need to run other commads, you can do that too. 
#
# Parameters:
10#   c - command to run,
11#   s - sleep time between pinging (in seconds),
12#   t - ping timeout (in seconds),
13#   IP addresses or hostnames to watch.
14# Example:
15#   Turn on the Rokudan when the router's down for a minute:
16#       ping_or_die -s 60 "mpg321 Rokudan.mp3" 10.0.0.2
17# Author:
18#   Konrad Siek
19
20# Packages
21use Net::Ping;
22use Getopt::Std;
23
24# Defaults
25my $command = "shutdown -h now";
26my $sleep_time = 300;
27my $timeout = 10;
28my $hosts = ();
29
30# Setup options
31my %options = ();
32getopt "cst"\%options;
33$command = @options{c} if defined @options{c};
34$sleep_time = @options{s} if defined @options{s};
35$timeout = @options{t} if defined @options{t};
36@hosts = @ARGV;
37
38# If no hosts were provided print help and exit.
39if (scalar @hosts < 1) {
40    print "Usage: $0 [options] list-of-ips\n";
41    print "\t-c\tcommand to run\n";
42    print "\t-s\tsleep time between pinging (in seconds)\n";
43    print "\t-t\tping timeout (in seconds)\n";    
44    exit -1;
45}
46
47# Setup ping - 30 second timeout
48$ping = Net::Ping->new("tcp"$timeout);
49
50# Main program
51my $again;
52do {
53    $again = 0;
54    # Wait some time before checking
55    sleep $sleep_time;
56    # Ping machines
57    foreach (@hosts) {
58        my $present = $ping->ping($_);
59        $again |= $present;
60    }
61} while ($again);
62
63# Finish up ping
64$ping->close();
65
66# Info
67print "$0: dead hosts: @hosts\n";
68print "$0: running command '$command'\n";
69
70# Run command
71system $command;
72


The code is also available at GitHub as perl/ping_or_die.
Continue Reading...

Ping all

If you happen to have many computers in your local network, and you want to find out which ones are working at the moment without getting up, well, there are several ways to do this, probably. Same for when you have DNS turned on and want to know what IP addresses all those computers have got at the moment.

So this might be yet another way to do this.

Its advantage is that it's straightforward. Its disadvantage is that it's rather crude and can be slow. Oh, and it doesn't find out the names of all those computers running non-gnu/linux systems... although, personally, I don't care about that very much.

It's written in Perl, because writing it in Bash would hurt too much, as it lacks easily-manipulated arrays and a way of getting the hostname out of the IP (well, I couldn't find a way) and Python doesn't provide anything to ping out of the box... I'm not good at Perl so a) I had a chance to practice and b) the code probably sucks tremendously in some bits.

I wanted to do the main monitoring using Perl's own ping object, but somehow it didn't want to produce correct results for non-gnu/linux systems... and a ping function shouldn't be so finicky. Whether, I used it wrong or there is something wrong with my configuration, it was easier to use an external ping command, redirect its output to /dev/null and return something if it finds a computer. All that is done on line 76.

Before pinging, the IP addresses for pinging are generated, one by one and put into an array. This is perhaps not the best way to do this, but it's rather convenient... not to mention that it's good practice.

Enough banter, here's the code.

#!/usr/bin/perl 
#
# Ping all
#
# Pings all ip addresses within the specified range and
# retrieves the name
#
# Parameters:
#   range start - IP address at which to check,
10#   range end - last IP address to check.
11# Example:
12#   pingall 10.0.0.10 10.0.0.20 
13#   Checks all the addresses between .10 and .20
14# Author:
15#   Konrad Siek
16
17use Socket;
18
19# Quit, if no range is specified.
20# Note: Number of parameters in Perl is one lower.
21die "Usage: $0 <range start> <range end>\n" if ($#ARGV != 1);
22
23# Validate IP and return its more manageable form.
24sub to_ip {
25    my $message = "$_[0] is not a valid IP.";
26    my @array = split(/\./, $_[0]);
27    die $message if $#array != 3;
28    foreach $e (@array) {
29        die $message if $e =~ m/[^0-9]+or $e > 255;
30    }
31    return @array;
32}
33
34# Check the validity of range IPs and turn them into arrays.
35my @start_range = to_ip(@ARGV[0]);
36my @end_range = to_ip(@ARGV[1]);
37
38# Increment the IP to the next. Roll over if overflow occurs.
39sub increment {
40    @array = @_;
41    for($i = 3; $i >= 0;) {
42        if(@array[$i] >= 255) { 
43            $i--;
44        } else {
45            @array[$i]++;
46            return @array;
47        }
48    }    
49    return (0000);
50}
51
52# Compare two IP arrays.
53sub compare {
54    @a = @_[0..3];
55    @b = @_[4..7];
56    for($i = 0; $i < 4; $i ++) {
57        if(@a[$i] < @b[$i]){
58            return -1;
59        }
60        if(@a[$i] > @b[$i]){
61            return 1;
62        }
63    }
64    return 0;
65}
66
67# Prepare list of addresses within range.
68@addresses = ();
69while (compare(@start_range@end_range) <= 0) {
70    @addresses[++$#addresses] = join('.'@start_range);
71    @start_range = increment(@start_range);
72}
73
74# Ping each of the addresses from the prepared list.
75foreach $address (@addresses) {
76    my $return = `ping -c 5 $address > /dev/null && echo 1`;
77    my $state = $return == 1 ? '+' : '-';
78    my $inet_addr = inet_aton($address);
79    my $hostname = gethostbyaddr($inet_addr, AF_INET);
80    print "[$state]\t$address\t$hostname\n";
81}


The code is also available at GitHub as perl/ping_all.
Continue Reading...

lala moulati ana9a maghribia

seo

 

Blogroll

Site Info

Text

telechargementz Copyright © 2009 WoodMag is Designed by Ipietoon for Free Blogger Template