Set primary domain name server IPv6 address. Repeat
this option to set secondary DNS server IPv6 addresses.
-Note: currently this is somewhat of a placeholder option - it is
-understood, but OpenVPN has no code to tell Windows about it (the
+Note: currently this is handled using netsh and requires admin rights (the
existing DHCP code can only do IPv4 DHCP, and that protocol only
permits IPv4 addresses anywhere). The option will be put into the
environment, so an
.B \-\-up
-script could act upon it.
+script could act upon it if needed.
.B WINS addr \-\-
Set primary WINS server address (NetBIOS over TCP/IP Name Server).
{
dhcp_option_address_parse ("DNS", p[2], o->dns, &o->dns_len, msglevel);
}
- else if (streq (p[1], "DNS6") && p[2])
+ else if (streq (p[1], "DNS6") && p[2] && ipv6_addr_safe(p[2]))
{
- /* this is somewhat of a placeholder - we understand the option,
- * but cannot act upon it - so we'll just accept it and put it
- * into the environment, as we would do on all non-win32 platforms
- */
+ struct in6_addr addr;
foreign_option (options, p, 3, es);
+ if (o->dns6_len >= N_DHCP_ADDR)
+ {
+ msg (msglevel, "--dhcp-option DNS6: maximum of %d dns servers can be specified",
+ N_DHCP_ADDR);
+ }
+ else if (get_ipv6_addr (p[2], &addr, NULL, msglevel))
+ {
+ o->dns6[o->dns6_len++] = addr;
+ }
}
else if (streq (p[1], "WINS") && p[2])
{
const in_addr_t ip,
const in_addr_t netmask,
const unsigned int flags);
+static void netsh_set_dns6_servers (const struct in6_addr *addr_list,
+ const int addr_len,
+ const char *flex_name);
static void netsh_command (const struct argv *a, int n, int msglevel);
static const char *netsh_get_id (const char *dev_node, struct gc_arena *gc);
else if (tt->options.msg_channel)
{
do_address_service (true, AF_INET6, tt);
+ /* TODO: do_dns6_service() */
}
else
{
iface,
ifconfig_ipv6_local );
netsh_command (&argv, 4, M_FATAL);
+ /* set ipv6 dns servers if any are specified */
+ netsh_set_dns6_servers(tt->options.dns6, tt->options.dns6_len, actual);
}
/* explicit route needed */
return false;
}
+/**
+ * Set the ipv6 dns servers on the specified interface.
+ * The list of dns servers currently set on the interface
+ * are cleared first.
+ * No action is taken if number of addresses (addr_len) < 1.
+ */
+static void
+netsh_set_dns6_servers (const struct in6_addr *addr_list,
+ const int addr_len,
+ const char *flex_name)
+{
+ struct gc_arena gc = gc_new ();
+ struct argv argv = argv_new ();
+
+ for (int i = 0; i < addr_len; ++i)
+ {
+ const char *fmt = (i == 0) ?
+ "%s%sc interface ipv6 set dns %s static %s"
+ : "%s%sc interface ipv6 add dns %s %s";
+ argv_printf (&argv, fmt, get_win_sys_path(),
+ NETSH_PATH_SUFFIX, flex_name,
+ print_in6_addr (addr_list[i], 0, &gc));
+
+ /* disable slow address validation on Windows 7 and higher */
+ if (win32_version_info() >= WIN_7)
+ argv_printf_cat (&argv, "%s", "validate=no");
+
+ /* Treat errors while adding as non-fatal as we do not check for duplicates */
+ netsh_command (&argv, 1, (i==0)? M_FATAL : M_NONFATAL);
+ }
+
+ argv_reset (&argv);
+ gc_free (&gc);
+}
+
static void
netsh_ifconfig_options (const char *type,
const in_addr_t *addr_list,
ifconfig_ipv6_local);
netsh_command (&argv, 1, M_WARN);
+
+ /* delete ipv6 dns servers if any were set */
+ if (tt->options.dns6_len > 0)
+ {
+ argv_printf (&argv,
+ "%s%sc interface ipv6 delete dns %s all",
+ get_win_sys_path(),
+ NETSH_PATH_SUFFIX,
+ tt->actual_name);
+ netsh_command (&argv, 1, M_WARN);
+ }
argv_reset (&argv);
}
}