xref: /illumos-gate/usr/src/uts/sparc/os/iscsi_boot.c (revision dedec472)
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);
50*dedec472SJack Meng 
51*dedec472SJack Meng static int
isdigit(int ch)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
iscsiboot_tgt_prop_read(void)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
iscsiboot_init_prop_read(void)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 }
2696cefaae1SJack Meng 
270*dedec472SJack Meng static boolean_t
iscsiboot_nic_prop_read(void)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 
358*dedec472SJack Meng /*
359*dedec472SJack Meng  * Manully construct iscsiboot_prop table based on
360*dedec472SJack Meng  * OBP '/chosen' properties related to iscsi boot
361*dedec472SJack Meng  */
3626cefaae1SJack Meng void
ld_ib_prop()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
parse_lun_num(uchar_t * str_num,uchar_t * hex_num)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
generate_iscsi_initiator_id(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
inet_aton(char * ipstr,uchar_t * ip)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