Определение MAC-адреса
Для определения MAC-адреса удалённого компьютера можно использовать NetBios:
Use Netapi32.lib
НО! На машине NetBios может быть и выключен. Тогда можно вытащить его из таблицы IPMAC если хост вообще использует IP-протокол. Технология следующая: мы посыалем хосту любой IP-пакет, например по UDP. Система обязательно широковещательным ARP-пакетом запросит его MAC-адрес и если получит, занесёт его в таблицу IPMAC. Откуда мы его и заберём. Абсолютно неважно, какой IP-based протокол будет использован, и будет ли он установлен и/или принят удалённым хостом. Важно лишь то, что система захочет отослать IP-пакет, а для этого она обязательно должна узнать его MAC.
Пример консольного приложения:
PPS: MAC-адрес этто физический адрес устройства, и в общем случае
может иметь длинну отличную от 6 байт.
NCB SNcb; // Структура для работы с NetBiosDeclared in Nb30.h
UCHAR rc = 0; //Код возврата
UCHAR Status[256]; // Буфер для получения данных
UCHAR HostName[]=_T("SomeHost"); // Имя удалённого компа
BYTE MAC[6]; //Буфер для нашего MAC-адреса.
memset( &SNcb, 0, sizeof(SNcb) );
SNcb.ncb_command = NCBRESET;
SNcb.ncb_lana_num = 0;
rc=Netbios( &SNcb ); //Сбрасываем NetBios
//Если HostName вдруг больше 15 символов его надо обрезать.
while( lstrlen(HostName) - 15)
lstrcat(HostName, " ");
memset(&SNcb, 0, sizeof(NCB));
SNcb.ncb_command = NCBASTAT;
SNcb.ncb_buffer = (unsigned char*)Status;
SNcb.ncb_length = 256;
lstrcpy((char*)SNcb.ncb_callname, HostName);
SNcb.ncb_lana_num = 0; //Сетевой адаптор по умалчанию
rc = Netbios( &SNcb );
if(rc==NRC_GOODRET) //Если всё ОК
memcpy(MAC, Status, 6);
Use Netapi32.lib
НО! На машине NetBios может быть и выключен. Тогда можно вытащить его из таблицы IPMAC если хост вообще использует IP-протокол. Технология следующая: мы посыалем хосту любой IP-пакет, например по UDP. Система обязательно широковещательным ARP-пакетом запросит его MAC-адрес и если получит, занесёт его в таблицу IPMAC. Откуда мы его и заберём. Абсолютно неважно, какой IP-based протокол будет использован, и будет ли он установлен и/или принят удалённым хостом. Важно лишь то, что система захочет отослать IP-пакет, а для этого она обязательно должна узнать его MAC.
Пример консольного приложения:
//--------stdafx.h--------PS: Последний способ действует только для той подсети, где сам находишься. Если использовать HOST_IP из др. подсети, то в IPMAC таблице будет находится IP и MAC шлюза к HOST_IP.
#include <stdio.h>
#include <windows.h>
#include <Winsock2.h>
//Use Ws2_32.lib
#include <Iphlpapi.h>
//Use Iphlpapi.lib (in SDK)
////====================
////-------- cpp-файл ----------
#include "stdafx.h"
char ip[]="192.168.100.1";
int main(int argc, char* argv[])
{
//Будем использовать сокеты
WSADATA WsaData;
DWORD _ip=inet_addr(ip);
if (WSAStartup(0x0202, &WsaData)==NULL)
printf("WSA Starup OK!\n");
//Создаём UDP-сокет и отсылаем по нему любые данные
SOCKET udp_s;
SOCKADDR_IN udp_sin;
udp_s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(udp_s!=SOCKET_ERROR)
{
udp_sin.sin_family = AF_INET;
udp_sin.sin_port = htons(5232); //Шлём на любой порт.
udp_sin.sin_addr.s_addr = _ip;
if(sendto(udp_s, "TEST", 5, NULL, (SOCKADDR*)&udp_sin, sizeof(udp_sin))>0)
{ //Пакет отослан. Вытаскиваем MAC-адрес из системы
MIB_IPNETTABLE * pIpNetTable = (MIB_IPNETTABLE *) new char[0xFFFF];
ULONG cbIpNetTable = 0xFFFF;
if (NO_ERROR == GetIpNetTable (pIpNetTable, &cbIpNetTable, TRUE))
{
for (DWORD i = 0; i < pIpNetTable->dwNumEntries; i++)
{
if(pIpNetTable->table[i].dwAddr==_ip&&pIpNetTable->table[i].dwType!=2)
{
printf("IP:%s MAC:%X-%X-%X-%X-%X-%X\n", ip,
pIpNetTable->table[i].bPhysAddr[0],
pIpNetTable->table[i].bPhysAddr[1],
pIpNetTable->table[i].bPhysAddr[2],
pIpNetTable->table[i].bPhysAddr[3],
pIpNetTable->table[i].bPhysAddr[4],
pIpNetTable->table[i].bPhysAddr[5]);
delete[] pIpNetTable;
closesocket(udp_s);
WSACleanup();
return 0;
}
}
printf("MAC-address not found\n");
delete[] pIpNetTable;
}
else printf("ERROR Open IPMAC table\n");
}
else printf("Send data ERROR!\n");
closesocket(udp_s);
}
else printf("ERROR open socket\n");
WSACleanup(); //Освобождаем ресурсы
return 0;
}
PPS: MAC-адрес этто физический адрес устройства, и в общем случае
может иметь длинну отличную от 6 байт.