gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r19297 - gnunet/src/vpn


From: gnunet
Subject: [GNUnet-SVN] r19297 - gnunet/src/vpn
Date: Sat, 21 Jan 2012 16:11:58 +0100

Author: grothoff
Date: 2012-01-21 16:11:58 +0100 (Sat, 21 Jan 2012)
New Revision: 19297

Modified:
   gnunet/src/vpn/gnunet-service-vpn.c
Log:
-add support for sending ICMP packets to service/internet

Modified: gnunet/src/vpn/gnunet-service-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-service-vpn.c 2012-01-21 15:03:38 UTC (rev 19296)
+++ gnunet/src/vpn/gnunet-service-vpn.c 2012-01-21 15:11:58 UTC (rev 19297)
@@ -878,6 +878,7 @@
   int is_new;
   const struct GNUNET_TUN_UdpHeader *udp;
   const struct GNUNET_TUN_TcpHeader *tcp;
+  const struct GNUNET_TUN_IcmpHeader *icmp;
   uint16_t spt;
   uint16_t dpt;
 
@@ -923,6 +924,26 @@
                               &key);
     }
     break;
+  case IPPROTO_ICMP:
+    {
+      if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader))
+      {
+       /* blame kernel? */
+       GNUNET_break (0);
+       return;
+      }
+      icmp = payload;
+      spt = 0;
+      dpt = 0;
+      get_tunnel_key_from_ips (af,
+                              IPPROTO_ICMP,
+                              source_ip,
+                              0,
+                              destination_ip,
+                              0,
+                              &key);
+    }
+    break;
   default:
     GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                _("Protocol %u not supported, dropping\n"),
@@ -1204,6 +1225,80 @@
              payload_length - sizeof (struct GNUNET_TUN_TcpHeader));
      }
     break;
+  case IPPROTO_ICMP:
+    if (destination->is_service)
+    {
+      struct GNUNET_EXIT_IcmpServiceMessage *ism;
+
+      mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + 
+       payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
+      if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+      {
+       GNUNET_break (0);
+       return;
+      }
+      tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen);
+      tnq->len = mlen;
+      tnq->msg = &tnq[1];
+      ism = (struct GNUNET_EXIT_IcmpServiceMessage *) &tnq[1];
+      ism->header.size = htons ((uint16_t) mlen);
+      ism->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE);
+      ism->af = htonl (af); /* need to tell destination ICMP protocol family! 
*/
+      ism->service_descriptor = 
destination->details.service_destination.service_descriptor;
+      ism->icmp_header = *icmp;
+      memcpy (&ism[1],
+             &icmp[1],
+             payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
+    }
+    else
+    {
+      struct GNUNET_EXIT_IcmpInternetMessage *iim;
+      struct in_addr *ip4dst;
+      struct in6_addr *ip6dst;
+      void *payload;
+
+      mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + 
+       alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader);
+      if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
+      {
+       GNUNET_break (0);
+       return;
+      }
+      tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + 
+                          mlen);
+      tnq->len = mlen;
+      tnq->msg = &tnq[1];
+      iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1];
+      iim->header.size = htons ((uint16_t) mlen);
+      iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); 
+      iim->af = htonl (af); /* need to tell destination ICMP protocol family! 
*/
+      iim->icmp_header = *icmp;
+      if (af != destination->details.exit_destination.af)
+      {
+       GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                   _("AF-translation for ICMP not implemented\n"));
+       return;
+      }
+      switch (destination->details.exit_destination.af)
+      {
+      case AF_INET:
+       ip4dst = (struct in_addr *) &iim[1];
+       *ip4dst = destination->details.exit_destination.ip.v4;
+       payload = &ip4dst[1];
+       break;
+      case AF_INET6:
+       ip6dst = (struct in6_addr *) &iim[1];
+       *ip6dst = destination->details.exit_destination.ip.v6;
+       payload = &ip6dst[1];
+       break;
+      default:
+       GNUNET_assert (0);
+      }
+      memcpy (payload,
+             &icmp[1],
+             payload_length - sizeof (struct GNUNET_TUN_IcmpHeader));
+    }
+    break;
   default:
     /* not supported above, how can we get here !? */
     GNUNET_assert (0);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]