Created
August 19, 2010 14:00
-
-
Save atr000/537946 to your computer and use it in GitHub Desktop.
osxMacAddress.m
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <Foundation/Foundation.h> | |
#include <IOKit/IOKitLib.h> | |
#include <IOKit/network/IOEthernetInterface.h> | |
#include <IOKit/network/IOEthernetController.h> | |
static NSDictionary* GetMACAddresses( io_iterator_t netIterator ); | |
static kern_return_t FindNetworkInterfaces( io_iterator_t *services ); | |
static NSString* bytesToHexString( NSData* data ); | |
int main (int argc, const char * argv[]) { | |
io_iterator_t intfIterator; | |
kern_return_t kernResult = KERN_FAILURE; | |
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; | |
NSLog(@"Detecting Network Interfaces..."); | |
kernResult = FindNetworkInterfaces( &intfIterator ); | |
if( KERN_SUCCESS != kernResult ) { | |
printf( "findNetworkInterfaces failed\n" ); | |
} else { | |
NSLog( @"Found one of more valid interfaces. Extracting MAC addresses..." ); | |
NSDictionary* intfDictionary = GetMACAddresses( intfIterator ); | |
for( id key in intfDictionary ) { | |
NSLog( @" %@ => %@", key, [intfDictionary objectForKey:key] ); | |
} | |
IOObjectRelease( intfIterator ); | |
} | |
[pool drain]; | |
return 0; | |
} | |
/* Search through each of the Network interfaces identified | |
* in the netIterator and pull out the MAC address and the BSD | |
* name of the interface. Then convert the raw MAC address into | |
* a readable string and return an NSDictionary with a mapping of | |
* BSD Name (NSString*) => MAC Address (NSString*) for each interface | |
*/ | |
static NSDictionary* GetMACAddresses( io_iterator_t netIterator ) { | |
NSMutableDictionary* etherDictionary = nil; | |
kern_return_t kernResult = KERN_FAILURE; | |
io_object_t interfaceService; | |
io_object_t controllerService; | |
while( interfaceService = IOIteratorNext( netIterator ) ) { | |
CFTypeRef MACAddrAsCFData = NULL; | |
CFTypeRef BSDNameAsCFString = NULL; | |
kernResult = IORegistryEntryGetParentEntry( interfaceService, | |
kIOServicePlane, | |
&controllerService ); | |
if( KERN_SUCCESS != kernResult ) { | |
printf( "IORegistryEntryGetParentEntry failed with 0x%08x\n", kernResult ); | |
} else { | |
MACAddrAsCFData = IORegistryEntryCreateCFProperty( controllerService, | |
CFSTR(kIOMACAddress), | |
kCFAllocatorDefault, | |
0 ); | |
BSDNameAsCFString = IORegistryEntryCreateCFProperty( interfaceService, | |
CFSTR("BSD Name"), | |
kCFAllocatorDefault, | |
0 ); | |
if( MACAddrAsCFData && BSDNameAsCFString ) { | |
if( nil == etherDictionary ) { | |
etherDictionary = [[NSMutableDictionary alloc] init]; | |
} | |
[etherDictionary setObject:bytesToHexString((NSData*)MACAddrAsCFData) | |
forKey:(NSString*)BSDNameAsCFString]; | |
} | |
if( nil != BSDNameAsCFString ) { | |
CFRelease( BSDNameAsCFString ); | |
} | |
if( nil != MACAddrAsCFData ) { | |
CFRelease( MACAddrAsCFData ); | |
} | |
} | |
} | |
return (nil == etherDictionary) ? nil : (NSDictionary*)[etherDictionary autorelease]; | |
} | |
/* Search through the IOServicePlane and find any services that | |
* represent an IOEthernetInterface. If you wanted to find a | |
* MAC address for a specific interface you could replace the | |
* IOServiceMatching calls with IOBSDNameMatching | |
*/ | |
static kern_return_t FindNetworkInterfaces( io_iterator_t *services ) { | |
CFMutableDictionaryRef matchClasses = NULL; | |
kern_return_t kernResult = KERN_FAILURE; | |
mach_port_t machPort; | |
kernResult = IOMasterPort( MACH_PORT_NULL, &machPort ); | |
if( KERN_SUCCESS != kernResult ) { | |
printf( "IOMasterPort failed: %d\n", kernResult ); | |
} | |
matchClasses = IOServiceMatching( kIOEthernetInterfaceClass ); | |
if( NULL == matchClasses ) { | |
printf( "IOServiceMatching returned a NULL dictionary" ); | |
} | |
kernResult = IOServiceGetMatchingServices( machPort, matchClasses, services ); | |
if( KERN_SUCCESS != kernResult ) { | |
printf( "IOServiceGetMatchingServices failed: %d\n", kernResult ); | |
} | |
return kernResult; | |
} | |
static NSString* bytesToHexString( NSData* data ) { | |
NSMutableString* result = [[NSMutableString alloc] initWithCapacity: [data length] << 1]; | |
UInt8* mbytes = (UInt8*)[data bytes]; | |
char hBytes[8] = {'\0'}; | |
int i = 0; | |
for( ; i < [data length]; i++ ) { | |
snprintf( hBytes, 3, "%02X", mbytes[ i ] ); | |
if( 0 == i ) { | |
[result appendFormat:@"%s", hBytes]; | |
} else { | |
[result appendFormat:@":%s", hBytes]; | |
} | |
} | |
return (NSString*)[result autorelease]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment