Created
November 13, 2012 16:01
-
-
Save qsorix/4066589 to your computer and use it in GitHub Desktop.
Getting original destination address on a UDP socket
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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