BLGetOpenFirmwareBootDeviceForNetworkPath.c [plain text]
#import <IOKit/IOKitLib.h>
#import <IOKit/IOBSD.h>
#import <IOKit/IOKitKeys.h>
#include <IOKit/network/IONetworkInterface.h>
#include <IOKit/network/IONetworkController.h>
#import <CoreFoundation/CoreFoundation.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/param.h>
#include "bless.h"
#include "bless_private.h"
int BLGetOpenFirmwareBootDeviceForNetworkPath(BLContextPtr context,
const char *interface,
const char *host,
const char *path,
char * ofstring) {
mach_port_t masterPort;
kern_return_t kret;
io_service_t iface, service;
io_iterator_t iter;
io_string_t pathInPlane;
bool gotPathInPlane = false;
CFMutableDictionaryRef matchDict;
kret = IOMasterPort(MACH_PORT_NULL, &masterPort);
if(kret) return 1;
matchDict = IOBSDNameMatching(masterPort, 0, interface);
CFDictionarySetValue(matchDict, CFSTR(kIOProviderClassKey), CFSTR(kIONetworkInterfaceClass));
iface = IOServiceGetMatchingService(masterPort,
matchDict);
if(iface == IO_OBJECT_NULL) {
contextprintf(context, kBLLogLevelError, "Could not find object for %s\n", interface);
return 1;
}
kret = IORegistryEntryCreateIterator(iface, kIOServicePlane,
kIORegistryIterateRecursively|kIORegistryIterateParents,
&iter);
IOObjectRelease(iface);
if(kret) {
contextprintf(context, kBLLogLevelError, "Could not find object for %s\n", interface);
return 2;
}
while ( (service = IOIteratorNext(iter)) != IO_OBJECT_NULL ) {
kret = IORegistryEntryGetPath(service, kIODeviceTreePlane, pathInPlane);
if(kret == 0) {
gotPathInPlane = true;
IOObjectRelease(service);
break;
}
IOObjectRelease(service);
}
IOObjectRelease(iter);
if(!gotPathInPlane) {
contextprintf(context, kBLLogLevelError, "Could not find parent for %s in device tree\n", interface);
return 3;
}
contextprintf(context, kBLLogLevelVerbose, "Got path %s for interface %s\n", pathInPlane, interface);
if(host && path && strlen(path)) {
sprintf(ofstring, "%s:%s,%s", pathInPlane + strlen(kIODeviceTreePlane) + 1, host, path);
} else {
sprintf(ofstring, "%s:bootp", pathInPlane + strlen(kIODeviceTreePlane) + 1);
}
return 0;
}