Linux下获取eth网卡MAC地址的代码

字体大小: 中小 标准 ->行高大小: 标准

因开发需要获取有线网卡的MAC地址,发现网上获取的方法多数只能获取联网网卡的MAC地址,因此重写了下Ubuntu 10下测试通过。

下面代码无论网卡是否连线,都可以获取MAC地址,稍作修改,可以输出系统所有的网卡硬件MAC地址,无论是否已经联网。 【6688电子商务网站 www.6688.cc  】

  1. /*   * getmac.c 
  2.  *   *  Created on: 2010-11-4 
  3.  *      Author: carl   */ 
  4.   #include <stdio.h> 
  5. #include <fcntl.h>  #include <stdlib.h> 
  6. #include <string.h>  #include <unistd.h> 
  7.   #include <sys/ioctl.h> 
  8. #include <sys/types.h>  #include <sys/socket.h> 
  9. #include <netinet/in.h>  #include <linux/if.h> 
  10.   #define IFNAMSIZ 16 
  11.   // data structs to store interface name list 
  12. char ifname_buf[2048];  char *ifnames = ifname_buf; 
  13. int count = 0;   
  14. void add_interface_name(const char * name)  { 
  15.     int i;      for (i=0;i<count;i++) 
  16.     {          if (!strcmp(ifnames+i*IFNAMSIZ, name)) 
  17.             return;      } 
  18.     strncpy(ifnames+(count++)*IFNAMSIZ, name, IFNAMSIZ-1);  } 
  19.   char * get_name(char *name, char *p) 
  20. {      while (isspace(*p)) 
  21.     p++;      while (*p) { 
  22.     if (isspace(*p))          break; 
  23.     if (*p == ':') {    /* could be an alias */          char *dot = p, *dotname = name; 
  24.         *name++ = *p++;          while (isdigit(*p)) 
  25.         *name++ = *p++;          if (*p != ':') {    /* it wasn't, backup */ 
  26.         p = dot;          name = dotname; 
  27.         }          if (*p == '\0') 
  28.         return NULL;          p++; 
  29.         break;      } 
  30.     *name++ = *p++;      } 
  31.     *name++ = '\0';      return p; 
  32. }   
  33. // get /proc/net/dev interface name list into buffer  // return 0 if success 
  34. int get_procnet_list()  { 
  35.     FILE *fh;      char buf[512]; 
  36.     fh = fopen("/proc/net/dev", "r");      if (!fh) 
  37.         return -1;   
  38.     fgets(buf, sizeof buf, fh); /* eat title lines */      fgets(buf, sizeof buf, fh); 
  39.     while (fgets(buf, sizeof buf, fh))      { 
  40.         char name[IFNAMSIZ];          get_name(name, buf); 
  41.         add_interface_name(name);      } 
  42.     fclose(fh);      return 0; 
  43. }   
  44. long mac_addr_sys ( u_char *addr)  { 
  45. /* implementation for Linux */      struct ifreq ifr; 
  46.     struct ifreq *IFR;      struct ifconf ifc; 
  47.     char buf[1024];      int s, i; 
  48.     int ok = 0;   
  49.     // clear buffer      memset(ifname_buf, 0, sizeof(ifname_buf)); 
  50.    
  51.     s = socket(AF_INET, SOCK_DGRAM, 0);      if (s==-1) { 
  52.         return -1;      } 
  53.       ifc.ifc_len = sizeof(buf); 
  54.     ifc.ifc_buf = buf;      ioctl(s, SIOCGIFCONF, &ifc); 
  55.       IFR = ifc.ifc_req; 
  56.     // put the ioctl interface names in the list      for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; IFR++) { 
  57.             add_interface_name(IFR->ifr_name);      } 
  58.     // put the /proc/net/dev interface names in the list      if (get_procnet_list()) 
  59.         return -1;   
  60.     // get the first mac address of eth* device hardware address      for (i = 0; i < count; i++) { 
  61.         strcpy(ifr.ifr_name, ifnames + i*IFNAMSIZ);          if (!strncmp(ifr.ifr_name, "eth", 3)) 
  62.             if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) {                  if (! (ifr.ifr_flags & IFF_LOOPBACK)) { 
  63.                     if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) {                          char *p = (char *)ifr.ifr_hwaddr.sa_data; 
  64.                         if (!*((int *)p) && !*((int *)(p+2)) )                              continue; 
  65.                         // if not 00:00:00:00:00:00, yes, we get the real mac addr                          ok = 1; 
  66.                         break;                      } 
  67.                 }              } 
  68.     }   
  69.     close(s);      if (ok) { 
  70.         bcopy( ifr.ifr_hwaddr.sa_data, addr, 6);      } 
  71.     else {          return -1; 
  72.     }      return 0; 
  73. }   
  74. /***********************************************************************/  /* 
  75.  * Main (only for testing)   */ 
  76. int main( int argc, char **argv)  { 
  77.     long stat;      int i; 
  78.     u_char addr[6];   
  79.     stat = mac_addr_sys( addr);      if (0 == stat) { 
  80.         printf( "MAC address = ");          for (i=0; i<6; ++i) { 
  81.             printf("%2.2x", addr[i]);              if (i<5) 
  82.                 printf(":");          } 
  83.         printf( "\n");      } 
  84.     else {          fprintf( stderr, "can't get MAC address\n"); 
  85.         exit( 1);      } 
  86.     return 0;  } 

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/61945.html