From ca51d9b99345521ca990e092234e140316ff95bd Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Wed, 27 Jul 2011 07:28:21 +0000 Subject: [PATCH] reply ipv4-icmp --- src/vpn/gnunet-daemon-vpn-helper.c | 46 ++++++++++++++++-- src/vpn/gnunet-daemon-vpn.c | 78 ++++++++++++++++++++++++++++-- src/vpn/gnunet-daemon-vpn.h | 7 +-- src/vpn/gnunet-service-dns.c | 16 +++--- src/vpn/gnunet-vpn-packet.h | 7 +++ 5 files changed, 136 insertions(+), 18 deletions(-) diff --git a/src/vpn/gnunet-daemon-vpn-helper.c b/src/vpn/gnunet-daemon-vpn-helper.c index 48cb4e6cf..76d169143 100644 --- a/src/vpn/gnunet-daemon-vpn-helper.c +++ b/src/vpn/gnunet-daemon-vpn-helper.c @@ -223,6 +223,7 @@ message_token (void *cls __attribute__((unused)), 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) @@ -232,7 +233,6 @@ message_token (void *cls __attribute__((unused)), struct ip6_tcp *pkt6_tcp; struct ip6_udp *pkt6_udp; struct ip6_icmp *pkt6_icmp; - GNUNET_HashCode *key; switch (pkt6->ip6_hdr.nxthdr) { @@ -241,7 +241,7 @@ message_token (void *cls __attribute__((unused)), 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); @@ -389,12 +389,12 @@ message_token (void *cls __attribute__((unused)), 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; } @@ -404,6 +404,9 @@ message_token (void *cls __attribute__((unused)), { 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 */ @@ -433,6 +436,41 @@ message_token (void *cls __attribute__((unused)), 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; + } + } } } diff --git a/src/vpn/gnunet-daemon-vpn.c b/src/vpn/gnunet-daemon-vpn.c index 257ab22b8..ef54cdf2d 100644 --- a/src/vpn/gnunet-daemon-vpn.c +++ b/src/vpn/gnunet-daemon-vpn.c @@ -113,7 +113,7 @@ cleanup(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULER_TaskCon * @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)); @@ -130,6 +130,34 @@ address_mapping_exists(unsigned char addr[]) { } } +/** + * @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) @@ -148,7 +176,47 @@ collect_mappings(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULE } 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; @@ -626,6 +694,8 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) { 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); } @@ -766,7 +836,7 @@ receive_udp_back (void *cls __attribute__((unused)), struct GNUNET_MESH_Tunnel* } 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); @@ -849,7 +919,7 @@ receive_tcp_back (void *cls __attribute__((unused)), struct GNUNET_MESH_Tunnel* } 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); diff --git a/src/vpn/gnunet-daemon-vpn.h b/src/vpn/gnunet-daemon-vpn.h index 217096273..7643a6e4d 100644 --- a/src/vpn/gnunet-daemon-vpn.h +++ b/src/vpn/gnunet-daemon-vpn.h @@ -38,13 +38,14 @@ 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); diff --git a/src/vpn/gnunet-service-dns.c b/src/vpn/gnunet-service-dns.c index 0c2304097..bfbcbca23 100644 --- a/src/vpn/gnunet-service-dns.c +++ b/src/vpn/gnunet-service-dns.c @@ -468,15 +468,24 @@ receive_mesh_answer (void *cls __attribute__((unused)), 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 */ @@ -484,16 +493,9 @@ receive_mesh_answer (void *cls __attribute__((unused)), (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 */ diff --git a/src/vpn/gnunet-vpn-packet.h b/src/vpn/gnunet-vpn-packet.h index 87b12cb69..91c6eb9c1 100644 --- a/src/vpn/gnunet-vpn-packet.h +++ b/src/vpn/gnunet-vpn-packet.h @@ -215,4 +215,11 @@ struct ip_tcp { 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 -- 2.25.1