47#include "gnunet_private_config.h"
52#include <sys/socket.h>
61#include <netinet/ip.h>
62#include <netinet/ip_icmp.h>
63#include <netinet/in.h>
66#ifndef ICMP_TIME_EXCEEDED
67#define ICMP_TIME_EXCEEDED 11
79#define GNUNET_memcpy(dst, src, n) do { if (0 != n) { (void) memcpy (dst, src, \
86#define DUMMY_IP "192.0.2.86"
88#define NAT_TRAV_PORT 22225
222 for (i = 0; i < bytes / 2; i++)
225 sum = htons (0xffff -
sum);
245 struct sockaddr_in dst;
254#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__)
255 ip_pkt.
pkt_len =
sizeof(packet);
257 ip_pkt.
pkt_len = htons (
sizeof(packet));
262 ip_pkt.
proto = IPPROTO_ICMP;
264 ip_pkt.
src_ip = my_ip->s_addr;
265 ip_pkt.
dst_ip = other->s_addr;
287 ip_pkt.
id = htons (0);
290 ip_pkt.
proto = IPPROTO_UDP;
292 ip_pkt.
src_ip = other->s_addr;
314 ((uint16_t *) &packet[
sizeof(
struct ip_header)],
321 memset (&dst, 0,
sizeof(dst));
322 dst.sin_family = AF_INET;
323#if HAVE_SOCKADDR_IN_SIN_LEN
324 dst.sin_len =
sizeof(
struct sockaddr_in);
326 dst.sin_addr = *other;
328 sendto (
rawsock, packet,
sizeof(packet), 0, (
struct sockaddr *) &dst,
332 fprintf (stderr,
"sendto failed: %s\n", strerror (errno));
334 else if (
sizeof(packet) != (
size_t) err)
336 fprintf (stderr,
"Error: partial send of ICMP message with size %lu\n",
337 (
unsigned long) off);
349send_icmp (
const struct in_addr *my_ip,
const struct in_addr *other)
354 struct sockaddr_in dst;
365#if defined(BSD) && defined(__FreeBSD__) && defined(__FreeBSD_kernel__)
366 ip_pkt.
pkt_len =
sizeof(packet);
368 ip_pkt.
pkt_len = htons (
sizeof(packet));
372 ip_pkt.
ttl = IPDEFTTL;
373 ip_pkt.
proto = IPPROTO_ICMP;
375 ip_pkt.
src_ip = my_ip->s_addr;
376 ip_pkt.
dst_ip = other->s_addr;
382 off =
sizeof(ip_pkt);
402 ip_pkt.
proto = IPPROTO_ICMP;
403 ip_pkt.
src_ip = other->s_addr;
413 icmp_echo.
type = ICMP_ECHO;
428 ((uint16_t *) &packet[off],
436 memset (&dst, 0,
sizeof(dst));
437 dst.sin_family = AF_INET;
438#if HAVE_SOCKADDR_IN_SIN_LEN
439 dst.sin_len =
sizeof(
struct sockaddr_in);
441 dst.sin_addr = *other;
443 sendto (
rawsock, packet,
sizeof(packet), 0, (
struct sockaddr *) &dst,
447 fprintf (stderr,
"sendto failed: %s\n", strerror (errno));
449 else if (
sizeof(packet) != (
size_t) err)
451 fprintf (stderr,
"Error: partial send of ICMP message\n");
457main (
int argc,
char *
const *argv)
460 struct in_addr external;
461 struct in_addr target;
468 rawsock = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
474 if (0 != setresuid (uid, uid, uid))
476 fprintf (stderr,
"Failed to setresuid: %s\n", strerror (errno));
481 if (0 != (setuid (uid) | seteuid (uid)))
483 fprintf (stderr,
"Failed to setuid: %s\n", strerror (errno));
490 fprintf (stderr,
"Error opening RAW socket: %s\n", strerror (raw_eno));
495 setsockopt (
rawsock, SOL_SOCKET, SO_BROADCAST, (
char *) &one,
498 fprintf (stderr,
"setsockopt failed: %s\n", strerror (errno));
503 setsockopt (
rawsock, IPPROTO_IP, IP_HDRINCL, (
char *) &one,
sizeof(one)))
505 fprintf (stderr,
"setsockopt failed: %s\n", strerror (errno));
513 "This program must be started with our IP, the targets external IP, and our port as arguments.\n");
517 if ((1 != inet_pton (AF_INET, argv[1], &external)) ||
518 (1 != inet_pton (AF_INET, argv[2], &target)))
520 fprintf (stderr,
"Error parsing IPv4 address: %s\n", strerror (errno));
524 if ((1 != sscanf (argv[3],
"%u", &
p)) || (0 ==
p) || (0xFFFF <
p))
526 fprintf (stderr,
"Error parsing port value `%s'\n", argv[3]);
533 fprintf (stderr,
"Internal error converting dummy IP to binary.\n");
static int global_ret
Global status value.
static char * data
The data to insert into the dht.
static void cleanup(void *cls)
Disconnect and shutdown.
static void send_icmp_udp(const struct in_addr *my_ip, const struct in_addr *other)
Send an ICMP message to the target.
#define ICMP_TIME_EXCEEDED
static uint16_t calc_checksum(const uint16_t *data, unsigned int bytes)
CRC-16 for IP/ICMP headers.
#define DUMMY_IP
Must match IP given in the server.
static uint16_t port
Our "source" port.
static int rawsock
Socket we use to send our fake ICMP replies.
static struct in_addr dummy
Target "dummy" address of the packet we pretend to respond to.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
int main(int argc, char *const *argv)
static void send_icmp(const struct in_addr *my_ip, const struct in_addr *other)
Send an ICMP message to the target.
#define PACKET_ID
Must match packet ID used by gnunet-helper-nat-server.c.
static struct GNUNET_OS_Process * p
Helper process we started.