diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c index 8841ba8a0..0bdd7a515 100644 --- a/src/detection/diskio/diskio_apple.c +++ b/src/detection/diskio/diskio_apple.c @@ -1,45 +1,70 @@ #include "diskio.h" +#include "util/apple/cf_helpers.h" #include +#include #include #include +#include + +static inline void wrapIoObjectRelease(io_service_t* service) +{ + assert(service); + if (*service) + IOObjectRelease(*service); +} +#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease))) const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { - io_iterator_t iterator; - if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != kIOReturnSuccess) + FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0; + if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS) return "IOServiceGetMatchingServices() failed"; io_registry_entry_t registryEntry; while((registryEntry = IOIteratorNext(iterator)) != 0) { - CFMutableDictionaryRef properties; - if(IORegistryEntryCreateCFProperties(registryEntry, &properties, kCFAllocatorDefault, kNilOptions) != kIOReturnSuccess) - { - IOObjectRelease(registryEntry); + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry; + + io_name_t deviceName; + if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS) continue; + + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0; + if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS) + continue; + + if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only + continue; + + FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions); + if (!statistics) + continue; + + FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); + ffStrbufInitS(&device->name, deviceName); + ffStrbufInit(&device->devPath); + ffStrbufInit(&device->type); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount); + + FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions); + if (bsdName) + { + ffCfStrGetString(bsdName, &device->devPath); + ffStrbufPrependS(&device->devPath, "/dev/"); } - io_registry_entry_t parent; - IORegistryEntryGetParentEntry(registryEntry, kIOServicePlane, &parent); - if(IOObjectConformsTo(parent, kIOBlockStorageDriverClass)) continue; - - io_name_t name; - if (IORegistryEntryGetName(registryEntry, name) != KERN_SUCCESS) - continue; - - // NSDictionary* props = (__bridge NSDictionary*) properties; - - // id statistics = [props valueForKey:@(kIOBlockStorageDriverStatisticsKey)]; - // if (!statistics) continue; - - // id volGroupaMntFromName = [props valueForKey:@"VolGroupMntFromName"]; - // if (!volGroupaMntFromName) continue; - - // NSLog(@"%@", props); + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0; + if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS) + { + FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions); + if (protocolCharacteristics) + ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->type); + } } - IOObjectRelease(iterator); - return NULL; } diff --git a/src/util/apple/cf_helpers.c b/src/util/apple/cf_helpers.c index 2ce563d5e..96b765114 100644 --- a/src/util/apple/cf_helpers.c +++ b/src/util/apple/cf_helpers.c @@ -83,6 +83,29 @@ const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result) return "TypeID is neither 'CFNumber' nor 'CFData'"; } +const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result) +{ + CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key); + if(cf == NULL) + return "CFDictionaryGetValue() failed"; + + if(CFGetTypeID(cf) == CFNumberGetTypeID()) + { + if(!CFNumberGetValue((CFNumberRef)cf, kCFNumberSInt64Type, result)) + return "Number type is not SInt64"; + return NULL; + } + else if(CFGetTypeID(cf) == CFDataGetTypeID()) + { + if(CFDataGetLength((CFDataRef)cf) != sizeof(int64_t)) + return "Data length is not sizeof(int64_t)"; + CFDataGetBytes((CFDataRef)cf, CFRangeMake(0, sizeof(int64_t)), (uint8_t*)result); + return NULL; + } + + return "TypeID is neither 'CFNumber' nor 'CFData'"; +} + const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length) { CFTypeRef cf = (CFTypeRef)CFDictionaryGetValue(dict, key); diff --git a/src/util/apple/cf_helpers.h b/src/util/apple/cf_helpers.h index a8d9804a3..2137766bb 100644 --- a/src/util/apple/cf_helpers.h +++ b/src/util/apple/cf_helpers.h @@ -11,6 +11,7 @@ const char* ffCfStrGetString(CFStringRef str, FFstrbuf* result); const char* ffCfDictGetString(CFDictionaryRef dict, CFStringRef key, FFstrbuf* result); const char* ffCfDictGetBool(CFDictionaryRef dict, CFStringRef key, bool* result); const char* ffCfDictGetInt(CFDictionaryRef dict, CFStringRef key, int* result); +const char* ffCfDictGetInt64(CFDictionaryRef dict, CFStringRef key, int64_t* result); const char* ffCfDictGetData(CFDictionaryRef dict, CFStringRef key, uint32_t offset, uint32_t size, uint8_t* result, uint32_t* length); const char* ffCfDictGetDict(CFDictionaryRef dict, CFStringRef key, CFDictionaryRef* result);