Как определить шлюз по умолчанию на iPhone? - PullRequest
6 голосов
/ 20 февраля 2010

Мне нужно получить IP-адрес шлюза по умолчанию в приложении iPhone. Я не могу найти правильный API. Кто-нибудь знает, раскрывает ли iPhone эту информацию?

Ответы [ 4 ]

8 голосов
/ 11 ноября 2011

Я решил это, хотя я не знаю, если это решение действительно (не будет отклонено яблоком)

Сначала я дам вам источники, которые я использовал для построения своего решения:

http://code.google.com/p/doubango/source/browse/trunk/thirdparties/iphone/include/net/route.h?r=348

http://code.google.com/p/touchcode/source/browse/Experimental/TouchHTTPD/Externals/libnatpmp-20071213/getgateway.c?r=bc90b03205cbebb0633a7b5b203c2c6d5cb860dc

Было бы здорово получить отзывы, если вы думаете, что Apple разрешит такой код.

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
0 голосов
/ 06 апреля 2016

для тех, кому нужен читабельный 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;
}
0 голосов
/ 24 февраля 2010

Мне удалось получить адрес по протоколу SSDP, отправив пакет UDP с поиском типа службы "urn: schemas-upnp-org: device: InternetGatewayDevice: 1" и отметив первое устройство (если оно есть), которое отвечает (игнорируя полезная нагрузка, так как мне нужен только IP-адрес шлюза).

Это работает для моего приложения, но требует, чтобы маршрутизатор реализовал SSDP, что не идеально, хотя работает в моем случае.

Поскольку это специальное приложение для iPhone (только для внутреннего использования), я собираюсь пойти на это. Я не буду отмечать это как «ответ», потому что это не решение общего назначения. Если я вернусь к этому и поищу решение общего назначения (например, с использованием ICMP) или выясню, как использовать API конфигурации iPhone SDK для запроса этой информации, я опубликую здесь.

0 голосов
/ 20 февраля 2010

Если я не ошибаюсь, IP-адрес шлюза всегда равен IP-адресу вашего устройства с последним октетом, установленным в «1», не так ли? Если это то, что вы ищете, вы сможете найти нужные подсказки в файле localhostAddresses.m, который является частью примеров в источниках CocoaHTTPServer. Я использую проект для добавления внутреннего веб-сервера в свое приложение и получаю IP-адрес устройства из методов этого исходного файла.

Dr. Touch говорит об этом по этой ссылке .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...