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

G

Gavin Yap

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 :)
 
T

Tanaka Akira

Gavin Yap said:
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.
 
G

Gavin Yap

Tanaka said:
Gavin Yap said:
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 Akira 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.
 
T

Tanaka Akira

Gavin Yap said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top