Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get destination address of a received UDP packet

Tags:

Upon receiving a UDP packet, I need to respond to the sender with the address he used to send the packet to which I'm replying.

The recvfrom call lets me get the address of the sender, but how do I get the destination address of the received packet, which should match the address of one of the local host's interfaces?

like image 657
Matt Joiner Avatar asked Mar 12 '11 08:03

Matt Joiner


People also ask

Is there any acknowledgement for UDP?

The UDP protocol does not wait for any acknowledgement and is unable to detect any lost packets. When acknowledgement or detection is required, it must be done by the application layer. However, it is better to use a TCP Socket for communication when acknowledgement is necessary.

Are UDP packets guaranteed to arrive at their destination?

Unlike TCP, UDP doesn't guarantee the packets will get to the right destinations. This means UDP doesn't connect to the receiving computer directly, which TCP does. Rather, it sends the data out and relies on the devices in between the sending and receiving computers to correctly get the data where it's supposed to go.

What is a packet destination address?

What is Destination Address? The address to which a frame or packet of data is sent over a network. The destination address is used by hosts on the network to determine whether the packet or frame is intended for them or for other hosts.

How do I get UDP packets?

To receive packets from all the sending hosts, specify the remote IP address as 0.0. 0.0 . Match the port number specified in the Local IP Port parameter with the remote port number of the sending host. You can choose to receive the UDP packets in blocking or non-blocking mode.


2 Answers

I've constructed an example that extracts the source, destination and interface addresses. For brevity, no error checking is provided.

// sock is bound AF_INET socket, usually SOCK_DGRAM // include struct in_pktinfo in the message "ancilliary" control data setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &opt, sizeof(opt)); // the control data is dumped here char cmbuf[0x100]; // the remote/source sockaddr is put here struct sockaddr_in peeraddr; // if you want access to the data you need to init the msg_iovec fields struct msghdr mh = {     .msg_name = &peeraddr,     .msg_namelen = sizeof(peeraddr),     .msg_control = cmbuf,     .msg_controllen = sizeof(cmbuf), }; recvmsg(sock, &mh, 0); for ( // iterate through all the control headers     struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);     cmsg != NULL;     cmsg = CMSG_NXTHDR(&mh, cmsg)) {     // ignore the control headers that don't match what we want     if (cmsg->cmsg_level != IPPROTO_IP ||         cmsg->cmsg_type != IP_PKTINFO)     {         continue;     }     struct in_pktinfo *pi = CMSG_DATA(cmsg);     // at this point, peeraddr is the source sockaddr     // pi->ipi_spec_dst is the destination in_addr     // pi->ipi_addr is the receiving interface in_addr } 
like image 155
Matt Joiner Avatar answered Oct 05 '22 07:10

Matt Joiner


You set the IP_PKTINFO option using setsockopt and then use recvmsg and get a in_pktinfo structure in the msg_control member of struct msghdr. the in_pktinfo has a field with the destination address of the packet.

See: http://www.linuxquestions.org/questions/programming-9/how-to-get-destination-address-of-udp-packet-600103/ where I found the answer for more details.

like image 26
gby Avatar answered Oct 05 '22 08:10

gby