gcontini
2020-10-31 85d97f05f6f8e4c1d73cd2bb096806839d16f3b0
Pc identifier Mac address issues #108 & #107
7个文件已修改
148 ■■■■■ 已修改文件
src/inspector/inspector.cpp 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/ethernet.cpp 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/network.cpp 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/network.hpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/network.cpp 105 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/generate-license.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/os/network_test.cpp 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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;
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);
    }
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));
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;
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;
}
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();
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);