--- /dev/null
+/*\r
+ * tunproxy.c --- small demo program for tunneling over UDP with tun/tap\r
+ *\r
+ * Copyright (C) 2003 Philippe Biondi <phil@secdev.org>\r
+ * Copyright (C) 2013 Felician Nemeth <nemethf@tmit.bme.hu>\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify it\r
+ * under the terms of the GNU Lesser General Public License as published by\r
+ * the Free Software Foundation.\r
+ *\r
+ * This program is distributed in the hope that it will be useful, but\r
+ * WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * http://www.secdev.org/projects/tuntap_udp/files/tunproxy.c\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <sys/types.h>\r
+#include <sys/socket.h>\r
+#include <netinet/in.h>\r
+#include <arpa/inet.h>\r
+#include <string.h>\r
+#include <net/if.h>\r
+#include <linux/if_tun.h>\r
+#include <getopt.h>\r
+#include <sys/ioctl.h>\r
+#include <errno.h>\r
+\r
+#define PERROR(x) do { perror(x); exit(1); } while (0)\r
+#define ERROR(x, args ...) do { fprintf(stderr,"ERROR:" x, ## args); exit(1); } while (0)\r
+\r
+extern void exit(int);\r
+\r
+void usage()\r
+{\r
+ fprintf(stderr, "Usage: tunproxy -t target_ip:port [-p local_port] [-e]\n");\r
+ exit(0);\r
+}\r
+\r
+int main(int argc, char *argv[])\r
+{\r
+ struct sockaddr_in sin, sout, remote;\r
+ struct ifreq ifr;\r
+ int fd, s, remote_len, remote_port, local_port, l;\r
+ unsigned int soutlen;\r
+ char c, *p, *remote_ip = 0;\r
+ char buf[2000];\r
+ fd_set fdset;\r
+\r
+ int TUNMODE = IFF_TUN, DEBUG = 0;\r
+\r
+ while ((c = getopt(argc, argv, "t:p:ehd")) != -1) {\r
+ switch (c) {\r
+ case 'h':\r
+ usage();\r
+ case 'd':\r
+ DEBUG++;\r
+ break;\r
+ case 'p':\r
+ local_port = atoi(optarg);\r
+ break;\r
+ case 't':\r
+ p = memchr(optarg,':',16);\r
+ if (!p) ERROR("invalid argument : [%s]\n",optarg);\r
+ *p = 0;\r
+ remote_ip = optarg;\r
+ remote_port = atoi(p+1);\r
+ break;\r
+ case 'e':\r
+ TUNMODE = IFF_TAP;\r
+ break;\r
+ default:\r
+ usage();\r
+ }\r
+ }\r
+ if (remote_ip == 0) usage();\r
+\r
+ if ( (fd = open("/dev/net/tun",O_RDWR)) < 0) PERROR("open");\r
+\r
+ memset(&ifr, 0, sizeof(ifr));\r
+ ifr.ifr_flags = TUNMODE | IFF_NO_PI;\r
+ strncpy(ifr.ifr_name, "toto%d", IFNAMSIZ);\r
+ if (ioctl(fd, TUNSETIFF, (void *)&ifr) < 0) PERROR("ioctl");\r
+\r
+ printf("Allocated interface %s. Configure and use it\n", ifr.ifr_name);\r
+ \r
+ s = socket(PF_INET, SOCK_DGRAM, 0);\r
+ sin.sin_family = AF_INET;\r
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);\r
+ sin.sin_port = htons(local_port);\r
+\r
+ if ( bind(s,(struct sockaddr *)&sin, sizeof(sin)) < 0)\r
+ PERROR("bind");\r
+\r
+ remote_len = sizeof(remote);\r
+ memset(&remote, 0, remote_len);\r
+ remote.sin_family = AF_INET;\r
+ remote.sin_port = htons(remote_port);\r
+ remote.sin_addr.s_addr=inet_addr(remote_ip);\r
+\r
+ while (1) {\r
+ FD_ZERO(&fdset);\r
+ FD_SET(fd, &fdset);\r
+ FD_SET(s, &fdset);\r
+ if (select(fd+s+1, &fdset,NULL,NULL,NULL) < 0) PERROR("select");\r
+ if (FD_ISSET(fd, &fdset)) {\r
+ if (DEBUG)\r
+ write(1,">", 1);\r
+ l = read(fd, buf, sizeof(buf));\r
+ if (l < 0) \r
+ PERROR("read");\r
+ if (sendto(s, buf, l, 0, (struct sockaddr *)&remote, remote_len) < 0)\r
+ PERROR("sendto");\r
+ }\r
+ if (FD_ISSET(s, &fdset)) {\r
+ if (DEBUG) \r
+ write(1,"<", 1);\r
+ soutlen = sizeof(sout);\r
+ l = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&sout, &soutlen);\r
+ if (l == -1) {\r
+ write(1,"(", 1);\r
+ fprintf(stderr, "[%s,%d]", strerror(errno), l);\r
+ continue;\r
+ }\r
+ if ((sout.sin_addr.s_addr != remote.sin_addr.s_addr) ||\r
+ (sout.sin_port != remote.sin_port)) {\r
+ printf("Got packet from %s:%u instead of %s:%u\n", \r
+ inet_ntoa(sout.sin_addr), ntohs(sout.sin_port),\r
+ inet_ntoa(remote.sin_addr), ntohs(remote.sin_port));\r
+ }\r
+ if (write(fd, buf, l) < 0) PERROR("write");\r
+ }\r
+ }\r
+}\r