From 0b62b71e4bc1635d90f3ccf16db5af5fc7a383ea Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Sat, 5 Feb 2011 21:52:39 +0000 Subject: [PATCH] Use the configures IP-addresses correctly --- src/vpn/gnunet-daemon-vpn.c | 53 +++++++++++++--------- src/vpn/gnunet-helper-hijack-dns.c | 9 ++-- src/vpn/gnunet-service-dns.c | 70 +++++++++++++++++++++++++++--- 3 files changed, 102 insertions(+), 30 deletions(-) diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 1213dd9f1..0c3c137fa 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -215,10 +215,27 @@ send_udp_to_peer (void *cls, * Create a new Address from an answer-packet */ void -new_ip6addr(char* buf, const GNUNET_HashCode *peer, const GNUNET_HashCode *service_desc) { /* {{{ */ - memcpy(buf+14, (int[]){htons(0x3412)}, 2); - memcpy(buf+8, service_desc, 6); - memcpy(buf, peer, 8); +new_ip6addr(unsigned char* buf, const GNUNET_HashCode *peer, const GNUNET_HashCode *service_desc) { /* {{{ */ + char* ipv6addr; + unsigned long long ipv6prefix; + GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); + GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "vpn", "IPV6PREFIX", &ipv6prefix)); + GNUNET_assert(ipv6prefix < 127); + ipv6prefix = (ipv6prefix + 7)/8; + + inet_pton (AF_INET6, ipv6addr, buf); + GNUNET_free(ipv6addr); + + int peer_length = 16 - ipv6prefix - 6; + if (peer_length <= 0) + peer_length = 0; + + int service_length = 16 - ipv6prefix - peer_length; + if (service_length <= 0) + service_length = 0; + + memcpy(buf+ipv6prefix, service_desc, service_length); + memcpy(buf+ipv6prefix+service_length, peer, peer_length); } /*}}}*/ @@ -246,7 +263,16 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { GNUNET_HashCode key; memset(&key, 0, sizeof(GNUNET_HashCode)); - new_ip6addr((char*)&key, &pkt->service_descr.peer, &pkt->service_descr.service_descriptor); + + unsigned char* c = ((unsigned char*)pkt)+ntohs(pkt->addroffset); + unsigned char* k = (unsigned char*)&key; + new_ip6addr(c, &pkt->service_descr.peer, &pkt->service_descr.service_descriptor); + /* + * Copy the newly generated ip-address to the key backwarts (as only the first part is hashed) + */ + unsigned int i; + for (i = 0; i < 16; i++) + k[15-i] = c[i]; uint16_t namelen = strlen((char*)pkt->data+12)+1; @@ -268,14 +294,6 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not store to hashmap\n"); } - /* - * Copy the newly generated backward ip-address to the packet - */ - char* c = ((char*)pkt)+ntohs(pkt->addroffset); - char* k = (char*)&key; - unsigned int i; - for (i = 0; i < 16; i++) - c[15-i] = k[i]; list = GNUNET_malloc(htons(pkt->hdr.size) + 2*sizeof(struct answer_packet_list*)); @@ -374,17 +392,16 @@ receive_udp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel, { GNUNET_HashCode *desc = (GNUNET_HashCode *) (message + 1); struct udp_pkt *pkt = (struct udp_pkt *) (desc + 1); - char addr[16]; const struct GNUNET_PeerIdentity* other = GNUNET_MESH_get_peer(tunnel); - new_ip6addr(addr, &other->hashPubKey, desc); - size_t size = sizeof(struct ip6_udp) + ntohs(pkt->len) - 1 - sizeof(struct udp_pkt); struct ip6_udp* pkt6 = alloca(size); GNUNET_assert(pkt6 != NULL); + new_ip6addr(pkt6->ip6_hdr.sadr, &other->hashPubKey, desc); + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Relaying calc:%d gnu:%d udp:%d bytes!\n", size, ntohs(message->size), ntohs(pkt->len)); pkt6->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER); @@ -401,10 +418,6 @@ receive_udp_back (void *cls, struct GNUNET_MESH_Tunnel* tunnel, pkt6->ip6_hdr.nxthdr = 0x11; pkt6->ip6_hdr.hoplmt = 0xff; - unsigned int i; - for (i = 0; i < 16; i++) - pkt6->ip6_hdr.sadr[15-i] = addr[i]; - { char* ipv6addr; GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); diff --git a/src/vpn/gnunet-helper-hijack-dns.c b/src/vpn/gnunet-helper-hijack-dns.c index 7a41b27d2..ee7ae1873 100644 --- a/src/vpn/gnunet-helper-hijack-dns.c +++ b/src/vpn/gnunet-helper-hijack-dns.c @@ -47,14 +47,17 @@ int fork_and_exec(char* file, char* cmd[]) { int main(int argc, char** argv) { int delete = 0; int port = 0; - if (argc < 2) return GNUNET_SYSERR; + char* virt_dns; + if (argc < 3) return GNUNET_SYSERR; if (strncmp(argv[1], "-d", 2) == 0) { if (argc < 3) return GNUNET_SYSERR; delete = 1; port = atoi(argv[2]); + virt_dns = argv[3]; } else { port = atoi(argv[1]); + virt_dns = argv[2]; } if (port == 0) return GNUNET_SYSERR; @@ -75,7 +78,7 @@ int main(int argc, char** argv) { int r; if (delete) { e4: - r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "del", "default", "via", "10.10.10.2","table","2", NULL}); + r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "del", "default", "via", virt_dns,"table","2", NULL}); e3: r = fork_and_exec("/sbin/ip", (char*[]){"ip", "rule", "del", "fwmark", "3", "table","2", NULL}); e2: @@ -90,7 +93,7 @@ e1: 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}); + r = fork_and_exec("/sbin/ip", (char*[]){"ip", "route", "add", "default", "via", virt_dns, "table","2", NULL}); if (!r) goto e4; } if (r) return GNUNET_YES; diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index b8488d3e1..12a85cdd1 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c @@ -104,6 +104,13 @@ struct receive_dht_cls { static void hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { char port_s[6]; + char* virt_dns; + + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "VIRTDNS", &virt_dns)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No entry 'VIRTDNS' in configuration!\n"); + exit(1); + } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Hijacking, port is %d\n", dnsoutport); snprintf(port_s, 6, "%d", dnsoutport); @@ -112,6 +119,7 @@ hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { "gnunet-helper-hijack-dns", "gnunet-hijack-dns", port_s, + virt_dns, NULL)); } @@ -121,6 +129,13 @@ hijack(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { static void unhijack(unsigned short port) { char port_s[6]; + char* virt_dns; + + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "VIRTDNS", &virt_dns)) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "No entry 'VIRTDNS' in configuration!\n"); + exit(1); + } GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "unHijacking, port is %d\n", port); snprintf(port_s, 6, "%d", port); @@ -130,6 +145,7 @@ unhijack(unsigned short port) { "gnunet-hijack-dns", "-d", port_s, + virt_dns, NULL); } @@ -403,16 +419,56 @@ receive_query(void *cls, goto outfree; } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Query for '%s'; namelen=%d\n", pdns->queries[0]->name, pdns->queries[0]->namelen); /* The query is for a PTR of a previosly resolved virtual IP */ if (htons(pdns->queries[0]->qtype) == 12 && - pdns->queries[0]->namelen > 19 && - 0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - 19), ".4.3.2.1.ip6.arpa.", 19)) + 74 == pdns->queries[0]->namelen) { - GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Reverse-Query for .gnunet!\n"); - - GNUNET_SCHEDULER_add_now(send_rev_query, pdns); - - goto out; + char* ipv6addr; + char ipv6[16]; + char ipv6rev[74] = "X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.X.ip6.arpa."; + unsigned int i; + unsigned long long ipv6prefix; + unsigned int comparelen; + + GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "vpn", "IPV6ADDR", &ipv6addr)); + inet_pton (AF_INET6, ipv6addr, ipv6); + GNUNET_free(ipv6addr); + + GNUNET_assert(GNUNET_OK == GNUNET_CONFIGURATION_get_value_number(cfg, "vpn", "IPV6PREFIX", &ipv6prefix)); + GNUNET_assert(ipv6prefix < 127); + ipv6prefix = (ipv6prefix + 7)/8; + + for (i = ipv6prefix; i < 16; i++) + ipv6[i] = 0; + + for (i = 0; i < 16; i++) + { + unsigned char c1 = ipv6[i] >> 4; + unsigned char c2 = ipv6[i] & 0xf; + + if (c1 <= 9) + ipv6rev[62-(4*i)] = c1 + '0'; + else + ipv6rev[62-(4*i)] = c1 + 87; /* 87 is the difference between 'a' and 10 */ + + if (c2 <= 9) + ipv6rev[62-((4*i)+2)] = c2 + '0'; + else + ipv6rev[62-((4*i)+2)] = c2 + 87; + } + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "My network is %s'.\n", ipv6rev); + comparelen = 10 + 4*ipv6prefix; + if(0 == strncmp(pdns->queries[0]->name+(pdns->queries[0]->namelen - comparelen), + ipv6rev + (74 - comparelen), + comparelen)) + { + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Reverse-Query for .gnunet!\n"); + + GNUNET_SCHEDULER_add_now(send_rev_query, pdns); + + goto out; + } } /* The query should be sent to the network */ -- 2.25.1