How can I see ICMP error messages in response to UDP messages in Ruby?

75 views Asked by At

I am trying to build a kind of traceroute in Ruby. The principle is that I send a UDP message with a TTL of 1 to the desired destination and get an ICMP error message back from the first hop. Since I do not want to use root privileges or similar for the program, I would like to use the native receive function.

I have therefore drafted the following code:

# frozen_string_literal: true
# sharable_constant_value: literal

require 'socket'

sock = Socket.open(Socket::AF_INET, Socket::SOCK_DGRAM, Socket::IPPROTO_UDP)

# Set TTL to one
sock.setsockopt Socket::IPPROTO_IP, Socket::IP_TTL, 1

# Enable receiving errors
sock.setsockopt Socket::IPPROTO_IP, Socket::IP_RECVERR, 1
sock.setsockopt Socket::IPPROTO_IP, Socket::IP_RECVTTL, 1

# Sending a packet to 1.1.1.1
dest = Socket.sockaddr_in 33435, '1.1.1.1'
sock.send "Test", 0, dest

# Receive error message
pp sock.recvmsg nil, Socket::MSG_ERRQUEUE
# Blocking forever
# But seeing ICMP error message in capture

or for IPv6:

# frozen_string_literal: true
# sharable_constant_value: literal

require 'socket'

sock = Socket.open(Socket::AF_INET6, Socket::SOCK_DGRAM, Socket::IPPROTO_UDP)

# Set IPv6 TTL / Hop Limit to 1
sock.setsockopt Socket::IPPROTO_IPV6, Socket::IPV6_UNICAST_HOPS, 1

dest = Socket.sockaddr_in 33435, '2a00:1450:4001:806::2003'
pp sock.send "Test", 0, dest
pp sock.recvmsg nil, Socket::MSG_ERRQUEUE

The problem I have now, however, is that sock.recvmsg (for IPv4 and IPv6) blocks forever and does not return an error message. However, according to the documentation, this should be the case (in my understanding). In WireShark I could see that the ICMP error messages also arrive as desired. My question is therefore, how can I view the ICMP error message in Ruby?

0

There are 0 answers