加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在Objective-C中获取路由器mac(没有ARP系统调用)

发布时间:2020-12-15 01:47:28 所属栏目:百科 来源:网络整理
导读:好的 – 我正在Objective C中编写一个守护进程,它每5秒检查一次连接的路由器mac地址. 我对目标C完全不熟悉,我正在寻找一种更好的方法来做我已经在做的事情. 我正在调用“arp -a”并通过“Task”解析结果: NSTask *task;task = [[NSTask alloc] init];[task
好的 – 我正在Objective C中编写一个守护进程,它每5秒检查一次连接的路由器mac地址.

我对目标C完全不熟悉,我正在寻找一种更好的方法来做我已经在做的事情.

我正在调用“arp -a”并通过“Task”解析结果:

NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/sbin/arp"];

NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-a",nil];
[task setArguments: arguments]; 

NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];

NSFileHandle *file;
file = [pipe fileHandleForReading];

[task launch];

NSData *data;
data = [file readDataToEndOfFile];

我担心这不是很有效率.

有什么建议么?我每5秒运行一次此代码块.

解决方法

Apple的arp实现是开源的.看看 the file,了解它的实现……它并不是非常复杂.但它是纯ANSI C.

您应该能够简单地复制粘贴大部分功能……而不是打印结果,只需存储原始地址.

编辑:这是源的精简版,只运行相当于arp -a.这应该编译没有任何特殊指令.

/*
 * Copyright (c) 1999 Apple Computer,Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis,WITHOUT WARRANTY OF ANY KIND,EITHER
 * EXPRESS OR IMPLIED,AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,* INCLUDING WITHOUT LIMITATION,ANY WARRANTIES OF MERCHANTABILITY,* FITNESS FOR A PARTICULAR PURPOSE,QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */


#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 <net/if_types.h>
#include <net/route.h>

#include <netinet/in.h>
#include <netinet/if_ether.h>

#include <arpa/inet.h>

#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <nlist.h>
#include <paths.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static int nflag;

void
ether_print(cp)
    u_char *cp;
{
    printf("%x:%x:%x:%x:%x:%x",cp[0],cp[1],cp[2],cp[3],cp[4],cp[5]);
}


/*
 * Dump the entire arp table
 */
int
dump(addr)
    u_long addr;
{
    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;
    int found_entry = 0;

    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,0) < 0)
        err(1,"route-sysctl-estimate");
    if ((buf = malloc(needed)) == NULL)
        err(1,"malloc");
    if (sysctl(mib,buf,"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;
        }
        printf("%s (%s) at ",host,inet_ntoa(sin->sin_addr));
        if (sdl->sdl_alen)
            ether_print((u_char *)LLADDR(sdl));
        else
            printf("(incomplete)");
        if (rtm->rtm_rmx.rmx_expire == 0)
            printf(" permanent");
        if (sin->sin_other & SIN_PROXY)
            printf(" published (proxy only)");
        if (rtm->rtm_addrs & RTA_NETMASK) {
            sin = (struct sockaddr_inarp *)
                (sdl->sdl_len + (char *)sdl);
            if (sin->sin_addr.s_addr == 0xffffffff)
                printf(" published");
            if (sin->sin_len != 8)
                printf("(weird)");
        }
        printf("n");
    }
    return (found_entry);
}

int main (int argc,char const *argv[])
{
    dump(0);
    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读