iOS11以下获取局域网mac address

##

#define BUFLEN (sizeof(struct rt_msghdr) + 512)
#define SEQ 9999
#define RTM_VERSION	5	// important, version 2 does not return a mac address!
#define RTM_GET	0x4	// Report Metrics
#define RTF_LLINFO	0x400	// generated by link layer (e.g. ARP)
#define RTF_IFSCOPE 0x1000000 // has valid interface scope
#define RTA_DST	0x1	// destination sockaddr present

+(NSString)ip2mac: (NSString)strIP {

    const char *ip = [strIP UTF8String];

    int sockfd;

    unsigned char buf[BUFLEN];

    unsigned char buf2[BUFLEN];

    ssize_t n;

    struct rt_msghdr *rtm;

    struct sockaddr_in *sin;

    memset(buf,0,sizeof(buf));

    memset(buf2,0,sizeof(buf2));

    
    //17,3

    sockfd = socket(AF_ROUTE, SOCK_RAW, 0);

    //PF_INET6;

    
    rtm = (struct rt_msghdr *) buf;

    rtm->rtm_msglen = sizeof(struct rt_msghdr) + sizeof(struct sockaddr_in);

    rtm->rtm_version = RTM_VERSION; //5

    rtm->rtm_type = RTM_GET; //4

    rtm->rtm_addrs = RTA_DST; //1

    rtm->rtm_flags = RTF_LLINFO; //1024

    rtm->rtm_pid = 1234;

    rtm->rtm_seq = SEQ;

    

    

    sin = (struct sockaddr_in *) (rtm + 1);

    sin->sin_len = sizeof(struct sockaddr_in);

    sin->sin_family = AF_INET;

    sin->sin_addr.s_addr = inet_addr(ip);

    

    int iiii = rtm->rtm_msglen;

    

    //len 108

    write(sockfd, rtm, rtm->rtm_msglen);

    

    int iii = BUFLEN;

    

    n = read(sockfd, buf2, BUFLEN);

    close(sockfd);

    

    if (n != 0) {

        int index =  sizeof(struct rt_msghdr) + sizeof(struct sockaddr_inarp) + 8;

        // savedata("test",buf2,n);

        NSString *macAddress =[NSString stringWithFormat:@"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",buf2[index+0], buf2[index+1], buf2[index+2], buf2[index+3], buf2[index+4], buf2[index+5]];

        //If macAddress is equal to 00:00.. then mac address not exist in ARP table and returns nil. If it retuns 08:00.. then the mac address not exist because it's not in the same subnet with the device and return nil

        if ([macAddress isEqualToString:@"00:00:00:00:00:00"] ||[macAddress isEqualToString:@"08:00:00:00:00:00"] ) {

            return nil;

        }

        return macAddress;

    }

    return nil;

}