2011-02-02 18 views
15

Necesito obtener la dirección de la puerta de enlace de la red wifi que conecto con el iPhone. Alguien sabe cómo conseguir eso?¿Cómo obtener la dirección de la puerta de enlace WIFI en el iPhone?

Solo para aclarar, estoy en busca de la información de esta pantalla:

enter image description here

Gracias.

+0

Una técnica, aunque quizás un poco especializada, se perfila aquí http://stackoverflow.com/questions/2300149/how-can-i -determine-the-default-gateway-on-iphone –

Respuesta

2

Después de comprobar la espalda con Apple, el SDK no ofrece una manera fácil de hacer eso. La forma más difícil, si la hay, es cavar profundamente en el sistema o usar un traceroute.

He archivado un informe de error, tal vez lo agregarán en el futuro.

0

Echa un vistazo a las respuestas a Objective-C : How to fetch the router address?

Tal vez sólo tangencialmente relacionado, pero ver la técnica descrita en esta entrada del blog: http://blog.zachwaugh.com/post/309927273/programmatically-retrieving-ip-address-of-iphone

Se obtiene la dirección IP de la interfaz Wi-Fi, y podría ser un otro punto de partida para la búsqueda de otra solución ....

- (NSString *)getIPAddress 
{ 
    NSString *address = @"error"; 
    struct ifaddrs *interfaces = NULL; 
    struct ifaddrs *temp_addr = NULL; 
    int success = 0; 

    // retrieve the current interfaces - returns 0 on success 
    success = getifaddrs(&interfaces); 
    if (success == 0) 
    { 
    // Loop through linked list of interfaces 
    temp_addr = interfaces; 
    while(temp_addr != NULL) 
    { 
     if(temp_addr->ifa_addr->sa_family == AF_INET) 
     { 
     // Check if interface is en0 which is the wifi connection on the iPhone 
     if([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) 
     { 
      // Get NSString from C String 
      address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)]; 
     } 
     } 

     temp_addr = temp_addr->ifa_next; 
    } 
    } 

    // Free memory 
    freeifaddrs(interfaces); 

    return address; 
} 
+0

buen punto, uno debe comprobar que la puerta de enlace devuelta es la puerta de enlace en la interfaz wifi – Jakob

+0

El código anterior devuelve una dirección IP del dispositivo, no una puerta de enlace. – Alena

+1

... que dije en el último párrafo –

11

esto funciona para mí, aunque tengo que conseguir una copia de la route.h en mi proyecto

mi entendimiento general es que este código consultas y recupera y tabla de enrutamiento y utiliza sus entradas para determinar el valor por defecto ruta también conocido como puerta de enlace IP

/* $Id: getgateway.c,v 1.6 2007/12/13 14:46:06 nanard Exp $ */ 
/* libnatpmp 
* Copyright (c) 2007, Thomas BERNARD <[email protected]> 
* 
* Permission to use, copy, modify, and/or distribute this software for any 
* purpose with or without fee is hereby granted, provided that the above 
* copyright notice and this permission notice appear in all copies. 
* 
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 

#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

¡Muchas gracias! Tu código me salvó :) – mohamede1945

+2

Solo una nota para cualquiera que pruebe esto en el simulador: "en1" podría ser la conexión de red activa en lugar de "en0". – newenglander

+2

Puede obtener route.h desde aquí: http://www.opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h Y luego obtenga la puerta de salida como: 'struct in_addr gatewayaddr; int r = getdefaultgateway (& (gatewayaddr.s_addr)); if (r> = 0) { NSString * ipString = [NSString stringWithFormat: @ "% s", inet_ntoa (gatewayaddr)]; NSLog (@ "puerta de enlace predeterminada:% @", ipString); } else { NSLog (@ "getdefaultgateway() failed"); } ' – ddiego

12

Añadir a su proyecto route.h archivo desde http://opensource.apple.com/source/xnu/xnu-1456.1.26/bsd/net/route.h

Crear getgateway.h

int getdefaultgateway(in_addr_t * addr); 

Crear getgateway.c

#include <stdio.h> 
#include <netinet/in.h> 
#include <stdlib.h> 
#include <sys/sysctl.h> 
#include "getgateway.h" 

#include "TargetConditionals.h" 
#if TARGET_IPHONE_SIMULATOR 
    #include <net/route.h> 
    #define TypeEN "en1" 
#else 
    #include "route.h" 
    #define TypeEN "en0" 
#endif 

#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(TypeEN,ifName)==0){ 
          *addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr; 
           r = 0;       
         } 
       } 
      } 
     } 
     free(buf); 
    } 
    return r; 
} 
#endif 

A través del siguiente fragmento, este ejemplo será un buen trabajo en el simulador y el legado.

#include "TargetConditionals.h" 
#if TARGET_IPHONE_SIMULATOR 
    #include <net/route.h> 
    #define TypeEN "en1" 
#else 
    #include "route.h" 
    #define TypeEN "en0" 
#endif 

Utilice este código en su proyecto Objetivo C

#import "getgateway.h" 
#import <arpa/inet.h> 

- (NSString *)getGatewayIP { 
    NSString *ipString = nil; 
    struct in_addr gatewayaddr; 
    int r = getdefaultgateway(&(gatewayaddr.s_addr)); 
    if(r >= 0) { 
     ipString = [NSString stringWithFormat: @"%s",inet_ntoa(gatewayaddr)]; 
     NSLog(@"default gateway : %@", ipString); 
    } else { 
     NSLog(@"getdefaultgateway() failed"); 
    } 

    return ipString; 

} 
+0

¿Cómo puedo actualizar el código a la red ipv6 solamente? – theFool

+0

es posible obtener todas las direcciones de pasarelas wifi dentro de la red –

+0

Usted hace que mi día Hombre ... funcione como un amuleto: D ... –

Cuestiones relacionadas