在Objective-C中获取路由器mac(无ARP系统调用)
好的-我正在用Objective C编写一个守护进程,每5秒检查一次连接的路由器mac地址 我对目标C完全陌生,我正在寻找一种更好的方法来完成我已经在做的事情 我目前正在调用“arp-a”,并通过“Task”解析结果: 恐怕这不是很有效在Objective-C中获取路由器mac(无ARP系统调用),objective-c,xcode,bash,macos,Objective C,Xcode,Bash,Macos,好的-我正在用Objective C编写一个守护进程,每5秒检查一次连接的路由器mac地址 我对目标C完全陌生,我正在寻找一种更好的方法来完成我已经在做的事情 我目前正在调用“arp-a”,并通过“Task”解析结果: 恐怕这不是很有效 有什么建议吗?我每5秒运行一次这个代码块。苹果的arp实现是开源的。请看一看,了解其实现的想法。。。这并不十分复杂。不过,它是纯ANSI C 您应该能够简单地复制粘贴大部分功能。。。而不是打印结果,只需存储原始地址 Edit:这是一个精简版的源代码,它只运行与a
有什么建议吗?我每5秒运行一次这个代码块。苹果的
arp
实现是开源的。请看一看,了解其实现的想法。。。这并不十分复杂。不过,它是纯ANSI C
您应该能够简单地复制粘贴大部分功能。。。而不是打印结果,只需存储原始地址
Edit:这是一个精简版的源代码,它只运行与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, 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;
}
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;
}
/*
*版权所有(c)1999苹果电脑公司。保留所有权利。
*
*@APPLE\u许可证\u标题\u开始@
*
*此文件包含原始代码和/或原始代码的修改
*如和中所定义,受苹果公共资源许可证的约束
*2.0版(“许可证”)。除非在中,否则不能使用此文件
*遵守许可证。请通过以下地址获取许可证副本:
* http://www.opensource.apple.com/apsl/ 并在使用前阅读
*文件。
*
*原始代码和许可证下分发的所有软件
*按“原样”分发,也不提供任何形式的担保
*明示或默示,苹果特此否认所有此类保证,
*包括但不限于任何适销性保证,
*适合特定用途、安静享受或不侵权。
*请参阅许可证,了解特定语言的管辖权和权限
*许可证下的限制。
*
*@APPLE\u LICENSE\u HEADER\u END@
*/
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
静态int-nflag;
无效的
乙醚打印(cp)
u_char*cp;
{
printf(“%x:%x:%x:%x:%x:%x”、cp[0]、cp[1]、cp[2]、cp[3]、cp[4]、cp[5]);
}
/*
*转储整个arp表
*/
int
转储(地址)
乌龙地址;
{
int-mib[6];
所需尺寸;
char*host、*lim、*buf、*next;
结构rt_msghdr*rtm;
结构sockaddr_inarp*sin;
结构sockaddr_dl*sdl;
外部内部h_errno;
结构主机*hp;
int found_entry=0;
mib[0]=CTL_NET;
mib[1]=PF_路由;
mib[2]=0;
mib[3]=AF_INET;
mib[4]=净放射性标志;
mib[5]=RTF_linfo;
if(sysctl(mib,6,NULL,&needed,NULL,0)<0)
err(1,“路由系统控制权估计”);
if((buf=malloc(需要))==NULL)
错误(1,“malloc”);
if(sysctl(mib,6,buf,&needed,NULL,0)<0)
err(1,“路由表的实际检索”);
lim=需要的buf+;
对于(next=buf;nextrtm\m格伦){
rtm=(struct rt_msghdr*)next;
sin=(结构sockaddr_inarp*)(rtm+1);
sdl=(结构sockaddr_dl*)(sin+1);
如果(地址){
if(addr!=sin->sin\u addr.s\u addr)
继续;
找到的_条目=1;
}
如果(nflag==0)
hp=gethostbyaddr((caddr__t)和(sin->sin_addr),
sizeof sin->sin地址,AF INET);
其他的
hp=0;
如果(hp)
主机=hp->h_名称;
否则{
host=“?”;
如果(h_errno==重试)
nflag=1;
}
printf(“%s(%s)at”,主机,inet_ntoa(sin->sin_addr));
如果(sdl->sdl\u alen)
以太打印((u_char*)LLADDR(sdl));
其他的
printf(“(不完整)”);
如果(rtm->rtm\u rmx.rmx\u expire==0)
printf(“永久”);
if(sin->sin\u其他&sin\u代理)
printf(“已发布(仅限代理)”;
if(rtm->rtm地址和RTA网络掩码){
sin=(结构sockaddr\u inarp*)
(sdl->sdl_len+(字符*)sdl);
如果(sin->sin\u addr.s\u addr==0xFFFFFF)
printf(“已出版”);
如果(sin->sin_len!=8)
printf(“(怪异)”);
}
printf(“\n”);
}
返回(找到输入项);
}
int main(int argc,char const*argv[]
{
转储(0);
返回0;
}
首先,我只想澄清“arp-a”不是系统调用。系统调用是一种特殊的函数,实际上是操作系统的挂钩。看起来您只是不想使用外部程序,而不是系统调用。系统调用的示例有read()、write()、socket()等。对此表示抱歉。我不熟悉这门语言,尤其是术语。你知道怎么做吗?你能说说你为什么要这么做吗?OS X已经提供了各种网络监控和配置服务,这些服务可能比您自己的更有用。是否有一个实用程序可以监控机场连接的路由器?如果有,我还没找到。我需要根据接入点连接的变化运行指定的配置脚本。由于某种原因,在下载了arp.c和arp.h之后,我无法编译这个。。。想法?是的,他们用#define
做了一些有趣的事情。我在我的答案中添加了一个可行的、完全独立的arp-a实现。哇,太酷了。我会查一查,然后再报告。非常有用。谢谢。这真是太棒了——对我来说这是一个非常好的学习时刻。非常感谢。首先,非常感谢你的回答。我正在尝试在IOS设备上运行此代码。它在模拟器(xcode 4.0.1)上运行良好。但是,在为设备编译时,我没有在以下位置获得这样的文件:net/if_types.h、net/route.h、netinet/if_ether.h和nlist.h。提前谢谢
/*
* 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, 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;
}
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;
}