有没有办法通过getifaddrs()
获取接口的MAC地址?
我已经有了这个,用来获取IP地址,但我有点怀念MAC
。我尝试在getifaddrs()
中查找信息,但没有任何关于MAC
地址的信息
struct ifaddrs *iflist, *iface;
if (getifaddrs(&iflist) < 0)
{
perror("getifaddrs");
}
char addrp[INET6_ADDRSTRLEN];
char macp[INET6_ADDRSTRLEN];
int i=0;
for (iface = iflist; iface; iface = iface->ifa_next)
{
int af = iface->ifa_addr->sa_family;
const void *addr;
const void *mac;
switch (af)
{
case AF_INET:
addr = &((struct sockaddr_in *)iface->ifa_addr)->sin_addr;
break;
//get mac address somehow?
default:
addr = NULL;
}
if (addr)
{
if (inet_ntop(af, addr, addrp, sizeof addrp) == NULL)
{
perror("inet_ntop");
continue;
}
if (inet_ntop(af, mac, macp, sizeof macp) == NULL) // this is already for MAC add
{
perror("inet_ntop");
continue;
}
if (strcmp(addrp, "127.0.0.1") != 0)
{
strcat(tableO[i].IPaddr, addrp);
strcat(tableO[i].MACaddr, macp);
i++;
}
}
谢谢
发布于 2011-07-22 23:34:22
下面是获取IP和MAC地址的代码
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/ioctl.h>
#include <net/if.h>
int main(void)
{
char buf[8192] = {0};
struct ifconf ifc = {0};
struct ifreq *ifr = NULL;
int sck = 0;
int nInterfaces = 0;
int i = 0;
char ip[INET6_ADDRSTRLEN] = {0};
char macp[19];
struct ifreq *item;
struct sockaddr *addr;
/* Get a socket handle. */
sck = socket(PF_INET, SOCK_DGRAM, 0);
if(sck < 0)
{
perror("socket");
return 1;
}
/* Query available interfaces. */
ifc.ifc_len = sizeof(buf);
ifc.ifc_buf = buf;
if(ioctl(sck, SIOCGIFCONF, &ifc) < 0)
{
perror("ioctl(SIOCGIFCONF)");
return 1;
}
/* Iterate through the list of interfaces. */
ifr = ifc.ifc_req;
nInterfaces = ifc.ifc_len / sizeof(struct ifreq);
for(i = 0; i < nInterfaces; i++)
{
item = &ifr[i];
addr = &(item->ifr_addr);
/* Get the IP address*/
if(ioctl(sck, SIOCGIFADDR, item) < 0)
{
perror("ioctl(OSIOCGIFADDR)");
}
if (inet_ntop(AF_INET, &(((struct sockaddr_in *)addr)->sin_addr), ip, sizeof ip) == NULL) //vracia adresu interf
{
perror("inet_ntop");
continue;
}
/* Get the MAC address */
if(ioctl(sck, SIOCGIFHWADDR, item) < 0) {
perror("ioctl(SIOCGIFHWADDR)");
return 1;
}
/* display result */
sprintf(macp, " %02x:%02x:%02x:%02x:%02x:%02x",
(unsigned char)item->ifr_hwaddr.sa_data[0],
(unsigned char)item->ifr_hwaddr.sa_data[1],
(unsigned char)item->ifr_hwaddr.sa_data[2],
(unsigned char)item->ifr_hwaddr.sa_data[3],
(unsigned char)item->ifr_hwaddr.sa_data[4],
(unsigned char)item->ifr_hwaddr.sa_data[5]);
printf("%s %s ", ip, macp);
}
return 0;
}
发布于 2012-10-14 08:46:08
在BSD系统上,您可以直接使用getifaddrs来检索MACs。下面是完整的macaddr.c工具的示例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
int listmacaddrs(void) {
struct ifaddrs *ifap, *ifaptr;
unsigned char *ptr;
if (getifaddrs(&ifap) == 0) {
for(ifaptr = ifap; ifaptr != NULL; ifaptr = (ifaptr)->ifa_next) {
if (((ifaptr)->ifa_addr)->sa_family == AF_LINK) {
ptr = (unsigned char *)LLADDR((struct sockaddr_dl *)(ifaptr)->ifa_addr);
printf("%s: %02x:%02x:%02x:%02x:%02x:%02x\n",
(ifaptr)->ifa_name,
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
}
}
freeifaddrs(ifap);
return 1;
} else {
return 0;
}
}
int macaddr(char *ifname, char *macaddrstr) {
struct ifaddrs *ifap, *ifaptr;
unsigned char *ptr;
if (getifaddrs(&ifap) == 0) {
for(ifaptr = ifap; ifaptr != NULL; ifaptr = (ifaptr)->ifa_next) {
if (!strcmp((ifaptr)->ifa_name, ifname) && (((ifaptr)->ifa_addr)->sa_family == AF_LINK)) {
ptr = (unsigned char *)LLADDR((struct sockaddr_dl *)(ifaptr)->ifa_addr);
sprintf(macaddrstr, "%02x:%02x:%02x:%02x:%02x:%02x",
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5));
break;
}
}
freeifaddrs(ifap);
return ifaptr != NULL;
} else {
return 0;
}
}
extern int
main(int argc, char* argv[]) {
char macaddrstr[18], *ifname;
if (argc == 2) {
ifname = argv[1];
if (!strcmp(ifname,"-l")) {
return listmacaddrs();
} else {
if (macaddr(ifname, macaddrstr)) {
printf("%s: %s\n", ifname, macaddrstr);
return 0;
} else {
printf("%s: not found\n", ifname);
return 1;
}
}
} else {
printf("list all interfaces: %s -l\n", argv[0]);
printf("single interface: %s interface_name\n", argv[0]);
return 2;
}
}
发布于 2011-07-20 21:44:49
在Linux上,您将执行以下操作
case AF_PACKET: {
struct sockaddr_ll *s = (struct sockaddr_ll*)iface->ifa_addr;
int i;
int len = 0;
for(i = 0; i < 6; i++)
len+=sprintf(macp+len,"%02X%s",s->sll_addr[i],i < 5 ? ":":"");
}
不过,您可能希望检查结构sockaddr_ll的更多成员,请参阅here获取说明。
https://stackoverflow.com/questions/6762766
复制相似问题