aboutsummaryrefslogtreecommitdiff
path: root/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c
diff options
context:
space:
mode:
authorJacob Appelbaum <jacob@appelbaum.net>2010-04-16 17:45:12 -0700
committerNick Mathewson <nickm@torproject.org>2010-09-30 11:37:53 -0400
commit9cc76cf0053cad90d2ff55d24993d9a0ac4c0cdb (patch)
tree46bcd8f511653b52b5b7fe1348485e42b43b9fab /src/tools/tor-fw-helper/tor-fw-helper-natpmp.c
parent3ad43ef75f09a21c0c1fc6eb173f8d131c7d638c (diff)
downloadtor-9cc76cf0053cad90d2ff55d24993d9a0ac4c0cdb.tar.gz
tor-9cc76cf0053cad90d2ff55d24993d9a0ac4c0cdb.zip
First implementation of tor-fw-helper.
tor-fw-helper is a command-line tool to wrap and abstract various firewall port-forwarding tools. This commit matches the state of Jacob's tor-fw-helper branch as of 23 September 2010. (commit msg by Nick)
Diffstat (limited to 'src/tools/tor-fw-helper/tor-fw-helper-natpmp.c')
-rw-r--r--src/tools/tor-fw-helper/tor-fw-helper-natpmp.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c b/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c
new file mode 100644
index 0000000000..ebcd9e61ad
--- /dev/null
+++ b/src/tools/tor-fw-helper/tor-fw-helper-natpmp.c
@@ -0,0 +1,142 @@
+/* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch.
+ * Copyright (c) 2010, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <arpa/inet.h>
+
+#include "tor-fw-helper.h"
+#include "tor-fw-helper-natpmp.h"
+
+int
+tor_natpmp_add_tcp_mapping(tor_fw_options_t *tor_fw_options)
+{
+ int r = 0;
+ int x = 0;
+ int sav_errno;
+ int protocol = NATPMP_PROTOCOL_TCP;
+ int lease = NATPMP_DEFAULT_LEASE;
+ natpmp_t natpmp;
+ natpmpresp_t response;
+
+ fd_set fds;
+ struct timeval timeout;
+
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: natpmp init...\n");
+ initnatpmp(&natpmp);
+
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: sending natpmp portmapping request...\n");
+ r = sendnewportmappingrequest(&natpmp, protocol,
+ tor_fw_options->internal_port,
+ tor_fw_options->external_port,
+ lease);
+ fprintf(stdout, "tor-fw-helper: NAT-PMP sendnewportmappingrequest returned"
+ " %d (%s)\n", r, r==12?"SUCCESS":"FAILED");
+
+ do {
+ FD_ZERO(&fds);
+ FD_SET(natpmp.s, &fds);
+ getnatpmprequesttimeout(&natpmp, &timeout);
+ select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: attempting to readnatpmpreponseorretry...\n");
+ r = readnatpmpresponseorretry(&natpmp, &response);
+ sav_errno = errno;
+
+ if (r<0 && r!=NATPMP_TRYAGAIN)
+ {
+ fprintf(stderr, "E: readnatpmpresponseorretry failed %d\n", r);
+ fprintf(stderr, "E: errno=%d '%s'\n", sav_errno,
+ strerror(sav_errno));
+ }
+
+ } while ( r == NATPMP_TRYAGAIN );
+
+ if (r == NATPMP_SUCCESS) {
+ fprintf(stdout, "tor-fw-helper: NAT-PMP mapped public port %hu to"
+ " localport %hu liftime %u\n",
+ response.pnu.newportmapping.mappedpublicport,
+ response.pnu.newportmapping.privateport,
+ response.pnu.newportmapping.lifetime);
+ }
+
+ x = closenatpmp(&natpmp);
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: closing natpmp socket: %d\n", x);
+ return r;
+}
+
+int
+tor_natpmp_fetch_public_ip(tor_fw_options_t *tor_fw_options)
+{
+ int r = 0;
+ int x = 0;
+ int sav_errno;
+ natpmp_t natpmp;
+ natpmpresp_t response;
+ struct timeval timeout;
+ fd_set fds;
+
+ r = initnatpmp(&natpmp);
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: NAT-PMP init: %d\n", r);
+
+ r = sendpublicaddressrequest(&natpmp);
+ fprintf(stdout, "tor-fw-helper: NAT-PMP sendpublicaddressrequest returned"
+ " %d (%s)\n", r, r==2?"SUCCESS":"FAILED");
+
+ do {
+ FD_ZERO(&fds);
+ FD_SET(natpmp.s, &fds);
+ getnatpmprequesttimeout(&natpmp, &timeout);
+ select(FD_SETSIZE, &fds, NULL, NULL, &timeout);
+
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: NAT-PMP attempting to read reponse...\n");
+ r = readnatpmpresponseorretry(&natpmp, &response);
+ sav_errno = errno;
+
+ if (tor_fw_options->verbose)
+ fprintf(stdout, "V: NAT-PMP readnatpmpresponseorretry returned"
+ " %d\n", r);
+
+ if ( r < 0 && r != NATPMP_TRYAGAIN)
+ {
+ fprintf(stderr, "E: NAT-PMP readnatpmpresponseorretry failed %d\n",
+ r);
+ fprintf(stderr, "E: NAT-PMP errno=%d '%s'\n", sav_errno,
+ strerror(sav_errno));
+ }
+
+ } while ( r == NATPMP_TRYAGAIN );
+
+ if (r != 0)
+ {
+ fprintf(stderr, "E: NAT-PMP It appears that something went wrong:"
+ " %d\n", r);
+ return r;
+ }
+
+ fprintf(stdout, "tor-fw-helper: ExternalIPAddress = %s\n",
+ inet_ntoa(response.pnu.publicaddress.addr));
+
+ x = closenatpmp(&natpmp);
+
+ if (tor_fw_options->verbose)
+ {
+ fprintf(stdout, "V: result = %u\n", r);
+ fprintf(stdout, "V: type = %u\n", response.type);
+ fprintf(stdout, "V: resultcode = %u\n", response.resultcode);
+ fprintf(stdout, "V: epoch = %u\n", response.epoch);
+ fprintf(stdout, "V: closing natpmp result: %d\n", r);
+ }
+
+ return r;
+}
+