1/* 2 * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24 * BLCreateEFIXMLRepresentationForNetworkPath.c 25 * bless 26 * 27 * Created by Shantonu Sen on 11/15/05. 28 * Copyright 2005-2007 Apple Inc. All Rights Reserved. 29 * 30 */ 31 32#import <IOKit/IOKitLib.h> 33#import <IOKit/IOCFSerialize.h> 34#import <IOKit/IOBSD.h> 35#import <IOKit/IOKitKeys.h> 36#include <IOKit/network/IONetworkInterface.h> 37#include <IOKit/network/IONetworkController.h> 38 39#import <CoreFoundation/CoreFoundation.h> 40 41#include <string.h> 42#include <sys/param.h> 43#include <sys/stat.h> 44 45#include "bless.h" 46#include "bless_private.h" 47 48int BLCreateEFIXMLRepresentationForNetworkPath(BLContextPtr context, 49 BLNetBootProtocolType protocol, 50 const char *interface, 51 const char *host, 52 const char *path, 53 const char *optionalData, 54 CFStringRef *xmlString) 55{ 56 mach_port_t masterPort; 57 kern_return_t kret; 58 io_service_t iface; 59 60 CFDataRef xmlData; 61 CFMutableDictionaryRef dict, matchDict; 62 CFMutableArrayRef array; 63 CFDataRef macAddress; 64 65 const UInt8 *xmlBuffer; 66 UInt8 *outBuffer; 67 CFIndex count; 68 69 kret = IOMasterPort(MACH_PORT_NULL, &masterPort); 70 if(kret) return 1; 71 72 73 74 array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); 75 76 dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, 77 &kCFTypeDictionaryValueCallBacks); 78 79 matchDict = IOBSDNameMatching(masterPort, 0, interface); 80 CFDictionarySetValue(matchDict, CFSTR(kIOProviderClassKey), CFSTR(kIONetworkInterfaceClass)); 81 82 CFRetain(matchDict); 83 iface = IOServiceGetMatchingService(masterPort, 84 matchDict); 85 86 if(iface == IO_OBJECT_NULL) { 87 contextprintf(context, kBLLogLevelError, "Could not find object for %s\n", interface); 88 CFRelease(matchDict); 89 CFRelease(dict); 90 CFRelease(array); 91 return 1; 92 } 93 94 CFDictionaryAddValue(dict, CFSTR("IOMatch"), matchDict); 95 CFRelease(matchDict); 96 97 macAddress = IORegistryEntrySearchCFProperty(iface, kIOServicePlane, 98 CFSTR(kIOMACAddress), 99 kCFAllocatorDefault, 100 kIORegistryIterateRecursively|kIORegistryIterateParents); 101 if(macAddress) { 102 contextprintf(context, kBLLogLevelVerbose, "MAC address %s found for %s\n", 103 BLGetCStringDescription(macAddress), interface); 104 105 CFDictionaryAddValue(dict, CFSTR("BLMACAddress"), macAddress); 106 CFRelease(macAddress); 107 } else { 108 contextprintf(context, kBLLogLevelVerbose, "No MAC address found for %s\n", interface); 109 } 110 111 IOObjectRelease(iface); 112 113 CFArrayAppendValue(array, dict); 114 CFRelease(dict); 115 116 if(host) { 117 CFStringRef hostString; 118 119 hostString = CFStringCreateWithCString(kCFAllocatorDefault, host, kCFStringEncodingUTF8); 120 121 dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, 122 &kCFTypeDictionaryValueCallBacks); 123 CFDictionaryAddValue(dict, CFSTR("IOEFIDevicePathType"), 124 CFSTR("MessagingIPv4")); 125 CFDictionaryAddValue(dict, CFSTR("RemoteIpAddress"), 126 hostString); 127 CFArrayAppendValue(array, dict); 128 CFRelease(dict); 129 CFRelease(hostString); 130 131 if(path) { 132 CFStringRef pathString; 133 134 pathString = CFStringCreateWithCString(kCFAllocatorDefault, path, kCFStringEncodingUTF8); 135 136 dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, 137 &kCFTypeDictionaryValueCallBacks); 138 CFDictionaryAddValue(dict, CFSTR("IOEFIDevicePathType"), 139 CFSTR("MediaFilePath")); 140 CFDictionaryAddValue(dict, CFSTR("Path"), 141 pathString); 142 CFArrayAppendValue(array, dict); 143 CFRelease(dict); 144 CFRelease(pathString); 145 } 146 147 } 148 149 contextprintf(context, kBLLogLevelVerbose, "Netboot protocol %d\n", protocol); 150 if (protocol == kBLNetBootProtocol_PXE) { 151 dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, 152 &kCFTypeDictionaryValueCallBacks); 153 CFDictionaryAddValue(dict, CFSTR("IOEFIDevicePathType"), 154 CFSTR("MessagingNetbootProtocol")); 155 CFDictionaryAddValue(dict, CFSTR("Protocol"), 156 CFSTR("FE3913DB-9AEE-4E40-A294-ABBE93A1A4B7")); 157 CFArrayAppendValue(array, dict); 158 CFRelease(dict); 159 } 160 161 if(optionalData) { 162 CFStringRef optString = CFStringCreateWithCString(kCFAllocatorDefault, optionalData, kCFStringEncodingUTF8); 163 164 dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, 165 &kCFTypeDictionaryValueCallBacks); 166 CFDictionaryAddValue(dict, CFSTR("IOEFIBootOption"), 167 optString); 168 CFArrayAppendValue(array, dict); 169 CFRelease(dict); 170 171 CFRelease(optString); 172 } 173 174 xmlData = IOCFSerialize(array, 0); 175 CFRelease(array); 176 177 if(xmlData == NULL) { 178 contextprintf(context, kBLLogLevelError, "Can't create XML representation\n"); 179 return 2; 180 } 181 182 count = CFDataGetLength(xmlData); 183 xmlBuffer = CFDataGetBytePtr(xmlData); 184 outBuffer = calloc(count+1, sizeof(char)); // terminate 185 186 memcpy(outBuffer, xmlBuffer, count); 187 CFRelease(xmlData); 188 189 *xmlString = CFStringCreateWithCString(kCFAllocatorDefault, (const char *)outBuffer, kCFStringEncodingUTF8); 190 191 free(outBuffer); 192 193 return 0; 194} 195 196