Daniel Upton
Daniel Upton

Reputation: 5741

Receive UDP datagram on raw socket?

I'm trying to write my own implementation of UDP in ruby for educational purposes using raw sockets.

Here's what I have so far:

require 'socket'

addr = Socket.pack_sockaddr_in(4567, '127.0.0.1')

socket = Socket.new(
  Socket::PF_INET,
  Socket::SOCK_RAW,
  Socket::IPPROTO_RAW
)

socket.bind(addr)
socket.recvfrom(1024)

I am testing it like so:

require 'socket'

udp = UDPSocket.new
udp.send "Hello World", 0, "127.0.0.1", 4567

But the call to recvfrom is blocking indefinitely.

If I change it to this:

socket = Socket.new(
  Socket::PF_INET,
  Socket::SOCK_DGRAM,
  Socket::IPPROTO_UDP
)

It of course works because this is the system-level way to accept UDP packets.

How can I receive UDP packets on a raw socket?
To be clear: I want to handle the actual UDP protocol (decoding the datagram & doing a checksum) myself!

Upvotes: 1

Views: 1135

Answers (1)

rodolk
rodolk

Reputation: 5907

Raw sockets work at IP level. You cannot bind a raw socket to a port. You can bind to a local address with bind or to an interface by setting the proper socket options (I don't know how to do it in Ruby, in C you call setsockopt. Instead of IPPROTO_RAW you should use IPPROTO_UDP in protocol.You will receive all UDP datagrams received on that IP address or that interface if the socket is bound to it.

Upvotes: 1

Related Questions