1 /*
2 * relayd.c - Miredo: binding between libtun6 and libteredo
3 */
4
5 /***********************************************************************
6 * Copyright © 2004-2007 Rémi Denis-Courmont. *
7 * This program is free software; you can redistribute and/or modify *
8 * it under the terms of the GNU General Public License as published *
9 * by the Free Software Foundation; version 2 of the license, or (at *
10 * your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
15 * See the GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, you can get it from: *
19 * http://www.gnu.org/copyleft/gpl.html *
20 ***********************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <assert.h>
27 #include <gettext.h>
28
29 #include <inttypes.h>
30 #include <stdlib.h> // free()
31 #include <stdio.h> // fputs()
32 #include <sys/types.h>
33 #include <string.h> // strcasecmp()
34 #include <errno.h>
35 #include <unistd.h> // close()
36 #include <fcntl.h>
37 #include <sys/wait.h> // wait()
38 #include <signal.h> // sigemptyset()
39 #include <syslog.h>
40 #include <pthread.h>
41
42 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <netinet/ip6.h>
45 #include <netinet/icmp6.h>
46 #include <arpa/inet.h> // inet_ntop()
47 #include <netdb.h> // NI_MAXHOST
48 #ifdef HAVE_SYS_CAPABILITY_H
49 # include <sys/capability.h>
50 #endif
51 #ifndef SOL_IPV6
52 # define SOL_IPV6 IPPROTO_IPV6
53 #endif
54 #ifndef SOL_ICMPV6
55 # define SOL_ICMPV6 IPPROTO_ICMPV6
56 #endif
57 #ifndef PF_LOCAL
58 # define PF_LOCAL PF_UNIX
59 #endif
60
61 #include <libtun6/tun6.h>
62
63 #include <libteredo/teredo.h>
64 #include <libteredo/tunnel.h>
65
66 #include "privproc.h"
67 #include "miredo.h"
68 #include "conf.h"
69
70 static void miredo_setup_fd (int fd);
71 static void miredo_setup_nonblock_fd (int fd);
72
relay_diagnose(void)73 static int relay_diagnose (void)
74 {
75 char errbuf[LIBTUN6_ERRBUF_SIZE];
76 if (tun6_driver_diagnose (errbuf))
77 {
78 fputs (errbuf, stderr);
79 return -1;
80 }
81
82 return 0;
83 }
84
85
86 typedef struct miredo_tunnel
87 {
88 tun6 *tunnel;
89 int priv_fd;
90 teredo_tunnel *relay;
91 } miredo_tunnel;
92
93 static int icmp6_fd = -1;
94
miredo_init(bool client)95 static int miredo_init (bool client)
96 {
97 if (teredo_startup (client))
98 return -1;
99
100 assert (icmp6_fd == -1);
101
102 icmp6_fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
103 if (icmp6_fd == -1)
104 return -1;
105
106 miredo_setup_nonblock_fd (icmp6_fd);
107
108 setsockopt (icmp6_fd, SOL_IPV6, IPV6_CHECKSUM, &(int){2}, sizeof (int));
109
110 /* We don't use the socket for receive -> block all */
111 struct icmp6_filter filt;
112 ICMP6_FILTER_SETBLOCKALL (&filt);
113 setsockopt (icmp6_fd, SOL_ICMPV6, ICMP6_FILTER, &filt, sizeof (filt));
114 return 0;
115 }
116
117
miredo_deinit(bool client)118 static void miredo_deinit (bool client)
119 {
120 assert (icmp6_fd != -1);
121 close (icmp6_fd);
122 teredo_cleanup (client);
123 }
124
125
126 /**
127 * Callback to transmit decapsulated Teredo IPv6 packets to the kernel.
128 */
129 static void
miredo_recv_callback(void * data,const void * packet,size_t length)130 miredo_recv_callback (void *data, const void *packet, size_t length)
131 {
132 assert (data != NULL);
133
134 (void)tun6_send (((miredo_tunnel *)data)->tunnel, packet, length);
135 }
136
137
138 /**
139 * Callback to emit an ICMPv6 error message through a raw ICMPv6 socket.
140 */
141 static void
miredo_icmp6_callback(void * data,const void * packet,size_t length,const struct in6_addr * dst)142 miredo_icmp6_callback (void *data, const void *packet, size_t length,
143 const struct in6_addr *dst)
144 {
145 (void)data;
146 assert (icmp6_fd != -1);
147
148 struct sockaddr_in6 addr =
149 {
150 .sin6_family = AF_INET6,
151 #ifdef HAVE_SA_LEN
152 .sin6_len = sizeof (struct sockaddr_in6),
153 #endif
154 .sin6_addr = *dst
155 };
156
157 /* TODO: use sendmsg and don't memcpy in BuildICMPv6Error */
158 (void)sendto (icmp6_fd, packet, length, 0,
159 (struct sockaddr *)&addr, sizeof (addr));
160 }
161
162
163 #define TEREDO_CONE 0
164 #define TEREDO_RESTRICT 1
165 #define TEREDO_CLIENT 2
166
167 static bool
ParseRelayType(miredo_conf * conf,const char * name,int * type)168 ParseRelayType (miredo_conf *conf, const char *name, int *type)
169 {
170 unsigned line;
171 char *val = miredo_conf_get (conf, name, &line);
172
173 if (val == NULL)
174 return true;
175
176 if ((strcasecmp (val, "client") == 0)
177 || (strcasecmp (val, "autoclient") == 0))
178 *type = TEREDO_CLIENT;
179 else
180 if (strcasecmp (val, "restricted") == 0)
181 {
182 syslog (LOG_WARNING, _("Using deprecated \"restricted\" relay type "
183 "which is STRONGLY DISCOURAGED (at line %u)."), line);
184 *type = TEREDO_RESTRICT;
185 }
186 else
187 if ((strcasecmp (val, "relay") == 0)
188 || (strcasecmp (val, "cone") == 0))
189 *type = TEREDO_CONE;
190 else
191 {
192 syslog (LOG_ERR, _("Invalid relay type \"%s\" at line %u"),
193 val, line);
194 free (val);
195 return false;
196 }
197 free (val);
198 return true;
199 }
200
201
202 #ifdef MIREDO_TEREDO_CLIENT
203 static tun6 *
create_dynamic_tunnel(const char * ifname,int * pfd)204 create_dynamic_tunnel (const char *ifname, int *pfd)
205 {
206 tun6 *tunnel = tun6_create (ifname);
207 if (tunnel == NULL)
208 return NULL;
209
210 int fd[2];
211 if (socketpair (PF_LOCAL, SOCK_STREAM, 0, fd))
212 goto error;
213
214 miredo_setup_fd (fd[0]);
215 miredo_setup_fd (fd[1]);
216
217 char ifindex[2 * sizeof (unsigned) + 1];
218 snprintf (ifindex, sizeof (ifindex), "%X", tun6_getId (tunnel));
219
220 static const char path[] = PKGLIBEXECDIR"/miredo-privproc";
221 switch (fork ())
222 {
223 case -1:
224 close (fd[0]);
225 close (fd[1]);
226 goto error;
227
228 case 0:
229 if (dup2 (fd[0], 0) == 0 && dup2 (fd[0], 1) == 1)
230 execl (path, path, ifindex, (char *)NULL);
231
232 syslog (LOG_ERR, _("Could not execute %s: %m"), path);
233 exit (1);
234 }
235 close (fd[0]);
236 *pfd = fd[1];
237 return tunnel;
238 error:
239 tun6_destroy (tunnel);
240 return NULL;
241 }
242
243
244 static int
configure_tunnel(int fd,const struct in6_addr * addr,unsigned mtu)245 configure_tunnel (int fd, const struct in6_addr *addr, unsigned mtu)
246 {
247 struct miredo_tunnel_settings s;
248 int res;
249
250 if (mtu > 65535)
251 {
252 errno = EINVAL;
253 return -1;
254 }
255
256 memset (&s, 0, sizeof (s));
257 memcpy (&s.addr, addr, sizeof (s.addr));
258 s.mtu = (uint16_t)mtu;
259
260 if ((send (fd, &s, sizeof (s), MSG_NOSIGNAL) != sizeof (s))
261 || (recv (fd, &res, sizeof (res), MSG_WAITALL) != sizeof (res)))
262 return -1;
263
264 return res;
265 }
266
267
268 static void
destroy_dynamic_tunnel(tun6 * tunnel,int fd)269 destroy_dynamic_tunnel (tun6 *tunnel, int fd)
270 {
271 assert (fd != -1);
272 close (fd);
273
274 wait (NULL); // wait for privsep process
275
276 tun6_destroy (tunnel);
277 }
278
279
280 /**
281 * Callback to configure a Teredo tunneling interface.
282 */
283 static void
miredo_up_callback(void * data,const struct in6_addr * addr,uint16_t mtu)284 miredo_up_callback (void *data, const struct in6_addr *addr, uint16_t mtu)
285 {
286 char str[INET6_ADDRSTRLEN];
287
288 syslog (LOG_NOTICE, _("Teredo pseudo-tunnel started"));
289 if (inet_ntop (AF_INET6, addr, str, sizeof (str)) != NULL)
290 syslog (LOG_INFO, _(" (address: %s, MTU: %"PRIu16")"),
291 str, mtu);
292
293 assert (data != NULL);
294
295 configure_tunnel (((miredo_tunnel *)data)->priv_fd, addr, mtu);
296 }
297
298
299 /**
300 * Callback to deconfigure a Teredo tunneling interface.
301 */
302 static void
miredo_down_callback(void * data)303 miredo_down_callback (void *data)
304 {
305 assert (data != NULL);
306
307 configure_tunnel (((miredo_tunnel *)data)->priv_fd, &in6addr_any,
308 1280);
309 syslog (LOG_NOTICE, _("Teredo pseudo-tunnel stopped"));
310 }
311
312
313 static int
setup_client(teredo_tunnel * client,const char * server,const char * server2)314 setup_client (teredo_tunnel *client, const char *server, const char *server2)
315 {
316 teredo_set_state_cb (client, miredo_up_callback, miredo_down_callback);
317 return teredo_set_client_mode (client, server, server2);
318 }
319 #else
320 # define create_dynamic_tunnel( a, b ) NULL
321 # define destroy_dynamic_tunnel( a, b ) (void)0
322 # define setup_client( a, b, c ) (-1)
323 #endif
324
325
326 static tun6 *
create_static_tunnel(const char * restrict ifname,const struct in6_addr * restrict prefix,uint16_t mtu)327 create_static_tunnel (const char *restrict ifname,
328 const struct in6_addr *restrict prefix,
329 uint16_t mtu)
330 {
331 tun6 *tunnel = tun6_create (ifname);
332
333 if ((tunnel == NULL) && (ifname != NULL) && (errno == ENOSYS))
334 tunnel = tun6_create (NULL);
335 if (tunnel == NULL)
336 return NULL;
337
338 if (tun6_setMTU (tunnel, mtu) || tun6_bringUp (tunnel)
339 || tun6_addAddress (tunnel, &teredo_restrict, 64)
340 || tun6_addRoute (tunnel, prefix, 32, 0))
341 {
342 tun6_destroy (tunnel);
343 return NULL;
344 }
345 return tunnel;
346 }
347
348
349 #if 0 && !defined (MIREDO_DEFAULT_USERNAME)
350 static void
351 destroy_static_tunnel (tun6 *restrict tunnel,
352 const struct in6_addr *restrict prefix)
353 {
354 /*
355 * Manual clean up of the tunnel device is only possible if we retain root
356 * privileges. Unfortunately, if we don't do this, it becomes impossible
357 * to restart Miredo on FreeBSD. The proper fix belongs in the FreeBSD
358 * kernel - that's the only way to handle kills (or would-be crashes) of
359 * Miredo; that's part of the standard job of a solid kernel process
360 * killer.
361 */
362 tun6_delRoute (tunnel, prefix, 32, 0);
363 tun6_delAddress (tunnel, &teredo_restrict, 64);
364 tun6_bringDown (tunnel);
365 tun6_destroy (tunnel);
366 }
367 #else
368 # define destroy_static_tunnel( t, p ) tun6_destroy( t )
369 #endif
370
371
372 static int
setup_relay(teredo_tunnel * relay,uint32_t prefix,bool cone)373 setup_relay (teredo_tunnel *relay, uint32_t prefix, bool cone)
374 {
375 teredo_set_prefix (relay, prefix);
376 teredo_set_cone_flag (relay, cone);
377 return teredo_set_relay_mode (relay);
378 }
379
380
381 /**
382 * Thread to encapsulate IPv6 packets into UDP.
383 * Cancellation safe.
384 */
miredo_encap_thread(void * d)385 static LIBTEREDO_NORETURN void *miredo_encap_thread (void *d)
386 {
387 teredo_tunnel *relay = ((miredo_tunnel *)d)->relay;
388 tun6 *tunnel = ((miredo_tunnel *)d)->tunnel;
389
390 for (;;)
391 {
392 /* Handle incoming data */
393 struct
394 {
395 struct ip6_hdr ip6;
396 uint8_t fill[65467];
397 } pbuf;
398
399 /* Forwards IPv6 packet to Teredo
400 * (Packet transmission) */
401 int val = tun6_wait_recv (tunnel, &pbuf.ip6, sizeof (pbuf));
402 if (val >= 40)
403 {
404 pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL);
405 teredo_transmit (relay, &pbuf.ip6, val);
406 pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL);
407 }
408 else
409 pthread_testcancel ();
410 }
411 }
412
413
414 /**
415 * Miredo main daemon function, with UDP datagrams and IPv6 packets
416 * receive loop.
417 */
418 static int
run_tunnel(miredo_tunnel * tunnel)419 run_tunnel (miredo_tunnel *tunnel)
420 {
421 pthread_t encap_th;
422 if (teredo_run_async (tunnel->relay)
423 || pthread_create (&encap_th, NULL, miredo_encap_thread, tunnel))
424 return -1;
425
426 sigset_t dummyset, set;
427 sigemptyset (&dummyset);
428 pthread_sigmask (SIG_BLOCK, &dummyset, &set);
429 while (sigwait (&set, &(int){ 0 }));
430
431 pthread_cancel (encap_th);
432 pthread_join (encap_th, NULL);
433 return 0;
434 }
435
436
437 static int
relay_run(miredo_conf * conf,const char * server_name)438 relay_run (miredo_conf *conf, const char *server_name)
439 {
440 /*
441 * CONFIGURATION
442 */
443 union teredo_addr prefix;
444 memset (&prefix, 0, sizeof (prefix));
445 prefix.teredo.prefix = htonl (TEREDO_PREFIX);
446
447 int mode = TEREDO_CLIENT;
448 if (!ParseRelayType (conf, "RelayType", &mode))
449 {
450 syslog (LOG_ALERT, _("Fatal configuration error"));
451 return -2;
452 }
453
454 #ifdef MIREDO_TEREDO_CLIENT
455 const char *server_name2 = NULL;
456 char namebuf[NI_MAXHOST], namebuf2[NI_MAXHOST];
457 #endif
458 uint16_t mtu = 1280;
459 bool cone = false;
460
461 if (mode & TEREDO_CLIENT)
462 {
463 #ifdef MIREDO_TEREDO_CLIENT
464 if (server_name == NULL)
465 {
466 char *name = miredo_conf_get (conf, "ServerAddress", NULL);
467 if (name == NULL)
468 {
469 syslog (LOG_ALERT, _("Server address not specified"));
470 syslog (LOG_ALERT, _("Fatal configuration error"));
471 return -2;
472 }
473 strlcpy (namebuf, name, sizeof (namebuf));
474 free (name);
475 server_name = namebuf;
476
477 name = miredo_conf_get (conf, "ServerAddress2", NULL);
478 if (name != NULL)
479 {
480 strlcpy (namebuf2, name, sizeof (namebuf2));
481 free (name);
482 server_name2 = namebuf2;
483 }
484 }
485 #else
486 syslog (LOG_ALERT, _("Unsupported Teredo client mode"));
487 syslog (LOG_ALERT, _("Fatal configuration error"));
488 return -2;
489 #endif
490 }
491 else
492 {
493 server_name = NULL;
494 mtu = 1280;
495 cone = (mode == TEREDO_CONE);
496
497 if (!miredo_conf_parse_teredo_prefix (conf, "Prefix",
498 &prefix.teredo.prefix)
499 || !miredo_conf_get_int16 (conf, "InterfaceMTU", &mtu, NULL))
500 {
501 syslog (LOG_ALERT, _("Fatal configuration error"));
502 return -2;
503 }
504 }
505
506 uint32_t bind_ip = INADDR_ANY;
507 uint16_t bind_port =
508 #if 0
509 /*
510 * We use 3545 as a Teredo service port.
511 * It is better to use a fixed port number for the
512 * purpose of firewalling, rather than a pseudo-random
513 * one (all the more as it might be a "dangerous"
514 * often firewalled port, such as 1214 as it happened
515 * to me once).
516 */
517 IPPORT_TEREDO + 1;
518 #else
519 0;
520 #endif
521
522 if (!miredo_conf_parse_IPv4 (conf, "BindAddress", &bind_ip)
523 || !miredo_conf_get_int16 (conf, "BindPort", &bind_port, NULL))
524 {
525 syslog (LOG_ALERT, _("Fatal configuration error"));
526 return -2;
527 }
528
529 bind_port = htons (bind_port);
530
531 char *ifname = miredo_conf_get (conf, "InterfaceName", NULL);
532
533 miredo_conf_clear (conf, 5);
534
535 /*
536 * SETUP
537 */
538
539 // Tunneling interface initialization
540 int privfd = -1;
541 tun6 *tunnel = (mode & TEREDO_CLIENT)
542 ? create_dynamic_tunnel (ifname, &privfd)
543 : create_static_tunnel (ifname, &prefix.ip6, mtu);
544
545 if (ifname != NULL)
546 free (ifname);
547
548 int retval = -1;
549
550 if (tunnel == NULL)
551 {
552 syslog (LOG_ALERT, _("Miredo setup failure: %s"),
553 _("Cannot create IPv6 tunnel"));
554 return -1;
555 }
556
557 if (miredo_init ((mode & TEREDO_CLIENT) != 0))
558 syslog (LOG_ALERT, _("Miredo setup failure: %s"),
559 _("libteredo cannot be initialized"));
560 else
561 {
562 if (drop_privileges () == 0)
563 {
564 teredo_tunnel *relay = teredo_create (bind_ip, bind_port);
565 if (relay != NULL)
566 {
567 miredo_tunnel data = { tunnel, privfd, relay };
568 teredo_set_privdata (relay, &data);
569 teredo_set_recv_callback (relay, miredo_recv_callback);
570 teredo_set_icmpv6_callback (relay, miredo_icmp6_callback);
571
572 retval = (mode & TEREDO_CLIENT)
573 ? setup_client (relay, server_name, server_name2)
574 : setup_relay (relay, prefix.teredo.prefix, cone);
575
576 /*
577 * RUN
578 */
579 if (retval == 0)
580 retval = run_tunnel (&data);
581 teredo_destroy (relay);
582 }
583
584 if (retval)
585 syslog (LOG_ALERT, _("Miredo setup failure: %s"),
586 _("libteredo cannot be initialized"));
587 }
588 miredo_deinit ((mode & TEREDO_CLIENT) != 0);
589 }
590
591 if (mode & TEREDO_CLIENT)
592 destroy_dynamic_tunnel (tunnel, privfd);
593 else
594 destroy_static_tunnel (tunnel, &prefix.ip6);
595
596 return retval;
597 }
598
599
miredo_setup_fd(int fd)600 static void miredo_setup_fd (int fd)
601 {
602 (void) fcntl (fd, F_SETFD, FD_CLOEXEC);
603 }
604
605
miredo_setup_nonblock_fd(int fd)606 static void miredo_setup_nonblock_fd (int fd)
607 {
608 int flags = fcntl (fd, F_GETFL);
609 if (flags == -1)
610 flags = 0;
611 (void) fcntl (fd, F_SETFL, O_NONBLOCK | flags);
612 miredo_setup_fd (fd);
613 }
614
615
main(int argc,char * argv[])616 int main (int argc, char *argv[])
617 {
618 #ifdef HAVE_LIBCAP
619 static const cap_value_t capv[] =
620 {
621 CAP_NET_ADMIN, /* required by libtun6 */
622 CAP_NET_RAW /* required for raw ICMPv6 socket */
623 };
624
625 miredo_capv = capv;
626 miredo_capc = sizeof (capv) / sizeof (capv[0]);
627 #endif
628
629 miredo_name = "miredo";
630 miredo_diagnose = relay_diagnose;
631 miredo_run = relay_run;
632
633 return miredo_main (argc, argv);
634 }
635
636