在局域網開發中,經常需要根據 IP 地址獲取遠程主機的 MAC 地址。Windows 提供了 SendARP API 可以直接發送 ARP 請求並獲取物理地址。本文將詳細解析一個完整的控制台程序示例,展示如何初始化 Winsock、解析主機名、發送 ARP 請求並格式化輸出 MAC 地址。
#include <stdio.h>
#include <stdlib.h>
#include <winsock2.h>
#include <iphlpapi.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Iphlpapi.lib")
void main(int argc, char **argv) {
int numberOfHost = 1;
struct hostent *remoteHostent;
// 處理命令行參數
if (argc == 3) numberOfHost = atoi(argv[2]);
if (argc > 3 || argc < 2) {
printf("RmtHost v0.2 - Get remote HostName /MacAddress\n");
printf("by ShotgunLabs ( Shotgun@xici.net )\n\n");
printf("Usage :\n\tRmtHost.exe [RemoteIP] [NUMBEROFHOSTTOSCAN]\n\n");
printf("Example:\n\tRmtHost.exe 192.168.0.3\n");
printf("\tRmtHost.exe 192.168.0.3 255\n\n");
exit(0);
}
// 初始化 SOCKET
WSADATA wsaData;
int iRet = WSAStartup(MAKEWORD(2,1), &wsaData);
if (iRet != 0) {
printf("WSAStartup Error:%d\n", GetLastError());
exit(0);
}
...
}
程序啟動時解析命令行參數:第一個參數為目標 IP,第二個可選參數指定掃描的主機數量(默認為 1)。隨後調用 WSAStartup 初始化 Winsock 2.1 環境。
int nRemoteAddr = inet_addr(argv[1]);
remoteHostent = (struct hostent*)malloc(sizeof(struct hostent));
struct in_addr sa;
for (int i = 0; i < numberOfHost; i++) {
// 獲取遠程機器名
sa.s_addr = nRemoteAddr;
printf("\nIpAddress : %s\n", inet_ntoa(sa));
remoteHostent = gethostbyaddr((char*)&nRemoteAddr, 4, AF_INET);
if (remoteHostent)
printf("HostName : %s\n", remoteHostent->h_name);
else
printf("gethostbyaddr Error:%d\n", GetLastError());
...
}
使用 inet_addr 將字符串 IP 轉換為網絡字節序整數。循環中調用 gethostbyaddr 進行反向 DNS 解析,嘗試獲取主機名。
// 發送ARP查詢包獲得遠程MAC地址
unsigned char macAddress[6];
ULONG macAddLen = 6;
iRet = SendARP(nRemoteAddr, (unsigned long)NULL, (PULONG)&macAddress, &macAddLen);
if (iRet == NO_ERROR) {
printf("MacAddress: ");
for (int i = 0; i < 6; i++) {
printf("%.2x", macAddress[i]);
if (i < 5) printf("-");
}
printf("\n");
} else {
printf("SendARP Error:%d\n", GetLastError());
}
// 移動到下一個 IP(網絡字節序加 1)
nRemoteAddr = htonl(ntohl(nRemoteAddr) + 1);
SendARP 是核心函數,它向目標 IP 發送 ARP 請求並填充 macAddress 緩衝區。成功後以 XX-XX-XX-XX-XX-XX 格式輸出。最後將 IP 地址加 1 以便掃描下一台主機。
ws2_32.lib 和 Iphlpapi.lib。RmtHost.exe 192.168.1.100 10 將掃描 192.168.1.100 到 192.168.1.109 共 10 台主機。本示例代碼簡潔地演示了 Windows 平台下 ARP 掃描的基本流程,適合作為網絡工具開發的起點。