How to programmatically get an iPhone's MAC address and IP address?
-
i want to get MAC address and IP address programmatically in an iPhone application. – Mar 24 '09 at 14:05
-
Wifi MAC address? or BlueTooth? There are many Mac addresses. – mskw Jun 07 '13 at 22:16
-
12Starting 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. Check my answer below. – Hejazi Jun 11 '13 at 23:36
-
For ios and up (till today) refer http://stackoverflow.com/questions/11836225/ios6-udid-what-advantages-does-identifierforvendor-have-over-identifierforadve – rptwsthi Jul 05 '13 at 12:41
12 Answers
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.
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.
-
i just wonder if this is any different from a generic OS X approach (i'm asking because i'm a mac n00b) – Tamas Czinege Mar 24 '09 at 14:59
-
@DrJokepu I think its basic OSX stuff. Actually its basic BSD stuff. The same approach would most likely work on linux as well (even possibly windows with a little tweaking) – PyjamaSam Mar 24 '09 at 15:19
-
2@abc: I recommend you post another question about that. Be better then burying it in comments for a different question. – PyjamaSam Mar 24 '09 at 15:21
-
1
-
I don't belive any of the methods used in this implimentation are concidered part of the private api. They are all base BSD calls. You can see more about ether_ntoa here: http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man3/ether_ntoa.3.html Its just converting the binary representation of the Ethernet address to a string form. – PyjamaSam Nov 13 '09 at 21:15
-
Does the MAC address change when the device goes from WiFi to cellular data service? – xanadont Aug 19 '11 at 22:00
-
@xanadont: As the WIFI and Cellular interfaces are different physical devices my guess is it does. I haven't run this code in a long time, so I don't know for sure, but it should be easy to test. – PyjamaSam Aug 31 '11 at 14:43
-
When you retrieve the mac adress of the iphone, is it itunesstore proof? (Can you upload it to itunesstore and will it be accepted by apple, or is it only possible to retrieve the mac adress with a jailbreaked iphone?) – NicTesla Sep 21 '11 at 11:15
-
1@NicTesla I can't comment for sure, but since its just doing basic networking calls I can't see a problem. Though that being said with the removal of the UDID from iOS5 getting the mac address and using it to develop some kind of alternate unique identifier might come under scrutiny by apple at some point in the future. – PyjamaSam Sep 22 '11 at 19:15
-
Can this get the MAC address of the Wi-Fi interface even if the Wi-Fi is off? – neilvillareal May 10 '12 at 09:24
-
1Regarding `ether_ntoa` warning, check out: http://stackoverflow.com/a/13412265/88597 – ohho Nov 16 '12 at 07:37
-
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;
}

- 11,701
- 4
- 29
- 41
-
-
Apple is VERY likely to break this in iOS7... and we wouldn't be able to comment on this publicly until it ships except on the official Apple Dev Forums. – Gabe Jul 22 '13 at 17:40
-
Yes, you should use [ASIdentifierManager](http://developer.apple.com/library/ios/#documentation/AdSupport/Reference/ASIdentifierManager_Ref/ASIdentifierManager.html) – ArtFeel Jul 23 '13 at 09:13
-
3This didn't work on my iPhone5 with iOS7. It gives me: 02:00:00:00:00:00 which is not right. – Sjoerd Perfors Sep 27 '13 at 14:26
-
-
-
3@Brenden You can't get network MAC address using PublicAPI on iOS7 anymore. So, if you need unique id, you should use `IdentifierManager` – ArtFeel Oct 03 '13 at 12:03
-
2@SjoerdPerfors Under iOS 7 you will indeed always get than same address `02:00:00:00:00:00` as a privacy precaution by Apple. – Basil Bourque May 22 '14 at 00:47
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);

- 24,597
- 18
- 99
- 131

- 3,994
- 4
- 30
- 33
-
9
-
This one doesn't work for me... says ifName is not declared as well as the macaddress variable. – bugfixr Aug 29 '11 at 13:53
-
The above calling code will leak. free(macAddressString); before returning from the above calling method. Also, macAddress should be autoreleased if the above calling code is in another method. – Oct 10 '11 at 22:29
-
@Veera.s.Vasan, you are correct. The snippet was not meant as complete code, just to show you how to use the above function. – shipmaster Oct 11 '11 at 19:33
-
4to be clear, the code itself will not leak, the commenter was talking about the calling snippet at the end, where I allocate two string without freeing them. – shipmaster Dec 20 '11 at 21:25
-
1I put this into a nice objective-c method and made it so it requires no parameters: https://gist.github.com/wsidell/5069159 – wsidell Mar 02 '13 at 01:15
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
-
Whats really nice about this deprecation in the API is that it still work on the simulator correctly, and only on hardware at the moment. – John Nye Jun 13 '13 at 15:26
There are vary solutions about this, but I couldn't find a whole thing. So I made my own solution for :
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!");
}
-
Very nice & useful class! Good work! However, you missed out [super dealloc] on both classes & forgot to include a library, which leads to warnings in xCode. Patched version can be found here: http://raptor.hk/download/NICInfo_raptor_patched.zip – Raptor Dec 30 '11 at 10:09
-
-
1Yes. Apple blocked this since iOS 7 :( ... https://developer.apple.com/library/content/releasenotes/General/WhatsNewIniOS/Articles/iOS7.html#//apple_ref/doc/uid/TP40013162-SW1 – Kenial Feb 02 '17 at 17:05
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);

- 923
- 12
- 23
-
would this identifier be consistent per device over multiple installations of the same app? – samsam Aug 06 '15 at 13:24
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;
}

- 4,875
- 4
- 32
- 50

- 2,620
- 26
- 26
-
1I use your solution, 99% cases work well as expected, but 1% rate can't get mac address, return NULL, reported by users in AppStore. Still not get reproducible steps, have you got it? Thank you. – jianhua Oct 15 '12 at 06:24
-
-
Following up on @jianhua's comment: we just received reports from a user who basically can't use the app because this code returns null for his device (we use the identifier to authenticate every server call). – samvermette Oct 15 '12 at 20:52
-
The failed case is on iPhone 4S with IOS version 5.0.1, of course it is only on some special occasions. – jianhua Oct 16 '12 at 02:49
@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;
}

- 37,241
- 25
- 195
- 267
-
and I don't understand why I can add comments for my own answers but not for other's answers? :/ – Cœur Mar 27 '12 at 18:16
-
1
-
Thanks, looks like a few people have come up with their own variants of this solution: http://ios.biomsoft.com/2011/11/07/determine-mac-address/ – josh-fuggle Feb 25 '13 at 01:17
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.)

- 12,762
- 3
- 58
- 74
#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;
}

- 3,569
- 4
- 34
- 51
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);

- 15,320
- 6
- 84
- 70
-
1
-
1Mac address is needed to uniquely identify device in most cases. Instead, you can use this solution. – Denis Kutlubaev Sep 04 '13 at 07:24
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 @"?.?.?.?";
}

- 19,885
- 13
- 86
- 90