From 4b7d5b4823c5f3b89f6ed98ed1ccd5862d5f8237 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 21 Sep 2010 11:04:55 +0000 Subject: [PATCH] hijack the DNS-Packets in another way The Problem with the old way (via DNAT) was, that, of course, the destination address was changed so the query could not be send to the original dns-server. This way (with policy-routing) the packets stay unchanged. This also might work for IPv6. --- src/vpn/gnunet-daemon-vpn.c | 2 +- src/vpn/gnunet-helper-hijack-dns.c | 25 +++++++++++++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 82692768f..1258f5120 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -169,7 +169,7 @@ static void message_token(void *cls, void *client, const struct GNUNET_MessageHe } else if (ntohs(pkt_tun->tun.type) == 0x0800) { struct ip_pkt *pkt = (struct ip_pkt*) message; struct ip_udp *udp = (struct ip_udp*) message; - if (pkt->ip_hdr.proto == 0x11 && udp->ip_hdr.dadr == 0x020a0a0a && ntohs(udp->udp_hdr.dpt) == 53 ) { + if (pkt->ip_hdr.proto == 0x11 && ntohs(udp->udp_hdr.dpt) == 53 ) { size_t len = sizeof(struct query_packet) + ntohs(udp->udp_hdr.len) - 9; /* 9 = 8 for the udp-header + 1 for the unsigned char data[1]; */ struct query_packet_list* query = GNUNET_malloc(len + 2*sizeof(struct query_packet_list*)); query->pkt.hdr.type = htons(GNUNET_MESSAGE_TYPE_LOCAL_QUERY_DNS); diff --git a/src/vpn/gnunet-helper-hijack-dns.c b/src/vpn/gnunet-helper-hijack-dns.c index cc002a8cb..7a41b27d2 100644 --- a/src/vpn/gnunet-helper-hijack-dns.c +++ b/src/vpn/gnunet-helper-hijack-dns.c @@ -64,17 +64,34 @@ int main(int argc, char** argv) { fprintf(stderr, "stat on /sbin/iptables failed: %s\n", strerror(errno)); return GNUNET_SYSERR; } + if (stat("/sbin/ip", &s) < 0) { + fprintf(stderr, "stat on /sbin/ip failed: %s\n", strerror(errno)); + 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}); +e4: + r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "del", "default", "via", "10.10.10.2","table","2", NULL}); +e3: + r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "del", "fwmark", "3", "table","2", NULL}); +e2: + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", "--dport", "53", "-j", "MARK", "--set-mark", "3", NULL}); +e1: + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-D", "OUTPUT", "-p", "udp", "--sport", localport, "--dport", "53", "-j", "ACCEPT", NULL}); + if (!delete) r = 0; } 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}); + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-I", "OUTPUT", "1", "-p", "udp", "--sport", localport, "--dport", "53", "-j", "ACCEPT", NULL}); + if (!r) goto e1; + r = fork_and_exec("/sbin/iptables", (char*[]){"iptables", "-t", "mangle", "-I", "OUTPUT", "2", "-p", "udp", "--dport", "53", "-j", "MARK", "--set-mark", "3", NULL}); + if (!r) goto e2; + r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "add", "fwmark", "3", "table","2", NULL}); + if (!r) goto e3; + r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "add", "default", "via", "10.10.10.2","table","2", NULL}); + if (!r) goto e4; } if (r) return GNUNET_YES; return GNUNET_SYSERR; -- 2.25.1