|
@@ -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);
|