gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r15780 - in gnunet/src: nat transport


From: gnunet
Subject: [GNUnet-SVN] r15780 - in gnunet/src: nat transport
Date: Mon, 27 Jun 2011 22:22:33 +0200

Author: grothoff
Date: 2011-06-27 22:22:33 +0200 (Mon, 27 Jun 2011)
New Revision: 15780

Added:
   gnunet/src/nat/gnunet-nat-client-script.sh
   gnunet/src/nat/gnunet-nat-client-windows.c
   gnunet/src/nat/gnunet-nat-client.c
   gnunet/src/nat/gnunet-nat-server-script.sh
   gnunet/src/nat/gnunet-nat-server-windows.c
   gnunet/src/nat/gnunet-nat-server.c
Removed:
   gnunet/src/transport/gnunet-nat-client-script.sh
   gnunet/src/transport/gnunet-nat-client-windows.c
   gnunet/src/transport/gnunet-nat-client.c
   gnunet/src/transport/gnunet-nat-server-script.sh
   gnunet/src/transport/gnunet-nat-server-windows.c
   gnunet/src/transport/gnunet-nat-server.c
Modified:
   gnunet/src/transport/Makefile.am
Log:
moving NAT client/server to NAT library

Copied: gnunet/src/nat/gnunet-nat-client-script.sh (from rev 15779, 
gnunet/src/transport/gnunet-nat-client-script.sh)
===================================================================
--- gnunet/src/nat/gnunet-nat-client-script.sh                          (rev 0)
+++ gnunet/src/nat/gnunet-nat-client-script.sh  2011-06-27 20:22:33 UTC (rev 
15780)
@@ -0,0 +1,4 @@
+#!/bin/sh
+IP=`ifconfig | grep inet | head -n1 | awk '{print $2}' | sed -e "s/addr://"`
+echo "Using IP $IP, trying to connect to $1"
+./gnunet-nat-client-udp $IP $1

Copied: gnunet/src/nat/gnunet-nat-client-windows.c (from rev 15779, 
gnunet/src/transport/gnunet-nat-client-windows.c)
===================================================================
--- gnunet/src/nat/gnunet-nat-client-windows.c                          (rev 0)
+++ gnunet/src/nat/gnunet-nat-client-windows.c  2011-06-27 20:22:33 UTC (rev 
15780)
@@ -0,0 +1,550 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+
+/**
+ * @file src/transport/gnunet-nat-client-windows.c
+ * @brief Tool to help bypass NATs using ICMP method; must run as
+ *        root (SUID will do) or administrator on W32
+ *        This code will work under GNU/Linux or W32.
+ * @author Nathan Evans
+ *
+ * This program will send ONE ICMP message using RAW sockets
+ * to the IP address specified as the second argument.  Since
+ * it uses RAW sockets, it must be installed SUID or run as 'root'.
+ * In order to keep the security risk of the resulting SUID binary
+ * minimal, the program ONLY opens the RAW socket with root
+ * privileges, then drops them and only then starts to process
+ * command line arguments.  The code also does not link against
+ * any shared libraries (except libc) and is strictly minimal
+ * (except for checking for errors).  The following list of people
+ * have reviewed this code and considered it safe since the last
+ * modification (if you reviewed it, please have your name added
+ * to the list):
+ *
+ * - Christian Grothoff
+ * - Nathan Evans
+ */
+#define _GNU_SOURCE
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <time.h>
+
+
+#define ICMP_ECHO 8
+#define IPDEFTTL 64
+#define ICMP_TIME_EXCEEDED 11
+
+/**
+ * Must match IP given in the server.
+ */
+#define DUMMY_IP "192.0.2.86"
+
+#define NAT_TRAV_PORT 22225
+
+/**
+ * IPv4 header.
+ */
+struct ip_header
+{
+
+  /**
+   * Version (4 bits) + Internet header length (4 bits)
+   */
+  uint8_t vers_ihl;
+
+  /**
+   * Type of service
+   */
+  uint8_t tos;
+
+  /**
+   * Total length
+   */
+  uint16_t pkt_len;
+
+  /**
+   * Identification
+   */
+  uint16_t id;
+
+  /**
+   * Flags (3 bits) + Fragment offset (13 bits)
+   */
+  uint16_t flags_frag_offset;
+
+  /**
+   * Time to live
+   */
+  uint8_t ttl;
+
+  /**
+   * Protocol
+   */
+  uint8_t proto;
+
+  /**
+   * Header checksum
+   */
+  uint16_t checksum;
+
+  /**
+   * Source address
+   */
+  uint32_t src_ip;
+
+  /**
+   * Destination address
+   */
+  uint32_t dst_ip;
+};
+
+
+/**
+ * Format of ICMP packet.
+ */
+struct icmp_ttl_exceeded_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t unused;
+
+  /* followed by original payload */
+};
+
+struct icmp_echo_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t reserved;
+};
+
+/**
+ * Beginning of UDP packet.
+ */
+struct udp_header
+{
+  uint16_t src_port;
+
+  uint16_t dst_port;
+
+  uint16_t length;
+
+  uint16_t crc;
+};
+
+
+/**
+ * Socket we use to send our ICMP packets.
+ */
+static SOCKET rawsock;
+
+/**
+ * Target "dummy" address.
+ */
+static struct in_addr dummy;
+
+/**
+ * Port we are listening on (communicated to the server).
+ */
+static uint16_t port;
+
+
+
+/**
+ * Convert IPv4 address from text to binary form.
+ *
+ * @param af address family
+ * @param cp the address to print
+ * @param buf where to write the address result
+ * @return 1 on success
+ */
+static int
+inet_pton (int af,
+          const char *cp,
+          struct in_addr *buf)
+{
+  buf->s_addr = inet_addr(cp);
+  if (buf->s_addr == INADDR_NONE)
+    {
+      fprintf(stderr,
+             "Error %d handling address %s",
+             WSAGetLastError(),
+             cp);
+      return 0;
+    }
+  return 1;
+}
+
+
+/**
+ * CRC-16 for IP/ICMP headers.
+ *
+ * @param data what to calculate the CRC over
+ * @param bytes number of bytes in data (must be multiple of 2)
+ * @return the CRC 16.
+ */
+static uint16_t
+calc_checksum(const uint16_t *data,
+             unsigned int bytes)
+{
+  uint32_t sum;
+  unsigned int i;
+
+  sum = 0;
+  for (i=0;i<bytes/2;i++)
+    sum += data[i];
+  sum = (sum & 0xffff) + (sum >> 16);
+  sum = htons(0xffff - sum);
+  return sum;
+}
+
+
+/**
+ * Send an ICMP message to the target.
+ *
+ * @param my_ip source address
+ * @param other target address
+ */
+static void
+send_icmp_udp (const struct in_addr *my_ip,
+               const struct in_addr *other)
+{
+  char packet[sizeof(struct ip_header) * 2 +
+             sizeof(struct icmp_ttl_exceeded_header) +
+             sizeof(struct udp_header)];
+  struct ip_header ip_pkt;
+  struct icmp_ttl_exceeded_header icmp_pkt;
+  struct udp_header udp_pkt;
+  struct sockaddr_in dst;
+  size_t off;
+  int err;
+
+  /* ip header: send to (known) ip address */
+  off = 0;
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons(sizeof (packet));
+  ip_pkt.id = htons(256);
+  ip_pkt.flags_frag_offset = 0;
+  ip_pkt.ttl = 128;
+  ip_pkt.proto = IPPROTO_ICMP;
+  ip_pkt.checksum = 0;
+  ip_pkt.src_ip = my_ip->s_addr;
+  ip_pkt.dst_ip = other->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));
+  off += sizeof(struct ip_header);
+
+  icmp_pkt.type = ICMP_TIME_EXCEEDED;
+  icmp_pkt.code = 0;
+  icmp_pkt.checksum = 0;
+  icmp_pkt.unused = 0;
+  memcpy(&packet[off],
+        &icmp_pkt,
+        sizeof(struct icmp_ttl_exceeded_header));
+  off += sizeof(struct icmp_ttl_exceeded_header);
+
+  /* ip header of the presumably 'lost' udp packet */
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons(sizeof (struct ip_header) +
+                        sizeof (struct udp_header));
+  ip_pkt.id = htons(0);
+  ip_pkt.flags_frag_offset = 0;
+  ip_pkt.ttl = 128;
+  ip_pkt.proto = IPPROTO_UDP;
+  ip_pkt.checksum = 0;
+  ip_pkt.src_ip = other->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));
+  off += sizeof(struct ip_header);
+
+  /* build UDP header */
+  udp_pkt.src_port = htons(NAT_TRAV_PORT);
+  udp_pkt.dst_port = htons(NAT_TRAV_PORT);
+  udp_pkt.length = htons (port);
+  udp_pkt.crc = 0;
+  memcpy(&packet[off],
+        &udp_pkt,
+        sizeof(struct udp_header));
+  off += sizeof(struct udp_header);
+
+  /* no go back to calculate ICMP packet checksum */
+  icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[off],
+                                         sizeof (struct 
icmp_ttl_exceeded_header) +
+                                         sizeof (struct ip_header) +
+                                         sizeof (struct udp_header)));
+  memcpy (&packet[sizeof (struct ip_header)],
+         &icmp_pkt,
+         sizeof (struct icmp_ttl_exceeded_header));
+
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+  dst.sin_addr = *other;
+  err = sendto(rawsock,
+               packet,
+               sizeof (packet), 0,
+               (struct sockaddr*)&dst,
+               sizeof(dst));
+  if (err < 0)
+    {
+      fprintf(stderr,
+              "sendto failed: %s\n", strerror(errno));
+    }
+  else if (sizeof (packet) != (size_t) err)
+    {
+      fprintf(stderr,
+              "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * Send an ICMP message to the target.
+ *
+ * @param my_ip source address
+ * @param other target address
+ */
+static void
+send_icmp (const struct in_addr *my_ip,
+          const struct in_addr *other)
+{
+  struct ip_header ip_pkt;
+  struct icmp_ttl_exceeded_header icmp_ttl;
+  struct icmp_echo_header icmp_echo;
+  struct sockaddr_in dst;
+  char packet[sizeof (struct ip_header) * 2 +
+             sizeof (struct icmp_ttl_exceeded_header) +
+             sizeof(struct icmp_echo_header)];
+  size_t off;
+  int err;
+
+  /* ip header: send to (known) ip address */
+  off = 0;
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons (sizeof (packet));
+  ip_pkt.id = htons(256);
+  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 = other->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));
+  off += sizeof (ip_pkt);
+
+  /* icmp reply: time exceeded */
+  icmp_ttl.type = ICMP_TIME_EXCEEDED;
+  icmp_ttl.code = 0;
+  icmp_ttl.checksum = 0;
+  icmp_ttl.unused = 0; 
+  memcpy (&packet[off],
+         &icmp_ttl,
+         sizeof (struct icmp_ttl_exceeded_header));
+  off += sizeof (struct icmp_ttl_exceeded_header);
+
+  /* ip header of the presumably 'lost' udp packet */
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons(sizeof (struct ip_header) + sizeof (struct 
icmp_echo_header));
+  ip_pkt.id = htons (256);
+  ip_pkt.flags_frag_offset = 0;
+  ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
+  ip_pkt.proto = IPPROTO_ICMP;
+  ip_pkt.src_ip = other->s_addr;
+  ip_pkt.dst_ip = dummy.s_addr;
+  ip_pkt.checksum = 0;
+  ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
+                                       sizeof (struct ip_header)));
+  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 = htonl(port);
+  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));
+
+  /* no go back to calculate ICMP packet checksum */
+  off = sizeof (struct ip_header);
+  icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off],
+                                         sizeof (struct 
icmp_ttl_exceeded_header) +
+                                         sizeof (struct ip_header) +
+                                         sizeof (struct icmp_echo_header)));
+  memcpy (&packet[off],
+         &icmp_ttl,
+         sizeof (struct icmp_ttl_exceeded_header));
+
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+  dst.sin_addr = *other;
+
+  err = sendto(rawsock,
+              packet,
+              sizeof (packet), 0,
+              (struct sockaddr*)&dst,
+              sizeof(dst));
+
+  if (err < 0)
+    {
+      fprintf(stderr,
+             "sendto failed: %s\n", strerror(errno));
+    }
+  else if (sizeof (packet) != (size_t) err)
+    {
+      fprintf(stderr,
+             "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * Create an ICMP raw socket.
+ *
+ * @return INVALID_SOCKET on error
+ */
+static SOCKET
+make_raw_socket ()
+{
+  DWORD bOptVal = TRUE;
+  int bOptLen = sizeof(bOptVal);
+  SOCKET ret;
+
+  ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
+  if (INVALID_SOCKET == ret)
+    {
+      fprintf (stderr,
+              "Error opening RAW socket: %s\n",
+              strerror (errno));
+      return INVALID_SOCKET;
+    }
+  if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen))
+    {
+      fprintf(stderr,
+             "Error setting SO_BROADCAST to ON: %s\n",
+             strerror (errno));
+      closesocket(rawsock);
+      return INVALID_SOCKET;
+    }
+
+  if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen))
+    {
+      fprintf(stderr,
+             "Error setting IP_HDRINCL to ON: %s\n",
+             strerror (errno));
+      closesocket(rawsock);
+      return INVALID_SOCKET;
+    }
+  return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  struct in_addr external;
+  struct in_addr target;
+  WSADATA wsaData;
+
+  unsigned int p;
+
+  if (argc != 4)
+    {
+      fprintf (stderr,
+              "This program must be started with our IP, the targets external 
IP, and our port as arguments.\n");
+      return 1;
+    }
+  if ( (1 != inet_pton (AF_INET, argv[1], &external)) ||
+       (1 != inet_pton (AF_INET, argv[2], &target)) )
+    {
+      fprintf (stderr,
+              "Error parsing IPv4 address: %s\n",
+              strerror (errno));
+      return 1;
+    }
+  if ( (1 != sscanf (argv[3], "%u", &p) ) ||
+       (0 == p) ||
+       (0xFFFF < p) )
+    {
+      fprintf (stderr,
+              "Error parsing port value `%s'\n",
+              argv[3]);
+      return 1;
+    }
+  port = (uint16_t) p;
+
+  if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData))
+    {
+      fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
+      return 2;
+    }
+  if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
+    {
+      fprintf (stderr,
+              "Internal error converting dummy IP to binary.\n");
+      return 2;
+    }
+  if (-1 == (rawsock = make_raw_socket()))
+    return 3;
+  send_icmp (&external,
+            &target);
+  send_icmp_udp (&external,
+                 &target);
+  closesocket (rawsock);
+  WSACleanup ();
+  return 0;
+}
+
+/* end of gnunet-nat-client-windows.c */

