From 4916b12e5eeb04b5719dae2815f411243fe4c0e6 Mon Sep 17 00:00:00 2001 From: "Nathan S. Evans" Date: Tue, 23 Feb 2010 15:50:17 +0000 Subject: [PATCH] add support for sending port along as icmp payload. needs tested on NAT boxes to see if it really works --- src/transport/gnunet-nat-client.c | 84 +++++++++++++++++++++++++++++-- src/transport/gnunet-nat-server.c | 37 +++++++++++--- 2 files changed, 108 insertions(+), 13 deletions(-) diff --git a/src/transport/gnunet-nat-client.c b/src/transport/gnunet-nat-client.c index b9c61a143..cbfc0a28c 100644 --- a/src/transport/gnunet-nat-client.c +++ b/src/transport/gnunet-nat-client.c @@ -58,6 +58,7 @@ * Must match IP given in the server. */ #define DUMMY_IP "1.2.3.4" +#define HAVE_PORT 1 struct ip_packet { @@ -79,7 +80,18 @@ struct icmp_packet uint8_t code; uint16_t checksum; uint32_t reserved; + }; + +struct icmp_echo_packet +{ + uint8_t type; + uint8_t code; + uint16_t checksum; + uint32_t reserved; + uint32_t data; +}; + static int rawsock; @@ -87,6 +99,9 @@ static struct in_addr dummy; static struct in_addr target; +#if HAVE_PORT + static uint32_t port; +#endif static uint16_t calc_checksum(const uint16_t *data, @@ -104,18 +119,36 @@ calc_checksum(const uint16_t *data, } + +#if HAVE_PORT + static void make_echo (const struct in_addr *src_ip, - struct icmp_packet *echo) + struct icmp_echo_packet *echo, uint32_t num) { - memset(echo, 0, sizeof(struct icmp_packet)); + memset(echo, 0, sizeof(struct icmp_echo_packet)); echo->type = ICMP_ECHO; echo->code = 0; echo->reserved = 0; echo->checksum = 0; + echo->data = htons(num); echo->checksum = htons(calc_checksum((uint16_t*)echo, - sizeof (struct icmp_packet))); + sizeof (struct icmp_echo_packet))); } +#else +static void +make_echo (const struct in_addr *src_ip, + struct icmp_packet *echo) +{ + memset(echo, 0, sizeof(struct icmp_packet)); + echo->type = ICMP_ECHO; + echo->code = 0; + echo->reserved = 0; + echo->checksum = 0; + echo->checksum = htons(calc_checksum((uint16_t*)echo, + sizeof (struct icmp_packet))); +} +#endif /** @@ -130,9 +163,17 @@ send_icmp (const struct in_addr *my_ip, { struct ip_packet ip_pkt; struct icmp_packet *icmp_pkt; +#if HAVE_PORT + struct icmp_echo_packet icmp_echo; +#else struct icmp_packet icmp_echo; +#endif struct sockaddr_in dst; +#if HAVE_PORT + char packet[sizeof (struct ip_packet)*2 + sizeof (struct icmp_packet) + sizeof(struct icmp_echo_packet)]; +#else char packet[sizeof (struct ip_packet)*2 + sizeof (struct icmp_packet)*2]; +#endif size_t off; int err; @@ -159,12 +200,18 @@ send_icmp (const struct in_addr *my_ip, icmp_pkt->code = 0; icmp_pkt->reserved = 0; icmp_pkt->checksum = 0; + off += sizeof (struct icmp_packet); /* ip header of the presumably 'lost' udp packet */ ip_pkt.vers_ihl = 0x45; ip_pkt.tos = 0; +#if HAVE_PORT + ip_pkt.pkt_len = (sizeof (struct ip_packet) + sizeof (struct icmp_echo_packet)); +#else ip_pkt.pkt_len = (sizeof (struct ip_packet) + sizeof (struct icmp_packet)); +#endif + ip_pkt.id = 1; ip_pkt.flags_frag_offset = 0; ip_pkt.ttl = 1; /* real TTL would be 1 on a time exceeded packet */ @@ -175,11 +222,28 @@ send_icmp (const struct in_addr *my_ip, ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt, sizeof (struct ip_packet))); memcpy (&packet[off], &ip_pkt, sizeof (struct ip_packet)); off += sizeof (struct ip_packet); + +#if HAVE_PORT + make_echo (other, &icmp_echo, port); + memcpy (&packet[off], &icmp_echo, sizeof(struct icmp_echo_packet)); + off += sizeof (struct icmp_echo_packet); +#else make_echo (other, &icmp_echo); memcpy (&packet[off], &icmp_echo, sizeof(struct icmp_packet)); off += sizeof (struct icmp_packet); +#endif + +#if HAVE_PORT + icmp_pkt->checksum = htons(calc_checksum((uint16_t*)icmp_pkt, + sizeof (struct icmp_packet) + sizeof(struct ip_packet) + sizeof(struct icmp_echo_packet))); + +#else icmp_pkt->checksum = htons(calc_checksum((uint16_t*)icmp_pkt, - sizeof (struct icmp_packet)*2 + sizeof(struct ip_packet))); + sizeof (struct icmp_packet)*2 + sizeof(struct ip_packet))); + +#endif + + memset (&dst, 0, sizeof (dst)); dst.sin_family = AF_INET; @@ -243,12 +307,22 @@ main (int argc, char *const *argv) fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno)); +#if HAVE_PORT + 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; + } + port = atoi(argv[3]); +#else if (argc != 3) { fprintf (stderr, - "This program must be started with our IP and the targets external IP as arguments.\n"); + "This program must be started with our IP and the targets external IP as arguments.\n"); return 1; } +#endif if ( (1 != inet_pton (AF_INET, argv[1], &external)) || (1 != inet_pton (AF_INET, argv[2], &target)) ) { diff --git a/src/transport/gnunet-nat-server.c b/src/transport/gnunet-nat-server.c index df6b69c65..6bead4c31 100644 --- a/src/transport/gnunet-nat-server.c +++ b/src/transport/gnunet-nat-server.c @@ -62,7 +62,7 @@ */ #define DUMMY_IP "1.2.3.4" -#define VERBOSE GNUNET_NO +#define VERBOSE 1 /** * How often do we send our ICMP messages to receive replies? @@ -193,6 +193,8 @@ process_icmp_response () struct ip_packet ip_pkt; struct icmp_packet icmp_pkt; size_t off; + int have_port; + uint32_t port; have = read (icmpsock, buf, sizeof (buf)); if (have == -1) @@ -202,7 +204,12 @@ process_icmp_response () strerror (errno)); return; } - if (have != sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2) + have_port = 0; + if (have == sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2 + sizeof(uint32_t)) + { + have_port = 1; + } + else if (have != sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2) { #if VERBOSE fprintf (stderr, @@ -226,12 +233,26 @@ process_icmp_response () memcpy(&sip, &ip_pkt.src_ip, sizeof (sip)); - fprintf (stdout, - "%s\n", - inet_ntop (AF_INET, - &sip, - buf, - sizeof (buf))); + if (have_port) + { + memcpy(&port, &buf[sizeof (struct ip_packet) *2 + sizeof (struct icmp_packet) * 2], sizeof(uint32_t)); + port = ntohs(port); + fprintf (stdout, + "%s:%d\n", + inet_ntop (AF_INET, + &sip, + buf, + sizeof (buf)), port); + } + else + { + fprintf (stdout, + "%s\n", + inet_ntop (AF_INET, + &sip, + buf, + sizeof (buf))); + } fflush (stdout); } -- 2.25.1