感谢支持
我们一直在努力

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

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


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



  1. /* 
  2.  * getmac.c 
  3.  * 
  4.  *  Created on: 2010-11-4 
  5.  *      Author: carl 
  6.  */ 
  7.  
  8. #include <stdio.h> 
  9. #include <fcntl.h> 
  10. #include <stdlib.h> 
  11. #include <string.h> 
  12. #include <unistd.h> 
  13.  
  14. #include <sys/ioctl.h> 
  15. #include <sys/types.h> 
  16. #include <sys/socket.h> 
  17. #include <netinet/in.h> 
  18. #include <linux/if.h> 
  19.  
  20. #define IFNAMSIZ 16 
  21.  
  22. // data structs to store interface name list 
  23. char ifname_buf[2048]; 
  24. char *ifnames = ifname_buf; 
  25. int count = 0; 
  26.  
  27. void add_interface_name(const char * name) 

  28.     int i; 
  29.     for (i=0;i<count;i++) 
  30.     { 
  31.         if (!strcmp(ifnames+i*IFNAMSIZ, name)) 
  32.             return
  33.     } 
  34.     strncpy(ifnames+(count++)*IFNAMSIZ, name, IFNAMSIZ-1); 

  35.  
  36. char * get_name(char *name, char *p) 

  37.     while (isspace(*p)) 
  38.     p++; 
  39.     while (*p) { 
  40.     if (isspace(*p)) 
  41.         break
  42.     if (*p == ‘:’) {    /* could be an alias */ 
  43.         char *dot = p, *dotname = name; 
  44.         *name++ = *p++; 
  45.         while (isdigit(*p)) 
  46.         *name++ = *p++; 
  47.         if (*p != ‘:’) {    /* it wasn’t, backup */ 
  48.         p = dot; 
  49.         name = dotname; 
  50.         } 
  51.         if (*p == ‘\0’
  52.         return NULL; 
  53.         p++; 
  54.         break
  55.     } 
  56.     *name++ = *p++; 
  57.     } 
  58.     *name++ = ‘\0’
  59.     return p; 

  60.  
  61. // get /proc/net/dev interface name list into buffer 
  62. // return 0 if success 
  63. int get_procnet_list() 

  64.     FILE *fh; 
  65.     char buf[512]; 
  66.     fh = fopen(“/proc/net/dev”“r”); 
  67.     if (!fh) 
  68.         return -1; 
  69.  
  70.     fgets(buf, sizeof buf, fh); /* eat title lines */ 
  71.     fgets(buf, sizeof buf, fh); 
  72.     while (fgets(buf, sizeof buf, fh)) 
  73.     { 
  74.         char name[IFNAMSIZ]; 
  75.         get_name(name, buf); 
  76.         add_interface_name(name); 
  77.     } 
  78.     fclose(fh); 
  79.     return 0; 

  80.  
  81. long mac_addr_sys ( u_char *addr) 

  82. /* implementation for Linux */ 
  83.     struct ifreq ifr; 
  84.     struct ifreq *IFR; 
  85.     struct ifconf ifc; 
  86.     char buf[1024]; 
  87.     int s, i; 
  88.     int ok = 0; 
  89.  
  90.     // clear buffer 
  91.     memset(ifname_buf, 0, sizeof(ifname_buf)); 
  92.  
  93.  
  94.     s = socket(AF_INET, SOCK_DGRAM, 0); 
  95.     if (s==-1) { 
  96.         return -1; 
  97.     } 
  98.  
  99.     ifc.ifc_len = sizeof(buf); 
  100.     ifc.ifc_buf = buf; 
  101.     ioctl(s, SIOCGIFCONF, &ifc); 
  102.  
  103.     IFR = ifc.ifc_req; 
  104.     // put the ioctl interface names in the list 
  105.     for (i = ifc.ifc_len / sizeof(struct ifreq); –i >= 0; IFR++) { 
  106.             add_interface_name(IFR->ifr_name); 
  107.     } 
  108.     // put the /proc/net/dev interface names in the list 
  109.     if (get_procnet_list()) 
  110.         return -1; 
  111.  
  112.     // get the first mac address of eth* device hardware address 
  113.     for (i = 0; i < count; i++) { 
  114.         strcpy(ifr.ifr_name, ifnames + i*IFNAMSIZ); 
  115.         if (!strncmp(ifr.ifr_name, “eth”, 3)) 
  116.             if (ioctl(s, SIOCGIFFLAGS, &ifr) == 0) { 
  117.                 if (! (ifr.ifr_flags & IFF_LOOPBACK)) { 
  118.                     if (ioctl(s, SIOCGIFHWADDR, &ifr) == 0) { 
  119.                         char *p = (char *)ifr.ifr_hwaddr.sa_data; 
  120.                         if (!*((int *)p) && !*((int *)(p+2)) ) 
  121.                             continue
  122.                         // if not 00:00:00:00:00:00, yes, we get the real mac addr 
  123.                         ok = 1; 
  124.                         break
  125.                     } 
  126.                 } 
  127.             } 
  128.     } 
  129.  
  130.     close(s); 
  131.     if (ok) { 
  132.         bcopy( ifr.ifr_hwaddr.sa_data, addr, 6); 
  133.     } 
  134.     else { 
  135.         return -1; 
  136.     } 
  137.     return 0; 

  138.  
  139. /***********************************************************************/ 
  140. /* 
  141.  * Main (only for testing) 
  142.  */ 
  143. int main( int argc, char **argv) 

  144.     long stat; 
  145.     int i; 
  146.     u_char addr[6]; 
  147.  
  148.     stat = mac_addr_sys( addr); 
  149.     if (0 == stat) { 
  150.         printf( “MAC address = “); 
  151.         for (i=0; i<6; ++i) { 
  152.             printf(“%2.2x”, addr[i]); 
  153.             if (i<5) 
  154.                 printf(“:”); 
  155.         } 
  156.         printf( “\n”); 
  157.     } 
  158.     else { 
  159.         fprintf( stderr, “can’t get MAC address\n”); 
  160.         exit( 1); 
  161.     } 
  162.     return 0; 

赞(0) 打赏
转载请注明出处:服务器评测 » Linux下获取eth网卡MAC地址的代码
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