I know how to get the IP address, via en0 interface, seen here: iPhone/iPad/OSX: How to get my IP address programmatically?
But now I'm implementing an ethernet connection to the LAN using the Lightning to USB 3 Camera Adapter in order to connect to the internet without Wifi in 9.3, so the above solution can't resolve the IP address without the wireless connection. The iPad is on the internet fine, now it's just important the app can resolve the device's own IP address.
How can I get the iPad's IP address through a Lightning->USB->Ethernet connection? As opposed to wirelessly.
Thanks in advance!
en2
interface.
Add:
[[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en2"]
to the first solution in iPhone/iPad/OSX: How to get my IP address programmatically? to also get the device's IP address through wired connection.
UPDATE: Just expanding on @Raptor's solution linked above; this will return both wired and wireless IP Address, if both or either is present. Then just check the return dictionary's values' lengths to see what you're working with.
#import <ifaddrs.h>
#import <arpa/inet.h>
+ (NSDictionary *)getBothIPAddresses {
const NSString *WIFI_IF = @"en0";
NSArray *KNOWN_WIRED_IFS = @[@"en1",@"en2",@"en3",@"en4"];
NSArray *KNOWN_CELL_IFS = @[@"pdp_ip0",@"pdp_ip1",@"pdp_ip2",@"pdp_ip3"];
const NSString *UNKNOWN_IP_ADDRESS = @"";
NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithDictionary:@{@"wireless":UNKNOWN_IP_ADDRESS,
@"wired":UNKNOWN_IP_ADDRESS,
@"cell":UNKNOWN_IP_ADDRESS}];
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 == NULL) {
temp_addr = temp_addr->ifa_next;
continue;
}
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:WIFI_IF]) {
// Get NSString from C String
[addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"wireless"];
}
// Check if interface is a wired connection
if([KNOWN_WIRED_IFS containsObject:[NSString stringWithUTF8String:temp_addr->ifa_name]]) {
[addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"wired"];
}
// Check if interface is a cellular connection
if([KNOWN_CELL_IFS containsObject:[NSString stringWithUTF8String:temp_addr->ifa_name]]) {
[addresses setObject:[NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)] forKey:@"cell"];
}
}
temp_addr = temp_addr->ifa_next;
}
}
// Free memory
freeifaddrs(interfaces);
return addresses;
}
UPDATE:
en3
interface, another possibility; seems to depend on the type of adapter. Makes me think there could be more interfaces that I'm still missing based on hardware being used, so please comment if anyone discovers more.
UPDATE:
en4
as well; doesn't necessarily depend on adapter like I originally thought, because a Mini with all the same hardware at one point decided to switch from one interface to this new one. Also, I'm starting to think it may be easier to just compare the ifa_name to any string with a format of en[2..n]
, so long as it's in the AF_INET
family (for example, en1
is NOT and doesn't return an address we're looking for); it's likely premature to implement something like that for Prod without more proof, so for now I manage with a list of 'known' wired interfaces.
UPDATE:
Considers cellular AF_INET
interfaces too, mentioned in What exactly means iOS networking interface name? what's pdp_ip ? what's ap?
UPDATE:
Ethernet IP addresses have begun showing up on the en1
interface lately on certain new iPads, so it should also be considered when it's a member of the AF_INET
family. No distinguishable rhyme or reason, it happens with varying iPad models and iOS versions.
Updated For Swift 3
import arpa
import ifaddrs
class func getBothIPAddresses() -> [AnyHashable: Any] {
let WIFI_IF: String = "en0"
let KNOWN_WIRED_IFS: [Any] = ["en2", "en3", "en4"]
let KNOWN_CELL_IFS: [Any] = ["pdp_ip0", "pdp_ip1", "pdp_ip2", "pdp_ip3"]
let UNKNOWN_IP_ADDRESS: String = ""
var addresses: [AnyHashable: Any] = ["wireless": UNKNOWN_IP_ADDRESS, "wired": UNKNOWN_IP_ADDRESS, "cell": UNKNOWN_IP_ADDRESS]
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 == nil {
temp_addr = temp_addr?.ifa_next
continue
}
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) == WIFI_IF) {
// Get NSString from C String
addresses["wireless"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
// Check if interface is a wired connection
if KNOWN_WIRED_IFS.contains(String(utf8String: temp_addr?.ifa_name)) {
addresses["wired"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
// Check if interface is a cellular connection
if KNOWN_CELL_IFS.contains(String(utf8String: temp_addr?.ifa_name)) {
addresses["cell"] = String(utf8String: inet_ntoa((temp_addr?.ifa_addr as? sockaddr_in)?.sin_addr))
}
}
temp_addr = temp_addr?.ifa_next
}
}
// Free memory
freeifaddrs(interfaces)
return addresses
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With