in reply to udp recv question

Net::Ping is probably what you are looking for. RTFS for the implementation details. Hint - you can't send the string 'test' and expect it to be treated as a valid ICMP request packet. See RFC792 for details or NetPacket::ICMP for an implementation that will assemble and disassemble ICMP packets for you.

cheers

tachyon

Replies are listed 'Best First'.
Re^2: udp recv question
by smackdab (Pilgrim) on Jun 28, 2004 at 01:46 UTC
    Thanks, NetPacket::ICMP looks great and I know I will need to decode the ICMP packet once I can figure out how to recv() it...

    My question is a UDP->ICMP question.

    I am sending out a UDP packet, which in the examples I have seen is valid and my example works correctly (when viewed from a sniffer type product).

    When a UDP port isn't available on the remote machine a ICMP unreachable packet is sent back.

    I can't figure out how to "read" that packet...and that is my question.

      You really don't want to code this yourself. Here is a trivial example for interest sake only. It shows you how to build a packet (and its checksum) and that you do get data back which as you can see it is encoded in a binary packet format.

      use IO::Socket; use constant ICMP_ECHO => 8; use constant SUBCODE => 0; # No ICMP subcode for ECHO and ECHOR +EPLY use constant ICMP_STRUCT => "C2 n3 A64"; my $icmp = IO::Socket::INET->new( PeerAddr => 'perlmonks.org', Proto=>'icmp' ); print "Got socket\n"; my $data = '1'x64; my $seq = 1; my $checksum = 0; my $msg = pack(ICMP_STRUCT, ICMP_ECHO, SUBCODE, $checksum, $$, $seq, $ +data); $checksum = checksum($msg); my $msg = pack(ICMP_STRUCT, ICMP_ECHO, SUBCODE, $checksum, $$, $seq, $ +data); print "Sending: $msg\n"; $icmp->send($msg); $icmp->recv(my $buf, 1500); print "Got: $buf"; print "Done\n"; sub checksum { my ($msg ) = @_; my $len_msg = length($msg); my $num_short = int($len_msg / 2); my $chk = 0; for my $short (unpack("n$num_short", $msg)) { $chk += $short; } $chk += (unpack("C", substr($msg, $len_msg - 1, 1)) << 8) if $len_ms +g % 2; $chk = ($chk >> 16) + ($chk & 0xffff); return(~(($chk >> 16) + $chk) & 0xffff); }

      cheers

      tachyon

        I VERY MUCH APPRECIATE YOUR COMMENTS.

        I can also be quite dense on some of these matters...but:
        I am NOT trying to SEND an ICMP packet.
        I AM trying to see if a remote UDP port is "open"
        My assumption has been to send a UDP packet out
        and if the port is CLOSED, then I get a ICMP error msg back
        Otherwise I know the remote port is OPEN...

        The code above sends an UDP packet out and an ICMP error msg is sent back. But I DON'T know how to grab it. I tried reading on the UDP and ICMP sockets but neither *seem* to have it.

        Are you saying that I need to send an ICMP packet out???

        Again, sorry if I am missing something completely obvious ;-)