Skip to content

Instantly share code, notes, and snippets.

@Coeur
Created November 30, 2011 17:11
Show Gist options
  • Save Coeur/1409855 to your computer and use it in GitHub Desktop.
Save Coeur/1409855 to your computer and use it in GitHub Desktop.
Get iOS MAC address #
/* 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;
}
@mikesilvers
Copy link

To prevent xcode errors
Change:
else if ((msgBuffer = malloc(length)) == NULL)
To:
else if ((msgBuffer = (char *)malloc(length)) == NULL)

@H2CO3
Copy link

H2CO3 commented Aug 2, 2012

No. Don't cast the return value of malloc() (I don't see anyway how it would prevent 'Xcode errors'...)

@cross-border-business-bridge

Use your method and work well for 99.5% cases, but very few users in AppStore report they can't get mac address (we use the identifier to authenticate every server call). The failed case is on iPhone 4S with IOS version 5.0.1.
Hey Coeur;
Do you know for which case it will fail? Thanks.

@Coeur
Copy link
Author

Coeur commented Nov 18, 2012

I've just tried both simulator 5.0 and simulator 6.1 and it was working fine.
In order to investigate this issue you have, you'll need such a device, connect it to your Mac and read the log (as you can see, there are 4 different error cases).

I've made a tiny edit today, replacing the instance method - (NSString *) by a class method + (NSString *).

@Coeur
Copy link
Author

Coeur commented Dec 11, 2012

I've made an edit today, replacing the return errorFlag with return nil. If you need an error string, then add some error:(NSError**)error to the method.

@edgartronic
Copy link

Under what conditions would this return nil? Seems to me that "en0" is always going to exist for a device...

@JeanetteMueller
Copy link

under iOS7 this returns 02:00:00:00:00:00
Maybe it is an iOS7 bug.

@tomleavy
Copy link

Same issue here with iOS7 ... i'm hoping its a bug that they fix soon

@pereglides
Copy link

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.)
In Deprecated APIs section at the bottom of https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS7.html#//apple_ref/doc/uid/TP40013162-SW1

@chrismaddern
Copy link

Hi @Coeur What's the license on this code? Free to use without attribution? :)

Cheers! Chris

@dev-things-30
Copy link

I want to determine the BLUETOOTH ADDRESS for an iPhone or iPad from within an app on said device. But I didn't find any API that will return the BLUETOOTH ADDRESS or name. Please help me for finding the BLUETOOTH ADDRESS in iOS7.

@Coeur
Copy link
Author

Coeur commented Apr 7, 2014

@JeanetteMueller and @tleavy86 no, not a bug, harpher is right about it
@chrismaddern yes: free to use, but I was requested to leave some "Original source code courtesy John from iOSDeveloperTips.com"
@jontyankit I will investigate with CoreBluetooth maybe
For all: sorry, I never received any email alert for your comments, so I didn't notice for months there were comments here.

@gringan
Copy link

gringan commented Feb 15, 2015

Hi. Coeur, i need this code but i have wrong value on my Iphone6+ Please can you help me ?
2015-02-15 15:37:37.947 MyDemo[438:223963] Mac Address: 02:00:00:00:00:00
Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment