hijack the DNS-Packets in another way
authorPhilipp Tölke <toelke@in.tum.de>
Tue, 21 Sep 2010 11:04:55 +0000 (11:04 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Tue, 21 Sep 2010 11:04:55 +0000 (11:04 +0000)
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
src/vpn/gnunet-helper-hijack-dns.c

index 82692768f2d7b94485449a16a595a515b0fca90c..1258f51201a0bd8c16208ef5fec56f2ac6372f6a 100644 (file)
@@ -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);
index cc002a8cbe62c9803c4419565a01c6f21f75ebf8..7a41b27d2821f1835236bb546a2ede2ec68bb32a 100644 (file)
@@ -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;