GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
+ GNUNET_HashCode *key;
/* ethertype is ipv6 */
if (ntohs (pkt_tun->tun.type) == 0x86dd)
struct ip6_tcp *pkt6_tcp;
struct ip6_udp *pkt6_udp;
struct ip6_icmp *pkt6_icmp;
- GNUNET_HashCode *key;
switch (pkt6->ip6_hdr.nxthdr)
{
pkt6_tcp = (struct ip6_tcp *) pkt6;
pkt6_udp = (struct ip6_udp *) pkt6;
- if ((key = address_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
+ if ((key = address6_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
{
struct map_entry *me =
GNUNET_CONTAINER_multihashmap_get (hashmap, key);
pkt6_icmp = (struct ip6_icmp *) pkt6;
/* If this packet is an icmp-echo-request and a mapping exists, answer */
if (pkt6_icmp->icmp_hdr.type == 0x80
- && (key = address_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
+ && (key = address6_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
{
GNUNET_free (key);
pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size));
memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size));
- GNUNET_SCHEDULER_add_now (&send_icmp_response, pkt6_icmp);
+ GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp);
}
break;
}
{
struct ip_pkt *pkt = (struct ip_pkt *) message;
struct ip_udp *udp = (struct ip_udp *) message;
+ struct ip_tcp *pkt_tcp;
+ struct ip_udp *pkt_udp;
+ struct ip_icmp *pkt_icmp;
GNUNET_assert (pkt->ip_hdr.version == 4);
/* Send dns-packets to the service-dns */
GNUNET_YES,
&send_query, NULL);
}
+ else
+ {
+ uint32_t dadr = pkt->ip_hdr.dadr;
+ unsigned char *c = (unsigned char*)&dadr;
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n",
+ c[0],
+ c[1],
+ c[2],
+ c[3],
+ pkt->ip_hdr.proto);
+ switch (pkt->ip_hdr.proto)
+ {
+ case 0x06: /* TCP */
+ case 0x11: /* UDP */
+ pkt_tcp = (struct ip_tcp*) pkt;
+ pkt_udp = (struct ip_udp*) pkt;
+
+ if ((key = address4_mapping_exists (dadr)) != NULL)
+ {
+ }
+ break;
+ case 0x01:
+ /* ICMP */
+ pkt_icmp = (struct ip_icmp*)pkt;
+ if (pkt_icmp->icmp_hdr.type == 0x8 &&
+ (key = address4_mapping_exists (dadr)) != NULL)
+ {
+ GNUNET_free(key);
+ pkt_icmp = GNUNET_malloc(ntohs(pkt->shdr.size));
+ memcpy(pkt_icmp, pkt, ntohs(pkt->shdr.size));
+ GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp);
+ }
+ break;
+ }
+ }
}
}
* @return the hash of the IP-Address if a mapping exists, NULL otherwise
*/
GNUNET_HashCode*
-address_mapping_exists(unsigned char addr[]) {
+address6_mapping_exists(unsigned char addr[]) {
GNUNET_HashCode* key = GNUNET_malloc(sizeof(GNUNET_HashCode));
unsigned char* k = (unsigned char*)key;
memset(key, 0, sizeof(GNUNET_HashCode));
}
}
+/**
+ * @return the hash of the IP-Address if a mapping exists, NULL otherwise
+ */
+GNUNET_HashCode *
+address4_mapping_exists (uint32_t addr)
+{
+ GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
+ memset (key, 0, sizeof (GNUNET_HashCode));
+ unsigned char *c = (unsigned char *) &addr;
+ unsigned char *k = (unsigned char *) key;
+ unsigned int i;
+ for (i = 0; i < 4; i++)
+ k[3 - i] = c[i];
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n",
+ *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]);
+
+ if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
+ return key;
+ else
+ {
+ GNUNET_free (key);
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
+ return NULL;
+ }
+}
+
static void
collect_mappings(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULER_TaskContext* tc) {
if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
}
void
-send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
+send_icmp4_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
+ if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
+ return;
+
+ struct ip_icmp* request = cls;
+
+ struct ip_icmp* response = alloca(ntohs(request->shdr.size));
+ GNUNET_assert(response != NULL);
+ memset(response, 0, ntohs(request->shdr.size));
+
+ response->shdr.size = request->shdr.size;
+ response->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
+
+ response->tun.flags = 0;
+ response->tun.type = htons(0x0800);
+
+ response->ip_hdr.hdr_lngth = 5;
+ response->ip_hdr.version = 4;
+ response->ip_hdr.proto = 0x01;
+ response->ip_hdr.dadr = request->ip_hdr.sadr;
+ response->ip_hdr.sadr = request->ip_hdr.dadr;
+ response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
+
+ response->ip_hdr.chks = calculate_ip_checksum((uint16_t*)&response->ip_hdr, 20);
+
+ response->icmp_hdr.code = 0;
+ response->icmp_hdr.type = 0x0;
+
+ /* Magic, more Magic! */
+ response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
+
+ /* Copy the rest of the packet */
+ memcpy(response+1, request+1, ntohs(request->shdr.size) - sizeof(struct ip_icmp));
+
+ write_to_helper(response, ntohs(response->shdr.size));
+
+ GNUNET_free(request);
+}
+
+void
+send_icmp6_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
return;
GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
value->heap_node = GNUNET_CONTAINER_heap_insert (heap, value,
GNUNET_TIME_absolute_get ().abs_value);
+ GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Mapping is saved in the hashmap with key %08x.\n",
+ *((uint32_t*)(&key)));
if (GNUNET_CONTAINER_heap_get_size(heap) > max_mappings)
GNUNET_SCHEDULER_add_now(collect_mappings, NULL);
}
}
memcpy(&pkt6->udp_hdr, pkt, ntohs(pkt->len));
- GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr);
+ GNUNET_HashCode* key = address6_mapping_exists(pkt6->ip6_hdr.sadr);
GNUNET_assert (key != NULL);
struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key);
}
memcpy(&pkt6->tcp_hdr, pkt, pktlen);
- GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr);
+ GNUNET_HashCode* key = address6_mapping_exists(pkt6->ip6_hdr.sadr);
GNUNET_assert (key != NULL);
struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key);
void
process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc);
-void
-send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+void send_icmp6_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+void send_icmp4_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
size_t
send_udp_service (void *cls, size_t size, void *buf);
-GNUNET_HashCode* address_mapping_exists(unsigned char addr[]);
+GNUNET_HashCode* address6_mapping_exists(unsigned char addr[]);
+GNUNET_HashCode* address4_mapping_exists(uint32_t addr);
unsigned int port_in_ports (uint64_t ports, uint16_t port);
struct dns_query_line *dque =
(struct dns_query_line *) (dpkt->data +
(query_states[dns->s.id].namelen));
+
+ struct dns_record_line *drec_data =
+ (struct dns_record_line *) (dpkt->data +
+ (query_states[dns->s.id].namelen) +
+ sizeof (struct dns_query_line) + 2);
if (16 == answer->pkt.addrsize)
{
answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA;
dque->type = htons (28); /* AAAA */
+ drec_data->type = htons (28); /* AAAA */
+ drec_data->data_len = htons (16);
}
else
{
answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_A;
dque->type = htons (1); /* A */
+ drec_data->type = htons (1); /* A*/
+ drec_data->data_len = htons (4);
}
dque->class = htons (1); /* IN */
(char *) (dpkt->data + (query_states[dns->s.id].namelen) +
sizeof (struct dns_query_line));
memcpy (anname, "\xc0\x0c", 2);
-
- struct dns_record_line *drec_data =
- (struct dns_record_line *) (dpkt->data +
- (query_states[dns->s.id].namelen) +
- sizeof (struct dns_query_line) + 2);
- drec_data->type = htons (28); /* AAAA */
drec_data->class = htons (1); /* IN */
drec_data->ttl = pdns->answers[0]->ttl;
- drec_data->data_len = htons (16);
/* Calculate at which offset in the packet the IPv6-Address belongs, it is
* filled in by the daemon-vpn */
unsigned char data[1];
};
+struct ip_icmp {
+ struct GNUNET_MessageHeader shdr;
+ struct pkt_tun tun;
+ struct ip_hdr ip_hdr;
+ struct icmp_hdr icmp_hdr;
+};
+
#endif