xref: /titanic_54/usr/src/cmd/iscsiadm/sun_ima.c (revision fcf3ce441efd61da9bb2884968af01cb7c1452cc)
1*fcf3ce44SJohn Forte /*
2*fcf3ce44SJohn Forte  * CDDL HEADER START
3*fcf3ce44SJohn Forte  *
4*fcf3ce44SJohn Forte  * The contents of this file are subject to the terms of the
5*fcf3ce44SJohn Forte  * Common Development and Distribution License (the "License").
6*fcf3ce44SJohn Forte  * You may not use this file except in compliance with the License.
7*fcf3ce44SJohn Forte  *
8*fcf3ce44SJohn Forte  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*fcf3ce44SJohn Forte  * or http://www.opensolaris.org/os/licensing.
10*fcf3ce44SJohn Forte  * See the License for the specific language governing permissions
11*fcf3ce44SJohn Forte  * and limitations under the License.
12*fcf3ce44SJohn Forte  *
13*fcf3ce44SJohn Forte  * When distributing Covered Code, include this CDDL HEADER in each
14*fcf3ce44SJohn Forte  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*fcf3ce44SJohn Forte  * If applicable, add the following below this CDDL HEADER, with the
16*fcf3ce44SJohn Forte  * fields enclosed by brackets "[]" replaced with your own identifying
17*fcf3ce44SJohn Forte  * information: Portions Copyright [yyyy] [name of copyright owner]
18*fcf3ce44SJohn Forte  *
19*fcf3ce44SJohn Forte  * CDDL HEADER END
20*fcf3ce44SJohn Forte  */
21*fcf3ce44SJohn Forte /*
22*fcf3ce44SJohn Forte  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23*fcf3ce44SJohn Forte  * Use is subject to license terms.
24*fcf3ce44SJohn Forte  */
25*fcf3ce44SJohn Forte 
26*fcf3ce44SJohn Forte #include <arpa/inet.h>
27*fcf3ce44SJohn Forte #include <sys/socket.h>
28*fcf3ce44SJohn Forte #include <sys/types.h>
29*fcf3ce44SJohn Forte #include <stdarg.h>
30*fcf3ce44SJohn Forte #include <stdlib.h>
31*fcf3ce44SJohn Forte #include <string.h>
32*fcf3ce44SJohn Forte #include <strings.h>
33*fcf3ce44SJohn Forte #include <unistd.h>
34*fcf3ce44SJohn Forte #include <syslog.h>
35*fcf3ce44SJohn Forte #include <errno.h>
36*fcf3ce44SJohn Forte 
37*fcf3ce44SJohn Forte #include <fcntl.h>
38*fcf3ce44SJohn Forte #include <stdio.h>
39*fcf3ce44SJohn Forte #include <time.h>
40*fcf3ce44SJohn Forte #include <libdevinfo.h>
41*fcf3ce44SJohn Forte 
42*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_if.h>
43*fcf3ce44SJohn Forte #include <sys/scsi/adapters/iscsi_protocol.h>
44*fcf3ce44SJohn Forte #include <ima.h>
45*fcf3ce44SJohn Forte #include "iscsiadm.h"
46*fcf3ce44SJohn Forte #include "sun_ima.h"
47*fcf3ce44SJohn Forte 
48*fcf3ce44SJohn Forte #define	LIBRARY_PROPERTY_SUPPORTED_IMA_VERSION	1
49*fcf3ce44SJohn Forte #define	LIBRARY_PROPERTY_IMPLEMENTATION_VERSION	L"1.0.0"
50*fcf3ce44SJohn Forte #define	LIBRARY_PROPERTY_VENDOR	L"Sun Microsystems, Inc."
51*fcf3ce44SJohn Forte #define	DEFAULT_NODE_NAME_FORMAT    "iqn.2003-13.com.ima.%s"
52*fcf3ce44SJohn Forte #define	PLUGIN_OWNER 1
53*fcf3ce44SJohn Forte 
54*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
55*fcf3ce44SJohn Forte static IMA_INT32		number_of_plugins = -1;
56*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
57*fcf3ce44SJohn Forte static IMA_NODE_NAME		sharedNodeName;
58*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
59*fcf3ce44SJohn Forte static IMA_NODE_ALIAS		sharedNodeAlias;
60*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
61*fcf3ce44SJohn Forte static IMA_PLUGIN_PROPERTIES	PluginProperties;
62*fcf3ce44SJohn Forte 
63*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
64*fcf3ce44SJohn Forte static IMA_OID			pluginOid;
65*fcf3ce44SJohn Forte static IMA_OID			lhbaObjectId;
66*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
67*fcf3ce44SJohn Forte static boolean_t		pluginInit = B_FALSE;
68*fcf3ce44SJohn Forte 
69*fcf3ce44SJohn Forte /* Forward declaration */
70*fcf3ce44SJohn Forte #define	BOOL_PARAM		1
71*fcf3ce44SJohn Forte #define	MIN_MAX_PARAM		2
72*fcf3ce44SJohn Forte #define	PARAM_OP_OK		0
73*fcf3ce44SJohn Forte #define	PARAM_OP_FAILED		1
74*fcf3ce44SJohn Forte 
75*fcf3ce44SJohn Forte static int open_driver(int *fd);
76*fcf3ce44SJohn Forte static IMA_STATUS getISCSINodeParameter(int paramType,
77*fcf3ce44SJohn Forte     IMA_OID *oid,
78*fcf3ce44SJohn Forte     void *pProps,
79*fcf3ce44SJohn Forte     uint32_t paramIndex);
80*fcf3ce44SJohn Forte static IMA_STATUS setISCSINodeParameter(int paramType,
81*fcf3ce44SJohn Forte     IMA_OID *oid,
82*fcf3ce44SJohn Forte     void *pProps,
83*fcf3ce44SJohn Forte     uint32_t paramIndex);
84*fcf3ce44SJohn Forte static IMA_STATUS getDigest(IMA_OID oid, int ioctlCmd,
85*fcf3ce44SJohn Forte     SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm);
86*fcf3ce44SJohn Forte static IMA_STATUS setAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount,
87*fcf3ce44SJohn Forte     const IMA_AUTHMETHOD *pMethodList);
88*fcf3ce44SJohn Forte static IMA_STATUS getAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount,
89*fcf3ce44SJohn Forte     IMA_AUTHMETHOD *pMethodList);
90*fcf3ce44SJohn Forte IMA_STATUS getNegotiatedDigest(int digestType,
91*fcf3ce44SJohn Forte 	SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm,
92*fcf3ce44SJohn Forte 	SUN_IMA_CONN_PROPERTIES *connProps);
93*fcf3ce44SJohn Forte 
94*fcf3ce44SJohn Forte /* OK */
95*fcf3ce44SJohn Forte #define	DISC_ADDR_OK		    0
96*fcf3ce44SJohn Forte /* Incorrect IP address */
97*fcf3ce44SJohn Forte #define	DISC_ADDR_INTEGRITY_ERROR   1
98*fcf3ce44SJohn Forte /* Error converting text IP address to numeric binary form */
99*fcf3ce44SJohn Forte #define	DISC_ADDR_IP_CONV_ERROR	    2
100*fcf3ce44SJohn Forte static int prepare_discovery_entry(SUN_IMA_TARGET_ADDRESS discoveryAddress,
101*fcf3ce44SJohn Forte     entry_t *entry);
102*fcf3ce44SJohn Forte static int prepare_discovery_entry_IMA(IMA_TARGET_ADDRESS discoveryAddress,
103*fcf3ce44SJohn Forte     entry_t *entry);
104*fcf3ce44SJohn Forte 
105*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
106*fcf3ce44SJohn Forte static IMA_STATUS configure_discovery_method(IMA_BOOL enable,
107*fcf3ce44SJohn Forte     iSCSIDiscoveryMethod_t method);
108*fcf3ce44SJohn Forte 
109*fcf3ce44SJohn Forte static IMA_STATUS get_target_oid_list(uint32_t targetListType,
110*fcf3ce44SJohn Forte     IMA_OID_LIST **ppList);
111*fcf3ce44SJohn Forte 
112*fcf3ce44SJohn Forte static IMA_STATUS get_target_lun_oid_list(IMA_OID * targetOid,
113*fcf3ce44SJohn Forte 					    iscsi_lun_list_t  **ppLunList);
114*fcf3ce44SJohn Forte 
115*fcf3ce44SJohn Forte static int get_lun_devlink(di_devlink_t link, void *osDeviceName);
116*fcf3ce44SJohn Forte 
117*fcf3ce44SJohn Forte static IMA_STATUS getConnOidList(
118*fcf3ce44SJohn Forte 	IMA_OID			*oid,
119*fcf3ce44SJohn Forte 	iscsi_conn_list_t	**ppConnList);
120*fcf3ce44SJohn Forte 
121*fcf3ce44SJohn Forte static IMA_STATUS getConnProps(
122*fcf3ce44SJohn Forte 	iscsi_if_conn_t		*pConn,
123*fcf3ce44SJohn Forte 	iscsi_conn_props_t	**ppConnProps);
124*fcf3ce44SJohn Forte 
125*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
126*fcf3ce44SJohn Forte static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...)
127*fcf3ce44SJohn Forte {
128*fcf3ce44SJohn Forte 	va_list args;
129*fcf3ce44SJohn Forte 	va_start(args, lpszFormat);
130*fcf3ce44SJohn Forte 	(void) vswprintf(wcs, 255, lpszFormat, args);
131*fcf3ce44SJohn Forte 	va_end(args);
132*fcf3ce44SJohn Forte }
133*fcf3ce44SJohn Forte 
134*fcf3ce44SJohn Forte 
135*fcf3ce44SJohn Forte char *
136*fcf3ce44SJohn Forte _strlwr(char *s)
137*fcf3ce44SJohn Forte {
138*fcf3ce44SJohn Forte 	char *t = s;
139*fcf3ce44SJohn Forte 	while (t != NULL && *t) {
140*fcf3ce44SJohn Forte 		if (*t >= 'A' && *t <= 'Z')
141*fcf3ce44SJohn Forte 			*t += 32;
142*fcf3ce44SJohn Forte 		t++;
143*fcf3ce44SJohn Forte 	}
144*fcf3ce44SJohn Forte 	return (s);
145*fcf3ce44SJohn Forte }
146*fcf3ce44SJohn Forte 
147*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
148*fcf3ce44SJohn Forte static void GetBuildTime(IMA_DATETIME* pdatetime)
149*fcf3ce44SJohn Forte {
150*fcf3ce44SJohn Forte #if defined(BUILD_DATE)
151*fcf3ce44SJohn Forte 	if (strptime(BUILD_DATE, "%Y/%m/%d %T %Z", pdatetime) == NULL) {
152*fcf3ce44SJohn Forte 		(void) memset(pdatetime, 0, sizeof (IMA_DATETIME));
153*fcf3ce44SJohn Forte 	}
154*fcf3ce44SJohn Forte #else
155*fcf3ce44SJohn Forte 	(void) memset(pdatetime, 0, sizeof (IMA_DATETIME));
156*fcf3ce44SJohn Forte #endif
157*fcf3ce44SJohn Forte }
158*fcf3ce44SJohn Forte 
159*fcf3ce44SJohn Forte /*
160*fcf3ce44SJohn Forte  * Non-IMA defined function.
161*fcf3ce44SJohn Forte  */
162*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_GetDiscoveryAddressPropertiesList(
163*fcf3ce44SJohn Forte     SUN_IMA_DISC_ADDR_PROP_LIST	**ppList
164*fcf3ce44SJohn Forte )
165*fcf3ce44SJohn Forte {
166*fcf3ce44SJohn Forte 	char		    discovery_addr_str[256];
167*fcf3ce44SJohn Forte 	int		    fd;
168*fcf3ce44SJohn Forte 	int		    i;
169*fcf3ce44SJohn Forte 	int		    discovery_addr_list_size;
170*fcf3ce44SJohn Forte 	int		    status;
171*fcf3ce44SJohn Forte 	int		    out_cnt;
172*fcf3ce44SJohn Forte 	iscsi_addr_list_t   *ialp;
173*fcf3ce44SJohn Forte 	/* LINTED E_FUNC_SET_NOT_USED */
174*fcf3ce44SJohn Forte 	IMA_IP_ADDRESS	    *ipAddr;
175*fcf3ce44SJohn Forte 
176*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
177*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
178*fcf3ce44SJohn Forte 	}
179*fcf3ce44SJohn Forte 
180*fcf3ce44SJohn Forte 	ialp = (iscsi_addr_list_t *)calloc(1, sizeof (iscsi_addr_list_t));
181*fcf3ce44SJohn Forte 	if (ialp == NULL) {
182*fcf3ce44SJohn Forte 		(void) close(fd);
183*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
184*fcf3ce44SJohn Forte 	}
185*fcf3ce44SJohn Forte 
186*fcf3ce44SJohn Forte 	ialp->al_vers = ISCSI_INTERFACE_VERSION;
187*fcf3ce44SJohn Forte 	ialp->al_in_cnt = ialp->al_out_cnt = 1;
188*fcf3ce44SJohn Forte 
189*fcf3ce44SJohn Forte 	/*
190*fcf3ce44SJohn Forte 	 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl
191*fcf3ce44SJohn Forte 	 * We have allocated space for one entry, if more than one
192*fcf3ce44SJohn Forte 	 * address is going to be returned, we will re-issue the ioctl
193*fcf3ce44SJohn Forte 	 */
194*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) {
195*fcf3ce44SJohn Forte 		(void) close(fd);
196*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
197*fcf3ce44SJohn Forte 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
198*fcf3ce44SJohn Forte 		    errno);
199*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
200*fcf3ce44SJohn Forte 	}
201*fcf3ce44SJohn Forte 
202*fcf3ce44SJohn Forte 	if (ialp->al_out_cnt > 1) {
203*fcf3ce44SJohn Forte 		/*
204*fcf3ce44SJohn Forte 		 * we need to allocate more space, save off the out_cnt
205*fcf3ce44SJohn Forte 		 * and free ialp
206*fcf3ce44SJohn Forte 		 */
207*fcf3ce44SJohn Forte 		out_cnt = ialp->al_out_cnt;
208*fcf3ce44SJohn Forte 		free(ialp);
209*fcf3ce44SJohn Forte 
210*fcf3ce44SJohn Forte 		discovery_addr_list_size = sizeof (iscsi_addr_list_t);
211*fcf3ce44SJohn Forte 		discovery_addr_list_size += (sizeof (iscsi_addr_t) *
212*fcf3ce44SJohn Forte 		    out_cnt - 1);
213*fcf3ce44SJohn Forte 		ialp = (iscsi_addr_list_t *)calloc(1, discovery_addr_list_size);
214*fcf3ce44SJohn Forte 		if (ialp == NULL) {
215*fcf3ce44SJohn Forte 			(void) close(fd);
216*fcf3ce44SJohn Forte 			return (IMA_ERROR_INSUFFICIENT_MEMORY);
217*fcf3ce44SJohn Forte 		}
218*fcf3ce44SJohn Forte 		ialp->al_vers = ISCSI_INTERFACE_VERSION;
219*fcf3ce44SJohn Forte 		ialp->al_in_cnt = out_cnt;
220*fcf3ce44SJohn Forte 
221*fcf3ce44SJohn Forte 		/*
222*fcf3ce44SJohn Forte 		 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain all
223*fcf3ce44SJohn Forte 		 * the discovery addresses.
224*fcf3ce44SJohn Forte 		 */
225*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) {
226*fcf3ce44SJohn Forte #define	ERROR_STR "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno :%d"
227*fcf3ce44SJohn Forte 			free(ialp);
228*fcf3ce44SJohn Forte 			(void) close(fd);
229*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
230*fcf3ce44SJohn Forte 			    ERROR_STR, errno);
231*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
232*fcf3ce44SJohn Forte #undef ERROR_STR
233*fcf3ce44SJohn Forte 
234*fcf3ce44SJohn Forte 		}
235*fcf3ce44SJohn Forte 	}
236*fcf3ce44SJohn Forte 
237*fcf3ce44SJohn Forte 	*ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *)calloc(1,
238*fcf3ce44SJohn Forte 	    sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) +
239*fcf3ce44SJohn Forte 	    ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES));
240*fcf3ce44SJohn Forte 	if (*ppList == NULL) {
241*fcf3ce44SJohn Forte 		free(ialp);
242*fcf3ce44SJohn Forte 		(void) close(fd);
243*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
244*fcf3ce44SJohn Forte 	}
245*fcf3ce44SJohn Forte 	(*ppList)->discAddrCount = ialp->al_out_cnt;
246*fcf3ce44SJohn Forte 
247*fcf3ce44SJohn Forte 	for (i = 0; i < ialp->al_out_cnt; i++) {
248*fcf3ce44SJohn Forte 		if (ialp->al_addrs[i].a_addr.i_insize ==
249*fcf3ce44SJohn Forte 		    sizeof (struct in_addr)) {
250*fcf3ce44SJohn Forte 
251*fcf3ce44SJohn Forte 			(*ppList)->props[i].discoveryAddress.hostnameIpAddress.
252*fcf3ce44SJohn Forte 			id.ipAddress.ipv4Address = IMA_TRUE;
253*fcf3ce44SJohn Forte 
254*fcf3ce44SJohn Forte 		} else if (ialp->al_addrs[i].a_addr.i_insize ==
255*fcf3ce44SJohn Forte 		    sizeof (struct in6_addr)) {
256*fcf3ce44SJohn Forte 
257*fcf3ce44SJohn Forte 			(*ppList)->props[i].discoveryAddress.hostnameIpAddress.
258*fcf3ce44SJohn Forte 			id.ipAddress.ipv4Address = IMA_FALSE;
259*fcf3ce44SJohn Forte 
260*fcf3ce44SJohn Forte 		} else {
261*fcf3ce44SJohn Forte 			(void) strlcpy(discovery_addr_str, "unknown",
262*fcf3ce44SJohn Forte 			    sizeof (discovery_addr_str));
263*fcf3ce44SJohn Forte 		}
264*fcf3ce44SJohn Forte 
265*fcf3ce44SJohn Forte 		ipAddr = &(*ppList)->props[i].discoveryAddress.
266*fcf3ce44SJohn Forte 		    hostnameIpAddress.id.ipAddress;
267*fcf3ce44SJohn Forte 
268*fcf3ce44SJohn Forte 		bcopy(&ialp->al_addrs[i].a_addr.i_addr,
269*fcf3ce44SJohn Forte 		    (*ppList)->props[i].discoveryAddress.hostnameIpAddress.id.
270*fcf3ce44SJohn Forte 		    ipAddress.ipAddress,
271*fcf3ce44SJohn Forte 		    sizeof (ipAddr->ipAddress));
272*fcf3ce44SJohn Forte 
273*fcf3ce44SJohn Forte 		(*ppList)->props[i].discoveryAddress.portNumber =
274*fcf3ce44SJohn Forte 		    ialp->al_addrs[i].a_port;
275*fcf3ce44SJohn Forte 	}
276*fcf3ce44SJohn Forte 
277*fcf3ce44SJohn Forte 	free(ialp);
278*fcf3ce44SJohn Forte 	(void) close(fd);
279*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
280*fcf3ce44SJohn Forte }
281*fcf3ce44SJohn Forte 
282*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_GetStaticTargetProperties(
283*fcf3ce44SJohn Forte 		IMA_OID	staticTargetOid,
284*fcf3ce44SJohn Forte 		SUN_IMA_STATIC_TARGET_PROPERTIES *pProps
285*fcf3ce44SJohn Forte )
286*fcf3ce44SJohn Forte {
287*fcf3ce44SJohn Forte 	int fd;
288*fcf3ce44SJohn Forte 	int status;
289*fcf3ce44SJohn Forte 	iscsi_static_property_t prop;
290*fcf3ce44SJohn Forte 	/* LINTED */
291*fcf3ce44SJohn Forte 	IMA_IP_ADDRESS	    *ipAddr;
292*fcf3ce44SJohn Forte 
293*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
294*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
295*fcf3ce44SJohn Forte 	}
296*fcf3ce44SJohn Forte 
297*fcf3ce44SJohn Forte 	(void) memset(&prop, 0, sizeof (iscsi_static_property_t));
298*fcf3ce44SJohn Forte 	prop.p_vers = ISCSI_INTERFACE_VERSION;
299*fcf3ce44SJohn Forte 	prop.p_oid = (uint32_t)staticTargetOid.objectSequenceNumber;
300*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_STATIC_GET, &prop) != 0) {
301*fcf3ce44SJohn Forte 		status = errno;
302*fcf3ce44SJohn Forte 		(void) close(fd);
303*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
304*fcf3ce44SJohn Forte 		    "ISCSI_STATIC_GET ioctl failed, errno: %d", status);
305*fcf3ce44SJohn Forte 		if (status == ENOENT) {
306*fcf3ce44SJohn Forte 			return (IMA_ERROR_OBJECT_NOT_FOUND);
307*fcf3ce44SJohn Forte 		} else {
308*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
309*fcf3ce44SJohn Forte 		}
310*fcf3ce44SJohn Forte 	}
311*fcf3ce44SJohn Forte 	(void) close(fd);
312*fcf3ce44SJohn Forte 
313*fcf3ce44SJohn Forte 	(void) mbstowcs(pProps->staticTarget.targetName, (char *)prop.p_name,
314*fcf3ce44SJohn Forte 	    sizeof (pProps->staticTarget.targetName)/sizeof (IMA_WCHAR));
315*fcf3ce44SJohn Forte 
316*fcf3ce44SJohn Forte 	if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
317*fcf3ce44SJohn Forte 	    sizeof (struct in_addr)) {
318*fcf3ce44SJohn Forte 		/* IPv4 */
319*fcf3ce44SJohn Forte 		pProps->staticTarget.targetAddress.imaStruct.hostnameIpAddress.
320*fcf3ce44SJohn Forte 			id.ipAddress.ipv4Address = IMA_TRUE;
321*fcf3ce44SJohn Forte 	} else if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
322*fcf3ce44SJohn Forte 	    sizeof (struct in6_addr)) {
323*fcf3ce44SJohn Forte 		/* IPv6 */
324*fcf3ce44SJohn Forte 		pProps->staticTarget.targetAddress.imaStruct.hostnameIpAddress.
325*fcf3ce44SJohn Forte 			id.ipAddress.ipv4Address = IMA_FALSE;
326*fcf3ce44SJohn Forte 	} else {
327*fcf3ce44SJohn Forte 		/* Should not happen */
328*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
329*fcf3ce44SJohn Forte 		    "ISCSI_STATIC_GET returned bad address");
330*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
331*fcf3ce44SJohn Forte 	}
332*fcf3ce44SJohn Forte 
333*fcf3ce44SJohn Forte 	ipAddr = &pProps->staticTarget.targetAddress.imaStruct.
334*fcf3ce44SJohn Forte 	    hostnameIpAddress.id.ipAddress;
335*fcf3ce44SJohn Forte 
336*fcf3ce44SJohn Forte 	bcopy(&prop.p_addr_list.al_addrs[0].a_addr.i_addr,
337*fcf3ce44SJohn Forte 	    pProps->staticTarget.targetAddress.imaStruct.hostnameIpAddress.id.
338*fcf3ce44SJohn Forte 	    ipAddress.ipAddress, sizeof (ipAddr->ipAddress));
339*fcf3ce44SJohn Forte 
340*fcf3ce44SJohn Forte 	pProps->staticTarget.targetAddress.imaStruct.portNumber =
341*fcf3ce44SJohn Forte 	    prop.p_addr_list.al_addrs[0].a_port;
342*fcf3ce44SJohn Forte 
343*fcf3ce44SJohn Forte 
344*fcf3ce44SJohn Forte 	if (prop.p_addr_list.al_tpgt == (uint32_t)ISCSI_DEFAULT_TPGT) {
345*fcf3ce44SJohn Forte 		pProps->staticTarget.targetAddress.defaultTpgt = IMA_TRUE;
346*fcf3ce44SJohn Forte 		pProps->staticTarget.targetAddress.tpgt = 0;
347*fcf3ce44SJohn Forte 	} else {
348*fcf3ce44SJohn Forte 		pProps->staticTarget.targetAddress.defaultTpgt = IMA_FALSE;
349*fcf3ce44SJohn Forte 		pProps->staticTarget.targetAddress.tpgt =
350*fcf3ce44SJohn Forte 		    prop.p_addr_list.al_tpgt;
351*fcf3ce44SJohn Forte 	}
352*fcf3ce44SJohn Forte 
353*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
354*fcf3ce44SJohn Forte }
355*fcf3ce44SJohn Forte 
356*fcf3ce44SJohn Forte /*ARGSUSED*/
357*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_AddStaticTarget(
358*fcf3ce44SJohn Forte 		IMA_OID lhbaOid,
359*fcf3ce44SJohn Forte 		const SUN_IMA_STATIC_DISCOVERY_TARGET staticConfig,
360*fcf3ce44SJohn Forte 		IMA_OID *pTargetOid
361*fcf3ce44SJohn Forte )
362*fcf3ce44SJohn Forte {
363*fcf3ce44SJohn Forte 	iscsi_target_entry_t	target;
364*fcf3ce44SJohn Forte 	int			fd;
365*fcf3ce44SJohn Forte 	int			target_in_addr_size;
366*fcf3ce44SJohn Forte 	int			status;
367*fcf3ce44SJohn Forte 	union {
368*fcf3ce44SJohn Forte 		struct in_addr	u_in4;
369*fcf3ce44SJohn Forte 		struct in6_addr	u_in6;
370*fcf3ce44SJohn Forte 	}			target_in;
371*fcf3ce44SJohn Forte 
372*fcf3ce44SJohn Forte 	/*
373*fcf3ce44SJohn Forte 	 * staticConfig.address may come in with port number at its trailer.
374*fcf3ce44SJohn Forte 	 * Parse it to separate the IP address and port number.
375*fcf3ce44SJohn Forte 	 * Also translate the hostname to IP address if needed.
376*fcf3ce44SJohn Forte 	 */
377*fcf3ce44SJohn Forte 
378*fcf3ce44SJohn Forte 	if (staticConfig.targetAddress.imaStruct.hostnameIpAddress.id.ipAddress.
379*fcf3ce44SJohn Forte 	    ipv4Address == IMA_FALSE) {
380*fcf3ce44SJohn Forte 
381*fcf3ce44SJohn Forte 		bcopy(staticConfig.targetAddress.imaStruct.hostnameIpAddress.
382*fcf3ce44SJohn Forte 		    id.ipAddress.ipAddress, &target_in.u_in6,
383*fcf3ce44SJohn Forte 		    sizeof (target_in.u_in6));
384*fcf3ce44SJohn Forte 
385*fcf3ce44SJohn Forte 		target_in_addr_size = sizeof (struct in6_addr);
386*fcf3ce44SJohn Forte 	} else {
387*fcf3ce44SJohn Forte 
388*fcf3ce44SJohn Forte 		bcopy(staticConfig.targetAddress.imaStruct.hostnameIpAddress.
389*fcf3ce44SJohn Forte 		    id.ipAddress.ipAddress, &target_in.u_in4,
390*fcf3ce44SJohn Forte 		    sizeof (target_in.u_in4));
391*fcf3ce44SJohn Forte 
392*fcf3ce44SJohn Forte 		target_in_addr_size = sizeof (struct in_addr);
393*fcf3ce44SJohn Forte 	}
394*fcf3ce44SJohn Forte 
395*fcf3ce44SJohn Forte 	(void) memset(&target, 0, sizeof (iscsi_target_entry_t));
396*fcf3ce44SJohn Forte 	target.te_entry.e_vers = ISCSI_INTERFACE_VERSION;
397*fcf3ce44SJohn Forte 	target.te_entry.e_oid = ISCSI_OID_NOTSET;
398*fcf3ce44SJohn Forte 
399*fcf3ce44SJohn Forte 	(void) wcstombs((char *)target.te_name, staticConfig.targetName,
400*fcf3ce44SJohn Forte 	    ISCSI_MAX_NAME_LEN);
401*fcf3ce44SJohn Forte 
402*fcf3ce44SJohn Forte 	target.te_entry.e_insize = target_in_addr_size;
403*fcf3ce44SJohn Forte 	if (target.te_entry.e_insize == sizeof (struct in_addr)) {
404*fcf3ce44SJohn Forte 		target.te_entry.e_u.u_in4.s_addr = target_in.u_in4.s_addr;
405*fcf3ce44SJohn Forte 	} else if (target.te_entry.e_insize == sizeof (struct in6_addr)) {
406*fcf3ce44SJohn Forte 		bcopy(target_in.u_in6.s6_addr,
407*fcf3ce44SJohn Forte 		    target.te_entry.e_u.u_in6.s6_addr,
408*fcf3ce44SJohn Forte 		    sizeof (struct in6_addr));
409*fcf3ce44SJohn Forte 	} else {
410*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
411*fcf3ce44SJohn Forte 	}
412*fcf3ce44SJohn Forte 
413*fcf3ce44SJohn Forte 	target.te_entry.e_port =
414*fcf3ce44SJohn Forte 	    staticConfig.targetAddress.imaStruct.portNumber;
415*fcf3ce44SJohn Forte 
416*fcf3ce44SJohn Forte 	if (staticConfig.targetAddress.defaultTpgt == IMA_TRUE) {
417*fcf3ce44SJohn Forte 		target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT;
418*fcf3ce44SJohn Forte 	} else {
419*fcf3ce44SJohn Forte 		target.te_entry.e_tpgt = staticConfig.targetAddress.tpgt;
420*fcf3ce44SJohn Forte 	}
421*fcf3ce44SJohn Forte 
422*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
423*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
424*fcf3ce44SJohn Forte 	}
425*fcf3ce44SJohn Forte 
426*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_STATIC_SET, &target)) {
427*fcf3ce44SJohn Forte 		/*
428*fcf3ce44SJohn Forte 		 * Encountered problem setting the IP address and port for
429*fcf3ce44SJohn Forte 		 * the target just added.
430*fcf3ce44SJohn Forte 		 */
431*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
432*fcf3ce44SJohn Forte 		    "ISCSI_STATIC_SET ioctl failed, errno: %d", errno);
433*fcf3ce44SJohn Forte 		(void) close(fd);
434*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
435*fcf3ce44SJohn Forte 	}
436*fcf3ce44SJohn Forte 
437*fcf3ce44SJohn Forte 	pTargetOid->objectType = IMA_OBJECT_TYPE_TARGET;
438*fcf3ce44SJohn Forte 	pTargetOid->ownerId = 1;
439*fcf3ce44SJohn Forte 	pTargetOid->objectSequenceNumber = target.te_entry.e_oid;
440*fcf3ce44SJohn Forte 
441*fcf3ce44SJohn Forte 	(void) close(fd);
442*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
443*fcf3ce44SJohn Forte }
444*fcf3ce44SJohn Forte 
445*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_GetTargetProperties(
446*fcf3ce44SJohn Forte 		IMA_OID targetId,
447*fcf3ce44SJohn Forte 		SUN_IMA_TARGET_PROPERTIES *pProps
448*fcf3ce44SJohn Forte )
449*fcf3ce44SJohn Forte {
450*fcf3ce44SJohn Forte 	int		    fd;
451*fcf3ce44SJohn Forte 	int			status;
452*fcf3ce44SJohn Forte 	iscsi_property_t    prop;
453*fcf3ce44SJohn Forte 
454*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
455*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
456*fcf3ce44SJohn Forte 	}
457*fcf3ce44SJohn Forte 
458*fcf3ce44SJohn Forte 	(void) memset(&prop, 0, sizeof (iscsi_property_t));
459*fcf3ce44SJohn Forte 	prop.p_vers = ISCSI_INTERFACE_VERSION;
460*fcf3ce44SJohn Forte 	prop.p_oid = (uint32_t)targetId.objectSequenceNumber;
461*fcf3ce44SJohn Forte 
462*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_TARGET_PROPS_GET, &prop) != 0) {
463*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
464*fcf3ce44SJohn Forte 		    "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
465*fcf3ce44SJohn Forte 		(void) close(fd);
466*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
467*fcf3ce44SJohn Forte 	}
468*fcf3ce44SJohn Forte 
469*fcf3ce44SJohn Forte 	(void) mbstowcs(pProps->imaProps.name,
470*fcf3ce44SJohn Forte 	    (char *)prop.p_name, IMA_NODE_NAME_LEN);
471*fcf3ce44SJohn Forte 	(void) memset(pProps->imaProps.alias, 0,
472*fcf3ce44SJohn Forte 	    (sizeof (IMA_WCHAR) * SUN_IMA_NODE_ALIAS_LEN));
473*fcf3ce44SJohn Forte 	if (prop.p_alias_len > 0) {
474*fcf3ce44SJohn Forte 		(void) mbstowcs(pProps->imaProps.alias, (char *)prop.p_alias,
475*fcf3ce44SJohn Forte 		    SUN_IMA_NODE_ALIAS_LEN);
476*fcf3ce44SJohn Forte 	}
477*fcf3ce44SJohn Forte 
478*fcf3ce44SJohn Forte 	/* Initialize the discovery method to unknown method. */
479*fcf3ce44SJohn Forte 	pProps->imaProps.discoveryMethodFlags =
480*fcf3ce44SJohn Forte 	    IMA_TARGET_DISCOVERY_METHOD_UNKNOWN;
481*fcf3ce44SJohn Forte 	if (!((prop.p_discovery & iSCSIDiscoveryMethodStatic) ^
482*fcf3ce44SJohn Forte 	    iSCSIDiscoveryMethodStatic)) {
483*fcf3ce44SJohn Forte 		pProps->imaProps.discoveryMethodFlags |=
484*fcf3ce44SJohn Forte 		    IMA_TARGET_DISCOVERY_METHOD_STATIC;
485*fcf3ce44SJohn Forte 	}
486*fcf3ce44SJohn Forte 
487*fcf3ce44SJohn Forte 	if (!((prop.p_discovery & iSCSIDiscoveryMethodSLP) ^
488*fcf3ce44SJohn Forte 	    iSCSIDiscoveryMethodSLP)) {
489*fcf3ce44SJohn Forte 		pProps->imaProps.discoveryMethodFlags |=
490*fcf3ce44SJohn Forte 		    IMA_TARGET_DISCOVERY_METHOD_SLP;
491*fcf3ce44SJohn Forte 	}
492*fcf3ce44SJohn Forte 
493*fcf3ce44SJohn Forte 	if (!((prop.p_discovery & iSCSIDiscoveryMethodISNS) ^
494*fcf3ce44SJohn Forte 	    iSCSIDiscoveryMethodISNS)) {
495*fcf3ce44SJohn Forte 		pProps->imaProps.discoveryMethodFlags |=
496*fcf3ce44SJohn Forte 		    iSCSIDiscoveryMethodISNS;
497*fcf3ce44SJohn Forte 	}
498*fcf3ce44SJohn Forte 
499*fcf3ce44SJohn Forte 	if (!((prop.p_discovery & iSCSIDiscoveryMethodSendTargets) ^
500*fcf3ce44SJohn Forte 	    iSCSIDiscoveryMethodSendTargets)) {
501*fcf3ce44SJohn Forte 		pProps->imaProps.discoveryMethodFlags |=
502*fcf3ce44SJohn Forte 		    iSCSIDiscoveryMethodSendTargets;
503*fcf3ce44SJohn Forte 	}
504*fcf3ce44SJohn Forte 
505*fcf3ce44SJohn Forte 	if (prop.p_tpgt_conf == ISCSI_DEFAULT_TPGT) {
506*fcf3ce44SJohn Forte 		pProps->defaultTpgtConf = IMA_TRUE;
507*fcf3ce44SJohn Forte 		pProps->tpgtConf = 0;
508*fcf3ce44SJohn Forte 	} else {
509*fcf3ce44SJohn Forte 		pProps->defaultTpgtConf = IMA_FALSE;
510*fcf3ce44SJohn Forte 		pProps->tpgtConf = prop.p_tpgt_conf;
511*fcf3ce44SJohn Forte 	}
512*fcf3ce44SJohn Forte 
513*fcf3ce44SJohn Forte 	if (prop.p_tpgt_nego == ISCSI_DEFAULT_TPGT) {
514*fcf3ce44SJohn Forte 		pProps->defaultTpgtNego = IMA_TRUE;
515*fcf3ce44SJohn Forte 		pProps->tpgtNego = 0;
516*fcf3ce44SJohn Forte 	} else {
517*fcf3ce44SJohn Forte 		pProps->defaultTpgtNego = IMA_FALSE;
518*fcf3ce44SJohn Forte 		pProps->tpgtNego = prop.p_tpgt_nego;
519*fcf3ce44SJohn Forte 	}
520*fcf3ce44SJohn Forte 
521*fcf3ce44SJohn Forte 	bcopy(prop.p_isid, pProps->isid, ISCSI_ISID_LEN);
522*fcf3ce44SJohn Forte 
523*fcf3ce44SJohn Forte 	(void) close(fd);
524*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
525*fcf3ce44SJohn Forte }
526*fcf3ce44SJohn Forte 
527*fcf3ce44SJohn Forte /*
528*fcf3ce44SJohn Forte  * This function only sets CHAP params since we only support CHAP for now.
529*fcf3ce44SJohn Forte  */
530*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_SetTargetAuthParams(
531*fcf3ce44SJohn Forte     IMA_OID targetOid,
532*fcf3ce44SJohn Forte     IMA_AUTHMETHOD method,
533*fcf3ce44SJohn Forte     const IMA_INITIATOR_AUTHPARMS *pParms
534*fcf3ce44SJohn Forte )
535*fcf3ce44SJohn Forte {
536*fcf3ce44SJohn Forte 	int fd;
537*fcf3ce44SJohn Forte 	iscsi_chap_props_t  chap_p;
538*fcf3ce44SJohn Forte 
539*fcf3ce44SJohn Forte 	if (method != IMA_AUTHMETHOD_CHAP)
540*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
541*fcf3ce44SJohn Forte 
542*fcf3ce44SJohn Forte 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
543*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
544*fcf3ce44SJohn Forte 		    ISCSI_DRIVER_DEVCTL, errno);
545*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
546*fcf3ce44SJohn Forte 	}
547*fcf3ce44SJohn Forte 
548*fcf3ce44SJohn Forte 	(void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
549*fcf3ce44SJohn Forte 	chap_p.c_vers = ISCSI_INTERFACE_VERSION;
550*fcf3ce44SJohn Forte 	chap_p.c_oid = (uint32_t)targetOid.objectSequenceNumber;
551*fcf3ce44SJohn Forte 
552*fcf3ce44SJohn Forte 	chap_p.c_user_len =
553*fcf3ce44SJohn Forte 	    pParms->chapParms.nameLength;
554*fcf3ce44SJohn Forte 	(void) memcpy(chap_p.c_user,
555*fcf3ce44SJohn Forte 	    pParms->chapParms.name, chap_p.c_user_len);
556*fcf3ce44SJohn Forte 
557*fcf3ce44SJohn Forte 	chap_p.c_secret_len =
558*fcf3ce44SJohn Forte 	    pParms->chapParms.challengeSecretLength;
559*fcf3ce44SJohn Forte 	(void) memcpy(chap_p.c_secret,
560*fcf3ce44SJohn Forte 	    pParms->chapParms.challengeSecret,
561*fcf3ce44SJohn Forte 	    chap_p.c_secret_len);
562*fcf3ce44SJohn Forte 
563*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_CHAP_SET, &chap_p) != 0) {
564*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
565*fcf3ce44SJohn Forte 		    "ISCSI_CHAP_SET ioctl failed, errno: %d", errno);
566*fcf3ce44SJohn Forte 		(void) close(fd);
567*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
568*fcf3ce44SJohn Forte 	}
569*fcf3ce44SJohn Forte 
570*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
571*fcf3ce44SJohn Forte }
572*fcf3ce44SJohn Forte 
573*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_GetTargetAuthMethods(
574*fcf3ce44SJohn Forte     IMA_OID		lhbaOid,
575*fcf3ce44SJohn Forte     IMA_OID		targetOid,
576*fcf3ce44SJohn Forte     IMA_UINT	*pMethodCount,
577*fcf3ce44SJohn Forte     IMA_AUTHMETHOD *pMethodList
578*fcf3ce44SJohn Forte )
579*fcf3ce44SJohn Forte {
580*fcf3ce44SJohn Forte 	if (getAuthMethods(targetOid, pMethodCount, pMethodList)
581*fcf3ce44SJohn Forte 	    != IMA_STATUS_SUCCESS) {
582*fcf3ce44SJohn Forte 		return (getAuthMethods(lhbaOid, pMethodCount, pMethodList));
583*fcf3ce44SJohn Forte 	}
584*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
585*fcf3ce44SJohn Forte }
586*fcf3ce44SJohn Forte 
587*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_SetInitiatorRadiusConfig(
588*fcf3ce44SJohn Forte 		IMA_OID	lhbaOid,
589*fcf3ce44SJohn Forte 		SUN_IMA_RADIUS_CONFIG *config
590*fcf3ce44SJohn Forte )
591*fcf3ce44SJohn Forte {
592*fcf3ce44SJohn Forte 	int			af;
593*fcf3ce44SJohn Forte 	int			fd;
594*fcf3ce44SJohn Forte 	int			status;
595*fcf3ce44SJohn Forte 	iscsi_radius_props_t	radius;
596*fcf3ce44SJohn Forte 	union {
597*fcf3ce44SJohn Forte 		struct in_addr	u_in4;
598*fcf3ce44SJohn Forte 		struct in6_addr	u_in6;
599*fcf3ce44SJohn Forte 	}	radius_in;
600*fcf3ce44SJohn Forte 
601*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
602*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
603*fcf3ce44SJohn Forte 	}
604*fcf3ce44SJohn Forte 
605*fcf3ce44SJohn Forte 	(void) memset(&radius, 0, sizeof (iscsi_radius_props_t));
606*fcf3ce44SJohn Forte 	radius.r_vers = ISCSI_INTERFACE_VERSION;
607*fcf3ce44SJohn Forte 	radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber;
608*fcf3ce44SJohn Forte 	/* Get first because other data fields may already exist */
609*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) {
610*fcf3ce44SJohn Forte 		/* EMPTY */
611*fcf3ce44SJohn Forte 		/* It's fine if other data fields are not there. */
612*fcf3ce44SJohn Forte 	}
613*fcf3ce44SJohn Forte 
614*fcf3ce44SJohn Forte 	if (config->isIpv6 == IMA_TRUE) {
615*fcf3ce44SJohn Forte 		af = AF_INET6;
616*fcf3ce44SJohn Forte 	} else {
617*fcf3ce44SJohn Forte 		af = AF_INET;
618*fcf3ce44SJohn Forte 	}
619*fcf3ce44SJohn Forte 
620*fcf3ce44SJohn Forte 	if (inet_pton(af, config->hostnameIpAddress, &radius_in.u_in4) != 1) {
621*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
622*fcf3ce44SJohn Forte 	}
623*fcf3ce44SJohn Forte 
624*fcf3ce44SJohn Forte 	switch (af) {
625*fcf3ce44SJohn Forte 		case AF_INET:
626*fcf3ce44SJohn Forte 			radius.r_addr.u_in4.s_addr = radius_in.u_in4.s_addr;
627*fcf3ce44SJohn Forte 			radius.r_insize = sizeof (struct in_addr);
628*fcf3ce44SJohn Forte 			break;
629*fcf3ce44SJohn Forte 		case AF_INET6:
630*fcf3ce44SJohn Forte 			(void) memcpy(radius.r_addr.u_in6.s6_addr,
631*fcf3ce44SJohn Forte 			    radius_in.u_in6.s6_addr, 16);
632*fcf3ce44SJohn Forte 			radius.r_insize = sizeof (struct in6_addr);
633*fcf3ce44SJohn Forte 			break;
634*fcf3ce44SJohn Forte 	}
635*fcf3ce44SJohn Forte 	radius.r_port = config->port;
636*fcf3ce44SJohn Forte 	radius.r_radius_config_valid = B_TRUE;
637*fcf3ce44SJohn Forte 	/* Allow resetting the RADIUS shared secret to NULL */
638*fcf3ce44SJohn Forte 	if (config->sharedSecretValid == IMA_TRUE) {
639*fcf3ce44SJohn Forte 		radius.r_shared_secret_len = config->sharedSecretLength;
640*fcf3ce44SJohn Forte 		(void) memset(&radius.r_shared_secret[0], 0,
641*fcf3ce44SJohn Forte 		    MAX_RAD_SHARED_SECRET_LEN);
642*fcf3ce44SJohn Forte 		(void) memcpy(&radius.r_shared_secret[0], config->sharedSecret,
643*fcf3ce44SJohn Forte 		    config->sharedSecretLength);
644*fcf3ce44SJohn Forte 	}
645*fcf3ce44SJohn Forte 
646*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_RADIUS_SET, &radius) != 0) {
647*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
648*fcf3ce44SJohn Forte 		    "ISCSI_RADIUS_SET ioctl failed, errno: %d", errno);
649*fcf3ce44SJohn Forte 		(void) close(fd);
650*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
651*fcf3ce44SJohn Forte 	}
652*fcf3ce44SJohn Forte 
653*fcf3ce44SJohn Forte 	(void) close(fd);
654*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
655*fcf3ce44SJohn Forte }
656*fcf3ce44SJohn Forte 
657*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_GetInitiatorRadiusConfig(
658*fcf3ce44SJohn Forte 		IMA_OID	lhbaOid,
659*fcf3ce44SJohn Forte 		SUN_IMA_RADIUS_CONFIG *config
660*fcf3ce44SJohn Forte )
661*fcf3ce44SJohn Forte {
662*fcf3ce44SJohn Forte 	int			af;
663*fcf3ce44SJohn Forte 	int			fd;
664*fcf3ce44SJohn Forte 	int			status;
665*fcf3ce44SJohn Forte 	iscsi_radius_props_t	radius;
666*fcf3ce44SJohn Forte 
667*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
668*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
669*fcf3ce44SJohn Forte 	}
670*fcf3ce44SJohn Forte 
671*fcf3ce44SJohn Forte 	(void) memset(&radius, 0, sizeof (iscsi_radius_props_t));
672*fcf3ce44SJohn Forte 	radius.r_vers = ISCSI_INTERFACE_VERSION;
673*fcf3ce44SJohn Forte 	radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber;
674*fcf3ce44SJohn Forte 
675*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) {
676*fcf3ce44SJohn Forte 		(void) close(fd);
677*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
678*fcf3ce44SJohn Forte 	}
679*fcf3ce44SJohn Forte 
680*fcf3ce44SJohn Forte 	(void) memset(config, 0, sizeof (SUN_IMA_RADIUS_CONFIG));
681*fcf3ce44SJohn Forte 	if (radius.r_insize == sizeof (struct in_addr)) {
682*fcf3ce44SJohn Forte 		/* IPv4 */
683*fcf3ce44SJohn Forte 		af = AF_INET;
684*fcf3ce44SJohn Forte 	} else if (radius.r_insize == sizeof (struct in6_addr)) {
685*fcf3ce44SJohn Forte 		/* IPv6 */
686*fcf3ce44SJohn Forte 		af = AF_INET6;
687*fcf3ce44SJohn Forte 	} else {
688*fcf3ce44SJohn Forte 		/*
689*fcf3ce44SJohn Forte 		 * It's legitimate that the existing RADIUS record does not
690*fcf3ce44SJohn Forte 		 * have configuration data.
691*fcf3ce44SJohn Forte 		 */
692*fcf3ce44SJohn Forte 		config->hostnameIpAddress[0] = '\0';
693*fcf3ce44SJohn Forte 		config->port = 0;
694*fcf3ce44SJohn Forte 		(void) close(fd);
695*fcf3ce44SJohn Forte 		return (IMA_STATUS_SUCCESS);
696*fcf3ce44SJohn Forte 	}
697*fcf3ce44SJohn Forte 	(void) inet_ntop(af, (void *)&radius.r_addr.u_in4,
698*fcf3ce44SJohn Forte 	    config->hostnameIpAddress, 256);
699*fcf3ce44SJohn Forte 	config->port = radius.r_port;
700*fcf3ce44SJohn Forte 	(void) memcpy(config->sharedSecret, &radius.r_shared_secret[0],
701*fcf3ce44SJohn Forte 	    radius.r_shared_secret_len);
702*fcf3ce44SJohn Forte 	config->sharedSecretLength = radius.r_shared_secret_len;
703*fcf3ce44SJohn Forte 	config->sharedSecretValid = B_TRUE;
704*fcf3ce44SJohn Forte 
705*fcf3ce44SJohn Forte 	(void) close(fd);
706*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
707*fcf3ce44SJohn Forte }
708*fcf3ce44SJohn Forte 
709*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_SetInitiatorRadiusAccess(
710*fcf3ce44SJohn Forte     IMA_OID lhbaOid,
711*fcf3ce44SJohn Forte     IMA_BOOL radiusAccess
712*fcf3ce44SJohn Forte )
713*fcf3ce44SJohn Forte {
714*fcf3ce44SJohn Forte 	int			fd;
715*fcf3ce44SJohn Forte 	int			status;
716*fcf3ce44SJohn Forte 	iscsi_radius_props_t	radius;
717*fcf3ce44SJohn Forte 
718*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
719*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
720*fcf3ce44SJohn Forte 	}
721*fcf3ce44SJohn Forte 
722*fcf3ce44SJohn Forte 	(void) memset(&radius, 0, sizeof (iscsi_radius_props_t));
723*fcf3ce44SJohn Forte 	radius.r_vers = ISCSI_INTERFACE_VERSION;
724*fcf3ce44SJohn Forte 	radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber;
725*fcf3ce44SJohn Forte 	/* Get first because other data fields may already exist */
726*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) {
727*fcf3ce44SJohn Forte 		if (radiusAccess == IMA_TRUE) {
728*fcf3ce44SJohn Forte 			/*
729*fcf3ce44SJohn Forte 			 * Cannot enable RADIUS if no RADIUS configuration
730*fcf3ce44SJohn Forte 			 * can be found.
731*fcf3ce44SJohn Forte 			 */
732*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
733*fcf3ce44SJohn Forte 			    "RADIUS config data not found - "
734*fcf3ce44SJohn Forte 			    "cannot enable RADIUS, errno: %d", errno);
735*fcf3ce44SJohn Forte 			(void) close(fd);
736*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
737*fcf3ce44SJohn Forte 		} else {
738*fcf3ce44SJohn Forte 			/* EMPTY */
739*fcf3ce44SJohn Forte 			/* Otherwise it's fine to disable RADIUS */
740*fcf3ce44SJohn Forte 		}
741*fcf3ce44SJohn Forte 	}
742*fcf3ce44SJohn Forte 
743*fcf3ce44SJohn Forte 	if ((radius.r_insize != sizeof (struct in_addr)) &&
744*fcf3ce44SJohn Forte 		(radius.r_insize != sizeof (struct in6_addr))) {
745*fcf3ce44SJohn Forte 		/*
746*fcf3ce44SJohn Forte 		 * Cannot enable RADIUS if no RADIUS configuration
747*fcf3ce44SJohn Forte 		 * can be found.
748*fcf3ce44SJohn Forte 		 */
749*fcf3ce44SJohn Forte 		if (radiusAccess == IMA_TRUE) {
750*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
751*fcf3ce44SJohn Forte 				"RADIUS config data not found - "
752*fcf3ce44SJohn Forte 				"cannot enable RADIUS");
753*fcf3ce44SJohn Forte 			(void) close(fd);
754*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
755*fcf3ce44SJohn Forte 		}
756*fcf3ce44SJohn Forte 	}
757*fcf3ce44SJohn Forte 
758*fcf3ce44SJohn Forte 	radius.r_radius_access = (radiusAccess == IMA_TRUE) ?
759*fcf3ce44SJohn Forte 	    B_TRUE : B_FALSE;
760*fcf3ce44SJohn Forte 
761*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_RADIUS_SET, &radius) != 0) {
762*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
763*fcf3ce44SJohn Forte 		    "ISCSI_RADIUS_SET ioctl failed, errno: %d", errno);
764*fcf3ce44SJohn Forte 		(void) close(fd);
765*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
766*fcf3ce44SJohn Forte 	}
767*fcf3ce44SJohn Forte 
768*fcf3ce44SJohn Forte 	(void) close(fd);
769*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
770*fcf3ce44SJohn Forte }
771*fcf3ce44SJohn Forte 
772*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_GetInitiatorRadiusAccess(
773*fcf3ce44SJohn Forte     IMA_OID lhbaOid,
774*fcf3ce44SJohn Forte     IMA_BOOL *radiusAccess
775*fcf3ce44SJohn Forte )
776*fcf3ce44SJohn Forte {
777*fcf3ce44SJohn Forte 	int			fd;
778*fcf3ce44SJohn Forte 	int			status;
779*fcf3ce44SJohn Forte 	iscsi_radius_props_t	radius;
780*fcf3ce44SJohn Forte 
781*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
782*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
783*fcf3ce44SJohn Forte 	}
784*fcf3ce44SJohn Forte 
785*fcf3ce44SJohn Forte 	(void) memset(&radius, 0, sizeof (iscsi_radius_props_t));
786*fcf3ce44SJohn Forte 	radius.r_vers = ISCSI_INTERFACE_VERSION;
787*fcf3ce44SJohn Forte 	radius.r_oid = (uint32_t)lhbaOid.objectSequenceNumber;
788*fcf3ce44SJohn Forte 
789*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_RADIUS_GET, &radius) != 0) {
790*fcf3ce44SJohn Forte 		(void) close(fd);
791*fcf3ce44SJohn Forte 		if (errno == ENOENT) {
792*fcf3ce44SJohn Forte 			return (IMA_ERROR_OBJECT_NOT_FOUND);
793*fcf3ce44SJohn Forte 		} else {
794*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
795*fcf3ce44SJohn Forte 		}
796*fcf3ce44SJohn Forte 	}
797*fcf3ce44SJohn Forte 
798*fcf3ce44SJohn Forte 	*radiusAccess = (radius.r_radius_access == B_TRUE) ?
799*fcf3ce44SJohn Forte 	    IMA_TRUE : IMA_FALSE;
800*fcf3ce44SJohn Forte 
801*fcf3ce44SJohn Forte 	(void) close(fd);
802*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
803*fcf3ce44SJohn Forte }
804*fcf3ce44SJohn Forte 
805*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_SendTargets(
806*fcf3ce44SJohn Forte     IMA_NODE_NAME nodeName,
807*fcf3ce44SJohn Forte     IMA_TARGET_ADDRESS address,
808*fcf3ce44SJohn Forte     SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
809*fcf3ce44SJohn Forte )
810*fcf3ce44SJohn Forte {
811*fcf3ce44SJohn Forte 	char	*colonPos;
812*fcf3ce44SJohn Forte 	char	discAddrStr[256];
813*fcf3ce44SJohn Forte 	char	nodeNameStr[ISCSI_MAX_NAME_LEN];
814*fcf3ce44SJohn Forte 	int	fd;
815*fcf3ce44SJohn Forte 	int	ctr;
816*fcf3ce44SJohn Forte 	int	stl_sz;
817*fcf3ce44SJohn Forte 	int status;
818*fcf3ce44SJohn Forte 	iscsi_sendtgts_list_t	*stl_hdr = NULL;
819*fcf3ce44SJohn Forte 	IMA_BOOL		retry = IMA_TRUE;
820*fcf3ce44SJohn Forte 	/* LINTED */
821*fcf3ce44SJohn Forte 	IMA_IP_ADDRESS	    *ipAddr;
822*fcf3ce44SJohn Forte 
823*fcf3ce44SJohn Forte #define	SENDTGTS_DEFAULT_NUM_TARGETS	10
824*fcf3ce44SJohn Forte 
825*fcf3ce44SJohn Forte 	stl_sz = sizeof (*stl_hdr) + ((SENDTGTS_DEFAULT_NUM_TARGETS - 1) *
826*fcf3ce44SJohn Forte 	    sizeof (iscsi_sendtgts_entry_t));
827*fcf3ce44SJohn Forte 	stl_hdr = (iscsi_sendtgts_list_t *)calloc(1, stl_sz);
828*fcf3ce44SJohn Forte 	if (stl_hdr == NULL) {
829*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
830*fcf3ce44SJohn Forte 	}
831*fcf3ce44SJohn Forte 	stl_hdr->stl_entry.e_vers = ISCSI_INTERFACE_VERSION;
832*fcf3ce44SJohn Forte 	stl_hdr->stl_in_cnt = SENDTGTS_DEFAULT_NUM_TARGETS;
833*fcf3ce44SJohn Forte 
834*fcf3ce44SJohn Forte 	(void) wcstombs(nodeNameStr, nodeName, ISCSI_MAX_NAME_LEN);
835*fcf3ce44SJohn Forte 
836*fcf3ce44SJohn Forte 	colonPos = strchr(discAddrStr, ':');
837*fcf3ce44SJohn Forte 	if (colonPos == NULL) {
838*fcf3ce44SJohn Forte 		/* IPv4 */
839*fcf3ce44SJohn Forte 		stl_hdr->stl_entry.e_insize = sizeof (struct in_addr);
840*fcf3ce44SJohn Forte 	} else {
841*fcf3ce44SJohn Forte 		/* IPv6 */
842*fcf3ce44SJohn Forte 		stl_hdr->stl_entry.e_insize = sizeof (struct in6_addr);
843*fcf3ce44SJohn Forte 	}
844*fcf3ce44SJohn Forte 
845*fcf3ce44SJohn Forte 	ipAddr = &address.hostnameIpAddress.id.ipAddress;
846*fcf3ce44SJohn Forte 
847*fcf3ce44SJohn Forte 	bcopy(address.hostnameIpAddress.id.ipAddress.ipAddress,
848*fcf3ce44SJohn Forte 	    &stl_hdr->stl_entry.e_u, sizeof (ipAddr->ipAddress));
849*fcf3ce44SJohn Forte 
850*fcf3ce44SJohn Forte 	stl_hdr->stl_entry.e_port = address.portNumber;
851*fcf3ce44SJohn Forte 
852*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
853*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
854*fcf3ce44SJohn Forte 	}
855*fcf3ce44SJohn Forte 
856*fcf3ce44SJohn Forte retry_sendtgts:
857*fcf3ce44SJohn Forte 	/*
858*fcf3ce44SJohn Forte 	 * Issue ioctl to obtain the SendTargets list
859*fcf3ce44SJohn Forte 	 */
860*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_SENDTGTS_GET, stl_hdr) != 0) {
861*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
862*fcf3ce44SJohn Forte 		    "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno);
863*fcf3ce44SJohn Forte 		(void) close(fd);
864*fcf3ce44SJohn Forte 		free(stl_hdr);
865*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
866*fcf3ce44SJohn Forte 	}
867*fcf3ce44SJohn Forte 
868*fcf3ce44SJohn Forte 	/* check if all targets received */
869*fcf3ce44SJohn Forte 	if (stl_hdr->stl_in_cnt < stl_hdr->stl_out_cnt) {
870*fcf3ce44SJohn Forte 		if (retry == IMA_TRUE) {
871*fcf3ce44SJohn Forte 			stl_sz = sizeof (*stl_hdr) +
872*fcf3ce44SJohn Forte 			    ((stl_hdr->stl_out_cnt - 1) *
873*fcf3ce44SJohn Forte 			    sizeof (iscsi_sendtgts_entry_t));
874*fcf3ce44SJohn Forte 			stl_hdr = (iscsi_sendtgts_list_t *)
875*fcf3ce44SJohn Forte 			    realloc(stl_hdr, stl_sz);
876*fcf3ce44SJohn Forte 			if (stl_hdr == NULL) {
877*fcf3ce44SJohn Forte 				(void) close(fd);
878*fcf3ce44SJohn Forte 				return (IMA_ERROR_INSUFFICIENT_MEMORY);
879*fcf3ce44SJohn Forte 			}
880*fcf3ce44SJohn Forte 			stl_hdr->stl_in_cnt = stl_hdr->stl_out_cnt;
881*fcf3ce44SJohn Forte 			retry = IMA_FALSE;
882*fcf3ce44SJohn Forte 			goto retry_sendtgts;
883*fcf3ce44SJohn Forte 		} else {
884*fcf3ce44SJohn Forte 			/*
885*fcf3ce44SJohn Forte 			 * don't retry after 2 attempts.  The target list
886*fcf3ce44SJohn Forte 			 * shouldn't continue to growing. Justs continue
887*fcf3ce44SJohn Forte 			 * on and display what was found.
888*fcf3ce44SJohn Forte 			 */
889*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
890*fcf3ce44SJohn Forte 			    "ISCSI_SENDTGTS_GET overflow: "
891*fcf3ce44SJohn Forte 			    "failed to obtain all targets");
892*fcf3ce44SJohn Forte 			stl_hdr->stl_out_cnt = stl_hdr->stl_in_cnt;
893*fcf3ce44SJohn Forte 		}
894*fcf3ce44SJohn Forte 	}
895*fcf3ce44SJohn Forte 
896*fcf3ce44SJohn Forte 	(void) close(fd);
897*fcf3ce44SJohn Forte 
898*fcf3ce44SJohn Forte 	/* allocate for caller return buffer */
899*fcf3ce44SJohn Forte 	*ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1,
900*fcf3ce44SJohn Forte 	    sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) +
901*fcf3ce44SJohn Forte 	    stl_hdr->stl_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY));
902*fcf3ce44SJohn Forte 	if (*ppList == NULL) {
903*fcf3ce44SJohn Forte 		free(stl_hdr);
904*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
905*fcf3ce44SJohn Forte 	}
906*fcf3ce44SJohn Forte 
907*fcf3ce44SJohn Forte 	(*ppList)->keyCount = stl_hdr->stl_out_cnt;
908*fcf3ce44SJohn Forte 
909*fcf3ce44SJohn Forte 	for (ctr = 0; ctr < stl_hdr->stl_out_cnt; ctr++) {
910*fcf3ce44SJohn Forte 		(void) mbstowcs((*ppList)->keys[ctr].name,
911*fcf3ce44SJohn Forte 		    (char *)stl_hdr->stl_list[ctr].ste_name,
912*fcf3ce44SJohn Forte 		    IMA_NODE_NAME_LEN);
913*fcf3ce44SJohn Forte 
914*fcf3ce44SJohn Forte 		(*ppList)->keys[ctr].tpgt = stl_hdr->stl_list[ctr].ste_tpgt;
915*fcf3ce44SJohn Forte 
916*fcf3ce44SJohn Forte 		(*ppList)->keys[ctr].address.portNumber =
917*fcf3ce44SJohn Forte 		    stl_hdr->stl_list[ctr].ste_ipaddr.a_port;
918*fcf3ce44SJohn Forte 
919*fcf3ce44SJohn Forte 		if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize ==
920*fcf3ce44SJohn Forte 		    sizeof (struct in_addr)) {
921*fcf3ce44SJohn Forte 			(*ppList)->keys[ctr].address.ipAddress.ipv4Address =
922*fcf3ce44SJohn Forte 			    IMA_TRUE;
923*fcf3ce44SJohn Forte 		} else if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize ==
924*fcf3ce44SJohn Forte 		    sizeof (struct in6_addr)) {
925*fcf3ce44SJohn Forte 			(*ppList)->keys[ctr].address.ipAddress.ipv4Address =
926*fcf3ce44SJohn Forte 			    IMA_FALSE;
927*fcf3ce44SJohn Forte 		} else {
928*fcf3ce44SJohn Forte 			free(stl_hdr);
929*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
930*fcf3ce44SJohn Forte 		}
931*fcf3ce44SJohn Forte 
932*fcf3ce44SJohn Forte 		(void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress,
933*fcf3ce44SJohn Forte 		    &(stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_addr),
934*fcf3ce44SJohn Forte 		    stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize);
935*fcf3ce44SJohn Forte 	}
936*fcf3ce44SJohn Forte 	free(stl_hdr);
937*fcf3ce44SJohn Forte 
938*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
939*fcf3ce44SJohn Forte }
940*fcf3ce44SJohn Forte 
941*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_SetTargetBidirAuthFlag(
942*fcf3ce44SJohn Forte     IMA_OID targetOid,
943*fcf3ce44SJohn Forte     IMA_BOOL *bidirAuthFlag
944*fcf3ce44SJohn Forte )
945*fcf3ce44SJohn Forte {
946*fcf3ce44SJohn Forte 	int fd;
947*fcf3ce44SJohn Forte 	int status;
948*fcf3ce44SJohn Forte 	iscsi_auth_props_t auth;
949*fcf3ce44SJohn Forte 
950*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
951*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
952*fcf3ce44SJohn Forte 	}
953*fcf3ce44SJohn Forte 
954*fcf3ce44SJohn Forte 	(void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
955*fcf3ce44SJohn Forte 	auth.a_vers = ISCSI_INTERFACE_VERSION;
956*fcf3ce44SJohn Forte 	auth.a_oid = (uint32_t)targetOid.objectSequenceNumber;
957*fcf3ce44SJohn Forte 	/* Get first because other data fields may already exist */
958*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
959*fcf3ce44SJohn Forte 		/* EMPTY */
960*fcf3ce44SJohn Forte 		/* It is fine if there is no other data fields. */
961*fcf3ce44SJohn Forte 	}
962*fcf3ce44SJohn Forte 	auth.a_bi_auth = (*bidirAuthFlag == IMA_TRUE) ? B_TRUE : B_FALSE;
963*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) {
964*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
965*fcf3ce44SJohn Forte 		    "ISCSI_AUTH_SET ioctl failed, errno: %d", errno);
966*fcf3ce44SJohn Forte 		(void) close(fd);
967*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
968*fcf3ce44SJohn Forte 	}
969*fcf3ce44SJohn Forte 
970*fcf3ce44SJohn Forte 	(void) close(fd);
971*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
972*fcf3ce44SJohn Forte }
973*fcf3ce44SJohn Forte 
974*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_GetTargetBidirAuthFlag(
975*fcf3ce44SJohn Forte     IMA_OID targetOid,
976*fcf3ce44SJohn Forte     IMA_BOOL *bidirAuthFlag
977*fcf3ce44SJohn Forte )
978*fcf3ce44SJohn Forte {
979*fcf3ce44SJohn Forte 	int fd;
980*fcf3ce44SJohn Forte 	int status;
981*fcf3ce44SJohn Forte 	iscsi_auth_props_t auth;
982*fcf3ce44SJohn Forte 
983*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
984*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
985*fcf3ce44SJohn Forte 	}
986*fcf3ce44SJohn Forte 
987*fcf3ce44SJohn Forte 	(void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
988*fcf3ce44SJohn Forte 	auth.a_vers = ISCSI_INTERFACE_VERSION;
989*fcf3ce44SJohn Forte 	auth.a_oid = (uint32_t)targetOid.objectSequenceNumber;
990*fcf3ce44SJohn Forte 
991*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
992*fcf3ce44SJohn Forte 		(void) close(fd);
993*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
994*fcf3ce44SJohn Forte 	}
995*fcf3ce44SJohn Forte 
996*fcf3ce44SJohn Forte 	*bidirAuthFlag = (auth.a_bi_auth == B_TRUE) ?
997*fcf3ce44SJohn Forte 	    IMA_TRUE : IMA_FALSE;
998*fcf3ce44SJohn Forte 
999*fcf3ce44SJohn Forte 	(void) close(fd);
1000*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1001*fcf3ce44SJohn Forte }
1002*fcf3ce44SJohn Forte 
1003*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_CreateTargetOid(
1004*fcf3ce44SJohn Forte     IMA_NODE_NAME targetName,
1005*fcf3ce44SJohn Forte     IMA_OID *targetOid
1006*fcf3ce44SJohn Forte )
1007*fcf3ce44SJohn Forte {
1008*fcf3ce44SJohn Forte 	int	    fd;
1009*fcf3ce44SJohn Forte 	int		status;
1010*fcf3ce44SJohn Forte 	iscsi_oid_t oid;
1011*fcf3ce44SJohn Forte 
1012*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1013*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1014*fcf3ce44SJohn Forte 	}
1015*fcf3ce44SJohn Forte 
1016*fcf3ce44SJohn Forte 	(void) memset(&oid, 0, sizeof (iscsi_oid_t));
1017*fcf3ce44SJohn Forte 	(void) wcstombs((char *)oid.o_name, targetName, ISCSI_MAX_NAME_LEN);
1018*fcf3ce44SJohn Forte 	oid.o_tpgt = ISCSI_DEFAULT_TPGT;
1019*fcf3ce44SJohn Forte 	oid.o_vers = ISCSI_INTERFACE_VERSION;
1020*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_CREATE_OID, &oid) == -1) {
1021*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1022*fcf3ce44SJohn Forte 		    "ISCSI_CREATE_OID ioctl failed, errno: %d", errno);
1023*fcf3ce44SJohn Forte 		(void) close(fd);
1024*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1025*fcf3ce44SJohn Forte 	}
1026*fcf3ce44SJohn Forte 
1027*fcf3ce44SJohn Forte 	targetOid->objectType = IMA_OBJECT_TYPE_TARGET;
1028*fcf3ce44SJohn Forte 	targetOid->ownerId = 1;
1029*fcf3ce44SJohn Forte 	targetOid->objectSequenceNumber = oid.o_oid;
1030*fcf3ce44SJohn Forte 
1031*fcf3ce44SJohn Forte 	(void) close(fd);
1032*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1033*fcf3ce44SJohn Forte }
1034*fcf3ce44SJohn Forte 
1035*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_RemoveTargetParam(
1036*fcf3ce44SJohn Forte 		IMA_OID targetOid
1037*fcf3ce44SJohn Forte )
1038*fcf3ce44SJohn Forte {
1039*fcf3ce44SJohn Forte 	entry_t	entry;
1040*fcf3ce44SJohn Forte 	int	fd;
1041*fcf3ce44SJohn Forte 	int status;
1042*fcf3ce44SJohn Forte 	iscsi_auth_props_t auth_p;
1043*fcf3ce44SJohn Forte 	iscsi_chap_props_t chap_p;
1044*fcf3ce44SJohn Forte 
1045*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1046*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1047*fcf3ce44SJohn Forte 	}
1048*fcf3ce44SJohn Forte 
1049*fcf3ce44SJohn Forte 	(void) memset(&entry, 0, sizeof (entry_t));
1050*fcf3ce44SJohn Forte 	entry.e_vers = ISCSI_INTERFACE_VERSION;
1051*fcf3ce44SJohn Forte 	entry.e_oid = (uint32_t)targetOid.objectSequenceNumber;
1052*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_TARGET_PARAM_CLEAR, &entry)) {
1053*fcf3ce44SJohn Forte 		/*
1054*fcf3ce44SJohn Forte 		 * It could be that the target exists but the associated
1055*fcf3ce44SJohn Forte 		 * target_param does not, and that is legitimate.
1056*fcf3ce44SJohn Forte 		 */
1057*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1058*fcf3ce44SJohn Forte 		    "ISCSI_TARGET_PARAM_CLEAR ioctl failed, errno: %d", errno);
1059*fcf3ce44SJohn Forte 	}
1060*fcf3ce44SJohn Forte 
1061*fcf3ce44SJohn Forte 	/* Issue ISCSI_CHAP_CLEAR ioctl */
1062*fcf3ce44SJohn Forte 	(void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
1063*fcf3ce44SJohn Forte 	chap_p.c_vers = ISCSI_INTERFACE_VERSION;
1064*fcf3ce44SJohn Forte 	chap_p.c_oid = (uint32_t)targetOid.objectSequenceNumber;
1065*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_CHAP_CLEAR, &chap_p) != 0) {
1066*fcf3ce44SJohn Forte 		/*
1067*fcf3ce44SJohn Forte 		 * It could be that the CHAP of this target has never
1068*fcf3ce44SJohn Forte 		 * been set.
1069*fcf3ce44SJohn Forte 		 */
1070*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1071*fcf3ce44SJohn Forte 		    "ISCSI_CHAP_CLEAR ioctl failed, errno: %d", errno);
1072*fcf3ce44SJohn Forte 	}
1073*fcf3ce44SJohn Forte 
1074*fcf3ce44SJohn Forte 	/* Issue ISCSI_AUTH_CLEAR ioctl */
1075*fcf3ce44SJohn Forte 	(void) memset(&auth_p, 0, sizeof (iscsi_auth_props_t));
1076*fcf3ce44SJohn Forte 	auth_p.a_vers = ISCSI_INTERFACE_VERSION;
1077*fcf3ce44SJohn Forte 	auth_p.a_oid = (uint32_t)targetOid.objectSequenceNumber;
1078*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_CLEAR, &auth_p) != 0) {
1079*fcf3ce44SJohn Forte 		/*
1080*fcf3ce44SJohn Forte 		 * It could be that the auth data of this target has
1081*fcf3ce44SJohn Forte 		 * never been set.
1082*fcf3ce44SJohn Forte 		 */
1083*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1084*fcf3ce44SJohn Forte 		    "ISCSI_AUTH_CLEAR ioctl failed, errno: %d", errno);
1085*fcf3ce44SJohn Forte 	}
1086*fcf3ce44SJohn Forte 
1087*fcf3ce44SJohn Forte 	(void) close(fd);
1088*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1089*fcf3ce44SJohn Forte }
1090*fcf3ce44SJohn Forte 
1091*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_SetHeaderDigest(
1092*fcf3ce44SJohn Forte 	IMA_OID oid,
1093*fcf3ce44SJohn Forte 	IMA_UINT algorithmCount,
1094*fcf3ce44SJohn Forte 	const SUN_IMA_DIGEST_ALGORITHM *algorithmList
1095*fcf3ce44SJohn Forte )
1096*fcf3ce44SJohn Forte {
1097*fcf3ce44SJohn Forte 	IMA_MIN_MAX_VALUE mv;
1098*fcf3ce44SJohn Forte 	uint32_t digest_algorithm;
1099*fcf3ce44SJohn Forte 
1100*fcf3ce44SJohn Forte 	/* We only support one preference of digest algorithm. */
1101*fcf3ce44SJohn Forte 	if (algorithmCount > 1) {
1102*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1103*fcf3ce44SJohn Forte 		    "More than one digest algorithm specified.");
1104*fcf3ce44SJohn Forte 		return (IMA_ERROR_NOT_SUPPORTED);
1105*fcf3ce44SJohn Forte 	}
1106*fcf3ce44SJohn Forte 	switch (algorithmList[0]) {
1107*fcf3ce44SJohn Forte 	case SUN_IMA_DIGEST_NONE:
1108*fcf3ce44SJohn Forte 		digest_algorithm = ISCSI_DIGEST_NONE;
1109*fcf3ce44SJohn Forte 		break;
1110*fcf3ce44SJohn Forte 	case SUN_IMA_DIGEST_CRC32:
1111*fcf3ce44SJohn Forte 		digest_algorithm = ISCSI_DIGEST_CRC32C;
1112*fcf3ce44SJohn Forte 		break;
1113*fcf3ce44SJohn Forte 	default:
1114*fcf3ce44SJohn Forte 		digest_algorithm = ISCSI_DIGEST_NONE;
1115*fcf3ce44SJohn Forte 		break;
1116*fcf3ce44SJohn Forte 	}
1117*fcf3ce44SJohn Forte 	mv.currentValue = digest_algorithm;
1118*fcf3ce44SJohn Forte 	return (setISCSINodeParameter(MIN_MAX_PARAM, &oid, &mv,
1119*fcf3ce44SJohn Forte 	    ISCSI_LOGIN_PARAM_HEADER_DIGEST));
1120*fcf3ce44SJohn Forte }
1121*fcf3ce44SJohn Forte 
1122*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_SetDataDigest(
1123*fcf3ce44SJohn Forte 	IMA_OID oid,
1124*fcf3ce44SJohn Forte 	IMA_UINT algorithmCount,
1125*fcf3ce44SJohn Forte 	const SUN_IMA_DIGEST_ALGORITHM *algorithmList
1126*fcf3ce44SJohn Forte )
1127*fcf3ce44SJohn Forte {
1128*fcf3ce44SJohn Forte 	IMA_MIN_MAX_VALUE mv;
1129*fcf3ce44SJohn Forte 	uint32_t digest_algorithm;
1130*fcf3ce44SJohn Forte 
1131*fcf3ce44SJohn Forte 	/* We only support one preference of digest algorithm. */
1132*fcf3ce44SJohn Forte 	if (algorithmCount > 1) {
1133*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1134*fcf3ce44SJohn Forte 		    "More than one digest algorithm specified.");
1135*fcf3ce44SJohn Forte 		return (IMA_ERROR_NOT_SUPPORTED);
1136*fcf3ce44SJohn Forte 	}
1137*fcf3ce44SJohn Forte 	switch (algorithmList[0]) {
1138*fcf3ce44SJohn Forte 	case SUN_IMA_DIGEST_NONE:
1139*fcf3ce44SJohn Forte 		digest_algorithm = ISCSI_DIGEST_NONE;
1140*fcf3ce44SJohn Forte 		break;
1141*fcf3ce44SJohn Forte 	case SUN_IMA_DIGEST_CRC32:
1142*fcf3ce44SJohn Forte 		digest_algorithm = ISCSI_DIGEST_CRC32C;
1143*fcf3ce44SJohn Forte 		break;
1144*fcf3ce44SJohn Forte 	default:
1145*fcf3ce44SJohn Forte 		digest_algorithm = ISCSI_DIGEST_NONE;
1146*fcf3ce44SJohn Forte 		break;
1147*fcf3ce44SJohn Forte 	}
1148*fcf3ce44SJohn Forte 	mv.currentValue = digest_algorithm;
1149*fcf3ce44SJohn Forte 	return (setISCSINodeParameter(MIN_MAX_PARAM, &oid, &mv,
1150*fcf3ce44SJohn Forte 	    ISCSI_LOGIN_PARAM_DATA_DIGEST));
1151*fcf3ce44SJohn Forte }
1152*fcf3ce44SJohn Forte 
1153*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_GetHeaderDigest(
1154*fcf3ce44SJohn Forte 	IMA_OID oid,
1155*fcf3ce44SJohn Forte 	SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm
1156*fcf3ce44SJohn Forte )
1157*fcf3ce44SJohn Forte {
1158*fcf3ce44SJohn Forte 	return (getDigest(oid, ISCSI_LOGIN_PARAM_HEADER_DIGEST, algorithm));
1159*fcf3ce44SJohn Forte }
1160*fcf3ce44SJohn Forte 
1161*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_GetDataDigest(
1162*fcf3ce44SJohn Forte 	IMA_OID oid,
1163*fcf3ce44SJohn Forte 	SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm
1164*fcf3ce44SJohn Forte )
1165*fcf3ce44SJohn Forte {
1166*fcf3ce44SJohn Forte 	return (getDigest(oid, ISCSI_LOGIN_PARAM_DATA_DIGEST, algorithm));
1167*fcf3ce44SJohn Forte }
1168*fcf3ce44SJohn Forte 
1169*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_GetLuProperties(
1170*fcf3ce44SJohn Forte 		IMA_OID luId,
1171*fcf3ce44SJohn Forte 		SUN_IMA_LU_PROPERTIES *pProps
1172*fcf3ce44SJohn Forte )
1173*fcf3ce44SJohn Forte {
1174*fcf3ce44SJohn Forte 	IMA_STATUS		status;
1175*fcf3ce44SJohn Forte 	iscsi_lun_list_t	*pLunList;
1176*fcf3ce44SJohn Forte 	int			j;
1177*fcf3ce44SJohn Forte 	IMA_BOOL		lunMatch = IMA_FALSE;
1178*fcf3ce44SJohn Forte 	int			fd;
1179*fcf3ce44SJohn Forte 	int			openStatus;
1180*fcf3ce44SJohn Forte 	iscsi_lun_props_t	lun;
1181*fcf3ce44SJohn Forte 	di_devlink_handle_t	hdl;
1182*fcf3ce44SJohn Forte 
1183*fcf3ce44SJohn Forte 	if (luId.objectType != IMA_OBJECT_TYPE_LU) {
1184*fcf3ce44SJohn Forte 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1185*fcf3ce44SJohn Forte 	}
1186*fcf3ce44SJohn Forte 
1187*fcf3ce44SJohn Forte 	/*
1188*fcf3ce44SJohn Forte 	 * get list of lun oids for all targets
1189*fcf3ce44SJohn Forte 	 */
1190*fcf3ce44SJohn Forte 	status = get_target_lun_oid_list(NULL, &pLunList);
1191*fcf3ce44SJohn Forte 	if (!IMA_SUCCESS(status)) {
1192*fcf3ce44SJohn Forte 		return (status);
1193*fcf3ce44SJohn Forte 	}
1194*fcf3ce44SJohn Forte 	for (j = 0; j < pLunList->ll_out_cnt; j++) {
1195*fcf3ce44SJohn Forte 		/*
1196*fcf3ce44SJohn Forte 		 * for each lun, check if match is found
1197*fcf3ce44SJohn Forte 		 */
1198*fcf3ce44SJohn Forte 		if (pLunList->ll_luns[j].l_oid == luId.objectSequenceNumber) {
1199*fcf3ce44SJohn Forte 			/*
1200*fcf3ce44SJohn Forte 			 * match found, break out of lun loop
1201*fcf3ce44SJohn Forte 			 */
1202*fcf3ce44SJohn Forte 			lunMatch = IMA_TRUE;
1203*fcf3ce44SJohn Forte 			break;
1204*fcf3ce44SJohn Forte 		}
1205*fcf3ce44SJohn Forte 	}
1206*fcf3ce44SJohn Forte 
1207*fcf3ce44SJohn Forte 	if (lunMatch == IMA_TRUE) {
1208*fcf3ce44SJohn Forte 		(void) memset(&lun, 0, sizeof (iscsi_lun_props_t));
1209*fcf3ce44SJohn Forte 		lun.lp_vers = ISCSI_INTERFACE_VERSION;
1210*fcf3ce44SJohn Forte 		lun.lp_tgt_oid = pLunList->ll_luns[j].l_tgt_oid;
1211*fcf3ce44SJohn Forte 		lun.lp_oid = pLunList->ll_luns[j].l_oid;
1212*fcf3ce44SJohn Forte 	}
1213*fcf3ce44SJohn Forte 
1214*fcf3ce44SJohn Forte 	free(pLunList);
1215*fcf3ce44SJohn Forte 
1216*fcf3ce44SJohn Forte 	if (lunMatch == IMA_FALSE) {
1217*fcf3ce44SJohn Forte 		return (IMA_ERROR_OBJECT_NOT_FOUND);
1218*fcf3ce44SJohn Forte 	}
1219*fcf3ce44SJohn Forte 
1220*fcf3ce44SJohn Forte 	/*
1221*fcf3ce44SJohn Forte 	 * get lun properties
1222*fcf3ce44SJohn Forte 	 */
1223*fcf3ce44SJohn Forte 	if ((openStatus = open_driver(&fd))) {
1224*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | openStatus);
1225*fcf3ce44SJohn Forte 	}
1226*fcf3ce44SJohn Forte 
1227*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_LUN_PROPS_GET, &lun)) {
1228*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1229*fcf3ce44SJohn Forte 		    "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno);
1230*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1231*fcf3ce44SJohn Forte 	}
1232*fcf3ce44SJohn Forte 
1233*fcf3ce44SJohn Forte 	(void) close(fd);
1234*fcf3ce44SJohn Forte 
1235*fcf3ce44SJohn Forte 	/*
1236*fcf3ce44SJohn Forte 	 * set property values
1237*fcf3ce44SJohn Forte 	 */
1238*fcf3ce44SJohn Forte 	pProps->imaProps.associatedTargetOid.objectType =
1239*fcf3ce44SJohn Forte 	    IMA_OBJECT_TYPE_TARGET;
1240*fcf3ce44SJohn Forte 	pProps->imaProps.associatedTargetOid.ownerId = 1;
1241*fcf3ce44SJohn Forte 	pProps->imaProps.associatedTargetOid.objectSequenceNumber = lun.lp_oid;
1242*fcf3ce44SJohn Forte 	pProps->imaProps.targetLun = (IMA_UINT64)lun.lp_num;
1243*fcf3ce44SJohn Forte 	(void) strncpy(pProps->vendorId, lun.lp_vid, SUN_IMA_LU_VENDOR_ID_LEN);
1244*fcf3ce44SJohn Forte 	(void) strncpy(pProps->productId, lun.lp_pid,
1245*fcf3ce44SJohn Forte 	    SUN_IMA_LU_PRODUCT_ID_LEN);
1246*fcf3ce44SJohn Forte 	/*
1247*fcf3ce44SJohn Forte 	 * lun.lp_status is defined as
1248*fcf3ce44SJohn Forte 	 *	LunValid = 0
1249*fcf3ce44SJohn Forte 	 *	LunDoesNotExist = 1
1250*fcf3ce44SJohn Forte 	 * IMA_LU_PROPS.exposedtoOS is defined as an IMA_BOOL
1251*fcf3ce44SJohn Forte 	 *	IMA_TRUE = 1
1252*fcf3ce44SJohn Forte 	 *	IMA_FALSE = 0
1253*fcf3ce44SJohn Forte 	 */
1254*fcf3ce44SJohn Forte 	pProps->imaProps.exposedToOs = !lun.lp_status;
1255*fcf3ce44SJohn Forte 	if (gmtime_r(&lun.lp_time_online, &pProps->imaProps.timeExposedToOs)
1256*fcf3ce44SJohn Forte 	    == NULL) {
1257*fcf3ce44SJohn Forte 		(void) memset(&pProps->imaProps.timeExposedToOs, 0,
1258*fcf3ce44SJohn Forte 		    sizeof (pProps->imaProps.timeExposedToOs));
1259*fcf3ce44SJohn Forte 	}
1260*fcf3ce44SJohn Forte 
1261*fcf3ce44SJohn Forte 	if (lun.lp_status == LunValid) {
1262*fcf3ce44SJohn Forte 
1263*fcf3ce44SJohn Forte 		/* add minor device delimiter */
1264*fcf3ce44SJohn Forte 		(void) strcat(lun.lp_pathname, ":");
1265*fcf3ce44SJohn Forte 
1266*fcf3ce44SJohn Forte 		if ((strstr(lun.lp_pathname, "sd@") != NULL) ||
1267*fcf3ce44SJohn Forte 		    (strstr(lun.lp_pathname, "ssd@") != NULL) ||
1268*fcf3ce44SJohn Forte 		    (strstr(lun.lp_pathname, "disk@") != NULL)) {
1269*fcf3ce44SJohn Forte 			/*
1270*fcf3ce44SJohn Forte 			 * modify returned pathname to obtain the 2nd slice
1271*fcf3ce44SJohn Forte 			 * of the raw disk
1272*fcf3ce44SJohn Forte 			 */
1273*fcf3ce44SJohn Forte 			(void) strcat(lun.lp_pathname, "c,raw");
1274*fcf3ce44SJohn Forte 		}
1275*fcf3ce44SJohn Forte 
1276*fcf3ce44SJohn Forte 		/*
1277*fcf3ce44SJohn Forte 		 * Pathname returned by driver is the physical device path.
1278*fcf3ce44SJohn Forte 		 * This name needs to be converted to the OS device name.
1279*fcf3ce44SJohn Forte 		 */
1280*fcf3ce44SJohn Forte 		if (hdl = di_devlink_init(lun.lp_pathname, DI_MAKE_LINK)) {
1281*fcf3ce44SJohn Forte 			pProps->imaProps.osDeviceName[0] = L'\0';
1282*fcf3ce44SJohn Forte 			(void) di_devlink_walk(hdl, NULL, lun.lp_pathname,
1283*fcf3ce44SJohn Forte 			    DI_PRIMARY_LINK,
1284*fcf3ce44SJohn Forte 			    (void *)pProps->imaProps.osDeviceName,
1285*fcf3ce44SJohn Forte 			    get_lun_devlink);
1286*fcf3ce44SJohn Forte 			if (pProps->imaProps.osDeviceName[0] != L'\0') {
1287*fcf3ce44SJohn Forte 				/* OS device name synchronously made */
1288*fcf3ce44SJohn Forte 				pProps->imaProps.osDeviceNameValid = IMA_TRUE;
1289*fcf3ce44SJohn Forte 			} else {
1290*fcf3ce44SJohn Forte 				pProps->imaProps.osDeviceNameValid = IMA_FALSE;
1291*fcf3ce44SJohn Forte 			}
1292*fcf3ce44SJohn Forte 
1293*fcf3ce44SJohn Forte 			(void) di_devlink_fini(&hdl);
1294*fcf3ce44SJohn Forte 
1295*fcf3ce44SJohn Forte 		} else {
1296*fcf3ce44SJohn Forte 			pProps->imaProps.osDeviceNameValid = IMA_FALSE;
1297*fcf3ce44SJohn Forte 		}
1298*fcf3ce44SJohn Forte 
1299*fcf3ce44SJohn Forte 	} else {
1300*fcf3ce44SJohn Forte 		pProps->imaProps.osDeviceNameValid = IMA_FALSE;
1301*fcf3ce44SJohn Forte 	}
1302*fcf3ce44SJohn Forte 
1303*fcf3ce44SJohn Forte 	pProps->imaProps.osParallelIdsValid = IMA_FALSE;
1304*fcf3ce44SJohn Forte 
1305*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1306*fcf3ce44SJohn Forte }
1307*fcf3ce44SJohn Forte 
1308*fcf3ce44SJohn Forte #define	IMA_DISK_DEVICE_NAME_PREFIX	"/dev/rdsk/"
1309*fcf3ce44SJohn Forte #define	IMA_TAPE_DEVICE_NAME_PREFIX	"/dev/rmt/"
1310*fcf3ce44SJohn Forte 
1311*fcf3ce44SJohn Forte static int
1312*fcf3ce44SJohn Forte get_lun_devlink(di_devlink_t link, void *osDeviceName)
1313*fcf3ce44SJohn Forte {
1314*fcf3ce44SJohn Forte 	if ((strncmp(IMA_DISK_DEVICE_NAME_PREFIX, di_devlink_path(link),
1315*fcf3ce44SJohn Forte 	    strlen(IMA_DISK_DEVICE_NAME_PREFIX)) == 0) ||
1316*fcf3ce44SJohn Forte 	    (strncmp(IMA_TAPE_DEVICE_NAME_PREFIX, di_devlink_path(link),
1317*fcf3ce44SJohn Forte 	    strlen(IMA_TAPE_DEVICE_NAME_PREFIX)) == 0)) {
1318*fcf3ce44SJohn Forte 		(void) mbstowcs((wchar_t *)osDeviceName, di_devlink_path(link),
1319*fcf3ce44SJohn Forte 		    MAXPATHLEN);
1320*fcf3ce44SJohn Forte 		return (DI_WALK_TERMINATE);
1321*fcf3ce44SJohn Forte 	}
1322*fcf3ce44SJohn Forte 
1323*fcf3ce44SJohn Forte 	return (DI_WALK_CONTINUE);
1324*fcf3ce44SJohn Forte }
1325*fcf3ce44SJohn Forte 
1326*fcf3ce44SJohn Forte /*
1327*fcf3ce44SJohn Forte  * SUN_IMA_GetConnectionOidList -
1328*fcf3ce44SJohn Forte  *
1329*fcf3ce44SJohn Forte  * Non-IMA defined function.
1330*fcf3ce44SJohn Forte  */
1331*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_GetConnOidList(
1332*fcf3ce44SJohn Forte 	IMA_OID			*oid,
1333*fcf3ce44SJohn Forte 	IMA_OID_LIST		**ppList
1334*fcf3ce44SJohn Forte )
1335*fcf3ce44SJohn Forte {
1336*fcf3ce44SJohn Forte 	IMA_STATUS		imaStatus;
1337*fcf3ce44SJohn Forte 	IMA_OID_LIST		*imaOidList;
1338*fcf3ce44SJohn Forte 	iscsi_conn_list_t	*iscsiConnList = NULL;
1339*fcf3ce44SJohn Forte 	int			i;
1340*fcf3ce44SJohn Forte 	size_t			allocLen;
1341*fcf3ce44SJohn Forte 
1342*fcf3ce44SJohn Forte 	if ((lhbaObjectId.objectType == oid->objectType) &&
1343*fcf3ce44SJohn Forte 	    (lhbaObjectId.ownerId == oid->ownerId) &&
1344*fcf3ce44SJohn Forte 	    (lhbaObjectId.objectSequenceNumber == oid->objectSequenceNumber)) {
1345*fcf3ce44SJohn Forte 		imaStatus = getConnOidList(NULL, &iscsiConnList);
1346*fcf3ce44SJohn Forte 	} else {
1347*fcf3ce44SJohn Forte 		if (oid->objectType == IMA_OBJECT_TYPE_TARGET) {
1348*fcf3ce44SJohn Forte 			imaStatus = getConnOidList(oid, &iscsiConnList);
1349*fcf3ce44SJohn Forte 		} else {
1350*fcf3ce44SJohn Forte 			return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
1351*fcf3ce44SJohn Forte 		}
1352*fcf3ce44SJohn Forte 	}
1353*fcf3ce44SJohn Forte 	if (imaStatus != IMA_STATUS_SUCCESS) {
1354*fcf3ce44SJohn Forte 		return (imaStatus);
1355*fcf3ce44SJohn Forte 	}
1356*fcf3ce44SJohn Forte 
1357*fcf3ce44SJohn Forte 	/*
1358*fcf3ce44SJohn Forte 	 * Based on the results a SUN_IMA_CONN_LIST structure is allocated.
1359*fcf3ce44SJohn Forte 	 */
1360*fcf3ce44SJohn Forte 	allocLen  = iscsiConnList->cl_out_cnt * sizeof (IMA_OID);
1361*fcf3ce44SJohn Forte 	allocLen += sizeof (IMA_OID_LIST) - sizeof (IMA_OID);
1362*fcf3ce44SJohn Forte 	imaOidList = (IMA_OID_LIST *)calloc(1, allocLen);
1363*fcf3ce44SJohn Forte 
1364*fcf3ce44SJohn Forte 	if (imaOidList == NULL) {
1365*fcf3ce44SJohn Forte 		free(iscsiConnList);
1366*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
1367*fcf3ce44SJohn Forte 	}
1368*fcf3ce44SJohn Forte 
1369*fcf3ce44SJohn Forte 	/* The data is transfered from iscsiConnList to imaConnList. */
1370*fcf3ce44SJohn Forte 	imaOidList->oidCount = iscsiConnList->cl_out_cnt;
1371*fcf3ce44SJohn Forte 	for (i = 0; i < iscsiConnList->cl_out_cnt; i++) {
1372*fcf3ce44SJohn Forte 		imaOidList->oids[i].objectType = SUN_IMA_OBJECT_TYPE_CONN;
1373*fcf3ce44SJohn Forte 		imaOidList->oids[i].ownerId = 1;
1374*fcf3ce44SJohn Forte 		imaOidList->oids[i].objectSequenceNumber =
1375*fcf3ce44SJohn Forte 		    iscsiConnList->cl_list[i].c_oid;
1376*fcf3ce44SJohn Forte 	}
1377*fcf3ce44SJohn Forte 	/* The pointer to the SUN_IMA_CONN_LIST structure is returned. */
1378*fcf3ce44SJohn Forte 	*ppList = imaOidList;
1379*fcf3ce44SJohn Forte 
1380*fcf3ce44SJohn Forte 	free(iscsiConnList);
1381*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1382*fcf3ce44SJohn Forte }
1383*fcf3ce44SJohn Forte 
1384*fcf3ce44SJohn Forte /*
1385*fcf3ce44SJohn Forte  * SUN_IMA_GetConnProperties -
1386*fcf3ce44SJohn Forte  *
1387*fcf3ce44SJohn Forte  * Non-IMA defined function.
1388*fcf3ce44SJohn Forte  */
1389*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_GetConnProperties(
1390*fcf3ce44SJohn Forte 	IMA_OID			*connOid,
1391*fcf3ce44SJohn Forte 	SUN_IMA_CONN_PROPERTIES	**pProps
1392*fcf3ce44SJohn Forte )
1393*fcf3ce44SJohn Forte {
1394*fcf3ce44SJohn Forte 	iscsi_conn_list_t	*pConnList;
1395*fcf3ce44SJohn Forte 	iscsi_conn_props_t	*pConnProps;
1396*fcf3ce44SJohn Forte 	/* LINTED */
1397*fcf3ce44SJohn Forte 	struct sockaddr_in6	*addrIn6;
1398*fcf3ce44SJohn Forte 	/* LINTED */
1399*fcf3ce44SJohn Forte 	struct sockaddr_in	*addrIn;
1400*fcf3ce44SJohn Forte 	SUN_IMA_CONN_PROPERTIES	*pImaConnProps;
1401*fcf3ce44SJohn Forte 	IMA_STATUS		imaStatus;
1402*fcf3ce44SJohn Forte 	int			i;
1403*fcf3ce44SJohn Forte 
1404*fcf3ce44SJohn Forte 	/* If there is any error *pProps should be set to NULL */
1405*fcf3ce44SJohn Forte 	*pProps = NULL;
1406*fcf3ce44SJohn Forte 
1407*fcf3ce44SJohn Forte 	pImaConnProps = (SUN_IMA_CONN_PROPERTIES *)calloc(1,
1408*fcf3ce44SJohn Forte 	    sizeof (SUN_IMA_CONN_PROPERTIES));
1409*fcf3ce44SJohn Forte 
1410*fcf3ce44SJohn Forte 	if (pImaConnProps == NULL) {
1411*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
1412*fcf3ce44SJohn Forte 	}
1413*fcf3ce44SJohn Forte 
1414*fcf3ce44SJohn Forte 	imaStatus = getConnOidList(NULL, &pConnList);
1415*fcf3ce44SJohn Forte 
1416*fcf3ce44SJohn Forte 	if (imaStatus != IMA_STATUS_SUCCESS) {
1417*fcf3ce44SJohn Forte 		free(pImaConnProps);
1418*fcf3ce44SJohn Forte 		return (imaStatus);
1419*fcf3ce44SJohn Forte 	}
1420*fcf3ce44SJohn Forte 
1421*fcf3ce44SJohn Forte 	/*
1422*fcf3ce44SJohn Forte 	 * Walk the list returned to find our connection.
1423*fcf3ce44SJohn Forte 	 */
1424*fcf3ce44SJohn Forte 	for (i = 0; i < pConnList->cl_out_cnt; i++) {
1425*fcf3ce44SJohn Forte 
1426*fcf3ce44SJohn Forte 		if (pConnList->cl_list[i].c_oid ==
1427*fcf3ce44SJohn Forte 		    (uint32_t)connOid->objectSequenceNumber) {
1428*fcf3ce44SJohn Forte 
1429*fcf3ce44SJohn Forte 			/* This is our connection. */
1430*fcf3ce44SJohn Forte 			imaStatus = getConnProps(&pConnList->cl_list[i],
1431*fcf3ce44SJohn Forte 			    &pConnProps);
1432*fcf3ce44SJohn Forte 
1433*fcf3ce44SJohn Forte 			if (imaStatus != IMA_STATUS_SUCCESS) {
1434*fcf3ce44SJohn Forte 				free(pConnList);
1435*fcf3ce44SJohn Forte 				free(pImaConnProps);
1436*fcf3ce44SJohn Forte 				return (imaStatus);
1437*fcf3ce44SJohn Forte 			}
1438*fcf3ce44SJohn Forte 			pImaConnProps->connectionID = pConnProps->cp_cid;
1439*fcf3ce44SJohn Forte 
1440*fcf3ce44SJohn Forte 			/*
1441*fcf3ce44SJohn Forte 			 * Local Propeties
1442*fcf3ce44SJohn Forte 			 */
1443*fcf3ce44SJohn Forte 			if (pConnProps->cp_local.soa4.sin_family == AF_INET) {
1444*fcf3ce44SJohn Forte 
1445*fcf3ce44SJohn Forte 				pImaConnProps->local.ipAddress.ipv4Address =
1446*fcf3ce44SJohn Forte 				    IMA_TRUE;
1447*fcf3ce44SJohn Forte 				pImaConnProps->local.portNumber =
1448*fcf3ce44SJohn Forte 				    pConnProps->cp_local.soa4.sin_port;
1449*fcf3ce44SJohn Forte 				addrIn = &(pConnProps->cp_local.soa4);
1450*fcf3ce44SJohn Forte 				bcopy(&pConnProps->cp_local.soa4.sin_addr,
1451*fcf3ce44SJohn Forte 				    pImaConnProps->local.ipAddress.ipAddress,
1452*fcf3ce44SJohn Forte 				    sizeof (addrIn->sin_addr));
1453*fcf3ce44SJohn Forte 
1454*fcf3ce44SJohn Forte 			} else {
1455*fcf3ce44SJohn Forte 				pImaConnProps->local.ipAddress.ipv4Address =
1456*fcf3ce44SJohn Forte 				    IMA_FALSE;
1457*fcf3ce44SJohn Forte 				pImaConnProps->local.portNumber =
1458*fcf3ce44SJohn Forte 				    pConnProps->cp_local.soa6.sin6_port;
1459*fcf3ce44SJohn Forte 				addrIn6 = &(pConnProps->cp_local.soa6);
1460*fcf3ce44SJohn Forte 				bcopy(&pConnProps->cp_local.soa6.sin6_addr,
1461*fcf3ce44SJohn Forte 				    pImaConnProps->local.ipAddress.ipAddress,
1462*fcf3ce44SJohn Forte 				    sizeof (addrIn6->sin6_addr));
1463*fcf3ce44SJohn Forte 
1464*fcf3ce44SJohn Forte 			}
1465*fcf3ce44SJohn Forte 
1466*fcf3ce44SJohn Forte 			/*
1467*fcf3ce44SJohn Forte 			 * Peer Propeties
1468*fcf3ce44SJohn Forte 			 */
1469*fcf3ce44SJohn Forte 			if (pConnProps->cp_peer.soa4.sin_family == AF_INET) {
1470*fcf3ce44SJohn Forte 
1471*fcf3ce44SJohn Forte 				pImaConnProps->peer.ipAddress.ipv4Address =
1472*fcf3ce44SJohn Forte 				    IMA_TRUE;
1473*fcf3ce44SJohn Forte 				pImaConnProps->peer.portNumber =
1474*fcf3ce44SJohn Forte 				    pConnProps->cp_peer.soa4.sin_port;
1475*fcf3ce44SJohn Forte 				addrIn = &(pConnProps->cp_local.soa4);
1476*fcf3ce44SJohn Forte 				bcopy(&pConnProps->cp_peer.soa4.sin_addr,
1477*fcf3ce44SJohn Forte 				    pImaConnProps->peer.ipAddress.ipAddress,
1478*fcf3ce44SJohn Forte 				    sizeof (addrIn->sin_addr));
1479*fcf3ce44SJohn Forte 
1480*fcf3ce44SJohn Forte 			} else {
1481*fcf3ce44SJohn Forte 				pImaConnProps->peer.ipAddress.ipv4Address =
1482*fcf3ce44SJohn Forte 				    IMA_FALSE;
1483*fcf3ce44SJohn Forte 				pImaConnProps->peer.portNumber =
1484*fcf3ce44SJohn Forte 				    pConnProps->cp_peer.soa6.sin6_port;
1485*fcf3ce44SJohn Forte 
1486*fcf3ce44SJohn Forte 				addrIn6 = &pConnProps->cp_local.soa6;
1487*fcf3ce44SJohn Forte 				bcopy(&pConnProps->cp_peer.soa6.sin6_addr,
1488*fcf3ce44SJohn Forte 				    pImaConnProps->peer.ipAddress.ipAddress,
1489*fcf3ce44SJohn Forte 				    sizeof (addrIn6->sin6_addr));
1490*fcf3ce44SJohn Forte 			}
1491*fcf3ce44SJohn Forte 
1492*fcf3ce44SJohn Forte 
1493*fcf3ce44SJohn Forte 			pImaConnProps->valuesValid =
1494*fcf3ce44SJohn Forte 			    pConnProps->cp_params_valid;
1495*fcf3ce44SJohn Forte 			pImaConnProps->defaultTime2Retain =
1496*fcf3ce44SJohn Forte 			    pConnProps->cp_params.default_time_to_retain;
1497*fcf3ce44SJohn Forte 			pImaConnProps->defaultTime2Wait =
1498*fcf3ce44SJohn Forte 			    pConnProps->cp_params.default_time_to_wait;
1499*fcf3ce44SJohn Forte 			pImaConnProps->errorRecoveryLevel =
1500*fcf3ce44SJohn Forte 			    pConnProps->cp_params.error_recovery_level;
1501*fcf3ce44SJohn Forte 			pImaConnProps->firstBurstLength =
1502*fcf3ce44SJohn Forte 			    pConnProps->cp_params.first_burst_length;
1503*fcf3ce44SJohn Forte 			pImaConnProps->maxBurstLength =
1504*fcf3ce44SJohn Forte 			    pConnProps->cp_params.max_burst_length;
1505*fcf3ce44SJohn Forte 			pImaConnProps->maxConnections =
1506*fcf3ce44SJohn Forte 			    pConnProps->cp_params.max_connections;
1507*fcf3ce44SJohn Forte 			pImaConnProps->maxOutstandingR2T =
1508*fcf3ce44SJohn Forte 			    pConnProps->cp_params.max_outstanding_r2t;
1509*fcf3ce44SJohn Forte 			pImaConnProps->maxRecvDataSegmentLength =
1510*fcf3ce44SJohn Forte 			    pConnProps->cp_params.max_recv_data_seg_len;
1511*fcf3ce44SJohn Forte 
1512*fcf3ce44SJohn Forte 			pImaConnProps->dataPduInOrder =
1513*fcf3ce44SJohn Forte 			    pConnProps->cp_params.data_pdu_in_order;
1514*fcf3ce44SJohn Forte 			pImaConnProps->dataSequenceInOrder =
1515*fcf3ce44SJohn Forte 			    pConnProps->cp_params.data_sequence_in_order;
1516*fcf3ce44SJohn Forte 			pImaConnProps->immediateData =
1517*fcf3ce44SJohn Forte 			    pConnProps->cp_params.immediate_data;
1518*fcf3ce44SJohn Forte 			pImaConnProps->initialR2T =
1519*fcf3ce44SJohn Forte 			    pConnProps->cp_params.initial_r2t;
1520*fcf3ce44SJohn Forte 
1521*fcf3ce44SJohn Forte 			pImaConnProps->headerDigest =
1522*fcf3ce44SJohn Forte 			    pConnProps->cp_params.header_digest;
1523*fcf3ce44SJohn Forte 			pImaConnProps->dataDigest =
1524*fcf3ce44SJohn Forte 			    pConnProps->cp_params.data_digest;
1525*fcf3ce44SJohn Forte 
1526*fcf3ce44SJohn Forte 			free(pConnProps);
1527*fcf3ce44SJohn Forte 			break;
1528*fcf3ce44SJohn Forte 		}
1529*fcf3ce44SJohn Forte 	}
1530*fcf3ce44SJohn Forte 	free(pConnList);
1531*fcf3ce44SJohn Forte 	*pProps = pImaConnProps;
1532*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1533*fcf3ce44SJohn Forte }
1534*fcf3ce44SJohn Forte 
1535*fcf3ce44SJohn Forte 
1536*fcf3ce44SJohn Forte /*
1537*fcf3ce44SJohn Forte  * SUN_IMA_GetConfigSessions -
1538*fcf3ce44SJohn Forte  *
1539*fcf3ce44SJohn Forte  * Non-IMA defined function.
1540*fcf3ce44SJohn Forte  */
1541*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_GetConfigSessions(
1542*fcf3ce44SJohn Forte     IMA_OID targetOid,
1543*fcf3ce44SJohn Forte     SUN_IMA_CONFIG_SESSIONS **pConfigSessions
1544*fcf3ce44SJohn Forte )
1545*fcf3ce44SJohn Forte {
1546*fcf3ce44SJohn Forte 	int			fd;
1547*fcf3ce44SJohn Forte 	int			status;
1548*fcf3ce44SJohn Forte 	iscsi_config_sess_t	*ics;
1549*fcf3ce44SJohn Forte 	int			size, idx;
1550*fcf3ce44SJohn Forte 
1551*fcf3ce44SJohn Forte 	/* Allocate and setup initial buffer */
1552*fcf3ce44SJohn Forte 	size = sizeof (*ics);
1553*fcf3ce44SJohn Forte 	ics = (iscsi_config_sess_t *)calloc(1, size);
1554*fcf3ce44SJohn Forte 	if (ics == NULL) {
1555*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
1556*fcf3ce44SJohn Forte 	}
1557*fcf3ce44SJohn Forte 	ics->ics_ver = ISCSI_INTERFACE_VERSION;
1558*fcf3ce44SJohn Forte 	ics->ics_oid = targetOid.objectSequenceNumber;
1559*fcf3ce44SJohn Forte 	ics->ics_in  = 1;
1560*fcf3ce44SJohn Forte 
1561*fcf3ce44SJohn Forte 	/* Open driver devctl for ioctl */
1562*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1563*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1564*fcf3ce44SJohn Forte 	}
1565*fcf3ce44SJohn Forte 
1566*fcf3ce44SJohn Forte 	/* Issue ioctl request */
1567*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_GET_CONFIG_SESSIONS, ics) != 0) {
1568*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1569*fcf3ce44SJohn Forte 		    "ISCSI_GET_CONFIG_SESSIONS ioctl failed, errno: %d",
1570*fcf3ce44SJohn Forte 		    errno);
1571*fcf3ce44SJohn Forte 		(void) close(fd);
1572*fcf3ce44SJohn Forte 		free(ics);
1573*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1574*fcf3ce44SJohn Forte 	}
1575*fcf3ce44SJohn Forte 
1576*fcf3ce44SJohn Forte 	/* Check if we need to collect more information */
1577*fcf3ce44SJohn Forte 	idx = ics->ics_out;
1578*fcf3ce44SJohn Forte 	if (idx > 1) {
1579*fcf3ce44SJohn Forte 
1580*fcf3ce44SJohn Forte 		/* Free old buffer and reallocate re-sized buffer */
1581*fcf3ce44SJohn Forte 		free(ics);
1582*fcf3ce44SJohn Forte 		size = ISCSI_SESSION_CONFIG_SIZE(idx);
1583*fcf3ce44SJohn Forte 		ics = (iscsi_config_sess_t *)calloc(1, size);
1584*fcf3ce44SJohn Forte 		if (ics == NULL) {
1585*fcf3ce44SJohn Forte 			return (IMA_ERROR_INSUFFICIENT_MEMORY);
1586*fcf3ce44SJohn Forte 		}
1587*fcf3ce44SJohn Forte 		ics->ics_ver = ISCSI_INTERFACE_VERSION;
1588*fcf3ce44SJohn Forte 		ics->ics_oid = targetOid.objectSequenceNumber;
1589*fcf3ce44SJohn Forte 		ics->ics_in = idx;
1590*fcf3ce44SJohn Forte 
1591*fcf3ce44SJohn Forte 		/* Issue ioctl request */
1592*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_GET_CONFIG_SESSIONS, ics) != 0) {
1593*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
1594*fcf3ce44SJohn Forte 			    "ISCSI_GET_CONFIG_SESSIONS ioctl failed, errno: %d",
1595*fcf3ce44SJohn Forte 			    errno);
1596*fcf3ce44SJohn Forte 			(void) close(fd);
1597*fcf3ce44SJohn Forte 			free(ics);
1598*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1599*fcf3ce44SJohn Forte 		}
1600*fcf3ce44SJohn Forte 	}
1601*fcf3ce44SJohn Forte 	(void) close(fd);
1602*fcf3ce44SJohn Forte 
1603*fcf3ce44SJohn Forte 	/* Allocate output buffer */
1604*fcf3ce44SJohn Forte 	size = sizeof (SUN_IMA_CONFIG_SESSIONS) +
1605*fcf3ce44SJohn Forte 	    ((ics->ics_out - 1) * sizeof (IMA_ADDRESS_KEY));
1606*fcf3ce44SJohn Forte 	*pConfigSessions = (SUN_IMA_CONFIG_SESSIONS *)calloc(1, size);
1607*fcf3ce44SJohn Forte 	if ((*pConfigSessions) == NULL) {
1608*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
1609*fcf3ce44SJohn Forte 	}
1610*fcf3ce44SJohn Forte 
1611*fcf3ce44SJohn Forte 	/* Copy output information */
1612*fcf3ce44SJohn Forte 	(*pConfigSessions)->bound =
1613*fcf3ce44SJohn Forte 	    (ics->ics_bound == B_TRUE ?  IMA_TRUE : IMA_FALSE);
1614*fcf3ce44SJohn Forte 	(*pConfigSessions)->in = ics->ics_in;
1615*fcf3ce44SJohn Forte 	(*pConfigSessions)->out = ics->ics_out;
1616*fcf3ce44SJohn Forte 	for (idx = 0; idx < ics->ics_in; idx++) {
1617*fcf3ce44SJohn Forte 		if (ics->ics_bindings[idx].i_insize ==
1618*fcf3ce44SJohn Forte 		    sizeof (struct in_addr)) {
1619*fcf3ce44SJohn Forte 			(*pConfigSessions)->bindings[idx].ipAddress.
1620*fcf3ce44SJohn Forte 			    ipv4Address = IMA_TRUE;
1621*fcf3ce44SJohn Forte 			bcopy(&ics->ics_bindings[idx].i_addr.in4,
1622*fcf3ce44SJohn Forte 			    (*pConfigSessions)->bindings[idx].ipAddress.
1623*fcf3ce44SJohn Forte 			    ipAddress, sizeof (struct in_addr));
1624*fcf3ce44SJohn Forte 		} else {
1625*fcf3ce44SJohn Forte 			(*pConfigSessions)->bindings[idx].ipAddress.
1626*fcf3ce44SJohn Forte 			    ipv4Address = IMA_FALSE;
1627*fcf3ce44SJohn Forte 			bcopy(&ics->ics_bindings[idx].i_addr.in6,
1628*fcf3ce44SJohn Forte 			    (*pConfigSessions)->bindings[idx].ipAddress.
1629*fcf3ce44SJohn Forte 			    ipAddress, sizeof (struct in6_addr));
1630*fcf3ce44SJohn Forte 		}
1631*fcf3ce44SJohn Forte 	}
1632*fcf3ce44SJohn Forte 
1633*fcf3ce44SJohn Forte 	free(ics);
1634*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1635*fcf3ce44SJohn Forte }
1636*fcf3ce44SJohn Forte 
1637*fcf3ce44SJohn Forte /*
1638*fcf3ce44SJohn Forte  * SUN_IMA_SetConfigSessions -
1639*fcf3ce44SJohn Forte  *
1640*fcf3ce44SJohn Forte  * Non-IMA defined function.
1641*fcf3ce44SJohn Forte  */
1642*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_SetConfigSessions(
1643*fcf3ce44SJohn Forte     IMA_OID targetOid,
1644*fcf3ce44SJohn Forte     SUN_IMA_CONFIG_SESSIONS *pConfigSessions
1645*fcf3ce44SJohn Forte )
1646*fcf3ce44SJohn Forte {
1647*fcf3ce44SJohn Forte 	int		    fd;
1648*fcf3ce44SJohn Forte 	int		    status;
1649*fcf3ce44SJohn Forte 	iscsi_config_sess_t *ics;
1650*fcf3ce44SJohn Forte 	int		    idx, size;
1651*fcf3ce44SJohn Forte 
1652*fcf3ce44SJohn Forte 	/* verify allowed range of sessions */
1653*fcf3ce44SJohn Forte 	if ((pConfigSessions->in < ISCSI_MIN_CONFIG_SESSIONS) ||
1654*fcf3ce44SJohn Forte 	    (pConfigSessions->in > ISCSI_MAX_CONFIG_SESSIONS)) {
1655*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
1656*fcf3ce44SJohn Forte 	}
1657*fcf3ce44SJohn Forte 
1658*fcf3ce44SJohn Forte 	/* allocate record config_sess size */
1659*fcf3ce44SJohn Forte 	size = ISCSI_SESSION_CONFIG_SIZE(pConfigSessions->in);
1660*fcf3ce44SJohn Forte 	ics = (iscsi_config_sess_t *)malloc(size);
1661*fcf3ce44SJohn Forte 
1662*fcf3ce44SJohn Forte 	/* setup config_sess information */
1663*fcf3ce44SJohn Forte 	(void) memset(ics, 0, sizeof (iscsi_config_sess_t));
1664*fcf3ce44SJohn Forte 	ics->ics_ver = ISCSI_INTERFACE_VERSION;
1665*fcf3ce44SJohn Forte 	ics->ics_oid = targetOid.objectSequenceNumber;
1666*fcf3ce44SJohn Forte 	ics->ics_bound =
1667*fcf3ce44SJohn Forte 	    (pConfigSessions->bound == IMA_TRUE ?  B_TRUE : B_FALSE);
1668*fcf3ce44SJohn Forte 	ics->ics_in  = pConfigSessions->in;
1669*fcf3ce44SJohn Forte 	for (idx = 0; idx < ics->ics_in; idx++) {
1670*fcf3ce44SJohn Forte 		if (pConfigSessions->bindings[idx].ipAddress.
1671*fcf3ce44SJohn Forte 		    ipv4Address == IMA_TRUE) {
1672*fcf3ce44SJohn Forte 			ics->ics_bindings[idx].i_insize =
1673*fcf3ce44SJohn Forte 			    sizeof (struct in_addr);
1674*fcf3ce44SJohn Forte 			bcopy(pConfigSessions->bindings[idx].
1675*fcf3ce44SJohn Forte 			    ipAddress.ipAddress,
1676*fcf3ce44SJohn Forte 			    &ics->ics_bindings[idx].i_addr.in4,
1677*fcf3ce44SJohn Forte 			    sizeof (struct in_addr));
1678*fcf3ce44SJohn Forte 		} else {
1679*fcf3ce44SJohn Forte 			ics->ics_bindings[idx].i_insize =
1680*fcf3ce44SJohn Forte 			    sizeof (struct in6_addr);
1681*fcf3ce44SJohn Forte 			bcopy(pConfigSessions->bindings[idx].
1682*fcf3ce44SJohn Forte 			    ipAddress.ipAddress,
1683*fcf3ce44SJohn Forte 			    &ics->ics_bindings[idx].i_addr.in6,
1684*fcf3ce44SJohn Forte 			    sizeof (struct in6_addr));
1685*fcf3ce44SJohn Forte 		}
1686*fcf3ce44SJohn Forte 	}
1687*fcf3ce44SJohn Forte 
1688*fcf3ce44SJohn Forte 	/* open driver */
1689*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1690*fcf3ce44SJohn Forte 		free(ics);
1691*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1692*fcf3ce44SJohn Forte 	}
1693*fcf3ce44SJohn Forte 
1694*fcf3ce44SJohn Forte 	/* issue ioctl request */
1695*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_SET_CONFIG_SESSIONS, ics) != 0) {
1696*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1697*fcf3ce44SJohn Forte 		    "ISCSI_SET_CONFIG_SESSIONS ioctl failed, errno: %d",
1698*fcf3ce44SJohn Forte 		    errno);
1699*fcf3ce44SJohn Forte 		(void) close(fd);
1700*fcf3ce44SJohn Forte 		free(ics);
1701*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1702*fcf3ce44SJohn Forte 	}
1703*fcf3ce44SJohn Forte 	(void) close(fd);
1704*fcf3ce44SJohn Forte 	free(ics);
1705*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1706*fcf3ce44SJohn Forte }
1707*fcf3ce44SJohn Forte 
1708*fcf3ce44SJohn Forte /* A helper function to obtain iSCSI node parameters. */
1709*fcf3ce44SJohn Forte static IMA_STATUS
1710*fcf3ce44SJohn Forte getISCSINodeParameter(
1711*fcf3ce44SJohn Forte     int paramType,
1712*fcf3ce44SJohn Forte     IMA_OID *oid,
1713*fcf3ce44SJohn Forte     void *pProps,
1714*fcf3ce44SJohn Forte     uint32_t paramIndex
1715*fcf3ce44SJohn Forte )
1716*fcf3ce44SJohn Forte {
1717*fcf3ce44SJohn Forte 	int		    fd;
1718*fcf3ce44SJohn Forte 	int 		status;
1719*fcf3ce44SJohn Forte 	iscsi_param_get_t   pg;
1720*fcf3ce44SJohn Forte 
1721*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1722*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1723*fcf3ce44SJohn Forte 	}
1724*fcf3ce44SJohn Forte 
1725*fcf3ce44SJohn Forte 	(void) memset(&pg, 0, sizeof (iscsi_param_get_t));
1726*fcf3ce44SJohn Forte 	pg.g_vers = ISCSI_INTERFACE_VERSION;
1727*fcf3ce44SJohn Forte 	pg.g_oid = (uint32_t)oid->objectSequenceNumber;
1728*fcf3ce44SJohn Forte 	pg.g_param = paramIndex;
1729*fcf3ce44SJohn Forte 	pg.g_param_type = ISCSI_SESS_PARAM;
1730*fcf3ce44SJohn Forte 
1731*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) {
1732*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1733*fcf3ce44SJohn Forte 		    "ISCSI_PARAM_GET ioctl failed, errno: %d", errno);
1734*fcf3ce44SJohn Forte 		(void) close(fd);
1735*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1736*fcf3ce44SJohn Forte 	}
1737*fcf3ce44SJohn Forte 
1738*fcf3ce44SJohn Forte 	switch (paramType) {
1739*fcf3ce44SJohn Forte 		IMA_BOOL_VALUE *bp;
1740*fcf3ce44SJohn Forte 		IMA_MIN_MAX_VALUE *mp;
1741*fcf3ce44SJohn Forte 
1742*fcf3ce44SJohn Forte 		case MIN_MAX_PARAM:
1743*fcf3ce44SJohn Forte 			mp = (IMA_MIN_MAX_VALUE *)pProps;
1744*fcf3ce44SJohn Forte 
1745*fcf3ce44SJohn Forte 			mp->currentValueValid =
1746*fcf3ce44SJohn Forte 			    (pg.g_value.v_valid == B_TRUE) ?
1747*fcf3ce44SJohn Forte 			    IMA_TRUE : IMA_FALSE;
1748*fcf3ce44SJohn Forte 			mp->currentValue = pg.g_value.v_integer.i_current;
1749*fcf3ce44SJohn Forte 			mp->defaultValue = pg.g_value.v_integer.i_default;
1750*fcf3ce44SJohn Forte 			mp->minimumValue = pg.g_value.v_integer.i_min;
1751*fcf3ce44SJohn Forte 			mp->maximumValue = pg.g_value.v_integer.i_max;
1752*fcf3ce44SJohn Forte 			mp->incrementValue = pg.g_value.v_integer.i_incr;
1753*fcf3ce44SJohn Forte 			break;
1754*fcf3ce44SJohn Forte 
1755*fcf3ce44SJohn Forte 		case BOOL_PARAM:
1756*fcf3ce44SJohn Forte 			bp = (IMA_BOOL_VALUE *)pProps;
1757*fcf3ce44SJohn Forte 			bp->currentValueValid =
1758*fcf3ce44SJohn Forte 			    (pg.g_value.v_valid == B_TRUE) ?
1759*fcf3ce44SJohn Forte 			    IMA_TRUE : IMA_FALSE;
1760*fcf3ce44SJohn Forte 			bp->currentValue = pg.g_value.v_bool.b_current;
1761*fcf3ce44SJohn Forte 			bp->defaultValue = pg.g_value.v_bool.b_default;
1762*fcf3ce44SJohn Forte 			break;
1763*fcf3ce44SJohn Forte 
1764*fcf3ce44SJohn Forte 		default:
1765*fcf3ce44SJohn Forte 			break;
1766*fcf3ce44SJohn Forte 	}
1767*fcf3ce44SJohn Forte 
1768*fcf3ce44SJohn Forte 	/* Issue ISCSI_PARAM_GET ioctl again to obtain connection parameters. */
1769*fcf3ce44SJohn Forte 	pg.g_param_type = ISCSI_CONN_PARAM;
1770*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) {
1771*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1772*fcf3ce44SJohn Forte 		    "ISCSI_PARAM_GET ioctl failed, errno: %d", errno);
1773*fcf3ce44SJohn Forte 		(void) close(fd);
1774*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1775*fcf3ce44SJohn Forte 	}
1776*fcf3ce44SJohn Forte 
1777*fcf3ce44SJohn Forte 	(void) close(fd);
1778*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1779*fcf3ce44SJohn Forte }
1780*fcf3ce44SJohn Forte 
1781*fcf3ce44SJohn Forte /* A helper function to set iSCSI node parameters. */
1782*fcf3ce44SJohn Forte static IMA_STATUS
1783*fcf3ce44SJohn Forte setISCSINodeParameter(
1784*fcf3ce44SJohn Forte     int paramType,
1785*fcf3ce44SJohn Forte     IMA_OID *oid,
1786*fcf3ce44SJohn Forte     void *pProp,
1787*fcf3ce44SJohn Forte     uint32_t paramIndex
1788*fcf3ce44SJohn Forte )
1789*fcf3ce44SJohn Forte {
1790*fcf3ce44SJohn Forte 	int		    fd;
1791*fcf3ce44SJohn Forte 	int			status;
1792*fcf3ce44SJohn Forte 	iscsi_param_set_t   ps;
1793*fcf3ce44SJohn Forte 
1794*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1795*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1796*fcf3ce44SJohn Forte 	}
1797*fcf3ce44SJohn Forte 
1798*fcf3ce44SJohn Forte 	(void) memset(&ps, 0, sizeof (iscsi_param_set_t));
1799*fcf3ce44SJohn Forte 	ps.s_vers = ISCSI_INTERFACE_VERSION;
1800*fcf3ce44SJohn Forte 	ps.s_oid = (uint32_t)oid->objectSequenceNumber;
1801*fcf3ce44SJohn Forte 	ps.s_param = paramIndex;
1802*fcf3ce44SJohn Forte 
1803*fcf3ce44SJohn Forte 	switch (paramType) {
1804*fcf3ce44SJohn Forte 		IMA_BOOL_VALUE *bp;
1805*fcf3ce44SJohn Forte 		IMA_MIN_MAX_VALUE *mp;
1806*fcf3ce44SJohn Forte 
1807*fcf3ce44SJohn Forte 		case MIN_MAX_PARAM:
1808*fcf3ce44SJohn Forte 			mp = (IMA_MIN_MAX_VALUE *)pProp;
1809*fcf3ce44SJohn Forte 			ps.s_value.v_integer = mp->currentValue;
1810*fcf3ce44SJohn Forte 			break;
1811*fcf3ce44SJohn Forte 		case BOOL_PARAM:
1812*fcf3ce44SJohn Forte 			bp = (IMA_BOOL_VALUE *)pProp;
1813*fcf3ce44SJohn Forte 			ps.s_value.v_bool =
1814*fcf3ce44SJohn Forte 			    (bp->currentValue == IMA_TRUE) ?
1815*fcf3ce44SJohn Forte 			    B_TRUE : B_FALSE;
1816*fcf3ce44SJohn Forte 			break;
1817*fcf3ce44SJohn Forte 
1818*fcf3ce44SJohn Forte 		default:
1819*fcf3ce44SJohn Forte 			break;
1820*fcf3ce44SJohn Forte 	}
1821*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_PARAM_SET, &ps)) {
1822*fcf3ce44SJohn Forte 		(void) close(fd);
1823*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1824*fcf3ce44SJohn Forte 		    "ISCSI_PARAM_SET ioctl failed, errno: %d", errno);
1825*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1826*fcf3ce44SJohn Forte 	}
1827*fcf3ce44SJohn Forte 
1828*fcf3ce44SJohn Forte 	(void) close(fd);
1829*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
1830*fcf3ce44SJohn Forte }
1831*fcf3ce44SJohn Forte 
1832*fcf3ce44SJohn Forte static int
1833*fcf3ce44SJohn Forte prepare_discovery_entry(
1834*fcf3ce44SJohn Forte     SUN_IMA_TARGET_ADDRESS discoveryAddress,
1835*fcf3ce44SJohn Forte     entry_t *entry
1836*fcf3ce44SJohn Forte )
1837*fcf3ce44SJohn Forte {
1838*fcf3ce44SJohn Forte 	return (prepare_discovery_entry_IMA(discoveryAddress.imaStruct, entry));
1839*fcf3ce44SJohn Forte }
1840*fcf3ce44SJohn Forte 
1841*fcf3ce44SJohn Forte static int
1842*fcf3ce44SJohn Forte prepare_discovery_entry_IMA(
1843*fcf3ce44SJohn Forte     IMA_TARGET_ADDRESS discoveryAddress,
1844*fcf3ce44SJohn Forte     entry_t *entry
1845*fcf3ce44SJohn Forte )
1846*fcf3ce44SJohn Forte {
1847*fcf3ce44SJohn Forte 	(void) memset(entry, 0, sizeof (entry_t));
1848*fcf3ce44SJohn Forte 	entry->e_vers = ISCSI_INTERFACE_VERSION;
1849*fcf3ce44SJohn Forte 	entry->e_oid = ISCSI_OID_NOTSET;
1850*fcf3ce44SJohn Forte 
1851*fcf3ce44SJohn Forte 	if (discoveryAddress.hostnameIpAddress.id.ipAddress.
1852*fcf3ce44SJohn Forte 	    ipv4Address == IMA_FALSE) {
1853*fcf3ce44SJohn Forte 
1854*fcf3ce44SJohn Forte 		bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.
1855*fcf3ce44SJohn Forte 		    ipAddress, entry->e_u.u_in6.s6_addr,
1856*fcf3ce44SJohn Forte 		    sizeof (entry->e_u.u_in6.s6_addr));
1857*fcf3ce44SJohn Forte 
1858*fcf3ce44SJohn Forte 		entry->e_insize = sizeof (struct in6_addr);
1859*fcf3ce44SJohn Forte 	} else {
1860*fcf3ce44SJohn Forte 
1861*fcf3ce44SJohn Forte 		bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.
1862*fcf3ce44SJohn Forte 		    ipAddress, &entry->e_u.u_in4.s_addr,
1863*fcf3ce44SJohn Forte 		    sizeof (entry->e_u.u_in4.s_addr));
1864*fcf3ce44SJohn Forte 
1865*fcf3ce44SJohn Forte 		entry->e_insize = sizeof (struct in_addr);
1866*fcf3ce44SJohn Forte 	}
1867*fcf3ce44SJohn Forte 
1868*fcf3ce44SJohn Forte 	entry->e_port = discoveryAddress.portNumber;
1869*fcf3ce44SJohn Forte 	entry->e_tpgt = 0;
1870*fcf3ce44SJohn Forte 	return (DISC_ADDR_OK);
1871*fcf3ce44SJohn Forte }
1872*fcf3ce44SJohn Forte 
1873*fcf3ce44SJohn Forte static IMA_STATUS configure_discovery_method(
1874*fcf3ce44SJohn Forte     IMA_BOOL enable,
1875*fcf3ce44SJohn Forte     iSCSIDiscoveryMethod_t method
1876*fcf3ce44SJohn Forte )
1877*fcf3ce44SJohn Forte {
1878*fcf3ce44SJohn Forte 	int	fd, status;
1879*fcf3ce44SJohn Forte 
1880*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1881*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1882*fcf3ce44SJohn Forte 	}
1883*fcf3ce44SJohn Forte 
1884*fcf3ce44SJohn Forte 	if (enable == IMA_FALSE) {
1885*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_DISCOVERY_CLEAR, &method)) {
1886*fcf3ce44SJohn Forte 			status = errno;
1887*fcf3ce44SJohn Forte 			(void) close(fd);
1888*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
1889*fcf3ce44SJohn Forte 			    "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d",
1890*fcf3ce44SJohn Forte 			    status);
1891*fcf3ce44SJohn Forte 			if (status == EBUSY) {
1892*fcf3ce44SJohn Forte 				return (IMA_ERROR_LU_IN_USE);
1893*fcf3ce44SJohn Forte 			} else {
1894*fcf3ce44SJohn Forte 				return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1895*fcf3ce44SJohn Forte 			}
1896*fcf3ce44SJohn Forte 		}
1897*fcf3ce44SJohn Forte 
1898*fcf3ce44SJohn Forte 		(void) close(fd);
1899*fcf3ce44SJohn Forte 		return (IMA_STATUS_SUCCESS);
1900*fcf3ce44SJohn Forte 	} else {
1901*fcf3ce44SJohn Forte 		/* Set the discovery method */
1902*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_DISCOVERY_SET, &method)) {
1903*fcf3ce44SJohn Forte 			status = errno;
1904*fcf3ce44SJohn Forte 			(void) close(fd);
1905*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
1906*fcf3ce44SJohn Forte 			    "ISCSI_DISCOVERY_SET ioctl failed, errno: %d",
1907*fcf3ce44SJohn Forte 			    status);
1908*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1909*fcf3ce44SJohn Forte 		}
1910*fcf3ce44SJohn Forte 
1911*fcf3ce44SJohn Forte 		(void) close(fd);
1912*fcf3ce44SJohn Forte 		return (IMA_STATUS_SUCCESS);
1913*fcf3ce44SJohn Forte 	}
1914*fcf3ce44SJohn Forte }
1915*fcf3ce44SJohn Forte 
1916*fcf3ce44SJohn Forte /* LINTED E_STATIC_UNUSED */
1917*fcf3ce44SJohn Forte static IMA_BOOL authMethodMatch(
1918*fcf3ce44SJohn Forte     IMA_AUTHMETHOD matchingMethod,
1919*fcf3ce44SJohn Forte     IMA_AUTHMETHOD *methodList,
1920*fcf3ce44SJohn Forte     IMA_UINT maxEntries
1921*fcf3ce44SJohn Forte )
1922*fcf3ce44SJohn Forte {
1923*fcf3ce44SJohn Forte 	IMA_UINT i;
1924*fcf3ce44SJohn Forte 
1925*fcf3ce44SJohn Forte 	for (i = 0; i < maxEntries; i++) {
1926*fcf3ce44SJohn Forte 		if (methodList[i] == matchingMethod) {
1927*fcf3ce44SJohn Forte 			return (IMA_TRUE);
1928*fcf3ce44SJohn Forte 		}
1929*fcf3ce44SJohn Forte 	}
1930*fcf3ce44SJohn Forte 
1931*fcf3ce44SJohn Forte 	return (IMA_FALSE);
1932*fcf3ce44SJohn Forte }
1933*fcf3ce44SJohn Forte 
1934*fcf3ce44SJohn Forte static IMA_STATUS get_target_oid_list(
1935*fcf3ce44SJohn Forte     uint32_t targetListType,
1936*fcf3ce44SJohn Forte     IMA_OID_LIST **ppList)
1937*fcf3ce44SJohn Forte {
1938*fcf3ce44SJohn Forte 	int		    fd;
1939*fcf3ce44SJohn Forte 	int		    i;
1940*fcf3ce44SJohn Forte 	int		    target_list_size;
1941*fcf3ce44SJohn Forte 	int		    status;
1942*fcf3ce44SJohn Forte 	int		    out_cnt;
1943*fcf3ce44SJohn Forte 	iscsi_target_list_t *idlp;
1944*fcf3ce44SJohn Forte 
1945*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
1946*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
1947*fcf3ce44SJohn Forte 	}
1948*fcf3ce44SJohn Forte 
1949*fcf3ce44SJohn Forte 	idlp = (iscsi_target_list_t *)calloc(1, sizeof (iscsi_target_list_t));
1950*fcf3ce44SJohn Forte 	if (idlp == NULL) {
1951*fcf3ce44SJohn Forte 		(void) close(fd);
1952*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
1953*fcf3ce44SJohn Forte 	}
1954*fcf3ce44SJohn Forte 	idlp->tl_vers = ISCSI_INTERFACE_VERSION;
1955*fcf3ce44SJohn Forte 	idlp->tl_in_cnt = idlp->tl_out_cnt = 1;
1956*fcf3ce44SJohn Forte 	idlp->tl_tgt_list_type = targetListType;
1957*fcf3ce44SJohn Forte 
1958*fcf3ce44SJohn Forte 	/*
1959*fcf3ce44SJohn Forte 	 * Issue ioctl.  Space has been allocted for one entry.
1960*fcf3ce44SJohn Forte 	 * If more than one entry should be returned, we will re-issue the
1961*fcf3ce44SJohn Forte 	 * entry with the right amount of space allocted
1962*fcf3ce44SJohn Forte 	 */
1963*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) {
1964*fcf3ce44SJohn Forte 		(void) close(fd);
1965*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
1966*fcf3ce44SJohn Forte 		    "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
1967*fcf3ce44SJohn Forte 		    targetListType, errno);
1968*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1969*fcf3ce44SJohn Forte 	}
1970*fcf3ce44SJohn Forte 	if (idlp->tl_out_cnt > 1) {
1971*fcf3ce44SJohn Forte 		out_cnt = idlp->tl_out_cnt;
1972*fcf3ce44SJohn Forte 		free(idlp);
1973*fcf3ce44SJohn Forte 
1974*fcf3ce44SJohn Forte 		target_list_size = sizeof (iscsi_target_list_t);
1975*fcf3ce44SJohn Forte 		target_list_size += (sizeof (uint32_t) * out_cnt - 1);
1976*fcf3ce44SJohn Forte 		idlp = (iscsi_target_list_t *)calloc(1, target_list_size);
1977*fcf3ce44SJohn Forte 		if (idlp == NULL) {
1978*fcf3ce44SJohn Forte 			(void) close(fd);
1979*fcf3ce44SJohn Forte 			return (IMA_ERROR_INSUFFICIENT_MEMORY);
1980*fcf3ce44SJohn Forte 		}
1981*fcf3ce44SJohn Forte 		idlp->tl_vers = ISCSI_INTERFACE_VERSION;
1982*fcf3ce44SJohn Forte 		idlp->tl_in_cnt = out_cnt;
1983*fcf3ce44SJohn Forte 		idlp->tl_tgt_list_type = targetListType;
1984*fcf3ce44SJohn Forte 
1985*fcf3ce44SJohn Forte 		/* Issue the same ioctl again to obtain all the OIDs. */
1986*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) {
1987*fcf3ce44SJohn Forte #define	ERROR_STR "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno :%d"
1988*fcf3ce44SJohn Forte 			free(idlp);
1989*fcf3ce44SJohn Forte 			(void) close(fd);
1990*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
1991*fcf3ce44SJohn Forte 			    ERROR_STR, targetListType, errno);
1992*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
1993*fcf3ce44SJohn Forte #undef ERROR_STR
1994*fcf3ce44SJohn Forte 
1995*fcf3ce44SJohn Forte 		}
1996*fcf3ce44SJohn Forte 	}
1997*fcf3ce44SJohn Forte 
1998*fcf3ce44SJohn Forte 	*ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) +
1999*fcf3ce44SJohn Forte 	    idlp->tl_out_cnt * sizeof (IMA_OID));
2000*fcf3ce44SJohn Forte 	(*ppList)->oidCount = idlp->tl_out_cnt;
2001*fcf3ce44SJohn Forte 	for (i = 0; i < idlp->tl_out_cnt; i++) {
2002*fcf3ce44SJohn Forte 		(*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_TARGET;
2003*fcf3ce44SJohn Forte 		(*ppList)->oids[i].ownerId = 1;
2004*fcf3ce44SJohn Forte 		(*ppList)->oids[i].objectSequenceNumber = idlp->tl_oid_list[i];
2005*fcf3ce44SJohn Forte 	}
2006*fcf3ce44SJohn Forte 
2007*fcf3ce44SJohn Forte 	free(idlp);
2008*fcf3ce44SJohn Forte 	(void) close(fd);
2009*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2010*fcf3ce44SJohn Forte }
2011*fcf3ce44SJohn Forte 
2012*fcf3ce44SJohn Forte static IMA_STATUS get_target_lun_oid_list(
2013*fcf3ce44SJohn Forte     IMA_OID * targetOid,
2014*fcf3ce44SJohn Forte     iscsi_lun_list_t  **ppLunList)
2015*fcf3ce44SJohn Forte {
2016*fcf3ce44SJohn Forte 	int			fd;
2017*fcf3ce44SJohn Forte 	iscsi_lun_list_t	*illp, *illp_saved;
2018*fcf3ce44SJohn Forte 	int			lun_list_size;
2019*fcf3ce44SJohn Forte 	int			status;
2020*fcf3ce44SJohn Forte 
2021*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2022*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2023*fcf3ce44SJohn Forte 	}
2024*fcf3ce44SJohn Forte 
2025*fcf3ce44SJohn Forte 	illp = (iscsi_lun_list_t *)calloc(1, sizeof (iscsi_lun_list_t));
2026*fcf3ce44SJohn Forte 	if (illp == NULL) {
2027*fcf3ce44SJohn Forte 		(void) close(fd);
2028*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2029*fcf3ce44SJohn Forte 	}
2030*fcf3ce44SJohn Forte 	illp->ll_vers = ISCSI_INTERFACE_VERSION;
2031*fcf3ce44SJohn Forte 	if (targetOid == NULL) {
2032*fcf3ce44SJohn Forte 		/* get lun oid list for all targets */
2033*fcf3ce44SJohn Forte 		illp->ll_all_tgts = B_TRUE;
2034*fcf3ce44SJohn Forte 	} else {
2035*fcf3ce44SJohn Forte 		/* get lun oid list for single target */
2036*fcf3ce44SJohn Forte 		illp->ll_all_tgts = B_FALSE;
2037*fcf3ce44SJohn Forte 		illp->ll_tgt_oid = (uint32_t)targetOid->objectSequenceNumber;
2038*fcf3ce44SJohn Forte 	}
2039*fcf3ce44SJohn Forte 	illp->ll_in_cnt = illp->ll_out_cnt = 1;
2040*fcf3ce44SJohn Forte 
2041*fcf3ce44SJohn Forte 	/*
2042*fcf3ce44SJohn Forte 	 * Issue ioctl to retrieve the target luns.  Space has been allocted
2043*fcf3ce44SJohn Forte 	 * for one entry.  If more than one entry should be returned, we
2044*fcf3ce44SJohn Forte 	 * will re-issue the entry with the right amount of space allocted
2045*fcf3ce44SJohn Forte 	 */
2046*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) {
2047*fcf3ce44SJohn Forte 		(void) close(fd);
2048*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2049*fcf3ce44SJohn Forte 		    "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno);
2050*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2051*fcf3ce44SJohn Forte 	}
2052*fcf3ce44SJohn Forte 
2053*fcf3ce44SJohn Forte 	if (illp->ll_out_cnt > 1) {
2054*fcf3ce44SJohn Forte 		illp_saved = illp;
2055*fcf3ce44SJohn Forte 		lun_list_size = sizeof (iscsi_lun_list_t);
2056*fcf3ce44SJohn Forte 		lun_list_size += (sizeof (iscsi_if_lun_t) *
2057*fcf3ce44SJohn Forte 		    (illp->ll_out_cnt - 1));
2058*fcf3ce44SJohn Forte 		illp = (iscsi_lun_list_t *)calloc(1, lun_list_size);
2059*fcf3ce44SJohn Forte 		if (illp == NULL) {
2060*fcf3ce44SJohn Forte 			(void) close(fd);
2061*fcf3ce44SJohn Forte 			return (IMA_ERROR_INSUFFICIENT_MEMORY);
2062*fcf3ce44SJohn Forte 		}
2063*fcf3ce44SJohn Forte 		illp->ll_vers = ISCSI_INTERFACE_VERSION;
2064*fcf3ce44SJohn Forte 		illp->ll_all_tgts = illp_saved->ll_all_tgts;
2065*fcf3ce44SJohn Forte 		illp->ll_tgt_oid = illp_saved->ll_tgt_oid;
2066*fcf3ce44SJohn Forte 		illp->ll_in_cnt = illp_saved->ll_out_cnt;
2067*fcf3ce44SJohn Forte 
2068*fcf3ce44SJohn Forte 		free(illp_saved);
2069*fcf3ce44SJohn Forte 
2070*fcf3ce44SJohn Forte 		/* Issue the same ioctl again to get all the target LUN list */
2071*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) {
2072*fcf3ce44SJohn Forte 			free(illp);
2073*fcf3ce44SJohn Forte 			(void) close(fd);
2074*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
2075*fcf3ce44SJohn Forte 			    "ISCSI_LUN_LIST_GET ioctl failed, errno: %d",
2076*fcf3ce44SJohn Forte 			    errno);
2077*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2078*fcf3ce44SJohn Forte 
2079*fcf3ce44SJohn Forte 		}
2080*fcf3ce44SJohn Forte 	}
2081*fcf3ce44SJohn Forte 	*ppLunList = illp;
2082*fcf3ce44SJohn Forte 
2083*fcf3ce44SJohn Forte 
2084*fcf3ce44SJohn Forte 	(void) close(fd);
2085*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2086*fcf3ce44SJohn Forte }
2087*fcf3ce44SJohn Forte 
2088*fcf3ce44SJohn Forte /* A helper function to obtain digest algorithms. */
2089*fcf3ce44SJohn Forte static IMA_STATUS
2090*fcf3ce44SJohn Forte getDigest(
2091*fcf3ce44SJohn Forte     IMA_OID oid,
2092*fcf3ce44SJohn Forte     int ioctlCmd,
2093*fcf3ce44SJohn Forte     SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm
2094*fcf3ce44SJohn Forte )
2095*fcf3ce44SJohn Forte {
2096*fcf3ce44SJohn Forte 	IMA_MIN_MAX_VALUE pProps;
2097*fcf3ce44SJohn Forte 	IMA_STATUS status;
2098*fcf3ce44SJohn Forte 
2099*fcf3ce44SJohn Forte 	if ((status = getISCSINodeParameter(MIN_MAX_PARAM, &oid, &pProps,
2100*fcf3ce44SJohn Forte 	    ioctlCmd)) != IMA_STATUS_SUCCESS) {
2101*fcf3ce44SJohn Forte 		return (status);
2102*fcf3ce44SJohn Forte 	}
2103*fcf3ce44SJohn Forte 
2104*fcf3ce44SJohn Forte 	switch (pProps.defaultValue) {
2105*fcf3ce44SJohn Forte 		case ISCSI_DIGEST_NONE:
2106*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_NONE;
2107*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithmCount = 1;
2108*fcf3ce44SJohn Forte 			break;
2109*fcf3ce44SJohn Forte 		case ISCSI_DIGEST_CRC32C:
2110*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_CRC32C;
2111*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithmCount = 1;
2112*fcf3ce44SJohn Forte 			break;
2113*fcf3ce44SJohn Forte 
2114*fcf3ce44SJohn Forte 		case ISCSI_DIGEST_CRC32C_NONE:
2115*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_CRC32C;
2116*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithms[1] = ISCSI_DIGEST_NONE;
2117*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithmCount = 2;
2118*fcf3ce44SJohn Forte 			break;
2119*fcf3ce44SJohn Forte 		case ISCSI_DIGEST_NONE_CRC32C:
2120*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithms[0] = ISCSI_DIGEST_NONE;
2121*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithms[1] = ISCSI_DIGEST_CRC32C;
2122*fcf3ce44SJohn Forte 			algorithm->defaultAlgorithmCount = 2;
2123*fcf3ce44SJohn Forte 			break;
2124*fcf3ce44SJohn Forte 		default:
2125*fcf3ce44SJohn Forte 			/* Error */
2126*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
2127*fcf3ce44SJohn Forte 			    "Invalid default digest: %d", pProps.defaultValue);
2128*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2129*fcf3ce44SJohn Forte 	}
2130*fcf3ce44SJohn Forte 
2131*fcf3ce44SJohn Forte 	/* The configured value */
2132*fcf3ce44SJohn Forte 	if (pProps.currentValueValid == IMA_TRUE) {
2133*fcf3ce44SJohn Forte 		algorithm->currentValid = IMA_TRUE;
2134*fcf3ce44SJohn Forte 
2135*fcf3ce44SJohn Forte 		switch (pProps.currentValue) {
2136*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_NONE:
2137*fcf3ce44SJohn Forte 				algorithm->currentAlgorithms[0] =
2138*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_NONE;
2139*fcf3ce44SJohn Forte 				algorithm->currentAlgorithmCount = 1;
2140*fcf3ce44SJohn Forte 				break;
2141*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_CRC32C:
2142*fcf3ce44SJohn Forte 				algorithm->currentAlgorithms[0] =
2143*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_CRC32C;
2144*fcf3ce44SJohn Forte 				algorithm->currentAlgorithmCount = 1;
2145*fcf3ce44SJohn Forte 				break;
2146*fcf3ce44SJohn Forte 
2147*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_CRC32C_NONE:
2148*fcf3ce44SJohn Forte 				algorithm->currentAlgorithms[0] =
2149*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_CRC32C;
2150*fcf3ce44SJohn Forte 				algorithm->currentAlgorithms[1] =
2151*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_NONE;
2152*fcf3ce44SJohn Forte 				algorithm->currentAlgorithmCount = 2;
2153*fcf3ce44SJohn Forte 				break;
2154*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_NONE_CRC32C:
2155*fcf3ce44SJohn Forte 				algorithm->currentAlgorithms[0] =
2156*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_NONE;
2157*fcf3ce44SJohn Forte 				algorithm->currentAlgorithms[1] =
2158*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_CRC32C;
2159*fcf3ce44SJohn Forte 				algorithm->currentAlgorithmCount = 2;
2160*fcf3ce44SJohn Forte 				break;
2161*fcf3ce44SJohn Forte 			default:
2162*fcf3ce44SJohn Forte 				/* Error */
2163*fcf3ce44SJohn Forte 				syslog(LOG_USER|LOG_DEBUG,
2164*fcf3ce44SJohn Forte 				    "Invalid configured digest: %d",
2165*fcf3ce44SJohn Forte 				    pProps.defaultValue);
2166*fcf3ce44SJohn Forte 				return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2167*fcf3ce44SJohn Forte 		}
2168*fcf3ce44SJohn Forte 
2169*fcf3ce44SJohn Forte 	} else {
2170*fcf3ce44SJohn Forte 		algorithm->currentValid = IMA_FALSE;
2171*fcf3ce44SJohn Forte 	}
2172*fcf3ce44SJohn Forte 
2173*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2174*fcf3ce44SJohn Forte }
2175*fcf3ce44SJohn Forte 
2176*fcf3ce44SJohn Forte /*
2177*fcf3ce44SJohn Forte  * getConnOidList -
2178*fcf3ce44SJohn Forte  */
2179*fcf3ce44SJohn Forte static IMA_STATUS getConnOidList(
2180*fcf3ce44SJohn Forte 	IMA_OID			*sessOid,
2181*fcf3ce44SJohn Forte 	iscsi_conn_list_t	**ppConnList
2182*fcf3ce44SJohn Forte )
2183*fcf3ce44SJohn Forte {
2184*fcf3ce44SJohn Forte 	iscsi_conn_list_t	*iscsiConnList = NULL;
2185*fcf3ce44SJohn Forte 	size_t			allocLen;
2186*fcf3ce44SJohn Forte 	int			fd;
2187*fcf3ce44SJohn Forte 	int			status;
2188*fcf3ce44SJohn Forte 	int			out_cnt;
2189*fcf3ce44SJohn Forte 
2190*fcf3ce44SJohn Forte 	/* Preset it to NULL to prepare for the case of failure */
2191*fcf3ce44SJohn Forte 	*ppConnList = NULL;
2192*fcf3ce44SJohn Forte 
2193*fcf3ce44SJohn Forte 	/* We try to open the driver now. */
2194*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2195*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2196*fcf3ce44SJohn Forte 	}
2197*fcf3ce44SJohn Forte 
2198*fcf3ce44SJohn Forte 	iscsiConnList = (iscsi_conn_list_t *)calloc(1,
2199*fcf3ce44SJohn Forte 	    sizeof (iscsi_conn_list_t));
2200*fcf3ce44SJohn Forte 	if (iscsiConnList == NULL) {
2201*fcf3ce44SJohn Forte 		(void) close(fd);
2202*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2203*fcf3ce44SJohn Forte 	}
2204*fcf3ce44SJohn Forte 	iscsiConnList->cl_vers = ISCSI_INTERFACE_VERSION;
2205*fcf3ce44SJohn Forte 	iscsiConnList->cl_in_cnt = iscsiConnList->cl_out_cnt = 1;
2206*fcf3ce44SJohn Forte 	if (sessOid == NULL) {
2207*fcf3ce44SJohn Forte 		iscsiConnList->cl_all_sess = B_TRUE;
2208*fcf3ce44SJohn Forte 	} else {
2209*fcf3ce44SJohn Forte 		iscsiConnList->cl_all_sess = B_FALSE;
2210*fcf3ce44SJohn Forte 		iscsiConnList->cl_sess_oid =
2211*fcf3ce44SJohn Forte 		    (uint32_t)sessOid->objectSequenceNumber;
2212*fcf3ce44SJohn Forte 	}
2213*fcf3ce44SJohn Forte 	/*
2214*fcf3ce44SJohn Forte 	 * Issue ioctl to retrieve the connection OIDs.  Space has been
2215*fcf3ce44SJohn Forte 	 * allocated for one entry.  If more than one entry should be
2216*fcf3ce44SJohn Forte 	 * returned, we will re-issue the entry with the right amount of
2217*fcf3ce44SJohn Forte 	 * space allocted
2218*fcf3ce44SJohn Forte 	 */
2219*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_CONN_OID_LIST_GET, iscsiConnList) != 0) {
2220*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2221*fcf3ce44SJohn Forte 		    "ISCSI_CONN_OID_LIST_GET ioctl failed, errno: %d", errno);
2222*fcf3ce44SJohn Forte 		*ppConnList = NULL;
2223*fcf3ce44SJohn Forte 		(void) close(fd);
2224*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2225*fcf3ce44SJohn Forte 	}
2226*fcf3ce44SJohn Forte 	if (iscsiConnList->cl_out_cnt > 1) {
2227*fcf3ce44SJohn Forte 		out_cnt = iscsiConnList->cl_out_cnt;
2228*fcf3ce44SJohn Forte 		free(iscsiConnList);
2229*fcf3ce44SJohn Forte 
2230*fcf3ce44SJohn Forte 		allocLen = sizeof (iscsi_conn_list_t);
2231*fcf3ce44SJohn Forte 		allocLen += (sizeof (iscsi_if_conn_t) * out_cnt - 1);
2232*fcf3ce44SJohn Forte 		iscsiConnList = (iscsi_conn_list_t *)calloc(1, allocLen);
2233*fcf3ce44SJohn Forte 		if (iscsiConnList == NULL) {
2234*fcf3ce44SJohn Forte 			*ppConnList = NULL;
2235*fcf3ce44SJohn Forte 			(void) close(fd);
2236*fcf3ce44SJohn Forte 			return (IMA_ERROR_INSUFFICIENT_MEMORY);
2237*fcf3ce44SJohn Forte 		}
2238*fcf3ce44SJohn Forte 		iscsiConnList->cl_vers = ISCSI_INTERFACE_VERSION;
2239*fcf3ce44SJohn Forte 		iscsiConnList->cl_in_cnt = out_cnt;
2240*fcf3ce44SJohn Forte 		if (sessOid == NULL) {
2241*fcf3ce44SJohn Forte 			iscsiConnList->cl_all_sess = B_TRUE;
2242*fcf3ce44SJohn Forte 		} else {
2243*fcf3ce44SJohn Forte 			iscsiConnList->cl_all_sess = B_FALSE;
2244*fcf3ce44SJohn Forte 			iscsiConnList->cl_sess_oid =
2245*fcf3ce44SJohn Forte 			    (uint32_t)sessOid->objectSequenceNumber;
2246*fcf3ce44SJohn Forte 		}
2247*fcf3ce44SJohn Forte 		/* Issue the same ioctl again to obtain all the OIDs */
2248*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_CONN_OID_LIST_GET, iscsiConnList) != 0) {
2249*fcf3ce44SJohn Forte 
2250*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
2251*fcf3ce44SJohn Forte 			    "ISCSI_CONN_OID_LIST_GET ioctl failed, errno: %d",
2252*fcf3ce44SJohn Forte 			    errno);
2253*fcf3ce44SJohn Forte 			*ppConnList = NULL;
2254*fcf3ce44SJohn Forte 			free(iscsiConnList);
2255*fcf3ce44SJohn Forte 			(void) close(fd);
2256*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2257*fcf3ce44SJohn Forte 
2258*fcf3ce44SJohn Forte 		}
2259*fcf3ce44SJohn Forte 
2260*fcf3ce44SJohn Forte 		if (out_cnt < iscsiConnList->cl_out_cnt) {
2261*fcf3ce44SJohn Forte 			/*
2262*fcf3ce44SJohn Forte 			 * The connection list grew between the first and second
2263*fcf3ce44SJohn Forte 			 * ioctls.
2264*fcf3ce44SJohn Forte 			 */
2265*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
2266*fcf3ce44SJohn Forte 			    "The connection list has grown. There could be "
2267*fcf3ce44SJohn Forte 			    "more connections than listed.");
2268*fcf3ce44SJohn Forte 		}
2269*fcf3ce44SJohn Forte 	}
2270*fcf3ce44SJohn Forte 
2271*fcf3ce44SJohn Forte 
2272*fcf3ce44SJohn Forte 	(void) close(fd);
2273*fcf3ce44SJohn Forte 	*ppConnList = iscsiConnList;
2274*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2275*fcf3ce44SJohn Forte }
2276*fcf3ce44SJohn Forte 
2277*fcf3ce44SJohn Forte /*
2278*fcf3ce44SJohn Forte  * getConnProps -
2279*fcf3ce44SJohn Forte  */
2280*fcf3ce44SJohn Forte static IMA_STATUS getConnProps(
2281*fcf3ce44SJohn Forte 	iscsi_if_conn_t		*pConn,
2282*fcf3ce44SJohn Forte 	iscsi_conn_props_t	**ppConnProps
2283*fcf3ce44SJohn Forte )
2284*fcf3ce44SJohn Forte {
2285*fcf3ce44SJohn Forte 	iscsi_conn_props_t	*iscsiConnProps;
2286*fcf3ce44SJohn Forte 	int			fd;
2287*fcf3ce44SJohn Forte 	int			status;
2288*fcf3ce44SJohn Forte 
2289*fcf3ce44SJohn Forte 	/* We try to open the driver. */
2290*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2291*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2292*fcf3ce44SJohn Forte 	}
2293*fcf3ce44SJohn Forte 
2294*fcf3ce44SJohn Forte 	iscsiConnProps = (iscsi_conn_props_t *)calloc(1,
2295*fcf3ce44SJohn Forte 	    sizeof (*iscsiConnProps));
2296*fcf3ce44SJohn Forte 
2297*fcf3ce44SJohn Forte 	if (iscsiConnProps == NULL) {
2298*fcf3ce44SJohn Forte 		(void) close(fd);
2299*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2300*fcf3ce44SJohn Forte 	}
2301*fcf3ce44SJohn Forte 
2302*fcf3ce44SJohn Forte 	iscsiConnProps->cp_vers = ISCSI_INTERFACE_VERSION;
2303*fcf3ce44SJohn Forte 	iscsiConnProps->cp_oid = pConn->c_oid;
2304*fcf3ce44SJohn Forte 	iscsiConnProps->cp_cid = pConn->c_cid;
2305*fcf3ce44SJohn Forte 	iscsiConnProps->cp_sess_oid = pConn->c_sess_oid;
2306*fcf3ce44SJohn Forte 
2307*fcf3ce44SJohn Forte 	/* The IOCTL is submitted. */
2308*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_CONN_PROPS_GET, iscsiConnProps) != 0) {
2309*fcf3ce44SJohn Forte 		/* IOCTL failed */
2310*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2311*fcf3ce44SJohn Forte 		    "ISCSI_AUTH_CLEAR ioctl failed, errno: %d", errno);
2312*fcf3ce44SJohn Forte 		free(iscsiConnProps);
2313*fcf3ce44SJohn Forte 		(void) close(fd);
2314*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2315*fcf3ce44SJohn Forte 	}
2316*fcf3ce44SJohn Forte 	(void) close(fd);
2317*fcf3ce44SJohn Forte 	*ppConnProps = iscsiConnProps;
2318*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2319*fcf3ce44SJohn Forte }
2320*fcf3ce44SJohn Forte 
2321*fcf3ce44SJohn Forte /* A helper function to set authentication method. */
2322*fcf3ce44SJohn Forte static IMA_STATUS
2323*fcf3ce44SJohn Forte setAuthMethods(
2324*fcf3ce44SJohn Forte     IMA_OID oid,
2325*fcf3ce44SJohn Forte     IMA_UINT *pMethodCount,
2326*fcf3ce44SJohn Forte     const IMA_AUTHMETHOD *pMethodList
2327*fcf3ce44SJohn Forte )
2328*fcf3ce44SJohn Forte {
2329*fcf3ce44SJohn Forte 	int fd;
2330*fcf3ce44SJohn Forte 	int i;
2331*fcf3ce44SJohn Forte 	int status;
2332*fcf3ce44SJohn Forte 	iscsi_auth_props_t auth;
2333*fcf3ce44SJohn Forte 
2334*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2335*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2336*fcf3ce44SJohn Forte 	}
2337*fcf3ce44SJohn Forte 	(void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
2338*fcf3ce44SJohn Forte 	auth.a_vers = ISCSI_INTERFACE_VERSION;
2339*fcf3ce44SJohn Forte 	auth.a_oid = (uint32_t)oid.objectSequenceNumber;
2340*fcf3ce44SJohn Forte 
2341*fcf3ce44SJohn Forte 	/*
2342*fcf3ce44SJohn Forte 	 * Get the current auth fields so they don't need to be reset
2343*fcf3ce44SJohn Forte 	 * here.
2344*fcf3ce44SJohn Forte 	 */
2345*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
2346*fcf3ce44SJohn Forte 	    /* EMPTY */
2347*fcf3ce44SJohn Forte 	    /* Initializing auth structure with current settings */
2348*fcf3ce44SJohn Forte 	}
2349*fcf3ce44SJohn Forte 	auth.a_auth_method = authMethodNone;
2350*fcf3ce44SJohn Forte 
2351*fcf3ce44SJohn Forte 	for (i = 0; i < *pMethodCount; i++) {
2352*fcf3ce44SJohn Forte 		switch (pMethodList[i]) {
2353*fcf3ce44SJohn Forte 			case IMA_AUTHMETHOD_CHAP:
2354*fcf3ce44SJohn Forte 				auth.a_auth_method |= authMethodCHAP;
2355*fcf3ce44SJohn Forte 				break;
2356*fcf3ce44SJohn Forte 			default:
2357*fcf3ce44SJohn Forte 				break;
2358*fcf3ce44SJohn Forte 		}
2359*fcf3ce44SJohn Forte 	}
2360*fcf3ce44SJohn Forte 
2361*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) {
2362*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2363*fcf3ce44SJohn Forte 		    "ISCSI_AUTH_SET failed, errno: %d", errno);
2364*fcf3ce44SJohn Forte 		(void) close(fd);
2365*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2366*fcf3ce44SJohn Forte 	}
2367*fcf3ce44SJohn Forte 
2368*fcf3ce44SJohn Forte 	(void) close(fd);
2369*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2370*fcf3ce44SJohn Forte }
2371*fcf3ce44SJohn Forte 
2372*fcf3ce44SJohn Forte /* A helper function to set authentication method. */
2373*fcf3ce44SJohn Forte static IMA_STATUS getAuthMethods(
2374*fcf3ce44SJohn Forte     IMA_OID oid,
2375*fcf3ce44SJohn Forte     IMA_UINT	*pMethodCount,
2376*fcf3ce44SJohn Forte     IMA_AUTHMETHOD *pMethodList
2377*fcf3ce44SJohn Forte )
2378*fcf3ce44SJohn Forte {
2379*fcf3ce44SJohn Forte 	int fd;
2380*fcf3ce44SJohn Forte 	int status;
2381*fcf3ce44SJohn Forte 	iscsi_auth_props_t auth;
2382*fcf3ce44SJohn Forte 
2383*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2384*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2385*fcf3ce44SJohn Forte 	}
2386*fcf3ce44SJohn Forte 
2387*fcf3ce44SJohn Forte 	(void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
2388*fcf3ce44SJohn Forte 	auth.a_vers = ISCSI_INTERFACE_VERSION;
2389*fcf3ce44SJohn Forte 	auth.a_oid = (uint32_t)oid.objectSequenceNumber;
2390*fcf3ce44SJohn Forte 
2391*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
2392*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2393*fcf3ce44SJohn Forte 		    "ISCSI_AUTH_GET failed, errno: %d", errno);
2394*fcf3ce44SJohn Forte 		(void) close(fd);
2395*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2396*fcf3ce44SJohn Forte 	}
2397*fcf3ce44SJohn Forte 
2398*fcf3ce44SJohn Forte 	if (auth.a_auth_method == authMethodNone) {
2399*fcf3ce44SJohn Forte 		pMethodList[0] = IMA_AUTHMETHOD_NONE;
2400*fcf3ce44SJohn Forte 		*pMethodCount = 1;
2401*fcf3ce44SJohn Forte 	} else {
2402*fcf3ce44SJohn Forte 		int i = 0;
2403*fcf3ce44SJohn Forte 		if (!((auth.a_auth_method & authMethodCHAP)^authMethodCHAP)) {
2404*fcf3ce44SJohn Forte 			pMethodList[i++] = IMA_AUTHMETHOD_CHAP;
2405*fcf3ce44SJohn Forte 		}
2406*fcf3ce44SJohn Forte 		*pMethodCount = i;
2407*fcf3ce44SJohn Forte 	}
2408*fcf3ce44SJohn Forte 
2409*fcf3ce44SJohn Forte 	(void) close(fd);
2410*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2411*fcf3ce44SJohn Forte }
2412*fcf3ce44SJohn Forte 
2413*fcf3ce44SJohn Forte /* Helper function to open driver */
2414*fcf3ce44SJohn Forte int open_driver(
2415*fcf3ce44SJohn Forte 	int *fd
2416*fcf3ce44SJohn Forte )
2417*fcf3ce44SJohn Forte {
2418*fcf3ce44SJohn Forte 	int ret = 0;
2419*fcf3ce44SJohn Forte 	if ((*fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2420*fcf3ce44SJohn Forte 		ret = errno;
2421*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2422*fcf3ce44SJohn Forte 		    ISCSI_DRIVER_DEVCTL, ret);
2423*fcf3ce44SJohn Forte 	}
2424*fcf3ce44SJohn Forte 	return (ret);
2425*fcf3ce44SJohn Forte }
2426*fcf3ce44SJohn Forte 
2427*fcf3ce44SJohn Forte /*
2428*fcf3ce44SJohn Forte  * Iscsi driver does not support OID for discovery address. Create
2429*fcf3ce44SJohn Forte  * a modified version of IMA_RemoveDiscoveryAddress that takes
2430*fcf3ce44SJohn Forte  * discoveryAddress (instead of an OID) as input argument.
2431*fcf3ce44SJohn Forte  */
2432*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_RemoveDiscoveryAddress(
2433*fcf3ce44SJohn Forte     SUN_IMA_TARGET_ADDRESS discoveryAddress
2434*fcf3ce44SJohn Forte )
2435*fcf3ce44SJohn Forte {
2436*fcf3ce44SJohn Forte 	entry_t	entry;
2437*fcf3ce44SJohn Forte 	int	fd;
2438*fcf3ce44SJohn Forte 	int status, i, addr_list_size, insize;
2439*fcf3ce44SJohn Forte 	iscsi_addr_list_t *idlp, al_info;
2440*fcf3ce44SJohn Forte 	iscsi_addr_t *matched_addr = NULL;
2441*fcf3ce44SJohn Forte 
2442*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2443*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2444*fcf3ce44SJohn Forte 	}
2445*fcf3ce44SJohn Forte 
2446*fcf3ce44SJohn Forte 	if (prepare_discovery_entry(discoveryAddress, &entry) !=
2447*fcf3ce44SJohn Forte 	    DISC_ADDR_OK) {
2448*fcf3ce44SJohn Forte 		(void) close(fd);
2449*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
2450*fcf3ce44SJohn Forte 	}
2451*fcf3ce44SJohn Forte 
2452*fcf3ce44SJohn Forte 	(void) memset(&al_info, 0, sizeof (al_info));
2453*fcf3ce44SJohn Forte 	al_info.al_vers = ISCSI_INTERFACE_VERSION;
2454*fcf3ce44SJohn Forte 	al_info.al_in_cnt = 0;
2455*fcf3ce44SJohn Forte 	/*
2456*fcf3ce44SJohn Forte 	 * Issue ioctl to get the number of discovery address.
2457*fcf3ce44SJohn Forte 	 */
2458*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
2459*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2460*fcf3ce44SJohn Forte 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
2461*fcf3ce44SJohn Forte 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
2462*fcf3ce44SJohn Forte 		(void) close(fd);
2463*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2464*fcf3ce44SJohn Forte 	}
2465*fcf3ce44SJohn Forte 
2466*fcf3ce44SJohn Forte 	if (al_info.al_out_cnt == 0) {
2467*fcf3ce44SJohn Forte 		(void) close(fd);
2468*fcf3ce44SJohn Forte 		return (IMA_ERROR_OBJECT_NOT_FOUND);
2469*fcf3ce44SJohn Forte 	}
2470*fcf3ce44SJohn Forte 
2471*fcf3ce44SJohn Forte 	addr_list_size = sizeof (iscsi_addr_list_t);
2472*fcf3ce44SJohn Forte 	if (al_info.al_out_cnt > 1) {
2473*fcf3ce44SJohn Forte 		addr_list_size += (sizeof (iscsi_addr_t) *
2474*fcf3ce44SJohn Forte 		    (al_info.al_out_cnt - 1));
2475*fcf3ce44SJohn Forte 	}
2476*fcf3ce44SJohn Forte 
2477*fcf3ce44SJohn Forte 	idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
2478*fcf3ce44SJohn Forte 	if (idlp == NULL) {
2479*fcf3ce44SJohn Forte 		(void) close(fd);
2480*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2481*fcf3ce44SJohn Forte 	}
2482*fcf3ce44SJohn Forte 
2483*fcf3ce44SJohn Forte 	idlp->al_vers = ISCSI_INTERFACE_VERSION;
2484*fcf3ce44SJohn Forte 	idlp->al_in_cnt = al_info.al_out_cnt;
2485*fcf3ce44SJohn Forte 
2486*fcf3ce44SJohn Forte 	/* issue the same ioctl to get all the discovery addresses */
2487*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
2488*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2489*fcf3ce44SJohn Forte 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
2490*fcf3ce44SJohn Forte 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
2491*fcf3ce44SJohn Forte 		free(idlp);
2492*fcf3ce44SJohn Forte 		(void) close(fd);
2493*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2494*fcf3ce44SJohn Forte 	}
2495*fcf3ce44SJohn Forte 
2496*fcf3ce44SJohn Forte 	/*
2497*fcf3ce44SJohn Forte 	 * find the matched discovery address
2498*fcf3ce44SJohn Forte 	 */
2499*fcf3ce44SJohn Forte 	for (i = 0; i < idlp->al_out_cnt; i++) {
2500*fcf3ce44SJohn Forte 		insize = idlp->al_addrs[i].a_addr.i_insize;
2501*fcf3ce44SJohn Forte 		if (insize != entry.e_insize) {
2502*fcf3ce44SJohn Forte 			continue;
2503*fcf3ce44SJohn Forte 		}
2504*fcf3ce44SJohn Forte 		if (insize == sizeof (struct in_addr)) {
2505*fcf3ce44SJohn Forte 			if (idlp->al_addrs[i].a_addr.i_addr.in4.s_addr ==
2506*fcf3ce44SJohn Forte 			    entry.e_u.u_in4.s_addr) {
2507*fcf3ce44SJohn Forte 				matched_addr = &(idlp->al_addrs[i]);
2508*fcf3ce44SJohn Forte 				break;
2509*fcf3ce44SJohn Forte 			}
2510*fcf3ce44SJohn Forte 		}
2511*fcf3ce44SJohn Forte 		if (insize == sizeof (struct in6_addr)) {
2512*fcf3ce44SJohn Forte 			if (bcmp(entry.e_u.u_in6.s6_addr,
2513*fcf3ce44SJohn Forte 			    idlp->al_addrs[i].a_addr.i_addr.in6.s6_addr,
2514*fcf3ce44SJohn Forte 			    insize) == 0) {
2515*fcf3ce44SJohn Forte 				matched_addr = &(idlp->al_addrs[i]);
2516*fcf3ce44SJohn Forte 				break;
2517*fcf3ce44SJohn Forte 			}
2518*fcf3ce44SJohn Forte 		}
2519*fcf3ce44SJohn Forte 	}
2520*fcf3ce44SJohn Forte 
2521*fcf3ce44SJohn Forte 	free(idlp);
2522*fcf3ce44SJohn Forte 
2523*fcf3ce44SJohn Forte 	if (matched_addr == NULL) {
2524*fcf3ce44SJohn Forte 		(void) close(fd);
2525*fcf3ce44SJohn Forte 		return (IMA_ERROR_OBJECT_NOT_FOUND);
2526*fcf3ce44SJohn Forte 	}
2527*fcf3ce44SJohn Forte 
2528*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_CLEAR, &entry)) {
2529*fcf3ce44SJohn Forte 		status = errno;
2530*fcf3ce44SJohn Forte 		(void) close(fd);
2531*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2532*fcf3ce44SJohn Forte 		    "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d",
2533*fcf3ce44SJohn Forte 		    errno);
2534*fcf3ce44SJohn Forte 		if (status == EBUSY) {
2535*fcf3ce44SJohn Forte 			return (IMA_ERROR_LU_IN_USE);
2536*fcf3ce44SJohn Forte 		} else {
2537*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2538*fcf3ce44SJohn Forte 		}
2539*fcf3ce44SJohn Forte 	}
2540*fcf3ce44SJohn Forte 
2541*fcf3ce44SJohn Forte 	(void) close(fd);
2542*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2543*fcf3ce44SJohn Forte }
2544*fcf3ce44SJohn Forte 
2545*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_SetTargetAuthMethods(
2546*fcf3ce44SJohn Forte 		IMA_OID targetOid,
2547*fcf3ce44SJohn Forte 		IMA_UINT *methodCount,
2548*fcf3ce44SJohn Forte 		const IMA_AUTHMETHOD *pMethodList
2549*fcf3ce44SJohn Forte )
2550*fcf3ce44SJohn Forte {
2551*fcf3ce44SJohn Forte 	return (setAuthMethods(targetOid, methodCount, pMethodList));
2552*fcf3ce44SJohn Forte }
2553*fcf3ce44SJohn Forte 
2554*fcf3ce44SJohn Forte IMA_STATUS getNegotiatedDigest(
2555*fcf3ce44SJohn Forte 	int digestType,
2556*fcf3ce44SJohn Forte 	SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm,
2557*fcf3ce44SJohn Forte 	SUN_IMA_CONN_PROPERTIES *connProps) {
2558*fcf3ce44SJohn Forte 
2559*fcf3ce44SJohn Forte 	IMA_UINT digest;
2560*fcf3ce44SJohn Forte 
2561*fcf3ce44SJohn Forte 	if (connProps->valuesValid == IMA_TRUE) {
2562*fcf3ce44SJohn Forte 		algorithm->negotiatedValid = IMA_TRUE;
2563*fcf3ce44SJohn Forte 
2564*fcf3ce44SJohn Forte 		if (digestType == ISCSI_LOGIN_PARAM_HEADER_DIGEST) {
2565*fcf3ce44SJohn Forte 			digest = connProps->headerDigest;
2566*fcf3ce44SJohn Forte 		} else {
2567*fcf3ce44SJohn Forte 			digest = connProps->dataDigest;
2568*fcf3ce44SJohn Forte 		}
2569*fcf3ce44SJohn Forte 
2570*fcf3ce44SJohn Forte 		switch (digest) {
2571*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_NONE:
2572*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithms[0] =
2573*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_NONE;
2574*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithmCount = 1;
2575*fcf3ce44SJohn Forte 				break;
2576*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_CRC32C:
2577*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithms[0] =
2578*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_CRC32C;
2579*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithmCount = 1;
2580*fcf3ce44SJohn Forte 				break;
2581*fcf3ce44SJohn Forte 
2582*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_CRC32C_NONE:
2583*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithms[0] =
2584*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_CRC32C;
2585*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithms[1] =
2586*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_NONE;
2587*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithmCount = 2;
2588*fcf3ce44SJohn Forte 				break;
2589*fcf3ce44SJohn Forte 			case ISCSI_DIGEST_NONE_CRC32C:
2590*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithms[0] =
2591*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_NONE;
2592*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithms[1] =
2593*fcf3ce44SJohn Forte 				    ISCSI_DIGEST_CRC32C;
2594*fcf3ce44SJohn Forte 				algorithm->negotiatedAlgorithmCount = 2;
2595*fcf3ce44SJohn Forte 				break;
2596*fcf3ce44SJohn Forte 			default:
2597*fcf3ce44SJohn Forte 				syslog(LOG_USER|LOG_DEBUG,
2598*fcf3ce44SJohn Forte 				    "Invalid negotiated digest: %d",
2599*fcf3ce44SJohn Forte 				    digest);
2600*fcf3ce44SJohn Forte 				return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2601*fcf3ce44SJohn Forte 		}
2602*fcf3ce44SJohn Forte 	} else {
2603*fcf3ce44SJohn Forte 		algorithm->negotiatedValid = IMA_FALSE;
2604*fcf3ce44SJohn Forte 	}
2605*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2606*fcf3ce44SJohn Forte }
2607*fcf3ce44SJohn Forte 
2608*fcf3ce44SJohn Forte /*
2609*fcf3ce44SJohn Forte  * Non-IMA defined function.
2610*fcf3ce44SJohn Forte  */
2611*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_GetISNSServerAddressPropertiesList(
2612*fcf3ce44SJohn Forte     SUN_IMA_DISC_ADDR_PROP_LIST	**ppList
2613*fcf3ce44SJohn Forte )
2614*fcf3ce44SJohn Forte {
2615*fcf3ce44SJohn Forte 	char		    isns_server_addr_str[256];
2616*fcf3ce44SJohn Forte 	int		    fd;
2617*fcf3ce44SJohn Forte 	int		    i;
2618*fcf3ce44SJohn Forte 	int		    isns_server_addr_list_size;
2619*fcf3ce44SJohn Forte 	int		    status;
2620*fcf3ce44SJohn Forte 	int		    out_cnt;
2621*fcf3ce44SJohn Forte 	iscsi_addr_list_t   *ialp;
2622*fcf3ce44SJohn Forte 	/* LINTED */
2623*fcf3ce44SJohn Forte 	IMA_IP_ADDRESS	    *ipAddr;
2624*fcf3ce44SJohn Forte 
2625*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2626*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2627*fcf3ce44SJohn Forte 	}
2628*fcf3ce44SJohn Forte 
2629*fcf3ce44SJohn Forte 	ialp = (iscsi_addr_list_t *)calloc(1, sizeof (iscsi_addr_list_t));
2630*fcf3ce44SJohn Forte 	if (ialp == NULL) {
2631*fcf3ce44SJohn Forte 		(void) close(fd);
2632*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2633*fcf3ce44SJohn Forte 	}
2634*fcf3ce44SJohn Forte 	ialp->al_vers = ISCSI_INTERFACE_VERSION;
2635*fcf3ce44SJohn Forte 	ialp->al_in_cnt = ialp->al_out_cnt = 1;
2636*fcf3ce44SJohn Forte 
2637*fcf3ce44SJohn Forte 	/*
2638*fcf3ce44SJohn Forte 	 * Issue ioctl to retrieve the isns server addresses.  Space has been
2639*fcf3ce44SJohn Forte 	 * allocted for one entry.  If more than one entry should be returned,
2640*fcf3ce44SJohn Forte 	 * we will re-issue the entry with the right amount of space allocted
2641*fcf3ce44SJohn Forte 	 */
2642*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_LIST_GET, ialp) != 0) {
2643*fcf3ce44SJohn Forte 		(void) close(fd);
2644*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2645*fcf3ce44SJohn Forte 		    "ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl failed, errno: %d",
2646*fcf3ce44SJohn Forte 		    errno);
2647*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2648*fcf3ce44SJohn Forte 	}
2649*fcf3ce44SJohn Forte 
2650*fcf3ce44SJohn Forte 	isns_server_addr_list_size = sizeof (iscsi_addr_list_t);
2651*fcf3ce44SJohn Forte 	if (ialp->al_out_cnt > 1) {
2652*fcf3ce44SJohn Forte 		out_cnt = ialp->al_out_cnt;
2653*fcf3ce44SJohn Forte 		free(ialp);
2654*fcf3ce44SJohn Forte 
2655*fcf3ce44SJohn Forte 		isns_server_addr_list_size += (sizeof (iscsi_addr_t) *
2656*fcf3ce44SJohn Forte 		    out_cnt - 1);
2657*fcf3ce44SJohn Forte 		ialp = (iscsi_addr_list_t *)calloc(1,
2658*fcf3ce44SJohn Forte 		    isns_server_addr_list_size);
2659*fcf3ce44SJohn Forte 		if (ialp == NULL) {
2660*fcf3ce44SJohn Forte 			(void) close(fd);
2661*fcf3ce44SJohn Forte 			return (IMA_ERROR_INSUFFICIENT_MEMORY);
2662*fcf3ce44SJohn Forte 		}
2663*fcf3ce44SJohn Forte 		ialp->al_vers = ISCSI_INTERFACE_VERSION;
2664*fcf3ce44SJohn Forte 		ialp->al_in_cnt = out_cnt;
2665*fcf3ce44SJohn Forte 
2666*fcf3ce44SJohn Forte 		/*
2667*fcf3ce44SJohn Forte 		 * Issue ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl again to obtain
2668*fcf3ce44SJohn Forte 		 * the list of all the iSNS server addresses
2669*fcf3ce44SJohn Forte 		 */
2670*fcf3ce44SJohn Forte 		if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_LIST_GET, ialp) != 0) {
2671*fcf3ce44SJohn Forte 			free(ialp);
2672*fcf3ce44SJohn Forte 			(void) close(fd);
2673*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
2674*fcf3ce44SJohn Forte 			    "ISCSI_ISNS_SERVER_ADDR_LIST_GET ioctl failed, "
2675*fcf3ce44SJohn Forte 			    "errno: %d", errno);
2676*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2677*fcf3ce44SJohn Forte 
2678*fcf3ce44SJohn Forte 		}
2679*fcf3ce44SJohn Forte 	}
2680*fcf3ce44SJohn Forte 
2681*fcf3ce44SJohn Forte 	*ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *)calloc(1,
2682*fcf3ce44SJohn Forte 	    sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) +
2683*fcf3ce44SJohn Forte 	    ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES));
2684*fcf3ce44SJohn Forte 	if (*ppList == NULL) {
2685*fcf3ce44SJohn Forte 		free(ialp);
2686*fcf3ce44SJohn Forte 		(void) close(fd);
2687*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2688*fcf3ce44SJohn Forte 	}
2689*fcf3ce44SJohn Forte 	(*ppList)->discAddrCount = ialp->al_out_cnt;
2690*fcf3ce44SJohn Forte 
2691*fcf3ce44SJohn Forte 	for (i = 0; i < ialp->al_out_cnt; i++) {
2692*fcf3ce44SJohn Forte 		if (ialp->al_addrs[i].a_addr.i_insize ==
2693*fcf3ce44SJohn Forte 		    sizeof (struct in_addr)) {
2694*fcf3ce44SJohn Forte 			(*ppList)->props[i].discoveryAddress.hostnameIpAddress.
2695*fcf3ce44SJohn Forte 			id.ipAddress.ipv4Address = IMA_TRUE;
2696*fcf3ce44SJohn Forte 		} else if (ialp->al_addrs[i].a_addr.i_insize ==
2697*fcf3ce44SJohn Forte 		    sizeof (struct in6_addr)) {
2698*fcf3ce44SJohn Forte 			(*ppList)->props[i].discoveryAddress.hostnameIpAddress.
2699*fcf3ce44SJohn Forte 			    id.ipAddress.ipv4Address = IMA_FALSE;
2700*fcf3ce44SJohn Forte 		} else {
2701*fcf3ce44SJohn Forte 			(void) strlcpy(isns_server_addr_str, "unknown",
2702*fcf3ce44SJohn Forte 			    sizeof (isns_server_addr_str));
2703*fcf3ce44SJohn Forte 		}
2704*fcf3ce44SJohn Forte 
2705*fcf3ce44SJohn Forte 		ipAddr = &(*ppList)->props[i].discoveryAddress.
2706*fcf3ce44SJohn Forte 		    hostnameIpAddress.id.ipAddress;
2707*fcf3ce44SJohn Forte 		bcopy(&ialp->al_addrs[i].a_addr.i_addr,
2708*fcf3ce44SJohn Forte 		    (*ppList)->props[i].discoveryAddress.hostnameIpAddress.id.
2709*fcf3ce44SJohn Forte 		    ipAddress.ipAddress,
2710*fcf3ce44SJohn Forte 		    sizeof (ipAddr->ipAddress));
2711*fcf3ce44SJohn Forte 		(*ppList)->props[i].discoveryAddress.portNumber =
2712*fcf3ce44SJohn Forte 		    ialp->al_addrs[i].a_port;
2713*fcf3ce44SJohn Forte 	}
2714*fcf3ce44SJohn Forte 
2715*fcf3ce44SJohn Forte 	free(ialp);
2716*fcf3ce44SJohn Forte 	(void) close(fd);
2717*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2718*fcf3ce44SJohn Forte }
2719*fcf3ce44SJohn Forte 
2720*fcf3ce44SJohn Forte /*ARGSUSED*/
2721*fcf3ce44SJohn Forte /*
2722*fcf3ce44SJohn Forte  * Remove iSNS Server Address
2723*fcf3ce44SJohn Forte  */
2724*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_RemoveISNSServerAddress(
2725*fcf3ce44SJohn Forte     SUN_IMA_TARGET_ADDRESS isnsServerAddress
2726*fcf3ce44SJohn Forte )
2727*fcf3ce44SJohn Forte {
2728*fcf3ce44SJohn Forte 	entry_t	entry;
2729*fcf3ce44SJohn Forte 	int	fd, status;
2730*fcf3ce44SJohn Forte 
2731*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2732*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2733*fcf3ce44SJohn Forte 	}
2734*fcf3ce44SJohn Forte 
2735*fcf3ce44SJohn Forte 	if (prepare_discovery_entry(isnsServerAddress, &entry) !=
2736*fcf3ce44SJohn Forte 	    DISC_ADDR_OK) {
2737*fcf3ce44SJohn Forte 		(void) close(fd);
2738*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
2739*fcf3ce44SJohn Forte 	}
2740*fcf3ce44SJohn Forte 
2741*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_CLEAR, &entry)) {
2742*fcf3ce44SJohn Forte 		status = errno;
2743*fcf3ce44SJohn Forte 		(void) close(fd);
2744*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2745*fcf3ce44SJohn Forte 		    "ISCSI_ISNS_SERVER_ADDR_CLEAR ioctl failed, errno: %d",
2746*fcf3ce44SJohn Forte 		    status);
2747*fcf3ce44SJohn Forte 		if (status == EBUSY) {
2748*fcf3ce44SJohn Forte 			return (IMA_ERROR_LU_IN_USE);
2749*fcf3ce44SJohn Forte 		} else {
2750*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2751*fcf3ce44SJohn Forte 		}
2752*fcf3ce44SJohn Forte 	}
2753*fcf3ce44SJohn Forte 
2754*fcf3ce44SJohn Forte 	(void) close(fd);
2755*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2756*fcf3ce44SJohn Forte }
2757*fcf3ce44SJohn Forte 
2758*fcf3ce44SJohn Forte /*ARGSUSED*/
2759*fcf3ce44SJohn Forte IMA_API IMA_STATUS SUN_IMA_AddISNSServerAddress(
2760*fcf3ce44SJohn Forte 		const SUN_IMA_TARGET_ADDRESS isnsServerAddress
2761*fcf3ce44SJohn Forte )
2762*fcf3ce44SJohn Forte {
2763*fcf3ce44SJohn Forte 	entry_t			    entry;
2764*fcf3ce44SJohn Forte 	int			    fd;
2765*fcf3ce44SJohn Forte 	int			    status;
2766*fcf3ce44SJohn Forte 
2767*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2768*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2769*fcf3ce44SJohn Forte 	}
2770*fcf3ce44SJohn Forte 
2771*fcf3ce44SJohn Forte 	if (prepare_discovery_entry(isnsServerAddress, &entry) !=
2772*fcf3ce44SJohn Forte 	    DISC_ADDR_OK) {
2773*fcf3ce44SJohn Forte 		(void) close(fd);
2774*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
2775*fcf3ce44SJohn Forte 	}
2776*fcf3ce44SJohn Forte 
2777*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_ISNS_SERVER_ADDR_SET, &entry)) {
2778*fcf3ce44SJohn Forte 		/*
2779*fcf3ce44SJohn Forte 		 * Encountered problem setting the discovery address.
2780*fcf3ce44SJohn Forte 		 */
2781*fcf3ce44SJohn Forte 		(void) close(fd);
2782*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2783*fcf3ce44SJohn Forte 		    "ISCSI_ISNS_SERVER_ADDR_SET ioctl failed, errno: %d",
2784*fcf3ce44SJohn Forte 		    errno);
2785*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2786*fcf3ce44SJohn Forte 	}
2787*fcf3ce44SJohn Forte 
2788*fcf3ce44SJohn Forte 	(void) close(fd);
2789*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2790*fcf3ce44SJohn Forte }
2791*fcf3ce44SJohn Forte 
2792*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_RetrieveISNSServerTargets(
2793*fcf3ce44SJohn Forte     IMA_TARGET_ADDRESS serverAddress,
2794*fcf3ce44SJohn Forte     SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
2795*fcf3ce44SJohn Forte )
2796*fcf3ce44SJohn Forte {
2797*fcf3ce44SJohn Forte 	int				    fd;
2798*fcf3ce44SJohn Forte 	int				    ctr;
2799*fcf3ce44SJohn Forte 	int				    server_pg_list_sz;
2800*fcf3ce44SJohn Forte 	int				    status;
2801*fcf3ce44SJohn Forte 	isns_server_portal_group_list_t	    *server_pg_list = NULL;
2802*fcf3ce44SJohn Forte 	isns_portal_group_list_t	    *pg_list = NULL;
2803*fcf3ce44SJohn Forte 	IMA_BOOL			    retry = IMA_TRUE;
2804*fcf3ce44SJohn Forte 	entry_t				    entry;
2805*fcf3ce44SJohn Forte 
2806*fcf3ce44SJohn Forte #define	ISNS_SERVER_DEFAULT_NUM_TARGETS	50
2807*fcf3ce44SJohn Forte 
2808*fcf3ce44SJohn Forte 	server_pg_list_sz = sizeof (*server_pg_list) +
2809*fcf3ce44SJohn Forte 	    ((ISNS_SERVER_DEFAULT_NUM_TARGETS - 1) *
2810*fcf3ce44SJohn Forte 	    sizeof (isns_portal_group_t));
2811*fcf3ce44SJohn Forte 
2812*fcf3ce44SJohn Forte 	server_pg_list = (isns_server_portal_group_list_t *)calloc(1,
2813*fcf3ce44SJohn Forte 	    server_pg_list_sz);
2814*fcf3ce44SJohn Forte 	if (server_pg_list == NULL) {
2815*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2816*fcf3ce44SJohn Forte 	}
2817*fcf3ce44SJohn Forte 	server_pg_list->addr_port_list.pg_in_cnt =
2818*fcf3ce44SJohn Forte 	    ISNS_SERVER_DEFAULT_NUM_TARGETS;
2819*fcf3ce44SJohn Forte 
2820*fcf3ce44SJohn Forte 	if ((prepare_discovery_entry_IMA(serverAddress, &entry)
2821*fcf3ce44SJohn Forte 	    != DISC_ADDR_OK)) {
2822*fcf3ce44SJohn Forte 		free(server_pg_list);
2823*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
2824*fcf3ce44SJohn Forte 	}
2825*fcf3ce44SJohn Forte 	server_pg_list->addr.a_port = entry.e_port;
2826*fcf3ce44SJohn Forte 	server_pg_list->addr.a_addr.i_insize = entry.e_insize;
2827*fcf3ce44SJohn Forte 	if (entry.e_insize == sizeof (struct in_addr)) {
2828*fcf3ce44SJohn Forte 		server_pg_list->addr.a_addr.i_addr.in4.s_addr =
2829*fcf3ce44SJohn Forte 		    (entry.e_u.u_in4.s_addr);
2830*fcf3ce44SJohn Forte 	} else if (entry.e_insize == sizeof (struct in6_addr)) {
2831*fcf3ce44SJohn Forte 		bcopy(&entry.e_u.u_in6.s6_addr,
2832*fcf3ce44SJohn Forte 		    server_pg_list->addr.a_addr.i_addr.in6.s6_addr, 16);
2833*fcf3ce44SJohn Forte 	}
2834*fcf3ce44SJohn Forte 
2835*fcf3ce44SJohn Forte 	if ((status = open_driver(&fd))) {
2836*fcf3ce44SJohn Forte 		free(server_pg_list);
2837*fcf3ce44SJohn Forte 		return (SUN_IMA_ERROR_SYSTEM_ERROR | status);
2838*fcf3ce44SJohn Forte 	}
2839*fcf3ce44SJohn Forte 
2840*fcf3ce44SJohn Forte retry_isns:
2841*fcf3ce44SJohn Forte 	/*
2842*fcf3ce44SJohn Forte 	 * Issue ioctl to obtain the ISNS Portal Group List list
2843*fcf3ce44SJohn Forte 	 */
2844*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_ISNS_SERVER_GET, server_pg_list) != 0) {
2845*fcf3ce44SJohn Forte 		int tmp_errno = errno;
2846*fcf3ce44SJohn Forte 		IMA_STATUS return_status;
2847*fcf3ce44SJohn Forte 
2848*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2849*fcf3ce44SJohn Forte 		    "ISCSI_ISNS_SERVER_GET ioctl failed, errno: %d", tmp_errno);
2850*fcf3ce44SJohn Forte 		if (tmp_errno == EACCES) {
2851*fcf3ce44SJohn Forte 			return_status = IMA_ERROR_OBJECT_NOT_FOUND;
2852*fcf3ce44SJohn Forte 		} else {
2853*fcf3ce44SJohn Forte 			return_status = IMA_ERROR_UNEXPECTED_OS_ERROR;
2854*fcf3ce44SJohn Forte 		}
2855*fcf3ce44SJohn Forte 		(void) close(fd);
2856*fcf3ce44SJohn Forte 		free(server_pg_list);
2857*fcf3ce44SJohn Forte 		return (return_status);
2858*fcf3ce44SJohn Forte 	}
2859*fcf3ce44SJohn Forte 	pg_list = &server_pg_list->addr_port_list;
2860*fcf3ce44SJohn Forte 
2861*fcf3ce44SJohn Forte 	/* check if all targets received */
2862*fcf3ce44SJohn Forte 	if (pg_list->pg_in_cnt < pg_list->pg_out_cnt) {
2863*fcf3ce44SJohn Forte 		if (retry == IMA_TRUE) {
2864*fcf3ce44SJohn Forte 			server_pg_list_sz = sizeof (*server_pg_list) +
2865*fcf3ce44SJohn Forte 			    ((pg_list->pg_out_cnt - 1) *
2866*fcf3ce44SJohn Forte 			    sizeof (isns_server_portal_group_list_t));
2867*fcf3ce44SJohn Forte 			server_pg_list = (isns_server_portal_group_list_t *)
2868*fcf3ce44SJohn Forte 			    realloc(server_pg_list, server_pg_list_sz);
2869*fcf3ce44SJohn Forte 			if (server_pg_list == NULL) {
2870*fcf3ce44SJohn Forte 				(void) close(fd);
2871*fcf3ce44SJohn Forte 				return (IMA_ERROR_INSUFFICIENT_MEMORY);
2872*fcf3ce44SJohn Forte 			}
2873*fcf3ce44SJohn Forte 			pg_list = &server_pg_list->addr_port_list;
2874*fcf3ce44SJohn Forte 			pg_list->pg_in_cnt = pg_list->pg_out_cnt;
2875*fcf3ce44SJohn Forte 			retry = IMA_FALSE;
2876*fcf3ce44SJohn Forte 			goto retry_isns;
2877*fcf3ce44SJohn Forte 		} else {
2878*fcf3ce44SJohn Forte 			/*
2879*fcf3ce44SJohn Forte 			 * don't retry after 2 attempts.  The target list
2880*fcf3ce44SJohn Forte 			 * shouldn't continue growing. Just continue
2881*fcf3ce44SJohn Forte 			 * on and display what was found.
2882*fcf3ce44SJohn Forte 			 */
2883*fcf3ce44SJohn Forte 			syslog(LOG_USER|LOG_DEBUG,
2884*fcf3ce44SJohn Forte 			    "ISCSI_SENDTGTS_GET overflow: "
2885*fcf3ce44SJohn Forte 			    "failed to obtain all targets");
2886*fcf3ce44SJohn Forte 			pg_list->pg_out_cnt = pg_list->pg_in_cnt;
2887*fcf3ce44SJohn Forte 		}
2888*fcf3ce44SJohn Forte 	}
2889*fcf3ce44SJohn Forte 
2890*fcf3ce44SJohn Forte 	(void) close(fd);
2891*fcf3ce44SJohn Forte 
2892*fcf3ce44SJohn Forte 	/* allocate for caller return buffer */
2893*fcf3ce44SJohn Forte 	*ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1,
2894*fcf3ce44SJohn Forte 	    sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) +
2895*fcf3ce44SJohn Forte 	    pg_list->pg_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY));
2896*fcf3ce44SJohn Forte 	if (*ppList == NULL) {
2897*fcf3ce44SJohn Forte 		free(server_pg_list);
2898*fcf3ce44SJohn Forte 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
2899*fcf3ce44SJohn Forte 	}
2900*fcf3ce44SJohn Forte 
2901*fcf3ce44SJohn Forte 	(*ppList)->keyCount = pg_list->pg_out_cnt;
2902*fcf3ce44SJohn Forte 
2903*fcf3ce44SJohn Forte 	for (ctr = 0; ctr < pg_list->pg_out_cnt; ctr++) {
2904*fcf3ce44SJohn Forte 		(void) mbstowcs((*ppList)->keys[ctr].name,
2905*fcf3ce44SJohn Forte 		    (char *)pg_list->pg_list[ctr].pg_iscsi_name,
2906*fcf3ce44SJohn Forte 		    IMA_NODE_NAME_LEN);
2907*fcf3ce44SJohn Forte 
2908*fcf3ce44SJohn Forte 		(*ppList)->keys[ctr].tpgt = pg_list->pg_list[ctr].pg_tag;
2909*fcf3ce44SJohn Forte 
2910*fcf3ce44SJohn Forte 		(*ppList)->keys[ctr].address.portNumber =
2911*fcf3ce44SJohn Forte 		    pg_list->pg_list[ctr].pg_port;
2912*fcf3ce44SJohn Forte 
2913*fcf3ce44SJohn Forte 		if (pg_list->pg_list[ctr].insize == sizeof (struct in_addr)) {
2914*fcf3ce44SJohn Forte 			(*ppList)->keys[ctr].address.ipAddress.ipv4Address =
2915*fcf3ce44SJohn Forte 			    IMA_TRUE;
2916*fcf3ce44SJohn Forte 		} else if (pg_list->pg_list[ctr].insize ==
2917*fcf3ce44SJohn Forte 		    sizeof (struct in6_addr)) {
2918*fcf3ce44SJohn Forte 			(*ppList)->keys[ctr].address.ipAddress.ipv4Address =
2919*fcf3ce44SJohn Forte 			    IMA_FALSE;
2920*fcf3ce44SJohn Forte 		} else {
2921*fcf3ce44SJohn Forte 			free(pg_list);
2922*fcf3ce44SJohn Forte 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2923*fcf3ce44SJohn Forte 		}
2924*fcf3ce44SJohn Forte 
2925*fcf3ce44SJohn Forte 		(void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress,
2926*fcf3ce44SJohn Forte 		    &(pg_list->pg_list[ctr].pg_ip_addr),
2927*fcf3ce44SJohn Forte 		    pg_list->pg_list[ctr].insize);
2928*fcf3ce44SJohn Forte 	}
2929*fcf3ce44SJohn Forte 	free(server_pg_list);
2930*fcf3ce44SJohn Forte 
2931*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2932*fcf3ce44SJohn Forte }
2933*fcf3ce44SJohn Forte 
2934*fcf3ce44SJohn Forte /* ARGSUSED */
2935*fcf3ce44SJohn Forte IMA_STATUS SUN_IMA_GetSessionOidList(
2936*fcf3ce44SJohn Forte     IMA_OID initiatorOid,
2937*fcf3ce44SJohn Forte     IMA_OID_LIST **ppList
2938*fcf3ce44SJohn Forte )
2939*fcf3ce44SJohn Forte {
2940*fcf3ce44SJohn Forte 	return (get_target_oid_list(ISCSI_TGT_OID_LIST, ppList));
2941*fcf3ce44SJohn Forte }
2942*fcf3ce44SJohn Forte 
2943*fcf3ce44SJohn Forte /*ARGSUSED*/
2944*fcf3ce44SJohn Forte IMA_API	IMA_STATUS SUN_IMA_GetTargetAuthParms(
2945*fcf3ce44SJohn Forte 	IMA_OID oid,
2946*fcf3ce44SJohn Forte 	IMA_AUTHMETHOD method,
2947*fcf3ce44SJohn Forte 	IMA_INITIATOR_AUTHPARMS *pParms
2948*fcf3ce44SJohn Forte )
2949*fcf3ce44SJohn Forte {
2950*fcf3ce44SJohn Forte 	int fd;
2951*fcf3ce44SJohn Forte 	iscsi_chap_props_t  chap_p;
2952*fcf3ce44SJohn Forte 
2953*fcf3ce44SJohn Forte 	if (pParms == NULL) {
2954*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
2955*fcf3ce44SJohn Forte 	}
2956*fcf3ce44SJohn Forte 
2957*fcf3ce44SJohn Forte 	if (oid.objectType != IMA_OBJECT_TYPE_TARGET) {
2958*fcf3ce44SJohn Forte 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
2959*fcf3ce44SJohn Forte 	}
2960*fcf3ce44SJohn Forte 
2961*fcf3ce44SJohn Forte 	if (method != IMA_AUTHMETHOD_CHAP) {
2962*fcf3ce44SJohn Forte 		return (IMA_ERROR_INVALID_PARAMETER);
2963*fcf3ce44SJohn Forte 	}
2964*fcf3ce44SJohn Forte 
2965*fcf3ce44SJohn Forte 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2966*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2967*fcf3ce44SJohn Forte 		    ISCSI_DRIVER_DEVCTL, errno);
2968*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2969*fcf3ce44SJohn Forte 	}
2970*fcf3ce44SJohn Forte 
2971*fcf3ce44SJohn Forte 	(void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
2972*fcf3ce44SJohn Forte 	chap_p.c_vers = ISCSI_INTERFACE_VERSION;
2973*fcf3ce44SJohn Forte 	chap_p.c_oid = (uint32_t)oid.objectSequenceNumber;
2974*fcf3ce44SJohn Forte 
2975*fcf3ce44SJohn Forte 	if (ioctl(fd, ISCSI_CHAP_GET, &chap_p) != 0) {
2976*fcf3ce44SJohn Forte 		syslog(LOG_USER|LOG_DEBUG,
2977*fcf3ce44SJohn Forte 
2978*fcf3ce44SJohn Forte 		    "ISCSI_CHAP_GET ioctl failed, errno: %d",
2979*fcf3ce44SJohn Forte 		    errno);
2980*fcf3ce44SJohn Forte 		(void) close(fd);
2981*fcf3ce44SJohn Forte 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2982*fcf3ce44SJohn Forte 	}
2983*fcf3ce44SJohn Forte 
2984*fcf3ce44SJohn Forte 	(void) memcpy(pParms->chapParms.name, chap_p.c_user,
2985*fcf3ce44SJohn Forte 	    chap_p.c_user_len);
2986*fcf3ce44SJohn Forte 
2987*fcf3ce44SJohn Forte 	pParms->chapParms.nameLength = chap_p.c_user_len;
2988*fcf3ce44SJohn Forte 	(void) memcpy(pParms->chapParms.challengeSecret, chap_p.c_secret,
2989*fcf3ce44SJohn Forte 	    chap_p.c_secret_len);
2990*fcf3ce44SJohn Forte 
2991*fcf3ce44SJohn Forte 	pParms->chapParms.challengeSecretLength = chap_p.c_secret_len;
2992*fcf3ce44SJohn Forte 
2993*fcf3ce44SJohn Forte 	return (IMA_STATUS_SUCCESS);
2994*fcf3ce44SJohn Forte }
2995