How do I get the destination IP of a received UDP packet?

Hi There,

I need to write a server which is able to identify client by
destinations.

My machine is listening to “0.0.0.0”, any IP addrs configured to it.
Take for instance, the machine is configured with “192.168.1.10,
172.16.0.10”, also listening to “0.0.0.0”, allow listening to Broadcast
queries, which is also important to my application

Hence, if one of the clients send a UDP packet to it, the server program
would check the destination address of the client request and reply the
client with different “answers”.

I’ve not been lucky enough to google how to get the destination address
of a incoming packet.

Hope someone here could shed some light. Thanks :slight_smile:

In article [email protected],
Gavin Y. [email protected] writes:

I need to write a server which is able to identify client by
destinations.

My machine is listening to “0.0.0.0”, any IP addrs configured to it.
Take for instance, the machine is configured with “192.168.1.10,
172.16.0.10”, also listening to “0.0.0.0”, allow listening to Broadcast
queries, which is also important to my application

How about using sockets for each IP address and “0.0.0.0”?

require ‘socket’

s0 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s0.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
s0.bind(Socket.sockaddr_in(9999, “0.0.0.0”))

s1 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s1.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
s1.bind(Socket.sockaddr_in(9999, “192.168.1.10”))

s2 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s2.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
s2.bind(Socket.sockaddr_in(9999, “172.16.0.10”))

while true
rs, = IO.select([s0, s1, s2])
rs.each {|s|
p [Socket.unpack_sockaddr_in(s.getsockname)[1], s.recv(100)]
}
end

I’m not certain about the portability of the broadcast
handling, though.

Tanaka A. wrote:

In article [email protected],
Gavin Y. [email protected] writes:

I need to write a server which is able to identify client by
destinations.

My machine is listening to “0.0.0.0”, any IP addrs configured to it.
Take for instance, the machine is configured with “192.168.1.10,
172.16.0.10”, also listening to “0.0.0.0”, allow listening to Broadcast
queries, which is also important to my application

How about using sockets for each IP address and “0.0.0.0”?

require ‘socket’

s0 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s0.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
s0.bind(Socket.sockaddr_in(9999, “0.0.0.0”))

s1 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s1.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
s1.bind(Socket.sockaddr_in(9999, “192.168.1.10”))

s2 = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s2.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1)
s2.bind(Socket.sockaddr_in(9999, “172.16.0.10”))

while true
rs, = IO.select([s0, s1, s2])
rs.each {|s|
p [Socket.unpack_sockaddr_in(s.getsockname)[1], s.recv(100)]
}
end

I’m not certain about the portability of the broadcast
handling, though.

Hi Tanaka A. san,

Thanks for the tip.

I guess this is the only way get my destination address.
I wonder if there’s a way to recieve the packet, with layer 3(IP header)
and layer 4(UDP header) info.
I dun mind to write a wrapper to strip off or add, the IP header and UDP
details.

In article [email protected],
Gavin Y. [email protected] writes:

I guess this is the only way get my destination address.
I wonder if there’s a way to recieve the packet, with layer 3(IP header)
and layer 4(UDP header) info.

Your OS may have another (non-portable) way.

For example, IP_PKTINFO of GNU/Linux, IP_RECVDSTADDR of 4.4BSD.

However they needs recvmsg which is not supported by Ruby, yet.