Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / nat / gnunet-helper-nat-server-windows.c
index 727a7be67f1866d299e1eaf73af8cfdf5976a1e6..09bd025386e1e878450a3e91f0cb287109255b3e 100644 (file)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
+     Copyright (C) 2010 GNUnet e.V.
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
 
      You should have received a copy of the GNU General Public License
      along with GNUnet; see the file COPYING.  If not, write to the
-     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-     Boston, MA 02111-1307, USA.
+     Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+     Boston, MA 02110-1301, USA.
 */
 
 /**
  * - Christian Grothoff
  */
 #define _GNU_SOURCE
+/* Instead of including gnunet_common.h */
+#define GNUNET_memcpy(dst,src,n) do { if (0 != n) { (void) memcpy (dst,src,n); } } while (0)
 
-
+#define FD_SETSIZE 1024
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <sys/time.h>
  */
 #define NAT_TRAV_PORT 22225
 
+/**
+ * Must match packet ID used by gnunet-helper-nat-client.c
+ */
+#define PACKET_ID 256
+
 /**
  * TTL to use for our outgoing messages.
  */
@@ -182,6 +189,11 @@ struct udp_header
   uint16_t crc;
 };
 
+/**
+ * Will this binary be run in permissions testing mode?
+ */
+static boolean privilege_testing = FALSE;
+
 /**
  * Socket we use to receive "fake" ICMP replies.
  */
@@ -265,32 +277,33 @@ send_icmp_echo (const struct in_addr *my_ip)
   ip_pkt.vers_ihl = 0x45;
   ip_pkt.tos = 0;
   ip_pkt.pkt_len = htons (sizeof (packet));
-  ip_pkt.id = htons (256);
+  ip_pkt.id = htons (PACKET_ID);
   ip_pkt.flags_frag_offset = 0;
   ip_pkt.ttl = IPDEFTTL;
   ip_pkt.proto = IPPROTO_ICMP;
   ip_pkt.checksum = 0;
   ip_pkt.src_ip = my_ip->s_addr;
   ip_pkt.dst_ip = dummy.s_addr;
-  ip_pkt.checksum = htons (calc_checksum ((uint16_t *) & ip_pkt,
-                                          sizeof (struct ip_header)));
-  memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
+  ip_pkt.checksum =
+      htons (calc_checksum ((uint16_t *) & ip_pkt, sizeof (struct ip_header)));
+  GNUNET_memcpy (&packet[off], &ip_pkt, sizeof (struct ip_header));
   off += sizeof (struct ip_header);
 
   icmp_echo.type = ICMP_ECHO;
   icmp_echo.code = 0;
   icmp_echo.reserved = 0;
   icmp_echo.checksum = 0;
-  icmp_echo.checksum = htons (calc_checksum ((uint16_t *) & icmp_echo,
-                                             sizeof (struct icmp_echo_header)));
-  memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
+  icmp_echo.checksum =
+      htons (calc_checksum
+             ((uint16_t *) & icmp_echo, sizeof (struct icmp_echo_header)));
+  GNUNET_memcpy (&packet[off], &icmp_echo, sizeof (struct icmp_echo_header));
   off += sizeof (struct icmp_echo_header);
 
   memset (&dst, 0, sizeof (dst));
   dst.sin_family = AF_INET;
   dst.sin_addr = dummy;
-  err = sendto (rawsock,
-                packet, off, 0, (struct sockaddr *) &dst, sizeof (dst));
+  err =
+      sendto (rawsock, packet, off, 0, (struct sockaddr *) &dst, sizeof (dst));
   if (err < 0)
   {
 #if VERBOSE
@@ -366,10 +379,10 @@ process_icmp_response ()
     return;
   }
   off = 0;
-  memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
+  GNUNET_memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
   off += sizeof (struct ip_header);
-  memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip));
-  memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header));
+  GNUNET_memcpy (&source_ip, &ip_pkt.src_ip, sizeof (source_ip));
+  GNUNET_memcpy (&icmp_ttl, &buf[off], sizeof (struct icmp_ttl_exceeded_header));
   off += sizeof (struct icmp_ttl_exceeded_header);
   if ((ICMP_TIME_EXCEEDED != icmp_ttl.type) || (0 != icmp_ttl.code))
   {
@@ -377,33 +390,34 @@ process_icmp_response ()
     return;
   }
   /* skip 2nd IP header */
