// Get whether the local-bridging is supported by current OS bool IsBridgeSupported() { UINT type = GetOsInfo()->OsType; if (OS_IS_WINDOWS(type)) { if (IsEthSupported()) { return true; } else { bool ret = false; #ifdef OS_WIN32 ret = MsIsAdmin(); #endif // OS_WIN32 return ret; } } else { return IsEthSupported(); } }
// Enumerate all devices UINT EtEnumAllDevice(EL *e, RPC_ENUM_DEVICE *t) { TOKEN_LIST *eth; UINT i; if (IsEthSupported() == false) { return ERR_NOT_SUPPORTED; } FreeRpcEnumDevice(t); Zero(t, sizeof(RPC_ENUM_DEVICE)); eth = GetEthList(); t->NumItem = eth->NumTokens; t->Items = ZeroMalloc(sizeof(RPC_ENUM_DEVICE_ITEM) * t->NumItem); for (i = 0;i < eth->NumTokens;i++) { char *name = eth->Token[i]; RPC_ENUM_DEVICE_ITEM *item = &t->Items[i]; StrCpy(item->DeviceName, sizeof(item->DeviceName), name); } FreeToken(eth); return ERR_NO_ERROR; }
// Get network connection name from Ethernet device name void GetEthNetworkConnectionName(wchar_t *dst, UINT size, char *device_name) { WP_ADAPTER *t; char *tmp = NULL, guid[MAX_SIZE]; wchar_t *ncname = NULL; UniStrCpy(dst, size, L""); // Validate arguments if (device_name == NULL || IsEthSupported() == false || IsNt() == false || MsIsWin2000OrGreater() == false) { return; } Lock(eth_list_lock); InitEthAdaptersList(); t = Win32EthSearch(device_name); if (t == NULL) { Unlock(eth_list_lock); return; } tmp = CopyStr(t->Name); Unlock(eth_list_lock); if (IsEmptyStr(t->Guid) == false) { StrCpy(guid, sizeof(guid), t->Guid); Free(tmp); } else { ReplaceStr(guid, sizeof(guid), tmp, "\\Device\\SEE_", ""); Free(tmp); ReplaceStr(guid, sizeof(guid), guid, "\\Device\\NPF_", ""); ReplaceStr(guid, sizeof(guid), guid, "\\Device\\PCD_", ""); } if(guid == NULL) { return; } ncname = MsGetNetworkConnectionName(guid); if(ncname != NULL) { UniStrCpy(dst, size, ncname); } Free(ncname); }
// Get whether WinPcap is needed bool IsNeedWinPcap() { if (IsBridgeSupported() == false) { // Not in Windows return false; } else { // Windows if (IsEthSupported()) { // Already success to access the Ethernet device return false; } else { // Failed to access the Ethernet device return true; } } }
// Get VLAN tag pass-through availability of all devices bool EnumEthVLanWin32(RPC_ENUM_ETH_VLAN *t) { UINT i; LIST *o; // Validate arguments if (t == NULL) { return false; } Zero(t, sizeof(RPC_ENUM_ETH_VLAN)); if (MsIsWin2000OrGreater() == false) { return false; } if (IsEthSupported() == false) { return false; } // Get device list Lock(eth_list_lock); InitEthAdaptersList(); o = NewListFast(CmpRpcEnumEthVLan); for (i = 0;i < LIST_NUM(eth_list);i++) { WP_ADAPTER *a = LIST_DATA(eth_list, i); if (IsEmptyStr(a->Guid) == false) { char class_key[MAX_SIZE]; char short_key[MAX_SIZE]; if (GetClassRegKeyWin32(class_key, sizeof(class_key), short_key, sizeof(short_key), a->Guid)) { char *device_instance_id = MsRegReadStr(REG_LOCAL_MACHINE, class_key, "DeviceInstanceID"); if (IsEmptyStr(device_instance_id)) { Free(device_instance_id); device_instance_id = SearchDeviceInstanceIdFromShortKey(short_key); } if (IsEmptyStr(device_instance_id) == false) { char device_key[MAX_SIZE]; char *service_name; Format(device_key, sizeof(device_key), "SYSTEM\\CurrentControlSet\\Enum\\%s", device_instance_id); service_name = MsRegReadStr(REG_LOCAL_MACHINE, device_key, "Service"); if (IsEmptyStr(service_name) == false) { char service_key[MAX_SIZE]; char *sys; Format(service_key, sizeof(service_key), "SYSTEM\\CurrentControlSet\\services\\%s", service_name); sys = MsRegReadStr(REG_LOCAL_MACHINE, service_key, "ImagePath"); if (IsEmptyStr(sys) == false) { char sysname[MAX_PATH]; GetFileNameFromFilePath(sysname, sizeof(sysname), sys); Trim(sysname); if (EndWith(sysname, ".sys")) { // device found RPC_ENUM_ETH_VLAN_ITEM *e = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM)); StrCpy(e->DeviceName, sizeof(e->DeviceName), a->Title); StrCpy(e->Guid, sizeof(e->Guid), a->Guid); StrCpy(e->DeviceInstanceId, sizeof(e->DeviceInstanceId), device_instance_id); StrCpy(e->DriverName, sizeof(e->DriverName), sysname); // Get VLAN tag pass-through availability of the device GetVLanSupportStatus(e); // Get current pass-through setting of the device GetVLanEnableStatus(e); Insert(o, e); } } Free(sys); } Free(service_name); } Free(device_instance_id); } } } t->NumItem = LIST_NUM(o); t->Items = ZeroMalloc(sizeof(RPC_ENUM_ETH_VLAN_ITEM) * i); for (i = 0;i < LIST_NUM(o);i++) { RPC_ENUM_ETH_VLAN_ITEM *e = LIST_DATA(o, i); Copy(&t->Items[i], e, sizeof(RPC_ENUM_ETH_VLAN_ITEM)); Free(e); } ReleaseList(o); Unlock(eth_list_lock); return true; }
TOKEN_LIST *GetEthListEx(UINT *total_num_including_hidden) { TOKEN_LIST *ret; UINT i; UINT j; UINT dummy_int; MS_ADAPTER_LIST *adapter_list; if (IsEthSupported() == false) { return NULL; } if (total_num_including_hidden == NULL) { total_num_including_hidden = &dummy_int; } *total_num_including_hidden = 0; Lock(eth_list_lock); InitEthAdaptersList(); adapter_list = MsCreateAdapterList(); ret = ZeroMalloc(sizeof(TOKEN_LIST)); ret->NumTokens = LIST_NUM(eth_list); ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens); j = 0; for (i = 0;i < ret->NumTokens;i++) { char tmp[MAX_SIZE]; WP_ADAPTER *a = LIST_DATA(eth_list, i); MS_ADAPTER *msa = NULL; bool show = true; if (Win32EthGetShowAllIf() == false) { msa = MsGetAdapterByGuidFromList(adapter_list, a->Guid); if (InStr(a->Title, "vpn client adapter")) { // Hide virtual NIC for VPN client show = false; } if (InStr(a->Title, "tunnel adapter")) { // Hide tunnel adapter show = false; } if (InStr(a->Title, "teredo tunnel")) { // Hide tunnel adapter show = false; } if (InStr(a->Title, "MS Tunnel Interface")) { // Hide tunnel adapter show = false; } if (InStr(a->Title, "pseudo-interface")) { // Hide tunnel adapter show = false; } } if (msa != NULL) { // Hide except physical Ethernet NIC if (msa->IsNotEthernetLan) { show = false; } MsFreeAdapter(msa); } Win32EthMakeCombinedName(tmp, sizeof(tmp), a->Title, a->Guid); if (show) { ret->Token[j++] = CopyStr(tmp); Debug("%s - %s\n", a->Guid, a->Title); } } *total_num_including_hidden = ret->NumTokens; ret->NumTokens = j; Unlock(eth_list_lock); MsFreeAdapterList(adapter_list); return ret; }
ETH *OpenEthInternal(char *name, bool local, bool tapmode, char *tapaddr) { WP_ADAPTER *t; ETH *e; ADAPTER *a = NULL; HANDLE h; CANCEL *c; MS_ADAPTER *ms; char name_with_id[MAX_SIZE]; SU *su = NULL; SU_ADAPTER *su_adapter = NULL; // Validate arguments if (name == NULL || IsEthSupported() == false) { return NULL; } if (tapmode) { // Tap is not supported in Windows return NULL; } Lock(eth_list_lock); InitEthAdaptersList(); t = Win32EthSearch(name); if (t == NULL) { Unlock(eth_list_lock); return NULL; } Debug("OpenEthInternal: %s\n", t->Name); if (StartWith(t->Name, SL_ADAPTER_ID_PREFIX)) { // Open with SU su = SuInit(); if (su == NULL) { // Fail to initialize SU Unlock(eth_list_lock); return NULL; } su_adapter = SuOpenAdapter(su, t->Name); if (su_adapter == NULL) { // Fail to get adapter SuFree(su); Unlock(eth_list_lock); return NULL; } is_using_selow = true; } else { // Open with SEE a = wp->PacketOpenAdapter(t->Name); if (a == NULL) { Unlock(eth_list_lock); return NULL; } if (IsWin32BridgeWithSee() == false) { MsSetThreadSingleCpu(); } is_using_selow = false; } e = ZeroMalloc(sizeof(ETH)); e->Name = CopyStr(t->Name); Win32EthMakeCombinedName(name_with_id, sizeof(name_with_id), t->Title, t->Guid); e->Title = CopyStr(name_with_id); if (su_adapter != NULL) { // SU e->SuAdapter = su_adapter; e->Su = su; // Get event object h = e->SuAdapter->hEvent; c = NewCancelSpecial(h); e->Cancel = c; } else { // SEE e->Adapter = a; wp->PacketSetBuff(e->Adapter, BRIDGE_WIN32_ETH_BUFFER); wp->PacketSetHwFilter(e->Adapter, local ? 0x0080 : 0x0020); wp->PacketSetMode(e->Adapter, PACKET_MODE_CAPT); wp->PacketSetReadTimeout(e->Adapter, -1); wp->PacketSetNumWrites(e->Adapter, 1); if (wp->PacketSetLoopbackBehavior != NULL) { // Filter loopback packet in kernel if (GET_KETA(GetOsType(), 100) >= 3) { if (MsIsWindows8() == false) { // Enable for Windows XP, Server 2003 or later // But disable for Windows 8 or later bool ret = wp->PacketSetLoopbackBehavior(e->Adapter, 1); Debug("*** PacketSetLoopbackBehavior: %u\n", ret); e->LoopbackBlock = ret; } } } // Get event object h = wp->PacketGetReadEvent(e->Adapter); c = NewCancelSpecial(h); e->Cancel = c; e->Packet = wp->PacketAllocatePacket(); e->PutPacket = wp->PacketAllocatePacket(); } e->Buffer = Malloc(BRIDGE_WIN32_ETH_BUFFER); e->BufferSize = BRIDGE_WIN32_ETH_BUFFER; e->PacketQueue = NewQueue(); // Get MAC address by GUID ms = MsGetAdapterByGuid(t->Guid); if (ms != NULL) { if (ms->AddressSize == 6) { Copy(e->MacAddress, ms->Address, 6); } MsFreeAdapter(ms); } Unlock(eth_list_lock); return e; }