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?
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.
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 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.
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.
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 }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With