saber encuentro donde direccion cómo cuál como celular cambiar iphone ios macos ipad ipv6

encuentro - iPhone/iPad/OSX: ¿cómo obtener mi dirección IP programáticamente?



direccion ip iphone sin wifi (9)

Me gustaría obtener la dirección IP de mi iPad mediante programación. ¿Cómo puedo consultar el subsistema de red para averiguar cuáles son mis direcciones IPv4 (y IPv6)?

Gracias. PD: ¿Puedo desactivar IPv6 de alguna manera?


¿Sería fácil simplemente llamar a uno de los servicios de búsqueda de direcciones IP? Configuré http://ipof.in como un servicio que devuelve la dirección IP del dispositivo como JSON / XML o texto sin formato. Usted puede encontrarlos aquí

http://ipof.in/json

http://ipof.in/xml

http://ipof.in/txt

Si desea HTTPS, puede usar las mismas URL con el prefijo https . La ventaja es que, incluso si está en un wifi, obtendrá la dirección pública.


En su archivo de implementación .m,

#import <ifaddrs.h> #import <arpa/inet.h> // Get IP Address - (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; }


Esta respuesta fue inspirada por la respuesta de @ DavidH. inet_ntop algunos problemas, reemplacé inet_ntop con getnameinfo que permite un enfoque más limpio. Tenga en cuenta que esto produce un diccionario que asigna un nombre de interfaz a una matriz de direcciones IP (una interfaz puede tener múltiples IPv4 e IPv6 asociados a ella, técnicamente). No distingue entre IPv4 e IPv6:

// Get all our interface addresses. struct ifaddrs *ifAddresses; if (getifaddrs( &ifAddresses ) != 0) { NSLog( @"Couldn''t get interface addresses: %d", errno ); return nil; } int error; char host[MAX( INET_ADDRSTRLEN, INET6_ADDRSTRLEN )]; _ipAddressesByInterface = [NSMutableDictionary dictionaryWithCapacity:8]; for (struct ifaddrs *ifAddress = ifAddresses; ifAddress; ifAddress = ifAddress->ifa_next) { if (!(ifAddress->ifa_flags & IFF_UP) || (ifAddress->ifa_flags & IFF_LOOPBACK)) // Ignore interfaces that aren''t up and loopback interfaces. continue; if (ifAddress->ifa_addr->sa_family != AF_INET && ifAddress->ifa_addr->sa_family != AF_INET6) // Ignore non-internet addresses. continue; if ((error = getnameinfo( ifAddress->ifa_addr, ifAddress->ifa_addr->sa_len, host, sizeof( host ), NULL, 0, NI_NUMERICHOST )) != noErr) { // Couldn''t to format host name for this address. NSLog( @"Couldn''t resolve host name for address: %s", gai_strerror( error ) ); continue; } NSString *ifName = [NSString stringWithCString:ifAddress->ifa_name encoding: NSUTF8StringEncoding]; NSMutableArray *ifIpAddresses = _ipAddressesByInterface[ifName]; if (!ifIpAddresses) ifIpAddresses = _ipAddressesByInterface[ifName] = [NSMutableArray arrayWithCapacity:2]; [ifIpAddresses addObject:[NSString stringWithCString:host encoding: NSUTF8StringEncoding]]; } freeifaddrs( ifAddresses ); return _ipAddressesByInterface;


Gran solución para swift en Este archivo que sirve todos los detalles.

En Una de mi aplicación, necesito buscar la dirección IP wifi. He usado las respuestas anteriores, en swift 3 como este:

let WIFI_IF = "en0" let UNKNOWN_IP_ADDRESS = "" var addresses: [AnyHashable: Any] = ["wireless": UNKNOWN_IP_ADDRESS, "wired": UNKNOWN_IP_ADDRESS, "cell": UNKNOWN_IP_ADDRESS] var interfaces: UnsafeMutablePointer<ifaddrs>? = nil var temp_addr: UnsafeMutablePointer<ifaddrs>? = nil var success: Int = 0 success = Int(getifaddrs(&interfaces)) if success == 0 { temp_addr = interfaces while temp_addr != nil { if temp_addr?.pointee.ifa_addr == nil { continue } if temp_addr?.pointee.ifa_addr.pointee.sa_family == UInt8(AF_INET) { if (String(utf8String: (temp_addr?.pointee.ifa_name)!) == WIFI_IF) { addresses["wireless"] = String(utf8String: inet_ntoa(((temp_addr?.pointee.ifa_addr as? sockaddr_in)?.sin_addr)!)) } } temp_addr = temp_addr?.pointee.ifa_next } }

En este código, se bloquea porque tengo que comprobar nil en cada declaración que he utilizado como opcional ? . Por lo tanto, es mejor para mí usar el archivo vinculado dado en mi clase. Me resulta fácil comprobar ahora como sigue:

