aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorPhilipp Tölke <toelke@in.tum.de>2011-07-27 07:28:21 +0000
committerPhilipp Tölke <toelke@in.tum.de>2011-07-27 07:28:21 +0000
commitca51d9b99345521ca990e092234e140316ff95bd (patch)
tree8d901d96a0f98f6d528eeaf6ae7c8aa76a43b7e0 /src/vpn
parent51074a30f34eee12cb388451a0fd94bfa78d3dd4 (diff)
downloadgnunet-ca51d9b99345521ca990e092234e140316ff95bd.tar.gz
gnunet-ca51d9b99345521ca990e092234e140316ff95bd.zip
reply ipv4-icmp
Diffstat (limited to 'src/vpn')
-rw-r--r--src/vpn/gnunet-daemon-vpn-helper.c46
-rw-r--r--src/vpn/gnunet-daemon-vpn.c78
-rw-r--r--src/vpn/gnunet-daemon-vpn.h7
-rw-r--r--src/vpn/gnunet-service-dns.c16
-rw-r--r--src/vpn/gnunet-vpn-packet.h7
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)),
223 GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER); 223 GNUNET_assert (ntohs (message->type) == GNUNET_MESSAGE_TYPE_VPN_HELPER);
224 224
225 struct tun_pkt *pkt_tun = (struct tun_pkt *) message; 225 struct tun_pkt *pkt_tun = (struct tun_pkt *) message;
226 GNUNET_HashCode *key;
226 227
227 /* ethertype is ipv6 */ 228 /* ethertype is ipv6 */
228 if (ntohs (pkt_tun->tun.type) == 0x86dd) 229 if (ntohs (pkt_tun->tun.type) == 0x86dd)
@@ -232,7 +233,6 @@ message_token (void *cls __attribute__((unused)),
232 struct ip6_tcp *pkt6_tcp; 233 struct ip6_tcp *pkt6_tcp;
233 struct ip6_udp *pkt6_udp; 234 struct ip6_udp *pkt6_udp;
234 struct ip6_icmp *pkt6_icmp; 235 struct ip6_icmp *pkt6_icmp;
235 GNUNET_HashCode *key;
236 236
237 switch (pkt6->ip6_hdr.nxthdr) 237 switch (pkt6->ip6_hdr.nxthdr)
238 { 238 {
@@ -241,7 +241,7 @@ message_token (void *cls __attribute__((unused)),
241 pkt6_tcp = (struct ip6_tcp *) pkt6; 241 pkt6_tcp = (struct ip6_tcp *) pkt6;
242 pkt6_udp = (struct ip6_udp *) pkt6; 242 pkt6_udp = (struct ip6_udp *) pkt6;
243 243
244 if ((key = address_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL) 244 if ((key = address6_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
245 { 245 {
246 struct map_entry *me = 246 struct map_entry *me =
247 GNUNET_CONTAINER_multihashmap_get (hashmap, key); 247 GNUNET_CONTAINER_multihashmap_get (hashmap, key);
@@ -389,12 +389,12 @@ message_token (void *cls __attribute__((unused)),
389 pkt6_icmp = (struct ip6_icmp *) pkt6; 389 pkt6_icmp = (struct ip6_icmp *) pkt6;
390 /* If this packet is an icmp-echo-request and a mapping exists, answer */ 390 /* If this packet is an icmp-echo-request and a mapping exists, answer */
391 if (pkt6_icmp->icmp_hdr.type == 0x80 391 if (pkt6_icmp->icmp_hdr.type == 0x80
392 && (key = address_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL) 392 && (key = address6_mapping_exists (pkt6->ip6_hdr.dadr)) != NULL)
393 { 393 {
394 GNUNET_free (key); 394 GNUNET_free (key);
395 pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size)); 395 pkt6_icmp = GNUNET_malloc (ntohs (pkt6->shdr.size));
396 memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size)); 396 memcpy (pkt6_icmp, pkt6, ntohs (pkt6->shdr.size));
397 GNUNET_SCHEDULER_add_now (&send_icmp_response, pkt6_icmp); 397 GNUNET_SCHEDULER_add_now (&send_icmp6_response, pkt6_icmp);
398 } 398 }
399 break; 399 break;
400 } 400 }
@@ -404,6 +404,9 @@ message_token (void *cls __attribute__((unused)),
404 { 404 {
405 struct ip_pkt *pkt = (struct ip_pkt *) message; 405 struct ip_pkt *pkt = (struct ip_pkt *) message;
406 struct ip_udp *udp = (struct ip_udp *) message; 406 struct ip_udp *udp = (struct ip_udp *) message;
407 struct ip_tcp *pkt_tcp;
408 struct ip_udp *pkt_udp;
409 struct ip_icmp *pkt_icmp;
407 GNUNET_assert (pkt->ip_hdr.version == 4); 410 GNUNET_assert (pkt->ip_hdr.version == 4);
408 411
409 /* Send dns-packets to the service-dns */ 412 /* Send dns-packets to the service-dns */
@@ -433,6 +436,41 @@ message_token (void *cls __attribute__((unused)),
433 GNUNET_YES, 436 GNUNET_YES,
434 &send_query, NULL); 437 &send_query, NULL);
435 } 438 }
439 else
440 {
441 uint32_t dadr = pkt->ip_hdr.dadr;
442 unsigned char *c = (unsigned char*)&dadr;
443 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Packet to %d.%d.%d.%d, proto %x\n",
444 c[0],
445 c[1],
446 c[2],
447 c[3],
448 pkt->ip_hdr.proto);
449 switch (pkt->ip_hdr.proto)
450 {
451 case 0x06: /* TCP */
452 case 0x11: /* UDP */
453 pkt_tcp = (struct ip_tcp*) pkt;
454 pkt_udp = (struct ip_udp*) pkt;
455
456 if ((key = address4_mapping_exists (dadr)) != NULL)
457 {
458 }
459 break;
460 case 0x01:
461 /* ICMP */
462 pkt_icmp = (struct ip_icmp*)pkt;
463 if (pkt_icmp->icmp_hdr.type == 0x8 &&
464 (key = address4_mapping_exists (dadr)) != NULL)
465 {
466 GNUNET_free(key);
467 pkt_icmp = GNUNET_malloc(ntohs(pkt->shdr.size));
468 memcpy(pkt_icmp, pkt, ntohs(pkt->shdr.size));
469 GNUNET_SCHEDULER_add_now (&send_icmp4_response, pkt_icmp);
470 }
471 break;
472 }
473 }
436 } 474 }
437} 475}
438 476
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
113 * @return the hash of the IP-Address if a mapping exists, NULL otherwise 113 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
114 */ 114 */
115GNUNET_HashCode* 115GNUNET_HashCode*
116address_mapping_exists(unsigned char addr[]) { 116address6_mapping_exists(unsigned char addr[]) {
117 GNUNET_HashCode* key = GNUNET_malloc(sizeof(GNUNET_HashCode)); 117 GNUNET_HashCode* key = GNUNET_malloc(sizeof(GNUNET_HashCode));
118 unsigned char* k = (unsigned char*)key; 118 unsigned char* k = (unsigned char*)key;
119 memset(key, 0, sizeof(GNUNET_HashCode)); 119 memset(key, 0, sizeof(GNUNET_HashCode));
@@ -130,6 +130,34 @@ address_mapping_exists(unsigned char addr[]) {
130 } 130 }
131} 131}
132 132
133/**
134 * @return the hash of the IP-Address if a mapping exists, NULL otherwise
135 */
136GNUNET_HashCode *
137address4_mapping_exists (uint32_t addr)
138{
139 GNUNET_HashCode *key = GNUNET_malloc (sizeof (GNUNET_HashCode));
140 memset (key, 0, sizeof (GNUNET_HashCode));
141 unsigned char *c = (unsigned char *) &addr;
142 unsigned char *k = (unsigned char *) key;
143 unsigned int i;
144 for (i = 0; i < 4; i++)
145 k[3 - i] = c[i];
146
147 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
148 "a4_m_e: getting with key %08x, addr is %08x, %d.%d.%d.%d\n",
149 *((uint32_t *) (key)), addr, c[0], c[1], c[2], c[3]);
150
151 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (hashmap, key))
152 return key;
153 else
154 {
155 GNUNET_free (key);
156 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Mapping not found!\n");
157 return NULL;
158 }
159}
160
133static void 161static void
134collect_mappings(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULER_TaskContext* tc) { 162collect_mappings(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULER_TaskContext* tc) {
135 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 163 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
@@ -148,7 +176,47 @@ collect_mappings(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULE
148} 176}
149 177
150void 178void
151send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { 179send_icmp4_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
180 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
181 return;
182
183 struct ip_icmp* request = cls;
184
185 struct ip_icmp* response = alloca(ntohs(request->shdr.size));
186 GNUNET_assert(response != NULL);
187 memset(response, 0, ntohs(request->shdr.size));
188
189 response->shdr.size = request->shdr.size;
190 response->shdr.type = htons(GNUNET_MESSAGE_TYPE_VPN_HELPER);
191
192 response->tun.flags = 0;
193 response->tun.type = htons(0x0800);
194
195 response->ip_hdr.hdr_lngth = 5;
196 response->ip_hdr.version = 4;
197 response->ip_hdr.proto = 0x01;
198 response->ip_hdr.dadr = request->ip_hdr.sadr;
199 response->ip_hdr.sadr = request->ip_hdr.dadr;
200 response->ip_hdr.tot_lngth = request->ip_hdr.tot_lngth;
201
202 response->ip_hdr.chks = calculate_ip_checksum((uint16_t*)&response->ip_hdr, 20);
203
204 response->icmp_hdr.code = 0;
205 response->icmp_hdr.type = 0x0;
206
207 /* Magic, more Magic! */
208 response->icmp_hdr.chks = request->icmp_hdr.chks + 0x8;
209
210 /* Copy the rest of the packet */
211 memcpy(response+1, request+1, ntohs(request->shdr.size) - sizeof(struct ip_icmp));
212
213 write_to_helper(response, ntohs(response->shdr.size));
214
215 GNUNET_free(request);
216}
217
218void
219send_icmp6_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
152 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) 220 if ( (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0)
153 return; 221 return;
154 222
@@ -626,6 +694,8 @@ process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc) {
626 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); 694 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY);
627 value->heap_node = GNUNET_CONTAINER_heap_insert (heap, value, 695 value->heap_node = GNUNET_CONTAINER_heap_insert (heap, value,
628 GNUNET_TIME_absolute_get ().abs_value); 696 GNUNET_TIME_absolute_get ().abs_value);
697 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Mapping is saved in the hashmap with key %08x.\n",
698 *((uint32_t*)(&key)));
629 if (GNUNET_CONTAINER_heap_get_size(heap) > max_mappings) 699 if (GNUNET_CONTAINER_heap_get_size(heap) > max_mappings)
630 GNUNET_SCHEDULER_add_now(collect_mappings, NULL); 700 GNUNET_SCHEDULER_add_now(collect_mappings, NULL);
631 } 701 }
@@ -766,7 +836,7 @@ receive_udp_back (void *cls __attribute__((unused)), struct GNUNET_MESH_Tunnel*
766 } 836 }
767 memcpy(&pkt6->udp_hdr, pkt, ntohs(pkt->len)); 837 memcpy(&pkt6->udp_hdr, pkt, ntohs(pkt->len));
768 838
769 GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr); 839 GNUNET_HashCode* key = address6_mapping_exists(pkt6->ip6_hdr.sadr);
770 GNUNET_assert (key != NULL); 840 GNUNET_assert (key != NULL);
771 841
772 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key); 842 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*
849 } 919 }
850 memcpy(&pkt6->tcp_hdr, pkt, pktlen); 920 memcpy(&pkt6->tcp_hdr, pkt, pktlen);
851 921
852 GNUNET_HashCode* key = address_mapping_exists(pkt6->ip6_hdr.sadr); 922 GNUNET_HashCode* key = address6_mapping_exists(pkt6->ip6_hdr.sadr);
853 GNUNET_assert (key != NULL); 923 GNUNET_assert (key != NULL);
854 924
855 struct map_entry *me = GNUNET_CONTAINER_multihashmap_get(hashmap, key); 925 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 @@
38void 38void
39process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc); 39process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc);
40 40
41void 41void send_icmp6_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
42send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc); 42void send_icmp4_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
43 43
44size_t 44size_t
45send_udp_service (void *cls, size_t size, void *buf); 45send_udp_service (void *cls, size_t size, void *buf);
46 46
47GNUNET_HashCode* address_mapping_exists(unsigned char addr[]); 47GNUNET_HashCode* address6_mapping_exists(unsigned char addr[]);
48GNUNET_HashCode* address4_mapping_exists(uint32_t addr);
48 49
49unsigned int port_in_ports (uint64_t ports, uint16_t port); 50unsigned int port_in_ports (uint64_t ports, uint16_t port);
50 51
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)),
468 struct dns_query_line *dque = 468 struct dns_query_line *dque =
469 (struct dns_query_line *) (dpkt->data + 469 (struct dns_query_line *) (dpkt->data +
470 (query_states[dns->s.id].namelen)); 470 (query_states[dns->s.id].namelen));
471
472 struct dns_record_line *drec_data =
473 (struct dns_record_line *) (dpkt->data +
474 (query_states[dns->s.id].namelen) +
475 sizeof (struct dns_query_line) + 2);
471 if (16 == answer->pkt.addrsize) 476 if (16 == answer->pkt.addrsize)
472 { 477 {
473 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA; 478 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_AAAA;
474 dque->type = htons (28); /* AAAA */ 479 dque->type = htons (28); /* AAAA */
480 drec_data->type = htons (28); /* AAAA */
481 drec_data->data_len = htons (16);
475 } 482 }
476 else 483 else
477 { 484 {
478 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_A; 485 answer->pkt.subtype = GNUNET_DNS_ANSWER_TYPE_REMOTE_A;
479 dque->type = htons (1); /* A */ 486 dque->type = htons (1); /* A */
487 drec_data->type = htons (1); /* A*/
488 drec_data->data_len = htons (4);
480 } 489 }
481 dque->class = htons (1); /* IN */ 490 dque->class = htons (1); /* IN */
482 491
@@ -484,16 +493,9 @@ receive_mesh_answer (void *cls __attribute__((unused)),
484 (char *) (dpkt->data + (query_states[dns->s.id].namelen) + 493 (char *) (dpkt->data + (query_states[dns->s.id].namelen) +
485 sizeof (struct dns_query_line)); 494 sizeof (struct dns_query_line));
486 memcpy (anname, "\xc0\x0c", 2); 495 memcpy (anname, "\xc0\x0c", 2);
487
488 struct dns_record_line *drec_data =
489 (struct dns_record_line *) (dpkt->data +
490 (query_states[dns->s.id].namelen) +
491 sizeof (struct dns_query_line) + 2);
492 drec_data->type = htons (28); /* AAAA */
493 drec_data->class = htons (1); /* IN */ 496 drec_data->class = htons (1); /* IN */
494 497
495 drec_data->ttl = pdns->answers[0]->ttl; 498 drec_data->ttl = pdns->answers[0]->ttl;
496 drec_data->data_len = htons (16);
497 499
498 /* Calculate at which offset in the packet the IPv6-Address belongs, it is 500 /* Calculate at which offset in the packet the IPv6-Address belongs, it is
499 * filled in by the daemon-vpn */ 501 * 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 {
215 unsigned char data[1]; 215 unsigned char data[1];
216}; 216};
217 217
218struct ip_icmp {
219 struct GNUNET_MessageHeader shdr;
220 struct pkt_tun tun;
221 struct ip_hdr ip_hdr;
222 struct icmp_hdr icmp_hdr;
223};
224
218#endif 225#endif