16cefaae1SJack Meng /* 26cefaae1SJack Meng * CDDL HEADER START 36cefaae1SJack Meng * 46cefaae1SJack Meng * The contents of this file are subject to the terms of the 56cefaae1SJack Meng * Common Development and Distribution License (the "License"). 66cefaae1SJack Meng * You may not use this file except in compliance with the License. 76cefaae1SJack Meng * 86cefaae1SJack Meng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96cefaae1SJack Meng * or http://www.opensolaris.org/os/licensing. 106cefaae1SJack Meng * See the License for the specific language governing permissions 116cefaae1SJack Meng * and limitations under the License. 126cefaae1SJack Meng * 136cefaae1SJack Meng * When distributing Covered Code, include this CDDL HEADER in each 146cefaae1SJack Meng * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156cefaae1SJack Meng * If applicable, add the following below this CDDL HEADER, with the 166cefaae1SJack Meng * fields enclosed by brackets "[]" replaced with your own identifying 176cefaae1SJack Meng * information: Portions Copyright [yyyy] [name of copyright owner] 186cefaae1SJack Meng * 196cefaae1SJack Meng * CDDL HEADER END 206cefaae1SJack Meng */ 216cefaae1SJack Meng /* 22*dedec472SJack Meng * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 236cefaae1SJack Meng * Use is subject to license terms. 246cefaae1SJack Meng */ 256cefaae1SJack Meng 266cefaae1SJack Meng #include <sys/bootprops.h> 27*dedec472SJack Meng #include <sys/bootconf.h> 28*dedec472SJack Meng #include <sys/modctl.h> 29*dedec472SJack Meng #include <sys/mman.h> 30*dedec472SJack Meng #include <sys/kmem.h> 31*dedec472SJack Meng #include <sys/ddi.h> 32*dedec472SJack Meng #include <sys/sunddi.h> 33*dedec472SJack Meng #include <sys/types.h> 34*dedec472SJack Meng #include <sys/obpdefs.h> 35*dedec472SJack Meng #include <sys/promif.h> 36*dedec472SJack Meng #include <sys/iscsi_protocol.h> 376cefaae1SJack Meng 38*dedec472SJack Meng #define ISCSI_OBP_MAX_CHAP_USER_LEN 16 39*dedec472SJack Meng #define ISCSI_OBP_MIN_CHAP_LEN 12 40*dedec472SJack Meng #define ISCSI_OBP_MAX_CHAP_LEN 16 41*dedec472SJack Meng 42*dedec472SJack Meng #define OBP_GET_KEY_STATUS_OK 0 43*dedec472SJack Meng #define OBP_GET_KEY_STATUS_NOT_EXIST -3 44*dedec472SJack Meng 45*dedec472SJack Meng ib_boot_prop_t boot_property; 466cefaae1SJack Meng extern ib_boot_prop_t *iscsiboot_prop; 47*dedec472SJack Meng static int inet_aton(char *ipstr, uchar_t *ip); 48*dedec472SJack Meng static boolean_t parse_lun_num(uchar_t *str_num, uchar_t *hex_num); 49*dedec472SJack Meng static void generate_iscsi_initiator_id(void); 506cefaae1SJack Meng 51*dedec472SJack Meng static int 52*dedec472SJack Meng isdigit(int ch) 53*dedec472SJack Meng { 54*dedec472SJack Meng return (ch >= '0' && ch <= '9'); 55*dedec472SJack Meng } 56*dedec472SJack Meng 57*dedec472SJack Meng static boolean_t 58*dedec472SJack Meng iscsiboot_tgt_prop_read(void) 59*dedec472SJack Meng { 60*dedec472SJack Meng int proplen; 61*dedec472SJack Meng boolean_t set = B_FALSE; 62*dedec472SJack Meng char iscsi_target_ip[INET6_ADDRSTRLEN]; 63*dedec472SJack Meng uchar_t iscsi_target_name[ISCSI_MAX_NAME_LEN]; 64*dedec472SJack Meng uchar_t iscsi_par[8]; 65*dedec472SJack Meng char chap_user[ISCSI_OBP_MAX_CHAP_USER_LEN] = {0}; 66*dedec472SJack Meng char chap_password[ISCSI_OBP_MAX_CHAP_LEN] = {0}; 67*dedec472SJack Meng uchar_t iscsi_port[8]; 68*dedec472SJack Meng uchar_t iscsi_lun[8]; 69*dedec472SJack Meng uchar_t iscsi_tpgt[8]; 70*dedec472SJack Meng long iscsi_tpgtl; 71*dedec472SJack Meng long port; 72*dedec472SJack Meng int ret = 0; 73*dedec472SJack Meng int status = 0; 74*dedec472SJack Meng int chap_user_len = 0; 75*dedec472SJack Meng int chap_pwd_len = 0; 76*dedec472SJack Meng 77*dedec472SJack Meng /* Get iscsi target IP address */ 78*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_TARGET_IP); 79*dedec472SJack Meng if (proplen > 0) { 80*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_TARGET_IP, 81*dedec472SJack Meng iscsi_target_ip) > 0) { 82*dedec472SJack Meng if (inet_aton(iscsi_target_ip, 83*dedec472SJack Meng (uchar_t *)&boot_property.boot_tgt.tgt_ip_u) == 84*dedec472SJack Meng 0) { 85*dedec472SJack Meng boot_property.boot_tgt.sin_family = AF_INET; 86*dedec472SJack Meng set = B_TRUE; 87*dedec472SJack Meng } 88*dedec472SJack Meng } 89*dedec472SJack Meng } 90*dedec472SJack Meng if (set != B_TRUE) { 91*dedec472SJack Meng return (B_FALSE); 92*dedec472SJack Meng } 93*dedec472SJack Meng 94*dedec472SJack Meng /* Get iscsi target port number */ 95*dedec472SJack Meng set = B_FALSE; 96*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_PORT); 97*dedec472SJack Meng if (proplen > 0) { 98*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_PORT, 99*dedec472SJack Meng iscsi_port) > 0) { 100*dedec472SJack Meng if (ddi_strtol((const char *)iscsi_port, NULL, 101*dedec472SJack Meng 10, &port) == 0) { 102*dedec472SJack Meng boot_property.boot_tgt.tgt_port = 103*dedec472SJack Meng (unsigned int)port; 104*dedec472SJack Meng set = B_TRUE; 105*dedec472SJack Meng } 106*dedec472SJack Meng } 107*dedec472SJack Meng } 108*dedec472SJack Meng if (set != B_TRUE) { 109*dedec472SJack Meng boot_property.boot_tgt.tgt_port = 3260; 110*dedec472SJack Meng } 111*dedec472SJack Meng 112*dedec472SJack Meng /* Get iscsi target LUN number */ 113*dedec472SJack Meng set = B_FALSE; 114*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_LUN); 115*dedec472SJack Meng if (proplen > 0) { 116*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_LUN, 117*dedec472SJack Meng iscsi_lun) > 0) { 118*dedec472SJack Meng if (parse_lun_num(iscsi_lun, 119*dedec472SJack Meng (uchar_t *) 120*dedec472SJack Meng (&boot_property.boot_tgt.tgt_boot_lun[0])) 121*dedec472SJack Meng == B_TRUE) { 122*dedec472SJack Meng set = B_TRUE; 123*dedec472SJack Meng } 124*dedec472SJack Meng } 125*dedec472SJack Meng } 126*dedec472SJack Meng if (set != B_TRUE) { 127*dedec472SJack Meng bzero((void *)boot_property.boot_tgt.tgt_boot_lun, 8); 128*dedec472SJack Meng } 129*dedec472SJack Meng 130*dedec472SJack Meng /* Get iscsi target portal group tag */ 131*dedec472SJack Meng set = B_FALSE; 132*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_TPGT); 133*dedec472SJack Meng if (proplen > 0) { 134*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_TPGT, 135*dedec472SJack Meng iscsi_tpgt) > 0) { 136*dedec472SJack Meng if (ddi_strtol((const char *)iscsi_tpgt, NULL, 10, 137*dedec472SJack Meng &iscsi_tpgtl) == 0) { 138*dedec472SJack Meng boot_property.boot_tgt.tgt_tpgt = 139*dedec472SJack Meng (uint16_t)iscsi_tpgtl; 140*dedec472SJack Meng set = B_TRUE; 141*dedec472SJack Meng } 142*dedec472SJack Meng } 143*dedec472SJack Meng } 144*dedec472SJack Meng if (set != B_TRUE) { 145*dedec472SJack Meng boot_property.boot_tgt.tgt_tpgt = 1; 146*dedec472SJack Meng } 147*dedec472SJack Meng 148*dedec472SJack Meng /* Get iscsi target node name */ 149*dedec472SJack Meng set = B_FALSE; 150*dedec472SJack Meng boot_property.boot_tgt.tgt_name = NULL; 151*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_TARGET_NAME); 152*dedec472SJack Meng if (proplen > 0) { 153*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_TARGET_NAME, 154*dedec472SJack Meng iscsi_target_name) > 0) { 155*dedec472SJack Meng boot_property.boot_tgt.tgt_name = 156*dedec472SJack Meng (uchar_t *)kmem_zalloc(proplen + 1, KM_SLEEP); 157*dedec472SJack Meng boot_property.boot_tgt.tgt_name_len = proplen + 1; 158*dedec472SJack Meng (void) snprintf((char *)boot_property.boot_tgt.tgt_name, 159*dedec472SJack Meng proplen + 1, "%s", iscsi_target_name); 160*dedec472SJack Meng set = B_TRUE; 161*dedec472SJack Meng } 162*dedec472SJack Meng } 163*dedec472SJack Meng if (set != B_TRUE) { 164*dedec472SJack Meng if (boot_property.boot_tgt.tgt_name != NULL) { 165*dedec472SJack Meng kmem_free(boot_property.boot_tgt.tgt_name, 166*dedec472SJack Meng boot_property.boot_tgt.tgt_name_len); 167*dedec472SJack Meng boot_property.boot_tgt.tgt_name = NULL; 168*dedec472SJack Meng boot_property.boot_tgt.tgt_name_len = 0; 169*dedec472SJack Meng } 170*dedec472SJack Meng return (B_FALSE); 171*dedec472SJack Meng } 172*dedec472SJack Meng 173*dedec472SJack Meng /* Get iscsi target boot partition */ 174*dedec472SJack Meng set = B_FALSE; 175*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par = NULL; 176*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par_len = 0; 177*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_PAR); 178*dedec472SJack Meng if (proplen > 0) { 179*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_PAR, iscsi_par) > 0) { 180*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par = 181*dedec472SJack Meng (uchar_t *)kmem_zalloc(proplen + 1, KM_SLEEP); 182*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par_len = proplen + 1; 183*dedec472SJack Meng (void) snprintf( 184*dedec472SJack Meng (char *)boot_property.boot_tgt.tgt_boot_par, 185*dedec472SJack Meng proplen + 1, "%s", iscsi_par); 186*dedec472SJack Meng set = B_TRUE; 187*dedec472SJack Meng } 188*dedec472SJack Meng } 189*dedec472SJack Meng if (set != B_TRUE) { 190*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par = 191*dedec472SJack Meng (uchar_t *)kmem_zalloc(2, KM_SLEEP); 192*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par_len = 2; 193*dedec472SJack Meng boot_property.boot_tgt.tgt_boot_par[0] = 'a'; 194*dedec472SJack Meng } 195*dedec472SJack Meng 196*dedec472SJack Meng /* Get CHAP name and secret */ 197*dedec472SJack Meng ret = prom_get_security_key(BP_CHAP_USER, chap_user, 198*dedec472SJack Meng ISCSI_OBP_MAX_CHAP_USER_LEN, &chap_user_len, &status); 199*dedec472SJack Meng if (ret != 0) { 200*dedec472SJack Meng return (B_FALSE); 201*dedec472SJack Meng } 202*dedec472SJack Meng if (status == OBP_GET_KEY_STATUS_NOT_EXIST) { 203*dedec472SJack Meng /* No chap name */ 204*dedec472SJack Meng return (B_TRUE); 205*dedec472SJack Meng } 206*dedec472SJack Meng if (status != OBP_GET_KEY_STATUS_OK || 207*dedec472SJack Meng chap_user_len > ISCSI_OBP_MAX_CHAP_USER_LEN || 208*dedec472SJack Meng chap_user_len <= 0) { 209*dedec472SJack Meng return (B_FALSE); 210*dedec472SJack Meng } 211*dedec472SJack Meng 212*dedec472SJack Meng ret = prom_get_security_key(BP_CHAP_PASSWORD, chap_password, 213*dedec472SJack Meng ISCSI_OBP_MAX_CHAP_LEN, &chap_pwd_len, &status); 214*dedec472SJack Meng if (ret != 0) { 215*dedec472SJack Meng return (B_FALSE); 216*dedec472SJack Meng } 217*dedec472SJack Meng 218*dedec472SJack Meng if (status == OBP_GET_KEY_STATUS_NOT_EXIST) { 219*dedec472SJack Meng /* No chap secret */ 220*dedec472SJack Meng return (B_TRUE); 221*dedec472SJack Meng } 222*dedec472SJack Meng if (status != OBP_GET_KEY_STATUS_OK || 223*dedec472SJack Meng chap_pwd_len > ISCSI_OBP_MAX_CHAP_LEN || 224*dedec472SJack Meng chap_pwd_len <= 0) { 225*dedec472SJack Meng return (B_FALSE); 226*dedec472SJack Meng } 227*dedec472SJack Meng 228*dedec472SJack Meng boot_property.boot_init.ini_chap_name = 229*dedec472SJack Meng (uchar_t *)kmem_zalloc(chap_user_len + 1, KM_SLEEP); 230*dedec472SJack Meng boot_property.boot_init.ini_chap_name_len = chap_user_len + 1; 231*dedec472SJack Meng (void) memcpy(boot_property.boot_init.ini_chap_name, chap_user, 232*dedec472SJack Meng chap_user_len); 233*dedec472SJack Meng 234*dedec472SJack Meng boot_property.boot_init.ini_chap_sec = 235*dedec472SJack Meng (uchar_t *)kmem_zalloc(chap_pwd_len + 1, KM_SLEEP); 236*dedec472SJack Meng boot_property.boot_init.ini_chap_sec_len = chap_pwd_len + 1; 237*dedec472SJack Meng (void) memcpy(boot_property.boot_init.ini_chap_sec, chap_password, 238*dedec472SJack Meng chap_pwd_len); 239*dedec472SJack Meng 240*dedec472SJack Meng return (B_TRUE); 241*dedec472SJack Meng } 242*dedec472SJack Meng 243*dedec472SJack Meng static boolean_t 244*dedec472SJack Meng iscsiboot_init_prop_read(void) 245*dedec472SJack Meng { 246*dedec472SJack Meng int proplen; 247*dedec472SJack Meng uchar_t iscsi_initiator_id[ISCSI_MAX_NAME_LEN]; 248*dedec472SJack Meng boolean_t set = B_FALSE; 249*dedec472SJack Meng 250*dedec472SJack Meng /* Get initiator node name */ 251*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_INITIATOR_ID); 252*dedec472SJack Meng if (proplen > 0) { 253*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_INITIATOR_ID, 254*dedec472SJack Meng iscsi_initiator_id) > 0) { 255*dedec472SJack Meng boot_property.boot_init.ini_name = 256*dedec472SJack Meng (uchar_t *)kmem_zalloc(proplen + 1, KM_SLEEP); 257*dedec472SJack Meng boot_property.boot_init.ini_name_len = proplen + 1; 258*dedec472SJack Meng (void) snprintf( 259*dedec472SJack Meng (char *)boot_property.boot_init.ini_name, 260*dedec472SJack Meng proplen + 1, "%s", iscsi_initiator_id); 261*dedec472SJack Meng set = B_TRUE; 262*dedec472SJack Meng } 263*dedec472SJack Meng } 264*dedec472SJack Meng if (set != B_TRUE) { 265*dedec472SJack Meng generate_iscsi_initiator_id(); 266*dedec472SJack Meng } 267*dedec472SJack Meng return (B_TRUE); 268*dedec472SJack Meng } 269*dedec472SJack Meng 270*dedec472SJack Meng static boolean_t 271*dedec472SJack Meng iscsiboot_nic_prop_read(void) 272*dedec472SJack Meng { 273*dedec472SJack Meng int proplen; 274*dedec472SJack Meng char host_ip[INET6_ADDRSTRLEN]; 275*dedec472SJack Meng char router_ip[INET6_ADDRSTRLEN]; 276*dedec472SJack Meng char subnet_mask[INET6_ADDRSTRLEN]; 277*dedec472SJack Meng uchar_t iscsi_network_path[MAXPATHLEN]; 278*dedec472SJack Meng char host_mac[6]; 279*dedec472SJack Meng uchar_t hex_netmask[4]; 280*dedec472SJack Meng pnode_t nodeid; 281*dedec472SJack Meng boolean_t set = B_FALSE; 282*dedec472SJack Meng 283*dedec472SJack Meng /* Get host IP address */ 284*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_HOST_IP); 285*dedec472SJack Meng if (proplen > 0) { 286*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_HOST_IP, 287*dedec472SJack Meng host_ip) > 0) { 288*dedec472SJack Meng if (inet_aton(host_ip, 289*dedec472SJack Meng (uchar_t *)&boot_property.boot_nic.nic_ip_u) == 290*dedec472SJack Meng 0) { 291*dedec472SJack Meng boot_property.boot_nic.sin_family = AF_INET; 292*dedec472SJack Meng set = B_TRUE; 293*dedec472SJack Meng } 294*dedec472SJack Meng } 295*dedec472SJack Meng } 296*dedec472SJack Meng if (set != B_TRUE) { 297*dedec472SJack Meng return (B_FALSE); 298*dedec472SJack Meng } 299*dedec472SJack Meng 300*dedec472SJack Meng /* Get router IP address */ 301*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ROUTER_IP); 302*dedec472SJack Meng if (proplen > 0) { 303*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ROUTER_IP, 304*dedec472SJack Meng router_ip) > 0) { 305*dedec472SJack Meng (void) inet_aton(router_ip, 306*dedec472SJack Meng (uchar_t *)&boot_property.boot_nic.nic_gw_u); 307*dedec472SJack Meng } 308*dedec472SJack Meng } 309*dedec472SJack Meng 310*dedec472SJack Meng /* Get host netmask */ 311*dedec472SJack Meng set = B_FALSE; 312*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_SUBNET_MASK); 313*dedec472SJack Meng if (proplen > 0) { 314*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_SUBNET_MASK, 315*dedec472SJack Meng subnet_mask) > 0) { 316*dedec472SJack Meng if (inet_aton(subnet_mask, hex_netmask) == 0) { 317*dedec472SJack Meng int i = 0; 318*dedec472SJack Meng uint32_t tmp = *((uint32_t *)hex_netmask); 319*dedec472SJack Meng while (tmp) { 320*dedec472SJack Meng i ++; 321*dedec472SJack Meng tmp = tmp << 1; 322*dedec472SJack Meng } 323*dedec472SJack Meng boot_property.boot_nic.sub_mask_prefix = i; 324*dedec472SJack Meng set = B_TRUE; 325*dedec472SJack Meng } 326*dedec472SJack Meng } 327*dedec472SJack Meng } 328*dedec472SJack Meng if (set != B_TRUE) { 329*dedec472SJack Meng boot_property.boot_nic.sub_mask_prefix = 24; 330*dedec472SJack Meng } 331*dedec472SJack Meng 332*dedec472SJack Meng /* Get iscsi boot NIC path in OBP */ 333*dedec472SJack Meng set = B_FALSE; 334*dedec472SJack Meng proplen = BOP_GETPROPLEN(bootops, BP_ISCSI_NETWORK_BOOTPATH); 335*dedec472SJack Meng if (proplen > 0) { 336*dedec472SJack Meng if (BOP_GETPROP(bootops, BP_ISCSI_NETWORK_BOOTPATH, 337*dedec472SJack Meng iscsi_network_path) > 0) { 338*dedec472SJack Meng nodeid = prom_finddevice((char *)iscsi_network_path); 339*dedec472SJack Meng proplen = prom_getproplen(nodeid, BP_LOCAL_MAC_ADDRESS); 340*dedec472SJack Meng if (proplen > 0) { 341*dedec472SJack Meng if (prom_getprop(nodeid, BP_LOCAL_MAC_ADDRESS, 342*dedec472SJack Meng host_mac) > 0) { 343*dedec472SJack Meng (void) memcpy( 344*dedec472SJack Meng boot_property.boot_nic.nic_mac, 345*dedec472SJack Meng host_mac, 6); 346*dedec472SJack Meng set = B_TRUE; 347*dedec472SJack Meng } 348*dedec472SJack Meng } 349*dedec472SJack Meng } 350*dedec472SJack Meng } 351*dedec472SJack Meng if (set != B_TRUE) { 352*dedec472SJack Meng return (B_FALSE); 353*dedec472SJack Meng } 354*dedec472SJack Meng 355*dedec472SJack Meng return (B_TRUE); 356*dedec472SJack Meng } 357*dedec472SJack Meng 3586cefaae1SJack Meng /* 359*dedec472SJack Meng * Manully construct iscsiboot_prop table based on 360*dedec472SJack Meng * OBP '/chosen' properties related to iscsi boot 3616cefaae1SJack Meng */ 362*dedec472SJack Meng void 363*dedec472SJack Meng ld_ib_prop() 364*dedec472SJack Meng { 365*dedec472SJack Meng if (iscsiboot_prop != NULL) 366*dedec472SJack Meng return; 367*dedec472SJack Meng 368*dedec472SJack Meng if ((iscsiboot_tgt_prop_read() == B_TRUE) && 369*dedec472SJack Meng (iscsiboot_init_prop_read() == B_TRUE) && 370*dedec472SJack Meng (iscsiboot_nic_prop_read() == B_TRUE)) { 371*dedec472SJack Meng iscsiboot_prop = &boot_property; 372*dedec472SJack Meng } else { 373*dedec472SJack Meng iscsi_boot_prop_free(); 374*dedec472SJack Meng } 375*dedec472SJack Meng } 376*dedec472SJack Meng 377*dedec472SJack Meng static boolean_t 378*dedec472SJack Meng parse_lun_num(uchar_t *str_num, uchar_t *hex_num) 379*dedec472SJack Meng { 380*dedec472SJack Meng char *p, *buf; 381*dedec472SJack Meng uint16_t *conv_num = (uint16_t *)hex_num; 382*dedec472SJack Meng long tmp; 383*dedec472SJack Meng int i = 0; 384*dedec472SJack Meng 385*dedec472SJack Meng if ((str_num == NULL) || (hex_num == NULL)) { 386*dedec472SJack Meng return (B_FALSE); 387*dedec472SJack Meng } 388*dedec472SJack Meng bzero((void *)hex_num, 8); 389*dedec472SJack Meng buf = (char *)str_num; 390*dedec472SJack Meng 391*dedec472SJack Meng for (i = 0; i < 4; i++) { 392*dedec472SJack Meng p = NULL; 393*dedec472SJack Meng p = strchr((const char *)buf, '-'); 394*dedec472SJack Meng if (p != NULL) { 395*dedec472SJack Meng *p = '\0'; 396*dedec472SJack Meng } 397*dedec472SJack Meng if (ddi_strtol((const char *)buf, NULL, 16, &tmp) != 0) { 398*dedec472SJack Meng return (B_FALSE); 399*dedec472SJack Meng } 400*dedec472SJack Meng conv_num[i] = (uint16_t)tmp; 401*dedec472SJack Meng if (p != NULL) { 402*dedec472SJack Meng buf = p + 1; 403*dedec472SJack Meng } else { 404*dedec472SJack Meng break; 405*dedec472SJack Meng } 406*dedec472SJack Meng } 407*dedec472SJack Meng 408*dedec472SJack Meng return (B_TRUE); 409*dedec472SJack Meng } 410*dedec472SJack Meng 411*dedec472SJack Meng static void 412*dedec472SJack Meng generate_iscsi_initiator_id(void) 413*dedec472SJack Meng { 414*dedec472SJack Meng boot_property.boot_init.ini_name_len = 38; 415*dedec472SJack Meng boot_property.boot_init.ini_name = 416*dedec472SJack Meng (uchar_t *)kmem_zalloc(boot_property.boot_init.ini_name_len, 417*dedec472SJack Meng KM_SLEEP); 418*dedec472SJack Meng (void) snprintf((char *)boot_property.boot_init.ini_name, 419*dedec472SJack Meng 38, "iqn.1986-03.com.sun:boot.%02x%02x%02x%02x%02x%02x", 420*dedec472SJack Meng boot_property.boot_nic.nic_mac[0], 421*dedec472SJack Meng boot_property.boot_nic.nic_mac[1], 422*dedec472SJack Meng boot_property.boot_nic.nic_mac[2], 423*dedec472SJack Meng boot_property.boot_nic.nic_mac[3], 424*dedec472SJack Meng boot_property.boot_nic.nic_mac[4], 425*dedec472SJack Meng boot_property.boot_nic.nic_mac[5]); 426*dedec472SJack Meng } 427*dedec472SJack Meng 428*dedec472SJack Meng 429*dedec472SJack Meng /* We only deal with a.b.c.d decimal format. ip points to 4 byte storage */ 430*dedec472SJack Meng static int 431*dedec472SJack Meng inet_aton(char *ipstr, uchar_t *ip) 432*dedec472SJack Meng { 433*dedec472SJack Meng int i = 0; 434*dedec472SJack Meng uchar_t val[4] = {0}; 435*dedec472SJack Meng char c = *ipstr; 436*dedec472SJack Meng 437*dedec472SJack Meng for (;;) { 438*dedec472SJack Meng if (!isdigit(c)) 439*dedec472SJack Meng return (-1); 440*dedec472SJack Meng for (;;) { 441*dedec472SJack Meng if (!isdigit(c)) 442*dedec472SJack Meng break; 443*dedec472SJack Meng val[i] = val[i] * 10 + (c - '0'); 444*dedec472SJack Meng c = *++ipstr; 445*dedec472SJack Meng } 446*dedec472SJack Meng i++; 447*dedec472SJack Meng if (i == 4) 448*dedec472SJack Meng break; 449*dedec472SJack Meng if (c != '.') 450*dedec472SJack Meng return (-1); 451*dedec472SJack Meng c = *++ipstr; 452*dedec472SJack Meng } 453*dedec472SJack Meng if (c != 0) 454*dedec472SJack Meng return (-1); 455*dedec472SJack Meng bcopy(val, ip, 4); 456*dedec472SJack Meng return (0); 4576cefaae1SJack Meng } 458