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; }
participants (1)
-
elyasaf