Информация об изменениях

Сообщение Re: получить MAC адрес активного девайса от 14.04.2017 11:41

Изменено 14.04.2017 12:16 Evgeniy Skvortsov

Re: получить MAC адрес активного девайса
Здравствуйте, niXman, Вы писали:

X>собственно, нужно узнать MAC адрес того девайса, с помощью которого машина в данный момент выходит в интернеты. девайсов же может быть несколько.


Простого способа вроде нет, только врукопашную.

1. Получаем локальный активный адрес с помощью пары gethostname() gethostbyname()
2. Получаем список всех ip адресов в системе с помощью GetIpAddrTable()
3. Получаем список всех адаптеров с помощью GetAdaptersInfo

В списке полученном из п. 2 находим запись с таким же ip который получили в п. 1
В списке полученном в п. 3 находим адаптер с нужным интерфейсом
Читаем его MAC

  Насобирал на скорую руку рабочий код из примеров в МСДН
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib, "Iphlpapi.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

int main()
{
    WSAData wsaData;
    in_addr ip;
    char hostname[128];
    if (WSAStartup(0x101, &wsaData) == 0) {
        gethostname(&hostname[0], 128);
        hostent *h = gethostbyname(&hostname[0]);
        ip = *(reinterpret_cast<in_addr *>(*(h->h_addr_list)));
    }
    WSACleanup();
    
    printf("IP adress : %d.%d.%d.%d\n", ip.S_un.S_un_b.s_b1, ip.S_un.S_un_b.s_b2, ip.S_un.S_un_b.s_b3, ip.S_un.S_un_b.s_b4);

    DWORD dwRetVal = 0;
    PMIB_IPADDRTABLE pIPAddrTable;
    DWORD dwSize = 0;

    pIPAddrTable = (MIB_IPADDRTABLE *)MALLOC(sizeof(MIB_IPADDRTABLE));

    if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
        FREE(pIPAddrTable);
        pIPAddrTable = (MIB_IPADDRTABLE *)MALLOC(dwSize);
    }

    if (pIPAddrTable == NULL) {
        printf("Memory allocation failed for GetIpAddrTable\n");
        exit(1);
    }
    if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR) {
        printf("GetIpAddrTable failed with error %d\n", dwRetVal);
        return 0;
    }

    DWORD index = 0;
    for (int i = 0; i < (int)pIPAddrTable->dwNumEntries; i++) {
        if (ip.S_un.S_addr == pIPAddrTable->table[i].dwAddr)
            index = pIPAddrTable->table[i].dwIndex;
    }

    if (pIPAddrTable) {
        FREE(pIPAddrTable);
        pIPAddrTable = NULL;
    }


    ULONG adapter_info_size = 0;
    PIP_ADAPTER_INFO ptr_adapter_info = NULL;
    PIP_ADAPTER_INFO ptr_adapter_info_first = NULL;

    GetAdaptersInfo(ptr_adapter_info, &adapter_info_size);

    ptr_adapter_info_first = ptr_adapter_info = (PIP_ADAPTER_INFO) new(char[adapter_info_size]);

    if (GetAdaptersInfo(ptr_adapter_info, &adapter_info_size) != ERROR_SUCCESS) {
        printf("Error while GetAdaptersInfo\n");
        delete(ptr_adapter_info);
        return(1);
    }

    while (ptr_adapter_info) {
        if (ptr_adapter_info->Index == index) {
            printf("MAC address: ");
            for (char i = 0; i < (int)ptr_adapter_info->AddressLength; i++)
                printf("%02x ", (unsigned char)ptr_adapter_info->Address[i]);
            printf("\n");
            break;

        }
        ptr_adapter_info = ptr_adapter_info->Next;

    }
    delete(ptr_adapter_info_first);

    return 0;
}


У меня работает, в компе встроенная сетевуха и usb wi-fi адаптер, IP и MAC показывает корректно.
В коде мрак и ужас, но это такие примеры в МСДН, да и местами я обработку ошибок выкинул. Надо конечно привести в порядок.
Re: получить MAC адрес активного девайса
Здравствуйте, niXman, Вы писали:

