{长度=6,容量=6,字节=0x0022412b03ad}
每次我开始构建 Xcode 项目时,我都会在控制台中看到以下内容:
<CFData 0x100516c60 [0x7fff71adaea0]>{length = 6, capacity = 6, bytes = 0x0022412b03ad}
我不知道它的含义以及它的原因。
有人可以帮助我吗?
谢谢!
编辑: 我认为这个方法创建了它:
//
// PrimaryMac.m
// Network Radar
//
// Created by Daniel Diener on 06.07.11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "PrimaryMac.h"
#include <stdio.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include "if_types.h"
#include "route.h"
#include "if_ether.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <paths.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetController.h>
@implementation PrimaryMac
@synthesize localMac, remoteMac;
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices);
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize);
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
//LOCAL MAC:::::::::::::::::::
// Returns an iterator containing the primary (built-in) Ethernet interface. The caller is responsible for
// releasing the iterator after the caller is done with it.
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices)
{
kern_return_t kernResult;
CFMutableDictionaryRef matchingDict;
CFMutableDictionaryRef propertyMatchDict;
// Ethernet interfaces are instances of class kIOEthernetInterfaceClass.
// IOServiceMatching is a convenience function to create a dictionary with the key kIOProviderClassKey and
// the specified value.
matchingDict = IOServiceMatching(kIOEthernetInterfaceClass);
// Note that another option here would be:
// matchingDict = IOBSDMatching("en0");
// but en0: isn't necessarily the primary interface, especially on systems with multiple Ethernet ports.
if (NULL == matchingDict) {
printf("IOServiceMatching returned a NULL dictionary.\n");
}
else {
// Each IONetworkInterface object has a Boolean property with the key kIOPrimaryInterface. Only the
// primary (built-in) interface has this property set to TRUE.
// IOServiceGetMatchingServices uses the default matching criteria defined by IOService. This considers
// only the following properties plus any family-specific matching in this order of precedence
// (see IOService::passiveMatch):
//
// kIOProviderClassKey (IOServiceMatching)
// kIONameMatchKey (IOServiceNameMatching)
// kIOPropertyMatchKey
// kIOPathMatchKey
// kIOMatchedServiceCountKey
// family-specific matching
// kIOBSDNameKey (IOBSDNameMatching)
// kIOLocationMatchKey
// The IONetworkingFamily does not define any family-specific matching. This means that in
// order to have IOServiceGetMatchingServices consider the kIOPrimaryInterface property, we must
// add that property to a separate dictionary and then add that to our matching dictionary
// specifying kIOPropertyMatchKey.
propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (NULL == propertyMatchDict) {
printf("CFDictionaryCreateMutable returned a NULL dictionary.\n");
}
else {
// Set the value in the dictionary of the property with the given key, or add the key
// to the dictionary if it doesn't exist. This call retains the value object passed in.
CFDictionarySetValue(propertyMatchDict, CFSTR(kIOPrimaryInterface), kCFBooleanTrue);
// Now add the dictionary containing the matching value for kIOPrimaryInterface to our main
// matching dictionary. This call will retain propertyMatchDict, so we can release our reference
// on propertyMatchDict after adding it to matchingDict.
CFDictionarySetValue(matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
CFRelease(propertyMatchDict);
}
}
// IOServiceGetMatchingServices retains the returned iterator, so release the iterator when we're done with it.
// IOServiceGetMatchingServices also consumes a reference on the matching dictionary so we don't need to release
// the dictionary explicitly.
kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, matchingServices);
if (KERN_SUCCESS != kernResult) {
printf("IOServiceGetMatchingServices returned 0x%08x\n", kernResult);
}
return kernResult;
}
// Given an iterator across a set of Ethernet interfaces, return the MAC address of the last one.
// If no interfaces are found the MAC address is set to an empty string.
// In this sample the iterator should contain just the primary interface.
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize)
{
io_object_t intfService;
io_object_t controllerService;
kern_return_t kernResult = KERN_FAILURE;
// Make sure the caller provided enough buffer space. Protect against buffer overflow problems.
if (bufferSize < kIOEthernetAddressSize) {
return kernResult;
}
// Initialize the returned address
bzero(MACAddress, bufferSize);
// IOIteratorNext retains the returned object, so release it when we're done with it.
while ((intfService = IOIteratorNext(intfIterator)))
{
CFTypeRef MACAddressAsCFData;
// IONetworkControllers can't be found directly by the IOServiceGetMatchingServices call,
// since they are hardware nubs and do not participate in driver matching. In other words,
// registerService() is never called on them. So we've found the IONetworkInterface and will
// get its parent controller by asking for it specifically.
// IORegistryEntryGetParentEntry retains the returned object, so release it when we're done with it.
kernResult = IORegistryEntryGetParentEntry(intfService,
kIOServicePlane,
&controllerService);
if (KERN_SUCCESS != kernResult) {
printf("IORegistryEntryGetParentEntry returned 0x%08x\n", kernResult);
}
else {
// Retrieve the MAC address property from the I/O Registry in the form of a CFData
MACAddressAsCFData = IORegistryEntryCreateCFProperty(controllerService,
CFSTR(kIOMACAddress),
kCFAllocatorDefault,
0);
if (MACAddressAsCFData) {
CFShow(MACAddressAsCFData); // for display purposes only; output goes to stderr
// Get the raw bytes of the MAC address from the CFData
CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress);
CFRelease(MACAddressAsCFData);
}
// Done with the parent Ethernet controller object so we release it.
(void) IOObjectRelease(controllerService);
}
// Done with the Ethernet interface object so we release it.
(void) IOObjectRelease(intfService);
}
return kernResult;
}
- (void)createLocalMac{
kern_return_t kernResult = KERN_SUCCESS;
io_iterator_t intfIterator;
UInt8 MACAddress[kIOEthernetAddressSize];
kernResult = FindEthernetInterfaces(&intfIterator);
if (KERN_SUCCESS != kernResult) {
printf("FindEthernetInterfaces returned 0x%08x\n", kernResult);
}
else {
kernResult = GetMACAddress(intfIterator, MACAddress, sizeof(MACAddress));
if (KERN_SUCCESS != kernResult) {
printf("GetMACAddress returned 0x%08x\n", kernResult);
}
else {
localMac = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
MACAddress[0], MACAddress[1], MACAddress[2], MACAddress[3], MACAddress[4], MACAddress[5]];
}
}
(void) IOObjectRelease(intfIterator); // Release the iterator.
}
//REMOTE MAC:::::::::::::::::::
- (void)createRemoteMac:(NSString *)ipAddr{
NSString *ret = nil;
in_addr_t addr = inet_addr([ipAddr UTF8String]);
size_t needed;
char *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
int mib[6];
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = (char*)malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &needed, NULL, 0) < 0)
err(1, "retrieval of routing table");
for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr != sin->sin_addr.s_addr || sdl->sdl_alen < 6)
continue;
u_char *cp = (u_char*)LLADDR(sdl);
ret = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
break;
}
free(buf);
remoteMac = ret;
}
- (void)dealloc {
[remoteMac release];
[localMac release];
[super dealloc];
}
@end
我用它来获取活动接口的 MAC 地址。
Every time I start build my Xcode Project, I get this in the console:
<CFData 0x100516c60 [0x7fff71adaea0]>{length = 6, capacity = 6, bytes = 0x0022412b03ad}
I have no idea, what it means and what it's causing it.
Can someone help me?
Thx!
Edit:
I think this method creates it:
//
// PrimaryMac.m
// Network Radar
//
// Created by Daniel Diener on 06.07.11.
// Copyright 2011 __MyCompanyName__. All rights reserved.
//
#import "PrimaryMac.h"
#include <stdio.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include "if_types.h"
#include "route.h"
#include "if_ether.h"
#include <netinet/in.h>
#include <arpa/inet.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <paths.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IOEthernetController.h>
@implementation PrimaryMac
@synthesize localMac, remoteMac;
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices);
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize);
- (id)init
{
self = [super init];
if (self) {
}
return self;
}
//LOCAL MAC:::::::::::::::::::
// Returns an iterator containing the primary (built-in) Ethernet interface. The caller is responsible for
// releasing the iterator after the caller is done with it.
static kern_return_t FindEthernetInterfaces(io_iterator_t *matchingServices)
{
kern_return_t kernResult;
CFMutableDictionaryRef matchingDict;
CFMutableDictionaryRef propertyMatchDict;
// Ethernet interfaces are instances of class kIOEthernetInterfaceClass.
// IOServiceMatching is a convenience function to create a dictionary with the key kIOProviderClassKey and
// the specified value.
matchingDict = IOServiceMatching(kIOEthernetInterfaceClass);
// Note that another option here would be:
// matchingDict = IOBSDMatching("en0");
// but en0: isn't necessarily the primary interface, especially on systems with multiple Ethernet ports.
if (NULL == matchingDict) {
printf("IOServiceMatching returned a NULL dictionary.\n");
}
else {
// Each IONetworkInterface object has a Boolean property with the key kIOPrimaryInterface. Only the
// primary (built-in) interface has this property set to TRUE.
// IOServiceGetMatchingServices uses the default matching criteria defined by IOService. This considers
// only the following properties plus any family-specific matching in this order of precedence
// (see IOService::passiveMatch):
//
// kIOProviderClassKey (IOServiceMatching)
// kIONameMatchKey (IOServiceNameMatching)
// kIOPropertyMatchKey
// kIOPathMatchKey
// kIOMatchedServiceCountKey
// family-specific matching
// kIOBSDNameKey (IOBSDNameMatching)
// kIOLocationMatchKey
// The IONetworkingFamily does not define any family-specific matching. This means that in
// order to have IOServiceGetMatchingServices consider the kIOPrimaryInterface property, we must
// add that property to a separate dictionary and then add that to our matching dictionary
// specifying kIOPropertyMatchKey.
propertyMatchDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (NULL == propertyMatchDict) {
printf("CFDictionaryCreateMutable returned a NULL dictionary.\n");
}
else {
// Set the value in the dictionary of the property with the given key, or add the key
// to the dictionary if it doesn't exist. This call retains the value object passed in.
CFDictionarySetValue(propertyMatchDict, CFSTR(kIOPrimaryInterface), kCFBooleanTrue);
// Now add the dictionary containing the matching value for kIOPrimaryInterface to our main
// matching dictionary. This call will retain propertyMatchDict, so we can release our reference
// on propertyMatchDict after adding it to matchingDict.
CFDictionarySetValue(matchingDict, CFSTR(kIOPropertyMatchKey), propertyMatchDict);
CFRelease(propertyMatchDict);
}
}
// IOServiceGetMatchingServices retains the returned iterator, so release the iterator when we're done with it.
// IOServiceGetMatchingServices also consumes a reference on the matching dictionary so we don't need to release
// the dictionary explicitly.
kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, matchingDict, matchingServices);
if (KERN_SUCCESS != kernResult) {
printf("IOServiceGetMatchingServices returned 0x%08x\n", kernResult);
}
return kernResult;
}
// Given an iterator across a set of Ethernet interfaces, return the MAC address of the last one.
// If no interfaces are found the MAC address is set to an empty string.
// In this sample the iterator should contain just the primary interface.
static kern_return_t GetMACAddress(io_iterator_t intfIterator, UInt8 *MACAddress, UInt8 bufferSize)
{
io_object_t intfService;
io_object_t controllerService;
kern_return_t kernResult = KERN_FAILURE;
// Make sure the caller provided enough buffer space. Protect against buffer overflow problems.
if (bufferSize < kIOEthernetAddressSize) {
return kernResult;
}
// Initialize the returned address
bzero(MACAddress, bufferSize);
// IOIteratorNext retains the returned object, so release it when we're done with it.
while ((intfService = IOIteratorNext(intfIterator)))
{
CFTypeRef MACAddressAsCFData;
// IONetworkControllers can't be found directly by the IOServiceGetMatchingServices call,
// since they are hardware nubs and do not participate in driver matching. In other words,
// registerService() is never called on them. So we've found the IONetworkInterface and will
// get its parent controller by asking for it specifically.
// IORegistryEntryGetParentEntry retains the returned object, so release it when we're done with it.
kernResult = IORegistryEntryGetParentEntry(intfService,
kIOServicePlane,
&controllerService);
if (KERN_SUCCESS != kernResult) {
printf("IORegistryEntryGetParentEntry returned 0x%08x\n", kernResult);
}
else {
// Retrieve the MAC address property from the I/O Registry in the form of a CFData
MACAddressAsCFData = IORegistryEntryCreateCFProperty(controllerService,
CFSTR(kIOMACAddress),
kCFAllocatorDefault,
0);
if (MACAddressAsCFData) {
CFShow(MACAddressAsCFData); // for display purposes only; output goes to stderr
// Get the raw bytes of the MAC address from the CFData
CFDataGetBytes(MACAddressAsCFData, CFRangeMake(0, kIOEthernetAddressSize), MACAddress);
CFRelease(MACAddressAsCFData);
}
// Done with the parent Ethernet controller object so we release it.
(void) IOObjectRelease(controllerService);
}
// Done with the Ethernet interface object so we release it.
(void) IOObjectRelease(intfService);
}
return kernResult;
}
- (void)createLocalMac{
kern_return_t kernResult = KERN_SUCCESS;
io_iterator_t intfIterator;
UInt8 MACAddress[kIOEthernetAddressSize];
kernResult = FindEthernetInterfaces(&intfIterator);
if (KERN_SUCCESS != kernResult) {
printf("FindEthernetInterfaces returned 0x%08x\n", kernResult);
}
else {
kernResult = GetMACAddress(intfIterator, MACAddress, sizeof(MACAddress));
if (KERN_SUCCESS != kernResult) {
printf("GetMACAddress returned 0x%08x\n", kernResult);
}
else {
localMac = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x",
MACAddress[0], MACAddress[1], MACAddress[2], MACAddress[3], MACAddress[4], MACAddress[5]];
}
}
(void) IOObjectRelease(intfIterator); // Release the iterator.
}
//REMOTE MAC:::::::::::::::::::
- (void)createRemoteMac:(NSString *)ipAddr{
NSString *ret = nil;
in_addr_t addr = inet_addr([ipAddr UTF8String]);
size_t needed;
char *buf, *next;
struct rt_msghdr *rtm;
struct sockaddr_inarp *sin;
struct sockaddr_dl *sdl;
int mib[6];
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0;
mib[3] = AF_INET;
mib[4] = NET_RT_FLAGS;
mib[5] = RTF_LLINFO;
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &needed, NULL, 0) < 0)
err(1, "route-sysctl-estimate");
if ((buf = (char*)malloc(needed)) == NULL)
err(1, "malloc");
if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), buf, &needed, NULL, 0) < 0)
err(1, "retrieval of routing table");
for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
rtm = (struct rt_msghdr *)next;
sin = (struct sockaddr_inarp *)(rtm + 1);
sdl = (struct sockaddr_dl *)(sin + 1);
if (addr != sin->sin_addr.s_addr || sdl->sdl_alen < 6)
continue;
u_char *cp = (u_char*)LLADDR(sdl);
ret = [NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]];
break;
}
free(buf);
remoteMac = ret;
}
- (void)dealloc {
[remoteMac release];
[localMac release];
[super dealloc];
}
@end
I use it to get the active interface's MAC address.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您的打印语句正在使用
CFShow
发生在这一行。只需注释掉即可:)Your print statement is happening on this line using
CFShow
. Just comment that out :)