получить MAC адрес активного девайса
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.04.17 07:05
Оценка:
привет!

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

подскажите, куда гуглить?



спасибо.
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: получить MAC адрес активного девайса
От: ononim  
Дата: 14.04.17 09:05
Оценка: +1
X>собственно, нужно узнать MAC адрес того девайса, с помощью которого машина в данный момент выходит в интернеты. девайсов же может быть несколько.
X>подскажите, куда гуглить?
GetBestRoute(интернеты)
Как много веселых ребят, и все делают велосипед...
Re[2]: получить MAC адрес активного девайса
От: niXman Ниоткуда https://github.com/niXman
Дата: 14.04.17 11:32
Оценка:
спасибо!

вот только я не понял, как получить MAC адрес используемого девайса?
смотрю на структуру MIB_IPFORWARDROW, и не вижу нужного мембера...
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: получить MAC адрес активного девайса
От: Evgeniy Skvortsov Россия  
Дата: 14.04.17 11:41
Оценка: 22 (2) +1
Здравствуйте, 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 показывает корректно.
В коде мрак и ужас, но это такие примеры в МСДН, да и местами я обработку ошибок выкинул. Надо конечно привести в порядок.
Отредактировано 14.04.2017 12:16 Evgeniy Skvortsov . Предыдущая версия . Еще …
Отредактировано 14.04.2017 11:44 Evgeniy Skvortsov . Предыдущая версия .
Re: получить MAC адрес активного девайса
От: Burbulis1978  
Дата: 14.04.17 12:01
Оценка:
Здравствуйте, niXman, Вы писали:

X>привет!


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


X>подскажите, куда гуглить?




X>спасибо.


Скажу только одно слово:
iphlpapi.
Re[3]: получить MAC адрес активного девайса
От: ononim  
Дата: 14.04.17 12:30
Оценка:
X>вот только я не понял, как получить MAC адрес используемого девайса?
X>смотрю на структуру MIB_IPFORWARDROW, и не вижу нужного мембера...
мембер зовется dwForwardIfIndex, GetIfTable выдает соответствие dwIndex — bPhysAddr.

Кстати, что значит "используемый девайс"?
Вот если у меня дома комп, в локальной домашней сети и в него откнут 3G свисток через который интернеты — какой из этих девайсов используемый?
Или вот у меня интернет через VPN через локалку, но сайт провайдера открывается напрямую, а все остальные интернеты — через VPN (который сам по себе является виртуальным интерфейсом)
Можно усложнить схему до нескольких интерфейсов каждый из которых смотрит в интернеты, но командой route юзер зароутил некоторые сайты через одну сетевуху, а некоторые — через другую. И какой из них используемый?
Как много веселых ребят, и все делают велосипед...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.