bool CEXIETHERNET::RecvStart() { if (!IsActivated()) return false; if (mHRecvEvent == INVALID_HANDLE_VALUE) RecvInit(); DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE, (LPDWORD)&mRecvBufferLength, &mReadOverlapped); if (res) { // Since the read is synchronous here, complete immediately RecvHandlePacket(); return true; } else { DWORD err = GetLastError(); if (err == ERROR_IO_PENDING) { return true; } // Unexpected error ERROR_LOG(SP1, "Failed to recieve packet with error 0x%X", err); return false; } }
bool CEXIETHERNET::RecvStart() { if (!IsActivated()) return false; if (mHRecvEvent == INVALID_HANDLE_VALUE) RecvInit(); DWORD res = ReadFile(mHAdapter, mRecvBuffer, BBA_RECV_SIZE, (LPDWORD)&mRecvBufferLength, &mReadOverlapped); if (!res && (GetLastError() != ERROR_IO_PENDING)) { // error occurred return false; } if (res) { // Completed immediately RecvHandlePacket(); } return true; }
bool CEXIETHERNET::RecvStart() { if (!readThread.joinable()) RecvInit(); readEnabled.store(true); return true; }
bool CEXIETHERNET::RecvStart() { #ifdef __linux__ if (!readThread.joinable()) RecvInit(); readEnabled = true; return true; #else NOTIMPLEMENTED("RecvStart"); return false; #endif }
bool CEXIETHERNET::Activate() { #ifdef __linux__ if (IsActivated()) return true; // Assumes that there is a TAP device named "Dolphin" preconfigured for // bridge/NAT/whatever the user wants it configured. if ((fd = open("/dev/net/tun", O_RDWR)) < 0) { ERROR_LOG(SP1, "Couldn't open /dev/net/tun, unable to init BBA"); return false; } struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_ONE_QUEUE; const int MAX_INTERFACES = 32; for (int i = 0; i < MAX_INTERFACES; ++i) { strncpy(ifr.ifr_name, StringFromFormat("Dolphin%d", i).c_str(), IFNAMSIZ); int err; if ((err = ioctl(fd, TUNSETIFF, (void*)&ifr)) < 0) { if (i == (MAX_INTERFACES - 1)) { close(fd); fd = -1; ERROR_LOG(SP1, "TUNSETIFF failed: Interface=%s err=%d", ifr.ifr_name, err); return false; } } else { break; } } ioctl(fd, TUNSETNOCSUM, 1); INFO_LOG(SP1, "BBA initialized with associated tap %s", ifr.ifr_name); return RecvInit(); #else NOTIMPLEMENTED("Activate"); return false; #endif }
bool CEXIETHERNET::Activate() { if (IsActivated()) return true; // Assumes TunTap OS X is installed, and /dev/tun0 is not in use // and readable / writable by the logged-in user if ((fd = open("/dev/tap0", O_RDWR)) < 0) { ERROR_LOG(SP1, "Couldn't open /dev/tap0, unable to init BBA"); return false; } INFO_LOG(SP1, "BBA initialized."); return RecvInit(); }
bool CEXIETHERNET::Activate() { if (IsActivated()) return true; DWORD len; std::vector<std::basic_string<TCHAR>> device_guids; if (!Win32TAPHelper::GetGUIDs(device_guids)) { ERROR_LOG(SP1, "Failed to find a TAP GUID"); return false; } for (size_t i = 0; i < device_guids.size(); i++) { if (Win32TAPHelper::OpenTAP(mHAdapter, device_guids.at(i))) { INFO_LOG(SP1, "OPENED %s", device_guids.at(i).c_str()); break; } } if (mHAdapter == INVALID_HANDLE_VALUE) { PanicAlert("Failed to open any TAP"); return false; } /* get driver version info */ ULONG info[3]; if (DeviceIoControl(mHAdapter, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof(info), &len, nullptr)) { INFO_LOG(SP1, "TAP-Win32 Driver Version %d.%d %s", info[0], info[1], info[2] ? "(DEBUG)" : ""); } if (!(info[0] > TAP_WIN32_MIN_MAJOR || (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR))) { PanicAlertT("ERROR: This version of Dolphin requires a TAP-Win32 driver" " that is at least version %d.%d -- If you recently upgraded your Dolphin" " distribution, a reboot is probably required at this point to get" " Windows to see the new driver.", TAP_WIN32_MIN_MAJOR, TAP_WIN32_MIN_MINOR); return false; } /* set driver media status to 'connected' */ ULONG status = TRUE; if (!DeviceIoControl(mHAdapter, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, nullptr)) { ERROR_LOG(SP1, "WARNING: The TAP-Win32 driver rejected a" "TAP_IOCTL_SET_MEDIA_STATUS DeviceIoControl call."); return false; } /* initialize read/write events */ mReadOverlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); mWriteOverlapped.hEvent = CreateEvent(nullptr, TRUE, FALSE, nullptr); if (mReadOverlapped.hEvent == nullptr || mWriteOverlapped.hEvent == nullptr) return false; mWriteBuffer.reserve(1518); return RecvInit(); }