Update
Figured it out, and as expected it was a rather dumb mistake on my side. The problem was that an external project I recently added delivered its own version of getifaddr.c
and my code was therefore including the wrong file.
A "quick fix" for this is to go into the project settings in XCode, then to your Build phases and then remove getifaddr.c
/getifaddr.h
from the "Compile Sources" phase. If you have a "Headers" phase, remove them there as well.
Depending on your project there might be a more elaborate solution, I've created another question to find out if there is: XCode include system file instead of local file
Original Question
I have a method in one of my iOS projects that returns the IP(s) of the network interfaces of the device. This has been working good so far, but I recently noticed that the method doesn't return any IPs anymore and instead getifaddrs()
returns error 6 (Device not configured).
This happens on multiple devices and on iOS7 and iOS8, so its not a device-issue. I suppose it must be some code change I made, but the method in question was never changed so I can't see how this could happen. Since I don't know exactly when this error first occurred, I can't really pinpoint it to a specific code change.
The method in question:
#include <ifaddrs.h>
#include <arpa/inet.h>
/* Thanks to
https://stackoverflow.com/questions/3434192/alternatives-to-nshost-in-iphone-app and
http://zachwaugh.me/posts/programmatically-retrieving-ip-address-of-iphone/
*/
+ (NSArray *)deviceInterfaceAddresses
{
struct ifaddrs *interfaces = NULL;
struct ifaddrs *temp_addr = NULL;
int success = -1;
NSMutableArray *ips = [NSMutableArray arrayWithCapacity:1];
// retrieve the current interfaces - returns 0 on success
success = getifaddrs(&interfaces);
if (success == 0)
{
while (temp_addr != NULL)
{
NSString *interfaceName = [NSString stringWithUTF8String:temp_addr->ifa_name];
if (temp_addr->ifa_addr->sa_family == AF_INET && ([interfaceName hasPrefix:@"en"] || [interfaceName hasPrefix:@"bridge"]))
{
//Get NSString from C String
NSString *ip = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
if ([ip hasPrefix:@"0."] == NO && [ip hasPrefix:@"127."] == NO && [ip hasPrefix:@"255."] == NO)
{
[ips addObject:ip];
}
}
temp_addr = temp_addr->ifa_next;
}
} else {
NSLog(@"Error getting IPs: %@ (%d)", [NSString stringWithUTF8String:strerror(errno)], errno);
}
// Free memory
freeifaddrs(interfaces);
//Remove duplicates
NSMutableArray *finalIps = [NSMutableArray arrayWithCapacity:[ips count]];
for (NSString *ip in ips)
{
if (![finalIps containsObject:ip]) [finalIps addObject:ip];
}
return finalIps;
}