我需要在iPhone应用程序中获取默认网关的IP地址。我找不到合适的API。有人知道iPhone是否公开了这些信息吗?
答案 0 :(得分:8)
我已经解决了这个问题,但我不知道这个解决方案是否有效(不会被苹果拒绝)
首先,我将为您提供用于构建解决方案的资源:
http://code.google.com/p/doubango/source/browse/trunk/thirdparties/iphone/include/net/route.h?r=348
如果您认为苹果允许这种代码,那么获得一些反馈会很棒。
getgateway.h
#ifndef __GETGATEWAY_H__
#define __GETGATEWAY_H__
/* getdefaultgateway() :
* return value :
* 0 : success
* -1 : failure */
int getdefaultgateway(in_addr_t * addr);
#endif
getgateway.c
#include <stdio.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <sys/sysctl.h>
#include "getgateway.h"
#include "route.h"
#include <net/if.h>
#include <string.h>
#define CTL_NET 4 /* network, see socket.h */
#if defined(BSD) || defined(__APPLE__)
#define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
int getdefaultgateway(in_addr_t * addr)
{
int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
NET_RT_FLAGS, RTF_GATEWAY};
size_t l;
char * buf, * p;
struct rt_msghdr * rt;
struct sockaddr * sa;
struct sockaddr * sa_tab[RTAX_MAX];
int i;
int r = -1;
if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
return -1;
}
if(l>0) {
buf = malloc(l);
if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
return -1;
}
for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
rt = (struct rt_msghdr *)p;
sa = (struct sockaddr *)(rt + 1);
for(i=0; i<RTAX_MAX; i++) {
if(rt->rtm_addrs & (1 << i)) {
sa_tab[i] = sa;
sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
} else {
sa_tab[i] = NULL;
}
}
if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
&& sa_tab[RTAX_DST]->sa_family == AF_INET
&& sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
char ifName[128];
if_indextoname(rt->rtm_index,ifName);
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
r = 0;
}
}
}
}
free(buf);
}
return r;
}
#endif
答案 1 :(得分:0)
我成功通过发送UDP数据包从服务类型“urn:schemas-upnp-org:device:InternetGatewayDevice:1”获取SSDP协议的地址,并注意到回复的第一个设备(如果有)(忽略有效载荷,因为我只想要网关的IP地址。
这适用于我的应用程序,但要求路由器实现SSDP,这不是完美的,尽管在我的情况下有效。
由于这是一款专用iPhone应用程序(仅限内部使用),我将继续使用此功能。我不会将此标记为“答案”,因为它不是通用解决方案。如果我回到这里并寻找通用解决方案(例如使用ICMP),或者想出如何使用iPhone SDK配置API查询此信息,我将在此处发布。
答案 2 :(得分:0)
对于那些需要人类可读IP的人,我修改了我的getgateway.c如下:
添加到包含:
#include <arpa/inet.h>
在最后一个if语句中,在* addr和r = 0之间;
if(strcmp("en0",ifName)==0){
*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
char str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr), str, INET_ADDRSTRLEN); // supports IPv6
printf("IP: %s\n", str); // prints "192.0.2.33"
r = 0;
}
答案 3 :(得分:0)
在iOS≥12上,您可以使用Network
框架。
从NWPath
获得的NWPathMonitor.pathUpdateHandler
会将NWPath.gateways
变量设置为网关IP。
let monitor = NWPathMonitor(requiredInterfaceType: .wifi)
monitor.pathUpdateHandler = { path in
print(path.gateways)
}
monitor.start(queue: DispatchQueue(label: "nwpathmonitor.queue"))
答案 4 :(得分:-2)
如果我没弄错的话,网关IP总是你的设备IP地址,最后一个八位字节设置为“1”,不是吗?如果您正在寻找,那么您应该能够从localhostAddresses.m文件中找到所需的提示,该文件是CocoaHTTPServer源代码中的示例的一部分。我使用该项目在我的应用程序中添加内部Web服务器,并从该源文件的方法中获取设备IP。
博士。触摸谈论它at this link。