if (addr.family == AF_INET)
{
- addr.address.ipv4.s_addr = tt->local;
- addr.prefix_len = 32;
+ addr.address.ipv4.s_addr = htonl(tt->local);
+ addr.prefix_len = netmask_to_netbits2(tt->adapter_netmask);
}
else
{
}
static bool
-do_dns6_service(bool add, const struct tuntap *tt)
+do_dns_service(bool add, const short family, const struct tuntap *tt)
{
bool ret = false;
ack_message_t ack;
struct gc_arena gc = gc_new();
HANDLE pipe = tt->options.msg_channel;
- int addr_len = add ? tt->options.dns6_len : 0;
+ int len = family == AF_INET6 ? tt->options.dns6_len : tt->options.dns_len;
+ int addr_len = add ? len : 0;
+ const char *ip_proto_name = family == AF_INET6 ? "IPv6" : "IPv4";
if (addr_len == 0 && add) /* no addresses to add */
{
},
.iface = { .index = tt->adapter_index, .name = "" },
.domains = "",
- .family = AF_INET6,
+ .family = family,
.addr_len = addr_len
};
{
addr_len = _countof(dns.addr);
dns.addr_len = addr_len;
- msg(M_WARN, "Number of IPv6 DNS addresses sent to service truncated to %d",
- addr_len);
+ msg(M_WARN, "Number of %s DNS addresses sent to service truncated to %d",
+ ip_proto_name, addr_len);
}
for (int i = 0; i < addr_len; ++i)
{
- dns.addr[i].ipv6 = tt->options.dns6[i];
+ if (family == AF_INET6)
+ {
+ dns.addr[i].ipv6 = tt->options.dns6[i];
+ }
+ else
+ {
+ dns.addr[i].ipv4.s_addr = htonl(tt->options.dns[i]);
+ }
}
- msg(D_LOW, "%s IPv6 dns servers on '%s' (if_index = %d) using service",
- (add ? "Setting" : "Deleting"), dns.iface.name, dns.iface.index);
+ msg(D_LOW, "%s %s dns servers on '%s' (if_index = %d) using service",
+ (add ? "Setting" : "Deleting"), ip_proto_name, dns.iface.name, dns.iface.index);
if (!send_msg_iservice(pipe, &dns, sizeof(dns), &ack, "TUN"))
{
if (ack.error_number != NO_ERROR)
{
- msg(M_WARN, "TUN: %s IPv6 dns failed using service: %s [status=%u if_name=%s]",
- (add ? "adding" : "deleting"), strerror_win32(ack.error_number, &gc),
+ msg(M_WARN, "TUN: %s %s dns failed using service: %s [status=%u if_name=%s]",
+ (add ? "adding" : "deleting"), ip_proto_name, strerror_win32(ack.error_number, &gc),
ack.error_number, dns.iface.name);
goto out;
}
- msg(M_INFO, "IPv6 dns servers %s using service", (add ? "set" : "deleted"));
+ msg(M_INFO, "%s dns servers %s using service", ip_proto_name, (add ? "set" : "deleted"));
ret = true;
out:
* an extra call to "route add..."
* -> helper function to simplify code below
*/
-void
+static void
add_route_connected_v6_net(struct tuntap *tt,
const struct env_set *es)
{
}
#endif /* if defined(_WIN32) || defined(TARGET_DARWIN) || defined(TARGET_NETBSD) || defined(TARGET_OPENBSD) */
+#if defined(_WIN32)
+void
+do_route_ipv4_service_tun(bool add, const struct tuntap *tt)
+{
+ struct route_ipv4 r4;
+ CLEAR(r4);
+ r4.network = tt->local & tt->remote_netmask;
+ r4.netmask = tt->remote_netmask;
+ r4.gateway = tt->local;
+ r4.metric = 0; /* connected route */
+ r4.flags = RT_DEFINED | RT_METRIC_DEFINED;
+ do_route_ipv4_service(add, &r4, tt);
+}
+#endif
+
#if defined(TARGET_FREEBSD) || defined(TARGET_DRAGONFLY) \
|| defined(TARGET_NETBSD) || defined(TARGET_OPENBSD)
/* we can't use true subnet mode on tun on all platforms, as that
else if (tt->options.msg_channel)
{
do_address_service(true, AF_INET6, tt);
- do_dns6_service(true, tt);
+ do_dns_service(true, AF_INET6, tt);
}
else
{
{
ASSERT(ifname != NULL);
- switch (tt->options.ip_win32_type)
+ if (tt->options.msg_channel && tt->wintun)
+ {
+ do_address_service(true, AF_INET, tt);
+ do_route_ipv4_service_tun(true, tt);
+ do_dns_service(true, AF_INET, tt);
+ }
+ else
{
+ switch (tt->options.ip_win32_type)
+ {
case IPW32_SET_MANUAL:
msg(M_INFO,
"******** NOTE: Please manually set the IP/netmask of '%s' to %s/%s (if it is not already set)",
tt->adapter_netmask, NI_IP_NETMASK|NI_OPTIONS);
break;
+ }
}
}
}
/* possibly use IP Helper API to set IP address on adapter */
+ if (!tt->wintun)
{
const DWORD index = tt->adapter_index;
do_address_service(false, AF_INET6, tt);
if (tt->options.dns6_len > 0)
{
- do_dns6_service(false, tt);
+ do_dns_service(false, AF_INET6, tt);
}
}
else
}
}
#if 1
+ if (tt->wintun && tt->options.msg_channel)
+ {
+ do_route_ipv4_service_tun(false, tt);
+ do_address_service(false, AF_INET, tt);
+ do_dns_service(false, AF_INET, tt);
+ }
+ else
if (tt->ipapi_context_defined)
{
DWORD status;