-  memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
+  GNUNET_memcpy (&ip_pkt, &buf[off], sizeof (struct ip_header));
   off += sizeof (struct ip_header);
 
   switch (ip_pkt.proto)
   {
   case IPPROTO_ICMP:
-    if (have != (sizeof (struct ip_header) * 2 +
-                 sizeof (struct icmp_ttl_exceeded_header) +
-                 sizeof (struct icmp_echo_header)))
+    if (have !=
+        (sizeof (struct ip_header) * 2 +
+         sizeof (struct icmp_ttl_exceeded_header) +
+         sizeof (struct icmp_echo_header)))
     {
       /* malformed */
       return;
     }
     /* grab ICMP ECHO content */
-    memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header));
+    GNUNET_memcpy (&icmp_echo, &buf[off], sizeof (struct icmp_echo_header));
     port = (uint16_t) ntohl (icmp_echo.reserved);
     break;
   case IPPROTO_UDP:
-    if (have != (sizeof (struct ip_header) * 2 +
-                 sizeof (struct icmp_ttl_exceeded_header) +
-                 sizeof (struct udp_header)))
+    if (have !=
+        (sizeof (struct ip_header) * 2 +
+         sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct udp_header)))
     {
       /* malformed */
       return;
     }
     /* grab UDP content */
-    memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header));
+    GNUNET_memcpy (&udp_pkt, &buf[off], sizeof (struct udp_header));
     port = ntohs (udp_pkt.length);
     break;
   default:
@@ -412,8 +426,8 @@ process_icmp_response ()
   }
 
   ssize = sizeof (buf);
-  WSAAddressToString ((LPSOCKADDR) & source_ip,
-                      sizeof (source_ip), NULL, buf, &ssize);
+  WSAAddressToString ((LPSOCKADDR) & source_ip, sizeof (source_ip), NULL, buf,
+                      &ssize);
   if (port == 0)
     fprintf (stdout, "%s\n", buf);
   else
@@ -460,16 +474,17 @@ make_raw_socket ()
     return INVALID_SOCKET;
   }
 
-  if (0 != setsockopt (rawsock,
-                       SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal, bOptLen))
+  if (0 !=
+      setsockopt (rawsock, SOL_SOCKET, SO_BROADCAST, (char *) &bOptVal,
+                  bOptLen))
   {
-    fprintf (stderr,
-             "Error setting SO_BROADCAST to ON: %s\n", strerror (errno));
+    fprintf (stderr, "Error setting SO_BROADCAST to ON: %s\n",
+             strerror (errno));
     closesocket (rawsock);
     return INVALID_SOCKET;
   }
-  if (0 != setsockopt (rawsock,
-                       IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen))
+  if (0 !=
+      setsockopt (rawsock, IPPROTO_IP, IP_HDRINCL, (char *) &bOptVal, bOptLen))
   {
     fprintf (stderr, "Error setting IP_HDRINCL to ON: %s\n", strerror (errno));
     closesocket (rawsock);
@@ -503,9 +518,8 @@ make_udp_socket (const struct in_addr *my_ip)
   addr.sin_port = htons (NAT_TRAV_PORT);
   if (0 != bind (ret, (struct sockaddr *) &addr, sizeof (addr)))
   {
-    fprintf (stderr,
-             "Error binding UDP socket to port %u: %s\n",
-             NAT_TRAV_PORT, strerror (errno));
+    fprintf (stderr, "Error binding UDP socket to port %u: %s\n", NAT_TRAV_PORT,
+             strerror (errno));
     /* likely problematic, but not certain, try to continue */
   }
   return ret;
@@ -519,9 +533,18 @@ main (int argc, char *const *argv)
   fd_set rs;
   struct timeval tv;
   WSADATA wsaData;
-  unsigned int alt;
+  unsigned int alt = 0;
+
+  if ( (argc > 1) && (0 != strcmp (argv[1], "-d")))
+  {
+    privilege_testing = TRUE;
+    fprintf (stderr,
+            "%s",
+            "DEBUG: Running binary in privilege testing mode.");
+    argv++;
+    argc--;
+  }
 
-  alt = 0;
   if (2 != argc)
   {
     fprintf (stderr,
@@ -530,9 +553,8 @@ main (int argc, char *const *argv)
   }
   if (1 != inet_pton (AF_INET, argv[1], &external))
   {
-    fprintf (stderr,
-             "Error parsing IPv4 address: %s, error %s\n",
-             argv[1], strerror (errno));
+    fprintf (stderr, "Error parsing IPv4 address: %s, error %s\n", argv[1],
+             strerror (errno));
     return 1;
   }
   if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
@@ -560,7 +582,8 @@ main (int argc, char *const *argv)
     closesocket (rawsock);
     return 3;
   }
-  while (1)
+
+  while ( ! privilege_testing)
   {
     FD_ZERO (&rs);
     FD_SET (icmpsock, &rs);
@@ -585,6 +608,8 @@ main (int argc, char *const *argv)
   closesocket (rawsock);
   closesocket (udpsock);
   WSACleanup ();
+  if (privilege_testing)
+    return 0;
   return 4;
 }