aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-07-01 08:46:27 +0000
committerChristian Grothoff <christian@grothoff.org>2011-07-01 08:46:27 +0000
commit11a2d8cd5b619a0fea63e766585c6ec4687a0707 (patch)
tree0b18ea0e567fd7bf5ca50b5994df5abe1ba77d95
parent9b986bcca579585f4f113d22b7c841a2ab28de0c (diff)
downloadgnunet-11a2d8cd5b619a0fea63e766585c6ec4687a0707.tar.gz
gnunet-11a2d8cd5b619a0fea63e766585c6ec4687a0707.zip
renaming gnunet-nat-server/client for consistency, other minor fixes
-rw-r--r--HACKING9
-rw-r--r--src/nat/Makefile.am28
-rw-r--r--src/nat/gnunet-helper-nat-client-windows.c (renamed from src/nat/gnunet-nat-client-windows.c)4
-rw-r--r--src/nat/gnunet-helper-nat-client.c (renamed from src/nat/gnunet-nat-client.c)4
-rw-r--r--src/nat/gnunet-helper-nat-server-windows.c (renamed from src/nat/gnunet-nat-server-windows.c)4
-rw-r--r--src/nat/gnunet-helper-nat-server.c651
-rw-r--r--src/nat/gnunet-nat-server.c631
-rw-r--r--src/nat/nat.c52
-rw-r--r--src/topology/gnunet-daemon-topology.c2
-rw-r--r--src/transport/Makefile.am8
10 files changed, 741 insertions, 652 deletions
diff --git a/HACKING b/HACKING
index 535d4498f..ecd9e6adb 100644
--- a/HACKING
+++ b/HACKING
@@ -14,6 +14,15 @@ include files:
14 * gettext.h --- external library 14 * gettext.h --- external library
15 15
16 16
17binaries:
18- gnunet-service-xxx: service process (has listen socket)
19- gnunet-daemon-xxx: daemon process (no listen socket)
20- gnunet-helper-xxx[-yyy]: SUID helper for module xxx
21- gnunet-yyy: command-line tool for end-users
22- libgnunet_plugin_xxx_yyy.so: plugin for API xxx
23- libgnunetxxx.so: library for API xxx
24
25
17configuration: 26configuration:
18- paths (that are substituted in all filenames) are in PATHS (have as few as possible) 27- paths (that are substituted in all filenames) are in PATHS (have as few as possible)
19- globals for the daemon are in [gnunetd] (for now, have as few as possible!) 28- globals for the daemon are in [gnunetd] (for now, have as few as possible!)
diff --git a/src/nat/Makefile.am b/src/nat/Makefile.am
index a60b4b5f3..e8dadb240 100644
--- a/src/nat/Makefile.am
+++ b/src/nat/Makefile.am
@@ -2,36 +2,38 @@ INCLUDES = -I$(top_srcdir)/src/include
2 2
3if MINGW 3if MINGW
4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols 4 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
5 NATBIN = gnunet-nat-server gnunet-nat-client 5 NATBIN = gnunet-helper-nat-server gnunet-helper-nat-client
6 NATSERVER = gnunet-nat-server-windows.c 6 NATSERVER = gnunet-helper-nat-server-windows.c
7 NATCLIENT = gnunet-nat-client-windows.c 7 NATCLIENT = gnunet-helper-nat-client-windows.c
8else
9 NATSERVER = gnunet-nat-server.c
10 NATCLIENT = gnunet-nat-client.c
11endif 8endif
12 9
13if LINUX 10if LINUX
14NATBIN = gnunet-nat-server gnunet-nat-client 11NATBIN = gnunet-helper-nat-server gnunet-helper-nat-client
12NATSERVER = gnunet-helper-nat-server.c
13NATCLIENT = gnunet-helper-nat-client.c
15install-exec-hook: 14install-exec-hook:
16 chown root:root $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client $(bindir)/gnunet-transport-wlan-helper || true 15 chown root:root $(bindir)/gnunet-helper-nat-server $(bindir)/gnunet-helper-nat-client || true
17 chmod u+s $(bindir)/gnunet-nat-server $(bindir)/gnunet-nat-client $(bindir)/gnunet-transport-wlan-helper || true 16 chmod u+s $(bindir)/gnunet-helper-nat-server $(bindir)/gnunet-helper-nat-client || true
18else 17else
19install-exec-hook: 18install-exec-hook:
20endif 19endif
21 20
22bin_PROGRAMS = \ 21bin_PROGRAMS = \
22 gnunet-nat-server \
23 $(NATBIN) 23 $(NATBIN)
24 24
25gnunet_nat_server_SOURCES = \ 25gnunet_nat_server_SOURCES = \
26 gnunet-nat-server.c
27gnunet_nat_server_LDADD = \
28 $(top_builddir)/src/util/libgnunetutil.la
29
30gnunet_helper_nat_server_SOURCES = \
26 $(NATSERVER) 31 $(NATSERVER)
27 32
28gnunet_nat_client_SOURCES = \ 33gnunet_helper_nat_client_SOURCES = \
29 $(NATCLIENT) 34 $(NATCLIENT)
30 35
31 36
32if MINGW
33 WINFLAGS = -Wl,--no-undefined -Wl,--export-all-symbols
34endif
35 37
36if USE_COVERAGE 38if USE_COVERAGE
37 AM_CFLAGS = -fprofile-arcs -ftest-coverage 39 AM_CFLAGS = -fprofile-arcs -ftest-coverage
diff --git a/src/nat/gnunet-nat-client-windows.c b/src/nat/gnunet-helper-nat-client-windows.c
index 2fe3643ac..0717eecfe 100644
--- a/src/nat/gnunet-nat-client-windows.c
+++ b/src/nat/gnunet-helper-nat-client-windows.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/nat/gnunet-nat-client-windows.c 22 * @file src/nat/gnunet-helper-nat-client-windows.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as 23 * @brief Tool to help bypass NATs using ICMP method; must run as
24 * administrator on W32 24 * administrator on W32
25 * This code is forx W32. 25 * This code is forx W32.
@@ -547,4 +547,4 @@ main (int argc, char *const *argv)
547 return 0; 547 return 0;
548} 548}
549 549
550/* end of gnunet-nat-client-windows.c */ 550/* end of gnunet-helper-nat-client-windows.c */
diff --git a/src/nat/gnunet-nat-client.c b/src/nat/gnunet-helper-nat-client.c
index 5f54f729b..10aa2f438 100644
--- a/src/nat/gnunet-nat-client.c
+++ b/src/nat/gnunet-helper-nat-client.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/nat/gnunet-nat-client.c 22 * @file src/nat/gnunet-helper-nat-client.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do) 23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do)
24 * This code will work under GNU/Linux only. 24 * This code will work under GNU/Linux only.
25 * @author Christian Grothoff 25 * @author Christian Grothoff
@@ -524,4 +524,4 @@ main (int argc, char *const *argv)
524 return 0; 524 return 0;
525} 525}
526 526
527/* end of gnunet-nat-client.c */ 527/* end of gnunet-helper-nat-client.c */
diff --git a/src/nat/gnunet-nat-server-windows.c b/src/nat/gnunet-helper-nat-server-windows.c
index 6c4c7d7a1..7a607c62d 100644
--- a/src/nat/gnunet-nat-server-windows.c
+++ b/src/nat/gnunet-helper-nat-server-windows.c
@@ -19,7 +19,7 @@
19*/ 19*/
20 20
21/** 21/**
22 * @file src/nat/gnunet-nat-server-windows.c 22 * @file src/nat/gnunet-helper-nat-server-windows.c
23 * @brief Windows tool to help bypass NATs using ICMP method 23 * @brief Windows tool to help bypass NATs using ICMP method
24 * This code will work under W32 only 24 * This code will work under W32 only
25 * @author Christian Grothoff 25 * @author Christian Grothoff
@@ -650,4 +650,4 @@ main (int argc,
650} 650}
651 651
652 652
653/* end of gnunet-nat-server-windows.c */ 653/* end of gnunet-helper-nat-server-windows.c */
diff --git a/src/nat/gnunet-helper-nat-server.c b/src/nat/gnunet-helper-nat-server.c
new file mode 100644
index 000000000..945c98735
--- /dev/null
+++ b/src/nat/gnunet-helper-nat-server.c
@@ -0,0 +1,651 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20
21/**
22 * @file src/nat/gnunet-helper-nat-server.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do)
24 * This code will work under GNU/Linux only (or maybe BSDs, but never W32)
25 * @author Christian Grothoff
26 *
27 * This program will send ONE ICMP message every 500 ms RAW sockets
28 * to a DUMMY IP address and also listens for ICMP replies. Since
29 * it uses RAW sockets, it must be installed SUID or run as 'root'.
30 * In order to keep the security risk of the resulting SUID binary
31 * minimal, the program ONLY opens the two RAW sockets with root
32 * privileges, then drops them and only then starts to process
33 * command line arguments. The code also does not link against
34 * any shared libraries (except libc) and is strictly minimal
35 * (except for checking for errors). The following list of people
36 * have reviewed this code and considered it safe since the last
37 * modification (if you reviewed it, please have your name added
38 * to the list):
39 *
40 * - Christian Grothoff
41 * - Nathan Evans
42 * - Benjamin Kuperman (22 Aug 2010)
43 */
44#if HAVE_CONFIG_H
45/* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */
46#include "gnunet_config.h"
47#else
48#define _GNU_SOURCE
49#endif
50#include <sys/types.h>
51#include <sys/socket.h>
52#include <arpa/inet.h>
53#include <sys/select.h>
54#include <sys/time.h>
55#include <sys/types.h>
56#include <unistd.h>
57#include <stdio.h>
58#include <string.h>
59#include <errno.h>
60#include <stdlib.h>
61#include <stdint.h>
62#include <time.h>
63#include <netinet/ip.h>
64#include <netinet/ip_icmp.h>
65#include <netinet/in.h>
66
67/**
68 * Should we print some debug output?
69 */
70#define VERBOSE 0
71
72/**
73 * Must match IP given in the client.
74 */
75#define DUMMY_IP "192.0.2.86"
76
77/**
78 * Port for UDP
79 */
80#define NAT_TRAV_PORT 22225
81
82/**
83 * How often do we send our ICMP messages to receive replies?
84 */
85#define ICMP_SEND_FREQUENCY_MS 500
86
87/**
88 * IPv4 header.
89 */
90struct ip_header
91{
92
93 /**
94 * Version (4 bits) + Internet header length (4 bits)
95 */
96 uint8_t vers_ihl;
97
98 /**
99 * Type of service
100 */
101 uint8_t tos;
102
103 /**
104 * Total length
105 */
106 uint16_t pkt_len;
107
108 /**
109 * Identification
110 */
111 uint16_t id;
112
113 /**
114 * Flags (3 bits) + Fragment offset (13 bits)
115 */
116 uint16_t flags_frag_offset;
117
118 /**
119 * Time to live
120 */
121 uint8_t ttl;
122
123 /**
124 * Protocol
125 */
126 uint8_t proto;
127
128 /**
129 * Header checksum
130 */
131 uint16_t checksum;
132
133 /**
134 * Source address
135 */
136 uint32_t src_ip;
137
138 /**
139 * Destination address
140 */
141 uint32_t dst_ip;
142};
143
144/**
145 * Format of ICMP packet.
146 */
147struct icmp_ttl_exceeded_header
148{
149 uint8_t type;
150
151 uint8_t code;
152
153 uint16_t checksum;
154
155 uint32_t unused;
156
157 /* followed by original payload */
158};
159
160struct icmp_echo_header
161{
162 uint8_t type;
163
164 uint8_t code;
165
166 uint16_t checksum;
167
168 uint32_t reserved;
169};
170
171
172/**
173 * Beginning of UDP packet.
174 */
175struct udp_header
176{
177 uint16_t src_port;
178
179 uint16_t dst_port;
180
181 uint16_t length;
182
183 uint16_t crc;
184};
185
186/**
187 * Socket we use to receive "fake" ICMP replies.
188 */
189static int icmpsock;
190
191/**
192 * Socket we use to send our ICMP requests.
193 */
194static int rawsock;
195
196/**
197 * Socket we use to send our UDP requests.
198 */
199static int udpsock;
200
201/**
202 * Target "dummy" address.
203 */
204static struct in_addr dummy;
205
206
207/**
208 * CRC-16 for IP/ICMP headers.
209 *
210 * @param data what to calculate the CRC over
211 * @param bytes number of bytes in data (must be multiple of 2)
212 * @return the CRC 16.
213 */
214static uint16_t
215calc_checksum(const uint16_t *data,
216 unsigned int bytes)
217{
218 uint32_t sum;
219 unsigned int i;
220
221 sum = 0;
222 for (i=0;i<bytes/2;i++)
223 sum += data[i];
224 sum = (sum & 0xffff) + (sum >> 16);
225 sum = htons(0xffff - sum);
226 return sum;
227}
228
229
230/**
231 * Send an ICMP message to the dummy IP.
232 *
233 * @param my_ip source address (our ip address)
234 */
235static void
236send_icmp_echo (const struct in_addr *my_ip)
237{
238 char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)];
239 struct icmp_echo_header icmp_echo;
240 struct ip_header ip_pkt;
241 struct sockaddr_in dst;
242 size_t off;
243 int err;
244
245 off = 0;
246 ip_pkt.vers_ihl = 0x45;
247 ip_pkt.tos = 0;
248 ip_pkt.pkt_len = htons (sizeof (packet));
249 ip_pkt.id = htons (256);
250 ip_pkt.flags_frag_offset = 0;
251 ip_pkt.ttl = IPDEFTTL;
252 ip_pkt.proto = IPPROTO_ICMP;
253 ip_pkt.checksum = 0;
254 ip_pkt.src_ip = my_ip->s_addr;
255 ip_pkt.dst_ip = dummy.s_addr;
256 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
257 sizeof (struct ip_header)));
258 memcpy (&packet[off],
259 &ip_pkt,
260 sizeof (struct ip_header));
261 off += sizeof (struct ip_header);
262
263 icmp_echo.type = ICMP_ECHO;
264 icmp_echo.code = 0;
265 icmp_echo.checksum = 0;
266 icmp_echo.reserved = 0;
267 icmp_echo.checksum = htons(calc_checksum((uint16_t*)&icmp_echo,
268 sizeof (struct icmp_echo_header)));
269 memcpy (&packet[off],
270 &icmp_echo,
271 sizeof (struct icmp_echo_header));
272 off += sizeof (struct icmp_echo_header);
273
274 memset (&dst, 0, sizeof (dst));
275 dst.sin_family = AF_INET;
276#if HAVE_SOCKADDR_IN_SIN_LEN
277 dst.sin_len = sizeof (struct sockaddr_in);
278#endif
279 dst.sin_addr = dummy;
280 err = sendto(rawsock,
281 packet, off, 0,
282 (struct sockaddr*)&dst,
283 sizeof(dst));
284 if (err < 0)
285 {
286#if VERBOSE
287 fprintf(stderr,
288 "sendto failed: %s\n", strerror(errno));
289#endif
290 }
291 else if (sizeof (packet) != err)
292 {
293 fprintf(stderr,
294 "Error: partial send of ICMP message\n");
295 }
296}
297
298
299/**
300 * Send a UDP message to the dummy IP.
301 */
302static void
303send_udp ()
304{
305 struct sockaddr_in dst;
306 ssize_t err;
307
308 memset (&dst, 0, sizeof (dst));
309 dst.sin_family = AF_INET;
310#if HAVE_SOCKADDR_IN_SIN_LEN
311 dst.sin_len = sizeof (struct sockaddr_in);
312#endif
313 dst.sin_addr = dummy;
314 dst.sin_port = htons (NAT_TRAV_PORT);
315 err = sendto(udpsock,
316 NULL, 0, 0,
317 (struct sockaddr*)&dst,
318 sizeof(dst));
319 if (err < 0)
320 {
321#if VERBOSE
322 fprintf(stderr,
323 "sendto failed: %s\n", strerror(errno));
324#endif
325 }
326 else if (0 != err)
327 {
328 fprintf(stderr,
329 "Error: partial send of ICMP message\n");
330 }
331}
332
333
334/**
335 * We've received an ICMP response. Process it.
336 */
337static void
338process_icmp_response ()
339{
340 char buf[65536];
341 ssize_t have;
342 struct in_addr source_ip;
343 struct ip_header ip_pkt;
344 struct icmp_ttl_exceeded_header icmp_ttl;
345 struct icmp_echo_header icmp_echo;
346 struct udp_header udp_pkt;
347 size_t off;
348 uint16_t port;
349
350 have = read (icmpsock, buf, sizeof (buf));
351 if (-1 == have)
352 {
353 fprintf (stderr,
354 "Error reading raw socket: %s\n",
355 strerror (errno));
356 return;
357 }
358#if VERBOSE
359 fprintf (stderr,
360 "Received message of %u bytes\n",
361 (unsigned int) have);
362#endif
363 if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header)))
364 {
365 /* malformed */
366 return;
367 }
368 off = 0;
369 memcpy (&ip_pkt,
370 &buf[off],
371 sizeof (struct ip_header));
372 off += sizeof (struct ip_header);
373 memcpy(&source_ip,
374 &ip_pkt.src_ip,
375 sizeof (source_ip));
376 memcpy (&icmp_ttl,
377 &buf[off],
378 sizeof (struct icmp_ttl_exceeded_header));
379 off += sizeof (struct icmp_ttl_exceeded_header);
380 if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) ||
381 (0 != icmp_ttl.code) )
382 {
383 /* different type than what we want */
384 return;
385 }
386 /* skip 2nd IP header */
387 memcpy (&ip_pkt,
388 &buf[off],
389 sizeof (struct ip_header));
390 off += sizeof (struct ip_header);
391
392 switch (ip_pkt.proto)
393 {
394 case IPPROTO_ICMP:
395 if (have != (sizeof (struct ip_header) * 2 +
396 sizeof (struct icmp_ttl_exceeded_header) +
397 sizeof (struct icmp_echo_header)) )
398 {
399 /* malformed */
400 return;
401 }
402 /* grab ICMP ECHO content */
403 memcpy (&icmp_echo,
404 &buf[off],
405 sizeof (struct icmp_echo_header));
406 port = (uint16_t) ntohl (icmp_echo.reserved);
407 break;
408 case IPPROTO_UDP:
409 if (have != (sizeof (struct ip_header) * 2 +
410 sizeof (struct icmp_ttl_exceeded_header) +
411 sizeof (struct udp_header)) )
412 {
413 /* malformed */
414 return;
415 }
416 /* grab UDP content */
417 memcpy (&udp_pkt,
418 &buf[off],
419 sizeof (struct udp_header));
420 port = ntohs (udp_pkt.length);
421 break;
422 default:
423 /* different type than what we want */
424 return;
425 }
426
427 if (port == 0)
428 fprintf (stdout,
429 "%s\n",
430 inet_ntop (AF_INET,
431 &source_ip,
432 buf,
433 sizeof (buf)));
434 else
435 fprintf (stdout,
436 "%s:%u\n",
437 inet_ntop (AF_INET,
438 &source_ip,
439 buf,
440 sizeof (buf)),
441 (unsigned int) port);
442 fflush (stdout);
443}
444
445
446/**
447 * Create an ICMP raw socket for reading.
448 *
449 * @return -1 on error
450 */
451static int
452make_icmp_socket ()
453{
454 int ret;
455
456 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
457 if (-1 == ret)
458 {
459 fprintf (stderr,
460 "Error opening RAW socket: %s\n",
461 strerror (errno));
462 return -1;
463 }
464 if (ret >= FD_SETSIZE)
465 {
466 fprintf (stderr,
467 "Socket number too large (%d > %u)\n",
468 ret,
469 (unsigned int) FD_SETSIZE);
470 close (ret);
471 return -1;
472 }
473 return ret;
474}
475
476
477/**
478 * Create an ICMP raw socket for writing.
479 *
480 * @return -1 on error
481 */
482static int
483make_raw_socket ()
484{
485 const int one = 1;
486 int ret;
487
488 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
489 if (-1 == ret)
490 {
491 fprintf (stderr,
492 "Error opening RAW socket: %s\n",
493 strerror (errno));
494 return -1;
495 }
496 if (-1 == setsockopt(ret,
497 SOL_SOCKET,
498 SO_BROADCAST,
499 (char *)&one, sizeof(one)))
500 {
501 fprintf(stderr,
502 "setsockopt failed: %s\n",
503 strerror (errno));
504 close (ret);
505 return -1;
506 }
507 if (-1 == setsockopt(ret,
508 IPPROTO_IP,
509 IP_HDRINCL,
510 (char *)&one, sizeof(one)))
511 {
512 fprintf(stderr,
513 "setsockopt failed: %s\n",
514 strerror (errno));
515 close (ret);
516 return -1;
517 }
518 return ret;
519}
520
521
522/**
523 * Create a UDP socket for writinging.
524 *
525 * @param my_ip source address (our ip address)
526 * @return -1 on error
527 */
528static int
529make_udp_socket (const struct in_addr *my_ip)
530{
531 int ret;
532 struct sockaddr_in addr;
533
534 ret = socket (AF_INET, SOCK_DGRAM, 0);
535 if (-1 == ret)
536 {
537 fprintf (stderr,
538 "Error opening UDP socket: %s\n",
539 strerror (errno));
540 return -1;
541 }
542 memset (&addr,
543 0,
544 sizeof (addr));
545 addr.sin_family = AF_INET;
546#if HAVE_SOCKADDR_IN_SIN_LEN
547 addr.sin_len = sizeof (struct sockaddr_in);
548#endif
549 addr.sin_addr = *my_ip;
550 addr.sin_port = htons (NAT_TRAV_PORT);
551
552 if (0 != bind (ret,
553 &addr,
554 sizeof(addr)))
555 {
556 fprintf (stderr,
557 "Error binding UDP socket to port %u: %s\n",
558 NAT_TRAV_PORT,
559 strerror (errno));
560 /* likely problematic, but not certain, try to continue */
561 }
562 return ret;
563}
564
565
566int
567main (int argc,
568 char *const *argv)
569{
570 struct in_addr external;
571 fd_set rs;
572 struct timeval tv;
573 uid_t uid;
574 unsigned int alt;
575
576 if (2 != argc)
577 {
578 fprintf (stderr,
579 "This program must be started with our (internal NAT) IP as the only argument.\n");
580 return 1;
581 }
582 if (1 != inet_pton (AF_INET, argv[1], &external))
583 {
584 fprintf (stderr,
585 "Error parsing IPv4 address: %s\n",
586 strerror (errno));
587 return 1;
588 }
589 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
590 {
591 fprintf (stderr,
592 "Internal error converting dummy IP to binary.\n");
593 return 2;
594 }
595 if (-1 == (icmpsock = make_icmp_socket()))
596 {
597 return 3;
598 }
599 if (-1 == (rawsock = make_raw_socket()))
600 {
601 close (icmpsock);
602 return 3;
603 }
604 uid = getuid ();
605 if (0 != setresuid (uid, uid, uid))
606 {
607 fprintf (stderr,
608 "Failed to setresuid: %s\n",
609 strerror (errno));
610 /* not critical, continue anyway */
611 }
612 if (-1 == (udpsock = make_udp_socket(&external)))
613 {
614 close (icmpsock);
615 close (rawsock);
616 return 3;
617 }
618 alt = 0;
619 while (1)
620 {
621 FD_ZERO (&rs);
622 FD_SET (icmpsock, &rs);
623 tv.tv_sec = 0;
624 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
625 if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
626 {
627 if (errno == EINTR)
628 continue;
629 fprintf (stderr,
630 "select failed: %s\n",
631 strerror (errno));
632 break;
633 }
634 if (1 == getppid()) /* Check the parent process id, if 1 the parent has died, so we should die too */
635 break;
636 if (FD_ISSET (icmpsock, &rs))
637 process_icmp_response ();
638 if (0 == (++alt % 2))
639 send_icmp_echo (&external);
640 else
641 send_udp ();
642 }
643 /* select failed (internal error or OS out of resources) */
644 close (icmpsock);
645 close (rawsock);
646 close (udpsock);
647 return 4;
648}
649
650
651/* end of gnunet-helper-nat-server.c */
diff --git a/src/nat/gnunet-nat-server.c b/src/nat/gnunet-nat-server.c
index ffc570146..c1f1be668 100644
--- a/src/nat/gnunet-nat-server.c
+++ b/src/nat/gnunet-nat-server.c
@@ -20,49 +20,12 @@
20 20
21/** 21/**
22 * @file src/nat/gnunet-nat-server.c 22 * @file src/nat/gnunet-nat-server.c
23 * @brief Tool to help bypass NATs using ICMP method; must run as root (SUID will do) 23 * @brief Daemon to run on 'gnunet.org' to help test NAT traversal code
24 * This code will work under GNU/Linux only (or maybe BSDs, but never W32)
25 * @author Christian Grothoff 24 * @author Christian Grothoff
26 * 25 *
27 * This program will send ONE ICMP message every 500 ms RAW sockets
28 * to a DUMMY IP address and also listens for ICMP replies. Since
29 * it uses RAW sockets, it must be installed SUID or run as 'root'.
30 * In order to keep the security risk of the resulting SUID binary
31 * minimal, the program ONLY opens the two RAW sockets with root
32 * privileges, then drops them and only then starts to process
33 * command line arguments. The code also does not link against
34 * any shared libraries (except libc) and is strictly minimal
35 * (except for checking for errors). The following list of people
36 * have reviewed this code and considered it safe since the last
37 * modification (if you reviewed it, please have your name added
38 * to the list):
39 *
40 * - Christian Grothoff
41 * - Nathan Evans
42 * - Benjamin Kuperman (22 Aug 2010)
43 */ 26 */
44#if HAVE_CONFIG_H 27#include "platform.h"
45/* Just needed for HAVE_SOCKADDR_IN_SIN_LEN test macro! */ 28#include "gnunet_util_lib.h"
46#include "gnunet_config.h"
47#else
48#define _GNU_SOURCE
49#endif
50#include <sys/types.h>
51#include <sys/socket.h>
52#include <arpa/inet.h>
53#include <sys/select.h>
54#include <sys/time.h>
55#include <sys/types.h>
56#include <unistd.h>
57#include <stdio.h>
58#include <string.h>
59#include <errno.h>
60#include <stdlib.h>
61#include <stdint.h>
62#include <time.h>
63#include <netinet/ip.h>
64#include <netinet/ip_icmp.h>
65#include <netinet/in.h>
66 29
67/** 30/**
68 * Should we print some debug output? 31 * Should we print some debug output?
@@ -70,581 +33,37 @@
70#define VERBOSE 0 33#define VERBOSE 0
71 34
72/** 35/**
73 * Must match IP given in the client. 36 * Main function that will be run.
74 */
75#define DUMMY_IP "192.0.2.86"
76
77/**
78 * Port for UDP
79 */
80#define NAT_TRAV_PORT 22225
81
82/**
83 * How often do we send our ICMP messages to receive replies?
84 */
85#define ICMP_SEND_FREQUENCY_MS 500
86
87/**
88 * IPv4 header.
89 */
90struct ip_header
91{
92
93 /**
94 * Version (4 bits) + Internet header length (4 bits)
95 */
96 uint8_t vers_ihl;
97
98 /**
99 * Type of service
100 */
101 uint8_t tos;
102
103 /**
104 * Total length
105 */
106 uint16_t pkt_len;
107
108 /**
109 * Identification
110 */
111 uint16_t id;
112
113 /**
114 * Flags (3 bits) + Fragment offset (13 bits)
115 */
116 uint16_t flags_frag_offset;
117
118 /**
119 * Time to live
120 */
121 uint8_t ttl;
122
123 /**
124 * Protocol
125 */
126 uint8_t proto;
127
128 /**
129 * Header checksum
130 */
131 uint16_t checksum;
132
133 /**
134 * Source address
135 */
136 uint32_t src_ip;
137
138 /**
139 * Destination address
140 */
141 uint32_t dst_ip;
142};
143
144/**
145 * Format of ICMP packet.
146 */
147struct icmp_ttl_exceeded_header
148{
149 uint8_t type;
150
151 uint8_t code;
152
153 uint16_t checksum;
154
155 uint32_t unused;
156
157 /* followed by original payload */
158};
159
160struct icmp_echo_header
161{
162 uint8_t type;
163
164 uint8_t code;
165
166 uint16_t checksum;
167
168 uint32_t reserved;
169};
170
171
172/**
173 * Beginning of UDP packet.
174 */
175struct udp_header
176{
177 uint16_t src_port;
178
179 uint16_t dst_port;
180
181 uint16_t length;
182
183 uint16_t crc;
184};
185
186/**
187 * Socket we use to receive "fake" ICMP replies.
188 */
189static int icmpsock;
190
191/**
192 * Socket we use to send our ICMP requests.
193 */
194static int rawsock;
195
196/**
197 * Socket we use to send our UDP requests.
198 */
199static int udpsock;
200
201/**
202 * Target "dummy" address.
203 */
204static struct in_addr dummy;
205
206
207/**
208 * CRC-16 for IP/ICMP headers.
209 *
210 * @param data what to calculate the CRC over
211 * @param bytes number of bytes in data (must be multiple of 2)
212 * @return the CRC 16.
213 */
214static uint16_t
215calc_checksum(const uint16_t *data,
216 unsigned int bytes)
217{
218 uint32_t sum;
219 unsigned int i;
220
221 sum = 0;
222 for (i=0;i<bytes/2;i++)
223 sum += data[i];
224 sum = (sum & 0xffff) + (sum >> 16);
225 sum = htons(0xffff - sum);
226 return sum;
227}
228
229
230/**
231 * Send an ICMP message to the dummy IP.
232 * 37 *
233 * @param my_ip source address (our ip address) 38 * @param cls closure
234 */ 39 * @param args remaining command-line arguments
235static void 40 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
236send_icmp_echo (const struct in_addr *my_ip) 41 * @param c configuration
237{
238 char packet[sizeof (struct ip_header) + sizeof (struct icmp_echo_header)];
239 struct icmp_echo_header icmp_echo;
240 struct ip_header ip_pkt;
241 struct sockaddr_in dst;
242 size_t off;
243 int err;
244
245 off = 0;
246 ip_pkt.vers_ihl = 0x45;
247 ip_pkt.tos = 0;
248 ip_pkt.pkt_len = htons (sizeof (packet));
249 ip_pkt.id = htons (256);
250 ip_pkt.flags_frag_offset = 0;
251 ip_pkt.ttl = IPDEFTTL;
252 ip_pkt.proto = IPPROTO_ICMP;
253 ip_pkt.checksum = 0;
254 ip_pkt.src_ip = my_ip->s_addr;
255 ip_pkt.dst_ip = dummy.s_addr;
256 ip_pkt.checksum = htons(calc_checksum((uint16_t*)&ip_pkt,
257 sizeof (struct ip_header)));
258 memcpy (&packet[off],
259 &ip_pkt,
260 sizeof (struct ip_header));
261 off += sizeof (struct ip_header);
262
263 icmp_echo.type = ICMP_ECHO;
264 icmp_echo.code = 0;
265 icmp_echo.checksum = 0;
266 icmp_echo.reserved = 0;
267 icmp_echo.checksum = htons(calc_checksum((uint16_t*)&icmp_echo,
268 sizeof (struct icmp_echo_header)));
269 memcpy (&packet[off],
270 &icmp_echo,
271 sizeof (struct icmp_echo_header));
272 off += sizeof (struct icmp_echo_header);
273
274 memset (&dst, 0, sizeof (dst));
275 dst.sin_family = AF_INET;
276#if HAVE_SOCKADDR_IN_SIN_LEN
277 dst.sin_len = sizeof (struct sockaddr_in);
278#endif
279 dst.sin_addr = dummy;
280 err = sendto(rawsock,
281 packet, off, 0,
282 (struct sockaddr*)&dst,
283 sizeof(dst));
284 if (err < 0)
285 {
286#if VERBOSE
287 fprintf(stderr,
288 "sendto failed: %s\n", strerror(errno));
289#endif
290 }
291 else if (sizeof (packet) != err)
292 {
293 fprintf(stderr,
294 "Error: partial send of ICMP message\n");
295 }
296}
297
298
299/**
300 * Send a UDP message to the dummy IP.
301 */
302static void
303send_udp ()
304{
305 struct sockaddr_in dst;
306 ssize_t err;
307
308 memset (&dst, 0, sizeof (dst));
309 dst.sin_family = AF_INET;
310#if HAVE_SOCKADDR_IN_SIN_LEN
311 dst.sin_len = sizeof (struct sockaddr_in);
312#endif
313 dst.sin_addr = dummy;
314 dst.sin_port = htons (NAT_TRAV_PORT);
315 err = sendto(udpsock,
316 NULL, 0, 0,
317 (struct sockaddr*)&dst,
318 sizeof(dst));
319 if (err < 0)
320 {
321#if VERBOSE
322 fprintf(stderr,
323 "sendto failed: %s\n", strerror(errno));
324#endif
325 }
326 else if (0 != err)
327 {
328 fprintf(stderr,
329 "Error: partial send of ICMP message\n");
330 }
331}
332
333
334/**
335 * We've received an ICMP response. Process it.
336 */ 42 */
337static void 43static void
338process_icmp_response () 44run (void *cls,
339{ 45 char *const *args,
340 char buf[65536]; 46 const char *cfgfile,
341 ssize_t have; 47 const struct GNUNET_CONFIGURATION_Handle * c)
342 struct in_addr source_ip;
343 struct ip_header ip_pkt;
344 struct icmp_ttl_exceeded_header icmp_ttl;
345 struct icmp_echo_header icmp_echo;
346 struct udp_header udp_pkt;
347 size_t off;
348 uint16_t port;
349
350 have = read (icmpsock, buf, sizeof (buf));
351 if (-1 == have)
352 {
353 fprintf (stderr,
354 "Error reading raw socket: %s\n",
355 strerror (errno));
356 return;
357 }
358#if VERBOSE
359 fprintf (stderr,
360 "Received message of %u bytes\n",
361 (unsigned int) have);
362#endif
363 if (have < (ssize_t) (sizeof (struct ip_header) + sizeof (struct icmp_ttl_exceeded_header) + sizeof (struct ip_header)))
364 {
365 /* malformed */
366 return;
367 }
368 off = 0;
369 memcpy (&ip_pkt,
370 &buf[off],
371 sizeof (struct ip_header));
372 off += sizeof (struct ip_header);
373 memcpy(&source_ip,
374 &ip_pkt.src_ip,
375 sizeof (source_ip));
376 memcpy (&icmp_ttl,
377 &buf[off],
378 sizeof (struct icmp_ttl_exceeded_header));
379 off += sizeof (struct icmp_ttl_exceeded_header);
380 if ( (ICMP_TIME_EXCEEDED != icmp_ttl.type) ||
381 (0 != icmp_ttl.code) )
382 {
383 /* different type than what we want */
384 return;
385 }
386 /* skip 2nd IP header */
387 memcpy (&ip_pkt,
388 &buf[off],
389 sizeof (struct ip_header));
390 off += sizeof (struct ip_header);
391
392 switch (ip_pkt.proto)
393 {
394 case IPPROTO_ICMP:
395 if (have != (sizeof (struct ip_header) * 2 +
396 sizeof (struct icmp_ttl_exceeded_header) +
397 sizeof (struct icmp_echo_header)) )
398 {
399 /* malformed */
400 return;
401 }
402 /* grab ICMP ECHO content */
403 memcpy (&icmp_echo,
404 &buf[off],
405 sizeof (struct icmp_echo_header));
406 port = (uint16_t) ntohl (icmp_echo.reserved);
407 break;
408 case IPPROTO_UDP:
409 if (have != (sizeof (struct ip_header) * 2 +
410 sizeof (struct icmp_ttl_exceeded_header) +
411 sizeof (struct udp_header)) )
412 {
413 /* malformed */
414 return;
415 }
416 /* grab UDP content */
417 memcpy (&udp_pkt,
418 &buf[off],
419 sizeof (struct udp_header));
420 port = ntohs (udp_pkt.length);
421 break;
422 default:
423 /* different type than what we want */
424 return;
425 }
426
427 if (port == 0)
428 fprintf (stdout,
429 "%s\n",
430 inet_ntop (AF_INET,
431 &source_ip,
432 buf,
433 sizeof (buf)));
434 else
435 fprintf (stdout,
436 "%s:%u\n",
437 inet_ntop (AF_INET,
438 &source_ip,
439 buf,
440 sizeof (buf)),
441 (unsigned int) port);
442 fflush (stdout);
443}
444
445
446/**
447 * Create an ICMP raw socket for reading.
448 *
449 * @return -1 on error
450 */
451static int
452make_icmp_socket ()
453{
454 int ret;
455
456 ret = socket (AF_INET, SOCK_RAW, IPPROTO_ICMP);
457 if (-1 == ret)
458 {
459 fprintf (stderr,
460 "Error opening RAW socket: %s\n",
461 strerror (errno));
462 return -1;
463 }
464 if (ret >= FD_SETSIZE)
465 {
466 fprintf (stderr,
467 "Socket number too large (%d > %u)\n",
468 ret,
469 (unsigned int) FD_SETSIZE);
470 close (ret);
471 return -1;
472 }
473 return ret;
474}
475
476
477/**
478 * Create an ICMP raw socket for writing.
479 *
480 * @return -1 on error
481 */
482static int
483make_raw_socket ()
484{
485 const int one = 1;
486 int ret;
487
488 ret = socket (AF_INET, SOCK_RAW, IPPROTO_RAW);
489 if (-1 == ret)
490 {
491 fprintf (stderr,
492 "Error opening RAW socket: %s\n",
493 strerror (errno));
494 return -1;
495 }
496 if (-1 == setsockopt(ret,
497 SOL_SOCKET,
498 SO_BROADCAST,
499 (char *)&one, sizeof(one)))
500 {
501 fprintf(stderr,
502 "setsockopt failed: %s\n",
503 strerror (errno));
504 close (ret);
505 return -1;
506 }
507 if (-1 == setsockopt(ret,
508 IPPROTO_IP,
509 IP_HDRINCL,
510 (char *)&one, sizeof(one)))
511 {
512 fprintf(stderr,
513 "setsockopt failed: %s\n",
514 strerror (errno));
515 close (ret);
516 return -1;
517 }
518 return ret;
519}
520
521
522/**
523 * Create a UDP socket for writinging.
524 *
525 * @param my_ip source address (our ip address)
526 * @return -1 on error
527 */
528static int
529make_udp_socket (const struct in_addr *my_ip)
530{ 48{
531 int ret;
532 struct sockaddr_in addr;
533
534 ret = socket (AF_INET, SOCK_DGRAM, 0);
535 if (-1 == ret)
536 {
537 fprintf (stderr,
538 "Error opening UDP socket: %s\n",
539 strerror (errno));
540 return -1;
541 }
542 memset (&addr,
543 0,
544 sizeof (addr));
545 addr.sin_family = AF_INET;
546#if HAVE_SOCKADDR_IN_SIN_LEN
547 addr.sin_len = sizeof (struct sockaddr_in);
548#endif
549 addr.sin_addr = *my_ip;
550 addr.sin_port = htons (NAT_TRAV_PORT);
551
552 if (0 != bind (ret,
553 &addr,
554 sizeof(addr)))
555 {
556 fprintf (stderr,
557 "Error binding UDP socket to port %u: %s\n",
558 NAT_TRAV_PORT,
559 strerror (errno));
560 /* likely problematic, but not certain, try to continue */
561 }
562 return ret;
563} 49}
564 50
565 51
566int 52int
567main (int argc, 53main (int argc, char *const argv[])
568 char *const *argv)
569{ 54{
570 struct in_addr external; 55 static const struct GNUNET_GETOPT_CommandLineOption options[] = {
571 fd_set rs; 56 GNUNET_GETOPT_OPTION_END
572 struct timeval tv; 57 };
573 uid_t uid; 58
574 unsigned int alt; 59 if (GNUNET_OK !=
575 60 GNUNET_PROGRAM_run (argc, argv,
576 if (2 != argc) 61 "gnunet-nat-server",
577 { 62 _("GNUnet NAT traversal test helper daemon"),
578 fprintf (stderr, 63 options,
579 "This program must be started with our (internal NAT) IP as the only argument.\n"); 64 &run, NULL))
580 return 1; 65 return 1;
581 } 66 return 0;
582 if (1 != inet_pton (AF_INET, argv[1], &external))
583 {
584 fprintf (stderr,
585 "Error parsing IPv4 address: %s\n",
586 strerror (errno));
587 return 1;
588 }
589 if (1 != inet_pton (AF_INET, DUMMY_IP, &dummy))
590 {
591 fprintf (stderr,
592 "Internal error converting dummy IP to binary.\n");
593 return 2;
594 }
595 if (-1 == (icmpsock = make_icmp_socket()))
596 {
597 return 3;
598 }
599 if (-1 == (rawsock = make_raw_socket()))
600 {
601 close (icmpsock);
602 return 3;
603 }
604 uid = getuid ();
605 if (0 != setresuid (uid, uid, uid))
606 {
607 fprintf (stderr,
608 "Failed to setresuid: %s\n",
609 strerror (errno));
610 /* not critical, continue anyway */
611 }
612 if (-1 == (udpsock = make_udp_socket(&external)))
613 {
614 close (icmpsock);
615 close (rawsock);
616 return 3;
617 }
618 alt = 0;
619 while (1)
620 {
621 FD_ZERO (&rs);
622 FD_SET (icmpsock, &rs);
623 tv.tv_sec = 0;
624 tv.tv_usec = ICMP_SEND_FREQUENCY_MS * 1000;
625 if (-1 == select (icmpsock + 1, &rs, NULL, NULL, &tv))
626 {
627 if (errno == EINTR)
628 continue;
629 fprintf (stderr,
630 "select failed: %s\n",
631 strerror (errno));
632 break;
633 }
634 if (1 == getppid()) /* Check the parent process id, if 1 the parent has died, so we should die too */
635 break;
636 if (FD_ISSET (icmpsock, &rs))
637 process_icmp_response ();
638 if (0 == (++alt % 2))
639 send_icmp_echo (&external);
640 else
641 send_udp ();
642 }
643 /* select failed (internal error or OS out of resources) */
644 close (icmpsock);
645 close (rawsock);
646 close (udpsock);
647 return 4;
648} 67}
649 68
650 69
diff --git a/src/nat/nat.c b/src/nat/nat.c
index 48d7faf9c..418c619e3 100644
--- a/src/nat/nat.c
+++ b/src/nat/nat.c
@@ -160,12 +160,12 @@ struct GNUNET_NAT_Handle
160 struct GNUNET_RESOLVER_RequestHandle *hostname_dns; 160 struct GNUNET_RESOLVER_RequestHandle *hostname_dns;
161 161
162 /** 162 /**
163 * stdout pipe handle for the gnunet-nat-server process 163 * stdout pipe handle for the gnunet-helper-nat-server process
164 */ 164 */
165 struct GNUNET_DISK_PipeHandle *server_stdout; 165 struct GNUNET_DISK_PipeHandle *server_stdout;
166 166
167 /** 167 /**
168 * stdout file handle (for reading) for the gnunet-nat-server process 168 * stdout file handle (for reading) for the gnunet-helper-nat-server process
169 */ 169 */
170 const struct GNUNET_DISK_FileHandle *server_stdout_handle; 170 const struct GNUNET_DISK_FileHandle *server_stdout_handle;
171 171
@@ -180,12 +180,12 @@ struct GNUNET_NAT_Handle
180 struct LocalAddressList *lal_tail; 180 struct LocalAddressList *lal_tail;
181 181
182 /** 182 /**
183 * How long do we wait for restarting a crashed gnunet-nat-server? 183 * How long do we wait for restarting a crashed gnunet-helper-nat-server?
184 */ 184 */
185 struct GNUNET_TIME_Relative server_retry_delay; 185 struct GNUNET_TIME_Relative server_retry_delay;
186 186
187 /** 187 /**
188 * ID of select gnunet-nat-server stdout read task 188 * ID of select gnunet-helper-nat-server stdout read task
189 */ 189 */
190 GNUNET_SCHEDULER_TaskIdentifier server_read_task; 190 GNUNET_SCHEDULER_TaskIdentifier server_read_task;
191 191
@@ -266,7 +266,7 @@ struct GNUNET_NAT_Handle
266 int enable_nat_client; 266 int enable_nat_client;
267 267
268 /** 268 /**
269 * Should we run the gnunet-nat-server? 269 * Should we run the gnunet-helper-nat-server?
270 */ 270 */
271 int enable_nat_server; 271 int enable_nat_server;
272 272
@@ -299,7 +299,7 @@ struct GNUNET_NAT_Handle
299 299
300 300
301/** 301/**
302 * Try to start the gnunet-nat-server (if it is not 302 * Try to start the gnunet-helper-nat-server (if it is not
303 * already running). 303 * already running).
304 * 304 *
305 * @param h handle to NAT 305 * @param h handle to NAT
@@ -380,7 +380,7 @@ add_to_address_list_as_is (struct GNUNET_NAT_Handle *h,
380 * Add the given address to the list of 'local' addresses, thereby 380 * Add the given address to the list of 'local' addresses, thereby
381 * making it a 'legal' address for this peer to have. Set the 381 * making it a 'legal' address for this peer to have. Set the
382 * port number in the process to the advertised port and possibly 382 * port number in the process to the advertised port and possibly
383 * also to zero (if we have the gnunet-nat-server). 383 * also to zero (if we have the gnunet-helper-nat-server).
384 * 384 *
385 * @param plugin the plugin 385 * @param plugin the plugin
386 * @param src where did the local address originate from? 386 * @param src where did the local address originate from?
@@ -773,7 +773,7 @@ check_gnunet_nat_binary (const char *binary)
773 773
774 774
775/** 775/**
776 * Task that restarts the gnunet-nat-server process after a crash 776 * Task that restarts the gnunet-helper-nat-server process after a crash
777 * after a certain delay. 777 * after a certain delay.
778 * 778 *
779 * @param cls the 'struct GNUNET_NAT_Handle' 779 * @param cls the 'struct GNUNET_NAT_Handle'
@@ -793,7 +793,7 @@ restart_nat_server (void *cls,
793 793
794 794
795/** 795/**
796 * We have been notified that gnunet-nat-server has written something to stdout. 796 * We have been notified that gnunet-helper-nat-server has written something to stdout.
797 * Handle the output, then reschedule this function to be called again once 797 * Handle the output, then reschedule this function to be called again once
798 * more is available. 798 * more is available.
799 * 799 *
@@ -870,10 +870,10 @@ nat_server_read (void *cls,
870 (1 != sscanf (port_start, "%d", &port)) || 870 (1 != sscanf (port_start, "%d", &port)) ||
871 (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr)) ) 871 (-1 == inet_pton(AF_INET, mybuf, &sin_addr.sin_addr)) )
872 { 872 {
873 /* should we restart gnunet-nat-server? */ 873 /* should we restart gnunet-helper-nat-server? */
874 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 874 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
875 "nat", 875 "nat",
876 _("gnunet-nat-server generated malformed address `%s'\n"), 876 _("gnunet-helper-nat-server generated malformed address `%s'\n"),
877 mybuf); 877 mybuf);
878 h->server_read_task 878 h->server_read_task
879 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, 879 = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
@@ -886,7 +886,7 @@ nat_server_read (void *cls,
886#if DEBUG_NAT 886#if DEBUG_NAT
887 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 887 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
888 "nat", 888 "nat",
889 "gnunet-nat-server read: %s:%d\n", 889 "gnunet-helper-nat-server read: %s:%d\n",
890 mybuf, port); 890 mybuf, port);
891#endif 891#endif
892 h->reversal_callback (h->callback_cls, 892 h->reversal_callback (h->callback_cls,
@@ -901,7 +901,7 @@ nat_server_read (void *cls,
901 901
902 902
903/** 903/**
904 * Try to start the gnunet-nat-server (if it is not 904 * Try to start the gnunet-helper-nat-server (if it is not
905 * already running). 905 * already running).
906 * 906 *
907 * @param h handle to NAT 907 * @param h handle to NAT
@@ -920,14 +920,14 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h)
920 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 920 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
921 "nat" 921 "nat"
922 "Starting %s at `%s'\n", 922 "Starting %s at `%s'\n",
923 "gnunet-nat-server", 923 "gnunet-helper-nat-server",
924 h->internal_address); 924 h->internal_address);
925#endif 925#endif
926 /* Start the server process */ 926 /* Start the server process */
927 h->server_proc = GNUNET_OS_start_process (NULL, 927 h->server_proc = GNUNET_OS_start_process (NULL,
928 h->server_stdout, 928 h->server_stdout,
929 "gnunet-nat-server", 929 "gnunet-helper-nat-server",
930 "gnunet-nat-server", 930 "gnunet-helper-nat-server",
931 h->internal_address, 931 h->internal_address,
932 NULL); 932 NULL);
933 if (h->server_proc == NULL) 933 if (h->server_proc == NULL)
@@ -935,7 +935,7 @@ start_gnunet_nat_server (struct GNUNET_NAT_Handle *h)
935 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, 935 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
936 "nat", 936 "nat",
937 _("Failed to start %s\n"), 937 _("Failed to start %s\n"),
938 "gnunet-nat-server"); 938 "gnunet-helper-nat-server");
939 GNUNET_DISK_pipe_close (h->server_stdout); 939 GNUNET_DISK_pipe_close (h->server_stdout);
940 h->server_stdout = NULL; 940 h->server_stdout = NULL;
941 } 941 }
@@ -1180,20 +1180,20 @@ GNUNET_NAT_register (const struct GNUNET_CONFIGURATION_Handle *cfg,
1180 /* Test for SUID binaries */ 1180 /* Test for SUID binaries */
1181 if ( (h->behind_nat == GNUNET_YES) && 1181 if ( (h->behind_nat == GNUNET_YES) &&
1182 (GNUNET_YES == h->enable_nat_server) && 1182 (GNUNET_YES == h->enable_nat_server) &&
1183 (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-server")) ) 1183 (GNUNET_YES != check_gnunet_nat_binary("gnunet-helper-nat-server")) )
1184 { 1184 {
1185 h->enable_nat_server = GNUNET_NO; 1185 h->enable_nat_server = GNUNET_NO;
1186 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1186 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1187 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), 1187 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"),
1188 "gnunet-nat-server"); 1188 "gnunet-helper-nat-server");
1189 } 1189 }
1190 if ( (GNUNET_YES == h->enable_nat_client) && 1190 if ( (GNUNET_YES == h->enable_nat_client) &&
1191 (GNUNET_YES != check_gnunet_nat_binary("gnunet-nat-client")) ) 1191 (GNUNET_YES != check_gnunet_nat_binary("gnunet-helper-nat-client")) )
1192 { 1192 {
1193 h->enable_nat_client = GNUNET_NO; 1193 h->enable_nat_client = GNUNET_NO;
1194 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1194 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1195 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"), 1195 _("Configuration requires `%s', but binary is not installed properly (SUID bit not set). Option disabled.\n"),
1196 "gnunet-nat-client"); 1196 "gnunet-helper-nat-client");
1197 } 1197 }
1198 1198
1199 start_gnunet_nat_server (h); 1199 start_gnunet_nat_server (h);
@@ -1291,7 +1291,7 @@ GNUNET_NAT_unregister (struct GNUNET_NAT_Handle *h)
1291 1291
1292/** 1292/**
1293 * We learned about a peer (possibly behind NAT) so run the 1293 * We learned about a peer (possibly behind NAT) so run the
1294 * gnunet-nat-client to send dummy ICMP responses to cause 1294 * gnunet-helper-nat-client to send dummy ICMP responses to cause
1295 * that peer to connect to us (connection reversal). 1295 * that peer to connect to us (connection reversal).
1296 * 1296 *
1297 * @param h NAT handle for us (largely used for configuration) 1297 * @param h NAT handle for us (largely used for configuration)
@@ -1330,22 +1330,22 @@ GNUNET_NAT_run_client (struct GNUNET_NAT_Handle *h,
1330#if DEBUG_TCP_NAT 1330#if DEBUG_TCP_NAT
1331 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 1331 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1332 "nat", 1332 "nat",
1333 _("Running gnunet-nat-client %s %s %u\n"), 1333 _("Running gnunet-helper-nat-client %s %s %u\n"),
1334 h->internal_address, 1334 h->internal_address,
1335 inet4, 1335 inet4,
1336 (unsigned int) h->adv_port); 1336 (unsigned int) h->adv_port);
1337#endif 1337#endif
1338 proc = GNUNET_OS_start_process (NULL, 1338 proc = GNUNET_OS_start_process (NULL,
1339 NULL, 1339 NULL,
1340 "gnunet-nat-client", 1340 "gnunet-helper-nat-client",
1341 "gnunet-nat-client", 1341 "gnunet-helper-nat-client",
1342 h->internal_address, 1342 h->internal_address,
1343 inet4, 1343 inet4,
1344 port_as_string, 1344 port_as_string,
1345 NULL); 1345 NULL);
1346 if (NULL == proc) 1346 if (NULL == proc)
1347 return; 1347 return;
1348 /* we know that the gnunet-nat-client will terminate virtually 1348 /* we know that the gnunet-helper-nat-client will terminate virtually
1349 instantly */ 1349 instantly */
1350 GNUNET_OS_process_wait (proc); 1350 GNUNET_OS_process_wait (proc);
1351 GNUNET_OS_process_close (proc); 1351 GNUNET_OS_process_close (proc);
diff --git a/src/topology/gnunet-daemon-topology.c b/src/topology/gnunet-daemon-topology.c
index 35841567a..026297b65 100644
--- a/src/topology/gnunet-daemon-topology.c
+++ b/src/topology/gnunet-daemon-topology.c
@@ -1482,7 +1482,7 @@ main (int argc, char *const *argv)
1482 ret = (GNUNET_OK == 1482 ret = (GNUNET_OK ==
1483 GNUNET_PROGRAM_run (argc, 1483 GNUNET_PROGRAM_run (argc,
1484 argv, 1484 argv,
1485 "topology", 1485 "gnunet-daemon-topology",
1486 _("GNUnet topology control (maintaining P2P mesh and F2F constraints)"), 1486 _("GNUnet topology control (maintaining P2P mesh and F2F constraints)"),
1487 options, 1487 options,
1488 &run, NULL)) ? 0 : 1; 1488 &run, NULL)) ? 0 : 1;
diff --git a/src/transport/Makefile.am b/src/transport/Makefile.am
index 123470a65..42488c7a0 100644
--- a/src/transport/Makefile.am
+++ b/src/transport/Makefile.am
@@ -36,6 +36,14 @@ if HAVE_EXPERIMENTAL
36endif 36endif
37endif 37endif
38 38
39if LINUX
40install-exec-hook:
41 chown root:root $(bindir)/gnunet-transport-wlan-helper || true
42 chmod u+s $(bindir)/gnunet-transport-wlan-helper || true
43else
44install-exec-hook:
45endif
46
39if !MINGW 47if !MINGW
40UNIX_PLUGIN_LA = libgnunet_plugin_transport_unix.la 48UNIX_PLUGIN_LA = libgnunet_plugin_transport_unix.la
41UNIX_PLUGIN_TEST = test_transport_api_unix 49UNIX_PLUGIN_TEST = test_transport_api_unix