diff options
Diffstat (limited to 'node/EthernetTap.cpp')
-rw-r--r-- | node/EthernetTap.cpp | 114 |
1 files changed, 55 insertions, 59 deletions
diff --git a/node/EthernetTap.cpp b/node/EthernetTap.cpp index 458f1eed..231fde06 100644 --- a/node/EthernetTap.cpp +++ b/node/EthernetTap.cpp @@ -268,8 +268,6 @@ EthernetTap::EthernetTap( _r(renv), _handler(handler), _arg(arg), - _dhcp(false), - _dhcp6(false), _fd(0) { char devpath[64],ethaddr[64],mtustr[16],tmp[4096]; @@ -389,7 +387,7 @@ void EthernetTap::whack() if (cpid == 0) { execl(ipconfig,ipconfig,"set",_dev,"AUTOMATIC-V6",(const char *)0); _exit(-1); - } else { + } else if (cpid > 0) { int exitcode = -1; waitpid(cpid,&exitcode,0); } @@ -399,17 +397,6 @@ void EthernetTap::whack() void EthernetTap::whack() {} #endif // __APPLE__ / !__APPLE__ -bool EthernetTap::setDhcpEnabled(bool dhcp) -{ - // TODO - return _dhcp; -} - -bool EthernetTap::setDhcp6Enabled(bool dhcp) -{ - return _dhcp6; -} - void EthernetTap::setDisplayName(const char *dn) { } @@ -810,7 +797,6 @@ static inline void _intl_freeifmaddrs(struct ifmaddrs *ifmp) free(ifmp); } - // -------------------------------------------------------------------------- bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups) @@ -981,8 +967,6 @@ EthernetTap::EthernetTap( _r(renv), _handler(handler), _arg(arg), - _dhcp(false), - _dhcp6(false), _tap(INVALID_HANDLE_VALUE), _injectSemaphore(INVALID_HANDLE_VALUE), _run(true) @@ -995,10 +979,14 @@ EthernetTap::EthernetTap( throw std::runtime_error("MTU too large for Windows tap"); #ifdef _WIN64 - const char *devcon = "\\devcon64.exe"; + BOOL is64Bit = TRUE; + const char *devcon = "\\devcon_x64.exe"; + const char *tapDriver = "\\tap-windows\\x64\\ztTap100.inf"; #else - BOOL f64 = FALSE; - const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"); + BOOL is64Bit = FALSE; + IsWow64Process(GetCurrentProcess(),&is64Bit); + const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe"); + const char *tapDriver = ((is64Bit == TRUE) ? "\\tap-windows\\x64\\ztTap100.inf" : "\\tap-windows\\x86\\ztTap100.inf"); #endif Mutex::Lock _l(_systemTapInitLock); // only init one tap at a time, process-wide @@ -1066,7 +1054,7 @@ EthernetTap::EthernetTap( PROCESS_INFORMATION processInfo; memset(&startupInfo,0,sizeof(STARTUPINFOA)); memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install \"" + _r->homePath + "\\ztTap100.inf\" ztTap100").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + if (!CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" install \"" + _r->homePath + tapDriver + "\" ztTap100").c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { RegCloseKey(nwAdapters); throw std::runtime_error(std::string("unable to find or execute devcon at ")+devcon); } @@ -1145,9 +1133,6 @@ EthernetTap::EthernetTap( throw std::runtime_error("unable to convert instance ID GUID to native GUID (invalid NetCfgInstanceId in registry?)"); } - setDhcpEnabled(false); - setDhcp6Enabled(false); - // Disable and enable interface to ensure registry settings take effect { STARTUPINFOA startupInfo; @@ -1211,24 +1196,25 @@ EthernetTap::~EthernetTap() CloseHandle(_tapOvlWrite.hEvent); CloseHandle(_injectSemaphore); - // Disable network device on shutdown #ifdef _WIN64 - const char *devcon = "\\devcon64.exe"; + BOOL is64Bit = TRUE; + const char *devcon = "\\devcon_x64.exe"; #else - BOOL f64 = FALSE; - const char *devcon = ((IsWow64Process(GetCurrentProcess(),&f64) == TRUE) ? "\\devcon64.exe" : "\\devcon32.exe"); + BOOL is64Bit = FALSE; + IsWow64Process(GetCurrentProcess(),&is64Bit); + const char *devcon = ((is64Bit == TRUE) ? "\\devcon_x64.exe" : "\\devcon_x86.exe"); #endif - { - STARTUPINFOA startupInfo; - startupInfo.cb = sizeof(startupInfo); - PROCESS_INFORMATION processInfo; - memset(&startupInfo,0,sizeof(STARTUPINFOA)); - memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); - if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { - WaitForSingleObject(processInfo.hProcess,INFINITE); - CloseHandle(processInfo.hProcess); - CloseHandle(processInfo.hThread); - } + + // Disable network device on shutdown + STARTUPINFOA startupInfo; + startupInfo.cb = sizeof(startupInfo); + PROCESS_INFORMATION processInfo; + memset(&startupInfo,0,sizeof(STARTUPINFOA)); + memset(&processInfo,0,sizeof(PROCESS_INFORMATION)); + if (CreateProcessA(NULL,(LPSTR)(std::string("\"") + _r->homePath + devcon + "\" disable @" + _myDeviceInstanceIdPath).c_str(),NULL,NULL,FALSE,0,NULL,NULL,&startupInfo,&processInfo)) { + WaitForSingleObject(processInfo.hProcess,INFINITE); + CloseHandle(processInfo.hProcess); + CloseHandle(processInfo.hThread); } } @@ -1236,25 +1222,6 @@ void EthernetTap::whack() { } -bool EthernetTap::setDhcpEnabled(bool dhcp) -{ - HKEY tcpIpInterfaces; - if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,"SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\Interfaces",0,KEY_READ|KEY_WRITE,&tcpIpInterfaces) == ERROR_SUCCESS) { - _dhcp = dhcp; - DWORD enable = (dhcp ? 1 : 0); - RegSetKeyValueA(tcpIpInterfaces,_myDeviceInstanceId.c_str(),"EnableDHCP",REG_DWORD,&enable,sizeof(enable)); - RegCloseKey(tcpIpInterfaces); - } else _dhcp = false; - - return _dhcp; -} - -bool EthernetTap::setDhcp6Enabled(bool dhcp) -{ - // TODO - return _dhcp6; -} - void EthernetTap::setDisplayName(const char *dn) { HKEY ifp; @@ -1394,14 +1361,43 @@ bool EthernetTap::updateMulticastGroups(std::set<MulticastGroup> &groups) { std::set<MulticastGroup> newGroups; + // Ensure that groups are added for each IP... this handles the MAC:ADI + // groups that are created from IPv4 addresses. Some of these may end + // up being duplicates of what the IOCTL returns but that's okay since + // the set will filter these. std::set<InetAddress> ipaddrs(allIps()); for(std::set<InetAddress>::const_iterator i(ipaddrs.begin());i!=ipaddrs.end();++i) newGroups.insert(MulticastGroup::deriveMulticastGroupForAddressResolution(*i)); - bool changed = false; + // The ZT1 tap driver supports an IOCTL to get multicast memberships at the L2 + // level... something Windows does not seem to expose ordinarily. This lets + // pretty much anything work... IPv4, IPv6, IPX, oldskool Netbios, who knows... + unsigned char mcastbuf[TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS_OUTPUT_BUF_SIZE]; + DWORD bytesReturned = 0; + if (DeviceIoControl(_tap,TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS,(LPVOID)0,0,(LPVOID)mcastbuf,sizeof(mcastbuf),&bytesReturned,NULL)) { + printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: got %d bytes\n",(int)bytesReturned); + MAC mac; + DWORD i = 0; + while ((i + 6) <= bytesReturned) { + mac.data[0] = mcastbuf[i++]; + mac.data[1] = mcastbuf[i++]; + mac.data[2] = mcastbuf[i++]; + mac.data[3] = mcastbuf[i++]; + mac.data[4] = mcastbuf[i++]; + mac.data[5] = mcastbuf[i++]; + if (mac.isMulticast()) { // exclude the nulls that may be returned or any other junk Windows puts in there + newGroups.insert(MulticastGroup(mac,0)); + printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: %s\n",mac.toString().c_str()); + } + } + } else { + printf("TAP_WIN_IOCTL_GET_MULTICAST_MEMBERSHIPS: failed\n"); + } newGroups.insert(_blindWildcardMulticastGroup); // always join this + bool changed = false; + for(std::set<MulticastGroup>::iterator mg(newGroups.begin());mg!=newGroups.end();++mg) { if (!groups.count(*mg)) { groups.insert(*mg); |