Copied: gnunet/src/nat/gnunet-nat-client.c (from rev 15779, 
gnunet/src/transport/gnunet-nat-client.c)
===================================================================
--- gnunet/src/nat/gnunet-nat-client.c                          (rev 0)
+++ gnunet/src/nat/gnunet-nat-client.c  2011-06-27 20:22:33 UTC (rev 15780)
@@ -0,0 +1,527 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+
+/**
+ * @file src/transport/gnunet-nat-client.c
+ * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID 
will do)
+ *        This code will work under GNU/Linux only.
+ * @author Christian Grothoff
+ *
+ * This program will send ONE ICMP message using RAW sockets
+ * to the IP address specified as the second argument.  Since
+ * it uses RAW sockets, it must be installed SUID or run as 'root'.
+ * In order to keep the security risk of the resulting SUID binary
+ * minimal, the program ONLY opens the RAW socket with root
+ * privileges, then drops them and only then starts to process
+ * command line arguments.  The code also does not link against
+ * any shared libraries (except libc) and is strictly minimal
+ * (except for checking for errors).  The following list of people
+ * have reviewed this code and considered it safe since the last
+ * modification (if you reviewed it, please have your name added
+ * to the list):
+ *
+ * - Christian Grothoff
+ * - Nathan Evans
+ * - Benjamin Kuperman (22 Aug 2010)
+ */
+#if HAVE_CONFIG_H
+/* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */
+#include "gnunet_config.h"
+#else
+#define _GNU_SOURCE
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/in.h>
+
+/**
+ * Must match IP given in the server.
+ */
+#define DUMMY_IP "192.0.2.86"
+
+#define NAT_TRAV_PORT 22225
+
+/**
+ * IPv4 header.
+ */
+struct ip_header
+{
+
+  /**
+   * Version (4 bits) + Internet header length (4 bits)
+   */
+  uint8_t vers_ihl;
+
+  /**
+   * Type of service
+   */
+  uint8_t tos;
+
+  /**
+   * Total length
+   */
+  uint16_t pkt_len;
+
+  /**
+   * Identification
+   */
+  uint16_t id;
+
+  /**
+   * Flags (3 bits) + Fragment offset (13 bits)
+   */
+  uint16_t flags_frag_offset;
+
+  /**
+   * Time to live
+   */
+  uint8_t ttl;
+
+  /**
+   * Protocol
+   */
+  uint8_t proto;
+
+  /**
+   * Header checksum
+   */
+  uint16_t checksum;
+
+  /**
+   * Source address
+   */
+  uint32_t src_ip;
+
+  /**
+   * Destination address
+   */
+  uint32_t dst_ip;
+};
+
+/**
+ * Format of ICMP packet.
+ */
+struct icmp_ttl_exceeded_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t unused;
+
+  /* followed by original payload */
+};
+
+struct icmp_echo_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t reserved;
+};
+
+/**
+ * Beginning of UDP packet.
+ */
+struct udp_header
+{
+  uint16_t src_port;
+
+  uint16_t dst_port;
+
+  uint16_t length;
+
+  uint16_t crc;
+};
+
+/**
+ * Socket we use to send our fake ICMP replies.
+ */
+static int rawsock;
+
+/**
+ * Target "dummy" address of the packet we pretend to respond to.
+ */
+static struct in_addr dummy;
+
+/**
+ * Our "source" port.
+ */
+static uint16_t port;
+
+
+/**
+ * CRC-16 for IP/ICMP headers.
+ *
+ * @param data what to calculate the CRC over
+ * @param bytes number of bytes in data (must be multiple of 2)
+ * @return the CRC 16.
+ */
+static uint16_t
+calc_checksum (const uint16_t *data,
+              unsigned int bytes)
+{
+  uint32_t sum;
+  unsigned int i;
+
+  sum = 0;
+  for (i=0;i<bytes/2;i++)
+    sum += data[i];
+  sum = (sum & 0xffff) + (sum >> 16);
+  sum = htons(0xffff - sum);
+  return sum;
+}
+
+
+/**
+ * Send an ICMP message to the target.
+ *
+ * @param my_ip source address
+ * @param other target address
+ */
+static void
+send_icmp_udp (const struct in_addr *my_ip,
+               const struct in_addr *other)
+{
+  char packet[sizeof(struct ip_header) * 2 +
+             sizeof(struct icmp_ttl_exceeded_header) +
+             sizeof(struct udp_header)];
+  struct ip_header ip_pkt;
+  struct icmp_ttl_exceeded_header icmp_pkt;
+  struct udp_header udp_pkt;
+  struct sockaddr_in dst;
+  size_t off;
+  int err;
+
+  /* ip header: send to (known) ip address */
+  off = 0;
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons (sizeof (packet));
+  ip_pkt.id = htons(256);
+  ip_pkt.flags_frag_offset = 0;
+  ip_pkt.ttl = 128;
+  ip_pkt.proto = IPPROTO_ICMP;
+  ip_pkt.checksum = 0;
+  ip_pkt.src_ip = my_ip->s_addr;
+  ip_pkt.dst_ip = other->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));
+  off += sizeof(struct ip_header);
+
+  icmp_pkt.type = ICMP_TIME_EXCEEDED;
+  icmp_pkt.code = 0;
+  icmp_pkt.checksum = 0;
+  icmp_pkt.unused = 0;
+  memcpy(&packet[off],
+        &icmp_pkt,
+        sizeof(struct icmp_ttl_exceeded_header));
+  off += sizeof(struct icmp_ttl_exceeded_header);
+
+  /* ip header of the presumably 'lost' udp packet */
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons(sizeof (struct ip_header) +
+                        sizeof (struct udp_header));
+  ip_pkt.id = htons(0);
+  ip_pkt.flags_frag_offset = 0;
+  ip_pkt.ttl = 128;
+  ip_pkt.proto = IPPROTO_UDP;
+  ip_pkt.checksum = 0;
+  ip_pkt.src_ip = other->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));
+  off += sizeof(struct ip_header);
+
+  /* build UDP header */
+  udp_pkt.src_port = htons(NAT_TRAV_PORT);
+  udp_pkt.dst_port = htons(NAT_TRAV_PORT);
+  udp_pkt.length = htons (port);
+  udp_pkt.crc = 0;
+  memcpy(&packet[off],
+        &udp_pkt,
+        sizeof(struct udp_header));
+  off += sizeof(struct udp_header);
+
+  /* set ICMP checksum */
+  icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[sizeof(struct 
ip_header)],
+                                         sizeof (struct 
icmp_ttl_exceeded_header) +
+                                         sizeof (struct ip_header) +
+                                         sizeof (struct udp_header)));
+  memcpy (&packet[sizeof(struct ip_header)],
+         &icmp_pkt,
+         sizeof (struct icmp_ttl_exceeded_header));
+
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+  dst.sin_len = sizeof (struct sockaddr_in);
+#endif
+  dst.sin_addr = *other;
+  err = sendto(rawsock,
+               packet,
+               sizeof (packet), 0,
+               (struct sockaddr*)&dst,
+               sizeof(dst));
+  if (err < 0)
+    {
+      fprintf(stderr,
+              "sendto failed: %s\n", strerror(errno));
+    }
+  else if (sizeof (packet) != (size_t) err)
+    {
+      fprintf(stderr,
+              "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * Send an ICMP message to the target.
+ *
+ * @param my_ip source address
+ * @param other target address
+ */
+static void
+send_icmp (const struct in_addr *my_ip,
+          const struct in_addr *other)
+{
+  struct ip_header ip_pkt;
+  struct icmp_ttl_exceeded_header icmp_ttl;
+  struct icmp_echo_header icmp_echo;
+  struct sockaddr_in dst;
+  char packet[sizeof (struct ip_header) * 2 +
+             sizeof (struct icmp_ttl_exceeded_header) +
+             sizeof (struct icmp_echo_header)];
+  size_t off;
+  int err;
+
+  /* ip header: send to (known) ip address */
+  off = 0;
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons (sizeof (packet));
+  ip_pkt.id = htons (256);
+  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 = other->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));
+  off = sizeof (ip_pkt);
+
+  /* icmp reply: time exceeded */
+  icmp_ttl.type = ICMP_TIME_EXCEEDED;
+  icmp_ttl.code = 0;
+  icmp_ttl.checksum = 0;
+  icmp_ttl.unused = 0;
+  memcpy (&packet[off],
+         &icmp_ttl,
+         sizeof (struct icmp_ttl_exceeded_header));
+  off += sizeof (struct icmp_ttl_exceeded_header);
+
+  /* ip header of the presumably 'lost' udp packet */
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons (sizeof (struct ip_header) + sizeof (struct 
icmp_echo_header));
+  ip_pkt.id = htons (256);
+  ip_pkt.flags_frag_offset = 0;
+  ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
+  ip_pkt.proto = IPPROTO_ICMP;
+  ip_pkt.src_ip = other->s_addr;
+  ip_pkt.dst_ip = dummy.s_addr;
+  ip_pkt.checksum = 0;
+  ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
+                                       sizeof (struct ip_header)));
+  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 = htonl (port);
+  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));
+
+  /* no go back to calculate ICMP packet checksum */
+  off = sizeof (struct ip_header);
+  icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off],
+                                         sizeof (struct 
icmp_ttl_exceeded_header) +
+                                         sizeof (struct ip_header) +
+                                         sizeof (struct icmp_echo_header)));
+  memcpy (&packet[off],
+         &icmp_ttl,
+         sizeof (struct icmp_ttl_exceeded_header));
+
+  /* prepare for transmission */
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+  dst.sin_len = sizeof (struct sockaddr_in);
+#endif
+  dst.sin_addr = *other;
+  err = sendto(rawsock,
+              packet,
+              sizeof (packet), 0,
+              (struct sockaddr*)&dst,
+              sizeof(dst));
+  if (err < 0)
+    {
+      fprintf(stderr,
+             "sendto failed: %s\n", strerror(errno));
+    }
+  else if (sizeof (packet) != (size_t) err)
+    {
+      fprintf(stderr,
+             "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * Create an ICMP raw socket for writing.
+ *
+ * @return -1 on error
+ */
+static int
+make_raw_socket ()
+{
+  const int one = 1;
+  int ret;
+
+  ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
+  if (-1 == ret)
+    {
+      fprintf (stderr,
+              "Error opening RAW socket: %s\n",
+              strerror (errno));
+      return -1;
+    }
+  if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST,
+                     (char *)&one, sizeof(one)))
+    {
+      fprintf(stderr,
+             "setsockopt failed: %s\n",
+             strerror (errno));
+      close (ret);
+      return -1;
+    }
+  if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL,
+                     (char *)&one, sizeof(one)))
+    {
+      fprintf(stderr,
+             "setsockopt failed: %s\n",
+             strerror (errno));
+      close (ret);
+      return -1;
+    }
+  return ret;
+}
+
+
+int
+main (int argc, char *const *argv)
+{
+  struct in_addr external;
+  struct in_addr target;
+  uid_t uid;
+  unsigned int p;
+
+  if (4 != argc)
+    {
+      fprintf (stderr,
+              "This program must be started with our IP, the targets external 
IP, and our port as arguments.\n");
+      return 1;
+    }
+  if ( (1 != inet_pton (AF_INET, argv[1], &external)) ||
+       (1 != inet_pton (AF_INET, argv[2], &target)) )
+    {
+      fprintf (stderr,
+              "Error parsing IPv4 address: %s\n",
+              strerror (errno));
+      return 1;
+    }
+  if ( (1 != sscanf (argv[3], "%u", &p) ) ||
+       (0 == p) ||
+       (0xFFFF < p) )
+    {
+      fprintf (stderr,
+              "Error parsing port value `%s'\n",
+              argv[3]);
+      return 1;
+    }
+  port = (uint16_t) p;
+  if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
+    {
+      fprintf (stderr,
+              "Internal error converting dummy IP to binary.\n");
+      return 2;
+    }
+  if (-1 == (rawsock = make_raw_socket()))
+    return 2;
+  uid = getuid ();
+  if (0 != setresuid (uid, uid, uid))
+    {
+      fprintf (stderr,
+              "Failed to setresuid: %s\n",
+              strerror (errno));
+      /* not critical, continue anyway */
+    }
+  send_icmp (&external,
+            &target);
+  send_icmp_udp (&external,
+                &target);
+  close (rawsock);
+  return 0;
+}
+
+/* end of gnunet-nat-client.c */

Copied: gnunet/src/nat/gnunet-nat-server-script.sh (from rev 15779, 
gnunet/src/transport/gnunet-nat-server-script.sh)
===================================================================
--- gnunet/src/nat/gnunet-nat-server-script.sh                          (rev 0)
+++ gnunet/src/nat/gnunet-nat-server-script.sh  2011-06-27 20:22:33 UTC (rev 
15780)
@@ -0,0 +1,4 @@
+#!/bin/sh
+IP=`ifconfig | grep inet | head -n1 | awk '{print $2}' | sed -e "s/addr://"`
+echo "Using IP $IP"
+./gnunet-nat-server $IP | sed -u -e "s/.*/.\/gnunet-nat-server-udp $IP &\&/" | 
sh

Copied: gnunet/src/nat/gnunet-nat-server-windows.c (from rev 15779, 
gnunet/src/transport/gnunet-nat-server-windows.c)
===================================================================
--- gnunet/src/nat/gnunet-nat-server-windows.c                          (rev 0)
+++ gnunet/src/nat/gnunet-nat-server-windows.c  2011-06-27 20:22:33 UTC (rev 
15780)
@@ -0,0 +1,653 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+
+/**
+ * @file src/transport/gnunet-nat-server-windows.c
+ * @brief Windows tool to help bypass NATs using ICMP method
+ *        This code will work under W32 only
+ * @author Christian Grothoff
+ *
+ * This program will send ONE ICMP message every 500 ms RAW sockets
+ * to a DUMMY IP address and also listens for ICMP replies.  Since
+ * it uses RAW sockets, it must be run as an administrative user.
+ * In order to keep the security risk of the resulting binary
+ * minimal, the program ONLY opens the two RAW sockets with administrative
+ * privileges, then drops them and only then starts to process
+ * command line arguments.  The code also does not link against
+ * any shared libraries (except libc) and is strictly minimal
+ * (except for checking for errors).  The following list of people
+ * have reviewed this code and considered it safe since the last
+ * modification (if you reviewed it, please have your name added
+ * to the list):
+ *
+ * - Nathan Evans
+ * - Christian Grothoff
+ */
+#define _GNU_SOURCE
+
+
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <time.h>
+
+/**
+ * Should we print some debug output?
+ */
+#define VERBOSE 0
+
+/**
+ * Must match IP given in the client.
+ */
+#define DUMMY_IP "192.0.2.86"
+
+/**
+ * Default Port
+ */
+#define NAT_TRAV_PORT 22225
+
+/**
+ * TTL to use for our outgoing messages.
+ */
+#define IPDEFTTL 64
+
+#define ICMP_ECHO 8
+
+#define ICMP_TIME_EXCEEDED 11
+
+/**
+ * How often do we send our ICMP messages to receive replies?
+ */
+#define ICMP_SEND_FREQUENCY_MS 500
+
+/**
+ * IPv4 header.
+ */
+struct ip_header
+{
+
+  /**
+   * Version (4 bits) + Internet header length (4 bits)
+   */
+  uint8_t vers_ihl;
+
+  /**
+   * Type of service
+   */
+  uint8_t tos;
+
+  /**
+   * Total length
+   */
+  uint16_t pkt_len;
+
+  /**
+   * Identification
+   */
+  uint16_t id;
+
+  /**
+   * Flags (3 bits) + Fragment offset (13 bits)
+   */
+  uint16_t flags_frag_offset;
+
+  /**
+   * Time to live
+   */
+  uint8_t  ttl;
+
+  /**
+   * Protocol
+   */
+  uint8_t  proto;
+
+  /**
+   * Header checksum
+   */
+  uint16_t checksum;
+
+  /**
+   * Source address
+   */
+  uint32_t  src_ip;
+
+  /**
+   * Destination address
+   */
+  uint32_t  dst_ip;
+};
+
+/**
+ * Format of ICMP packet.
+ */
+struct icmp_ttl_exceeded_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t unused;
+
+  /* followed by original payload */
+};
+
+struct icmp_echo_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t reserved;
+};
+
+/**
+ * Beginning of UDP packet.
+ */
+struct udp_header
+{
+  uint16_t src_port;
+
+  uint16_t dst_port;
+
+  uint16_t length;
+
+  uint16_t crc;
+};
+
+/**
+ * Socket we use to receive "fake" ICMP replies.
+ */
+static SOCKET icmpsock;
+
+/**
+ * Socket we use to send our ICMP requests.
+ */
+static SOCKET rawsock;
+
+/**
+ * Socket we use to send our UDP requests.
+ */
+static SOCKET udpsock;
+
+/**
+ * Target "dummy" address.
+ */
+static struct in_addr dummy;
+
+
+/**
+ * CRC-16 for IP/ICMP headers.
+ *
+ * @param data what to calculate the CRC over
+ * @param bytes number of bytes in data (must be multiple of 2)
+ * @return the CRC 16.
+ */
+static uint16_t
+calc_checksum(const uint16_t *data,
+             unsigned int bytes)
+{
+  uint32_t sum;
+  unsigned int i;
+
+  sum = 0;
+  for (i=0;i<bytes/2;i++)
+    sum += data[i];
+  sum = (sum & 0xffff) + (sum >> 16);
+  sum = htons(0xffff - sum);
+  return sum;
+}
+
+
+/**
+ * Convert IPv4 address from text to binary form.
+ *
+ * @param af address family
+ * @param cp the address to print
+ * @param buf where to write the address result
+ * @return 1 on success
+ */
+static int
+inet_pton (int af,
+          const char *cp,
+          struct in_addr *buf)
+{
+  buf->s_addr = inet_addr(cp);
+  if (buf->s_addr == INADDR_NONE)
+    {
+      fprintf(stderr,
+             "Error %d handling address %s",
+             WSAGetLastError(),
+             cp);
+      return 0;
+    }
+  return 1;
+}
+
+
+/**
+ * Send an ICMP message to the dummy IP.
+ *
+ * @param my_ip source address (our ip address)
+ */
+static void
+send_icmp_echo (const struct in_addr *my_ip)
+{
+  char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)];
+  struct icmp_echo_header icmp_echo;
+  struct ip_header ip_pkt;
+  struct sockaddr_in dst;
+  size_t off;
+  int err;
+
+  off = 0;
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons (sizeof (packet));
+  ip_pkt.id = htons (256);
+  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));
+  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));
+  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));
+  if (err < 0)
+    {
+#if VERBOSE
+      fprintf(stderr,
+             "sendto failed: %s\n", strerror(errno));
+#endif
+    }
+  else if (err != off)
+    {
+      fprintf(stderr,
+             "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * Send a UDP message to the dummy IP.
+ */
+static void
+send_udp ()
+{
+  struct sockaddr_in dst;
+  ssize_t err;
+
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+  dst.sin_addr = dummy;
+  dst.sin_port = htons (NAT_TRAV_PORT);
+  err = sendto(udpsock,
+              NULL, 0, 0,
+              (struct sockaddr*)&dst,
+              sizeof(dst));
+  if (err < 0)
+    {
+#if VERBOSE
+      fprintf(stderr,
+             "sendto failed: %s\n", strerror(errno));
+#endif
+    }
+  else if (0 != err)
+    {
+      fprintf(stderr,
+             "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * We've received an ICMP response.  Process it.
+ */
+static void
+process_icmp_response ()
+{
+  char buf[65536];
+  ssize_t have;
+  struct in_addr source_ip;
+  struct ip_header ip_pkt;
+  struct icmp_ttl_exceeded_header icmp_ttl;
+  struct icmp_echo_header icmp_echo;
+  struct udp_header udp_pkt;
+  size_t off;
+  uint16_t port;
+  DWORD ssize;
+
+  have = read (icmpsock, buf, sizeof (buf));
+  if (have == -1)
+    {
+      fprintf (stderr,
+              "Error reading raw socket: %s\n",
+              strerror (errno));
+      return;
+    }
+#if VERBOSE
+  fprintf (stderr,
+           "Received message of %u bytes\n",
+           (unsigned int) have);
+#endif
+  if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct 
icmp_ttl_exceeded_header) + sizeof (struct ip_header)))
+    {
+      /* malformed */
+      return;
+    }
+  off = 0;
+  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));
+  off += sizeof (struct icmp_ttl_exceeded_header);
+  if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) ||
+       (0 != icmp_ttl.code) )
+    {
+      /* different type than what we want */
+      return;
+    }
+  /* skip 2nd IP header */
+  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)) )
+       {
+         /* malformed */
+         return;
+       }
+      /* grab ICMP ECHO content */
+      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)) )
+       {
+         /* malformed */
+         return;
+       }
+      /* grab UDP content */
+      memcpy (&udp_pkt,
+             &buf[off],
+             sizeof (struct udp_header));
+      port = ntohs (udp_pkt.length);
+      break;
+    default:
+      /* different type than what we want */
+      return;
+    }
+
+  ssize = sizeof(buf);
+  WSAAddressToString((LPSOCKADDR)&source_ip,
+                    sizeof(source_ip),
+                    NULL,
+                    buf,
+                    &ssize);
+  if (port == 0)
+    fprintf (stdout,
+            "%s\n",
+            buf);
+  else
+    fprintf (stdout,
+            "%s:%u\n",
+            buf,
+            (unsigned int) port);
+  fflush (stdout);
+}
+
+
+/**
+ * Create an ICMP raw socket for reading.
+ *
+ * @return INVALID_SOCKET on error
+ */
+static SOCKET
+make_icmp_socket ()
+{
+  SOCKET ret;
+
+  ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == ret)
+    {
+      fprintf (stderr,
+              "Error opening RAW socket: %s\n",
+              strerror (errno));
+      return INVALID_SOCKET;
+    }
+  return ret;
+}
+
+
+/**
+ * Create an ICMP raw socket for writing.
+ *
+ * @return INVALID_SOCKET on error
+ */
+static SOCKET
+make_raw_socket ()
+{
+  DWORD bOptVal = TRUE;
+  int bOptLen = sizeof(bOptVal);
+
+  rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == rawsock)
+    {
+      fprintf (stderr,
+              "Error opening RAW socket: %s\n",
+              strerror (errno));
+      return INVALID_SOCKET;
+    }
+
+  if (0 != setsockopt(rawsock,
+                     SOL_SOCKET,
+                     SO_BROADCAST,
+                     (char*)&bOptVal, bOptLen))
+    {
+      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))
+    {
+      fprintf(stderr,
+             "Error setting IP_HDRINCL to ON: %s\n",
+             strerror (errno));
+      closesocket(rawsock);
+      return INVALID_SOCKET;
+    }
+  return rawsock;
+}
+
+
+/**
+ * Create a UDP socket for writing.
+ *
+ * @param my_ip source address (our ip address)
+ * @return INVALID_SOCKET on error
+ */
+static SOCKET
+make_udp_socket (const struct in_addr *my_ip)
+{
+  SOCKET ret;
+  struct sockaddr_in addr;
+
+  ret = socket (AF_INET, SOCK_DGRAM, 0);
+  if (INVALID_SOCKET == ret)
+    {
+      fprintf (stderr,
+              "Error opening UDP socket: %s\n",
+              strerror (errno));
+      return INVALID_SOCKET;
+    }
+  memset (&addr, 0, sizeof (addr));
+  addr.sin_family = AF_INET;
+  addr.sin_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));
+      /* likely problematic, but not certain, try to continue */
+    }
+  return ret;
+}
+
+
+int
+main (int argc,
+      char *const *argv)
+{
+  struct in_addr external;
+  fd_set rs;
+  struct timeval tv;
+  WSADATA wsaData;
+  unsigned int alt;
+
+  alt = 0;
+  if (2 != argc)
+    {
+      fprintf (stderr,
+              "This program must be started with our (internal NAT) IP as the 
only argument.\n");
+      return 1;
+    }
+  if (1 != inet_pton (AF_INET, argv[1], &external))
+    {
+      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))
+    {
+      fprintf (stderr,
+              "Internal error converting dummy IP to binary.\n");
+      return 2;
+    }
+  if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
+    {
+      fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
+      return 2;
+    }
+  if (INVALID_SOCKET == (icmpsock = make_icmp_socket()))
+    {
+      return 3;
+    }
+  if (INVALID_SOCKET == (make_raw_socket()))
+    {
+      closesocket (icmpsock);
+      return 3;
+    }
+  if (INVALID_SOCKET == (udpsock = make_udp_socket(&external)))
+    {
+      closesocket (icmpsock);
+      closesocket (rawsock);
+      return 3;
+    }
+  while (1)
+    {
+      FD_ZERO (&rs);
+      FD_SET (icmpsock, &rs);
+      tv.tv_sec = 0;
+      tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
+      if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
+       {
+         if (errno == EINTR)
+           continue;
+         fprintf (stderr,
+                  "select failed: %s\n",
+                  strerror (errno));
+         break;
+       }
+      if (FD_ISSET (icmpsock, &rs))
+        process_icmp_response ();
+      if (0 == (++alt % 2))
+       send_icmp_echo (&external);
+      else
+       send_udp ();
+    }
+  /* select failed (internal error or OS out of resources) */
+  closesocket(icmpsock);
+  closesocket(rawsock);
+  closesocket(udpsock);
+  WSACleanup ();
+  return 4;
+}
+
+
+/* end of gnunet-nat-server-windows.c */

