From 1da6888188fb9f1db06151240c2aa4b2a6c4c18b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 3 Aug 2010 18:59:14 +0000 Subject: [PATCH] helper-program to use iptables --- src/vpn/Makefile.am | 14 ++--- src/vpn/gnunet-helper-hijack-dns.c | 91 ++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 src/vpn/gnunet-helper-hijack-dns.c diff --git a/src/vpn/Makefile.am b/src/vpn/Makefile.am index 8af6af749..77e49e098 100644 --- a/src/vpn/Makefile.am +++ b/src/vpn/Makefile.am @@ -10,16 +10,19 @@ endif if LINUX VPNBIN = gnunet-helper-vpn +HIJACKBIN = gnunet-helper-hijack-dns install-exec-hook: chown root $(bindir)/gnunet-helper-vpn || true chmod u+s $(bindir)/gnunet-helper-vpn || true + chown root $(bindir)/gnunet-helper-hijack-dns || true + chmod u+s $(bindir)/gnunet-helper-hijack-dns || true else install-exec-hook: endif bin_PROGRAMS = \ - gnunet-daemon-vpn $(VPNBIN) + gnunet-daemon-vpn $(VPNBIN) $(HIJACKBIN) gnunet_helper_vpn_SOURCES = \ @@ -27,13 +30,8 @@ gnunet_helper_vpn_SOURCES = \ gnunet-vpn-helper-p.h \ gnunet-vpn-tun.h gnunet-vpn-tun.c -# debug.c debug.h \ -# packet.h packet.c \ -# pretty-print.c pretty-print.h \ -# tcp.c tcp.h \ -# test.c \ -# tun.c tun.h \ -# udp.c udp.h +gnunet_helper_hijack_dns_SOURCES = \ + gnunet-helper-hijack-dns.c gnunet_daemon_vpn_SOURCES = \ gnunet-daemon-vpn.c gnunet-vpn-pretty-print.c diff --git a/src/vpn/gnunet-helper-hijack-dns.c b/src/vpn/gnunet-helper-hijack-dns.c new file mode 100644 index 000000000..7add2cc3e --- /dev/null +++ b/src/vpn/gnunet-helper-hijack-dns.c @@ -0,0 +1,91 @@ +/* + This file is part of GNUnet. + (C) 2010 Christian Grothoff + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ + +/** + * @file vpn/gnunet-helper-hijack-dns.c + * @brief + * @author Philipp Tölke + */ +#define _GNU_SOURCE + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +int fork_and_exec(char* file, char* cmd[]) { + pid_t pid = fork(); + if (pid < 0) { + fprintf(stderr, "could not fork: %m\n"); + return GNUNET_SYSERR; + } + + int st = 0; + + if (pid == 0) { + execv(file, cmd); + } else { + waitpid(pid, &st, 0); + } + return WIFEXITED(st) && (WEXITSTATUS(st) == 0); +} + +int main(int argc, char** argv) { + int delete = 0; + int port = 0; + if (argc < 2) return GNUNET_SYSERR; + + if (strncmp(argv[1], "-d", 2) == 0) { + if (argc < 3) return GNUNET_SYSERR; + delete = 1; + port = atoi(argv[2]); + } else { + port = atoi(argv[1]); + } + + if (port == 0) return GNUNET_SYSERR; + + struct stat s; + if (stat("/sbin/iptables", &s) < 0) { + fprintf(stderr, "stat on /sbin/iptables failed: %m\n"); + return GNUNET_SYSERR; + } + + char localport[7]; + snprintf(localport, 7, "%d", port); + + int r; + if (delete) { + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "nat", "-D", "OUTPUT", "-p", "udp", "--sport", localport, "--dport", "53", "-j", "ACCEPT", NULL}); + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "nat", "-D", "OUTPUT", "-p", "udp", "--dport", "53", "-j", "DNAT", "--to-destination", "10.10.10.2:53", NULL}); + } else { + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "nat", "-I", "OUTPUT", "1", "-p", "udp", "--sport", localport, "--dport", "53", "-j", "ACCEPT", NULL}); + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "nat", "-I", "OUTPUT", "2", "-p", "udp", "--dport", "53", "-j", "DNAT", "--to-destination", "10.10.10.2:53", NULL}); + } + if (r) return GNUNET_YES; + return GNUNET_SYSERR; +} -- 2.25.1