• 获取mac地址


    使用方法

    首先要生成一个可用的套接字描述符,TCP或UDP的都可以,为方便一般使用UDP套接字描述符
    然后调用ioctl函数获取所有网络接口列表(struct ifconf), 网卡越多列表数目越多
    再次调用ioctl函数从一个个网络接口中获取子项(struct ifreq)进行输出
    每获取一个子项(属性)都要调用一次ioctl函数, 因为在struct ifreq中使用了union结构, 一次只能正确返回一个属性

    接口结构

    以下结构摘自net/if.h头文件中,头文件中定义了很多宏来简化结构成员的访问

    struct ifreq   {
    # define IFHWADDRLEN 6
    # define IFNAMSIZ IF_NAMESIZE
        union {
            char ifrn_name[IFNAMSIZ]; /* Interface name, e.g. "en0".  */
        } ifr_ifrn;
     
        union {
            struct sockaddr ifru_addr;
            struct sockaddr ifru_dstaddr;
            struct sockaddr ifru_broadaddr;
            struct sockaddr ifru_netmask;
            struct sockaddr ifru_hwaddr;
            short int ifru_flags;
            int ifru_ivalue;
            int ifru_mtu;
            struct ifmap ifru_map;
            char ifru_slave[IFNAMSIZ]; /* Just fits the size */
            char ifru_newname[IFNAMSIZ];
            __caddr_t ifru_data;
        } ifr_ifru;
    };
    # define ifr_name ifr_ifrn.ifrn_name /* interface name */
    # define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
    # define ifr_addr ifr_ifru.ifru_addr /* address */
    # define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-p lnk */
    # define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
    # define ifr_netmask ifr_ifru.ifru_netmask /* interface net mask */
    # define ifr_flags ifr_ifru.ifru_flags /* flags */
    # define ifr_metric ifr_ifru.ifru_ivalue /* metric */
    # define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
    # define ifr_map ifr_ifru.ifru_map /* device map */
    # define ifr_slave ifr_ifru.ifru_slave /* slave device */
    # define ifr_data ifr_ifru.ifru_data /* for use by interface */
    # define ifr_ifindex ifr_ifru.ifru_ivalue    /* interface index      */
    # define ifr_bandwidth ifr_ifru.ifru_ivalue /* link bandwidth */
    # define ifr_qlen ifr_ifru.ifru_ivalue /* queue length */
    # define ifr_newname ifr_ifru.ifru_newname /* New name */
     
    struct ifconf   {
        int ifc_len; /* Size of buffer.  */
        union {
            __caddr_t ifcu_buf;
            struct ifreq *ifcu_req;
        } ifc_ifcu;
    };
    # define ifc_buf ifc_ifcu.ifcu_buf /* Buffer address.  */
    # define ifc_req ifc_ifcu.ifcu_req /* Array of structures.  */
    

    以下为ioctl在设置或获取套接字属性时的一些标识

    int ioctl(int fd, int request, ... /* void *arg */);
    
    /* Socket configuration controls. */
    #define SIOCGIFNAME	0x8910		/* get iface name		*/
    #define SIOCSIFLINK	0x8911		/* set iface channel		*/
    #define SIOCGIFCONF	0x8912		/* get iface list		*/
    #define SIOCGIFFLAGS	0x8913		/* get flags			*/
    #define SIOCSIFFLAGS	0x8914		/* set flags			*/
    #define SIOCGIFADDR	0x8915		/* get PA address		*/
    #define SIOCSIFADDR	0x8916		/* set PA address		*/
    #define SIOCGIFDSTADDR	0x8917		/* get remote PA address	*/
    #define SIOCSIFDSTADDR	0x8918		/* set remote PA address	*/
    #define SIOCGIFBRDADDR	0x8919		/* get broadcast PA address	*/
    #define SIOCSIFBRDADDR	0x891a		/* set broadcast PA address	*/
    #define SIOCGIFNETMASK	0x891b		/* get network PA mask		*/
    #define SIOCSIFNETMASK	0x891c		/* set network PA mask		*/
    #define SIOCGIFMETRIC	0x891d		/* get metric			*/
    #define SIOCSIFMETRIC	0x891e		/* set metric			*/
    #define SIOCGIFMEM	0x891f		/* get memory address (BSD)	*/
    #define SIOCSIFMEM	0x8920		/* set memory address (BSD)	*/
    #define SIOCGIFMTU	0x8921		/* get MTU size			*/
    #define SIOCSIFMTU	0x8922		/* set MTU size			*/
    #define SIOCSIFNAME	0x8923		/* set interface name		*/
    #define	SIOCSIFHWADDR	0x8924		/* set hardware address 	*/
    #define SIOCGIFENCAP	0x8925		/* get/set encapsulations       */
    #define SIOCSIFENCAP	0x8926
    #define SIOCGIFHWADDR	0x8927		/* Get hardware address		*/
    #define SIOCGIFSLAVE	0x8929		/* Driver slaving support	*/
    #define SIOCSIFSLAVE	0x8930
    #define SIOCADDMULTI	0x8931		/* Multicast address lists	*/
    #define SIOCDELMULTI	0x8932
    #define SIOCGIFINDEX	0x8933		/* name -> if_index mapping	*/
    #define SIOGIFINDEX	SIOCGIFINDEX	/* misprint compatibility :-)	*/
    #define SIOCSIFPFLAGS	0x8934		/* set/get extended flags set	*/
    #define SIOCGIFPFLAGS	0x8935
    #define SIOCDIFADDR	0x8936		/* delete PA address		*/
    #define	SIOCSIFHWBROADCAST	0x8937	/* set hardware broadcast addr	*/
    #define SIOCGIFCOUNT	0x8938		/* get number of devices */
    
    #define SIOCGIFBR	0x8940		/* Bridging support		*/
    #define SIOCSIFBR	0x8941		/* Set bridging options 	*/
    
    #define SIOCGIFTXQLEN	0x8942		/* Get the tx queue length	*/
    #define SIOCSIFTXQLEN	0x8943		/* Set the tx queue length 	*/
    

    获取mac地址实例

    #include <sys/ioctl.h>
    #include <net/if.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <string.h>
    #include <stdio.h>
     
    int main(int argc,char *argv[]) {
        struct ifreq ifr;
        struct ifconf ifc;
        char buf[2048];
    
    //生成一个可用套接字描述符 
        int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
        if (sock == -1) {
            printf("socket error
    ");
            return -1;
        }
     
    //获取所有网络接口列表
        ifc.ifc_len = sizeof(buf);
        ifc.ifc_buf = buf;
        if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) {
            printf("ioctl error
    ");
            return -1;
        }
     
    //对子项进行操作输出
        struct ifreq* it = ifc.ifc_req;
        const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq));
        char szMac[64];
        int count = 0;
        for (; it != end; ++it) {
            strcpy(ifr.ifr_name, it->ifr_name);
            if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) {
                if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback
                    if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) {
                        count ++ ;
                        unsigned char * ptr ;
                        ptr = (unsigned char  *)&ifr.ifr_ifru.ifru_hwaddr.sa_data[0];
                        snprintf(szMac,64,"%02X:%02X:%02X:%02X:%02X:%02X",*ptr,*(ptr+1),*(ptr+2),*(ptr+3),*(ptr+4),*(ptr+5));
                        printf("%d,Interface name : %s , Mac address : %s 
    ",count,ifr.ifr_name,szMac);
                    }
                }
            }else{
                printf("get mac info error
    ");
                return -1;
            }
        }
     
        return 0;
    }
    
  • 相关阅读:
    vs2005发布生成自定义dll
    模拟msn消息提示(右下角)
    通过GridView导出Excel
    在ASP.NET 2.0中直接得到本页面生成的HTML代码
    asp.net实现SQL Server备份还原
    通用分页存储过程算法(.net类实现)
    超链接打开自定义的协议
    GridView技巧2
    sql语句获取本周、本月数据
    asp.net开发自定义控件
  • 原文地址:https://www.cnblogs.com/cfans1993/p/6598314.html
Copyright © 2020-2023  润新知