1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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;
}
|