diff options
author | Jacob Appelbaum <jacob@appelbaum.net> | 2010-04-16 17:45:12 -0700 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2010-09-30 11:37:53 -0400 |
commit | 9cc76cf0053cad90d2ff55d24993d9a0ac4c0cdb (patch) | |
tree | 46bcd8f511653b52b5b7fe1348485e42b43b9fab /src/tools/tor-fw-helper/tor-fw-helper-upnp.c | |
parent | 3ad43ef75f09a21c0c1fc6eb173f8d131c7d638c (diff) | |
download | tor-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-upnp.c')
-rw-r--r-- | src/tools/tor-fw-helper/tor-fw-helper-upnp.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/tools/tor-fw-helper/tor-fw-helper-upnp.c b/src/tools/tor-fw-helper/tor-fw-helper-upnp.c new file mode 100644 index 0000000000..b471a6cd6f --- /dev/null +++ b/src/tools/tor-fw-helper/tor-fw-helper-upnp.c @@ -0,0 +1,125 @@ +/* Copyright (c) 2010, Jacob Appelbaum, Steven J. Murdoch. + * Copyright (c) 2010, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include <stdint.h> +#include <string.h> +#include <stdio.h> + +#include "tor-fw-helper.h" +#include "tor-fw-helper-upnp.h" + +#define UPNP_DISCOVER_TIMEOUT 2000 +/* Description of the port mapping in the UPnP table */ +#define UPNP_DESC "Tor relay" + +#define UPNP_ERR_SUCCESS 0 +#define UPNP_ERR_NODEVICESFOUND 1 +#define UPNP_ERR_NOIGDFOUND 2 +#define UPNP_ERR_ADDPORTMAPPING 3 +#define UPNP_ERR_GETPORTMAPPING 4 +#define UPNP_ERR_DELPORTMAPPING 5 +#define UPNP_ERR_GETEXTERNALIP 6 +#define UPNP_ERR_INVAL 7 +#define UPNP_ERR_OTHER 8 +#define UPNP_SUCCESS 1 + +int +tor_upnp_init(miniupnpc_state_t *state) +{ + struct UPNPDev *devlist; + int r; + + memset(&(state->urls), 0, sizeof(struct UPNPUrls)); + memset(&(state->data), 0, sizeof(struct IGDdatas)); + + devlist = upnpDiscover(UPNP_DISCOVER_TIMEOUT, NULL, NULL, 0); + if (NULL == devlist) { + fprintf(stderr, "E: upnpDiscover returned: NULL\n"); + return UPNP_ERR_NODEVICESFOUND; + } + + r = UPNP_GetValidIGD(devlist, &(state->urls), &(state->data), + state->lanaddr, UPNP_LANADDR_SZ); + fprintf(stdout, "tor-fw-helper: UPnP GetValidIGD returned: %d (%s)\n", r, + r==UPNP_SUCCESS?"SUCCESS":"FAILED"); + + freeUPNPDevlist(devlist); + + if (r != 1 && r != 2) + return UPNP_ERR_NOIGDFOUND; + + state->init = 1; + return UPNP_ERR_SUCCESS; +} + +int +tor_upnp_cleanup(miniupnpc_state_t *state) +{ + if (state->init) + FreeUPNPUrls(&(state->urls)); + state->init = 0; + + return UPNP_ERR_SUCCESS; +} + +int +tor_upnp_fetch_public_ip(miniupnpc_state_t *state) +{ + int r; + char externalIPAddress[16]; + + if (!state->init) { + r = tor_upnp_init(state); + if (r != UPNP_ERR_SUCCESS) + return r; + } + + r = UPNP_GetExternalIPAddress(state->urls.controlURL, + state->data.first.servicetype, + externalIPAddress); + + if (r != UPNPCOMMAND_SUCCESS) + goto err; + + if (externalIPAddress[0]) { + fprintf(stdout, "tor-fw-helper: ExternalIPAddress = %s\n", + externalIPAddress); tor_upnp_cleanup(state); + return UPNP_ERR_SUCCESS; + } else + goto err; + + err: + tor_upnp_cleanup(state); + return UPNP_ERR_GETEXTERNALIP; +} + +int +tor_upnp_add_tcp_mapping(miniupnpc_state_t *state, + uint16_t internal_port, uint16_t external_port) +{ + int r; + char internal_port_str[6]; + char external_port_str[6]; + + if (!state->init) { + r = tor_upnp_init(state); + if (r != UPNP_ERR_SUCCESS) + return r; + } + + snprintf(internal_port_str, sizeof(internal_port_str), + "%d", internal_port); + snprintf(external_port_str, sizeof(external_port_str), + "%d", external_port); + + r = UPNP_AddPortMapping(state->urls.controlURL, + state->data.first.servicetype, + external_port_str, internal_port_str, + state->lanaddr, UPNP_DESC, "TCP", 0); + if (r != UPNPCOMMAND_SUCCESS) + return UPNP_ERR_ADDPORTMAPPING; + + return UPNP_ERR_SUCCESS; +} + |