[tproxy] example of using udp on tproxy4
elyasaf
elyasaf at icomsw.com
Sun Nov 30 13:43:02 CET 2008
> While I can see example of using udp on tproxy2 onto the
> redirect-udp-recv.c
> file, I can't find equivalent on tproxy4.
>
> Here are my iptables\ip route redirection lines:
> ${iptables} -t mangle -N DIVERT
> ${iptables} -t mangle -A PREROUTING -p udp -m socket -j DIVERT
> ${iptables} -t mangle -A DIVERT -j MARK --set-mark 1
> ${iptables} -t mangle -A DIVERT -j ACCEPT
> ${iptables} -t mangle -A PREROUTING -p udp --dport 1500 -j TPROXY
> --tproxy-mark 1 --on-port 3127
>
> ip rule add fwmark 1 lookup 100
> ip route add local 0.0.0.0/0 dev lo table 100
#include <netdb.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#define LOCAL_PROXY_PORT 3127
#define MAX_MSG 100
#ifndef IP_TRANSPARENT
#define IP_TRANSPARENT 19
#endif
#ifndef IP_ORIGADDRS
#define IP_ORIGADDRS 20
#endif
#ifndef IP_RECVORIGADDRS
#define IP_RECVORIGADDRS IP_ORIGADDRS
#endif
#define CTL_BUF_SIZE 64
int main(int argc, char *argv[]) {
int fd, rc, n, cliLen, flags;
struct sockaddr_in sourceAddr, destinationAddr , proxyAddr;
char buf[MAX_MSG];
struct in_origaddrs *ioa;
/* socket creation */
fd=socket(AF_INET, SOCK_DGRAM, 0);
if(fd<0) {
printf("%s: cannot open socket \n",argv[0]);
exit(1);
}
flags=1;
if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &flags, sizeof(int)) == -1){
perror("proxy-setsockopt() IP_TRANSPARENT error!");
exit(1);
}else
printf("proxy-setsockopt IP_TRANSPARENT is OK...\n");
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &flags, sizeof(flags));
if ( setsockopt(fd, SOL_IP, IP_ORIGADDRS , &flags, sizeof(flags))){
perror("proxy-setsockopt() IP_ORIGADDRS error");
}else{
printf("proxy-setsockopt IP_ORIGADDRS is OK...\n");
}
/* bind local server port */
proxyAddr.sin_family = AF_INET;
proxyAddr.sin_addr.s_addr = htonl(INADDR_ANY);
proxyAddr.sin_port = htons(LOCAL_PROXY_PORT);
rc = bind (fd, (struct sockaddr *) &proxyAddr,sizeof(proxyAddr));
if(rc<0) {
printf("%s: cannot bind port number %d \n",argv[0], LOCAL_PROXY_PORT);
exit(1);
}
printf("%s: waiting for data on port UDP %u\n",argv[0],LOCAL_PROXY_PORT);
/* proxy infinite loop */
while(1) {
struct msghdr msg;
struct cmsghdr *cmsg;
struct iovec iov;
char ctl_buf[CTL_BUF_SIZE];
/* init buffer */
memset(buf,0,MAX_MSG);
memset(&msg, 0, sizeof(msg));
msg.msg_name = &sourceAddr;
msg.msg_namelen = sizeof(sourceAddr);
msg.msg_controllen = CTL_BUF_SIZE;
msg.msg_control = ctl_buf;
msg.msg_iovlen = 1;
msg.msg_iov = &iov;
iov.iov_base = buf;
iov.iov_len = MAX_MSG;
n = recvmsg(fd, &msg, 0);
if(n<0) {
printf("%s: cannot receive data \n",argv[0]);
perror("recvmsg");
continue;
}
printf("%s: source %s:UDP%u : %s \n",
argv[0],inet_ntoa(sourceAddr.sin_addr),
ntohs(sourceAddr.sin_port),buf);
memset(&destinationAddr,0,sizeof(struct sockaddr_in));
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg =
CMSG_NXTHDR(&msg,cmsg)){
if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type ==
IP_RECVORIGADDRS){
memcpy(&destinationAddr,(struct sockaddr_in
*)CMSG_DATA(cmsg),sizeof(struct sockaddr_in));
destinationAddr.sin_family = AF_INET;
printf("%s: destination %s:UDP%u\n",
argv[0],inet_ntoa(destinationAddr.sin_addr),
ntohs(destinationAddr.sin_port));
send_to_transparenty(buf,n,&sourceAddr,&destinationAddr);
//sendto(fd,buf,n,&sourceAddr,&destinationAddr);
}
}
}/* end of proxy infinite loop */
return 0;
}
int send_to_transparenty(char *buf,int len,struct sockaddr_in *source,struct
sockaddr_in *destination){
int fd,flags,i;
fd=socket(AF_INET, SOCK_DGRAM, 0);
flags=1;
if (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &flags, sizeof(int)) ==
-1){
perror("destination-setsockopt() IP_TRANSPARENT error!");
return;
}else{
//printf("destination-setsockopt IP_TRANSPARENT is
OK...\n");
}
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flags, sizeof(flags));
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &flags, sizeof(flags));
if(bind (fd, (struct sockaddr *) source,sizeof(*source))==-1){
perror("source-bind() error!");
return;
}
flags=0;
if(sendto(fd,buf,len,flags,(struct sockaddr
*)destination,sizeof(*destination))==-1){
perror("destination-sendto() error!");
return 0;
}else{
printf("send to other side\n");
}
close(fd);
return 1;
}
More information about the tproxy
mailing list