Hi, 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. Any suggestions?? All ideas are very welcomed. Thank you Xavier PS. Here is the code: int main() { int fd; struct sockaddr_in myAddr; struct sockaddr_in originalAddr; struct msghdr msgh; struct iovec v; unsigned char acilliarydatabuff[1000]; unsigned char buffer[MAXBUFFSIZE]; int bytes; if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) return 0; 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) return 0; /* 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? */ for(;;) { /* 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 ) continue; // 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??? */ } } }
Hi, 2004-10-14, cs keltezéssel 23:45-kor Javier Govea ezt írta:
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
You don't need the DNAT rule, only the TPROXY one. You can also specify a destination IP to TPROXY with --on-ip, if you omit that argument it will use the address of the interface the packet came in.
/* 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? */
Yes, you have to set the RECVORIGADDRS socket option with setsockopt() in order to receive the original address with recvmsg().
/* 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? */
You got the msg setup right, but do not process the received msg appropriately. Read below.
/* QUESTION 3: * Is the payload suppose to be in cdata? */ void *cdata = CMSG_DATA(cmsg);
No, it's in msgh.msg_iov.iov_base (buffer in your case).
/* QUESTION 4: * The original destination IP address and port are in msgh.msg_name??? */ sockaddr_in *originalDst = (sockaddr_in *)(msgh.msg_name);
No, it's in CMSG_DATA(cmsg).
/* 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??? */
Yes. But please take a look at the example code, redirect-udp-recv.c is _exactly_ you're looking for. -- Regards, Krisztian KOVACS
participants (2)
-
Javier Govea
-
KOVACS Krisztian