diff options
author | Christian Pointner <equinox@anytun.org> | 2009-01-21 01:47:19 +0000 |
---|---|---|
committer | Christian Pointner <equinox@anytun.org> | 2009-01-21 01:47:19 +0000 |
commit | 8c548fa566d2c19f2f31f8ed5f5c0917a232441d (patch) | |
tree | 49092cd318d8354bbb3de5a3dd65a2689f93c4f2 /src/win32 | |
parent | tun mode works now on windows (diff) |
Windows tunDevice cleanup
Diffstat (limited to 'src/win32')
-rw-r--r-- | src/win32/tunDevice.cpp | 106 |
1 files changed, 68 insertions, 38 deletions
diff --git a/src/win32/tunDevice.cpp b/src/win32/tunDevice.cpp index e6167d3..8f91414 100644 --- a/src/win32/tunDevice.cpp +++ b/src/win32/tunDevice.cpp @@ -49,6 +49,53 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifc if(conf_.type_ != TYPE_TUN && conf_.type_ != TYPE_TAP) throw std::runtime_error("unable to recognize type of device (tun or tap)"); + handle_ = INVALID_HANDLE_VALUE; + if(!getAdapter(dev_name)) + throw std::runtime_error("can't find any suitable device"); + + if(handle_ == INVALID_HANDLE_VALUE) { + std::stringstream tapname; + tapname << USERMODEDEVICEDIR << actual_node_ << TAPSUFFIX; + handle_ = CreateFile(tapname.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); + if(handle_ == INVALID_HANDLE_VALUE) { + std::stringstream msg; + msg << "Unable to open device: " << actual_node_ << " (" << actual_name_ << "): " << LogErrno(GetLastError()); + throw std::runtime_error(msg.str()); + } + } + + DWORD err; + if(conf_.type_ == TYPE_TUN) { + u_long ep[2]; + ep[0] = htonl(conf_.local_.getNetworkAddressV4().to_ulong()); + ep[1] = htonl(conf_.remote_netmask_.getNetworkAddressV4().to_ulong()); + err = performIoControl(TAP_IOCTL_CONFIG_POINT_TO_POINT, ep, sizeof(ep), ep, sizeof(ep)); + if(err != ERROR_SUCCESS) { + CloseHandle(handle_); + std::stringstream msg; + msg << "Unable to set device point-to-point mode: " << LogErrno(err); + throw std::runtime_error(msg.str()); + } + } + + int status = true; + err = performIoControl(TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status)); + if(err != ERROR_SUCCESS) { + CloseHandle(handle_); + std::stringstream msg; + msg << "Unable to set device media status: " << LogErrno(err); + throw std::runtime_error(msg.str()); + } + +// if(ifcfg_lp != "" && ifcfg_rnmp != "") +// do_ifconfig(); + + roverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + woverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); +} + +bool TunDevice::getAdapter(std::string const& dev_name) +{ HKEY key, key2; LONG err = RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_CONNECTIONS_KEY, 0, KEY_ENUMERATE_SUB_KEYS, &key); if(err != ERROR_SUCCESS) { @@ -57,7 +104,6 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifc throw std::runtime_error(msg.str()); } - handle_ = INVALID_HANDLE_VALUE; bool found = false; DWORD len; char adapterid[REG_KEY_LENGTH]; @@ -108,50 +154,34 @@ TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifc } } RegCloseKey(key); - - if(!found) - throw std::runtime_error("can't find any suitable device"); - if(handle_ == INVALID_HANDLE_VALUE) { - std::stringstream tapname; - tapname << USERMODEDEVICEDIR << adapterid << TAPSUFFIX; - handle_ = CreateFile(tapname.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0); - if(handle_ == INVALID_HANDLE_VALUE) { - std::stringstream msg; - msg << "Unable to open device: " << adapterid << " (" << adaptername << "): " << LogErrno(GetLastError()); - throw std::runtime_error(msg.str()); - } - } actual_node_ = adapterid; actual_name_ = adaptername; + return found; +} - if(conf_.type_ == TYPE_TUN) { - u_long ep[2]; - ep[0] = htonl(conf_.local_.getNetworkAddressV4().to_ulong()); - ep[1] = htonl(conf_.remote_netmask_.getNetworkAddressV4().to_ulong()); - if(!DeviceIoControl(handle_, TAP_IOCTL_CONFIG_POINT_TO_POINT, ep, sizeof(ep), ep, sizeof(ep), &len, NULL)) { - CloseHandle(handle_); - std::stringstream msg; - msg << "Unable to set device point-to-point mode: " << LogErrno(GetLastError()); - throw std::runtime_error(msg.str()); - } +DWORD TunDevice::performIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inBufferSize, LPVOID outBuffer, DWORD outBufferSize) +{ + OVERLAPPED overlapped; + overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + overlapped.Offset = 0; + overlapped.OffsetHigh = 0; + + DWORD len; + if(!DeviceIoControl(handle_, controlCode, inBuffer, inBufferSize, outBuffer, outBufferSize, &len, &overlapped)) { + DWORD err = GetLastError(); + if(err == ERROR_IO_PENDING) { + WaitForSingleObject(overlapped.hEvent, INFINITE); + if(!GetOverlappedResult(handle_, &overlapped, &len, FALSE)) + return GetLastError(); + } + else + return GetLastError(); } - - int status = true; - if(!DeviceIoControl(handle_, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL)) { - CloseHandle(handle_); - std::stringstream msg; - msg << "Unable to set device media status: " << LogErrno(GetLastError()); - throw std::runtime_error(msg.str()); - } - -// if(ifcfg_lp != "" && ifcfg_rnmp != "") -// do_ifconfig(); - - roverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - woverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + return ERROR_SUCCESS; } + TunDevice::~TunDevice() { CloseHandle(handle_); |