Copied: gnunet/src/nat/gnunet-nat-server.c (from rev 15779, 
gnunet/src/transport/gnunet-nat-server.c)
===================================================================
--- gnunet/src/nat/gnunet-nat-server.c                          (rev 0)
+++ gnunet/src/nat/gnunet-nat-server.c  2011-06-27 20:22:33 UTC (rev 15780)
@@ -0,0 +1,651 @@
+/*
+     This file is part of GNUnet.
+     (C) 2010 Christian Grothoff (and other contributing authors)
+
+     GNUnet is free software; you can redistribute it and/or modify
+     it under the terms of the GNU General Public License as published
+     by the Free Software Foundation; either version 3, or (at your
+     option) any later version.
+
+     GNUnet is distributed in the hope that it will be useful, but
+     WITHOUT ANY WARRANTY; without even the implied warranty of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+     General Public License for more details.
+
+     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.
+*/
+
+/**
+ * @file src/transport/gnunet-nat-server.c
+ * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID 
will do)
+ *        This code will work under GNU/Linux only (or maybe BSDs, but never 
W32)
+ * @author Christian Grothoff
+ *
+ * This program will send ONE ICMP message every 500 ms RAW sockets
+ * to a DUMMY IP address and also listens for ICMP replies.  Since
+ * it uses RAW sockets, it must be installed SUID or run as 'root'.
+ * In order to keep the security risk of the resulting SUID binary
+ * minimal, the program ONLY opens the two RAW sockets with root
+ * privileges, then drops them and only then starts to process
+ * command line arguments.  The code also does not link against
+ * any shared libraries (except libc) and is strictly minimal
+ * (except for checking for errors).  The following list of people
+ * have reviewed this code and considered it safe since the last
+ * modification (if you reviewed it, please have your name added
+ * to the list):
+ *
+ * - Christian Grothoff
+ * - Nathan Evans
+ * - Benjamin Kuperman (22 Aug 2010)
+ */
+#if HAVE_CONFIG_H
+/* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */
+#include "gnunet_config.h"
+#else
+#define _GNU_SOURCE
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <time.h>
+#include <netinet/ip.h>
+#include <netinet/ip_icmp.h>
+#include <netinet/in.h>
+
+/**
+ * Should we print some debug output?
+ */
+#define VERBOSE 0
+
+/**
+ * Must match IP given in the client.
+ */
+#define DUMMY_IP "192.0.2.86"
+
+/**
+ * Port for UDP
+ */
+#define NAT_TRAV_PORT 22225
+
+/**
+ * How often do we send our ICMP messages to receive replies?
+ */
+#define ICMP_SEND_FREQUENCY_MS 500
+
+/**
+ * IPv4 header.
+ */
+struct ip_header
+{
+
+  /**
+   * Version (4 bits) + Internet header length (4 bits)
+   */
+  uint8_t vers_ihl;
+
+  /**
+   * Type of service
+   */
+  uint8_t tos;
+
+  /**
+   * Total length
+   */
+  uint16_t pkt_len;
+
+  /**
+   * Identification
+   */
+  uint16_t id;
+
+  /**
+   * Flags (3 bits) + Fragment offset (13 bits)
+   */
+  uint16_t flags_frag_offset;
+
+  /**
+   * Time to live
+   */
+  uint8_t ttl;
+
+  /**
+   * Protocol
+   */
+  uint8_t proto;
+
+  /**
+   * Header checksum
+   */
+  uint16_t checksum;
+
+  /**
+   * Source address
+   */
+  uint32_t src_ip;
+
+  /**
+   * Destination address
+   */
+  uint32_t dst_ip;
+};
+
+/**
+ * Format of ICMP packet.
+ */
+struct icmp_ttl_exceeded_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t unused;
+
+  /* followed by original payload */
+};
+
+struct icmp_echo_header
+{
+  uint8_t type;
+
+  uint8_t code;
+
+  uint16_t checksum;
+
+  uint32_t reserved;
+};
+
+
+/**
+ * Beginning of UDP packet.
+ */
+struct udp_header
+{
+  uint16_t src_port;
+
+  uint16_t dst_port;
+
+  uint16_t length;
+
+  uint16_t crc;
+};
+
+/**
+ * Socket we use to receive "fake" ICMP replies.
+ */
+static int icmpsock;
+
+/**
+ * Socket we use to send our ICMP requests.
+ */
+static int rawsock;
+
+/**
+ * Socket we use to send our UDP requests.
+ */
+static int udpsock;
+
+/**
+ * Target "dummy" address.
+ */
+static struct in_addr dummy;
+
+
+/**
+ * CRC-16 for IP/ICMP headers.
+ *
+ * @param data what to calculate the CRC over
+ * @param bytes number of bytes in data (must be multiple of 2)
+ * @return the CRC 16.
+ */
+static uint16_t
+calc_checksum(const uint16_t *data,
+             unsigned int bytes)
+{
+  uint32_t sum;
+  unsigned int i;
+
+  sum = 0;
+  for (i=0;i<bytes/2;i++)
+    sum += data[i];
+  sum = (sum & 0xffff) + (sum >> 16);
+  sum = htons(0xffff - sum);
+  return sum;
+}
+
+
+/**
+ * Send an ICMP message to the dummy IP.
+ *
+ * @param my_ip source address (our ip address)
+ */
+static void
+send_icmp_echo (const struct in_addr *my_ip)
+{
+  char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)];
+  struct icmp_echo_header icmp_echo;
+  struct ip_header ip_pkt;
+  struct sockaddr_in dst;
+  size_t off;
+  int err;
+
+  off = 0;
+  ip_pkt.vers_ihl = 0x45;
+  ip_pkt.tos = 0;
+  ip_pkt.pkt_len = htons (sizeof (packet));
+  ip_pkt.id = htons (256);
+  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));
+  off += sizeof (struct ip_header);
+
+  icmp_echo.type = ICMP_ECHO;
+  icmp_echo.code = 0;
+  icmp_echo.checksum = 0;
+  icmp_echo.reserved = 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));
+  off += sizeof (struct icmp_echo_header);
+
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+  dst.sin_len = sizeof (struct sockaddr_in);
+#endif
+  dst.sin_addr = dummy;
+  err = sendto(rawsock,
+              packet, off, 0,
+              (struct sockaddr*)&dst,
+              sizeof(dst));
+  if (err < 0)
+    {
+#if VERBOSE
+      fprintf(stderr,
+             "sendto failed: %s\n", strerror(errno));
+#endif
+    }
+  else if (sizeof (packet) != err)
+    {
+      fprintf(stderr,
+             "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * Send a UDP message to the dummy IP.
+ */
+static void
+send_udp ()
+{
+  struct sockaddr_in dst;
+  ssize_t err;
+
+  memset (&dst, 0, sizeof (dst));
+  dst.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+  dst.sin_len = sizeof (struct sockaddr_in);
+#endif
+  dst.sin_addr = dummy;
+  dst.sin_port = htons (NAT_TRAV_PORT);
+  err = sendto(udpsock,
+              NULL, 0, 0,
+              (struct sockaddr*)&dst,
+              sizeof(dst));
+  if (err < 0)
+    {
+#if VERBOSE
+      fprintf(stderr,
+             "sendto failed: %s\n", strerror(errno));
+#endif
+    }
+  else if (0 != err)
+    {
+      fprintf(stderr,
+             "Error: partial send of ICMP message\n");
+    }
+}
+
+
+/**
+ * We've received an ICMP response.  Process it.
+ */
+static void
+process_icmp_response ()
+{
+  char buf[65536];
+  ssize_t have;
+  struct in_addr source_ip;
+  struct ip_header ip_pkt;
+  struct icmp_ttl_exceeded_header icmp_ttl;
+  struct icmp_echo_header icmp_echo;
+  struct udp_header udp_pkt;
+  size_t off;
+  uint16_t port;
+
+  have = read (icmpsock, buf, sizeof (buf));
+  if (-1 == have)
+    {
+      fprintf (stderr,
+              "Error reading raw socket: %s\n",
+              strerror (errno));
+      return;
+    }
+#if VERBOSE
+  fprintf (stderr,
+           "Received message of %u bytes\n",
+           (unsigned int) have);
+#endif
+  if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct 
icmp_ttl_exceeded_header) + sizeof (struct ip_header)))
+    {
+      /* malformed */
+      return;
+    }
+  off = 0;
+  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));
+  off += sizeof (struct icmp_ttl_exceeded_header);
+  if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) ||
+       (0 != icmp_ttl.code) )
+    {
+      /* different type than what we want */
+      return;
+    }
+  /* skip 2nd IP header */
+  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)) )
+       {
+         /* malformed */
+         return;
+       }
+      /* grab ICMP ECHO content */
+      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)) )
+       {
+         /* malformed */
+         return;
+       }
+      /* grab UDP content */
+      memcpy (&udp_pkt,
+             &buf[off],
+             sizeof (struct udp_header));
+      port = ntohs (udp_pkt.length);
+      break;
+    default:
+      /* different type than what we want */
+      return;
+    }
+
+  if (port == 0)
+    fprintf (stdout,
+            "%s\n",
+            inet_ntop (AF_INET,
+                       &source_ip,
+                       buf,
+                       sizeof (buf)));
+  else
+    fprintf (stdout,
+            "%s:%u\n",
+            inet_ntop (AF_INET,
+                       &source_ip,
+                       buf,
+                       sizeof (buf)),
+            (unsigned int) port);
+  fflush (stdout);
+}
+
+
+/**
+ * Create an ICMP raw socket for reading.
+ *
+ * @return -1 on error
+ */
+static int
+make_icmp_socket ()
+{
+  int ret;
+
+  ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (-1 == ret)
+    {
+      fprintf (stderr,
+              "Error opening RAW socket: %s\n",
+              strerror (errno));
+      return -1;
+    }
+  if (ret >= FD_SETSIZE)
+    {
+      fprintf (stderr,
+              "Socket number too large (%d > %u)\n",
+              ret,
+              (unsigned int) FD_SETSIZE);
+      close (ret);
+      return -1;
+    }
+  return ret;
+}
+
+
+/**
+ * Create an ICMP raw socket for writing.
+ *
+ * @return -1 on error
+ */
+static int
+make_raw_socket ()
+{
+  const int one = 1;
+  int ret;
+
+  ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
+  if (-1 == ret)
+    {
+      fprintf (stderr,
+              "Error opening RAW socket: %s\n",
+              strerror (errno));
+      return -1;
+    }
+  if (-1 == setsockopt(ret,
+                      SOL_SOCKET,
+                      SO_BROADCAST,
+                      (char *)&one, sizeof(one)))
+    {
+      fprintf(stderr,
+             "setsockopt failed: %s\n",
+             strerror (errno));
+      close (ret);
+      return -1;
+    }
+  if (-1 == setsockopt(ret,
+                      IPPROTO_IP,
+                      IP_HDRINCL,
+                      (char *)&one, sizeof(one)))
+    {
+      fprintf(stderr,
+             "setsockopt failed: %s\n",
+             strerror (errno));
+      close (ret);
+      return -1;
+    }
+  return ret;
+}
+
+
+/**
+ * Create a UDP socket for writinging.
+ *
+ * @param my_ip source address (our ip address)
+ * @return -1 on error
+ */
+static int
+make_udp_socket (const struct in_addr *my_ip)
+{
+  int ret;
+  struct sockaddr_in addr;
+
+  ret = socket (AF_INET, SOCK_DGRAM, 0);
+  if (-1 == ret)
+    {
+      fprintf (stderr,
+              "Error opening UDP socket: %s\n",
+              strerror (errno));
+      return -1;
+    }
+  memset (&addr,
+         0,
+         sizeof (addr));
+  addr.sin_family = AF_INET;
+#if HAVE_SOCKADDR_IN_SIN_LEN
+  addr.sin_len = sizeof (struct sockaddr_in);
+#endif
+  addr.sin_addr = *my_ip;
+  addr.sin_port = htons (NAT_TRAV_PORT);
+
+  if (0 != bind (ret,
+                &addr,
+                sizeof(addr)))
+    {
+      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;
+}
+
+
+int
+main (int argc,
+      char *const *argv)
+{
+  struct in_addr external;
+  fd_set rs;
+  struct timeval tv;
+  uid_t uid;
+  unsigned int alt;
+
+  if (2 != argc)
+    {
+      fprintf (stderr,
+              "This program must be started with our (internal NAT) IP as the 
only argument.\n");
+      return 1;
+    }
+  if (1 != inet_pton (AF_INET, argv[1], &external))
+    {
+      fprintf (stderr,
+              "Error parsing IPv4 address: %s\n",
+              strerror (errno));
+      return 1;
+    }
+  if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
+    {
+      fprintf (stderr,
+              "Internal error converting dummy IP to binary.\n");
+      return 2;
+    }
+  if (-1 == (icmpsock = make_icmp_socket()))
+    {
+      return 3;
+    }
+  if (-1 == (rawsock = make_raw_socket()))
+    {
+      close (icmpsock);
+      return 3;
+    }
+  uid = getuid ();
+  if (0 != setresuid (uid, uid, uid))
+    {
+      fprintf (stderr,
+              "Failed to setresuid: %s\n",
+              strerror (errno));
+      /* not critical, continue anyway */
+    }
+  if (-1 == (udpsock = make_udp_socket(&external)))
+    {
+      close (icmpsock);
+      close (rawsock);
+      return 3;
+    }
+  alt = 0;
+  while (1)
+    {
+      FD_ZERO (&rs);
+      FD_SET (icmpsock, &rs);
+      tv.tv_sec = 0;
+      tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
+      if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
+       {
+         if (errno == EINTR)
+           continue;
+         fprintf (stderr,
+                  "select failed: %s\n",
+                  strerror (errno));
+         break;
+       }
+      if (1 == getppid()) /* Check the parent process id, if 1 the parent has 
died, so we should die too */
+        break;
+      if (FD_ISSET (icmpsock, &rs))
+        process_icmp_response ();
+      if (0 == (++alt % 2))
+       send_icmp_echo (&external);
+      else
+       send_udp ();
+    }
+  /* select failed (internal error or OS out of resources) */
+  close (icmpsock);
+  close (rawsock);
+  close (udpsock);
+  return 4;
+}
+
+
+/* end of gnunet-nat-server.c */

Modified: gnunet/src/transport/Makefile.am
===================================================================
--- gnunet/src/transport/Makefile.am    2011-06-27 17:02:59 UTC (rev 15779)
+++ gnunet/src/transport/Makefile.am    2011-06-27 20:22:33 UTC (rev 15780)
@@ -2,15 +2,6 @@
 
 plugindir = $(libdir)/gnunet
 
-if MINGW
-  WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
-  NATBIN = gnunet-nat-server gnunet-nat-client
-  NATSERVER = gnunet-nat-server-windows.c
-  NATCLIENT = gnunet-nat-client-windows.c
-else
-  NATSERVER = gnunet-nat-server.c
-  NATCLIENT = gnunet-nat-client.c
-endif
 
 if HAVE_MHD
 if HAVE_EXPERIMENTAL
@@ -53,15 +44,6 @@
      test_quota_compliance_unix_asymmetric_recv_constant
 endif
 
-if LINUX
-NATBIN = gnunet-nat-server gnunet-nat-client
-install-exec-hook:
-       chown root:root $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client 
$(bindir)/gnunet-transport-wlan-helper || true
-       chmod u+s $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client 
$(bindir)/gnunet-transport-wlan-helper || true
-else
-install-exec-hook:
-endif
-
 #noinst_PROGRAMS = ${check_PROGRAMS}
 
 lib_LTLIBRARIES = \
@@ -96,16 +78,13 @@
 bin_PROGRAMS = \
  gnunet-transport \
  $(WLAN_BIN) \
- gnunet-service-transport $(NATBIN) \
+ gnunet-service-transport \
  $(WLAN_BIN_DUMMY)
 
 bin_SCRIPTS = \
  gnunet-transport-certificate-creation
 
-gnunet_nat_server_SOURCES = \
- $(NATSERVER)
 
-
 gnunet_transport_wlan_helper_SOURCES = \
  wlan/byteorder.h \
  wlan/crctable_osdep.h \
@@ -127,9 +106,6 @@
 gnunet_transport_wlan_helper_dummy_LDADD = \
   $(top_builddir)/src/util/libgnunetutil.la 
 
-gnunet_nat_client_SOURCES = \
- $(NATCLIENT)         
-
 gnunet_transport_SOURCES = \
  gnunet-transport.c         
 gnunet_transport_LDADD = \
@@ -161,7 +137,6 @@
   $(HTTPS_PLUGIN_LA) \
   $(WLAN_PLUGIN_LA) \
   libgnunet_plugin_transport_template.la
-# TODO: add nat, etc.
 
 libgnunet_plugin_transport_tcp_la_SOURCES = \
   plugin_transport_tcp.c
@@ -197,6 +172,7 @@
   $(top_builddir)/src/hello/libgnunethello.la \
   $(top_builddir)/src/statistics/libgnunetstatistics.la \
   $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
+  $(top_builddir)/src/nat/libgnunetnat.la \
   $(top_builddir)/src/util/libgnunetutil.la 
 libgnunet_plugin_transport_udp_la_LDFLAGS = \
  $(GN_PLUGIN_LDFLAGS)
@@ -218,6 +194,7 @@
   $(top_builddir)/src/statistics/libgnunetstatistics.la \
   $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
   @LIBCURL@ \
+  $(top_builddir)/src/nat/libgnunetnat.la \
   $(top_builddir)/src/util/libgnunetutil.la 
 libgnunet_plugin_transport_http_la_LDFLAGS = \
  $(GN_LIBMHD) \
@@ -234,6 +211,7 @@
   $(top_builddir)/src/statistics/libgnunetstatistics.la \
   $(top_builddir)/src/peerinfo/libgnunetpeerinfo.la \
   @LIBCURL@ \
+  $(top_builddir)/src/nat/libgnunetnat.la \
   $(top_builddir)/src/util/libgnunetutil.la 
 libgnunet_plugin_transport_https_la_LDFLAGS = \
  $(GN_LIBMHD) \
@@ -277,7 +255,6 @@
  $(WLAN_API_TEST) \
  $(WLAN_REL_TEST) \
  $(WLAN_UREL_TEST)
-# TODO: add tests for nat, etc.
 
 if ENABLE_TEST_RUN
 TESTS = \

Deleted: gnunet/src/transport/gnunet-nat-client-script.sh
===================================================================
--- gnunet/src/transport/gnunet-nat-client-script.sh    2011-06-27 17:02:59 UTC 
(rev 15779)
+++ gnunet/src/transport/gnunet-nat-client-script.sh    2011-06-27 20:22:33 UTC 
(rev 15780)
@@ -1,4 +0,0 @@
-#!/bin/sh
-IP=`ifconfig | grep inet | head -n1 | awk '{print $2}' | sed -e "s/addr://"`
-echo "Using IP $IP, trying to connect to $1"
-./gnunet-nat-client-udp $IP $1

Deleted: gnunet/src/transport/gnunet-nat-client-windows.c
===================================================================
--- gnunet/src/transport/gnunet-nat-client-windows.c    2011-06-27 17:02:59 UTC 
(rev 15779)
+++ gnunet/src/transport/gnunet-nat-client-windows.c    2011-06-27 20:22:33 UTC 
(rev 15780)
@@ -1,550 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file src/transport/gnunet-nat-client-windows.c
- * @brief Tool to help bypass NATs using ICMP method; must run as
- *        root (SUID will do) or administrator on W32
- *        This code will work under GNU/Linux or W32.
- * @author Nathan Evans
- *
- * This program will send ONE ICMP message using RAW sockets
- * to the IP address specified as the second argument.  Since
- * it uses RAW sockets, it must be installed SUID or run as 'root'.
- * In order to keep the security risk of the resulting SUID binary
- * minimal, the program ONLY opens the RAW socket with root
- * privileges, then drops them and only then starts to process
- * command line arguments.  The code also does not link against
- * any shared libraries (except libc) and is strictly minimal
- * (except for checking for errors).  The following list of people
- * have reviewed this code and considered it safe since the last
- * modification (if you reviewed it, please have your name added
- * to the list):
- *
- * - Christian Grothoff
- * - Nathan Evans
- */
-#define _GNU_SOURCE
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <time.h>
-
-
-#define ICMP_ECHO 8
-#define IPDEFTTL 64
-#define ICMP_TIME_EXCEEDED 11
-
-/**
- * Must match IP given in the server.
- */
-#define DUMMY_IP "192.0.2.86"
-
-#define NAT_TRAV_PORT 22225
-
-/**
- * IPv4 header.
- */
-struct ip_header
-{
-
-  /**
-   * Version (4 bits) + Internet header length (4 bits)
-   */
-  uint8_t vers_ihl;
-
-  /**
-   * Type of service
-   */
-  uint8_t tos;
-
-  /**
-   * Total length
-   */
-  uint16_t pkt_len;
-
-  /**
-   * Identification
-   */
-  uint16_t id;
-
-  /**
-   * Flags (3 bits) + Fragment offset (13 bits)
-   */
-  uint16_t flags_frag_offset;
-
-  /**
-   * Time to live
-   */
-  uint8_t ttl;
-
-  /**
-   * Protocol
-   */
-  uint8_t proto;
-
-  /**
-   * Header checksum
-   */
-  uint16_t checksum;
-
-  /**
-   * Source address
-   */
-  uint32_t src_ip;
-
-  /**
-   * Destination address
-   */
-  uint32_t dst_ip;
-};
-
-
-/**
- * Format of ICMP packet.
- */
-struct icmp_ttl_exceeded_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t unused;
-
-  /* followed by original payload */
-};
-
-struct icmp_echo_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t reserved;
-};
-
-/**
- * Beginning of UDP packet.
- */
-struct udp_header
-{
-  uint16_t src_port;
-
-  uint16_t dst_port;
-
-  uint16_t length;
-
-  uint16_t crc;
-};
-
-
-/**
- * Socket we use to send our ICMP packets.
- */
-static SOCKET rawsock;
-
-/**
- * Target "dummy" address.
- */
-static struct in_addr dummy;
-
-/**
- * Port we are listening on (communicated to the server).
- */
-static uint16_t port;
-
-
-
-/**
- * Convert IPv4 address from text to binary form.
- *
- * @param af address family
- * @param cp the address to print
- * @param buf where to write the address result
- * @return 1 on success
- */
-static int
-inet_pton (int af,
-          const char *cp,
-          struct in_addr *buf)
-{
-  buf->s_addr = inet_addr(cp);
-  if (buf->s_addr == INADDR_NONE)
-    {
-      fprintf(stderr,
-             "Error %d handling address %s",
-             WSAGetLastError(),
-             cp);
-      return 0;
-    }
-  return 1;
-}
-
-
-/**
- * CRC-16 for IP/ICMP headers.
- *
- * @param data what to calculate the CRC over
- * @param bytes number of bytes in data (must be multiple of 2)
- * @return the CRC 16.
- */
-static uint16_t
-calc_checksum(const uint16_t *data,
-             unsigned int bytes)
-{
-  uint32_t sum;
-  unsigned int i;
-
-  sum = 0;
-  for (i=0;i<bytes/2;i++)
-    sum += data[i];
-  sum = (sum & 0xffff) + (sum >> 16);
-  sum = htons(0xffff - sum);
-  return sum;
-}
-
-
-/**
- * Send an ICMP message to the target.
- *
- * @param my_ip source address
- * @param other target address
- */
-static void
-send_icmp_udp (const struct in_addr *my_ip,
-               const struct in_addr *other)
-{
-  char packet[sizeof(struct ip_header) * 2 +
-             sizeof(struct icmp_ttl_exceeded_header) +
-             sizeof(struct udp_header)];
-  struct ip_header ip_pkt;
-  struct icmp_ttl_exceeded_header icmp_pkt;
-  struct udp_header udp_pkt;
-  struct sockaddr_in dst;
-  size_t off;
-  int err;
-
-  /* ip header: send to (known) ip address */
-  off = 0;
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons(sizeof (packet));
-  ip_pkt.id = htons(256);
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 128;
-  ip_pkt.proto = IPPROTO_ICMP;
-  ip_pkt.checksum = 0;
-  ip_pkt.src_ip = my_ip->s_addr;
-  ip_pkt.dst_ip = other->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));
-  off += sizeof(struct ip_header);
-
-  icmp_pkt.type = ICMP_TIME_EXCEEDED;
-  icmp_pkt.code = 0;
-  icmp_pkt.checksum = 0;
-  icmp_pkt.unused = 0;
-  memcpy(&packet[off],
-        &icmp_pkt,
-        sizeof(struct icmp_ttl_exceeded_header));
-  off += sizeof(struct icmp_ttl_exceeded_header);
-
-  /* ip header of the presumably 'lost' udp packet */
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons(sizeof (struct ip_header) +
-                        sizeof (struct udp_header));
-  ip_pkt.id = htons(0);
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 128;
-  ip_pkt.proto = IPPROTO_UDP;
-  ip_pkt.checksum = 0;
-  ip_pkt.src_ip = other->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));
-  off += sizeof(struct ip_header);
-
-  /* build UDP header */
-  udp_pkt.src_port = htons(NAT_TRAV_PORT);
-  udp_pkt.dst_port = htons(NAT_TRAV_PORT);
-  udp_pkt.length = htons (port);
-  udp_pkt.crc = 0;
-  memcpy(&packet[off],
-        &udp_pkt,
-        sizeof(struct udp_header));
-  off += sizeof(struct udp_header);
-
-  /* no go back to calculate ICMP packet checksum */
-  icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[off],
-                                         sizeof (struct 
icmp_ttl_exceeded_header) +
-                                         sizeof (struct ip_header) +
-                                         sizeof (struct udp_header)));
-  memcpy (&packet[sizeof (struct ip_header)],
-         &icmp_pkt,
-         sizeof (struct icmp_ttl_exceeded_header));
-
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-  dst.sin_addr = *other;
-  err = sendto(rawsock,
-               packet,
-               sizeof (packet), 0,
-               (struct sockaddr*)&dst,
-               sizeof(dst));
-  if (err < 0)
-    {
-      fprintf(stderr,
-              "sendto failed: %s\n", strerror(errno));
-    }
-  else if (sizeof (packet) != (size_t) err)
-    {
-      fprintf(stderr,
-              "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * Send an ICMP message to the target.
- *
- * @param my_ip source address
- * @param other target address
- */
-static void
-send_icmp (const struct in_addr *my_ip,
-          const struct in_addr *other)
-{
-  struct ip_header ip_pkt;
-  struct icmp_ttl_exceeded_header icmp_ttl;
-  struct icmp_echo_header icmp_echo;
-  struct sockaddr_in dst;
-  char packet[sizeof (struct ip_header) * 2 +
-             sizeof (struct icmp_ttl_exceeded_header) +
-             sizeof(struct icmp_echo_header)];
-  size_t off;
-  int err;
-
-  /* ip header: send to (known) ip address */
-  off = 0;
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons (sizeof (packet));
-  ip_pkt.id = htons(256);
-  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 = other->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));
-  off += sizeof (ip_pkt);
-
-  /* icmp reply: time exceeded */
-  icmp_ttl.type = ICMP_TIME_EXCEEDED;
-  icmp_ttl.code = 0;
-  icmp_ttl.checksum = 0;
-  icmp_ttl.unused = 0; 
-  memcpy (&packet[off],
-         &icmp_ttl,
-         sizeof (struct icmp_ttl_exceeded_header));
-  off += sizeof (struct icmp_ttl_exceeded_header);
-
-  /* ip header of the presumably 'lost' udp packet */
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons(sizeof (struct ip_header) + sizeof (struct 
icmp_echo_header));
-  ip_pkt.id = htons (256);
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
-  ip_pkt.proto = IPPROTO_ICMP;
-  ip_pkt.src_ip = other->s_addr;
-  ip_pkt.dst_ip = dummy.s_addr;
-  ip_pkt.checksum = 0;
-  ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
-                                       sizeof (struct ip_header)));
-  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 = htonl(port);
-  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));
-
-  /* no go back to calculate ICMP packet checksum */
-  off = sizeof (struct ip_header);
-  icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off],
-                                         sizeof (struct 
icmp_ttl_exceeded_header) +
-                                         sizeof (struct ip_header) +
-                                         sizeof (struct icmp_echo_header)));
-  memcpy (&packet[off],
-         &icmp_ttl,
-         sizeof (struct icmp_ttl_exceeded_header));
-
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-  dst.sin_addr = *other;
-
-  err = sendto(rawsock,
-              packet,
-              sizeof (packet), 0,
-              (struct sockaddr*)&dst,
-              sizeof(dst));
-
-  if (err < 0)
-    {
-      fprintf(stderr,
-             "sendto failed: %s\n", strerror(errno));
-    }
-  else if (sizeof (packet) != (size_t) err)
-    {
-      fprintf(stderr,
-             "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * Create an ICMP raw socket.
- *
- * @return INVALID_SOCKET on error
- */
-static SOCKET
-make_raw_socket ()
-{
-  DWORD bOptVal = TRUE;
-  int bOptLen = sizeof(bOptVal);
-  SOCKET ret;
-
-  ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
-  if (INVALID_SOCKET == ret)
-    {
-      fprintf (stderr,
-              "Error opening RAW socket: %s\n",
-              strerror (errno));
-      return INVALID_SOCKET;
-    }
-  if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen))
-    {
-      fprintf(stderr,
-             "Error setting SO_BROADCAST to ON: %s\n",
-             strerror (errno));
-      closesocket(rawsock);
-      return INVALID_SOCKET;
-    }
-
-  if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL, (char*)&bOptVal, bOptLen))
-    {
-      fprintf(stderr,
-             "Error setting IP_HDRINCL to ON: %s\n",
-             strerror (errno));
-      closesocket(rawsock);
-      return INVALID_SOCKET;
-    }
-  return ret;
-}
-
-
-int
-main (int argc, char *const *argv)
-{
-  struct in_addr external;
-  struct in_addr target;
-  WSADATA wsaData;
-
-  unsigned int p;
-
-  if (argc != 4)
-    {
-      fprintf (stderr,
-              "This program must be started with our IP, the targets external 
IP, and our port as arguments.\n");
-      return 1;
-    }
-  if ( (1 != inet_pton (AF_INET, argv[1], &external)) ||
-       (1 != inet_pton (AF_INET, argv[2], &target)) )
-    {
-      fprintf (stderr,
-              "Error parsing IPv4 address: %s\n",
-              strerror (errno));
-      return 1;
-    }
-  if ( (1 != sscanf (argv[3], "%u", &p) ) ||
-       (0 == p) ||
-       (0xFFFF < p) )
-    {
-      fprintf (stderr,
-              "Error parsing port value `%s'\n",
-              argv[3]);
-      return 1;
-    }
-  port = (uint16_t) p;
-
-  if (0 != WSAStartup (MAKEWORD (2, 1), &wsaData))
-    {
-      fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
-      return 2;
-    }
-  if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
-    {
-      fprintf (stderr,
-              "Internal error converting dummy IP to binary.\n");
-      return 2;
-    }
-  if (-1 == (rawsock = make_raw_socket()))
-    return 3;
-  send_icmp (&external,
-            &target);
-  send_icmp_udp (&external,
-                 &target);
-  closesocket (rawsock);
-  WSACleanup ();
-  return 0;
-}
-
-/* end of gnunet-nat-client-windows.c */

Deleted: gnunet/src/transport/gnunet-nat-client.c
===================================================================
--- gnunet/src/transport/gnunet-nat-client.c    2011-06-27 17:02:59 UTC (rev 
15779)
+++ gnunet/src/transport/gnunet-nat-client.c    2011-06-27 20:22:33 UTC (rev 
15780)
@@ -1,527 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file src/transport/gnunet-nat-client.c
- * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID 
will do)
- *        This code will work under GNU/Linux only.
- * @author Christian Grothoff
- *
- * This program will send ONE ICMP message using RAW sockets
- * to the IP address specified as the second argument.  Since
- * it uses RAW sockets, it must be installed SUID or run as 'root'.
- * In order to keep the security risk of the resulting SUID binary
- * minimal, the program ONLY opens the RAW socket with root
- * privileges, then drops them and only then starts to process
- * command line arguments.  The code also does not link against
- * any shared libraries (except libc) and is strictly minimal
- * (except for checking for errors).  The following list of people
- * have reviewed this code and considered it safe since the last
- * modification (if you reviewed it, please have your name added
- * to the list):
- *
- * - Christian Grothoff
- * - Nathan Evans
- * - Benjamin Kuperman (22 Aug 2010)
- */
-#if HAVE_CONFIG_H
-/* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */
-#include "gnunet_config.h"
-#else
-#define _GNU_SOURCE
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/in.h>
-
-/**
- * Must match IP given in the server.
- */
-#define DUMMY_IP "192.0.2.86"
-
-#define NAT_TRAV_PORT 22225
-
-/**
- * IPv4 header.
- */
-struct ip_header
-{
-
-  /**
-   * Version (4 bits) + Internet header length (4 bits)
-   */
-  uint8_t vers_ihl;
-
-  /**
-   * Type of service
-   */
-  uint8_t tos;
-
-  /**
-   * Total length
-   */
-  uint16_t pkt_len;
-
-  /**
-   * Identification
-   */
-  uint16_t id;
-
-  /**
-   * Flags (3 bits) + Fragment offset (13 bits)
-   */
-  uint16_t flags_frag_offset;
-
-  /**
-   * Time to live
-   */
-  uint8_t ttl;
-
-  /**
-   * Protocol
-   */
-  uint8_t proto;
-
-  /**
-   * Header checksum
-   */
-  uint16_t checksum;
-
-  /**
-   * Source address
-   */
-  uint32_t src_ip;
-
-  /**
-   * Destination address
-   */
-  uint32_t dst_ip;
-};
-
-/**
- * Format of ICMP packet.
- */
-struct icmp_ttl_exceeded_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t unused;
-
-  /* followed by original payload */
-};
-
-struct icmp_echo_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t reserved;
-};
-
-/**
- * Beginning of UDP packet.
- */
-struct udp_header
-{
-  uint16_t src_port;
-
-  uint16_t dst_port;
-
-  uint16_t length;
-
-  uint16_t crc;
-};
-
-/**
- * Socket we use to send our fake ICMP replies.
- */
-static int rawsock;
-
-/**
- * Target "dummy" address of the packet we pretend to respond to.
- */
-static struct in_addr dummy;
-
-/**
- * Our "source" port.
- */
-static uint16_t port;
-
-
-/**
- * CRC-16 for IP/ICMP headers.
- *
- * @param data what to calculate the CRC over
- * @param bytes number of bytes in data (must be multiple of 2)
- * @return the CRC 16.
- */
-static uint16_t
-calc_checksum (const uint16_t *data,
-              unsigned int bytes)
-{
-  uint32_t sum;
-  unsigned int i;
-
-  sum = 0;
-  for (i=0;i<bytes/2;i++)
-    sum += data[i];
-  sum = (sum & 0xffff) + (sum >> 16);
-  sum = htons(0xffff - sum);
-  return sum;
-}
-
-
-/**
- * Send an ICMP message to the target.
- *
- * @param my_ip source address
- * @param other target address
- */
-static void
-send_icmp_udp (const struct in_addr *my_ip,
-               const struct in_addr *other)
-{
-  char packet[sizeof(struct ip_header) * 2 +
-             sizeof(struct icmp_ttl_exceeded_header) +
-             sizeof(struct udp_header)];
-  struct ip_header ip_pkt;
-  struct icmp_ttl_exceeded_header icmp_pkt;
-  struct udp_header udp_pkt;
-  struct sockaddr_in dst;
-  size_t off;
-  int err;
-
-  /* ip header: send to (known) ip address */
-  off = 0;
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons (sizeof (packet));
-  ip_pkt.id = htons(256);
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 128;
-  ip_pkt.proto = IPPROTO_ICMP;
-  ip_pkt.checksum = 0;
-  ip_pkt.src_ip = my_ip->s_addr;
-  ip_pkt.dst_ip = other->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));
-  off += sizeof(struct ip_header);
-
-  icmp_pkt.type = ICMP_TIME_EXCEEDED;
-  icmp_pkt.code = 0;
-  icmp_pkt.checksum = 0;
-  icmp_pkt.unused = 0;
-  memcpy(&packet[off],
-        &icmp_pkt,
-        sizeof(struct icmp_ttl_exceeded_header));
-  off += sizeof(struct icmp_ttl_exceeded_header);
-
-  /* ip header of the presumably 'lost' udp packet */
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons(sizeof (struct ip_header) +
-                        sizeof (struct udp_header));
-  ip_pkt.id = htons(0);
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 128;
-  ip_pkt.proto = IPPROTO_UDP;
-  ip_pkt.checksum = 0;
-  ip_pkt.src_ip = other->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));
-  off += sizeof(struct ip_header);
-
-  /* build UDP header */
-  udp_pkt.src_port = htons(NAT_TRAV_PORT);
-  udp_pkt.dst_port = htons(NAT_TRAV_PORT);
-  udp_pkt.length = htons (port);
-  udp_pkt.crc = 0;
-  memcpy(&packet[off],
-        &udp_pkt,
-        sizeof(struct udp_header));
-  off += sizeof(struct udp_header);
-
-  /* set ICMP checksum */
-  icmp_pkt.checksum = htons(calc_checksum((uint16_t*)&packet[sizeof(struct 
ip_header)],
-                                         sizeof (struct 
icmp_ttl_exceeded_header) +
-                                         sizeof (struct ip_header) +
-                                         sizeof (struct udp_header)));
-  memcpy (&packet[sizeof(struct ip_header)],
-         &icmp_pkt,
-         sizeof (struct icmp_ttl_exceeded_header));
-
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  dst.sin_len = sizeof (struct sockaddr_in);
-#endif
-  dst.sin_addr = *other;
-  err = sendto(rawsock,
-               packet,
-               sizeof (packet), 0,
-               (struct sockaddr*)&dst,
-               sizeof(dst));
-  if (err < 0)
-    {
-      fprintf(stderr,
-              "sendto failed: %s\n", strerror(errno));
-    }
-  else if (sizeof (packet) != (size_t) err)
-    {
-      fprintf(stderr,
-              "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * Send an ICMP message to the target.
- *
- * @param my_ip source address
- * @param other target address
- */
-static void
-send_icmp (const struct in_addr *my_ip,
-          const struct in_addr *other)
-{
-  struct ip_header ip_pkt;
-  struct icmp_ttl_exceeded_header icmp_ttl;
-  struct icmp_echo_header icmp_echo;
-  struct sockaddr_in dst;
-  char packet[sizeof (struct ip_header) * 2 +
-             sizeof (struct icmp_ttl_exceeded_header) +
-             sizeof (struct icmp_echo_header)];
-  size_t off;
-  int err;
-
-  /* ip header: send to (known) ip address */
-  off = 0;
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons (sizeof (packet));
-  ip_pkt.id = htons (256);
-  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 = other->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));
-  off = sizeof (ip_pkt);
-
-  /* icmp reply: time exceeded */
-  icmp_ttl.type = ICMP_TIME_EXCEEDED;
-  icmp_ttl.code = 0;
-  icmp_ttl.checksum = 0;
-  icmp_ttl.unused = 0;
-  memcpy (&packet[off],
-         &icmp_ttl,
-         sizeof (struct icmp_ttl_exceeded_header));
-  off += sizeof (struct icmp_ttl_exceeded_header);
-
-  /* ip header of the presumably 'lost' udp packet */
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons (sizeof (struct ip_header) + sizeof (struct 
icmp_echo_header));
-  ip_pkt.id = htons (256);
-  ip_pkt.flags_frag_offset = 0;
-  ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */
-  ip_pkt.proto = IPPROTO_ICMP;
-  ip_pkt.src_ip = other->s_addr;
-  ip_pkt.dst_ip = dummy.s_addr;
-  ip_pkt.checksum = 0;
-  ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
-                                       sizeof (struct ip_header)));
-  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 = htonl (port);
-  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));
-
-  /* no go back to calculate ICMP packet checksum */
-  off = sizeof (struct ip_header);
-  icmp_ttl.checksum = htons(calc_checksum((uint16_t*) &packet[off],
-                                         sizeof (struct 
icmp_ttl_exceeded_header) +
-                                         sizeof (struct ip_header) +
-                                         sizeof (struct icmp_echo_header)));
-  memcpy (&packet[off],
-         &icmp_ttl,
-         sizeof (struct icmp_ttl_exceeded_header));
-
-  /* prepare for transmission */
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  dst.sin_len = sizeof (struct sockaddr_in);
-#endif
-  dst.sin_addr = *other;
-  err = sendto(rawsock,
-              packet,
-              sizeof (packet), 0,
-              (struct sockaddr*)&dst,
-              sizeof(dst));
-  if (err < 0)
-    {
-      fprintf(stderr,
-             "sendto failed: %s\n", strerror(errno));
-    }
-  else if (sizeof (packet) != (size_t) err)
-    {
-      fprintf(stderr,
-             "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * Create an ICMP raw socket for writing.
- *
- * @return -1 on error
- */
-static int
-make_raw_socket ()
-{
-  const int one = 1;
-  int ret;
-
-  ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
-  if (-1 == ret)
-    {
-      fprintf (stderr,
-              "Error opening RAW socket: %s\n",
-              strerror (errno));
-      return -1;
-    }
-  if (0 != setsockopt(ret, SOL_SOCKET, SO_BROADCAST,
-                     (char *)&one, sizeof(one)))
-    {
-      fprintf(stderr,
-             "setsockopt failed: %s\n",
-             strerror (errno));
-      close (ret);
-      return -1;
-    }
-  if (0 != setsockopt(ret, IPPROTO_IP, IP_HDRINCL,
-                     (char *)&one, sizeof(one)))
-    {
-      fprintf(stderr,
-             "setsockopt failed: %s\n",
-             strerror (errno));
-      close (ret);
-      return -1;
-    }
-  return ret;
-}
-
-
-int
-main (int argc, char *const *argv)
-{
-  struct in_addr external;
-  struct in_addr target;
-  uid_t uid;
-  unsigned int p;
-
-  if (4 != argc)
-    {
-      fprintf (stderr,
-              "This program must be started with our IP, the targets external 
IP, and our port as arguments.\n");
-      return 1;
-    }
-  if ( (1 != inet_pton (AF_INET, argv[1], &external)) ||
-       (1 != inet_pton (AF_INET, argv[2], &target)) )
-    {
-      fprintf (stderr,
-              "Error parsing IPv4 address: %s\n",
-              strerror (errno));
-      return 1;
-    }
-  if ( (1 != sscanf (argv[3], "%u", &p) ) ||
-       (0 == p) ||
-       (0xFFFF < p) )
-    {
-      fprintf (stderr,
-              "Error parsing port value `%s'\n",
-              argv[3]);
-      return 1;
-    }
-  port = (uint16_t) p;
-  if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
-    {
-      fprintf (stderr,
-              "Internal error converting dummy IP to binary.\n");
-      return 2;
-    }
-  if (-1 == (rawsock = make_raw_socket()))
-    return 2;
-  uid = getuid ();
-  if (0 != setresuid (uid, uid, uid))
-    {
-      fprintf (stderr,
-              "Failed to setresuid: %s\n",
-              strerror (errno));
-      /* not critical, continue anyway */
-    }
-  send_icmp (&external,
-            &target);
-  send_icmp_udp (&external,
-                &target);
-  close (rawsock);
-  return 0;
-}
-
-/* end of gnunet-nat-client.c */

Deleted: gnunet/src/transport/gnunet-nat-server-script.sh
===================================================================
--- gnunet/src/transport/gnunet-nat-server-script.sh    2011-06-27 17:02:59 UTC 
(rev 15779)
+++ gnunet/src/transport/gnunet-nat-server-script.sh    2011-06-27 20:22:33 UTC 
(rev 15780)
@@ -1,4 +0,0 @@
-#!/bin/sh
-IP=`ifconfig | grep inet | head -n1 | awk '{print $2}' | sed -e "s/addr://"`
-echo "Using IP $IP"
-./gnunet-nat-server $IP | sed -u -e "s/.*/.\/gnunet-nat-server-udp $IP &\&/" | 
sh

Deleted: gnunet/src/transport/gnunet-nat-server-windows.c
===================================================================
--- gnunet/src/transport/gnunet-nat-server-windows.c    2011-06-27 17:02:59 UTC 
(rev 15779)
+++ gnunet/src/transport/gnunet-nat-server-windows.c    2011-06-27 20:22:33 UTC 
(rev 15780)
@@ -1,653 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file src/transport/gnunet-nat-server-windows.c
- * @brief Windows tool to help bypass NATs using ICMP method
- *        This code will work under W32 only
- * @author Christian Grothoff
- *
- * This program will send ONE ICMP message every 500 ms RAW sockets
- * to a DUMMY IP address and also listens for ICMP replies.  Since
- * it uses RAW sockets, it must be run as an administrative user.
- * In order to keep the security risk of the resulting binary
- * minimal, the program ONLY opens the two RAW sockets with administrative
- * privileges, then drops them and only then starts to process
- * command line arguments.  The code also does not link against
- * any shared libraries (except libc) and is strictly minimal
- * (except for checking for errors).  The following list of people
- * have reviewed this code and considered it safe since the last
- * modification (if you reviewed it, please have your name added
- * to the list):
- *
- * - Nathan Evans
- * - Christian Grothoff
- */
-#define _GNU_SOURCE
-
-
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <time.h>
-
-/**
- * Should we print some debug output?
- */
-#define VERBOSE 0
-
-/**
- * Must match IP given in the client.
- */
-#define DUMMY_IP "192.0.2.86"
-
-/**
- * Default Port
- */
-#define NAT_TRAV_PORT 22225
-
-/**
- * TTL to use for our outgoing messages.
- */
-#define IPDEFTTL 64
-
-#define ICMP_ECHO 8
-
-#define ICMP_TIME_EXCEEDED 11
-
-/**
- * How often do we send our ICMP messages to receive replies?
- */
-#define ICMP_SEND_FREQUENCY_MS 500
-
-/**
- * IPv4 header.
- */
-struct ip_header
-{
-
-  /**
-   * Version (4 bits) + Internet header length (4 bits)
-   */
-  uint8_t vers_ihl;
-
-  /**
-   * Type of service
-   */
-  uint8_t tos;
-
-  /**
-   * Total length
-   */
-  uint16_t pkt_len;
-
-  /**
-   * Identification
-   */
-  uint16_t id;
-
-  /**
-   * Flags (3 bits) + Fragment offset (13 bits)
-   */
-  uint16_t flags_frag_offset;
-
-  /**
-   * Time to live
-   */
-  uint8_t  ttl;
-
-  /**
-   * Protocol
-   */
-  uint8_t  proto;
-
-  /**
-   * Header checksum
-   */
-  uint16_t checksum;
-
-  /**
-   * Source address
-   */
-  uint32_t  src_ip;
-
-  /**
-   * Destination address
-   */
-  uint32_t  dst_ip;
-};
-
-/**
- * Format of ICMP packet.
- */
-struct icmp_ttl_exceeded_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t unused;
-
-  /* followed by original payload */
-};
-
-struct icmp_echo_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t reserved;
-};
-
-/**
- * Beginning of UDP packet.
- */
-struct udp_header
-{
-  uint16_t src_port;
-
-  uint16_t dst_port;
-
-  uint16_t length;
-
-  uint16_t crc;
-};
-
-/**
- * Socket we use to receive "fake" ICMP replies.
- */
-static SOCKET icmpsock;
-
-/**
- * Socket we use to send our ICMP requests.
- */
-static SOCKET rawsock;
-
-/**
- * Socket we use to send our UDP requests.
- */
-static SOCKET udpsock;
-
-/**
- * Target "dummy" address.
- */
-static struct in_addr dummy;
-
-
-/**
- * CRC-16 for IP/ICMP headers.
- *
- * @param data what to calculate the CRC over
- * @param bytes number of bytes in data (must be multiple of 2)
- * @return the CRC 16.
- */
-static uint16_t
-calc_checksum(const uint16_t *data,
-             unsigned int bytes)
-{
-  uint32_t sum;
-  unsigned int i;
-
-  sum = 0;
-  for (i=0;i<bytes/2;i++)
-    sum += data[i];
-  sum = (sum & 0xffff) + (sum >> 16);
-  sum = htons(0xffff - sum);
-  return sum;
-}
-
-
-/**
- * Convert IPv4 address from text to binary form.
- *
- * @param af address family
- * @param cp the address to print
- * @param buf where to write the address result
- * @return 1 on success
- */
-static int
-inet_pton (int af,
-          const char *cp,
-          struct in_addr *buf)
-{
-  buf->s_addr = inet_addr(cp);
-  if (buf->s_addr == INADDR_NONE)
-    {
-      fprintf(stderr,
-             "Error %d handling address %s",
-             WSAGetLastError(),
-             cp);
-      return 0;
-    }
-  return 1;
-}
-
-
-/**
- * Send an ICMP message to the dummy IP.
- *
- * @param my_ip source address (our ip address)
- */
-static void
-send_icmp_echo (const struct in_addr *my_ip)
-{
-  char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)];
-  struct icmp_echo_header icmp_echo;
-  struct ip_header ip_pkt;
-  struct sockaddr_in dst;
-  size_t off;
-  int err;
-
-  off = 0;
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons (sizeof (packet));
-  ip_pkt.id = htons (256);
-  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));
-  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));
-  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));
-  if (err < 0)
-    {
-#if VERBOSE
-      fprintf(stderr,
-             "sendto failed: %s\n", strerror(errno));
-#endif
-    }
-  else if (err != off)
-    {
-      fprintf(stderr,
-             "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * Send a UDP message to the dummy IP.
- */
-static void
-send_udp ()
-{
-  struct sockaddr_in dst;
-  ssize_t err;
-
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-  dst.sin_addr = dummy;
-  dst.sin_port = htons (NAT_TRAV_PORT);
-  err = sendto(udpsock,
-              NULL, 0, 0,
-              (struct sockaddr*)&dst,
-              sizeof(dst));
-  if (err < 0)
-    {
-#if VERBOSE
-      fprintf(stderr,
-             "sendto failed: %s\n", strerror(errno));
-#endif
-    }
-  else if (0 != err)
-    {
-      fprintf(stderr,
-             "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * We've received an ICMP response.  Process it.
- */
-static void
-process_icmp_response ()
-{
-  char buf[65536];
-  ssize_t have;
-  struct in_addr source_ip;
-  struct ip_header ip_pkt;
-  struct icmp_ttl_exceeded_header icmp_ttl;
-  struct icmp_echo_header icmp_echo;
-  struct udp_header udp_pkt;
-  size_t off;
-  uint16_t port;
-  DWORD ssize;
-
-  have = read (icmpsock, buf, sizeof (buf));
-  if (have == -1)
-    {
-      fprintf (stderr,
-              "Error reading raw socket: %s\n",
-              strerror (errno));
-      return;
-    }
-#if VERBOSE
-  fprintf (stderr,
-           "Received message of %u bytes\n",
-           (unsigned int) have);
-#endif
-  if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct 
icmp_ttl_exceeded_header) + sizeof (struct ip_header)))
-    {
-      /* malformed */
-      return;
-    }
-  off = 0;
-  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));
-  off += sizeof (struct icmp_ttl_exceeded_header);
-  if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) ||
-       (0 != icmp_ttl.code) )
-    {
-      /* different type than what we want */
-      return;
-    }
-  /* skip 2nd IP header */
-  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)) )
-       {
-         /* malformed */
-         return;
-       }
-      /* grab ICMP ECHO content */
-      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)) )
-       {
-         /* malformed */
-         return;
-       }
-      /* grab UDP content */
-      memcpy (&udp_pkt,
-             &buf[off],
-             sizeof (struct udp_header));
-      port = ntohs (udp_pkt.length);
-      break;
-    default:
-      /* different type than what we want */
-      return;
-    }
-
-  ssize = sizeof(buf);
-  WSAAddressToString((LPSOCKADDR)&source_ip,
-                    sizeof(source_ip),
-                    NULL,
-                    buf,
-                    &ssize);
-  if (port == 0)
-    fprintf (stdout,
-            "%s\n",
-            buf);
-  else
-    fprintf (stdout,
-            "%s:%u\n",
-            buf,
-            (unsigned int) port);
-  fflush (stdout);
-}
-
-
-/**
- * Create an ICMP raw socket for reading.
- *
- * @return INVALID_SOCKET on error
- */
-static SOCKET
-make_icmp_socket ()
-{
-  SOCKET ret;
-
-  ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
-  if (INVALID_SOCKET == ret)
-    {
-      fprintf (stderr,
-              "Error opening RAW socket: %s\n",
-              strerror (errno));
-      return INVALID_SOCKET;
-    }
-  return ret;
-}
-
-
-/**
- * Create an ICMP raw socket for writing.
- *
- * @return INVALID_SOCKET on error
- */
-static SOCKET
-make_raw_socket ()
-{
-  DWORD bOptVal = TRUE;
-  int bOptLen = sizeof(bOptVal);
-
-  rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
-  if (INVALID_SOCKET == rawsock)
-    {
-      fprintf (stderr,
-              "Error opening RAW socket: %s\n",
-              strerror (errno));
-      return INVALID_SOCKET;
-    }
-
-  if (0 != setsockopt(rawsock,
-                     SOL_SOCKET,
-                     SO_BROADCAST,
-                     (char*)&bOptVal, bOptLen))
-    {
-      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))
-    {
-      fprintf(stderr,
-             "Error setting IP_HDRINCL to ON: %s\n",
-             strerror (errno));
-      closesocket(rawsock);
-      return INVALID_SOCKET;
-    }
-  return rawsock;
-}
-
-
-/**
- * Create a UDP socket for writing.
- *
- * @param my_ip source address (our ip address)
- * @return INVALID_SOCKET on error
- */
-static SOCKET
-make_udp_socket (const struct in_addr *my_ip)
-{
-  SOCKET ret;
-  struct sockaddr_in addr;
-
-  ret = socket (AF_INET, SOCK_DGRAM, 0);
-  if (INVALID_SOCKET == ret)
-    {
-      fprintf (stderr,
-              "Error opening UDP socket: %s\n",
-              strerror (errno));
-      return INVALID_SOCKET;
-    }
-  memset (&addr, 0, sizeof (addr));
-  addr.sin_family = AF_INET;
-  addr.sin_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));
-      /* likely problematic, but not certain, try to continue */
-    }
-  return ret;
-}
-
-
-int
-main (int argc,
-      char *const *argv)
-{
-  struct in_addr external;
-  fd_set rs;
-  struct timeval tv;
-  WSADATA wsaData;
-  unsigned int alt;
-
-  alt = 0;
-  if (2 != argc)
-    {
-      fprintf (stderr,
-              "This program must be started with our (internal NAT) IP as the 
only argument.\n");
-      return 1;
-    }
-  if (1 != inet_pton (AF_INET, argv[1], &external))
-    {
-      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))
-    {
-      fprintf (stderr,
-              "Internal error converting dummy IP to binary.\n");
-      return 2;
-    }
-  if (WSAStartup (MAKEWORD (2, 1), &wsaData) != 0)
-    {
-      fprintf (stderr, "Failed to find Winsock 2.1 or better.\n");
-      return 2;
-    }
-  if (INVALID_SOCKET == (icmpsock = make_icmp_socket()))
-    {
-      return 3;
-    }
-  if (INVALID_SOCKET == (make_raw_socket()))
-    {
-      closesocket (icmpsock);
-      return 3;
-    }
-  if (INVALID_SOCKET == (udpsock = make_udp_socket(&external)))
-    {
-      closesocket (icmpsock);
-      closesocket (rawsock);
-      return 3;
-    }
-  while (1)
-    {
-      FD_ZERO (&rs);
-      FD_SET (icmpsock, &rs);
-      tv.tv_sec = 0;
-      tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
-      if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
-       {
-         if (errno == EINTR)
-           continue;
-         fprintf (stderr,
-                  "select failed: %s\n",
-                  strerror (errno));
-         break;
-       }
-      if (FD_ISSET (icmpsock, &rs))
-        process_icmp_response ();
-      if (0 == (++alt % 2))
-       send_icmp_echo (&external);
-      else
-       send_udp ();
-    }
-  /* select failed (internal error or OS out of resources) */
-  closesocket(icmpsock);
-  closesocket(rawsock);
-  closesocket(udpsock);
-  WSACleanup ();
-  return 4;
-}
-
-
-/* end of gnunet-nat-server-windows.c */

