reply ipv4-icmp
authorPhilipp Tölke <toelke@in.tum.de>
Wed, 27 Jul 2011 07:28:21 +0000 (07:28 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Wed, 27 Jul 2011 07:28:21 +0000 (07:28 +0000)
src/vpn/gnunet-daemon-vpn-helper.c
src/vpn/gnunet-daemon-vpn.c
src/vpn/gnunet-daemon-vpn.h
src/vpn/gnunet-service-dns.c
src/vpn/gnunet-vpn-packet.h

index 48cb4e6cf4baf1f96f551181cd85f55cdfa50354..76d169143097442b838f8fdc5ae15ace62a6a6e3 100644 (file)
@@ -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;
+            }
+        }
     }
 }
 
index 257ab22b83858fcb23104e4d030a143948afb644..ef54cdf2d0f41a34743ed93e9e324444ce4605e9 100644 (file)
@@ -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);
index 21709627320f50279377e833de04babef7a9ad67..7643a6e4dc270312aa126258ecfedacffacb025c 100644 (file)
 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);
 
index 0c2304097a6dc0ad665ff31862059b8ba332fd0c..bfbcbca235971cfbf29c49b785c83241687f2443 100644 (file)
@@ -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 */
index 87b12cb69fafd3398d5d595bd3208861f78f6f54..91c6eb9c10f7027e5d54872fb495ab77a7f94f8b 100644 (file)
@@ -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