gcontini
2020-05-02 4bd7da9ff2eb06c11b1f54e2b8e2cfb44af56776
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
 * @file network_id.c
 * @date 16 Sep 2014
 * @brief File containing network interface detection functions for Windows.
 *
 * The only public function of this module is #getAdapterInfos(OsAdapterInfo *,
 *        size_t *), other functions are either static or inline.
 *
 * Responsibility of this module is to fill OsAdapterInfo structures, in a predictable way (skip loopback/vpn interfaces)
 */
 
#ifdef _MSC_VER
#include <Windows.h>
#endif
#include <iphlpapi.h>
#include <unordered_map>
#include <stdio.h>
//#pragma comment(lib, "IPHLPAPI.lib")
 
#include "../../base/string_utils.h"
#include "../../base/logger.h"
#include "../network.hpp"
 
namespace license {
namespace os {
using namespace std;
 
static int translate(char ipStringIn[16], unsigned char ipv4[4]) {
    size_t index = 0;
 
    char *str2 = ipStringIn; /* save the pointer */
    while (*str2) {
        if (isdigit((unsigned char)*str2)) {
            ipv4[index] *= 10;
            ipv4[index] += *str2 - '0';
        } else {
            index++;
        }
        str2++;
    }
    return 0;
}
/**
 *
 * @param adapterInfos
 * @param adapter_info_size
 * @return
 */
FUNCTION_RETURN getAdapterInfos(vector<OsAdapterInfo> &adapterInfos) {
    unordered_map<string, OsAdapterInfo> adapterByName;
    FUNCTION_RETURN f_return = FUNC_RET_OK;
    DWORD dwStatus;
    int adapter_info_size;
    PIP_ADAPTER_INFO pAdapterInfo;
    DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
 
    unsigned int i = 3;
    do {
        pAdapterInfo = (PIP_ADAPTER_INFO)malloc(dwBufLen);
        dwStatus = GetAdaptersInfo(     // Call GetAdapterInfo
            pAdapterInfo,  // [out] buffer to receive data
            &dwBufLen  // [in] size of receive data buffer
        );
        if (dwStatus != NO_ERROR && pAdapterInfo != nullptr) {
            free(pAdapterInfo);
            pAdapterInfo = nullptr;
        }
    } while (dwStatus == ERROR_BUFFER_OVERFLOW && i-- > 0);
 
    if (dwStatus == ERROR_BUFFER_OVERFLOW) {
        return FUNC_RET_ERROR;
    }
 
    adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO);
    if (adapter_info_size == 0) {
        return FUNC_RET_NOT_AVAIL;
    }
 
    PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    i = 0;
    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;
        i++;
        pAdapter = pAdapter->Next;
        if (i == adapter_info_size) {
            result = FUNC_RET_BUFFER_TOO_SMALL;
            break;
        }
        adapterByName[string(ai.description)] = ai;
    }
    free(pAdapterInfo);
 
    // FIXME sort by eth , enps, wlan
    if (adapterByName.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);
        }
    }
    return f_return;
}
 
}  // namespace os
}  // namespace license