|
|
|
|
@ -639,63 +639,28 @@ bool WindowsEthernetTap::enabled() const
|
|
|
|
|
|
|
|
|
|
bool WindowsEthernetTap::addIp(const InetAddress &ip) |
|
|
|
|
{ |
|
|
|
|
if (!_initialized) |
|
|
|
|
return false; |
|
|
|
|
if (!ip.netmaskBits()) // sanity check... netmask of 0.0.0.0 is WUT?
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
std::vector<InetAddress> haveIps(ips()); |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
// Add IP to interface at the netlink level if not already assigned.
|
|
|
|
|
if (!std::binary_search(haveIps.begin(),haveIps.end(),ip)) { |
|
|
|
|
MIB_UNICASTIPADDRESS_ROW ipr; |
|
|
|
|
|
|
|
|
|
InitializeUnicastIpAddressEntry(&ipr); |
|
|
|
|
if (ip.isV4()) { |
|
|
|
|
ipr.Address.Ipv4.sin_family = AF_INET; |
|
|
|
|
ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)ip.rawIpData()); |
|
|
|
|
ipr.OnLinkPrefixLength = ip.port(); |
|
|
|
|
if (ipr.OnLinkPrefixLength >= 32) |
|
|
|
|
return false; |
|
|
|
|
} else if (ip.isV6()) { |
|
|
|
|
ipr.Address.Ipv6.sin6_family = AF_INET6; |
|
|
|
|
memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte,ip.rawIpData(),16); |
|
|
|
|
ipr.OnLinkPrefixLength = ip.port(); |
|
|
|
|
if (ipr.OnLinkPrefixLength >= 128) |
|
|
|
|
return false; |
|
|
|
|
} else return false; |
|
|
|
|
|
|
|
|
|
ipr.PrefixOrigin = IpPrefixOriginManual; |
|
|
|
|
ipr.SuffixOrigin = IpSuffixOriginManual; |
|
|
|
|
ipr.ValidLifetime = 0xffffffff; |
|
|
|
|
ipr.PreferredLifetime = 0xffffffff; |
|
|
|
|
|
|
|
|
|
ipr.InterfaceLuid = _deviceLuid; |
|
|
|
|
ipr.InterfaceIndex = _getDeviceIndex(); |
|
|
|
|
|
|
|
|
|
if (CreateUnicastIpAddressEntry(&ipr) != NO_ERROR) |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::vector<std::string> regIps(_getRegistryIPv4Value("IPAddress")); |
|
|
|
|
if (std::find(regIps.begin(),regIps.end(),ip.toIpString()) == regIps.end()) { |
|
|
|
|
std::vector<std::string> regSubnetMasks(_getRegistryIPv4Value("SubnetMask")); |
|
|
|
|
regIps.push_back(ip.toIpString()); |
|
|
|
|
regSubnetMasks.push_back(ip.netmask().toIpString()); |
|
|
|
|
_setRegistryIPv4Value("IPAddress",regIps); |
|
|
|
|
_setRegistryIPv4Value("SubnetMask",regSubnetMasks); |
|
|
|
|
} |
|
|
|
|
} catch ( ... ) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
Mutex::Lock _l(_assignedIps_m); |
|
|
|
|
if (std::find(_assignedIps.begin(),_assignedIps.end(),ip) != _assignedIps.end()) |
|
|
|
|
return true; |
|
|
|
|
_assignedIps.push_back(ip); |
|
|
|
|
_syncIps(); |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool WindowsEthernetTap::removeIp(const InetAddress &ip) |
|
|
|
|
{ |
|
|
|
|
{ |
|
|
|
|
Mutex::Lock _l(_assignedIps_m); |
|
|
|
|
std::vector<InetAddress>::iterator aip(std::find(_assignedIps.begin(),_assignedIps.end(),ip)); |
|
|
|
|
if (aip != _assignedIps.end()) |
|
|
|
|
_assignedIps.erase(aip); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!_initialized) |
|
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
MIB_UNICASTIPADDRESS_TABLE *ipt = (MIB_UNICASTIPADDRESS_TABLE *)0; |
|
|
|
|
if (GetUnicastIpAddressTable(AF_UNSPEC,&ipt) == NO_ERROR) { |
|
|
|
|
@ -972,6 +937,12 @@ void WindowsEthernetTap::threadMain()
|
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// Assign or re-assign any should-be-assigned IPs in case we have restarted
|
|
|
|
|
{ |
|
|
|
|
Mutex::Lock _l(_assignedIps_m); |
|
|
|
|
_syncIps(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memset(&tapOvlRead,0,sizeof(tapOvlRead)); |
|
|
|
|
tapOvlRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); |
|
|
|
|
memset(&tapOvlWrite,0,sizeof(tapOvlWrite)); |
|
|
|
|
@ -1135,4 +1106,55 @@ void WindowsEthernetTap::_setRegistryIPv4Value(const char *regKey,const std::vec
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void WindowsEthernetTap::_syncIps() |
|
|
|
|
{ |
|
|
|
|
// assumes _assignedIps_m is locked
|
|
|
|
|
|
|
|
|
|
if (!_initialized) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
std::vector<InetAddress> haveIps(ips()); |
|
|
|
|
|
|
|
|
|
for(std::vector<InetAddress>::const_iterator aip(_assignedIps.begin());aip!=_assignedIps.end();++aip) { |
|
|
|
|
if (std::find(haveIps.begin(),haveIps.end(),*aip) == haveIps.end()) { |
|
|
|
|
MIB_UNICASTIPADDRESS_ROW ipr; |
|
|
|
|
|
|
|
|
|
InitializeUnicastIpAddressEntry(&ipr); |
|
|
|
|
if (aip->isV4()) { |
|
|
|
|
ipr.Address.Ipv4.sin_family = AF_INET; |
|
|
|
|
ipr.Address.Ipv4.sin_addr.S_un.S_addr = *((const uint32_t *)aip->rawIpData()); |
|
|
|
|
ipr.OnLinkPrefixLength = aip->netmaskBits(); |
|
|
|
|
if (ipr.OnLinkPrefixLength >= 32) |
|
|
|
|
continue; |
|
|
|
|
} else if (aip->isV6()) { |
|
|
|
|
ipr.Address.Ipv6.sin6_family = AF_INET6; |
|
|
|
|
memcpy(ipr.Address.Ipv6.sin6_addr.u.Byte,aip->rawIpData(),16); |
|
|
|
|
ipr.OnLinkPrefixLength = aip->netmaskBits(); |
|
|
|
|
if (ipr.OnLinkPrefixLength >= 128) |
|
|
|
|
continue; |
|
|
|
|
} else continue; |
|
|
|
|
|
|
|
|
|
ipr.PrefixOrigin = IpPrefixOriginManual; |
|
|
|
|
ipr.SuffixOrigin = IpSuffixOriginManual; |
|
|
|
|
ipr.ValidLifetime = 0xffffffff; |
|
|
|
|
ipr.PreferredLifetime = 0xffffffff; |
|
|
|
|
|
|
|
|
|
ipr.InterfaceLuid = _deviceLuid; |
|
|
|
|
ipr.InterfaceIndex = _getDeviceIndex(); |
|
|
|
|
|
|
|
|
|
CreateUnicastIpAddressEntry(&ipr); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
std::string ipStr(aip->toString()); |
|
|
|
|
std::vector<std::string> regIps(_getRegistryIPv4Value("IPAddress")); |
|
|
|
|
if (std::find(regIps.begin(),regIps.end(),ipStr) == regIps.end()) { |
|
|
|
|
std::vector<std::string> regSubnetMasks(_getRegistryIPv4Value("SubnetMask")); |
|
|
|
|
regIps.push_back(ipStr); |
|
|
|
|
regSubnetMasks.push_back(aip->netmask().toIpString()); |
|
|
|
|
_setRegistryIPv4Value("IPAddress",regIps); |
|
|
|
|
_setRegistryIPv4Value("SubnetMask",regSubnetMasks); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace ZeroTier
|
|
|
|
|
|