#!/usr/bin/perl -w

my $subnet = '192.168.101.';
#my $single = '192.168.101.106';


use Socket;
use Symbol;
use NetAddr::IP::Lite;

sub ICMP_ECHO       ()  { 8 }
sub ICMP_SUBCODE    ()  { 0 }
sub ICMP_STRUCT     ()  { 'C2S3A56' }
sub ICMP_FLAGS      ()  { 0 }
sub ICMP_PORT       ()  { 0 }

$sequence=0;

for $i (2..254) {

            $protocol = (getprotobyname('icmp'))[2] or
               die('Cannot get ICMP protocol number by name - ', $!);

            $socket = Symbol::gensym;
            socket($socket, PF_INET, SOCK_RAW, $protocol) or
                die('Cannot create IMCP socket - ', $!);


            $sequence = ($sequence+1) & 0xFFFF;

        my $checksum = 0;
       	my $msg = pack(
            ICMP_STRUCT,
               	ICMP_ECHO,
                ICMP_SUBCODE,
               	$checksum,
                $$ & 0xFFFF,
                $sequence,
                '0' x 56
       	);

       	my $short = int(length($msg) / 2);
        $checksum += $_ for unpack "S$short", $msg;
        $checksum += ord(substr($msg, -1)) if length($msg) % 2;
        $checksum = ($checksum >> 16) + ($checksum & 0xFFFF);
       	$checksum = ~(($checksum >> 16) + $checksum) & 0xFFFF;

       	$msg = pack(
            ICMP_STRUCT,
                ICMP_ECHO,
               	ICMP_SUBCODE,
               	$checksum,
                $$ & 0xFFFF,
               	$sequence,
                '0' x 56
        );
        $length = length $msg;

my($address)=$single?$single:"$subnet$i";
        my $netaddr = inet_aton($address);
        my $sockaddr = pack_sockaddr_in(ICMP_PORT, $netaddr);
        send($socket, $msg, ICMP_FLAGS, $sockaddr) or
            die("Error sending ICMP packet - $!");

print "sent $address\n";
}
