Determine MAC Address – UDID Alternative

The MAC (Media Access Control) address is an identifier that is associated with a network adapter and uniquely identifies a device on a network. A MAC address consists of 12 hexadecimal numbers, typically formatted as follows


The XX values in a MAC address identify the manufacturer, the YY values are the serial number assigned to the network adapter.

The MAC address can be useful if you need a way to uniquely identify a device – this can be used as a substitute for the UDID value that is now deprecated in iOS 5 and greater.

The code below shows how to get the MAC address on an iOS device:

#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";
    // Get the size of the data available (store in len)
    if (sysctl(mgmtInfoBase, 6, NULL, &length, NULL, 0) < 0) 
      errorFlag = @"sysctl mgmtInfoBase failure";
      // Alloc memory based on above call
      if ((msgBuffer = malloc(length)) == NULL)
        errorFlag = @"buffer allocation failure";
        // 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
  return macAddressString;

The output will look as follows: Mac Address: E0:F8:47:C0:E3:C9


  1. Great tip, but, will Apple aprove an application that uses this code?

    • All the code is based on available (public) API’s, so there should be no issues with app approval.

  2. What headers does one need to import to compile this for iOS?

  3. Can this be isolated under a cocoa touch static library?

    which frameworks are needed in order to use the static lib under another project?

  4. Beautiful … almost cried after seeing pure C code after such a long time … oh the good old memcpy malloc/free … the classics. Thanks :)

  5. Hi John,

    What libraries do you need to link against for this? From a quick grep, it seems like libresolve.dylib and/or perhaps system/libsystem_info.dylib or system/libsystem_network.dylib?

    • Hi Jeffrey, I didn’t link any additional libraries/frameworks in my test project, only UIKit and Foundation.

      • It needs more than UIKit and Foundation. That might be enough if you are building a project inside Xcode, (i.e. it probably links against other libs that you aren’t aware of) but it definitely needs more when building/linking manually outside of Xcode :-(

        • Not sure how to determine which libs are included in the build. I’ve looked at the binary, however, nothing obvious stands out. Interesting question, how to determine which libs are included in a build?

  6. There is i a potential memory leak in case errorFlag = @”sysctl msgBuffer failure”, as msgBuffer will not be released…

    You should add it for example before the ‘return errorFlag’, like in the code below:

    if (errorFlag != NULL)
    NSLog(@”Error: %@”, errorFlag);
    if ( msgBuffer ) free(msgBuffer);
    return errorFlag;

  7. Does it work to get Bluetooth MAC address also?

  8. This is much better than the official UUID approach, just wondering if Apple will deprecate this one sooner or later…Anyway, thanks for sharing!

  9. Great great! Works perfectly. Great thanks to you!!!!!…by the way, i love pure C :D

Comments are closed.