Странно, если скопипастить вопрос в Гугол без изменений, находится довольно много полезного, или надо что-то "свыше"? Чем https://www.cyberforum.ru/cpp-networks/thread1950556.html или http://mycomponent.blogspot.com/2009/05/get-mac-address-in-c-from-ip.html не устраивают?
MAC-адрес если что используется в пределах домена коллизий (в современном сетевом оборудовании это от сетевого разъема в компе до разъема роутера, у дедовских 10мбит хабов домен коллизий был в пределах коаксиального шланга, к которому все подключены), это типа аппаратного идентификатора сетевого интерфейса. Пожалуй только если ты соединяешь два кампуцера патч-кордом, то можешь с одного из них выяснить мак адрес соседнего. Я бы не назвал это "удаленно", для 100BASE-TX, 1000BASE-T и 1000BASE-TX эта удаленность не может превышать 100 метров.
Более того, сейчас многие локальные сети уже не используют чистый езернет. И мак-адрес может быть вам тупо недоступен за счет прослойки. В общем нужно больше инфы, что автор воспринимает про удаленность и о каких сетях идет речь.
Код (C): #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if_arp.h> #include <net/if.h> #include <netinet/in.h> #include <linux/sockios.h> #include <errno.h> int main(void) { const char *addr = "192.168.0.2"; int s; struct arpreq areq; struct ifconf ifc; struct ifreq ifrBuff[1024]; struct ifreq *ifr; struct sockaddr_in *sin; struct in_addr ipaddr; int num, i; unsigned char mac[10] = {0}; // Create socket if (-1 == (s = socket(AF_INET, SOCK_STREAM, 0))) { perror("socket"); exit(1); } // Put address const char *addr to struct in_addr ipaddr if (0 == inet_aton(addr, &ipaddr)) { fprintf(stderr, "Error: bad dotted-decimal IP '%s'.\n", addr); exit(1); } memset(&areq, 0, sizeof(areq)); sin = (struct sockaddr_in *)&areq.arp_pa; sin->sin_family = AF_INET; sin->sin_addr = ipaddr; ifc.ifc_len = sizeof(ifrBuff); ifc.ifc_buf = (char *)ifrBuff; if (-1 == ioctl(s, SIOCGIFCONF, &ifc)) { printf("Unable to make SIOCGIFCONF request, error %d: %s\n", errno, strerror(errno)); exit(1); } num = ifc.ifc_len/sizeof(struct ifreq); for(ifr = ifc.ifc_req, i = 0; i<num; ifr++, i++) { if(ifr->ifr_addr.sa_family != AF_INET) printf("[%d]: (%s) is not AF_INET interface!\n", i, ifr->ifr_name); else printf("[%d]: (%s) interface\n", i, ifr->ifr_name); if(-1 == ioctl(s, SIOCGIFHWADDR, ifr)) { printf("Unable to make SIOCGIFHWADDR request, error %d: %s\n", errno, strerror(errno)); continue; } memcpy(mac, (unsigned char *)&(ifr->ifr_hwaddr.sa_data), sizeof(struct sockaddr)); printf("[%d] MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", i, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); strncpy(areq.arp_dev, ifr->ifr_name, 15); if(-1 == ioctl(s, SIOCGARP, &areq)) { printf("Unable to make ARP request, error %d: %s\n", errno, strerror(errno)); continue; } printf("%s -> %02X:%02X:%02X:%02X:%02X:%02X\n", addr, (&areq.arp_ha)->sa_data[0], (&areq.arp_ha)->sa_data[1], (&areq.arp_ha)->sa_data[2], (&areq.arp_ha)->sa_data[3], (&areq.arp_ha)->sa_data[4], (&areq.arp_ha)->sa_data[5]); } return 0; } ну вот код к примеру по ссылке но он для линукс, как его на винду переписать?
Если быть точным, то для Ethernet в пределах broadcast домена. Разница большая очень. Если грубо, то домен коллизий это хаб (Level-1 по OSI), а broadcast домен это свич (Level-2 по OSI). В пределах broadcast домена мак можно получить arp протоколом если разговор про IP сети.
addedie, у меня была старая статья https://wasm.in/blogs/vzgljad-na-set-iz-drugoj-galaktiki.407/ там пример работы с посылкой arp под винду
Конечно же можно )) Зашлите троян на удаленную машину и узнавайте не только MAC адрес. f13nd, абсолютно прав.