• linux下使用ioctl() 获取本机mac地址、ip地址等等


     

     

           在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(">; ");  
    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 ",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 ",ether_ntoa((struct ether_addr *)LLADDR((struct sockaddr_dl *)sa)));  
    104.                 //printf("types %x ",((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. }  
  • 相关阅读:
    iOS内存管理机制
    iOS开发之XML和JSON数据解析
    Ubuntu小点汇总,更新中...
    Android与服务器的简单通讯
    Gedit乱码问题
    Eclipse软件问题-方案积累
    开放接口使用积累
    定制知识积累
    Android小代码-技巧积累
    Android初学点滴积累(操作篇)
  • 原文地址:https://www.cnblogs.com/LxwEmbedded/p/4728146.html
Copyright © 2020-2023  润新知