[tproxy] UDP tproxy
Thu, 14 Oct 2004 17:45:37 -0400 (EDT)
I've been googling for some information about using tproxy for UDP traffic but I am still
a bit confiused. I hope you guys can help me out.
I want to intercept, at the application layer with a C written program, all UDP traffic,
and then obtain the final destionation IP address and port.
So, please correct me if I am wrong, I need two rules:
iptables -t nat -A PREROUTING -j DNAT --to-dest 192.168.1.10
iptables -t tproxy -A PREROUTING -j TPROXY --on-port 1025
These two rules suppose to redirect all UDP traffic to my box (192.168.1.10) to my C
program listening to port 1025, am i right?
Now, my C program needs to obtain the payload, original destination IP address and port is
below. However I receive no ancilliary data, in my program msgh.msg_controllen is always
equal to zero.
All ideas are very welcomed.
PS. Here is the code:
struct sockaddr_in myAddr;
struct sockaddr_in originalAddr;
struct msghdr msgh;
struct iovec v;
unsigned char acilliarydatabuff;
unsigned char buffer[MAXBUFFSIZE];
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
memset((char *)&myAddr, 0x0, sizeof(struct sockaddr_in));
myAddr.sin_family = AF_INET;
myAddr.sin_port = htons(1025);
myAddr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(fd, (struct sockaddr *)&myAddr, sizeof(struct sockaddr_in)) == -1)
/* QUESTION 1:
* Do I need to use getsockopt or setsockopt in here???
* If so, what exactly should I pass as paramenters to getsockopt or setsockopt
* Krisztian Kovacs, in a message posted in this list on 07 Jul 2004, mentions
* that I need to use getsockopt, but I'm not sure about the
* paramenters I need to pass, can somebody please clarify this point?
/* QUESTION 2:
* The same message posted by Krisztian Kovacs mentions that I need to use
* recvmsg and that the original destination IP address and port is the
* acilliary data. Is the following code correct??? Is that how I suppose to
* extract the payload, original destination IP address and port
* from the ancilliary data?
memset((char *)&originalAddr, 0x0, sizeof(struct sockaddr_in));
memset(&msgh, 0, sizeof(msgh));
msgh.msg_name = &originalAddr;
msgh.msg_namelen = sizeof(struct sockaddr_in);
v.iov_base = buffer;
v.iov_len = MAXBUFFSIZE;
msgh.msg_iov = &v;
msgh.msg_iovlen = 1;
msgh.msg_control = acilliarydatabuff;
msgh.msg_controllen = 1000;
if ( (bytes = recvmsg(fd, &msgh, 0)) == -1 )
// Get ancilliary data
struct cmsghdr *cmsg;
if (msgh.msg_controllen > 0)
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg!=NULL; cmsg = CMSG_NXTHDR(&msgh,cmsg))
/* QUESTION 3:
* Is the payload suppose to be in cdata?
void *cdata = CMSG_DATA(cmsg);
/* QUESTION 4:
* The original destination IP address and port are in msgh.msg_name???
sockaddr_in *originalDst = (sockaddr_in *)(msgh.msg_name);
/* Original destination IP address in originalDst->sin_addr.s_addr and
* original destination port in originalDst->sin_port
* Does any of this make any sense???