class func getWifiIPAddress() -> String { var wifiIp = "" let WIFI_IF = "en0" let allInterface = Interface.allInterfaces() for interf in allInterface { if interf.name == WIFI_IF { if let address = interf.address { if address.contains(".") { wifiIp = address break } } } } return wifiIp }

He analizado una cadena para "." porque Interface Class devuelve dos interfaces en mi iPhone para una dirección en0 como "fb00 ::" y una dirección como "101.10.1.1"


La respuesta de @DavidH funciona bien hasta que obtuve este resultado de alguna red celular 4G:

{ "lo0/ipv4" = "127.0.0.1"; "lo0/ipv6" = "fe80::1"; "pdp_ip0/ipv4" = "10.132.76.168"; "utun0/ipv6" = "fe80::72c3:e25e:da85:b730"; }

No estoy usando vpn así que no tengo idea de por qué tenía utun0 / ipv6.

--- Actualizado ---

Además, soluciono este problema y descubrí que puedo obtener una dirección vpn falsa incluso en otras redes 4G (¿es este error de iOS?),

{ ""awdl0/ipv6"" = ""fe80::c018:9fff:feb2:988""; ""en0/ipv6"" = ""fe80::181a:2e43:f91b:db2b""; ""lo0/ipv4"" = ""127.0.0.1""; ""lo0/ipv6"" = ""fe80::1""; ""pdp_ip0/ipv4"" = ""10.48.10.210""; ""utun0/ipv4"" = ""192.168.99.2""; }

Si utilicé vpn obtendré esto:

