在linux下,我们知道可以通过ifconfig获取mac地址和ip地址等相关信息,但是如果要使用gcc程序实现的话,我们就需要使用到系统所提供的一个函数ioctl(),iotec函数是对设备的i/o通道进行管理的函数。由于这个函数用途比较多,如果要学习可以参照官方的说明。

       第一步,我们需要定义几个变量:

 

  1. struct ifreq *ifrp,ifr;  
  2. struct ifconf ifc;  
  3. char buffer[720],name[16];  
  4. int socketfd,error,flags,len,space=0;  

       其中,struct ifreq 就是用来存储返回的接口相关信息的结构体,由于电脑可能有多个硬件借口,因此我们使用指针来存储返回的结构体数组。struct ifconf变量是用来存储ioctl()函数返回结果的。因为我们是要获取mac地址的相关信
  1. //  
  2. //  main.cpp  
  3. //  arp  
  4. //  
  5. //  Created by Allen on 14-4-7.  
  6. //  Copyright (c) 2014年 Allen. All rights reserved.  
  7. //  
  8. #include <iostream>  
  9.   
  10.   
  11. #include <sys/param.h>  
  12. #include <sys/ioctl.h>  
  13. #include <sys/socket.h>  
  14. #include <sys/sysctl.h>  
  15.   
  16. #include <net/ethernet.h>  
  17. #include <net/if.h>  
  18. #include <net/if_var.h>  
  19. #include <net/if_dl.h>  
  20. #include <net/if_types.h>  
  21.   
  22. #include <netinet/in.h>  
  23. #include <netinet/in_var.h>  
  24. #include <arpa/inet.h>  
  25.   
  26. #include <err.h>  
  27. #include <errno.h>  
  28. #include <fcntl.h>  
  29. #include <stdio.h>  
  30. #include <stdlib.h>  
  31. #include <string.h>  
  32. #include <unistd.h>  
  33. //读取本机mac地址的方法  
  34. int main()  
  35. {  
  36.     struct ifreq *ifrp,ifr;  
  37.     struct ifconf ifc;  
  38.     char buffer[720],name[16];  
  39.     int socketfd,error,flags,len,space=0;  
  40.     ifc.ifc_len=sizeof(buffer);  
  41.     len=ifc.ifc_len;  
  42.       
  43.     ifc.ifc_buf=buffer;  
  44.       
  45.     socketfd=socket(AF_INET,SOCK_DGRAM,0);//创建一个socket  
  46.       
  47.     if((error=ioctl(socketfd,SIOCGIFCONF,&ifc))<0)//使用SIOCGIFCONF获得所有接口的清单  
  48.     {  
  49.         perror("ioctl faild");  
  50.         exit(1);  
  51.     }  
  52.       
  53.     if(ifc.ifc_len<=len)//buffer 的大小如果没有问题  
  54.     {  
  55.         ifrp=ifc.ifc_req;//将获取的所有借口的所有清单传到ifrp指针上。  
  56.         do  
  57.         {  
  58.             struct sockaddr *sa=&ifrp->ifr_addr;//定义sockaddr对象  
  59.             strcpy(ifr.ifr_name,ifrp->ifr_name);  
  60.             if(strcmp(ifrp->ifr_name,name)!=0){  
  61.                 strcpy(name,ifrp->ifr_name);  
  62.                 printf("%s:",ifrp->ifr_name);// 打印接口名  
  63.                 if(!ioctl(socketfd,SIOCGIFFLAGS,&ifr))//get ifnet flags  
  64.                 {  
  65.                     flags=ifr.ifr_flags;  
  66.                     printf("flags=%x<",flags<<16);  
  67.                     if(ifr.ifr_flags&IFF_UP){  
  68.                         printf("UP,");  
  69.                     }  
  70.                     else{  
  71.                         printf("DOWN");  
  72.                     }  
  73.                     if(ifr.ifr_flags&IFF_BROADCAST){  
  74.                         printf("BOROADCAST,");  
  75.                     }  
  76.                     if(ifr.ifr_flags&IFF_POINTOPOINT){  
  77.                         printf("POINTOPOINT,");  
  78.                     }  
  79.                     if(ifr.ifr_flags&IFF_LOOPBACK){  
  80.                         printf("LOOPBACK,");  
  81.                     }  
  82.                     if(ifr.ifr_flags&IFF_RUNNING){  
  83.                         printf("RUNNING,");  
  84.                     }  
  85.                     if(ifr.ifr_flags&IFF_SIMPLEX){  
  86.                         printf("SIMPLEX,");  
  87.                     }  
  88.                     if(ifr.ifr_flags&IFF_MULTICAST){  
  89.                         printf("MULTICAST");  
  90.                     }  
  91.                     printf(">;\n");  
  92.                 }  
  93.                 if(!ioctl(socketfd,SIOCGIFADDR,&ifr)){  
  94.                     printf("     inet %s",inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));  
  95.                 }  
  96.                 if(!ioctl(socketfd,SIOCGIFNETMASK,&ifr)){  
  97.                     printf(" netmask %s",inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));  
  98.                 }  
  99.                 if(!ioctl(socketfd,SIOCGIFBRDADDR,&ifr)){  
  100.                     printf(" broadcast %s\n",inet_ntoa(((struct sockaddr_in *)&ifr.ifr_broadaddr)->sin_addr));  
  101.                 }  
  102.                 if(((struct sockaddr_dl *)sa)->sdl_type==IFT_ETHER)  
  103.                     printf("     ether %s\n",ether_ntoa((struct ether_addr *)LLADDR((struct sockaddr_dl *)sa)));  
  104.                 //printf("types %x\n",((struct sockaddr_dl *)sa)->;sdl_type);  
  105.                   
  106.             }  
  107.             ifrp=(struct ifreq*)(sa->sa_len+(caddr_t)&ifrp->ifr_addr);  
  108.             space+=(int)sa->sa_len+sizeof(ifrp->ifr_name);  
  109.         }  
  110.         while(space<ifc.ifc_len);  
  111.           
  112.     }  
  113.     exit(0);  
  114. }