X>собственно, нужно узнать MAC адрес того девайса, с помощью которого машина в данный момент выходит в интернеты. девайсов же может быть несколько.


Простого способа вроде нет, только врукопашную.

1. Получаем локальный активный адрес с помощью пары gethostname() gethostbyname()
2. Получаем список всех ip адресов в системе с помощью GetIpAddrTable()
3. Получаем список всех адаптеров с помощью GetAdaptersInfo

В списке полученном из п. 2 находим запись с таким же ip который получили в п. 1, запоминаем его индекс
В списке полученном в п. 3 находим адаптер с нужным индексом.
Читаем его MAC

  Насобирал на скорую руку рабочий код из примеров в МСДН
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include <windows.h>
#include <winsock2.h>
#include <ws2ipdef.h>
#include <iphlpapi.h>
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,"Ws2_32.lib")
#pragma comment(lib, "Iphlpapi.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

int main()
{
    WSAData wsaData;
    in_addr ip;
    char hostname[128];
    if (WSAStartup(0x101, &wsaData) == 0) {
        gethostname(&hostname[0], 128);
        hostent *h = gethostbyname(&hostname[0]);
        ip = *(reinterpret_cast<in_addr *>(*(h->h_addr_list)));
    }
    WSACleanup();
    
    printf("IP adress : %d.%d.%d.%d\n", ip.S_un.S_un_b.s_b1, ip.S_un.S_un_b.s_b2, ip.S_un.S_un_b.s_b3, ip.S_un.S_un_b.s_b4);

    DWORD dwRetVal = 0;
    PMIB_IPADDRTABLE pIPAddrTable;
    DWORD dwSize = 0;

    pIPAddrTable = (MIB_IPADDRTABLE *)MALLOC(sizeof(MIB_IPADDRTABLE));

    if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
        FREE(pIPAddrTable);
        pIPAddrTable = (MIB_IPADDRTABLE *)MALLOC(dwSize);
    }

    if (pIPAddrTable == NULL) {
        printf("Memory allocation failed for GetIpAddrTable\n");
        exit(1);
    }
    if ((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR) {
        printf("GetIpAddrTable failed with error %d\n", dwRetVal);
        return 0;
    }

    DWORD index = 0;
    for (int i = 0; i < (int)pIPAddrTable->dwNumEntries; i++) {
        if (ip.S_un.S_addr == pIPAddrTable->table[i].dwAddr)
            index = pIPAddrTable->table[i].dwIndex;
    }

    if (pIPAddrTable) {
        FREE(pIPAddrTable);
        pIPAddrTable = NULL;
    }


    ULONG adapter_info_size = 0;
    PIP_ADAPTER_INFO ptr_adapter_info = NULL;
    PIP_ADAPTER_INFO ptr_adapter_info_first = NULL;

    GetAdaptersInfo(ptr_adapter_info, &adapter_info_size);

    ptr_adapter_info_first = ptr_adapter_info = (PIP_ADAPTER_INFO) new(char[adapter_info_size]);

    if (GetAdaptersInfo(ptr_adapter_info, &adapter_info_size) != ERROR_SUCCESS) {
        printf("Error while GetAdaptersInfo\n");
        delete(ptr_adapter_info);
        return(1);
    }

    while (ptr_adapter_info) {
        if (ptr_adapter_info->Index == index) {
            printf("MAC address: ");
            for (char i = 0; i < (int)ptr_adapter_info->AddressLength; i++)
                printf("%02x ", (unsigned char)ptr_adapter_info->Address[i]);
            printf("\n");
            break;

        }
        ptr_adapter_info = ptr_adapter_info->Next;

    }
    delete(ptr_adapter_info_first);

    return 0;
}


У меня работает, в компе встроенная сетевуха и usb wi-fi адаптер, IP и MAC показывает корректно.
В коде мрак и ужас, но это такие примеры в МСДН, да и местами я обработку ошибок выкинул. Надо конечно привести в порядок.