كيف يمكنني الحصول على عنوان MAC الخاص بجهاز iPhone برمجيًا

StackOverflow https://stackoverflow.com/questions/677530

سؤال

كيف يمكن الحصول برمجياً على عنوان MAC وعنوان IP الخاصين بجهاز iPhone؟

هل كانت مفيدة؟

المحلول


<قوية> ملاحظة اعتبارا من iOS7، أنت لم تعد قادرة على استرداد جهاز عناوين MAC. سيتم إرجاع قيمة ثابتة بدلا من MAC الفعلي


وسومثينغ أنا تعثرت عبر منذ فترة. أصلا من href="http://www.iphonedevsdk.com/forum/iphone-sdk-development/5293-get-current-ip-address.html" هنا I تعديل عليه قليلا وتنظيف الامور.

IPAddress.h
IPAddress.c

واستخدامه

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]);
    }
}
تختلف

وأسماء محول تبعا لمحاكاة / الجهاز وكذلك واي فاي أو خلية على الجهاز.

نصائح أخرى

تحديث: هذا لن يعمل على نظام التشغيل iOS 7.يجب عليك استخدام ASIDentifierManager.


حل أكثر نظافة على موقع MobileDeveloperTips:

#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;
}

وكنت أريد شيئا للعودة عنوان بغض النظر عن وجود أو عدم واي فاي تم تمكين، لذلك فإن الحل المختار لا تعمل بالنسبة لي. اعتدت مكالمة أخرى وجدت على بعض منتدى بعد بعض التغيير والتبديل. انتهى بي الأمر مع ما يلي (عذر لي صدئ 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;
}

وبعد ذلك أود أن نسميها طلب على en0 ، أو كما يلي:

char* macAddressString= (char*)malloc(18);
NSString* macAddress= [[NSString alloc] initWithCString:getMacAddress(macAddressString, "en0")
                                              encoding:NSMacOSRomanStringEncoding];
free(macAddressString);

وبدءا من دائرة الرقابة الداخلية 7، ونظام دوما بإرجاع قيمة 02:00:00:00:00:00 عندما تسأل عن عنوان MAC على أي جهاز.

<اقتباس فقرة>   

في دائرة الرقابة الداخلية 7 و في وقت لاحق، إذا كنت تسأل عن عنوان MAC من جهاز دائرة الرقابة الداخلية، ونظام إرجاع القيمة 02: 00: 00: 00: 00: 00. إذا كنت بحاجة إلى التعرف على الجهاز، استخدام الخاصية identifierForVendor من UIDevice بدلا من ذلك. (تطبيقات التي تحتاج إلى معرف لأغراض الدعاية الخاصة بها ينبغي أن تنظر باستخدام الخاصية advertisingIdentifier من ASIdentifierManager بدلا من ذلك.) "

والمرجعي: <لأ href = "https://developer.apple.com/library/prerelease/ios/releasenotes/General/WhatsNewIniOS/Articles/iOS7.html#//apple_ref/doc/uid/TP40013162-SW34" > releasenotes

وهناك تختلف الحلول حول هذا الموضوع، ولكن لم أتمكن من العثور على كل شيء. لذلك جعل حل بلدي ل:

nicinfo

وكيفية استخدام:

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!");
}

وهذا يبدو وكأنه حل نظيفة جدا: <لأ href = "https://github.com/gekitz/UIDevice-with-UniqueIdentifier-for-iOS-5/blob/master/Classes/UIDevice+IdentifierAddition.m# L32 "يختلط =" نوفولو noreferrer "> 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;
}

والآن دائرة الرقابة الداخلية 7 الأجهزة - دائما يعودون عنوان MAC من 02: 00: 00: 00: 00: 00

.

وهكذا أفضل استخدام [UIDevice identifierForVendor].

وهكذا من الأفضل أن نسمي هذا الأسلوب للحصول على مفتاح فريد محددة التطبيق

والفئة سوف أكثر ملاءمة

واستيراد "UIDevice + Identifier.h"

- (NSString *) identifierForVendor1
{
    if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
        return [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    }
    return @"";
}

والآن ندعو فوق طريقة للحصول على عنوان فريد

NSString *like_UDID=[NSString stringWithFormat:@"%@",
                [[UIDevice currentDevice] identifierForVendor1]];

NSLog(@"%@",like_UDID);

وGrantland هذا "الحل جميلة نظيفة" مشابها لتحسين بلدي على حل iPhoneDeveloperTips.

ويمكنك ان ترى وجهتي هنا: 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;
}

على ليس من الممكن بعد الآن على أجهزة تعمل بنظام التشغيل iOS 7.0 أو في وقت لاحق، وبالتالي غير متاحة للحصول على عنوان MAC في سويفت.

وكما ذكر أبل:

<اقتباس فقرة>   

في دائرة الرقابة الداخلية 7 و في وقت لاحق، إذا كنت تسأل عن عنوان MAC من جهاز دائرة الرقابة الداخلية، ونظام إرجاع القيمة 02: 00: 00: 00: 00: 00. إذا كنت بحاجة إلى التعرف على الجهاز، استخدام الخاصية identifierForVendor من UIDevice بدلا من ذلك. (تطبيقات التي تحتاج إلى معرف لأغراض الدعاية الخاصة بها ينبغي أن تنظر باستخدام الخاصية advertisingIdentifier من ASIdentifierManager بدلا من ذلك.)

#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;
}

لإنشاء uniqueString على أساس المعرف الفريد للجهاز في دائرة الرقابة الداخلية 6:

#import <AdSupport/ASIdentifierManager.h>

NSString *uniqueString = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
NSLog(@"uniqueString: %@", uniqueString);

وهناك الكثير من هذه الأسئلة تتناول فقط عنوان ماك. إذا كنت تحتاج أيضا عنوان IP أنا فقط كتبت هذا، قد تحتاج الى بعض العمل ولكن يبدو أن تعمل بشكل جيد على الجهاز الخاص بي ...

- (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 @"?.?.?.?";
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top