Skip to content

Instantly share code, notes, and snippets.

@qsorix
Created November 13, 2012 16:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qsorix/4066589 to your computer and use it in GitHub Desktop.
Save qsorix/4066589 to your computer and use it in GitHub Desktop.
Getting original destination address on a UDP socket
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <string.h>
int main()
{
// --------------------------------------------
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9876);
addr.sin_addr.s_addr = INADDR_ANY;
int udp_socket = socket(AF_INET, SOCK_DGRAM, 0);
int ret = bind(udp_socket, (sockaddr*)&addr, sizeof(addr));
int flags = 1;
ret = setsockopt(udp_socket, IPPROTO_IP, IP_RECVORIGDSTADDR, &flags, sizeof(flags));
// --------------------------------------------
struct sockaddr_in cl_addr;
cl_addr.sin_family = AF_INET;
cl_addr.sin_port = htons(9879);
cl_addr.sin_addr.s_addr = INADDR_ANY;
int client_socket = socket(AF_INET, SOCK_DGRAM, 0);
std::cout << "client socket: " << client_socket << std::endl;
ret = bind(client_socket, (sockaddr*)&cl_addr, sizeof(cl_addr));
std::cout << "client bind ret= " << ret << std::endl;
// --------------------------------------------
char buf[1] = {'f'};
ret = sendto(client_socket, buf, 1, 0, (sockaddr*)&addr, sizeof(addr));
std::cout << "client send ret=" << ret << std::endl;
// --------------------------------------------
char buf2[1] = { 0 };
struct iovec indata = {0};
indata.iov_base = buf2;
indata.iov_len = sizeof(buf2);
char inmsg[1000];
struct msghdr incoming_msg = { 0 };
incoming_msg.msg_iov = &indata;
incoming_msg.msg_iovlen = 1;
incoming_msg.msg_control = inmsg;
incoming_msg.msg_controllen = sizeof(inmsg);
ret = recvmsg(udp_socket, &incoming_msg, 0);
sockaddr_in dstaddr = { 0 };
for (struct cmsghdr* cmsg = CMSG_FIRSTHDR(&incoming_msg);
cmsg != NULL;
cmsg = CMSG_NXTHDR(&incoming_msg,cmsg))
{
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_RECVORIGDSTADDR))
{
memcpy (&dstaddr, CMSG_DATA(cmsg), sizeof (dstaddr));
dstaddr.sin_family = AF_INET;
}
}
std::cout << " original dst address " << std::hex << ntohl(dstaddr.sin_addr.s_addr) << std::dec << ":" << ntohs(dstaddr.sin_port) << std::endl;
std::cout << "buf2[0] = " << buf2[0] << std::endl;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment