Lines 56-68
Link Here
|
56 |
const in_addr_t ip, |
56 |
const in_addr_t ip, |
57 |
const in_addr_t netmask, |
57 |
const in_addr_t netmask, |
58 |
const unsigned int flags); |
58 |
const unsigned int flags); |
|
|
59 |
static void netsh_command (const struct argv *a, int n); |
59 |
|
60 |
|
60 |
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc); |
61 |
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc); |
61 |
|
62 |
|
62 |
#endif |
63 |
#endif |
63 |
|
64 |
|
64 |
#ifdef TARGET_SOLARIS |
65 |
#ifdef TARGET_SOLARIS |
65 |
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual); |
66 |
static void solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual, bool unplumb_inet6); |
66 |
#include <stropts.h> |
67 |
#include <stropts.h> |
67 |
#endif |
68 |
#endif |
68 |
|
69 |
|
Lines 129-158
Link Here
|
129 |
return dev; |
130 |
return dev; |
130 |
} |
131 |
} |
131 |
|
132 |
|
132 |
/* |
|
|
133 |
* Called by the open_tun function of OSes to check if we |
134 |
* explicitly support IPv6. |
135 |
* |
136 |
* In this context, explicit means that the OS expects us to |
137 |
* do something special to the tun socket in order to support |
138 |
* IPv6, i.e. it is not transparent. |
139 |
* |
140 |
* ipv6_explicitly_supported should be set to false if we don't |
141 |
* have any explicit IPv6 code in the tun device handler. |
142 |
* |
143 |
* If ipv6_explicitly_supported is true, then we have explicit |
144 |
* OS-specific tun dev code for handling IPv6. If so, tt->ipv6 |
145 |
* is set according to the --tun-ipv6 command line option. |
146 |
*/ |
147 |
static void |
148 |
ipv6_support (bool ipv6, bool ipv6_explicitly_supported, struct tuntap* tt) |
149 |
{ |
150 |
tt->ipv6 = false; |
151 |
if (ipv6_explicitly_supported) |
152 |
tt->ipv6 = ipv6; |
153 |
else if (ipv6) |
154 |
msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS"); |
155 |
} |
156 |
|
133 |
|
157 |
/* --ifconfig-nowarn disables some options sanity checking */ |
134 |
/* --ifconfig-nowarn disables some options sanity checking */ |
158 |
static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)"; |
135 |
static const char ifconfig_warn_how_to_silence[] = "(silence this warning with --ifconfig-nowarn)"; |
Lines 423-428
Link Here
|
423 |
int topology, /* one of the TOP_x values */ |
400 |
int topology, /* one of the TOP_x values */ |
424 |
const char *ifconfig_local_parm, /* --ifconfig parm 1 */ |
401 |
const char *ifconfig_local_parm, /* --ifconfig parm 1 */ |
425 |
const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ |
402 |
const char *ifconfig_remote_netmask_parm, /* --ifconfig parm 2 */ |
|
|
403 |
const char *ifconfig_ipv6_local_parm, /* --ifconfig parm 1 IPv6 */ |
404 |
const char *ifconfig_ipv6_remote_parm, /* --ifconfig parm 2 IPv6 */ |
426 |
in_addr_t local_public, |
405 |
in_addr_t local_public, |
427 |
in_addr_t remote_public, |
406 |
in_addr_t remote_public, |
428 |
const bool strict_warn, |
407 |
const bool strict_warn, |
Lines 537-542
Link Here
|
537 |
|
516 |
|
538 |
tt->did_ifconfig_setup = true; |
517 |
tt->did_ifconfig_setup = true; |
539 |
} |
518 |
} |
|
|
519 |
|
520 |
if (ifconfig_ipv6_local_parm && ifconfig_ipv6_remote_parm) |
521 |
{ |
522 |
const char *ifconfig_ipv6_local = NULL; |
523 |
const char *ifconfig_ipv6_remote = NULL; |
524 |
|
525 |
/* |
526 |
* Convert arguments to binary IPv6 addresses. |
527 |
*/ |
528 |
|
529 |
if ( inet_pton( AF_INET6, ifconfig_ipv6_local_parm, &tt->local_ipv6 ) != 1 || |
530 |
inet_pton( AF_INET6, ifconfig_ipv6_remote_parm, &tt->remote_ipv6 ) != 1 ) |
531 |
{ |
532 |
msg( M_FATAL, "init_tun: problem converting IPv6 ifconfig addresses %s and %s to binary", ifconfig_ipv6_local_parm, ifconfig_ipv6_remote_parm ); |
533 |
} |
534 |
tt->netbits_ipv6 = 64; |
535 |
|
536 |
/* |
537 |
* Set ifconfig parameters |
538 |
*/ |
539 |
ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc); |
540 |
ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc); |
541 |
|
542 |
/* |
543 |
* Set environmental variables with ifconfig parameters. |
544 |
*/ |
545 |
if (es) |
546 |
{ |
547 |
setenv_str (es, "ifconfig_ipv6_local", ifconfig_ipv6_local); |
548 |
setenv_str (es, "ifconfig_ipv6_remote", ifconfig_ipv6_remote); |
549 |
} |
550 |
tt->did_ifconfig_ipv6_setup = true; |
551 |
} |
552 |
|
540 |
gc_free (&gc); |
553 |
gc_free (&gc); |
541 |
return tt; |
554 |
return tt; |
542 |
} |
555 |
} |
Lines 559-564
Link Here
|
559 |
#endif |
572 |
#endif |
560 |
} |
573 |
} |
561 |
|
574 |
|
|
|
575 |
#if defined(TARGET_WIN32) || \ |
576 |
defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) |
577 |
|
578 |
/* some of the platforms will auto-add a "network route" pointing |
579 |
* to the interface on "ifconfig tunX 2001:db8::1/64", others need |
580 |
* an extra call to "route add..." |
581 |
* -> helper function to simplify code below |
582 |
*/ |
583 |
void add_route_connected_v6_net(struct tuntap * tt, |
584 |
const struct env_set *es) |
585 |
{ |
586 |
struct route_ipv6 r6; |
587 |
|
588 |
r6.defined = true; |
589 |
r6.network = tt->local_ipv6; |
590 |
r6.netbits = tt->netbits_ipv6; |
591 |
r6.gateway = tt->local_ipv6; |
592 |
add_route_ipv6 (&r6, tt, 0, es); |
593 |
} |
594 |
|
595 |
void delete_route_connected_v6_net(struct tuntap * tt, |
596 |
const struct env_set *es) |
597 |
{ |
598 |
struct route_ipv6 r6; |
599 |
|
600 |
r6.defined = true; |
601 |
r6.network = tt->local_ipv6; |
602 |
r6.netbits = tt->netbits_ipv6; |
603 |
r6.gateway = tt->local_ipv6; |
604 |
delete_route_ipv6 (&r6, tt, 0, es); |
605 |
} |
606 |
#endif |
607 |
|
608 |
|
562 |
/* execute the ifconfig command through the shell */ |
609 |
/* execute the ifconfig command through the shell */ |
563 |
void |
610 |
void |
564 |
do_ifconfig (struct tuntap *tt, |
611 |
do_ifconfig (struct tuntap *tt, |
Lines 574-583
Link Here
|
574 |
const char *ifconfig_local = NULL; |
621 |
const char *ifconfig_local = NULL; |
575 |
const char *ifconfig_remote_netmask = NULL; |
622 |
const char *ifconfig_remote_netmask = NULL; |
576 |
const char *ifconfig_broadcast = NULL; |
623 |
const char *ifconfig_broadcast = NULL; |
|
|
624 |
const char *ifconfig_ipv6_local = NULL; |
625 |
const char *ifconfig_ipv6_remote = NULL; |
626 |
bool do_ipv6 = false; |
577 |
struct argv argv; |
627 |
struct argv argv; |
578 |
|
628 |
|
579 |
argv_init (&argv); |
629 |
argv_init (&argv); |
580 |
|
630 |
|
|
|
631 |
msg( M_INFO, "do_ifconfig, tt->ipv6=%d, tt->did_ifconfig_ipv6_setup=%d", |
632 |
tt->ipv6, tt->did_ifconfig_ipv6_setup ); |
633 |
|
581 |
/* |
634 |
/* |
582 |
* We only handle TUN/TAP devices here, not --dev null devices. |
635 |
* We only handle TUN/TAP devices here, not --dev null devices. |
583 |
*/ |
636 |
*/ |
Lines 589-594
Link Here
|
589 |
ifconfig_local = print_in_addr_t (tt->local, 0, &gc); |
642 |
ifconfig_local = print_in_addr_t (tt->local, 0, &gc); |
590 |
ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc); |
643 |
ifconfig_remote_netmask = print_in_addr_t (tt->remote_netmask, 0, &gc); |
591 |
|
644 |
|
|
|
645 |
if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) |
646 |
{ |
647 |
ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc); |
648 |
ifconfig_ipv6_remote = print_in6_addr (tt->remote_ipv6, 0, &gc); |
649 |
do_ipv6 = true; |
650 |
} |
651 |
|
592 |
/* |
652 |
/* |
593 |
* If TAP-style device, generate broadcast address. |
653 |
* If TAP-style device, generate broadcast address. |
594 |
*/ |
654 |
*/ |
Lines 647-653
Link Here
|
647 |
argv_msg (M_INFO, &argv); |
707 |
argv_msg (M_INFO, &argv); |
648 |
openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed"); |
708 |
openvpn_execve_check (&argv, es, S_FATAL, "Linux ip addr add failed"); |
649 |
} |
709 |
} |
650 |
tt->did_ifconfig = true; |
710 |
if ( do_ipv6 ) |
|
|
711 |
{ |
712 |
argv_printf( &argv, |
713 |
"%s -6 addr add %s/%d dev %s", |
714 |
iproute_path, |
715 |
ifconfig_ipv6_local, |
716 |
tt->netbits_ipv6, |
717 |
actual |
718 |
); |
719 |
argv_msg (M_INFO, &argv); |
720 |
openvpn_execve_check (&argv, es, S_FATAL, "Linux ip -6 addr add failed"); |
721 |
} |
722 |
tt->did_ifconfig = true; |
651 |
#else |
723 |
#else |
652 |
if (tun) |
724 |
if (tun) |
653 |
argv_printf (&argv, |
725 |
argv_printf (&argv, |
Lines 670-675
Link Here
|
670 |
); |
742 |
); |
671 |
argv_msg (M_INFO, &argv); |
743 |
argv_msg (M_INFO, &argv); |
672 |
openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed"); |
744 |
openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig failed"); |
|
|
745 |
if ( do_ipv6 ) |
746 |
{ |
747 |
argv_printf (&argv, |
748 |
"%s %s inet6 add %s/%d", |
749 |
IFCONFIG_PATH, |
750 |
actual, |
751 |
ifconfig_ipv6_local, |
752 |
tt->netbits_ipv6 |
753 |
); |
754 |
argv_msg (M_INFO, &argv); |
755 |
openvpn_execve_check (&argv, es, S_FATAL, "Linux ifconfig inet6 failed"); |
756 |
} |
673 |
tt->did_ifconfig = true; |
757 |
tt->did_ifconfig = true; |
674 |
|
758 |
|
675 |
#endif /*CONFIG_FEATURE_IPROUTE*/ |
759 |
#endif /*CONFIG_FEATURE_IPROUTE*/ |
Lines 693-699
Link Here
|
693 |
|
777 |
|
694 |
argv_msg (M_INFO, &argv); |
778 |
argv_msg (M_INFO, &argv); |
695 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed")) |
779 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-1 failed")) |
696 |
solaris_error_close (tt, es, actual); |
780 |
solaris_error_close (tt, es, actual, false); |
697 |
|
781 |
|
698 |
argv_printf (&argv, |
782 |
argv_printf (&argv, |
699 |
"%s %s netmask 255.255.255.255", |
783 |
"%s %s netmask 255.255.255.255", |
Lines 725-731
Link Here
|
725 |
|
809 |
|
726 |
argv_msg (M_INFO, &argv); |
810 |
argv_msg (M_INFO, &argv); |
727 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed")) |
811 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig phase-2 failed")) |
728 |
solaris_error_close (tt, es, actual); |
812 |
solaris_error_close (tt, es, actual, false); |
|
|
813 |
|
814 |
if ( do_ipv6 ) |
815 |
{ |
816 |
argv_printf (&argv, "%s %s inet6 unplumb", |
817 |
IFCONFIG_PATH, actual ); |
818 |
argv_msg (M_INFO, &argv); |
819 |
openvpn_execve_check (&argv, es, 0, NULL); |
820 |
|
821 |
if ( tt->type == DEV_TYPE_TUN ) |
822 |
{ |
823 |
argv_printf (&argv, |
824 |
"%s %s inet6 plumb %s/%d %s up", |
825 |
IFCONFIG_PATH, |
826 |
actual, |
827 |
ifconfig_ipv6_local, |
828 |
tt->netbits_ipv6, |
829 |
ifconfig_ipv6_remote |
830 |
); |
831 |
} |
832 |
else /* tap mode */ |
833 |
{ |
834 |
/* base IPv6 tap interface needs to be brought up first |
835 |
*/ |
836 |
argv_printf (&argv, "%s %s inet6 plumb up", |
837 |
IFCONFIG_PATH, actual ); |
838 |
argv_msg (M_INFO, &argv); |
839 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 (prepare) failed")) |
840 |
solaris_error_close (tt, es, actual, true); |
841 |
|
842 |
/* we might need to do "ifconfig %s inet6 auto-dhcp drop" |
843 |
* after the system has noticed the interface and fired up |
844 |
* the DHCPv6 client - but this takes quite a while, and the |
845 |
* server will ignore the DHCPv6 packets anyway. So we don't. |
846 |
*/ |
847 |
|
848 |
/* static IPv6 addresses need to go to a subinterface (tap0:1) |
849 |
*/ |
850 |
argv_printf (&argv, |
851 |
"%s %s inet6 addif %s/%d up", |
852 |
IFCONFIG_PATH, actual, |
853 |
ifconfig_ipv6_local, tt->netbits_ipv6 ); |
854 |
} |
855 |
argv_msg (M_INFO, &argv); |
856 |
if (!openvpn_execve_check (&argv, es, 0, "Solaris ifconfig IPv6 failed")) |
857 |
solaris_error_close (tt, es, actual, true); |
858 |
} |
729 |
|
859 |
|
730 |
if (!tun && tt->topology == TOP_SUBNET) |
860 |
if (!tun && tt->topology == TOP_SUBNET) |
731 |
{ |
861 |
{ |
Lines 787-796
Link Here
|
787 |
); |
917 |
); |
788 |
argv_msg (M_INFO, &argv); |
918 |
argv_msg (M_INFO, &argv); |
789 |
openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed"); |
919 |
openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig failed"); |
|
|
920 |
if ( do_ipv6 ) |
921 |
{ |
922 |
argv_printf (&argv, |
923 |
"%s %s inet6 %s/%d", |
924 |
IFCONFIG_PATH, |
925 |
actual, |
926 |
ifconfig_ipv6_local, |
927 |
tt->netbits_ipv6 |
928 |
); |
929 |
argv_msg (M_INFO, &argv); |
930 |
openvpn_execve_check (&argv, es, S_FATAL, "OpenBSD ifconfig inet6 failed"); |
931 |
|
932 |
/* and, hooray, we explicitely need to add a route... */ |
933 |
add_route_connected_v6_net(tt, es); |
934 |
} |
790 |
tt->did_ifconfig = true; |
935 |
tt->did_ifconfig = true; |
791 |
|
936 |
|
792 |
#elif defined(TARGET_NETBSD) |
937 |
#elif defined(TARGET_NETBSD) |
793 |
|
938 |
|
|
|
939 |
/* whether or not NetBSD can do IPv6 can be seen by the availability of |
940 |
* the TUNSIFHEAD ioctl() - see next TARGET_NETBSD block for more details |
941 |
*/ |
942 |
#ifdef TUNSIFHEAD |
943 |
# define NETBSD_MULTI_AF |
944 |
#endif |
945 |
|
946 |
/* as on OpenBSD and Darwin, destroy and re-create tun<x> interface |
947 |
*/ |
948 |
argv_printf (&argv, "%s %s destroy", IFCONFIG_PATH, actual ); |
949 |
argv_msg (M_INFO, &argv); |
950 |
openvpn_execve_check (&argv, es, 0, "NetBSD ifconfig destroy failed"); |
951 |
|
952 |
argv_printf (&argv, "%s %s create", IFCONFIG_PATH, actual ); |
953 |
argv_msg (M_INFO, &argv); |
954 |
openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig create failed"); |
955 |
|
794 |
if (tun) |
956 |
if (tun) |
795 |
argv_printf (&argv, |
957 |
argv_printf (&argv, |
796 |
"%s %s %s %s mtu %d netmask 255.255.255.255 up", |
958 |
"%s %s %s %s mtu %d netmask 255.255.255.255 up", |
Lines 817-822
Link Here
|
817 |
); |
979 |
); |
818 |
argv_msg (M_INFO, &argv); |
980 |
argv_msg (M_INFO, &argv); |
819 |
openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed"); |
981 |
openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig failed"); |
|
|
982 |
|
983 |
if ( do_ipv6 ) |
984 |
{ |
985 |
#ifdef NETBSD_MULTI_AF |
986 |
argv_printf (&argv, |
987 |
"%s %s inet6 %s/%d", |
988 |
IFCONFIG_PATH, |
989 |
actual, |
990 |
ifconfig_ipv6_local, |
991 |
tt->netbits_ipv6 |
992 |
); |
993 |
argv_msg (M_INFO, &argv); |
994 |
openvpn_execve_check (&argv, es, S_FATAL, "NetBSD ifconfig inet6 failed"); |
995 |
|
996 |
/* and, hooray, we explicitely need to add a route... */ |
997 |
add_route_connected_v6_net(tt, es); |
998 |
#else |
999 |
msg( M_INFO, "no IPv6 support for tun interfaces on NetBSD before 4.0 (if your system is newer, recompile openvpn)" ); |
1000 |
tt->ipv6 = false; |
1001 |
#endif |
1002 |
} |
820 |
tt->did_ifconfig = true; |
1003 |
tt->did_ifconfig = true; |
821 |
|
1004 |
|
822 |
#elif defined(TARGET_DARWIN) |
1005 |
#elif defined(TARGET_DARWIN) |
Lines 882-887
Link Here
|
882 |
add_route (&r, tt, 0, es); |
1065 |
add_route (&r, tt, 0, es); |
883 |
} |
1066 |
} |
884 |
|
1067 |
|
|
|
1068 |
if ( do_ipv6 ) |
1069 |
{ |
1070 |
argv_printf (&argv, |
1071 |
"%s %s inet6 %s/%d", |
1072 |
IFCONFIG_PATH, |
1073 |
actual, |
1074 |
ifconfig_ipv6_local, |
1075 |
tt->netbits_ipv6 |
1076 |
); |
1077 |
argv_msg (M_INFO, &argv); |
1078 |
openvpn_execve_check (&argv, es, S_FATAL, "MacOS X ifconfig inet6 failed"); |
1079 |
|
1080 |
/* and, hooray, we explicitely need to add a route... */ |
1081 |
add_route_connected_v6_net(tt, es); |
1082 |
} |
1083 |
|
885 |
#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY) |
1084 |
#elif defined(TARGET_FREEBSD)||defined(TARGET_DRAGONFLY) |
886 |
|
1085 |
|
887 |
/* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */ |
1086 |
/* example: ifconfig tun2 10.2.0.2 10.2.0.1 mtu 1450 netmask 255.255.255.255 up */ |
Lines 920-925
Link Here
|
920 |
add_route (&r, tt, 0, es); |
1119 |
add_route (&r, tt, 0, es); |
921 |
} |
1120 |
} |
922 |
|
1121 |
|
|
|
1122 |
if ( do_ipv6 ) |
1123 |
{ |
1124 |
argv_printf (&argv, |
1125 |
"%s %s inet6 %s/%d", |
1126 |
IFCONFIG_PATH, |
1127 |
actual, |
1128 |
ifconfig_ipv6_local, |
1129 |
tt->netbits_ipv6 |
1130 |
); |
1131 |
argv_msg (M_INFO, &argv); |
1132 |
openvpn_execve_check (&argv, es, S_FATAL, "FreeBSD ifconfig inet6 failed"); |
1133 |
} |
1134 |
|
923 |
#elif defined (WIN32) |
1135 |
#elif defined (WIN32) |
924 |
{ |
1136 |
{ |
925 |
/* |
1137 |
/* |
Lines 959-964
Link Here
|
959 |
tt->did_ifconfig = true; |
1171 |
tt->did_ifconfig = true; |
960 |
} |
1172 |
} |
961 |
|
1173 |
|
|
|
1174 |
/* IPv6 always uses "netsh" interface */ |
1175 |
if ( do_ipv6 ) |
1176 |
{ |
1177 |
char * saved_actual; |
1178 |
|
1179 |
if (!strcmp (actual, "NULL")) |
1180 |
msg (M_FATAL, "Error: When using --tun-ipv6, if you have more than one TAP-Win32 adapter, you must also specify --dev-node"); |
1181 |
|
1182 |
/* example: netsh interface ipv6 set address MyTap 2001:608:8003::d store=active */ |
1183 |
argv_printf (&argv, |
1184 |
"%s%sc interface ipv6 set address %s %s store=active", |
1185 |
get_win_sys_path(), |
1186 |
NETSH_PATH_SUFFIX, |
1187 |
actual, |
1188 |
ifconfig_ipv6_local ); |
1189 |
|
1190 |
netsh_command (&argv, 4); |
1191 |
|
1192 |
/* explicit route needed */ |
1193 |
/* on windows, OpenVPN does ifconfig first, open_tun later, so |
1194 |
* tt->actual_name might not yet be initialized, but routing code |
1195 |
* needs to know interface name - point to "actual", restore later |
1196 |
*/ |
1197 |
saved_actual = tt->actual_name; |
1198 |
tt->actual_name = (char*) actual; |
1199 |
add_route_connected_v6_net(tt, es); |
1200 |
tt->actual_name = saved_actual; |
1201 |
} |
962 |
#else |
1202 |
#else |
963 |
msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script."); |
1203 |
msg (M_FATAL, "Sorry, but I don't know how to do 'ifconfig' commands on this operating system. You should ifconfig your TUN/TAP device manually or use an --up script."); |
964 |
#endif |
1204 |
#endif |
Lines 991-1004
Link Here
|
991 |
#ifndef WIN32 |
1231 |
#ifndef WIN32 |
992 |
static void |
1232 |
static void |
993 |
open_tun_generic (const char *dev, const char *dev_type, const char *dev_node, |
1233 |
open_tun_generic (const char *dev, const char *dev_type, const char *dev_node, |
994 |
bool ipv6, bool ipv6_explicitly_supported, bool dynamic, |
1234 |
bool ipv6_explicitly_supported, bool dynamic, |
995 |
struct tuntap *tt) |
1235 |
struct tuntap *tt) |
996 |
{ |
1236 |
{ |
997 |
char tunname[256]; |
1237 |
char tunname[256]; |
998 |
char dynamic_name[256]; |
1238 |
char dynamic_name[256]; |
999 |
bool dynamic_opened = false; |
1239 |
bool dynamic_opened = false; |
1000 |
|
1240 |
|
1001 |
ipv6_support (ipv6, ipv6_explicitly_supported, tt); |
1241 |
|
|
|
1242 |
if ( tt->ipv6 && ! ipv6_explicitly_supported ) |
1243 |
msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS"); |
1002 |
|
1244 |
|
1003 |
if (tt->type == DEV_TYPE_NULL) |
1245 |
if (tt->type == DEV_TYPE_NULL) |
1004 |
{ |
1246 |
{ |
Lines 1094-1109
Link Here
|
1094 |
#if !PEDANTIC |
1336 |
#if !PEDANTIC |
1095 |
|
1337 |
|
1096 |
void |
1338 |
void |
1097 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
1339 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1098 |
{ |
1340 |
{ |
1099 |
struct ifreq ifr; |
1341 |
struct ifreq ifr; |
1100 |
|
1342 |
|
1101 |
/* |
1343 |
/* warn if a very old linux version is used & --tun-ipv6 set |
1102 |
* Set tt->ipv6 to true if |
|
|
1103 |
* (a) we have the capability of supporting --tun-ipv6, and |
1104 |
* (b) --tun-ipv6 was specified. |
1105 |
*/ |
1344 |
*/ |
1106 |
ipv6_support (ipv6, LINUX_IPV6, tt); |
1345 |
#if LINUX_IPV6 == 0 |
|
|
1346 |
if ( tt->ipv6 ) |
1347 |
msg (M_WARN, "NOTE: explicit support for IPv6 tun devices is not provided for this OS"); |
1348 |
#endif |
1107 |
|
1349 |
|
1108 |
/* |
1350 |
/* |
1109 |
* We handle --dev null specially, we do not open /dev/null for this. |
1351 |
* We handle --dev null specially, we do not open /dev/null for this. |
Lines 1212-1218
Link Here
|
1212 |
#else |
1454 |
#else |
1213 |
|
1455 |
|
1214 |
void |
1456 |
void |
1215 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
1457 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1216 |
{ |
1458 |
{ |
1217 |
ASSERT (0); |
1459 |
ASSERT (0); |
1218 |
} |
1460 |
} |
Lines 1222-1230
Link Here
|
1222 |
#else |
1464 |
#else |
1223 |
|
1465 |
|
1224 |
void |
1466 |
void |
1225 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
1467 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1226 |
{ |
1468 |
{ |
1227 |
open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt); |
1469 |
open_tun_generic (dev, dev_type, dev_node, false, true, tt); |
1228 |
} |
1470 |
} |
1229 |
|
1471 |
|
1230 |
#endif /* HAVE_LINUX_IF_TUN_H */ |
1472 |
#endif /* HAVE_LINUX_IF_TUN_H */ |
Lines 1244-1250
Link Here
|
1244 |
#endif |
1486 |
#endif |
1245 |
|
1487 |
|
1246 |
void |
1488 |
void |
1247 |
tuncfg (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options) |
1489 |
tuncfg (const char *dev, const char *dev_type, const char *dev_node, int persist_mode, const char *username, const char *groupname, const struct tuntap_options *options) |
1248 |
{ |
1490 |
{ |
1249 |
struct tuntap *tt; |
1491 |
struct tuntap *tt; |
1250 |
|
1492 |
|
Lines 1252-1258
Link Here
|
1252 |
clear_tuntap (tt); |
1494 |
clear_tuntap (tt); |
1253 |
tt->type = dev_type_enum (dev, dev_type); |
1495 |
tt->type = dev_type_enum (dev, dev_type); |
1254 |
tt->options = *options; |
1496 |
tt->options = *options; |
1255 |
open_tun (dev, dev_type, dev_node, ipv6, tt); |
1497 |
open_tun (dev, dev_type, dev_node, tt); |
1256 |
if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0) |
1498 |
if (ioctl (tt->fd, TUNSETPERSIST, persist_mode) < 0) |
1257 |
msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); |
1499 |
msg (M_ERR, "Cannot ioctl TUNSETPERSIST(%d) %s", persist_mode, dev); |
1258 |
if (username != NULL) |
1500 |
if (username != NULL) |
Lines 1395-1401
Link Here
|
1395 |
#endif |
1637 |
#endif |
1396 |
|
1638 |
|
1397 |
void |
1639 |
void |
1398 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
1640 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1399 |
{ |
1641 |
{ |
1400 |
int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1; |
1642 |
int if_fd, ip_muxid, arp_muxid, arp_fd, ppa = -1; |
1401 |
struct lifreq ifr; |
1643 |
struct lifreq ifr; |
Lines 1406-1413
Link Here
|
1406 |
bool is_tun; |
1648 |
bool is_tun; |
1407 |
struct strioctl strioc_if, strioc_ppa; |
1649 |
struct strioctl strioc_if, strioc_ppa; |
1408 |
|
1650 |
|
1409 |
ipv6_support (ipv6, true, tt); |
1651 |
/* improved generic TUN/TAP driver from |
1410 |
memset(&ifr, 0x0, sizeof(ifr)); |
1652 |
* http://www.whiteboard.ne.jp/~admin2/tuntap/ |
|
|
1653 |
* has IPv6 support |
1654 |
*/ |
1655 |
CLEAR(ifr); |
1411 |
|
1656 |
|
1412 |
if (tt->type == DEV_TYPE_NULL) |
1657 |
if (tt->type == DEV_TYPE_NULL) |
1413 |
{ |
1658 |
{ |
Lines 1561-1566
Link Here
|
1561 |
{ |
1806 |
{ |
1562 |
if (tt) |
1807 |
if (tt) |
1563 |
{ |
1808 |
{ |
|
|
1809 |
/* IPv6 interfaces need to be 'manually' de-configured */ |
1810 |
if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) |
1811 |
{ |
1812 |
struct argv argv; |
1813 |
argv_init (&argv); |
1814 |
argv_printf( &argv, "%s %s inet6 unplumb", |
1815 |
IFCONFIG_PATH, tt->actual_name ); |
1816 |
argv_msg (M_INFO, &argv); |
1817 |
openvpn_execve_check (&argv, NULL, 0, "Solaris ifconfig inet6 unplumb failed"); |
1818 |
argv_reset (&argv); |
1819 |
} |
1820 |
|
1564 |
if (tt->ip_fd >= 0) |
1821 |
if (tt->ip_fd >= 0) |
1565 |
{ |
1822 |
{ |
1566 |
struct lifreq ifr; |
1823 |
struct lifreq ifr; |
Lines 1613-1623
Link Here
|
1613 |
} |
1870 |
} |
1614 |
|
1871 |
|
1615 |
static void |
1872 |
static void |
1616 |
solaris_error_close (struct tuntap *tt, const struct env_set *es, const char *actual) |
1873 |
solaris_error_close (struct tuntap *tt, const struct env_set *es, |
|
|
1874 |
const char *actual, bool unplumb_inet6 ) |
1617 |
{ |
1875 |
{ |
1618 |
struct argv argv; |
1876 |
struct argv argv; |
1619 |
argv_init (&argv); |
1877 |
argv_init (&argv); |
1620 |
|
1878 |
|
|
|
1879 |
if (unplumb_inet6) |
1880 |
{ |
1881 |
argv_printf( &argv, "%s %s inet6 unplumb", |
1882 |
IFCONFIG_PATH, actual ); |
1883 |
argv_msg (M_INFO, &argv); |
1884 |
openvpn_execve_check (&argv, es, 0, "Solaris ifconfig inet6 unplumb failed"); |
1885 |
} |
1886 |
|
1621 |
argv_printf (&argv, |
1887 |
argv_printf (&argv, |
1622 |
"%s %s unplumb", |
1888 |
"%s %s unplumb", |
1623 |
IFCONFIG_PATH, |
1889 |
IFCONFIG_PATH, |
Lines 1674-1682
Link Here
|
1674 |
*/ |
1940 |
*/ |
1675 |
|
1941 |
|
1676 |
void |
1942 |
void |
1677 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
1943 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1678 |
{ |
1944 |
{ |
1679 |
open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); |
1945 |
open_tun_generic (dev, dev_type, dev_node, true, true, tt); |
1680 |
|
1946 |
|
1681 |
/* Enable multicast on the interface */ |
1947 |
/* Enable multicast on the interface */ |
1682 |
if (tt->fd >= 0) |
1948 |
if (tt->fd >= 0) |
Lines 1697-1708
Link Here
|
1697 |
} |
1963 |
} |
1698 |
} |
1964 |
} |
1699 |
|
1965 |
|
|
|
1966 |
/* the current way OpenVPN handles tun devices on OpenBSD leads to |
1967 |
* lingering tunX interfaces after close -> for a full cleanup, they |
1968 |
* need to be explicitely destroyed |
1969 |
*/ |
1970 |
|
1700 |
void |
1971 |
void |
1701 |
close_tun (struct tuntap* tt) |
1972 |
close_tun (struct tuntap* tt) |
1702 |
{ |
1973 |
{ |
1703 |
if (tt) |
1974 |
if (tt) |
1704 |
{ |
1975 |
{ |
|
|
1976 |
struct gc_arena gc = gc_new (); |
1977 |
struct argv argv; |
1978 |
|
1979 |
/* setup command, close tun dev (clears tt->actual_name!), run command |
1980 |
*/ |
1981 |
|
1982 |
argv_init (&argv); |
1983 |
argv_printf (&argv, "%s %s destroy", |
1984 |
IFCONFIG_PATH, tt->actual_name); |
1985 |
|
1705 |
close_tun_generic (tt); |
1986 |
close_tun_generic (tt); |
|
|
1987 |
|
1988 |
argv_msg (M_INFO, &argv); |
1989 |
openvpn_execve_check (&argv, NULL, 0, "OpenBSD 'destroy tun interface' failed (non-critical)"); |
1990 |
|
1706 |
free (tt); |
1991 |
free (tt); |
1707 |
} |
1992 |
} |
1708 |
} |
1993 |
} |
Lines 1765-1797
Link Here
|
1765 |
#elif defined(TARGET_NETBSD) |
2050 |
#elif defined(TARGET_NETBSD) |
1766 |
|
2051 |
|
1767 |
/* |
2052 |
/* |
1768 |
* NetBSD does not support IPv6 on tun out of the box, |
2053 |
* NetBSD before 4.0 does not support IPv6 on tun out of the box, |
1769 |
* but there exists a patch. When this patch is applied, |
2054 |
* but there exists a patch (sys/net/if_tun.c, 1.79->1.80, see PR 32944). |
1770 |
* only two things are left to openvpn: |
2055 |
* |
1771 |
* 1. Activate multicasting (this has already been done |
2056 |
* NetBSD 4.0 and up do, but we need to put the tun interface into |
1772 |
* before by the kernel, but we make sure that nobody |
2057 |
* "multi_af" mode, which will prepend the address family to all packets |
1773 |
* has deactivated multicasting inbetween. |
2058 |
* (same as OpenBSD and FreeBSD). If this is not enabled, the kernel |
1774 |
* 2. Deactivate "link layer mode" (otherwise NetBSD |
2059 |
* silently drops all IPv6 packets on output and gets confused on input. |
1775 |
* prepends the address family to the packet, and we |
2060 |
* |
1776 |
* would run into the same trouble as with OpenBSD. |
2061 |
* On earlier versions, multi_af is not available at all, so we have |
|
|
2062 |
* two different NetBSD code variants here :-( |
2063 |
* |
1777 |
*/ |
2064 |
*/ |
1778 |
|
2065 |
|
1779 |
void |
2066 |
void |
1780 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
2067 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1781 |
{ |
2068 |
{ |
1782 |
open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); |
2069 |
#ifdef NETBSD_MULTI_AF |
|
|
2070 |
open_tun_generic (dev, dev_type, dev_node, true, true, tt); |
2071 |
#else |
2072 |
open_tun_generic (dev, dev_type, dev_node, false, true, tt); |
2073 |
#endif |
2074 |
|
1783 |
if (tt->fd >= 0) |
2075 |
if (tt->fd >= 0) |
1784 |
{ |
2076 |
{ |
1785 |
int i = IFF_POINTOPOINT|IFF_MULTICAST; |
2077 |
int i = IFF_POINTOPOINT|IFF_MULTICAST; |
1786 |
ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */ |
2078 |
ioctl (tt->fd, TUNSIFMODE, &i); /* multicast on */ |
1787 |
i = 0; |
2079 |
i = 0; |
1788 |
ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */ |
2080 |
ioctl (tt->fd, TUNSLMODE, &i); /* link layer mode off */ |
|
|
2081 |
|
2082 |
#ifdef NETBSD_MULTI_AF |
2083 |
i = 1; |
2084 |
if (ioctl (tt->fd, TUNSIFHEAD, &i) < 0) /* multi-af mode on */ |
2085 |
{ |
2086 |
msg (M_WARN | M_ERRNO, "ioctl(TUNSIFHEAD): %s", strerror(errno)); |
2087 |
} |
2088 |
#endif |
1789 |
} |
2089 |
} |
1790 |
} |
2090 |
} |
1791 |
|
2091 |
|
1792 |
void |
2092 |
void |
1793 |
close_tun (struct tuntap *tt) |
2093 |
close_tun (struct tuntap *tt) |
1794 |
{ |
2094 |
{ |
|
|
2095 |
/* TODO: we really should cleanup non-persistant tunX with |
2096 |
* "ifconfig tunX destroy" here... |
2097 |
*/ |
1795 |
if (tt) |
2098 |
if (tt) |
1796 |
{ |
2099 |
{ |
1797 |
close_tun_generic (tt); |
2100 |
close_tun_generic (tt); |
Lines 1799-1804
Link Here
|
1799 |
} |
2102 |
} |
1800 |
} |
2103 |
} |
1801 |
|
2104 |
|
|
|
2105 |
#ifdef NETBSD_MULTI_AF |
2106 |
|
2107 |
static inline int |
2108 |
netbsd_modify_read_write_return (int len) |
2109 |
{ |
2110 |
if (len > 0) |
2111 |
return len > sizeof (u_int32_t) ? len - sizeof (u_int32_t) : 0; |
2112 |
else |
2113 |
return len; |
2114 |
} |
2115 |
|
2116 |
int |
2117 |
write_tun (struct tuntap* tt, uint8_t *buf, int len) |
2118 |
{ |
2119 |
if (tt->type == DEV_TYPE_TUN) |
2120 |
{ |
2121 |
u_int32_t type; |
2122 |
struct iovec iv[2]; |
2123 |
struct openvpn_iphdr *iph; |
2124 |
|
2125 |
iph = (struct openvpn_iphdr *) buf; |
2126 |
|
2127 |
if (tt->ipv6 && OPENVPN_IPH_GET_VER(iph->version_len) == 6) |
2128 |
type = htonl (AF_INET6); |
2129 |
else |
2130 |
type = htonl (AF_INET); |
2131 |
|
2132 |
iv[0].iov_base = (char *)&type; |
2133 |
iv[0].iov_len = sizeof (type); |
2134 |
iv[1].iov_base = buf; |
2135 |
iv[1].iov_len = len; |
2136 |
|
2137 |
return netbsd_modify_read_write_return (writev (tt->fd, iv, 2)); |
2138 |
} |
2139 |
else |
2140 |
return write (tt->fd, buf, len); |
2141 |
} |
2142 |
|
2143 |
int |
2144 |
read_tun (struct tuntap* tt, uint8_t *buf, int len) |
2145 |
{ |
2146 |
if (tt->type == DEV_TYPE_TUN) |
2147 |
{ |
2148 |
u_int32_t type; |
2149 |
struct iovec iv[2]; |
2150 |
|
2151 |
iv[0].iov_base = (char *)&type; |
2152 |
iv[0].iov_len = sizeof (type); |
2153 |
iv[1].iov_base = buf; |
2154 |
iv[1].iov_len = len; |
2155 |
|
2156 |
return netbsd_modify_read_write_return (readv (tt->fd, iv, 2)); |
2157 |
} |
2158 |
else |
2159 |
return read (tt->fd, buf, len); |
2160 |
} |
2161 |
|
2162 |
#else /* not NETBSD_MULTI_AF -> older code, IPv4 only */ |
2163 |
|
1802 |
int |
2164 |
int |
1803 |
write_tun (struct tuntap* tt, uint8_t *buf, int len) |
2165 |
write_tun (struct tuntap* tt, uint8_t *buf, int len) |
1804 |
{ |
2166 |
{ |
Lines 1810-1815
Link Here
|
1810 |
{ |
2172 |
{ |
1811 |
return read (tt->fd, buf, len); |
2173 |
return read (tt->fd, buf, len); |
1812 |
} |
2174 |
} |
|
|
2175 |
#endif /* NETBSD_MULTI_AF */ |
1813 |
|
2176 |
|
1814 |
#elif defined(TARGET_FREEBSD) |
2177 |
#elif defined(TARGET_FREEBSD) |
1815 |
|
2178 |
|
Lines 1823-1831
Link Here
|
1823 |
} |
2186 |
} |
1824 |
|
2187 |
|
1825 |
void |
2188 |
void |
1826 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
2189 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1827 |
{ |
2190 |
{ |
1828 |
open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); |
2191 |
open_tun_generic (dev, dev_type, dev_node, true, true, tt); |
1829 |
|
2192 |
|
1830 |
if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN) |
2193 |
if (tt->fd >= 0 && tt->type == DEV_TYPE_TUN) |
1831 |
{ |
2194 |
{ |
Lines 1911-1919
Link Here
|
1911 |
} |
2274 |
} |
1912 |
|
2275 |
|
1913 |
void |
2276 |
void |
1914 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
2277 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
1915 |
{ |
2278 |
{ |
1916 |
open_tun_generic (dev, dev_type, dev_node, ipv6, true, true, tt); |
2279 |
open_tun_generic (dev, dev_type, dev_node, true, true, tt); |
1917 |
|
2280 |
|
1918 |
if (tt->fd >= 0) |
2281 |
if (tt->fd >= 0) |
1919 |
{ |
2282 |
{ |
Lines 1982-1987
Link Here
|
1982 |
return read (tt->fd, buf, len); |
2345 |
return read (tt->fd, buf, len); |
1983 |
} |
2346 |
} |
1984 |
|
2347 |
|
|
|
2348 |
#elif defined(TARGET_DARWIN) |
2349 |
|
2350 |
/* Darwin (MacOS X) is mostly "just use the generic stuff", but there |
2351 |
* is always one caveat...: |
2352 |
* |
2353 |
* If IPv6 is configured, and the tun device is closed, the IPv6 address |
2354 |
* configured to the tun interface changes to a lingering /128 route |
2355 |
* pointing to lo0. Need to unconfigure... (observed on 10.5) |
2356 |
*/ |
2357 |
|
2358 |
void |
2359 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
2360 |
{ |
2361 |
open_tun_generic (dev, dev_type, dev_node, false, true, tt); |
2362 |
} |
2363 |
|
2364 |
void |
2365 |
close_tun (struct tuntap* tt) |
2366 |
{ |
2367 |
if (tt) |
2368 |
{ |
2369 |
struct gc_arena gc = gc_new (); |
2370 |
struct argv argv; |
2371 |
argv_init (&argv); |
2372 |
|
2373 |
if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) |
2374 |
{ |
2375 |
const char * ifconfig_ipv6_local = |
2376 |
print_in6_addr (tt->local_ipv6, 0, &gc); |
2377 |
|
2378 |
argv_printf (&argv, "%s delete -inet6 %s", |
2379 |
ROUTE_PATH, ifconfig_ipv6_local ); |
2380 |
argv_msg (M_INFO, &argv); |
2381 |
openvpn_execve_check (&argv, NULL, 0, "MacOS X 'remove inet6 route' failed (non-critical)"); |
2382 |
} |
2383 |
|
2384 |
close_tun_generic (tt); |
2385 |
free (tt); |
2386 |
argv_reset (&argv); |
2387 |
gc_free (&gc); |
2388 |
} |
2389 |
} |
2390 |
|
2391 |
int |
2392 |
write_tun (struct tuntap* tt, uint8_t *buf, int len) |
2393 |
{ |
2394 |
return write (tt->fd, buf, len); |
2395 |
} |
2396 |
|
2397 |
int |
2398 |
read_tun (struct tuntap* tt, uint8_t *buf, int len) |
2399 |
{ |
2400 |
return read (tt->fd, buf, len); |
2401 |
} |
2402 |
|
1985 |
#elif defined(WIN32) |
2403 |
#elif defined(WIN32) |
1986 |
|
2404 |
|
1987 |
int |
2405 |
int |
Lines 3967-3973
Link Here
|
3967 |
} |
4385 |
} |
3968 |
|
4386 |
|
3969 |
void |
4387 |
void |
3970 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
4388 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
3971 |
{ |
4389 |
{ |
3972 |
struct gc_arena gc = gc_new (); |
4390 |
struct gc_arena gc = gc_new (); |
3973 |
char device_path[256]; |
4391 |
char device_path[256]; |
Lines 3978-3984
Link Here
|
3978 |
|
4396 |
|
3979 |
/*netcmd_semaphore_lock ();*/ |
4397 |
/*netcmd_semaphore_lock ();*/ |
3980 |
|
4398 |
|
3981 |
ipv6_support (ipv6, false, tt); |
4399 |
msg( M_INFO, "open_tun, tt->ipv6=%d", tt->ipv6 ); |
3982 |
|
4400 |
|
3983 |
if (tt->type == DEV_TYPE_NULL) |
4401 |
if (tt->type == DEV_TYPE_NULL) |
3984 |
{ |
4402 |
{ |
Lines 4101-4106
Link Here
|
4101 |
TAP_WIN32_MIN_MAJOR, |
4519 |
TAP_WIN32_MIN_MAJOR, |
4102 |
TAP_WIN32_MIN_MINOR); |
4520 |
TAP_WIN32_MIN_MINOR); |
4103 |
|
4521 |
|
|
|
4522 |
/* usage of numeric constants is ugly, but this is really tied to |
4523 |
* *this* version of the driver |
4524 |
*/ |
4525 |
if ( tt->ipv6 && tt->type == DEV_TYPE_TUN && |
4526 |
info[0] == 9 && info[1] < 8) |
4527 |
{ |
4528 |
msg( M_INFO, "WARNING: Tap-Win32 driver version %d.%d does not support IPv6 in TUN mode. IPv6 will be disabled. Upgrade to Tap-Win32 9.8 (2.2-beta3 release or later) or use TAP mode to get IPv6", (int) info[0], (int) info[1] ); |
4529 |
tt->ipv6 = false; |
4530 |
} |
4531 |
|
4104 |
/* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy |
4532 |
/* tap driver 9.8 (2.2.0 and 2.2.1 release) is buggy |
4105 |
*/ |
4533 |
*/ |
4106 |
if ( tt->type == DEV_TYPE_TUN && |
4534 |
if ( tt->type == DEV_TYPE_TUN && |
Lines 4432-4437
Link Here
|
4432 |
|
4860 |
|
4433 |
if (tt) |
4861 |
if (tt) |
4434 |
{ |
4862 |
{ |
|
|
4863 |
if ( tt->ipv6 && tt->did_ifconfig_ipv6_setup ) |
4864 |
{ |
4865 |
struct argv argv; |
4866 |
argv_init (&argv); |
4867 |
|
4868 |
/* remove route pointing to interface */ |
4869 |
delete_route_connected_v6_net(tt, NULL); |
4870 |
|
4871 |
/* netsh interface ipv6 delete address \"%s\" %s */ |
4872 |
const char * ifconfig_ipv6_local = print_in6_addr (tt->local_ipv6, 0, &gc); |
4873 |
argv_printf (&argv, |
4874 |
"%s%sc interface ipv6 delete address %s %s", |
4875 |
get_win_sys_path(), |
4876 |
NETSH_PATH_SUFFIX, |
4877 |
tt->actual_name, |
4878 |
ifconfig_ipv6_local ); |
4879 |
|
4880 |
netsh_command (&argv, 1); |
4881 |
argv_reset (&argv); |
4882 |
} |
4435 |
#if 1 |
4883 |
#if 1 |
4436 |
if (tt->ipapi_context_defined) |
4884 |
if (tt->ipapi_context_defined) |
4437 |
{ |
4885 |
{ |
Lines 4535-4543
Link Here
|
4535 |
#else /* generic */ |
4983 |
#else /* generic */ |
4536 |
|
4984 |
|
4537 |
void |
4985 |
void |
4538 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, bool ipv6, struct tuntap *tt) |
4986 |
open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) |
4539 |
{ |
4987 |
{ |
4540 |
open_tun_generic (dev, dev_type, dev_node, ipv6, false, true, tt); |
4988 |
open_tun_generic (dev, dev_type, dev_node, false, true, tt); |
4541 |
} |
4989 |
} |
4542 |
|
4990 |
|
4543 |
void |
4991 |
void |