我正在尝试使用 C 在 OSX 上获取我所有接口的 MAC 地址。获取它的常用方法 Linux 在 BSD 上不起作用 - 从我所看到的一切来看,您必须获取接口并查找类型AF_LINK。我的问题是 LLADDR(sockaddr_dl) 给了我一大堆数据(包括我的 MAC),我不知道数据的格式。例如;以下代码将输出:
设备:en1 链接 sdl_alen:101 mac:31:f8:1e:df:d6:22:1d :00:00:00:00:00:00:00:00:00:00:00:00:00:00 :00:b0:06:10:00:01:00:00:00:c0:02:10:00:01:00:00:00:00:00:00:00:00:00:00:00 :40 :03:10:00:01:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:03:00:6c :6f:30:00:00:00:00:00:00:00:00:00:00:00:00:00:70:03:10:00:01:00:00:00:e0:02 :10:00:01:00:00:
我的 MAC 是粗体的。似乎这是一直以来的格式,但如果我可以将 LLADDR(sockaddr_dl) 转换为某些东西,我会更舒服。在 net/if_dl.h 中,LLADDR 定义为:
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
据我所知,这就是说结果是类型 (void *) - 没有帮助。
其他帖子如:
在弄清楚如何使用 ioctl/SIOCGIFADDR/SIOCGIFCONF 在 Mac OS X 上获取以太网接口信息时遇到问题?
似乎认为他们已经弄清楚了,但是如果您查看代码,您会发现它不会工作,因为 sdl_alen 不是 6。
int main() {
pcap_if_t *alldevs;
pcap_if_t *d;
pcap_addr_t *alladdrs;
pcap_addr_t *a;
struct sockaddr_dl* link;
char eb[PCAP_ERRBUF_SIZE];
char *addr_buf[40];
if (pcap_findalldevs(&alldevs, eb) == -1) {
printf("no devs found\n");
return(-1);
}
for (d = alldevs; d != NULL; d = d->next) {
printf("Device: %s\n", d->name);
alladdrs = d->addresses;
for (a = alladdrs; a != NULL; a = a->next) {
if(a->addr->sa_family == AF_LINK && a->addr->sa_data != NULL){
// MAC ADDRESS
//struct sockaddr_dl *sdl = (struct sockaddr_dl *) a->addr->sa_data;
link = (struct sockaddr_dl*)a->addr->sa_data;
char mac[link->sdl_alen];
caddr_t macaddr = LLADDR(link);
memcpy(mac, LLADDR(link), link->sdl_alen);
printf("link sdl_alen: %i\n", link->sdl_alen);
int i;
printf("mac: ");
for(i = 0; i<link->sdl_alen; i++){
printf("%02x:", (unsigned char)mac[i]);
}
printf("\n");
}
}
}
}