tunproxy
authorGiuseppe Lettieri <g.lettieri@iet.unipi.it>
Wed, 3 Apr 2013 14:17:35 +0000 (16:17 +0200)
committerGiuseppe Lettieri <g.lettieri@iet.unipi.it>
Wed, 3 Apr 2013 14:17:35 +0000 (16:17 +0200)
From Philippe Biondi and Felician Nemeth.

planetlab/exp-tool/tunproxy.c [new file with mode: 0644]

diff --git a/planetlab/exp-tool/tunproxy.c b/planetlab/exp-tool/tunproxy.c
new file mode 100644 (file)
index 0000000..0f3ab81
--- /dev/null
@@ -0,0 +1,141 @@
+/*\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