Answer an icmp-request
authorPhilipp Tölke <toelke@in.tum.de>
Thu, 4 Nov 2010 17:26:58 +0000 (17:26 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Thu, 4 Nov 2010 17:26:58 +0000 (17:26 +0000)
src/vpn/gnunet-daemon-vpn.c
src/vpn/gnunet-vpn-packet.h

index 010d3c1ef68be8ca684429a6a9d3f7627cae40f1..d4ff33b9c19a58d0dfd951ab7d6dc8aee2ba3574 100644 (file)
@@ -350,6 +350,45 @@ helper_write(void* cls, const struct GNUNET_SCHEDULER_TaskContext* tsdkctx) {
                                       NULL);
 }
 
+static int
+address_mapping_exists(unsigned char addr[]) {
+    return 1;
+}
+
+static void
+send_icmp_response(void* cls, const struct GNUNET_SCHEDULER_TaskContext *tc) {
+    struct ip6_icmp* request = cls;
+
+    struct ip6_icmp* response = alloca(ntohs(request->shdr.size));
+    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(0x86dd);
+
+    response->ip6_hdr.hoplmt = 255;
+    response->ip6_hdr.paylgth = request->ip6_hdr.paylgth;
+    response->ip6_hdr.nxthdr = 0x3a;
+    response->ip6_hdr.version = 6;
+    memcpy(&response->ip6_hdr.sadr, &request->ip6_hdr.dadr, 16);
+    memcpy(&response->ip6_hdr.dadr, &request->ip6_hdr.sadr, 16);
+
+    response->icmp_hdr.code = 0;
+    response->icmp_hdr.type = 0x81;
+
+    /* Magic, more Magic! */
+    response->icmp_hdr.chks = request->icmp_hdr.chks - 0x1;
+
+    /* Copy the rest of the packet */
+    memcpy(response+1, request+1, ntohs(request->shdr.size) - sizeof(struct ip6_icmp));
+
+    /* FIXME */ GNUNET_DISK_file_write(fh_to_helper, response, ntohs(response->shdr.size));
+
+    GNUNET_free(request);
+}
+
 /**
  * Receive packets from the helper-process
  */
@@ -368,6 +407,7 @@ message_token(void *cls,
        GNUNET_assert(pkt6->ip6_hdr.version == 6);
        struct ip6_tcp *pkt6_tcp;
        struct ip6_udp *pkt6_udp;
+       struct ip6_icmp *pkt6_icmp;
 
        pkt_printf(pkt6);
        switch(pkt6->ip6_hdr.nxthdr)
@@ -383,6 +423,14 @@ message_token(void *cls,
                pkt_printf_ip6dns((struct ip6_udp_dns*)pkt6_udp);
            }
            break;
+         case 0x3a:
+           /* ICMPv6 */
+           pkt6_icmp = GNUNET_malloc(ntohs(pkt6->shdr.size));
+           memcpy(pkt6_icmp, pkt6, ntohs(pkt6->shdr.size));
+           /* If this packet is an icmp-echo-request and a mapping exists, answer */
+           if (pkt6_icmp->icmp_hdr.type == 0x80 && address_mapping_exists(pkt6->ip6_hdr.sadr))
+               GNUNET_SCHEDULER_add_now(sched, &send_icmp_response, pkt6_icmp);
+           break;
          }
       }
     /* ethertype is ipv4 */
index a298fa7c793febe21f69277258a353c62dcb34a4..4510098ae99539c8026ce1522f691b23ab3fc266 100644 (file)
@@ -61,6 +61,12 @@ struct udp_pkt {
        unsigned crc:16 GNUNET_PACKED;
 };
 
+struct icmp_hdr {
+    unsigned type:8 GNUNET_PACKED;
+    unsigned code:8 GNUNET_PACKED;
+    unsigned chks:16 GNUNET_PACKED;
+};
+
 // DNS-Stuff
 struct dns_static {
        unsigned short id GNUNET_PACKED;
@@ -155,6 +161,13 @@ struct ip6_tcp {
        unsigned char data[1];
 };
 
+struct ip6_icmp {
+    struct GNUNET_MessageHeader shdr;
+    struct pkt_tun tun;
+    struct ip6_hdr ip6_hdr;
+    struct icmp_hdr icmp_hdr;
+};
+
 struct ip6_udp {
        struct GNUNET_MessageHeader shdr;
        struct pkt_tun tun;