#include "GetMACAddress.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IOEthernetController.h>
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices);
static kern_return_t GetMACAddressInternal(io_iterator_t intfIterator, UInt8 *MACAddress);
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices)
{
kern_return_t kernResult = KERN_FAILURE;
mach_port_t masterPort = MACH_PORT_NULL;
CFMutableDictionaryRef classesToMatch = NULL;
kernResult = IOMasterPort(MACH_PORT_NULL, &masterPort);
if ( kernResult == KERN_SUCCESS )
{
classesToMatch = IOServiceMatching(kIOEthernetInterfaceClass);
if ( classesToMatch != NULL )
{
CFMutableDictionaryRef propertyMatch = CFDictionaryCreateMutable( kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks );
CFDictionarySetValue( propertyMatch, CFSTR(kIOPrimaryInterface), kCFBooleanTrue );
CFDictionarySetValue( classesToMatch, CFSTR(kIOPropertyMatchKey), propertyMatch );
CFRelease( propertyMatch );
kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch, matchingServices);
}
}
return kernResult;
}
static kern_return_t GetMACAddressInternal(io_iterator_t intfIterator, UInt8 *MACAddress)
{
io_object_t intfService = MACH_PORT_NULL;
io_object_t controllerService = MACH_PORT_NULL;
kern_return_t kernResult = KERN_FAILURE;
intfService = IOIteratorNext(intfIterator);
if ( intfService != MACH_PORT_NULL )
{
CFDataRef MACAddressAsCFData = NULL;
kernResult = IORegistryEntryGetParentEntry( intfService,
kIOServicePlane,
&controllerService );
if ( kernResult == KERN_SUCCESS && controllerService != MACH_PORT_NULL )
{
MACAddressAsCFData = (CFDataRef) IORegistryEntryCreateCFProperty( controllerService,
CFSTR(kIOMACAddress),
kCFAllocatorDefault,
0);
if (MACAddressAsCFData != NULL)
{
CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress);
CFRelease(MACAddressAsCFData);
}
(void) IOObjectRelease(controllerService);
}
(void) IOObjectRelease(intfService);
}
return kernResult;
}
SInt32 GetMACAddress( CFStringRef *theLZMACAddress, CFStringRef *theNLZMACAddress, bool bWithColons )
{
kern_return_t kernResult = KERN_SUCCESS;
io_iterator_t intfIterator = MACH_PORT_NULL;
unsigned char macAddress[ kIOEthernetAddressSize ];
kernResult = FindEthernetInterfaces(&intfIterator);
if (kernResult == KERN_SUCCESS)
{
kernResult = GetMACAddressInternal(intfIterator, &macAddress[0]);
if (kernResult == KERN_SUCCESS)
{
if (theLZMACAddress != nil)
*theLZMACAddress = GetMACAddressFormattedStr(&macAddress[0], true, bWithColons);
if (theNLZMACAddress != nil)
*theNLZMACAddress = GetMACAddressFormattedStr(&macAddress[0], false, bWithColons);
}
IOObjectRelease(intfIterator); }
return kernResult;
}
CFStringRef GetMACAddressFormattedStr(unsigned char* addr, bool bLeadingZeros, bool bWithColons )
{
char buffer[32];
char *p = buffer;
short i;
CFStringRef outString;
if (bLeadingZeros)
{
for (i = 0; i < 6; ++i )
{
if( bWithColons )
p += sprintf( p, "%2.2x:", addr[i] );
else
p += sprintf( p, "%2.2x", addr[i] );
}
}
else
{
for (i = 0; i < 6; ++i )
{
if( bWithColons )
p += sprintf( p, "%x:", addr[i] );
else
p += sprintf( p, "%x", addr[i] );
}
}
if( bWithColons )
*(--p) = '\0';
outString = CFStringCreateWithCString(kCFAllocatorDefault, buffer, kCFStringEncodingMacRoman);
return outString;
}