How to perform DNS query on iOS - iphone

i want to perform some DNS queries e.g. to get IP records against a specific domain name, i am looking for a preferred way or some useful snippet for this on iOS 3.2+ SDK.
thanx in advance
part from other snippets i found this code
Boolean result;
CFHostRef hostRef;
NSArray *addresses;
NSString *hostname = #"apple.com";
hostRef = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)hostname);
if (hostRef) {
result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); // pass an error instead of NULL here to find out why it failed
if (result == TRUE) {
addresses = (NSArray*)CFHostGetAddressing(hostRef, &result);
}
}
if (result == TRUE) {
[addresses enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *strDNS = [NSString stringWithUTF8String:inet_ntoa(*((struct in_addr *)obj))];
NSLog(#"Resolved %d->%#", idx, strDNS);
}];
} else {
NSLog(#"Not resolved");
}
but this is producing same IP for every host Resolved 0->220.120.64.1 any help??

Figured out a change in this snippet makes it working
if (result == TRUE) {
NSMutableArray *tempDNS = [[NSMutableArray alloc] init];
for(int i = 0; i < CFArrayGetCount(addresses); i++){
struct sockaddr_in* remoteAddr;
CFDataRef saData = (CFDataRef)CFArrayGetValueAtIndex(addresses, i);
remoteAddr = (struct sockaddr_in*)CFDataGetBytePtr(saData);
if(remoteAddr != NULL){
// Extract the ip address
//const char *strIP41 = inet_ntoa(remoteAddr->sin_addr);
NSString *strDNS =[NSString stringWithCString:inet_ntoa(remoteAddr->sin_addr) encoding:NSASCIIStringEncoding];
NSLog(#"RESOLVED %d:<%#>", i, strDNS);
[tempDNS addObject:strDNS];
}
}
}

Bros there is a lot simpler way! Thanks to iOS being a unix system, you become a god with unlimited power and resource! I present elegance.
- (NSString*)lookupHostIPAddressForURL:(NSURL*)url
{
// Ask the unix subsytem to query the DNS
struct hostent *remoteHostEnt = gethostbyname([[url host] UTF8String]);
// Get address info from host entry
struct in_addr *remoteInAddr = (struct in_addr *) remoteHostEnt->h_addr_list[0];
// Convert numeric addr to ASCII string
char *sRemoteInAddr = inet_ntoa(*remoteInAddr);
// hostIP
NSString* hostIP = [NSString stringWithUTF8String:sRemoteInAddr];
return hostIP;
}

Related

How to get ip address from NetService

When I get a NetService object,I try to do:
NSNetService *ss=[netArray objectAtIndex:indexPath.row];
ss.delegate=self;
[ss resolveWithTimeout:3.0];
On the delegate method:
-(void)netServiceDidResolveAddress:(NSNetService *)sender
{
NSArray *address=sender.addresses;
NSData *addressData=[NSData dataWithBytes:address length:sizeof(address)];
/*
How?
*/
}
Thanks.
// Sent when addresses are resolved
- (void)netServiceDidResolveAddress:(NSNetService *)netService
{
// Make sure [netService addresses] contains the
// necessary connection information
if ([self addressesComplete:[netService addresses]
forServiceType:[netService type]]) {
[services addObject:netService];
}
}
// Verifies [netService addresses]
- (BOOL)addressesComplete:(NSArray *)addresses
forServiceType:(NSString *)serviceType
{
// Perform appropriate logic to ensure that [netService addresses]
// contains the appropriate information to connect to the service
NSData *myData = nil;
myData = [addresses objectAtIndex:0];
NSString *addressString;
int port=0;
struct sockaddr *addressGeneric;
struct sockaddr_in addressClient;
addressGeneric = (struct sockaddr *) [myData bytes];
switch( addressGeneric->sa_family ) {
case AF_INET: {
struct sockaddr_in *ip4;
char dest[INET_ADDRSTRLEN];
ip4 = (struct sockaddr_in *) [myData bytes];
port = ntohs(ip4->sin_port);
addressString = [NSString stringWithFormat: #"IP4: %s Port: %d", inet_ntop(AF_INET, &ip4->sin_addr, dest, sizeof dest),port];
}
break;
case AF_INET6: {
struct sockaddr_in6 *ip6;
char dest[INET6_ADDRSTRLEN];
ip6 = (struct sockaddr_in6 *) [myData bytes];
port = ntohs(ip6->sin6_port);
addressString = [NSString stringWithFormat: #"IP6: %s Port: %d", inet_ntop(AF_INET6, &ip6->sin6_addr, dest, sizeof dest),port];
}
break;
default:
addressString=#"Unknown family";
break;
}
NSLog(#"Client Address: %#",addressString);
return YES;
}
This is the output
Client Address: IP4: 192.168.69.38 Port: 58612
I found a post which suggests the following solution.
NSString* addressString = [[NSString alloc] initWithData:addressData encoding:NSASCIIStringEncoding];
Though it does not output a human readable string for me... It might work for you.
This is what is written to the console when I print the NSData object.
<10026a5e 0a0a7893 00000000 00000000>
Meanwhile, I found out that the second segment is the hexadecimal form of the ip-address. In this example it is ...
10.10.120.147 // 0a0a7893
I have written a Host class that does the conversion. The NSString extension can be found here. I only use the first 16-bytes address and ignore all others. Feel free to extend the class.

IP Address Lookup using Hostname when Bonjour is off in iOS

I just like to ask if it is possible to identify the IP Address of a device (e.g. a printer) using its Hostname even if its Bonjour setting is turned off? Also can you give me an example on how to do it? I am developing an app in iOS that should handle this scenario.
I have looked at the following:
getaddrinfo
CFHostStartInfoResolution
but they work only if the device's bonjour is turned ON.
Assuming the hostname (let's say nameOfTheDevice) is registered with the zone's authoritative DNS server, you can use CFHost to look up an address or hostname. For example:
NSString* hostname = #"nameOfTheDevice";
CFHostRef hostRef = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)hostname);
Boolean lookup = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL);
NSArray* addresses = (NSArray*)CFHostGetAddressing(hostRef, &lookup);
[addresses enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *strDNS = [NSString stringWithUTF8String:inet_ntoa(*((struct in_addr *)obj))];
NSLog(#"Resolved %d->%#", idx, strDNS);
}];
(Remember to put error checks in your production code). Bear in mind that if the DNS server isn't aware of that hostname, there's nothing you can do. It's not safe to assume that you'll be able to perform a successful lookup, especially on a home network where built-in DHCP/DNS servers have widely varying capabilities.
From previous answer get callback func and pass obj as a parameter into this function
void printAddr(CFDataRef address)
{
NSString *addressString;
struct sockaddr *addressGeneric;
NSData *myData = (__bridge NSData*)address;
addressGeneric = (struct sockaddr*)[myData bytes];
switch(addressGeneric->sa_family) {
case AF_INET: {
struct sockaddr_in *ip4;
char dest[INET_ADDRSTRLEN];
ip4 = (struct sockaddr_in *) [myData bytes];
addressString = [NSString stringWithFormat: #"IP4: %s", inet_ntop(AF_INET, &ip4->sin_addr, dest, sizeof dest)];
}
break;
case AF_INET6: {
struct sockaddr_in6 *ip6;
char dest[INET6_ADDRSTRLEN];
ip6 = (struct sockaddr_in6 *) [myData bytes];
addressString = [NSString stringWithFormat: #"IP6: %s", inet_ntop(AF_INET6, &ip6->sin6_addr, dest, sizeof dest)];
}
break;
}
NSLog(#"%#", addressString);
}

NSString * to Char[] (GameCenter Send Struct)

I want to send a struct to another player in GameCenter.
I have read the other questions about this, however, I cannot get any of them to work.
I need to get #"1234" into a char[4] (ex char[0] = '1', char[1] = '2', etc)
I have tried [NSString UTF8String], but it doesn't seem to do what I want.
It assigns fine, but when I pull it back into NSString * with [NSString stringWithUTF8String:], It returns blank.
If someone could show me the conversion to and from, it would be greatly appreciated.
Thanks.
EDIT:
I can't get it to work :/ Here is my code (the abridged version):
Matchmaker.h
enum { NChars = 4 };
typedef struct {
MessageType messageType;
} Message;
typedef struct {
Message message;
char code[NChars];
} MessageGameCode;
#interface Matchmaker : CCLayer <GameCenterMasterDelegate>{
NSString *_code;
}
#property (nonatomic,retain) NSString *_code;
Matchmaker.m
#synthesize _code;
-(void)viewDidLoad{
self._code = #"1234";
}
- (void)sendCode {
NSLog(#"Sending Code....");
MessageGameCode message;
message.message.messageType = kMessageTypeGameCode;
NSString * const source = self._code;
const char* const sourceAsUTF8 = source.UTF8String;
for (size_t idx = 0; idx < NChars; ++idx) {
message.code[idx] = sourceAsUTF8[idx];
}
NSData *data = [NSData dataWithBytes:&message length:NChars];
[self sendData:data];
}
- (void)match:(GKMatch *)match didReceiveData:(NSData *)data fromPlayer:(NSString *)playerID {
Message *message = (Message *) [data bytes];
if (message->messageType == kMessageTypeGameCode) {
MessageGameCode *codeMessage = (MessageGameCode *)[data bytes];
self._code = [[NSString alloc] initWithBytes:codeMessage->code length:NChars encoding:NSUTF8StringEncoding];
[self setGameState:kGameStateWaitingForStart];
NSLog(#"Game Code Recieved");
NSLog(#"Recieved Code: %#",self._code); //This always shows self._code as blank
}
}
Your attempt will fail because the cstring which you pass to + [NSString stringWithUTF8String:] is not terminated.
Try this:
NSString * result = [[NSString alloc] initWithBytes:bytes
length:4
encoding:NSUTF8StringEncoding];
Edit
A more complete demonstration:
enum { NChars = 4 };
/* requires error checking */
void transmit() {
NSString * const source = #"1234";
char tmp[NChars] = { 0 };
const char* const sourceAsUTF8 = source.UTF8String;
for (size_t idx = 0; idx < NChars; ++idx) {
tmp[idx] = sourceAsUTF8[idx];
}
/* .. */
}
/* requires error checking */
void receive(const char bytes[NChars]) {
NSString * result = [[NSString alloc] initWithBytes:bytes length:NChars encoding:NSUTF8StringEncoding];
/* ... */
}
One way is
char bytes[4];
NSData* data = [#"1234" dataUsingEncoding: NSUTF8StringEncoding];
if ([data length] <= 4)
{
memcpy(bytes, [data bytes], [data length]);
}
And to go the other way:
NSString* recodedString = [[NSString alloc] initWithBytes: bytes
length: savedLengthFromBefore
encoding: NSUTF8StringEncoding];
There are a couple of possible pitfalls here.
One is that with [NSString UTF8String] "The returned C string is automatically freed just as a returned object would be released; you should copy the C string if it needs to store it outside of the autorelease context in which the C string is created.". So, depending on how long you're expecting the value to stick around you may need to copy it (for example, using strcpy)
The other issue is that [NSString UTF8String] and [NSString stringWithUTF8String:] both expect NULL-terminated C strings, so you need a char[5], not a char[4] to hold #"1234".

How to retrieve the WiFi Mac address of a device -- IOS [duplicate]

How to programmatically get an iPhone's MAC address and IP address?
NOTE As of iOS7, you can no longer retrieve device MAC addresses. A fixed value will be returned rather than the actual MAC
Somthing I stumbled across a while ago. Originally from here I modified it a bit and cleaned things up.
IPAddress.h
IPAddress.c
And to use it
InitAddresses();
GetIPAddresses();
GetHWAddresses();
int i;
NSString *deviceIP = nil;
for (i=0; i<MAXADDRS; ++i)
{
static unsigned long localHost = 0x7F000001; // 127.0.0.1
unsigned long theAddr;
theAddr = ip_addrs[i];
if (theAddr == 0) break;
if (theAddr == localHost) continue;
NSLog(#"Name: %s MAC: %s IP: %s\n", if_names[i], hw_addrs[i], ip_names[i]);
//decided what adapter you want details for
if (strncmp(if_names[i], "en", 2) == 0)
{
NSLog(#"Adapter en has a IP of %s", ip_names[i]);
}
}
Adapter names vary depending on the simulator/device as well as wifi or cell on the device.
Update: this will not work on iOS 7. You should use ASIdentifierManager.
More clean solution on MobileDeveloperTips website:
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
...
- (NSString *)getMacAddress
{
int mgmtInfoBase[6];
char *msgBuffer = NULL;
size_t length;
unsigned char macAddress[6];
struct if_msghdr *interfaceMsgStruct;
struct sockaddr_dl *socketStruct;
NSString *errorFlag = NULL;
// Setup the management Information Base (mib)
mgmtInfoBase[0] = CTL_NET; // Request network subsystem
mgmtInfoBase[1] = AF_ROUTE; // Routing table info
mgmtInfoBase[2] = 0;
mgmtInfoBase[3] = AF_LINK; // Request link layer information
mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces
// With all configured interfaces requested, get handle index
if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0)
errorFlag = #"if_nametoindex failure";
else
{
// Get the size of the data available (store in len)
if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = #"sysctl mgmtInfoBase failure";
else
{
// Alloc memory based on above call
if ((msgBuffer = malloc(length)) == NULL)
errorFlag = #"buffer allocation failure";
else
{
// Get system information, store in buffer
if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
errorFlag = #"sysctl msgBuffer failure";
}
}
}
// Befor going any further...
if (errorFlag != NULL)
{
NSLog(#"Error: %#", errorFlag);
return errorFlag;
}
// Map msgbuffer to interface message structure
interfaceMsgStruct = (struct if_msghdr *) msgBuffer;
// Map to link-level socket structure
socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);
// Copy link layer address data in socket structure to an array
memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);
// Read from char array into a string object, into traditional Mac address format
NSString *macAddressString = [NSString stringWithFormat:#"%02X:%02X:%02X:%02X:%02X:%02X",
macAddress[0], macAddress[1], macAddress[2],
macAddress[3], macAddress[4], macAddress[5]];
NSLog(#"Mac Address: %#", macAddressString);
// Release the buffer memory
free(msgBuffer);
return macAddressString;
}
I wanted something to return the address regardless of whether or not wifi was enabled, so the chosen solution didn't work for me. I used another call I found on some forum after some tweaking. I ended up with the following (excuse my rusty C ) :
#include <sys/types.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <net/if_dl.h>
#include <ifaddrs.h>
char* getMacAddress(char* macAddress, char* ifName) {
int success;
struct ifaddrs * addrs;
struct ifaddrs * cursor;
const struct sockaddr_dl * dlAddr;
const unsigned char* base;
int i;
success = getifaddrs(&addrs) == 0;
if (success) {
cursor = addrs;
while (cursor != 0) {
if ( (cursor->ifa_addr->sa_family == AF_LINK)
&& (((const struct sockaddr_dl *) cursor->ifa_addr)->sdl_type == IFT_ETHER) && strcmp(ifName, cursor->ifa_name)==0 ) {
dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;
base = (const unsigned char*) &dlAddr->sdl_data[dlAddr->sdl_nlen];
strcpy(macAddress, "");
for (i = 0; i < dlAddr->sdl_alen; i++) {
if (i != 0) {
strcat(macAddress, ":");
}
char partialAddr[3];
sprintf(partialAddr, "%02X", base[i]);
strcat(macAddress, partialAddr);
}
}
cursor = cursor->ifa_next;
}
freeifaddrs(addrs);
}
return macAddress;
}
And then I would call it asking for en0, as follows:
char* macAddressString= (char*)malloc(18);
NSString* macAddress= [[NSString alloc] initWithCString:getMacAddress(macAddressString, "en0")
encoding:NSMacOSRomanStringEncoding];
free(macAddressString);
Starting from iOS 7, the system always returns the value 02:00:00:00:00:00 when you ask for the MAC address on any device.
In iOS 7 and later, if you ask for the MAC address of an iOS device, the system returns the value 02:00:00:00:00:00. If you need to identify the device, use the identifierForVendor property of UIDevice instead. (Apps that need an identifier for their own advertising purposes should consider using the advertisingIdentifier property of ASIdentifierManager instead.)"
Reference: releasenotes
There are vary solutions about this, but I couldn't find a whole thing.
So I made my own solution for :
nicinfo
How to use :
NICInfoSummary* summary = [[[NICInfoSummary alloc] init] autorelease];
// en0 is for WiFi
NICInfo* wifi_info = [summary findNICInfo:#"en0"];
// you can get mac address in 'XX-XX-XX-XX-XX-XX' form
NSString* mac_address = [wifi_info getMacAddressWithSeparator:#"-"];
// ip can be multiple
if(wifi_info.nicIPInfos.count > 0)
{
NICIPInfo* ip_info = [wifi_info.nicIPInfos objectAtIndex:0];
NSString* ip = ip_info.ip;
NSString* netmask = ip_info.netmask;
NSString* broadcast_ip = ip_info.broadcastIP;
}
else
{
NSLog(#"WiFi not connected!");
}
This looks like a pretty clean solution: UIDevice BIdentifier
// Return the local MAC addy
// Courtesy of FreeBSD hackers email list
// Accidentally munged during previous update. Fixed thanks to erica sadun & mlamb.
- (NSString *) macaddress{
int mib[6];
size_t len;
char *buf;
unsigned char *ptr;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
if ((mib[5] = if_nametoindex("en0")) == 0) {
printf("Error: if_nametoindex error\n");
return NULL;
}
if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 1\n");
return NULL;
}
if ((buf = malloc(len)) == NULL) {
printf("Could not allocate memory. error!\n");
return NULL;
}
if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
printf("Error: sysctl, take 2");
free(buf);
return NULL;
}
ifm = (struct if_msghdr *)buf;
sdl = (struct sockaddr_dl *)(ifm + 1);
ptr = (unsigned char *)LLADDR(sdl);
NSString *outstring = [NSString stringWithFormat:#"%02X:%02X:%02X:%02X:%02X:%02X",
*ptr, *(ptr+1), *(ptr+2), *(ptr+3), *(ptr+4), *(ptr+5)];
free(buf);
return outstring;
}
Now iOS 7 devices – are always returning a MAC address of 02:00:00:00:00:00.
So better use [UIDevice identifierForVendor].
so better to call this method to get app specific unique key
Category will more suitable
import "UIDevice+Identifier.h"
- (NSString *) identifierForVendor1
{
if ([[UIDevice currentDevice] respondsToSelector:#selector(identifierForVendor)]) {
return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
}
return #"";
}
Now call above method to get unique address
NSString *like_UDID=[NSString stringWithFormat:#"%#",
[[UIDevice currentDevice] identifierForVendor1]];
NSLog(#"%#",like_UDID);
#Grantland
This "pretty clean solution" looks similar to my own improvement over iPhoneDeveloperTips solution.
You can see my step here:
https://gist.github.com/1409855/
/* Original source code courtesy John from iOSDeveloperTips.com */
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
+ (NSString *)getMacAddress
{
int mgmtInfoBase[6];
char *msgBuffer = NULL;
NSString *errorFlag = NULL;
size_t length;
// Setup the management Information Base (mib)
mgmtInfoBase[0] = CTL_NET; // Request network subsystem
mgmtInfoBase[1] = AF_ROUTE; // Routing table info
mgmtInfoBase[2] = 0;
mgmtInfoBase[3] = AF_LINK; // Request link layer information
mgmtInfoBase[4] = NET_RT_IFLIST; // Request all configured interfaces
// With all configured interfaces requested, get handle index
if ((mgmtInfoBase[5] = if_nametoindex("en0")) == 0)
errorFlag = #"if_nametoindex failure";
// Get the size of the data available (store in len)
else if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0)
errorFlag = #"sysctl mgmtInfoBase failure";
// Alloc memory based on above call
else if ((msgBuffer = malloc(length)) == NULL)
errorFlag = #"buffer allocation failure";
// Get system information, store in buffer
else if (sysctl(mgmtInfoBase, 6, msgBuffer, &length, NULL, 0) < 0)
{
free(msgBuffer);
errorFlag = #"sysctl msgBuffer failure";
}
else
{
// Map msgbuffer to interface message structure
struct if_msghdr *interfaceMsgStruct = (struct if_msghdr *) msgBuffer;
// Map to link-level socket structure
struct sockaddr_dl *socketStruct = (struct sockaddr_dl *) (interfaceMsgStruct + 1);
// Copy link layer address data in socket structure to an array
unsigned char macAddress[6];
memcpy(&macAddress, socketStruct->sdl_data + socketStruct->sdl_nlen, 6);
// Read from char array into a string object, into traditional Mac address format
NSString *macAddressString = [NSString stringWithFormat:#"%02X:%02X:%02X:%02X:%02X:%02X",
macAddress[0], macAddress[1], macAddress[2], macAddress[3], macAddress[4], macAddress[5]];
NSLog(#"Mac Address: %#", macAddressString);
// Release the buffer memory
free(msgBuffer);
return macAddressString;
}
// Error...
NSLog(#"Error: %#", errorFlag);
return nil;
}
It's not possible anymore on devices running iOS 7.0 or later, thus unavailable to get MAC address in Swift.
As Apple stated:
In iOS 7 and later, if you ask for the MAC address of an iOS device, the system returns the value 02:00:00:00:00:00. If you need to identify the device, use the identifierForVendor property of UIDevice instead. (Apps that need an identifier for their own advertising purposes should consider using the advertisingIdentifier property of ASIdentifierManager instead.)
#import <sys/socket.h>
#import <net/if_dl.h>
#import <ifaddrs.h>
#import <sys/xattr.h>
#define IFT_ETHER 0x6
...
- (NSString*)macAddress
{
NSString* result = nil;
char* macAddressString = (char*)malloc(18);
if (macAddressString != NULL)
{
strcpy(macAddressString, "");
struct ifaddrs* addrs = NULL;
struct ifaddrs* cursor;
if (getifaddrs(&addrs) == 0)
{
cursor = addrs;
while (cursor != NULL)
{
if ((cursor->ifa_addr->sa_family == AF_LINK) && (((const struct sockaddr_dl*)cursor->ifa_addr)->sdl_type == IFT_ETHER) && strcmp("en0", cursor->ifa_name) == 0)
{
const struct sockaddr_dl* dlAddr = (const struct sockaddr_dl*) cursor->ifa_addr;
const unsigned char* base = (const unsigned char*)&dlAddr->sdl_data[dlAddr->sdl_nlen];
for (NSInteger index = 0; index < dlAddr->sdl_alen; index++)
{
char partialAddr[3];
sprintf(partialAddr, "%02X", base[index]);
strcat(macAddressString, partialAddr);
}
}
cursor = cursor->ifa_next;
}
}
result = [[[NSString alloc] initWithUTF8String:macAddressString] autorelease];
free(macAddressString);
}
return result;
}
To create a uniqueString based on unique identifier of device in iOS 6:
#import <AdSupport/ASIdentifierManager.h>
NSString *uniqueString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog(#"uniqueString: %#", uniqueString);
A lot of these questions only address the Mac address. If you also require the IP address I just wrote this, may need some work but seems to work well on my machine...
- (NSString *)getLocalIPAddress
{
NSArray *ipAddresses = [[NSHost currentHost] addresses];
NSArray *sortedIPAddresses = [ipAddresses sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
numberFormatter.allowsFloats = NO;
for (NSString *potentialIPAddress in sortedIPAddresses)
{
if ([potentialIPAddress isEqualToString:#"127.0.0.1"]) {
continue;
}
NSArray *ipParts = [potentialIPAddress componentsSeparatedByString:#"."];
BOOL isMatch = YES;
for (NSString *ipPart in ipParts) {
if (![numberFormatter numberFromString:ipPart]) {
isMatch = NO;
break;
}
}
if (isMatch) {
return potentialIPAddress;
}
}
// No IP found
return #"?.?.?.?";
}

Find IP address in iphone

I want to find IP address in an application. I am able to find it. But, problem is, it works fins in iphone os 2.0 or so. But, in iphone os 3.0 it is giving me a warning:
warning: no '+currentHost' method found
warning: (Messages without a matching method signature)
I am using this code, and it works fine with os version 2.0.
-(NSString*)getAddress {
char iphone_ip[255];
strcpy(iphone_ip,"127.0.0.1"); // if everything fails
NSHost* myhost = [NSHost currentHost];
if (myhost)
{
NSString *ad = [myhost address];
if (ad)
strcpy(iphone_ip,[ad cStringUsingEncoding: NSISOLatin1StringEncoding]);
}
return [NSString stringWithFormat:#"%s",iphone_ip];
}
How to find IP address in iphone os 3.0 or greater os version?
Thanks in advance.
#include <arpa/inet.h>
#include <netdb.h>
#include <net/if.h>
#include <ifaddrs.h>
// retun the host name
+ (NSString *)hostname
{
char baseHostName[256];
int success = gethostname(baseHostName, 255);
if (success != 0) return nil;
baseHostName[255] = '\0';
#if !TARGET_IPHONE_SIMULATOR
return [NSString stringWithFormat:#"%s.local", baseHostName];
#else
return [NSString stringWithFormat:#"%s", baseHostName];
#endif
}
// return IP Address
+ (NSString *)localIPAddress
{
struct hostent *host = gethostbyname([[self hostname] UTF8String]);
if (!host) {herror("resolv"); return nil;}
struct in_addr **list = (struct in_addr **)host->h_addr_list;
return [NSString stringWithCString:inet_ntoa(*list[0]) encoding:NSUTF8StringEncoding];
}
As far as I know there is only one hacky way to do that. You basically open a socket and get its address using POSIX functions. Here is the code I used for this:
http://iphonesdksnippets.com/post/2009/09/07/Get-IP-address-of-iPhone.aspx
[NSHost currentHost] will also work, but it is deprecated and considered a "Private API" by Apple, so you won't be able to submit your application to App Store.
Put this script on a web server running PHP:
<?php
$ip = getenv("REMOTE_ADDR");
echo $ip;
?>
Call this on the device:
NSURL *scriptURL = [[NSURL alloc] initWithString:#"http://yourserver.com/script.php"];
NSString *ip = [NSString stringWithContentsOfURL: scriptURL encoding:NSASCIIStringEncoding error:nil];
- (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
// it may also be en1 on your ipad3.
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;
}
Use this to get your IP
If any errors
Please use
#include <ifaddrs.h>
#include <arpa/inet.h>
Getting the IP address is a bit hacky. Are you sure you couldn't live with the device ID (UDID) that is unique to each iPhone and can be retrieved easily via the public API ?
[UIDevice currentDevice].uniqueIdentifier
There is one more way to get the IP address and that too Global IP
NSString* ip=#"http://www.whatismyip.org/";
NSURL *url = [[NSURL alloc] initWithString:ip];
NSString *ans = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];
NSLog(#"%#",ans);
The above site will give you the Global IP.
Just put this in your code and use the IP address where ever you want and also get the location of the user using your app as this gives global IP.
You should have a look to this good project:
uidevice-extension
Specialy this class
Import UIDevice-Reachability.h in your project then try with one of those commands:
NSString *myIp = [UIDevice localIPAddress];
NSString *myIp = [UIDevice localWiFiIPAddress];
NSString *myIp = [UIDevice whatismyipdotcom]; // is using #aamritrao solution
bool success;
struct ifaddrs *addrs;
const struct ifaddrs *cursor;
const struct sockaddr_dl *dlAddr;
const uint8_t *base;
int i;
success = getifaddrs(&addrs) == 0;
if (success) {
cursor = addrs;
while (cursor != NULL) {
if ( (cursor->ifa_addr->sa_family == AF_LINK)
&& (((const struct sockaddr_dl *) cursor->ifa_addr)->sdl_type ==IFT_ETHER)
) {
dlAddr = (const struct sockaddr_dl *) cursor->ifa_addr;
// fprintf(stderr, " sdl_nlen = %d\n", dlAddr->sdl_nlen);
// fprintf(stderr, " sdl_alen = %d\n", dlAddr->sdl_alen);
base = (const uint8_t *) &dlAddr->sdl_data[dlAddr->sdl_nlen];
printf(" MAC address ");
for (i = 0; i < dlAddr->sdl_alen; i++) {
if (i != 0) {
printf(":");
}
printf("%02x", base[i]);
}
printf("\n");
}
cursor = cursor->ifa_next;
}
}