【问题标题】:How do I query the ARP table on iPhone?如何在 iPhone 上查询 ARP 表?
【发布时间】:2011-01-16 12:31:25
【问题描述】:

我是 iPhone 开发的新手,我想将网络唤醒功能集成到我的应用程序中,而不会在已知 IP 的情况下强迫我的用户输入计算机 MAC 地址。 我用谷歌搜索了大约几个小时,获取了一个 ARP 工具的源代码,但我不知道如何在 iPhone 上进行管理。

【问题讨论】:

    标签: iphone ip-address mac-address arp


    【解决方案1】:

    由于没有人回答我的问题...这是答案;)

    #include <sys/param.h>
    #include <sys/file.h>
    #include <sys/socket.h>
    #include <sys/sysctl.h>
    
    #include <net/if.h>
    #include <net/if_dl.h>
    #include "if_types.h"
    #include "route.h"
    #include "if_ether.h"
    #include <netinet/in.h>
    
    
    #include <arpa/inet.h>
    
    #include <err.h>
    #include <errno.h>
    #include <netdb.h>
    
    #include <paths.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    
        -(NSString*) ip2mac: (char*) ip
        {
    
    
    
            int expire_time, flags, export_only, doing_proxy, found_entry;
    
    
    
            NSString *mAddr = nil;
            u_long addr = inet_addr(ip);
            int mib[6];
            size_t needed;
            char *host, *lim, *buf, *next;
            struct rt_msghdr *rtm;
            struct sockaddr_inarp *sin;
            struct sockaddr_dl *sdl;
            extern int h_errno;
            struct hostent *hp;
    
            mib[0] = CTL_NET;
            mib[1] = PF_ROUTE;
            mib[2] = 0;
            mib[3] = AF_INET;
            mib[4] = NET_RT_FLAGS;
            mib[5] = RTF_LLINFO;
            if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
                err(1, "route-sysctl-estimate");
            if ((buf = malloc(needed)) == NULL)
                err(1, "malloc");
            if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0)
                err(1, "actual retrieval of routing table");
    
    
            lim = buf + needed;
            for (next = buf; next < lim; next += rtm->rtm_msglen) {
                rtm = (struct rt_msghdr *)next;
                sin = (struct sockaddr_inarp *)(rtm + 1);
                sdl = (struct sockaddr_dl *)(sin + 1);
                if (addr) {
                    if (addr != sin->sin_addr.s_addr)
                        continue;
                    found_entry = 1;
                }
                if (nflag == 0)
                    hp = gethostbyaddr((caddr_t)&(sin->sin_addr),
                                       sizeof sin->sin_addr, AF_INET);
                else
                    hp = 0;
                if (hp)
                    host = hp->h_name;
                else {
                    host = "?";
                    if (h_errno == TRY_AGAIN)
                        nflag = 1;
                }
    
    
    
                if (sdl->sdl_alen) {
    
                    u_char *cp = LLADDR(sdl);
    
                    mAddr = [NSString stringWithFormat:@"%x:%x:%x:%x:%x:%x", cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
    
    
                //  ether_print((u_char *)LLADDR(sdl));
                }
                else
    
                    mAddr = nil;
    
    
    
            }
    
    
            if (found_entry == 0) {
                return nil;
            } else {
                return mAddr;
            }
    
    
    
    
        }
    

    来自苹果 arp.c 在 iphone 上工作

    复制以下内容:

    - "if_types.h"
    - "route.h"
    - "if_ether.h"
    

    来自 mac 的头文件包含在您的项目文件夹中并添加到类中

    【讨论】:

    • 感谢您的提示。我只复制了“route.h”标头,因为其他标头包含在 SDK (3.2+) 中。
    • 嗨,@anthony iam 收到 nflag 未声明的标识符错误,我需要包含什么才能使其正常工作。?
    • 只需在文件顶部添加 static int nflag;
    • @anthony vage:对不起,我是 Objective-C 的新手。我已经在X-code project 中添加了上面的代码。添加到.m file 后如何调用- (NSString*)ip2mac:(in_addr_t)addr
    • Apple 会批准这个 API 吗?
    【解决方案2】:

    我简化了代码并修复了内存泄漏。

    在我的机器上,头文件位于 /usr/include/netinet 和 /usr/include/net 中。

    - (NSString*)ip2mac:(in_addr_t)addr
    {
        NSString *ret = nil;
    
        size_t needed;
        char *buf, *next;
    
        struct rt_msghdr *rtm;
        struct sockaddr_inarp *sin;
        struct sockaddr_dl *sdl;
    
        int mib[6];
    
        mib[0] = CTL_NET;
        mib[1] = PF_ROUTE;
        mib[2] = 0;
        mib[3] = AF_INET;
        mib[4] = NET_RT_FLAGS;
        mib[5] = RTF_LLINFO;
    
        if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &needed, NULL, 0) < 0)
            err(1, "route-sysctl-estimate");
    
        if ((buf = (char*)malloc(needed)) == NULL)
            err(1, "malloc");
    
        if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &needed, NULL, 0) < 0)
            err(1, "retrieval of routing table");
    
        for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
    
            rtm = (struct rt_msghdr *)next;
            sin = (struct sockaddr_inarp *)(rtm + 1);
            sdl = (struct sockaddr_dl *)(sin + 1);
    
            if (addr != sin->sin_addr.s_addr || sdl->sdl_alen < 6)
                continue;
    
            u_char *cp = (u_char*)LLADDR(sdl);
    
            ret = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
                   cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
    
            break;
        }
    
        free(buf);
    
        return ret;
    }
    

    【讨论】:

    • 您能否提供一个简单的演示代码。 Bcz 我无法使用它。谢谢
    【解决方案3】:

    我不确定 sysctl 函数是公共 API 的一部分。我已经使用了明显的方法,并且我的应用因“非公开”API 使用而被拒绝。但是我也不相信除了上面显示的方法之外还有其他方法可以做到这一点。

    【讨论】:

    • 你好 new299,所以如果我将它用于合法和公共应用程序,它会被应用商店拒绝吗?
    • 这是给我的,那是不久前的事了。可能值得一试。
    • 我知道这是题外话,但您是否有指导以编程方式在网络上寻找将被苹果当局接受的识别设备?我问过 SO here
    猜你喜欢
    • 2012-05-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-07
    • 1970-01-01
    • 1970-01-01
    • 2018-10-12
    • 2023-03-12
    相关资源
    最近更新 更多