[英]How can I determine the default gateway on iPhone?
我需要在 iPhone 應用程序中獲取默認網關的 IP 地址。 我找不到合適的 API。 有誰知道 iPhone 是否會公開這些信息?
我已經解決了這個問題,雖然我不知道這個解決方案是否有效(不會被蘋果拒絕)
首先,我會給你我用來構建我的解決方案的來源:
http://code.google.com/p/doubango/source/browse/trunk/thirdparties/iphone/include/net/route.h?r=348
如果你認為蘋果會允許這種代碼,那么得到一些反饋會很棒。
獲取網關.h
#ifndef __GETGATEWAY_H__
#define __GETGATEWAY_H__
/* getdefaultgateway() :
* return value :
* 0 : success
* -1 : failure */
int getdefaultgateway(in_addr_t * addr);
#endif
獲取網關
#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
通過發送 UDP 數據包尋找服務類型“urn:schemas-upnp-org:device:InternetGatewayDevice:1”並注意響應的第一個設備(如果有)(忽略有效負載,因為我只想要網關的 IP 地址)。
這適用於我的應用程序,但需要路由器實現 SSDP,這並不完美,盡管在我的情況下有效。
由於這是一個特殊用途的 iPhone 應用程序(僅限內部使用),我將采用它。 我不會將此標記為“答案”,因為它不是通用解決方案。 如果我回到這里並尋找通用解決方案(例如使用 ICMP),或者弄清楚如何使用 iPhone SDK 配置 API 來查詢此信息,我將在此處發布。
對於那些需要人類可讀 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;
}
在 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"))
如果我沒記錯的話,網關 IP 始終是您的設備 IP 地址,最后一個八位字節設置為“1”,不是嗎? 如果這就是您要查找的內容,您應該能夠從 localhostAddresses.m 文件中找到您需要的提示,該文件是 CocoaHTTPServer 源中示例的一部分。 我使用該項目在我的應用程序中添加一個內部網絡服務器,並從該源文件的方法中獲取設備 IP。
Touch 博士在此鏈接中對此進行了討論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.