hi..
im trying to make icmp script (send echo req and hopes there's a reply from alive host) with this script :
| Posted on 2005-09-06 13:12:15-07 by zak |
| trying to make ping echo req script without Net::Ping ..and problem |
|
hi.. im trying to make icmp script (send echo req and hopes there's a reply from alive host) with this script :
use Socket;
use strict;
socket(SOCK,PF_INET,SOCK_RAW,getprotobyname('icmp')) || die $!;
my $checksum = 0;
use constant ICMP_ECHOREPLY => 0;
use constant ICMP_ECHO => 8;
use constant ICMP_STRUCT => "C2 n3 A0";
use constant SUBCODE => 0;
use constant ICMP_FLAGS => 0;
use constant ICMP_PORT => 0;
my $seq=1;
my $data= "";
my $msg = pack(ICMP_STRUCT,ICMP_ECHO,SUBCODE,$checksum,$$,$seq,$data);
my $chks = &ceksum($msg);
$msg = pack(ICMP_STRUCT,ICMP_ECHO,SUBCODE,$chks,$$,$seq,$data);
my $host = sockaddr_in(ICMP_PORT,inet_aton('192.168.0.1'));
send(SOCK,$msg,ICMP_FLAGS,$host) || warn "$! \n";
sub ceksum {
my ($msg) = @_;
my ($len_msg,$num_short,$short,$chk);
$len_msg = length($msg);
$num_short =int($len_msg/2);
$chk = 0;
foreach $short(unpack("n$num_short", $msg)) {
$chk += $short;
}
$chk +=(unpack("C",substr($msg,$len_msg-1,1)) << 8) if $len_msg % 2;
$chk = ($chk >> 16) + ($chk & 0xffff);
return(~(($chk >> 16) + $chk) & 0xffff);
}
too bad this script is working fine FOR LOCALHOST ONLY. so i read ping.pm from Net::Ping, i made a lil change to this pm file (dont laugh please), so ping.pm looks like this :
package Net::Ping;
use strict;
use Socket;
ping_icmp();
use constant ICMP_ECHOREPLY => 0; # ICMP packet types
use constant ICMP_ECHO => 8;
use constant ICMP_STRUCT => "C2 n3 A"; # Structure of a minimal ICMP packet
use constant SUBCODE => 0; # No ICMP subcode for ECHO and ECHOREPLY
use constant ICMP_FLAGS => 0; # No special flags for send or recv
use constant ICMP_PORT => 0; # No port with ICMP
sub ping_icmp
{
my ($ip) = inet_aton('192.168.0.1');
my ($saddr, # sockaddr_in with port and ip
$checksum, # Checksum of ICMP packet
$msg, # ICMP packet to send
$len_msg, # Length of $msg
$ret, # Return value
);
my $seq = 1;
my $pid = 5000;
$checksum = 0; # No checksum for starters
my $data= "";
$msg = pack(ICMP_STRUCT . 0, ICMP_ECHO, SUBCODE,
$checksum, $pid, $seq, $data);
$checksum =checksum($msg);
$msg = pack(ICMP_STRUCT . 0, ICMP_ECHO, SUBCODE,
$checksum, $pid, $seq, $data);
$len_msg = length($msg);
$saddr = sockaddr_in(ICMP_PORT, $ip);
socket(SOCK,PF_INET,SOCK_RAW,getprotobyname('icmp'));
send(SOCK,$msg,ICMP_FLAGS,$saddr);
return $ret;
}
# Description: Do a checksum on the message. Basically sum all of
# the short words and fold the high order bits into the low order bits.
sub checksum
{
my (
$msg # The message to checksum
) = @_;
my ($len_msg, # Length of the message
$num_short, # The number of short words in the message
$short, # One short word
$chk # The checksum
);
$len_msg = length($msg);
$num_short = int($len_msg / 2);
$chk = 0;
foreach $short (unpack("n$num_short", $msg))
{
$chk += $short;
} # Add the odd byte in
$chk += (unpack("C", substr($msg, $len_msg - 1, 1)) << 8) if $len_msg % 2;
$chk = ($chk >> 16) + ($chk & 0xffff); # Fold high into low
return(~(($chk >> 16) + $chk) & 0xffff); # Again and complement
}
1;
and then i make a lil script (named ping1.pl) with codes like this :
require 'ping.pm';
$host=shift;
$p = Net::Ping->new('icmp');
print "$host is alive \n" if $p->ping($host);
so i executed this ping1.pl and its work fine, 192.168.0.1's detected by this ping1.pl. and my question is : is there a way to change this modified ping.pm to pl file (example : ping.pl) ? i tried to rename ping.pm to ping.pl and commented out 'package Net::Ping', and then execute this ping.pl but there's an error.. i mean.. yea this ping.pl still send single icmp packet to 192.168.0.1 but the checksum was error ? do u know why (remember the code of ping.pm and ping.pl is still the same) ? im not sure if this place is a right place to post my problem, and sorry for my english, i'll ask my friend to translate my prob for better english.... regs zac |
| Direct Responses: Write a response |