1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 28 #include <fstream> 29 #include "fcntl.h" 30 #include "Handle.h" 31 #include "Trace.h" 32 #include "Exceptions.h" 33 #include "sun_fc.h" 34 #include <unistd.h> 35 36 #ifdef __cplusplus 37 extern "C" { 38 #endif 39 40 void get_random_bytes(HBA_UINT8 *ptr, size_t len) { 41 int fd = open("/dev/urandom", O_RDONLY); 42 size_t resid = len; 43 ssize_t bytes; 44 45 while (resid != 0) { 46 bytes = read(fd, ptr, resid); 47 ptr += bytes; 48 resid -= bytes; 49 } 50 close (fd); 51 return; 52 } 53 54 HBA_STATUS Sun_fcAdapterCreateWWN(HBA_HANDLE handle, 55 HBA_UINT32 portindex, HBA_WWN *nwwn, HBA_WWN *pwwn, 56 HBA_WWN *OUI, HBA_INT32 method) { 57 HBA_UINT8 randombyte[5] = {0}; 58 HBA_WWN randomwwn = {0}; 59 int index = 0; 60 61 Trace log("Sun_fcAdapterCreateWWN"); 62 63 if ((nwwn == NULL) || (pwwn == NULL)) { 64 log.userError( 65 "NULL WWN pointer"); 66 return (HBA_STATUS_ERROR_ARG); 67 } 68 if (method == HBA_CREATE_WWN_FACTORY) { 69 return (HBA_STATUS_ERROR_NOT_SUPPORTED); 70 } 71 72 try { 73 /* create EUI-64 Mapped WWN */ 74 if (OUI == NULL) { 75 /* if no OUI spec'd, used one of Sun's */ 76 randomwwn.wwn[index++] = 0x0; 77 randomwwn.wwn[index++] = 0x0; 78 randomwwn.wwn[index++] = 0x7D; 79 } else { 80 memcpy(randomwwn.wwn, OUI->wwn, sizeof(HBA_WWN)); 81 index += 3; 82 } 83 /* 84 * for EUI-64 mapped, shift OUI first byte right two bits 85 * then set top two bits to 11 86 */ 87 randomwwn.wwn[0] = randomwwn.wwn[0] >> 2; 88 randomwwn.wwn[0] = randomwwn.wwn[0] | 0xc0; 89 90 /* now create and add 40 random bits */ 91 get_random_bytes(randombyte, 5); 92 memcpy(randomwwn.wwn+index, randombyte, 5); 93 94 memcpy(nwwn->wwn, randomwwn.wwn, sizeof(HBA_WWN)); 95 96 /* toggle lowest bit, to make NWWN and PWWN unique */ 97 randomwwn.wwn[7] = randomwwn.wwn[7] ^ 1; 98 memcpy(pwwn->wwn, randomwwn.wwn, sizeof(HBA_WWN)); 99 100 return (HBA_STATUS_OK); 101 } catch (HBAException &e) { 102 return (e.getErrorCode()); 103 } catch (...) { 104 log.internalError( 105 "Uncaught exception"); 106 return (HBA_STATUS_ERROR); 107 } 108 } 109 #ifdef __cplusplus 110 } 111 #endif 112