{ "lo0/ipv4" = "127.0.0.1"; "lo0/ipv6" = "fe80::1"; "pdp_ip0/ipv4" = "10.49.187.23"; "utun0/ipv6" = "fe80::5748:5b5d:2bf0:658d"; "utun1/ipv4" = "192.168.99.2"; //the real one }

Entonces, utun1 NO utun0

Sin averiguar por qué tendré que soltar el vpn check :(

---- actualización ----

Repliqué un error (28131847) a Apple y respondí con "No todas las interfaces utun son para VPN. Hay otras características del sistema operativo que usan interfaces utun".

Pero cuando le pregunté cómo obtener una dirección IP vpn válida, su respuesta fue bastante decepcionante: "Puede ir a Ajustes -> VPN y mirar su configuración de VPN para ver si la VPN está activa. En algunos casos, puede ver el También se asignó una dirección IP allí. Ahora estamos cerrando este informe de errores ". :(

---- actualización 2016/11/04 ----

Apunto el problema nuevamente y necesito modificar aún más la respuesta de @ DavidH para arreglarlo:

Estaba en la red 4G y obtuve esta dirección:

addresses: { "awdl0/ipv6" = "fe80::98fd:e6ff:fea9:3afd"; "en0/ipv6" = "fe80::8dd:7d92:4159:170e"; "lo0/ipv4" = "127.0.0.1"; "lo0/ipv6" = "fe80::1"; "pdp_ip0/ipv4" = "10.37.212.102"; "utun0/ipv6" = "fe80::279c:ea56:a2ef:d128"; }

Con su respuesta original obtendré el wifi IP fe80 :: 8dd: 7d92: 4159: 170e, que fue falso y falló la conexión.

Así que modifiqué el código para me gusta,

[searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) { if ((internetReach.isReachableViaWiFi && [key hasPrefix:IOS_WIFI]) || (internetReach.isReachableViaWWAN && [key hasPrefix:IOS_CELLULAR])) { address = addresses[key]; if(address) *stop = YES; } } ];


La solución actual no devuelve el dispositivo en0 en OS X, el siguiente código usa el Marco de Configuración del Sistema para obtener las interfaces y luego usa las funciones C estándar para obtener la dirección IP.

#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> #include <sys/ioctl.h> #include <net/if.h> #define IFT_ETHER 0x6 #include <SystemConfiguration/SCDynamicStore.h> +(void)getInterfaces { SCDynamicStoreRef storeRef = SCDynamicStoreCreate(NULL, (CFStringRef)@"FindCurrentInterfaceIpMac", NULL, NULL); CFPropertyListRef global = SCDynamicStoreCopyValue (storeRef,CFSTR("State:/Network/Interface")); id primaryInterface = [(__bridge NSDictionary *)global valueForKey:@"Interfaces"]; for (NSString* item in primaryInterface) { if(get_iface_address([item UTF8String])) { NSString *ip = [NSString stringWithUTF8String:get_iface_address([item UTF8String])]; NSLog(@"interface: %@ - %@",item,ip); } else NSLog(@"interface: %@",item); } } static char * get_iface_address (char *interface) { int sock; uint32_t ip; struct ifreq ifr; char *val; if (!interface) return NULL; /* determine UDN according to MAC address */ sock = socket (AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror ("socket"); return NULL; } strcpy (ifr.ifr_name, interface); ifr.ifr_addr.sa_family = AF_INET; if (ioctl (sock, SIOCGIFADDR, &ifr) < 0) { perror ("ioctl"); close (sock); return NULL; } val = (char *) malloc (16 * sizeof (char)); ip = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr; ip = ntohl (ip); sprintf (val, "%d.%d.%d.%d", (ip >> 24) & 0xFF, (ip >> 16) & 0xFF, (ip >> 8) & 0xFF, ip & 0xFF); close (sock); return val; }



Obtener la dirección IP usando Swift 3:

func getIPAddress() -> String { var address: String = "error" var interfaces: ifaddrs? = nil var temp_addr: ifaddrs? = nil var success: Int = 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 != nil { if temp_addr?.ifa_addr?.sa_family == AF_INET { // Check if interface is en0 which is the wifi connection on the iPhone if (String(utf8String: temp_addr?.ifa_name) == "en0") { // Get NSString from C String address = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr)) } } temp_addr = temp_addr?.ifa_next } } // Free memory freeifaddrs(interfaces) return address }


El siguiente código encuentra todas las direcciones IPv4 e IPv6 en un dispositivo iOS o OSX. El primer método getIPAddress actúa más o menos como el código anterior en esta respuesta: puede preferir una u otra dirección de tipo, y siempre prefiere WIFI sobre celular (obviamente, podría cambiar esto).

Lo que es más interesante, puede devolver un diccionario de todas las direcciones encontradas, omitiendo direcciones para interfaces que not up , o direcciones asociadas con loopback . El código anterior, así como otras soluciones sobre este tema, no decodificarán correctamente IPv6 (inet_ntoa no puede tratar con ellos). Esto me lo indicó Jens Alfke en un foro de Apple: la función adecuada para usar es inet_ntop (mira la página man, o consulta este artículo inet_ntop también proporcionado por Jens).

Las claves del diccionario tienen la forma "interfaz" "/" "ipv4 o ipv6".

#include <ifaddrs.h> #include <arpa/inet.h> #include <net/if.h> #define IOS_CELLULAR @"pdp_ip0" #define IOS_WIFI @"en0" //#define IOS_VPN @"utun0" #define IP_ADDR_IPv4 @"ipv4" #define IP_ADDR_IPv6 @"ipv6" - (NSString *)getIPAddress:(BOOL)preferIPv4 { NSArray *searchArray = preferIPv4 ? @[ /*IOS_VPN @"/" IP_ADDR_IPv4, IOS_VPN @"/" IP_ADDR_IPv6,*/ IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] : @[ /*IOS_VPN @"/" IP_ADDR_IPv6, IOS_VPN @"/" IP_ADDR_IPv4,*/ IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ; NSDictionary *addresses = [self getIPAddresses]; NSLog(@"addresses: %@", addresses); __block NSString *address; [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop) { address = addresses[key]; if(address) *stop = YES; } ]; return address ? address : @"0.0.0.0"; } - (NSDictionary *)getIPAddresses { NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8]; // retrieve the current interfaces - returns 0 on success struct ifaddrs *interfaces; if(!getifaddrs(&interfaces)) { // Loop through linked list of interfaces struct ifaddrs *interface; for(interface=interfaces; interface; interface=interface->ifa_next) { if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) { continue; // deeply nested code harder to read } const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr; char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ]; if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) { NSString *name = [NSString stringWithUTF8String:interface->ifa_name]; NSString *type; if(addr->sin_family == AF_INET) { if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) { type = IP_ADDR_IPv4; } } else { const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr; if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) { type = IP_ADDR_IPv6; } } if(type) { NSString *key = [NSString stringWithFormat:@"%@/%@", name, type]; addresses[key] = [NSString stringWithUTF8String:addrBuf]; } } } // Free memory freeifaddrs(interfaces); } return [addresses count] ? addresses : nil; }

EDIT1: Código actualizado el 16 de mayo de 2014 (error señalado por lhunath, ver comentarios). Ahora se devuelven direcciones de bucle invertido, pero es fácil para usted descomentar la prueba para excluirlas usted mismo.

EDIT2: (por una persona desconocida): Mejorado aún más el 13 de marzo de 2015: en caso de que el usuario utilice una VPN (independientemente de WiFi o celular), el código anterior habría fallado. Ahora, funciona incluso con conexiones VPN. Las conexiones VPN tienen prioridad sobre WiFi y Cell porque así es como lo maneja el dispositivo. Esto debería funcionar incluso para Mac ya que la conexión VPN en una Mac también usa IF utun0 pero no se ha probado.

EDIT3: (9/8/2016) Dados los problemas experimentados por @Qiulang (ver comentarios) con el código VPN (que alguien más agregó), lo he comentado. Si alguien sabe definitivamente cómo especificar una VPN de usuario, por favor haga sonar un comentario.