* 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);
}
/*}}}*/
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;
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*));
{
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);
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));
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;
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:
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;
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);
"gnunet-helper-hijack-dns",
"gnunet-hijack-dns",
port_s,
+ virt_dns,
NULL));
}
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);
"gnunet-hijack-dns",
"-d",
port_s,
+ virt_dns,
NULL);
}
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 */