Changes between Initial Version and Version 1 of ネットワークのハードウエアアドレスを取得する


Ignore:
Timestamp:
Nov 9, 2016, 9:56:02 AM (7 years ago)
Author:
admin
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • ネットワークのハードウエアアドレスを取得する

    v1 v1  
     1
     2ネットワークのハードウエアアドレスを取得する
     3{{{
     4
     5#include <errno.h>
     6#include <stdio.h>
     7#include <stdlib.h>
     8#include <string.h>
     9#include <sys/types.h>
     10#include <unistd.h>
     11#include <netinet/in.h>
     12#include <sys/socket.h>
     13#include <sys/ioctl.h>
     14#include <arpa/inet.h>
     15#include <net/if.h>
     16#if defined(SIOCGARP)
     17# include <net/if_arp.h>
     18#endif
     19
     20#if defined __linux__
     21# define HAVE_INET_NTOP 1
     22#elif defined __CYGWIN__
     23# define HAVE_INET_NTOP 1
     24#else
     25# define HAVE_INET_NTOP 1
     26# define HAVE_SOCKADDR_SA_LEN 1
     27#endif
     28
     29
     30static
     31const char *
     32my_sockaddr_in_ntop(const struct sockaddr_in *sin)
     33{
     34#if HAVE_INET_NTOP
     35  static char buf[INET6_ADDRSTRLEN];
     36  return inet_ntop(sin->sin_family, &(sin->sin_addr), buf, sizeof(buf));
     37#else
     38  return inet_ntoa(sin->sin_addr);
     39#endif
     40}
     41
     42static
     43const char *
     44#if defined(SIOCGIFHWADDR)
     45my_inet_ntop_mac(const struct ifreq *ifr)  /* linux & cygwin */
     46{
     47  const unsigned char *p = (const unsigned char *)ifr->ifr_hwaddr.sa_data;
     48#elif defined(SIOCGARP)
     49my_inet_ntop_mac(const struct arpreq *arp)
     50{
     51  const unsigned char *p = (const unsigned char *)arp->arp_ha.sa_data;
     52#else
     53# error not supported...
     54#endif
     55  static char buf[65];
     56 
     57  sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
     58                p[0],p[1],p[2],p[3],p[4],p[5]
     59         );
     60  return buf;
     61}
     62
     63
     64int
     65main(void)
     66{
     67  char  buf[16384];
     68  struct ifconf ifc;
     69  int i, numnic, fd;
     70  int rc;
     71 
     72  fd = socket(AF_INET, SOCK_DGRAM, 0);
     73  if (fd == -1) {
     74    fprintf(stderr, "socket err\n");
     75    exit(1);
     76  }
     77  memset(buf, 0, sizeof(buf));
     78  memset(&ifc, 0, sizeof(ifc));
     79  ifc.ifc_req = (struct ifreq *)buf;
     80  ifc.ifc_len = sizeof(buf);
     81  errno = 0;
     82  rc = ioctl(fd, SIOCGIFCONF, &ifc);
     83  if (rc == -1 || errno == EINVAL) {
     84    fprintf(stderr, "ioctl SIOCGIFCONF err\n");
     85    exit(1);
     86  }
     87 
     88  for(i=0, numnic=0; i<ifc.ifc_len; ) {
     89    struct ifreq  *ifr;
     90#if defined(SIOCGIFHWADDR)
     91    struct ifreq req;
     92#elif defined(SIOCGARP)
     93    struct arpreq req;
     94#endif
     95   
     96    ifr = (struct ifreq *)(buf + i);
     97    switch (ifr->ifr_addr.sa_family) {
     98      case AF_INET:
     99        printf("%3d \"%s\" ", numnic, ifr->ifr_name);
     100        printf("AF_INET %s", my_sockaddr_in_ntop((struct sockaddr_in *)&ifr->ifr_addr));
     101#if defined(SIOCGIFHWADDR)
     102        memcpy(&req, ifr, sizeof(req));
     103        rc = ioctl(fd, SIOCGIFHWADDR, &req);  /* linux */
     104#elif defined(SIOCGARP)
     105        memset(&req, 0, sizeof(req));
     106        memcpy(&req.arp_pa, &ifr->ifr_addr, sizeof(struct sockaddr_in));
     107        rc = ioctl(fd, SIOCGARP, &req);
     108#else
     109# error not supported...
     110#endif
     111        if (rc >= 0) {
     112          printf("  %s", my_inet_ntop_mac(&req));
     113        }
     114        printf("\n");
     115        break;
     116    default:
     117        printf("%3d \"%s\" family=%d\n", numnic, ifr->ifr_name, ifr->ifr_addr.sa_family);
     118      break;
     119    }
     120    ++numnic;
     121#if HAVE_SOCKADDR_SA_LEN
     122    i += ifr->ifr_addr.sa_len <= sizeof(struct sockaddr) ?
     123      sizeof(struct ifreq) :
     124      sizeof(struct ifreq) - sizeof(struct sockaddr) + ifr->ifr_addr.sa_len;
     125#else
     126    i += sizeof(struct ifreq);
     127#endif
     128  }
     129 
     130  return 0;
     131}
     132
     133}}}