Deleted: gnunet/src/transport/gnunet-nat-server.c
===================================================================
--- gnunet/src/transport/gnunet-nat-server.c    2011-06-27 17:02:59 UTC (rev 
15779)
+++ gnunet/src/transport/gnunet-nat-server.c    2011-06-27 20:22:33 UTC (rev 
15780)
@@ -1,651 +0,0 @@
-/*
-     This file is part of GNUnet.
-     (C) 2010 Christian Grothoff (and other contributing authors)
-
-     GNUnet is free software; you can redistribute it and/or modify
-     it under the terms of the GNU General Public License as published
-     by the Free Software Foundation; either version 3, or (at your
-     option) any later version.
-
-     GNUnet is distributed in the hope that it will be useful, but
-     WITHOUT ANY WARRANTY; without even the implied warranty of
-     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-     General Public License for more details.
-
-     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.
-*/
-
-/**
- * @file src/transport/gnunet-nat-server.c
- * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID 
will do)
- *        This code will work under GNU/Linux only (or maybe BSDs, but never 
W32)
- * @author Christian Grothoff
- *
- * This program will send ONE ICMP message every 500 ms RAW sockets
- * to a DUMMY IP address and also listens for ICMP replies.  Since
- * it uses RAW sockets, it must be installed SUID or run as 'root'.
- * In order to keep the security risk of the resulting SUID binary
- * minimal, the program ONLY opens the two RAW sockets with root
- * privileges, then drops them and only then starts to process
- * command line arguments.  The code also does not link against
- * any shared libraries (except libc) and is strictly minimal
- * (except for checking for errors).  The following list of people
- * have reviewed this code and considered it safe since the last
- * modification (if you reviewed it, please have your name added
- * to the list):
- *
- * - Christian Grothoff
- * - Nathan Evans
- * - Benjamin Kuperman (22 Aug 2010)
- */
-#if HAVE_CONFIG_H
-/* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */
-#include "gnunet_config.h"
-#else
-#define _GNU_SOURCE
-#endif
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <sys/select.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <time.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/in.h>
-
-/**
- * Should we print some debug output?
- */
-#define VERBOSE 0
-
-/**
- * Must match IP given in the client.
- */
-#define DUMMY_IP "192.0.2.86"
-
-/**
- * Port for UDP
- */
-#define NAT_TRAV_PORT 22225
-
-/**
- * How often do we send our ICMP messages to receive replies?
- */
-#define ICMP_SEND_FREQUENCY_MS 500
-
-/**
- * IPv4 header.
- */
-struct ip_header
-{
-
-  /**
-   * Version (4 bits) + Internet header length (4 bits)
-   */
-  uint8_t vers_ihl;
-
-  /**
-   * Type of service
-   */
-  uint8_t tos;
-
-  /**
-   * Total length
-   */
-  uint16_t pkt_len;
-
-  /**
-   * Identification
-   */
-  uint16_t id;
-
-  /**
-   * Flags (3 bits) + Fragment offset (13 bits)
-   */
-  uint16_t flags_frag_offset;
-
-  /**
-   * Time to live
-   */
-  uint8_t ttl;
-
-  /**
-   * Protocol
-   */
-  uint8_t proto;
-
-  /**
-   * Header checksum
-   */
-  uint16_t checksum;
-
-  /**
-   * Source address
-   */
-  uint32_t src_ip;
-
-  /**
-   * Destination address
-   */
-  uint32_t dst_ip;
-};
-
-/**
- * Format of ICMP packet.
- */
-struct icmp_ttl_exceeded_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t unused;
-
-  /* followed by original payload */
-};
-
-struct icmp_echo_header
-{
-  uint8_t type;
-
-  uint8_t code;
-
-  uint16_t checksum;
-
-  uint32_t reserved;
-};
-
-
-/**
- * Beginning of UDP packet.
- */
-struct udp_header
-{
-  uint16_t src_port;
-
-  uint16_t dst_port;
-
-  uint16_t length;
-
-  uint16_t crc;
-};
-
-/**
- * Socket we use to receive "fake" ICMP replies.
- */
-static int icmpsock;
-
-/**
- * Socket we use to send our ICMP requests.
- */
-static int rawsock;
-
-/**
- * Socket we use to send our UDP requests.
- */
-static int udpsock;
-
-/**
- * Target "dummy" address.
- */
-static struct in_addr dummy;
-
-
-/**
- * CRC-16 for IP/ICMP headers.
- *
- * @param data what to calculate the CRC over
- * @param bytes number of bytes in data (must be multiple of 2)
- * @return the CRC 16.
- */
-static uint16_t
-calc_checksum(const uint16_t *data,
-             unsigned int bytes)
-{
-  uint32_t sum;
-  unsigned int i;
-
-  sum = 0;
-  for (i=0;i<bytes/2;i++)
-    sum += data[i];
-  sum = (sum & 0xffff) + (sum >> 16);
-  sum = htons(0xffff - sum);
-  return sum;
-}
-
-
-/**
- * Send an ICMP message to the dummy IP.
- *
- * @param my_ip source address (our ip address)
- */
-static void
-send_icmp_echo (const struct in_addr *my_ip)
-{
-  char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)];
-  struct icmp_echo_header icmp_echo;
-  struct ip_header ip_pkt;
-  struct sockaddr_in dst;
-  size_t off;
-  int err;
-
-  off = 0;
-  ip_pkt.vers_ihl = 0x45;
-  ip_pkt.tos = 0;
-  ip_pkt.pkt_len = htons (sizeof (packet));
-  ip_pkt.id = htons (256);
-  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));
-  off += sizeof (struct ip_header);
-
-  icmp_echo.type = ICMP_ECHO;
-  icmp_echo.code = 0;
-  icmp_echo.checksum = 0;
-  icmp_echo.reserved = 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));
-  off += sizeof (struct icmp_echo_header);
-
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  dst.sin_len = sizeof (struct sockaddr_in);
-#endif
-  dst.sin_addr = dummy;
-  err = sendto(rawsock,
-              packet, off, 0,
-              (struct sockaddr*)&dst,
-              sizeof(dst));
-  if (err < 0)
-    {
-#if VERBOSE
-      fprintf(stderr,
-             "sendto failed: %s\n", strerror(errno));
-#endif
-    }
-  else if (sizeof (packet) != err)
-    {
-      fprintf(stderr,
-             "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * Send a UDP message to the dummy IP.
- */
-static void
-send_udp ()
-{
-  struct sockaddr_in dst;
-  ssize_t err;
-
-  memset (&dst, 0, sizeof (dst));
-  dst.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  dst.sin_len = sizeof (struct sockaddr_in);
-#endif
-  dst.sin_addr = dummy;
-  dst.sin_port = htons (NAT_TRAV_PORT);
-  err = sendto(udpsock,
-              NULL, 0, 0,
-              (struct sockaddr*)&dst,
-              sizeof(dst));
-  if (err < 0)
-    {
-#if VERBOSE
-      fprintf(stderr,
-             "sendto failed: %s\n", strerror(errno));
-#endif
-    }
-  else if (0 != err)
-    {
-      fprintf(stderr,
-             "Error: partial send of ICMP message\n");
-    }
-}
-
-
-/**
- * We've received an ICMP response.  Process it.
- */
-static void
-process_icmp_response ()
-{
-  char buf[65536];
-  ssize_t have;
-  struct in_addr source_ip;
-  struct ip_header ip_pkt;
-  struct icmp_ttl_exceeded_header icmp_ttl;
-  struct icmp_echo_header icmp_echo;
-  struct udp_header udp_pkt;
-  size_t off;
-  uint16_t port;
-
-  have = read (icmpsock, buf, sizeof (buf));
-  if (-1 == have)
-    {
-      fprintf (stderr,
-              "Error reading raw socket: %s\n",
-              strerror (errno));
-      return;
-    }
-#if VERBOSE
-  fprintf (stderr,
-           "Received message of %u bytes\n",
-           (unsigned int) have);
-#endif
-  if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct 
icmp_ttl_exceeded_header) + sizeof (struct ip_header)))
-    {
-      /* malformed */
-      return;
-    }
-  off = 0;
-  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));
-  off += sizeof (struct icmp_ttl_exceeded_header);
-  if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) ||
-       (0 != icmp_ttl.code) )
-    {
-      /* different type than what we want */
-      return;
-    }
-  /* skip 2nd IP header */
-  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)) )
-       {
-         /* malformed */
-         return;
-       }
-      /* grab ICMP ECHO content */
-      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)) )
-       {
-         /* malformed */
-         return;
-       }
-      /* grab UDP content */
-      memcpy (&udp_pkt,
-             &buf[off],
-             sizeof (struct udp_header));
-      port = ntohs (udp_pkt.length);
-      break;
-    default:
-      /* different type than what we want */
-      return;
-    }
-
-  if (port == 0)
-    fprintf (stdout,
-            "%s\n",
-            inet_ntop (AF_INET,
-                       &source_ip,
-                       buf,
-                       sizeof (buf)));
-  else
-    fprintf (stdout,
-            "%s:%u\n",
-            inet_ntop (AF_INET,
-                       &source_ip,
-                       buf,
-                       sizeof (buf)),
-            (unsigned int) port);
-  fflush (stdout);
-}
-
-
-/**
- * Create an ICMP raw socket for reading.
- *
- * @return -1 on error
- */
-static int
-make_icmp_socket ()
-{
-  int ret;
-
-  ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
-  if (-1 == ret)
-    {
-      fprintf (stderr,
-              "Error opening RAW socket: %s\n",
-              strerror (errno));
-      return -1;
-    }
-  if (ret >= FD_SETSIZE)
-    {
-      fprintf (stderr,
-              "Socket number too large (%d > %u)\n",
-              ret,
-              (unsigned int) FD_SETSIZE);
-      close (ret);
-      return -1;
-    }
-  return ret;
-}
-
-
-/**
- * Create an ICMP raw socket for writing.
- *
- * @return -1 on error
- */
-static int
-make_raw_socket ()
-{
-  const int one = 1;
-  int ret;
-
-  ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
-  if (-1 == ret)
-    {
-      fprintf (stderr,
-              "Error opening RAW socket: %s\n",
-              strerror (errno));
-      return -1;
-    }
-  if (-1 == setsockopt(ret,
-                      SOL_SOCKET,
-                      SO_BROADCAST,
-                      (char *)&one, sizeof(one)))
-    {
-      fprintf(stderr,
-             "setsockopt failed: %s\n",
-             strerror (errno));
-      close (ret);
-      return -1;
-    }
-  if (-1 == setsockopt(ret,
-                      IPPROTO_IP,
-                      IP_HDRINCL,
-                      (char *)&one, sizeof(one)))
-    {
-      fprintf(stderr,
-             "setsockopt failed: %s\n",
-             strerror (errno));
-      close (ret);
-      return -1;
-    }
-  return ret;
-}
-
-
-/**
- * Create a UDP socket for writinging.
- *
- * @param my_ip source address (our ip address)
- * @return -1 on error
- */
-static int
-make_udp_socket (const struct in_addr *my_ip)
-{
-  int ret;
-  struct sockaddr_in addr;
-
-  ret = socket (AF_INET, SOCK_DGRAM, 0);
-  if (-1 == ret)
-    {
-      fprintf (stderr,
-              "Error opening UDP socket: %s\n",
-              strerror (errno));
-      return -1;
-    }
-  memset (&addr,
-         0,
-         sizeof (addr));
-  addr.sin_family = AF_INET;
-#if HAVE_SOCKADDR_IN_SIN_LEN
-  addr.sin_len = sizeof (struct sockaddr_in);
-#endif
-  addr.sin_addr = *my_ip;
-  addr.sin_port = htons (NAT_TRAV_PORT);
-
-  if (0 != bind (ret,
-                &addr,
-                sizeof(addr)))
-    {
-      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;
-}
-
-
-int
-main (int argc,
-      char *const *argv)
-{
-  struct in_addr external;
-  fd_set rs;
-  struct timeval tv;
-  uid_t uid;
-  unsigned int alt;
-
-  if (2 != argc)
-    {
-      fprintf (stderr,
-              "This program must be started with our (internal NAT) IP as the 
only argument.\n");
-      return 1;
-    }
-  if (1 != inet_pton (AF_INET, argv[1], &external))
-    {
-      fprintf (stderr,
-              "Error parsing IPv4 address: %s\n",
-              strerror (errno));
-      return 1;
-    }
-  if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
-    {
-      fprintf (stderr,
-              "Internal error converting dummy IP to binary.\n");
-      return 2;
-    }
-  if (-1 == (icmpsock = make_icmp_socket()))
-    {
-      return 3;
-    }
-  if (-1 == (rawsock = make_raw_socket()))
-    {
-      close (icmpsock);
-      return 3;
-    }
-  uid = getuid ();
-  if (0 != setresuid (uid, uid, uid))
-    {
-      fprintf (stderr,
-              "Failed to setresuid: %s\n",
-              strerror (errno));
-      /* not critical, continue anyway */
-    }
-  if (-1 == (udpsock = make_udp_socket(&external)))
-    {
-      close (icmpsock);
-      close (rawsock);
-      return 3;
-    }
-  alt = 0;
-  while (1)
-    {
-      FD_ZERO (&rs);
-      FD_SET (icmpsock, &rs);
-      tv.tv_sec = 0;
-      tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
-      if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
-       {
-         if (errno == EINTR)
-           continue;
-         fprintf (stderr,
-                  "select failed: %s\n",
-                  strerror (errno));
-         break;
-       }
-      if (1 == getppid()) /* Check the parent process id, if 1 the parent has 
died, so we should die too */
-        break;
-      if (FD_ISSET (icmpsock, &rs))
-        process_icmp_response ();
-      if (0 == (++alt % 2))
-       send_icmp_echo (&external);
-      else
-       send_udp ();
-    }
-  /* select failed (internal error or OS out of resources) */
-  close (icmpsock);
-  close (rawsock);
-  close (udpsock);
-  return 4;
-}
-
-
-/* end of gnunet-nat-server.c */




reply via email to

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