diff options
author | Philipp Tölke <toelke@in.tum.de> | 2011-07-27 07:28:21 +0000 |
---|---|---|
committer | Philipp Tölke <toelke@in.tum.de> | 2011-07-27 07:28:21 +0000 |
commit | ca51d9b99345521ca990e092234e140316ff95bd (patch) | |
tree | 8d901d96a0f98f6d528eeaf6ae7c8aa76a43b7e0 /src/vpn | |
parent | 51074a30f34eee12cb388451a0fd94bfa78d3dd4 (diff) | |
download | gnunet-ca51d9b99345521ca990e092234e140316ff95bd.tar.gz gnunet-ca51d9b99345521ca990e092234e140316ff95bd.zip |
reply ipv4-icmp
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-daemon-vpn-helper.c | 46 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.c | 78 | ||||
-rw-r--r-- | src/vpn/gnunet-daemon-vpn.h | 7 | ||||
-rw-r--r-- | src/vpn/gnunet-service-dns.c | 16 | ||||
-rw-r--r-- | 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)), | |||
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 | */ |
115 | GNUNET_HashCode* | 115 | GNUNET_HashCode* |
116 | address_mapping_exists(unsigned char addr[]) { | 116 | address6_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 | */ | ||
136 | GNUNET_HashCode * | ||
137 | address4_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 | |||
133 | static void | 161 | static void |
134 | collect_mappings(void* cls __attribute__((unused)), const struct GNUNET_SCHEDULER_TaskContext* tc) { | 162 | collect_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 | ||
150 | void | 178 | void |
151 | send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { | 179 | send_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 | |||
218 | void | ||
219 | send_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 @@ | |||
38 | void | 38 | void |
39 | process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc); | 39 | process_answer(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tc); |
40 | 40 | ||
41 | void | 41 | void send_icmp6_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
42 | send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 42 | void send_icmp4_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
43 | 43 | ||
44 | size_t | 44 | size_t |
45 | send_udp_service (void *cls, size_t size, void *buf); | 45 | send_udp_service (void *cls, size_t size, void *buf); |
46 | 46 | ||
47 | GNUNET_HashCode* address_mapping_exists(unsigned char addr[]); | 47 | GNUNET_HashCode* address6_mapping_exists(unsigned char addr[]); |
48 | GNUNET_HashCode* address4_mapping_exists(uint32_t addr); | ||
48 | 49 | ||
49 | unsigned int port_in_ports (uint64_t ports, uint16_t port); | 50 | unsigned 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 | ||
218 | struct 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 |