MAC address with getifaddrs

Viewed 31023

Is there a way to get interface's MAC address via getifaddrs() ?

I already have this, to get IP addresses, but I have kinda missed MAC. Ive tried to look for the information in getifaddrs(), but there is nothing about MAC addresses

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++;
    }
      }

Thanks

7 Answers

Combining a couple answers, this works on both Linux and Mac/iOS/BSD

#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <ifaddrs.h>
#ifdef __linux__
    #include <arpa/inet.h>
    #include <netpacket/packet.h>
    #include <net/ethernet.h>
#else
    #include <net/if_dl.h>
#endif

int listmacaddrs(void) {
    struct ifaddrs *ifap, *ifaptr;
    unsigned char *ptr;

    if (getifaddrs(&ifap) == 0) {
        for(ifaptr = ifap; ifaptr != NULL; ifaptr = (ifaptr)->ifa_next) {
            #ifdef __linux__
                char macp[INET6_ADDRSTRLEN];
                if (((ifaptr)->ifa_addr)->sa_family == AF_PACKET) {
                    struct sockaddr_ll *s = (struct sockaddr_ll*)(ifaptr->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 ? ":":"");
                    }
                    printf("%s: %s\n", (ifaptr)->ifa_name, macp);
                }
            #else
            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));
            }
            #endif
        }
        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) {
            #ifdef __linux__
                if (!strcmp((ifaptr)->ifa_name, ifname) && (((ifaptr)->ifa_addr)->sa_family == AF_PACKET)) {
                    struct sockaddr_ll *s = (struct sockaddr_ll*)(ifaptr->ifa_addr);
                    int i;
                    int len = 0;
                    for (i = 0; i < 6; i++) {
                        len += sprintf(macaddrstr+len, "%02X%s", s->sll_addr[i], i < 5 ? ":":"");
                    }
                    break;
                }
            #else
            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;
            }
            #endif
        }
        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;
    }
}
Related