ネットワークのハードウエアアドレスを取得する
#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> #include <netinet/in.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <arpa/inet.h> #include <net/if.h> #if defined(SIOCGARP) # include <net/if_arp.h> #endif #if defined __linux__ # define HAVE_INET_NTOP 1 #elif defined __CYGWIN__ # define HAVE_INET_NTOP 1 #else # define HAVE_INET_NTOP 1 # define HAVE_SOCKADDR_SA_LEN 1 #endif static const char * my_sockaddr_in_ntop(const struct sockaddr_in *sin) { #if HAVE_INET_NTOP static char buf[INET6_ADDRSTRLEN]; return inet_ntop(sin->sin_family, &(sin->sin_addr), buf, sizeof(buf)); #else return inet_ntoa(sin->sin_addr); #endif } static const char * #if defined(SIOCGIFHWADDR) my_inet_ntop_mac(const struct ifreq *ifr) /* linux & cygwin */ { const unsigned char *p = (const unsigned char *)ifr->ifr_hwaddr.sa_data; #elif defined(SIOCGARP) my_inet_ntop_mac(const struct arpreq *arp) { const unsigned char *p = (const unsigned char *)arp->arp_ha.sa_data; #else # error not supported... #endif static char buf[65]; sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X", p[0],p[1],p[2],p[3],p[4],p[5] ); return buf; } int main(void) { char buf[16384]; struct ifconf ifc; int i, numnic, fd; int rc; fd = socket(AF_INET, SOCK_DGRAM, 0); if (fd == -1) { fprintf(stderr, "socket err\n"); exit(1); } memset(buf, 0, sizeof(buf)); memset(&ifc, 0, sizeof(ifc)); ifc.ifc_req = (struct ifreq *)buf; ifc.ifc_len = sizeof(buf); errno = 0; rc = ioctl(fd, SIOCGIFCONF, &ifc); if (rc == -1 || errno == EINVAL) { fprintf(stderr, "ioctl SIOCGIFCONF err\n"); exit(1); } for(i=0, numnic=0; i<ifc.ifc_len; ) { struct ifreq *ifr; #if defined(SIOCGIFHWADDR) struct ifreq req; #elif defined(SIOCGARP) struct arpreq req; #endif ifr = (struct ifreq *)(buf + i); switch (ifr->ifr_addr.sa_family) { case AF_INET: printf("%3d \"%s\" ", numnic, ifr->ifr_name); printf("AF_INET %s", my_sockaddr_in_ntop((struct sockaddr_in *)&ifr->ifr_addr)); #if defined(SIOCGIFHWADDR) memcpy(&req, ifr, sizeof(req)); rc = ioctl(fd, SIOCGIFHWADDR, &req); /* linux */ #elif defined(SIOCGARP) memset(&req, 0, sizeof(req)); memcpy(&req.arp_pa, &ifr->ifr_addr, sizeof(struct sockaddr_in)); rc = ioctl(fd, SIOCGARP, &req); #else # error not supported... #endif if (rc >= 0) { printf(" %s", my_inet_ntop_mac(&req)); } printf("\n"); break; default: printf("%3d \"%s\" family=%d\n", numnic, ifr->ifr_name, ifr->ifr_addr.sa_family); break; } ++numnic; #if HAVE_SOCKADDR_SA_LEN i += ifr->ifr_addr.sa_len <= sizeof(struct sockaddr) ? sizeof(struct ifreq) : sizeof(struct ifreq) - sizeof(struct sockaddr) + ifr->ifr_addr.sa_len; #else i += sizeof(struct ifreq); #endif } return 0; }
Last modified
8 years ago
Last modified on Nov 9, 2016, 9:56:02 AM
Note:
See TracWiki
for help on using the wiki.