# # How to get an ICMP host unreachable packet??? # use IO::Select; use IO::Socket; use strict; use warnings; my $sock_udp = IO::Socket::INET->new(Proto=>'udp'); print "created udp=$sock_udp\n"; my $sock_icmp = IO::Socket::INET->new(Proto=>'icmp'); print "created icmp=$sock_icmp\n"; my $select = IO::Select->new(); my $host = '192.168.0.4'; my $port = 2; my $rbits = 0; my $aton = inet_aton($host); my $addr = sockaddr_in($port, $aton); $sock_udp->connect($addr) or die "$!\n"; #Unix socket faq says udp must be "connected" to get icmp msg print " udp 'connected' to $host:$port\n"; #http://www.unixprogram.com/socket/socket-faq.html#faq55 $select->add($sock_icmp); $select->add($sock_udp); vec($rbits, $sock_icmp->fileno(), 1) = 1; vec($rbits, $sock_udp->fileno(), 1) = 1; $sock_udp->send("test", 0) or die "$!\n"; print " send test msg to $host:$port\n"; # select attempt my $found = select($rbits, undef, undef, 1); if ($found > 0) { my $msg = ""; my $size = 1500; my $from_icmp = recv($sock_icmp, $msg, $size, 0) or die "$!\n"; my $from_udp = recv($sock_icmp, $msg, $size, 0) or die "$!\n"; my ($from_port, $from_ip) = sockaddr_in($from_icmp); # I need to unpack the packet here I think... } # io::select attempt my @found = $select->can_read(); foreach (@found) { print " got a can_read on socket=$_\n"; my $msg = ""; my $size = 1500; #my $from_icmp = recv($sock_icmp, $msg, $size, 0) or die " $!\n"; my $from_udp = recv($sock_icmp, $msg, $size, 0) or die " $!\n"; my ($from_port, $from_ip) = sockaddr_in($from_udp); # I need to unpack the packet here I think... } #If you can figure this out, here is another question: #I want to scan more than 1 machine for a certain open UDP ports #(for use internally at my business and I want to write it myself and not use the awesome nmap...) #Should I create a new UDP socket for each host I want to test? #and then wait in the select loop? #The reason I ask is that I expect to get stuck on determinig #what hosts/ports replied back as ICMP unreachable... #I am not there yet, but expect to get stuck ;-)