From 85d97f05f6f8e4c1d73cd2bb096806839d16f3b0 Mon Sep 17 00:00:00 2001 From: gcontini <1121667+gcontini@users.noreply.github.com> Date: 周六, 31 10月 2020 10:27:16 +0800 Subject: [PATCH] Pc identifier Mac address issues #108 & #107 --- src/library/os/linux/network.cpp | 1 test/library/os/network_test.cpp | 5 + src/library/os/network.hpp | 2 test/functional/generate-license.cpp | 6 +- src/library/hw_identifier/ethernet.cpp | 20 ++++-- src/library/os/windows/network.cpp | 105 ++++++++++++++++++++++++---------- src/inspector/inspector.cpp | 9 ++ 7 files changed, 102 insertions(+), 46 deletions(-) diff --git a/src/inspector/inspector.cpp b/src/inspector/inspector.cpp index 640071d..eb23c0e 100644 --- a/src/inspector/inspector.cpp +++ b/src/inspector/inspector.cpp @@ -5,6 +5,7 @@ #include <licensecc/licensecc.h> #include <fstream> #include <string.h> +#include <iomanip> #include "../library/base/string_utils.h" #include "../library/ini/SimpleIni.h" #include "../library/os/dmi_info.hpp" @@ -105,10 +106,14 @@ << static_cast<unsigned int>(osAdapter.ipv4_address[2]) << "-" << static_cast<unsigned int>(osAdapter.ipv4_address[1]) << "-" << static_cast<unsigned int>(osAdapter.ipv4_address[0]) << "]" << endl; - cout << " mac address ["; + cout << " mac address [" << std::hex; for (int i = 0; i < 8; i++) { - // print mac + if (i != 0) { + cout << ":"; + } + cout << static_cast<unsigned int>(osAdapter.mac_address[i]); } + cout << "]" << std::dec << endl; } } else { cout << "problem in getting adapter informations:" << ret << endl; diff --git a/src/library/hw_identifier/ethernet.cpp b/src/library/hw_identifier/ethernet.cpp index 55b5197..fe68a51 100644 --- a/src/library/hw_identifier/ethernet.cpp +++ b/src/library/hw_identifier/ethernet.cpp @@ -33,17 +33,25 @@ for (auto &it : adapters) { unsigned int k, data_len; - array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> identifier; + array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> identifier = {}; data_len = use_ip ? sizeof(os::OsAdapterInfo::ipv4_address) : sizeof(os::OsAdapterInfo::mac_address); - - for (k = 0; k < HW_IDENTIFIER_PROPRIETARY_DATA; k++) { - if (k < data_len) { - identifier[k] = use_ip ? it.ipv4_address[k] : it.mac_address[k]; + bool all_zero = true; + for (k = 0; k < data_len && all_zero;k++) { + all_zero = all_zero && ((use_ip ? it.ipv4_address[k] : it.mac_address[k]) == 0); + } + if (all_zero) { + continue; + } + for (k = 1; k < HW_IDENTIFIER_PROPRIETARY_DATA; k++) { + if ((k - 1) < data_len) { + identifier[k] = + use_ip ? it.ipv4_address[k - 1] : it.mac_address[k - 1]; } else { identifier[k] = 42; } } - identifier[0] = identifier[0] & 0x1F; + //identifier[0] = identifier[0] & 0x1F; + identifier[0] = 0; data.push_back(identifier); } diff --git a/src/library/os/linux/network.cpp b/src/library/os/linux/network.cpp index 1281aca..8720c50 100644 --- a/src/library/os/linux/network.cpp +++ b/src/library/os/linux/network.cpp @@ -64,7 +64,6 @@ // if_name_position = ifname_position(ifnames, ifa->ifa_name, if_num); // interface name not seen en advance OsAdapterInfo *currentAdapter; - // FIXME not working if (adapterByName.find(if_name) == adapterByName.end()) { OsAdapterInfo newAdapter; memset(&newAdapter, 0, sizeof(OsAdapterInfo)); diff --git a/src/library/os/network.hpp b/src/library/os/network.hpp index fd991d3..4dbc9aa 100644 --- a/src/library/os/network.hpp +++ b/src/library/os/network.hpp @@ -33,7 +33,7 @@ typedef struct { int id; char description[LCC_ADAPTER_DESCRIPTION_LEN + 1]; - unsigned char mac_address[8]; + unsigned char mac_address[6]; unsigned char ipv4_address[4]; IFACE_TYPE type; } OsAdapterInfo; diff --git a/src/library/os/windows/network.cpp b/src/library/os/windows/network.cpp index 1b0d554..5116d39 100644 --- a/src/library/os/windows/network.cpp +++ b/src/library/os/windows/network.cpp @@ -9,26 +9,34 @@ * Responsibility of this module is to fill OsAdapterInfo structures, in a predictable way (skip loopback/vpn interfaces) */ +#define _CRTDBG_MAP_ALLOC +#define NOMINMAX + #ifdef _MSC_VER #include <Windows.h> #endif #include <iphlpapi.h> #include <unordered_map> #include <stdio.h> +#include <algorithm> +#include <cctype> #pragma comment(lib, "IPHLPAPI.lib") #include "../../base/string_utils.h" #include "../../base/logger.h" #include "../network.hpp" +#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) +#define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) + namespace license { namespace os { using namespace std; -static int translate(char ipStringIn[16], unsigned char ipv4[4]) { +static int translate(const char ipStringIn[16], unsigned char ipv4[4]) { size_t index = 0; - char *str2 = ipStringIn; /* save the pointer */ + const char *str2 = ipStringIn; /* save the pointer */ while (*str2) { if (isdigit((unsigned char)*str2)) { ipv4[index] *= 10; @@ -40,34 +48,59 @@ } return 0; } -/** + +int score(const OsAdapterInfo &a) { + int score = 0; + bool allzero = true; + const char *bads[] = {"virtual", "ppp", "tunnel", "vpn"}; + const char *goods[] = {"realtek", "intel", "wireless"}; + + for (int i = 0; i < sizeof(a.description) && allzero; i++) { + allzero = allzero && (a.description[i] == 0); + } + if (!allzero) { + score++; + } + + string descr=string(a.description); + std::transform(descr.begin(), descr.end(), descr.begin(), [](unsigned char c) { return std::tolower(c); }); + for (auto bad: bads) { + score += descr.find(bad) == std::string::npos ? 1 : -1; + } + for (auto good : goods) { + score += descr.find(good) == std::string::npos ? -1 : 1; + } + return score; +} + +bool cmp(const OsAdapterInfo &a, const OsAdapterInfo &b) { return score(a) >= score(b); } + /** * * @param adapterInfos * @param adapter_info_size * @return */ FUNCTION_RETURN getAdapterInfos(vector<OsAdapterInfo> &adapterInfos) { - unordered_map<string, OsAdapterInfo> adapterByName; + vector<OsAdapterInfo> tmpAdapters; FUNCTION_RETURN f_return = FUNC_RET_OK; DWORD dwStatus; - PIP_ADAPTER_INFO pAdapterInfo; - DWORD dwBufLen = sizeof(IP_ADAPTER_INFO); - // Make an initial call to GetAdaptersInfo to get the necessary size into the ulOutBufLen variable - pAdapterInfo = (PIP_ADAPTER_INFO)malloc(dwBufLen); + ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO) *10; + IP_ADAPTER_INFO *pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(sizeof(IP_ADAPTER_INFO) * 10); + if (pAdapterInfo == nullptr) { return FUNC_RET_ERROR; } - dwStatus = GetAdaptersInfo( // Call GetAdapterInfo + dwStatus = GetAdaptersInfo( pAdapterInfo, // [out] buffer to receive data - &dwBufLen // [in] size of receive data buffer + &ulOutBufLen // [in] size of receive data buffer ); // Incase the buffer was too small, reallocate with the returned dwBufLen if (dwStatus == ERROR_BUFFER_OVERFLOW) { - free(pAdapterInfo); - pAdapterInfo = (PIP_ADAPTER_INFO)malloc(dwBufLen); + FREE(pAdapterInfo); + pAdapterInfo = (IP_ADAPTER_INFO *)MALLOC(ulOutBufLen); // Will only fail if buffer cannot be allocated (out of memory) if (pAdapterInfo == nullptr) { @@ -76,7 +109,7 @@ dwStatus = GetAdaptersInfo( // Call GetAdapterInfo pAdapterInfo, // [out] buffer to receive data - &dwBufLen // [in] size of receive data buffer + &ulOutBufLen // [in] size of receive data buffer ); switch (dwStatus) { @@ -84,38 +117,48 @@ break; case ERROR_BUFFER_OVERFLOW: - free(pAdapterInfo); + FREE(pAdapterInfo); return FUNC_RET_BUFFER_TOO_SMALL; default: - free(pAdapterInfo); + FREE(pAdapterInfo); return FUNC_RET_ERROR; } } - PIP_ADAPTER_INFO pAdapter = pAdapterInfo; + IP_ADAPTER_INFO* pAdapter = pAdapterInfo; FUNCTION_RETURN result = FUNC_RET_OK; while (pAdapter) { - OsAdapterInfo ai = {}; - strncpy(ai.description, pAdapter->Description, - min((int)sizeof(ai.description), MAX_ADAPTER_DESCRIPTION_LENGTH)); - memcpy(ai.mac_address, pAdapter->Address, 8); - translate(pAdapter->IpAddressList.IpAddress.String, ai.ipv4_address); - ai.type = IFACE_TYPE_ETHERNET; + if (pAdapter->Type == MIB_IF_TYPE_ETHERNET) { + OsAdapterInfo ai = {}; + LOG_DEBUG("Ethernet found %s, %s, mac_l: %d", pAdapter->AdapterName, pAdapter->Description, pAdapter->AddressLength); + if (pAdapter->AddressLength > 0) { + bool allzero = true; + const size_t size_to_be_copied = std::min(sizeof(ai.mac_address), (size_t)pAdapter->AddressLength); + for (int i = 0; i < size_to_be_copied && allzero; i++) { + allzero = allzero && (pAdapter->Address[i] == 0); + } + if (!allzero) { + strncpy(ai.description, pAdapter->Description, + min(sizeof(ai.description) - 1, (size_t)MAX_ADAPTER_DESCRIPTION_LENGTH)); + memcpy(ai.mac_address, pAdapter->Address, size_to_be_copied); + translate(pAdapter->IpAddressList.IpAddress.String, ai.ipv4_address); + ai.type = IFACE_TYPE_ETHERNET; + tmpAdapters.push_back(ai); + } + } + } pAdapter = pAdapter->Next; - adapterByName[string(ai.description)] = ai; } - free(pAdapterInfo); + if (pAdapterInfo!=nullptr) { + FREE(pAdapterInfo); + } - // FIXME sort by eth , enps, wlan - if (adapterByName.size() == 0) { + if (tmpAdapters.size() == 0) { f_return = FUNC_RET_NOT_AVAIL; } else { - f_return = FUNC_RET_OK; - adapterInfos.reserve(adapterByName.size()); - for (auto &it : adapterByName) { - adapterInfos.push_back(it.second); - } + std::sort(tmpAdapters.begin(), tmpAdapters.end(), cmp); + adapterInfos = std::move(tmpAdapters); } return f_return; } diff --git a/test/functional/generate-license.cpp b/test/functional/generate-license.cpp index cdaa175..a1a760a 100644 --- a/test/functional/generate-license.cpp +++ b/test/functional/generate-license.cpp @@ -48,11 +48,11 @@ } cout << "executing :" << ss.str() << endl; const int retCode = std::system(ss.str().c_str()); - BOOST_CHECK_EQUAL(retCode, 0); - BOOST_ASSERT_MSG(fs::exists(license_fname), "license exists"); + BOOST_REQUIRE_EQUAL(retCode, 0); + BOOST_REQUIRE_MESSAGE(fs::exists(license_fname), "license exists"); CSimpleIniA ini; const SI_Error rc = ini.LoadFile(license_fname.c_str()); - BOOST_CHECK_GE(rc, 0); + BOOST_REQUIRE_GE(rc, 0); const int sectionSize = ini.GetSectionSize(LCC_PROJECT_NAME); BOOST_CHECK_GT(sectionSize, 0); return license_fname.string(); diff --git a/test/library/os/network_test.cpp b/test/library/os/network_test.cpp index 50e4254..ac599d8 100644 --- a/test/library/os/network_test.cpp +++ b/test/library/os/network_test.cpp @@ -18,8 +18,8 @@ BOOST_AUTO_TEST_CASE(read_network_adapters) { std::vector<license::os::OsAdapterInfo> adapters; - // we can suppose every test environment other than docker has at least one network interface (it's hard to - // download this source code) + // we can suppose every test environment other than docker has at least + // one network interface FUNCTION_RETURN result = getAdapterInfos(adapters); ExecutionEnvironment exec_env; if (result != FUNC_RET_OK && exec_env.is_docker()) { @@ -27,6 +27,7 @@ return; } BOOST_CHECK_EQUAL(result, FUNC_RET_OK); + BOOST_CHECK_GT(adapters.size(),0); for (auto& it : adapters) { cout << "Interface found: " << string(it.description) << endl; BOOST_CHECK_GT(strlen(it.description), 0); -- Gitblit v1.9.1