aboutsummaryrefslogtreecommitdiff
path: root/src/cli/vpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/vpn')
-rw-r--r--src/cli/vpn/.gitignore1
-rw-r--r--src/cli/vpn/Makefile.am22
-rw-r--r--src/cli/vpn/gnunet-vpn.c364
-rw-r--r--src/cli/vpn/meson.build13
4 files changed, 400 insertions, 0 deletions
diff --git a/src/cli/vpn/.gitignore b/src/cli/vpn/.gitignore
new file mode 100644
index 000000000..dbd75eb25
--- /dev/null
+++ b/src/cli/vpn/.gitignore
@@ -0,0 +1 @@
gnunet-vpn
diff --git a/src/cli/vpn/Makefile.am b/src/cli/vpn/Makefile.am
new file mode 100644
index 000000000..0c7c459ef
--- /dev/null
+++ b/src/cli/vpn/Makefile.am
@@ -0,0 +1,22 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include -I$(top_builddir)/src/include
3
4if USE_COVERAGE
5 AM_CFLAGS = --coverage -O0
6endif
7
8pkgcfgdir= $(pkgdatadir)/config.d/
9
10libexecdir= $(pkglibdir)/libexec/
11
12plugindir = $(libdir)/gnunet
13
14bin_PROGRAMS = \
15 gnunet-vpn
16
17gnunet_vpn_SOURCES = \
18 gnunet-vpn.c
19gnunet_vpn_LDADD = \
20 $(top_builddir)/src/service/vpn/libgnunetvpn.la \
21 $(top_builddir)/src/lib/util/libgnunetutil.la \
22 $(GN_LIBINTL)
diff --git a/src/cli/vpn/gnunet-vpn.c b/src/cli/vpn/gnunet-vpn.c
new file mode 100644
index 000000000..a67e17016
--- /dev/null
+++ b/src/cli/vpn/gnunet-vpn.c
@@ -0,0 +1,364 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file src/vpn/gnunet-vpn.c
23 * @brief Tool to manually request VPN tunnels to be created
24 * @author Christian Grothoff
25 */
26
27#include "platform.h"
28#include "gnunet_util_lib.h"
29#include "gnunet_vpn_service.h"
30
31
32/**
33 * Handle to vpn service.
34 */
35static struct GNUNET_VPN_Handle *handle;
36
37/**
38 * Opaque redirection request handle.
39 */
40static struct GNUNET_VPN_RedirectionRequest *request;
41
42/**
43 * Option -p: destination peer identity for service
44 */
45static char *peer_id;
46
47/**
48 * Option -s: service name (hash to get service descriptor)
49 */
50static char *service_name;
51
52/**
53 * Option -i: target IP
54 */
55static char *target_ip;
56
57/**
58 * Option -4: IPv4 requested.
59 */
60static int ipv4;
61
62/**
63 * Option -6: IPv6 requested.
64 */
65static int ipv6;
66
67/**
68 * Option -t: TCP requested.
69 */
70static int tcp;
71
72/**
73 * Option -u: UDP requested.
74 */
75static int udp;
76
77/**
78 * Selected level of verbosity.
79 */
80static unsigned int verbosity;
81
82/**
83 * Global return value.
84 */
85static int ret;
86
87/**
88 * Option '-d': duration of the mapping
89 */
90static struct GNUNET_TIME_Relative duration = { 5 * 60 * 1000 };
91
92
93/**
94 * Shutdown.
95 */
96static void
97do_disconnect (void *cls)
98{
99 if (NULL != request)
100 {
101 GNUNET_VPN_cancel_request (request);
102 request = NULL;
103 }
104 if (NULL != handle)
105 {
106 GNUNET_VPN_disconnect (handle);
107 handle = NULL;
108 }
109 GNUNET_free (peer_id);
110 GNUNET_free (service_name);
111 GNUNET_free (target_ip);
112}
113
114
115/**
116 * Callback invoked from the VPN service once a redirection is
117 * available. Provides the IP address that can now be used to
118 * reach the requested destination.
119 *
120 * @param cls closure
121 * @param af address family, AF_INET or AF_INET6; AF_UNSPEC on error;
122 * will match 'result_af' from the request
123 * @param address IP address (struct in_addr or struct in_addr6, depending on 'af')
124 * that the VPN allocated for the redirection;
125 * traffic to this IP will now be redirected to the
126 * specified target peer; NULL on error
127 */
128static void
129allocation_cb (void *cls, int af, const void *address)
130{
131 char buf[INET6_ADDRSTRLEN];
132
133 request = NULL;
134 switch (af)
135 {
136 case AF_INET6:
137 case AF_INET:
138 fprintf (stdout, "%s\n", inet_ntop (af, address, buf, sizeof(buf)));
139 break;
140
141 case AF_UNSPEC:
142 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _ ("Error creating tunnel\n"));
143 ret = 1;
144 break;
145
146 default:
147 break;
148 }
149 GNUNET_SCHEDULER_shutdown ();
150}
151
152
153/**
154 * Main function that will be run by the scheduler.
155 *
156 * @param cls closure
157 * @param args remaining command-line arguments
158 * @param cfgfile name of the configuration file used (for saving, can be NULL!)
159 * @param cfg configuration
160 */
161static void
162run (void *cls,
163 char *const *args,
164 const char *cfgfile,
165 const struct GNUNET_CONFIGURATION_Handle *cfg)
166{
167 int dst_af;
168 int req_af;
169 struct GNUNET_PeerIdentity peer;
170 struct GNUNET_HashCode sd;
171 const void *addr;
172 struct in_addr v4;
173 struct in6_addr v6;
174 uint8_t protocol;
175 struct GNUNET_TIME_Absolute etime;
176
177 etime = GNUNET_TIME_relative_to_absolute (duration);
178 GNUNET_SCHEDULER_add_shutdown (&do_disconnect, NULL);
179 handle = GNUNET_VPN_connect (cfg);
180 if (NULL == handle)
181 goto error;
182 req_af = AF_UNSPEC;
183 if (ipv4)
184 {
185 if (ipv6)
186 {
187 fprintf (stderr,
188 _ ("Option `%s' makes no sense with option `%s'.\n"),
189 "-4",
190 "-6");
191 goto error;
192 }
193 req_af = AF_INET;
194 }
195 if (ipv6)
196 req_af = AF_INET6;
197
198 if (NULL == target_ip)
199 {
200 if (NULL == service_name)
201 {
202 fprintf (stderr, _ ("Option `%s' or `%s' is required.\n"), "-i", "-s");
203 goto error;
204 }
205 if (NULL == peer_id)
206 {
207 fprintf (stderr,
208 _ ("Option `%s' is required when using option `%s'.\n"),
209 "-p",
210 "-s");
211 goto error;
212 }
213 if (! (tcp | udp))
214 {
215 fprintf (stderr,
216 _ ("Option `%s' or `%s' is required when using option `%s'.\n"),
217 "-t",
218 "-u",
219 "-s");
220 goto error;
221 }
222 if (tcp & udp)
223 {
224 fprintf (stderr,
225 _ ("Option `%s' makes no sense with option `%s'.\n"),
226 "-t",
227 "-u");
228 goto error;
229 }
230 if (tcp)
231 protocol = IPPROTO_TCP;
232 if (udp)
233 protocol = IPPROTO_UDP;
234 if (GNUNET_OK !=
235 GNUNET_CRYPTO_eddsa_public_key_from_string (peer_id,
236 strlen (peer_id),
237 &peer.public_key))
238 {
239 fprintf (stderr, _ ("`%s' is not a valid peer identifier.\n"), peer_id);
240 goto error;
241 }
242 GNUNET_TUN_service_name_to_hash (service_name, &sd);
243 request = GNUNET_VPN_redirect_to_peer (handle,
244 req_af,
245 protocol,
246 &peer,
247 &sd,
248 etime,
249 &allocation_cb,
250 NULL);
251 }
252 else
253 {
254 if (1 != inet_pton (AF_INET6, target_ip, &v6))
255 {
256 if (1 != inet_pton (AF_INET, target_ip, &v4))
257 {
258 fprintf (stderr, _ ("`%s' is not a valid IP address.\n"), target_ip);
259 goto error;
260 }
261 else
262 {
263 dst_af = AF_INET;
264 addr = &v4;
265 }
266 }
267 else
268 {
269 dst_af = AF_INET6;
270 addr = &v6;
271 }
272 request = GNUNET_VPN_redirect_to_ip (handle,
273 req_af,
274 dst_af,
275 addr,
276 etime,
277 &allocation_cb,
278 NULL);
279 }
280 return;
281
282error:
283 GNUNET_SCHEDULER_shutdown ();
284 ret = 1;
285}
286
287
288int
289main (int argc, char *const *argv)
290{
291 struct GNUNET_GETOPT_CommandLineOption options[] =
292 { GNUNET_GETOPT_option_flag ('4',
293 "ipv4",
294 gettext_noop (
295 "request that result should be an IPv4 address"),
296 &ipv4),
297
298 GNUNET_GETOPT_option_flag ('6',
299 "ipv6",
300 gettext_noop (
301 "request that result should be an IPv6 address"),
302 &ipv6),
303
304 GNUNET_GETOPT_option_relative_time (
305 'd',
306 "duration",
307 "TIME",
308 gettext_noop ("how long should the mapping be valid for new tunnels?"),
309 &duration),
310
311 GNUNET_GETOPT_option_string ('i',
312 "ip",
313 "IP",
314 gettext_noop (
315 "destination IP for the tunnel"),
316 &target_ip),
317
318 GNUNET_GETOPT_option_string (
319 'p',
320 "peer",
321 "PEERID",
322 gettext_noop ("peer offering the service we would like to access"),
323 &peer_id),
324
325 GNUNET_GETOPT_option_string ('s',
326 "service",
327 "NAME",
328 gettext_noop (
329 "name of the service we would like to access"),
330 &service_name),
331
332 GNUNET_GETOPT_option_flag ('t',
333 "tcp",
334 gettext_noop ("service is offered via TCP"),
335 &tcp),
336
337 GNUNET_GETOPT_option_flag ('u',
338 "udp",
339 gettext_noop ("service is offered via UDP"),
340 &udp),
341
342 GNUNET_GETOPT_option_verbose (&verbosity),
343
344 GNUNET_GETOPT_OPTION_END };
345
346 if (GNUNET_OK != GNUNET_STRINGS_get_utf8_args (argc, argv, &argc, &argv))
347 return 2;
348
349 ret =
350 (GNUNET_OK == GNUNET_PROGRAM_run (argc,
351 argv,
352 "gnunet-vpn",
353 gettext_noop ("Setup tunnels via VPN."),
354 options,
355 &run,
356 NULL))
357 ? ret
358 : 1;
359 GNUNET_free_nz ((void *) argv);
360 return ret;
361}
362
363
364/* end of gnunet-vpn.c */
diff --git a/src/cli/vpn/meson.build b/src/cli/vpn/meson.build
new file mode 100644
index 000000000..477551f1d
--- /dev/null
+++ b/src/cli/vpn/meson.build
@@ -0,0 +1,13 @@
1executable ('gnunet-vpn',
2 ['gnunet-vpn.c'],
3 dependencies: [libgnunetvpn_dep,
4 libgnunetutil_dep,
5 libgnunetstatistics_dep,
6 libgnunetregex_dep,
7 libgnunetcore_dep,
8 libgnunetcadet_dep,
9 libgnunetblock_dep],
10 include_directories: [incdir, configuration_inc, exitdir],
11 install: true,
12 install_dir: get_option('bindir'))
13