Necesito obtener la dirección IP de la puerta de enlace predeterminada en una aplicación de iPhone. No puedo encontrar la API correcta. Alguien sabe si iPhone expone esta información?¿Cómo puedo determinar la puerta de enlace predeterminada en iPhone?
Respuesta
Si no me equivoco, la IP de la puerta de enlace siempre es la que sea la dirección IP de su dispositivo, con el último octeto configurado en "1", ¿no es así? Si eso es lo que está buscando, debería poder encontrar los consejos que necesita del archivo localhostAddresses.m que forma parte de las muestras en las fuentes de CocoaHTTPServer. Utilizo el proyecto para agregar un servidor web interno dentro de mi aplicación y obtengo la IP de los dispositivos de los métodos del archivo fuente.
Dr. Touch habla del tema at this link.
Tuve éxito obteniendo la dirección del protocolo SSDP enviando un paquete UDP buscando el tipo de servicio "urn: schemas-upnp-org: dispositivo: InternetGatewayDevice: 1" y tomando nota del primer dispositivo (si hay alguno) que responde (ignorando la carga útil, ya que solo quiero la dirección IP de la puerta de enlace).
Esto funciona para mi aplicación, pero requiere que el enrutador implemente SSDP, que no es perfecto, aunque funciona en mi caso.
Dado que esta es una aplicación de iPhone para fines especiales (interna, solamente), me voy a ir con esto. No marcaré esto como "la respuesta" porque no es una solución de propósito general. Si vuelvo a esto y busco una solución de propósito general (como el uso de ICMP) o descubro cómo usar las API de configuración de SDK de iPhone para consultar esta información, publicaré aquí.
Hola Bill, ¿Alguna sugerencia sobre el envío y la recepción de paquetes UDP? Me estoy perdiendo en los documentos en este momento y algo de claridad realmente ayudaría. Intento usar el iPhone para descubrir dispositivos SSDP y parece que ya has hecho eso. Saludos, Dave. –
He resuelto esto, aunque yo sé si esta solución es válida (no será rechazada por manzana)
primero te voy a dar las fuentes que utiliza para construir mi solución al:
http://code.google.com/p/doubango/source/browse/trunk/thirdparties/iphone/include/net/route.h?r=348
sería muy bueno para obtener alguna información si cree que apple va a permitir que este tipo de código.
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
192.168 no es el único espacio de direcciones IP reservado para redes privadas, por lo que la cláusula if que ha agregado es realmente perjudicial. Este código perderá las IP de la puerta de enlace en 10.x y 172.16.x, que son tan válidas como 192.168.x. Considera usar el código original en su lugar. – AriX
Usar el código original como he sugerido puede causar problemas, ya que en un iPhone puede obtener la puerta de enlace de la red interna del operador en lugar de la de Wi-Fi. Supongo que es por eso que agregó el cheque para 192.168.x en primer lugar. Estoy trabajando en una forma de obtener el nombre de la interfaz para estas puertas de enlace, para que pueda verificar que la puerta de enlace corresponde a la interfaz de Wi-Fi. – AriX
considere actualizar la respuesta una vez que encuentre una solución – Jakob
para aquellos que necesitan IP legible por humanos, he modificado mi getgateway.c de la siguiente manera:
añadir a incluye:
#include <arpa/inet.h>
dentro de la última instrucción if, entre * addr yr = 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;
}
- 1. Cómo obtener la puerta de enlace predeterminada en Mac OSX
- 2. Obtener la puerta de enlace predeterminada en java
- 3. Puerta de enlace predeterminada en C en Linux
- 4. ¿Cómo puedo determinar la IP de mi enrutador/puerta de enlace en Java?
- 5. Interfaz de red de búsqueda de Java para la puerta de enlace predeterminada
- 6. ¿Cómo obtener la dirección de la puerta de enlace WIFI en el iPhone?
- 7. ¿Cómo crear una puerta de enlace SMS?
- 8. ¿Cómo determinar la impresora predeterminada usando WPF?
- 9. ¿Qué es una puerta de enlace SMS
- 10. Repositorio o patrón de puerta de enlace en Ruby
- 11. Play2-mini y Akka2 para la puerta de enlace HTTP
- 12. "Hg a Hg (puerta de enlace) a SVN" en comparación con "Git a Git (puerta de enlace) a SVN"
- 13. hgweb.cgi arroja un 502 (puerta de enlace defectuosa) al pulsar
- 14. primavera Integración de puerta de enlace sin argumentos
- 15. ¿Cómo integrar la puerta de enlace de pagos de CCavenue en mi sitio web?
- 16. Obtener la dirección IP de la puerta de enlace en android
- 17. Biblioteca de puerta de enlace de pago Java
- 18. ¿Cómo puedo determinar mediante programación la página de códigos predeterminada actual de Windows?
- 19. Obteniendo la puerta de enlace para usar para una IP determinada en ANSI C
- 20. Android como puerta de enlace SIP a GSM
- 21. Cómo depurar EXC_BAD_ACCESS en la aplicación iPhone cuando no puedo determinar la causa?
- 22. usando la puerta de enlace de pago y la conformidad PCI
- 23. cómo abrir el enlace de iTunes en la aplicación iphone?
- 24. Cómo evito un tiempo de espera de puerta de enlace con FastCGI en Nginx
- 25. Sistemas de tarjetas de crédito basadas en tokens frente a la puerta de enlace tradicional
- 26. ¿Cómo puedo determinar la velocidad de CodeIgniter?
- 27. PHP falla la conexión de socket con la puerta de enlace de notificaciones de Apple
- 28. android: determinar un enlace simbólico
- 29. eMail a través de la puerta de enlace SMS se envía, pero no se recibe
- 30. Creación de una puerta de enlace de pago en línea completa como Paypal
Esto es incorrecto. Si bien es una convención común, colocar el enrutador en x.y.z.1 no es obligatorio ni está garantizado por la especificación. He visto muchas redes en vivo donde el enrutador era xyz254, y he visto redes en vivo donde la puerta de enlace predeterminada NO está en la subred del dispositivo (la mayoría de los sistemas operativos intentarán enviar a la dirección IP de la puerta de enlace sin condiciones si la IP a la que se envían es no enrutable, incluso si la puerta de enlace no se puede enrutar ... algunos ISP dependen de este comportamiento). Además, las cosas tienden a configurarse de manera diferente en las subredes Clase A y B. –
Gracias por iluminarme. Espero (por curiosidad) escuchar lo que descubres. – wkw