xref: /onnv-gate/usr/src/lib/libsun_ima/common/ima.c (revision 8656:d00942080f9a)
17836SJohn.Forte@Sun.COM /*
27836SJohn.Forte@Sun.COM  * CDDL HEADER START
37836SJohn.Forte@Sun.COM  *
47836SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
57836SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
67836SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
77836SJohn.Forte@Sun.COM  *
87836SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97836SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
107836SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
117836SJohn.Forte@Sun.COM  * and limitations under the License.
127836SJohn.Forte@Sun.COM  *
137836SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
147836SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157836SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
167836SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
177836SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
187836SJohn.Forte@Sun.COM  *
197836SJohn.Forte@Sun.COM  * CDDL HEADER END
207836SJohn.Forte@Sun.COM  */
217836SJohn.Forte@Sun.COM /*
22*8656SPeter.Dunlap@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237836SJohn.Forte@Sun.COM  * Use is subject to license terms.
247836SJohn.Forte@Sun.COM  */
257836SJohn.Forte@Sun.COM 
267836SJohn.Forte@Sun.COM #include <arpa/inet.h>
277836SJohn.Forte@Sun.COM #include <sys/socket.h>
287836SJohn.Forte@Sun.COM #include <sys/types.h>
297836SJohn.Forte@Sun.COM #include <stdarg.h>
307836SJohn.Forte@Sun.COM #include <stdlib.h>
317836SJohn.Forte@Sun.COM #include <string.h>
327836SJohn.Forte@Sun.COM #include <strings.h>
337836SJohn.Forte@Sun.COM #include <unistd.h>
347836SJohn.Forte@Sun.COM #include <syslog.h>
357836SJohn.Forte@Sun.COM #include <errno.h>
367836SJohn.Forte@Sun.COM #include <wchar.h>
377836SJohn.Forte@Sun.COM #include <widec.h>
387836SJohn.Forte@Sun.COM #include <libsysevent.h>
397836SJohn.Forte@Sun.COM #include <sys/nvpair.h>
407836SJohn.Forte@Sun.COM #include <fcntl.h>
417836SJohn.Forte@Sun.COM #include <stdio.h>
427836SJohn.Forte@Sun.COM #include <time.h>
437836SJohn.Forte@Sun.COM #include <libdevinfo.h>
447836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_if.h>
45*8656SPeter.Dunlap@Sun.COM #include <sys/iscsi_protocol.h>
467836SJohn.Forte@Sun.COM #include <ima.h>
477836SJohn.Forte@Sun.COM 
487836SJohn.Forte@Sun.COM #define	LIBRARY_PROPERTY_IMPLEMENTATION_VERSION	L"1.0.0"
497836SJohn.Forte@Sun.COM #define	LIBRARY_PROPERTY_VENDOR			L"Sun Microsystems, Inc."
507836SJohn.Forte@Sun.COM #define	OS_DEVICE_NAME 				"/devices/iscsi"
517836SJohn.Forte@Sun.COM #define	LIBRARY_FILE_NAME			L"libsun_ima.so"
527836SJohn.Forte@Sun.COM 
537836SJohn.Forte@Sun.COM #define	OS_DEVICE_NAME_LEN		256
547836SJohn.Forte@Sun.COM #define	INQUIRY_CMD			0x12
557836SJohn.Forte@Sun.COM #define	GETCAPACITY_CMD  		0x25
567836SJohn.Forte@Sun.COM #define	INQUIRY_CMDLEN			6
577836SJohn.Forte@Sun.COM #define	INQUIRY_REPLY_LEN		96
587836SJohn.Forte@Sun.COM #define	USCSI_TIMEOUT_IN_SEC		10
597836SJohn.Forte@Sun.COM #define	MAX_AUTHMETHODS			10
607836SJohn.Forte@Sun.COM #define	NUM_SUPPORTED_AUTH_METHODS	2
617836SJohn.Forte@Sun.COM #define	SUN_IMA_MAX_DIGEST_ALGORITHMS	2	/* NONE and CRC 32 */
627836SJohn.Forte@Sun.COM #define	SUN_IMA_IP_ADDRESS_LEN		256
637836SJohn.Forte@Sun.COM #define	SUN_IMA_IP_PORT_LEN		64
647836SJohn.Forte@Sun.COM #define	SUN_IMA_MAX_RADIUS_SECRET_LEN	128
657836SJohn.Forte@Sun.COM 
667836SJohn.Forte@Sun.COM /* Forward declaration */
677836SJohn.Forte@Sun.COM #define	BOOL_PARAM			1
687836SJohn.Forte@Sun.COM #define	MIN_MAX_PARAM			2
697836SJohn.Forte@Sun.COM 
707836SJohn.Forte@Sun.COM /* OK */
717836SJohn.Forte@Sun.COM #define	DISC_ADDR_OK			0
727836SJohn.Forte@Sun.COM /* Incorrect IP address */
737836SJohn.Forte@Sun.COM #define	DISC_ADDR_INTEGRITY_ERROR   	1
747836SJohn.Forte@Sun.COM /* Error converting text IP address to numeric binary form */
757836SJohn.Forte@Sun.COM #define	DISC_ADDR_IP_CONV_ERROR		2
767836SJohn.Forte@Sun.COM 
777836SJohn.Forte@Sun.COM /* Currently not defined in  IMA_TARGET_DISCOVERY_METHOD enum */
787836SJohn.Forte@Sun.COM #define	IMA_TARGET_DISCOVERY_METHOD_UNKNOWN  0
797836SJohn.Forte@Sun.COM 
807836SJohn.Forte@Sun.COM static IMA_OID		lhbaObjectId;
817836SJohn.Forte@Sun.COM static IMA_UINT32	pluginOwnerId;
827836SJohn.Forte@Sun.COM static sysevent_handle_t *shp;
837836SJohn.Forte@Sun.COM 
847836SJohn.Forte@Sun.COM 
857836SJohn.Forte@Sun.COM 
867836SJohn.Forte@Sun.COM /*
877836SJohn.Forte@Sun.COM  * Custom struct to allow tgpt to be specified.
887836SJohn.Forte@Sun.COM  */
897836SJohn.Forte@Sun.COM typedef struct _SUN_IMA_DISC_ADDRESS_KEY
907836SJohn.Forte@Sun.COM {
917836SJohn.Forte@Sun.COM 	IMA_NODE_NAME name;
927836SJohn.Forte@Sun.COM 	IMA_ADDRESS_KEY	address;
937836SJohn.Forte@Sun.COM 	IMA_UINT16 tpgt;
947836SJohn.Forte@Sun.COM } SUN_IMA_DISC_ADDRESS_KEY;
957836SJohn.Forte@Sun.COM 
967836SJohn.Forte@Sun.COM /*
977836SJohn.Forte@Sun.COM  * Custom struct to allow tgpt to be specified.
987836SJohn.Forte@Sun.COM  */
997836SJohn.Forte@Sun.COM typedef struct _SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
1007836SJohn.Forte@Sun.COM {
1017836SJohn.Forte@Sun.COM 	IMA_UINT keyCount;
1027836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDRESS_KEY keys[1];
1037836SJohn.Forte@Sun.COM } SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES;
1047836SJohn.Forte@Sun.COM 
1057836SJohn.Forte@Sun.COM /*
1067836SJohn.Forte@Sun.COM  * Custom struct to allow tgpt to be specified.
1077836SJohn.Forte@Sun.COM  */
1087836SJohn.Forte@Sun.COM typedef struct _SUN_IMA_DISC_ADDR_PROP_LIST
1097836SJohn.Forte@Sun.COM {
1107836SJohn.Forte@Sun.COM 	IMA_UINT discAddrCount;
1117836SJohn.Forte@Sun.COM 	IMA_DISCOVERY_ADDRESS_PROPERTIES props[1];
1127836SJohn.Forte@Sun.COM } SUN_IMA_DISC_ADDR_PROP_LIST;
1137836SJohn.Forte@Sun.COM 
1147836SJohn.Forte@Sun.COM 
1157836SJohn.Forte@Sun.COM static IMA_OBJECT_VISIBILITY_FN pObjectVisibilityCallback = NULL;
1167836SJohn.Forte@Sun.COM static IMA_OBJECT_PROPERTY_FN pObjectPropertyCallback = NULL;
1177836SJohn.Forte@Sun.COM 
1187836SJohn.Forte@Sun.COM static IMA_STATUS getISCSINodeParameter(int paramType, IMA_OID *oid,
1197836SJohn.Forte@Sun.COM     void *pProps, uint32_t paramIndex);
1207836SJohn.Forte@Sun.COM static IMA_STATUS setISCSINodeParameter(int paramType, IMA_OID *oid,
1217836SJohn.Forte@Sun.COM     void *pProps, uint32_t paramIndex);
1227836SJohn.Forte@Sun.COM static IMA_STATUS setAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount,
1237836SJohn.Forte@Sun.COM     const IMA_AUTHMETHOD *pMethodList);
1247836SJohn.Forte@Sun.COM static IMA_STATUS getAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount,
1257836SJohn.Forte@Sun.COM     IMA_AUTHMETHOD *pMethodList);
1267836SJohn.Forte@Sun.COM 
1277836SJohn.Forte@Sun.COM static int prepare_discovery_entry(IMA_TARGET_ADDRESS discoveryAddress,
1287836SJohn.Forte@Sun.COM     entry_t *entry);
1297836SJohn.Forte@Sun.COM static IMA_STATUS configure_discovery_method(IMA_BOOL enable,
1307836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t method);
1317836SJohn.Forte@Sun.COM static IMA_STATUS get_target_oid_list(uint32_t targetListType,
1327836SJohn.Forte@Sun.COM     IMA_OID_LIST **ppList);
1337836SJohn.Forte@Sun.COM static IMA_STATUS get_target_lun_oid_list(IMA_OID * targetOid,
1347836SJohn.Forte@Sun.COM 		iscsi_lun_list_t  **ppLunList);
1357836SJohn.Forte@Sun.COM static int get_lun_devlink(di_devlink_t link, void *osDeviceName);
1367836SJohn.Forte@Sun.COM static IMA_STATUS getDiscoveryAddressPropertiesList(
1377836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDR_PROP_LIST **ppList
1387836SJohn.Forte@Sun.COM );
1397836SJohn.Forte@Sun.COM static IMA_STATUS sendTargets(IMA_TARGET_ADDRESS address,
1407836SJohn.Forte@Sun.COM     SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
1417836SJohn.Forte@Sun.COM );
1427836SJohn.Forte@Sun.COM 
1437836SJohn.Forte@Sun.COM static IMA_STATUS getSupportedAuthMethods(IMA_OID lhbaOid,
1447836SJohn.Forte@Sun.COM     IMA_BOOL getSettableMethods, IMA_UINT *pMethodCount,
1457836SJohn.Forte@Sun.COM     IMA_AUTHMETHOD *pMethodList);
1467836SJohn.Forte@Sun.COM static IMA_STATUS getLuProperties(IMA_OID luId, IMA_LU_PROPERTIES *pProps);
1477836SJohn.Forte@Sun.COM static IMA_STATUS getTargetProperties(IMA_OID targetId,
1487836SJohn.Forte@Sun.COM     IMA_TARGET_PROPERTIES *pProps);
1497836SJohn.Forte@Sun.COM 
1507836SJohn.Forte@Sun.COM void InitLibrary();
1517836SJohn.Forte@Sun.COM 
1527836SJohn.Forte@Sun.COM static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...)
1537836SJohn.Forte@Sun.COM {
1547836SJohn.Forte@Sun.COM 	va_list args;
1557836SJohn.Forte@Sun.COM 	va_start(args, lpszFormat);
1567836SJohn.Forte@Sun.COM 	(void) vswprintf(wcs, OS_DEVICE_NAME_LEN - 1, lpszFormat, args);
1577836SJohn.Forte@Sun.COM 	va_end(args);
1587836SJohn.Forte@Sun.COM }
1597836SJohn.Forte@Sun.COM 
1607836SJohn.Forte@Sun.COM static void
1617836SJohn.Forte@Sun.COM sysevent_handler(sysevent_t *ev)
1627836SJohn.Forte@Sun.COM {
1637836SJohn.Forte@Sun.COM 	IMA_OID tmpOid;
1647836SJohn.Forte@Sun.COM 	IMA_BOOL becomingVisible = IMA_FALSE;
1657836SJohn.Forte@Sun.COM 	IMA_UINT i;
1667836SJohn.Forte@Sun.COM 
1677836SJohn.Forte@Sun.COM 	const char *visibility_subclasses[] = {
1687836SJohn.Forte@Sun.COM 		ESC_ISCSI_STATIC_START,
1697836SJohn.Forte@Sun.COM 		ESC_ISCSI_STATIC_END,
1707836SJohn.Forte@Sun.COM 		ESC_ISCSI_SEND_TARGETS_START,
1717836SJohn.Forte@Sun.COM 		ESC_ISCSI_SEND_TARGETS_END,
1727836SJohn.Forte@Sun.COM 		ESC_ISCSI_SLP_START,
1737836SJohn.Forte@Sun.COM 		ESC_ISCSI_SLP_END,
1747836SJohn.Forte@Sun.COM 		ESC_ISCSI_ISNS_START,
1757836SJohn.Forte@Sun.COM 		ESC_ISCSI_ISNS_END,
1767836SJohn.Forte@Sun.COM 		NULL
1777836SJohn.Forte@Sun.COM 	};
1787836SJohn.Forte@Sun.COM 
1797836SJohn.Forte@Sun.COM 	tmpOid.ownerId = pluginOwnerId;
1807836SJohn.Forte@Sun.COM 	tmpOid.objectType = IMA_OBJECT_TYPE_TARGET;
1817836SJohn.Forte@Sun.COM 	tmpOid.objectSequenceNumber = 0;
1827836SJohn.Forte@Sun.COM 
1837836SJohn.Forte@Sun.COM 	/* Make sure our event class matches what we are looking for */
1847836SJohn.Forte@Sun.COM 	if (strncmp(EC_ISCSI, sysevent_get_class_name(ev),
1857836SJohn.Forte@Sun.COM 	    strlen(EC_ISCSI)) != 0) {
1867836SJohn.Forte@Sun.COM 		return;
1877836SJohn.Forte@Sun.COM 	}
1887836SJohn.Forte@Sun.COM 
1897836SJohn.Forte@Sun.COM 
1907836SJohn.Forte@Sun.COM 	/* Check for object property changes */
1917836SJohn.Forte@Sun.COM 	if ((strncmp(ESC_ISCSI_PROP_CHANGE,
1927836SJohn.Forte@Sun.COM 	    sysevent_get_subclass_name(ev),
1937836SJohn.Forte@Sun.COM 	    strlen(ESC_ISCSI_PROP_CHANGE)) == 0)) {
1947836SJohn.Forte@Sun.COM 		if (pObjectPropertyCallback != NULL)
1957836SJohn.Forte@Sun.COM 			pObjectPropertyCallback(tmpOid);
1967836SJohn.Forte@Sun.COM 	} else {
1977836SJohn.Forte@Sun.COM 		i = 0;
1987836SJohn.Forte@Sun.COM 		while (visibility_subclasses[i] != NULL) {
1997836SJohn.Forte@Sun.COM 			if ((strncmp(visibility_subclasses[i],
2007836SJohn.Forte@Sun.COM 			    sysevent_get_subclass_name(ev),
2017836SJohn.Forte@Sun.COM 			    strlen(visibility_subclasses[i])) == 0) &&
2027836SJohn.Forte@Sun.COM 			    pObjectVisibilityCallback != NULL) {
2037836SJohn.Forte@Sun.COM 				becomingVisible = IMA_TRUE;
2047836SJohn.Forte@Sun.COM 				pObjectVisibilityCallback(becomingVisible,
2057836SJohn.Forte@Sun.COM 				    tmpOid);
2067836SJohn.Forte@Sun.COM 			}
2077836SJohn.Forte@Sun.COM 			i++;
2087836SJohn.Forte@Sun.COM 		}
2097836SJohn.Forte@Sun.COM 	}
2107836SJohn.Forte@Sun.COM }
2117836SJohn.Forte@Sun.COM 
2127836SJohn.Forte@Sun.COM IMA_STATUS init_sysevents() {
2137836SJohn.Forte@Sun.COM 	const char *subclass_list[] = {
2147836SJohn.Forte@Sun.COM 		ESC_ISCSI_STATIC_START,
2157836SJohn.Forte@Sun.COM 		ESC_ISCSI_STATIC_END,
2167836SJohn.Forte@Sun.COM 		ESC_ISCSI_SEND_TARGETS_START,
2177836SJohn.Forte@Sun.COM 		ESC_ISCSI_SEND_TARGETS_END,
2187836SJohn.Forte@Sun.COM 		ESC_ISCSI_SLP_START,
2197836SJohn.Forte@Sun.COM 		ESC_ISCSI_SLP_END,
2207836SJohn.Forte@Sun.COM 		ESC_ISCSI_ISNS_START,
2217836SJohn.Forte@Sun.COM 		ESC_ISCSI_ISNS_END,
2227836SJohn.Forte@Sun.COM 		ESC_ISCSI_PROP_CHANGE,
2237836SJohn.Forte@Sun.COM 	};
2247836SJohn.Forte@Sun.COM 
2257836SJohn.Forte@Sun.COM 	/* Bind event handler and create subscriber handle */
2267836SJohn.Forte@Sun.COM 	shp = sysevent_bind_handle(sysevent_handler);
2277836SJohn.Forte@Sun.COM 	if (shp == NULL) {
2287836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2297836SJohn.Forte@Sun.COM 	}
2307836SJohn.Forte@Sun.COM 
2317836SJohn.Forte@Sun.COM 	if (sysevent_subscribe_event(shp, EC_ISCSI, subclass_list, 9) != 0) {
2327836SJohn.Forte@Sun.COM 		sysevent_unbind_handle(shp);
2337836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2347836SJohn.Forte@Sun.COM 	}
2357836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
2367836SJohn.Forte@Sun.COM }
2377836SJohn.Forte@Sun.COM 
2387836SJohn.Forte@Sun.COM IMA_STATUS Initialize(IMA_UINT32 pluginOid) {
2397836SJohn.Forte@Sun.COM 	pluginOwnerId = pluginOid;
2407836SJohn.Forte@Sun.COM 	return (init_sysevents());
2417836SJohn.Forte@Sun.COM }
2427836SJohn.Forte@Sun.COM 
2437836SJohn.Forte@Sun.COM void Terminate() {
2447836SJohn.Forte@Sun.COM 	if (shp != NULL) {
2457836SJohn.Forte@Sun.COM 		sysevent_unsubscribe_event(shp, EC_ISCSI);
2467836SJohn.Forte@Sun.COM 	}
2477836SJohn.Forte@Sun.COM 
2487836SJohn.Forte@Sun.COM }
2497836SJohn.Forte@Sun.COM 
2507836SJohn.Forte@Sun.COM void InitLibrary() {
2517836SJohn.Forte@Sun.COM }
2527836SJohn.Forte@Sun.COM 
2537836SJohn.Forte@Sun.COM static void GetBuildTime(IMA_DATETIME* pdatetime)
2547836SJohn.Forte@Sun.COM {
2557836SJohn.Forte@Sun.COM 	(void) memset(pdatetime, 0, sizeof (IMA_DATETIME));
2567836SJohn.Forte@Sun.COM }
2577836SJohn.Forte@Sun.COM 
2587836SJohn.Forte@Sun.COM /*ARGSUSED*/
2597836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetNodeProperties(
2607836SJohn.Forte@Sun.COM 	IMA_OID nodeOid,
2617836SJohn.Forte@Sun.COM 	IMA_NODE_PROPERTIES *pProps
2627836SJohn.Forte@Sun.COM )
2637836SJohn.Forte@Sun.COM {
2647836SJohn.Forte@Sun.COM 	int fd;
2657836SJohn.Forte@Sun.COM 	iscsi_param_get_t pg;
2667836SJohn.Forte@Sun.COM 
2677836SJohn.Forte@Sun.COM 	pProps->runningInInitiatorMode = IMA_TRUE;
2687836SJohn.Forte@Sun.COM 	pProps->runningInTargetMode = IMA_FALSE;
2697836SJohn.Forte@Sun.COM 	pProps->nameAndAliasSettable = IMA_FALSE;
2707836SJohn.Forte@Sun.COM 
2717836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
2727836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
2737836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
2747836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
2757836SJohn.Forte@Sun.COM 	}
2767836SJohn.Forte@Sun.COM 
2777836SJohn.Forte@Sun.COM 	(void) memset(&pg, 0, sizeof (iscsi_param_get_t));
2787836SJohn.Forte@Sun.COM 	pg.g_vers = ISCSI_INTERFACE_VERSION;
2797836SJohn.Forte@Sun.COM 	pg.g_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME;
2807836SJohn.Forte@Sun.COM 
2817836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_PARAM_GET, &pg) == -1) {
2827836SJohn.Forte@Sun.COM 		pProps->nameValid = IMA_FALSE;
2837836SJohn.Forte@Sun.COM 	} else {
2847836SJohn.Forte@Sun.COM 		if (strlen((char *)pg.g_value.v_name) > 0) {
2857836SJohn.Forte@Sun.COM 			(void) mbstowcs(pProps->name,
2867836SJohn.Forte@Sun.COM 			    (char *)pg.g_value.v_name,
2877836SJohn.Forte@Sun.COM 			    IMA_NODE_NAME_LEN);
2887836SJohn.Forte@Sun.COM 			pProps->nameValid = IMA_TRUE;
2897836SJohn.Forte@Sun.COM 		} else {
2907836SJohn.Forte@Sun.COM 			pProps->nameValid = IMA_FALSE;
2917836SJohn.Forte@Sun.COM 		}
2927836SJohn.Forte@Sun.COM 	}
2937836SJohn.Forte@Sun.COM 
2947836SJohn.Forte@Sun.COM 	(void) memset(&pg, 0, sizeof (iscsi_param_get_t));
2957836SJohn.Forte@Sun.COM 	pg.g_vers = ISCSI_INTERFACE_VERSION;
2967836SJohn.Forte@Sun.COM 	pg.g_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS;
2977836SJohn.Forte@Sun.COM 	(void) memset(pProps->alias, 0,
2987836SJohn.Forte@Sun.COM 	    sizeof (IMA_WCHAR) * IMA_NODE_ALIAS_LEN);
2997836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_PARAM_GET, &pg) == -1) {
3007836SJohn.Forte@Sun.COM 		pProps->aliasValid = IMA_FALSE;
3017836SJohn.Forte@Sun.COM 	} else {
3027836SJohn.Forte@Sun.COM 		if (strlen((char *)pg.g_value.v_name) > 0) {
3037836SJohn.Forte@Sun.COM 			(void) mbstowcs(pProps->alias,
3047836SJohn.Forte@Sun.COM 			    (char *)pg.g_value.v_name,
3057836SJohn.Forte@Sun.COM 			    IMA_NODE_ALIAS_LEN);
3067836SJohn.Forte@Sun.COM 			pProps->aliasValid = IMA_TRUE;
3077836SJohn.Forte@Sun.COM 		}
3087836SJohn.Forte@Sun.COM 	}
3097836SJohn.Forte@Sun.COM 
3107836SJohn.Forte@Sun.COM 	(void) close(fd);
3117836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
3127836SJohn.Forte@Sun.COM }
3137836SJohn.Forte@Sun.COM 
3147836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetNodeName(
3157836SJohn.Forte@Sun.COM 	IMA_OID nodeOid,
3167836SJohn.Forte@Sun.COM 	const IMA_NODE_NAME newName
3177836SJohn.Forte@Sun.COM )
3187836SJohn.Forte@Sun.COM {
3197836SJohn.Forte@Sun.COM 	int fd;
3207836SJohn.Forte@Sun.COM 	iscsi_param_set_t ps;
3217836SJohn.Forte@Sun.COM 
3227836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
3237836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
3247836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
3257836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3267836SJohn.Forte@Sun.COM 	}
3277836SJohn.Forte@Sun.COM 
3287836SJohn.Forte@Sun.COM 	(void) memset(&ps, 0, sizeof (iscsi_param_set_t));
3297836SJohn.Forte@Sun.COM 	ps.s_oid = nodeOid.objectSequenceNumber;
3307836SJohn.Forte@Sun.COM 	ps.s_vers = ISCSI_INTERFACE_VERSION;
3317836SJohn.Forte@Sun.COM 	ps.s_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME;
3327836SJohn.Forte@Sun.COM 	(void) wcstombs((char *)ps.s_value.v_name, newName, ISCSI_MAX_NAME_LEN);
3337836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_INIT_NODE_NAME_SET, &ps)) {
3347836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
3357836SJohn.Forte@Sun.COM 		    "ISCSI_PARAM_SET ioctl failed, errno: %d", errno);
3367836SJohn.Forte@Sun.COM 		(void) close(fd);
3377836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3387836SJohn.Forte@Sun.COM 	}
3397836SJohn.Forte@Sun.COM 
3407836SJohn.Forte@Sun.COM 	(void) close(fd);
3417836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
3427836SJohn.Forte@Sun.COM }
3437836SJohn.Forte@Sun.COM 
3447836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetNodeAlias(
3457836SJohn.Forte@Sun.COM 	IMA_OID nodeOid,
3467836SJohn.Forte@Sun.COM 	const IMA_NODE_ALIAS newAlias
3477836SJohn.Forte@Sun.COM )
3487836SJohn.Forte@Sun.COM {
3497836SJohn.Forte@Sun.COM 	int fd;
3507836SJohn.Forte@Sun.COM 	iscsi_param_set_t ps;
3517836SJohn.Forte@Sun.COM 
3527836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
3537836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
3547836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
3557836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3567836SJohn.Forte@Sun.COM 	}
3577836SJohn.Forte@Sun.COM 
3587836SJohn.Forte@Sun.COM 	(void) memset(&ps, 0, sizeof (iscsi_param_set_t));
3597836SJohn.Forte@Sun.COM 	ps.s_oid = nodeOid.objectSequenceNumber;
3607836SJohn.Forte@Sun.COM 	ps.s_vers = ISCSI_INTERFACE_VERSION;
3617836SJohn.Forte@Sun.COM 	ps.s_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS;
3627836SJohn.Forte@Sun.COM 
3637836SJohn.Forte@Sun.COM 	/* newAlias = NULL specifies that the alias should be deleted. */
3647836SJohn.Forte@Sun.COM 	if (newAlias != NULL)
3657836SJohn.Forte@Sun.COM 		(void) wcstombs((char *)ps.s_value.v_name, newAlias,
3667836SJohn.Forte@Sun.COM 		    ISCSI_MAX_NAME_LEN);
3677836SJohn.Forte@Sun.COM 	else
3687836SJohn.Forte@Sun.COM 		(void) wcstombs((char *)ps.s_value.v_name,
3697836SJohn.Forte@Sun.COM 		    L"", ISCSI_MAX_NAME_LEN);
3707836SJohn.Forte@Sun.COM 
3717836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_PARAM_SET, &ps)) {
3727836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
3737836SJohn.Forte@Sun.COM 		    "ISCSI_PARAM_SET ioctl failed, errno: %d", errno);
3747836SJohn.Forte@Sun.COM 		(void) close(fd);
3757836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
3767836SJohn.Forte@Sun.COM 	}
3777836SJohn.Forte@Sun.COM 
3787836SJohn.Forte@Sun.COM 	(void) close(fd);
3797836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
3807836SJohn.Forte@Sun.COM }
3817836SJohn.Forte@Sun.COM 
3827836SJohn.Forte@Sun.COM 
3837836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetLhbaOidList(
3847836SJohn.Forte@Sun.COM 	IMA_OID_LIST **ppList
3857836SJohn.Forte@Sun.COM )
3867836SJohn.Forte@Sun.COM {
3877836SJohn.Forte@Sun.COM 	/* Always return the same object ID for the lhba */
3887836SJohn.Forte@Sun.COM 	lhbaObjectId.objectType = IMA_OBJECT_TYPE_LHBA;
3897836SJohn.Forte@Sun.COM 	lhbaObjectId.ownerId = pluginOwnerId;
3907836SJohn.Forte@Sun.COM 	lhbaObjectId.objectSequenceNumber = ISCSI_INITIATOR_OID;
3917836SJohn.Forte@Sun.COM 
3927836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST));
3937836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
3947836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
3957836SJohn.Forte@Sun.COM 	}
3967836SJohn.Forte@Sun.COM 
3977836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = 1;
3987836SJohn.Forte@Sun.COM 	(void) memcpy(&(*ppList)->oids[0],
3997836SJohn.Forte@Sun.COM 	    &lhbaObjectId, sizeof (lhbaObjectId));
4007836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
4017836SJohn.Forte@Sun.COM }
4027836SJohn.Forte@Sun.COM 
4037836SJohn.Forte@Sun.COM 
4047836SJohn.Forte@Sun.COM /*
4057836SJohn.Forte@Sun.COM  * Get the discovery properties of the LHBA
4067836SJohn.Forte@Sun.COM  */
4077836SJohn.Forte@Sun.COM /*ARGSUSED*/
4087836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetDiscoveryProperties(
4097836SJohn.Forte@Sun.COM 	IMA_OID oid,
4107836SJohn.Forte@Sun.COM 	IMA_DISCOVERY_PROPERTIES *pProps
4117836SJohn.Forte@Sun.COM )
4127836SJohn.Forte@Sun.COM {
4137836SJohn.Forte@Sun.COM 	int fd;
4147836SJohn.Forte@Sun.COM 	iSCSIDiscoveryProperties_t discoveryProps;
4157836SJohn.Forte@Sun.COM 
4167836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
4177836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
4187836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
4197836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
4207836SJohn.Forte@Sun.COM 	}
4217836SJohn.Forte@Sun.COM 
4227836SJohn.Forte@Sun.COM 	(void) memset(&discoveryProps, 0, sizeof (discoveryProps));
4237836SJohn.Forte@Sun.COM 	discoveryProps.vers = ISCSI_INTERFACE_VERSION;
4247836SJohn.Forte@Sun.COM 
4257836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_PROPS, &discoveryProps) != 0) {
4267836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
4277836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_PROPS ioctl failed, errno: %d", errno);
4287836SJohn.Forte@Sun.COM 		(void) close(fd);
4297836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
4307836SJohn.Forte@Sun.COM 	}
4317836SJohn.Forte@Sun.COM 
4327836SJohn.Forte@Sun.COM 	pProps->iSnsDiscoverySettable = discoveryProps.iSNSDiscoverySettable;
4337836SJohn.Forte@Sun.COM 	pProps->iSnsDiscoveryEnabled = discoveryProps.iSNSDiscoveryEnabled;
4347836SJohn.Forte@Sun.COM 	/*
4357836SJohn.Forte@Sun.COM 	 * Set the iSNS discovery method - The IMA specification indicates
4367836SJohn.Forte@Sun.COM 	 * this field is valid only if iSNS discovery is enabled.
4377836SJohn.Forte@Sun.COM 	 */
4387836SJohn.Forte@Sun.COM 	if (pProps->iSnsDiscoveryEnabled == IMA_TRUE) {
4397836SJohn.Forte@Sun.COM 		switch (discoveryProps.iSNSDiscoveryMethod) {
4407836SJohn.Forte@Sun.COM 			case iSNSDiscoveryMethodStatic:
4417836SJohn.Forte@Sun.COM 				pProps->iSnsDiscoveryMethod =
4427836SJohn.Forte@Sun.COM 				    IMA_ISNS_DISCOVERY_METHOD_STATIC;
4437836SJohn.Forte@Sun.COM 				break;
4447836SJohn.Forte@Sun.COM 			case iSNSDiscoveryMethodDHCP:
4457836SJohn.Forte@Sun.COM 				pProps->iSnsDiscoveryMethod =
4467836SJohn.Forte@Sun.COM 				    IMA_ISNS_DISCOVERY_METHOD_DHCP;
4477836SJohn.Forte@Sun.COM 				break;
4487836SJohn.Forte@Sun.COM 			case iSNSDiscoveryMethodSLP:
4497836SJohn.Forte@Sun.COM 				pProps->iSnsDiscoveryMethod =
4507836SJohn.Forte@Sun.COM 				    IMA_ISNS_DISCOVERY_METHOD_SLP;
4517836SJohn.Forte@Sun.COM 				break;
4527836SJohn.Forte@Sun.COM 			default:
4537836SJohn.Forte@Sun.COM 				(void) close(fd);
4547836SJohn.Forte@Sun.COM 				return (IMA_ERROR_UNEXPECTED_OS_ERROR);
4557836SJohn.Forte@Sun.COM 		}
4567836SJohn.Forte@Sun.COM 	}
4577836SJohn.Forte@Sun.COM 	(void) memcpy(pProps->iSnsHost.id.hostname,
4587836SJohn.Forte@Sun.COM 	    discoveryProps.iSNSDomainName,
4597836SJohn.Forte@Sun.COM 	    sizeof (pProps->iSnsHost.id.hostname));
4607836SJohn.Forte@Sun.COM 	pProps->slpDiscoverySettable = discoveryProps.SLPDiscoverySettable;
4617836SJohn.Forte@Sun.COM 	pProps->slpDiscoveryEnabled = discoveryProps.SLPDiscoveryEnabled;
4627836SJohn.Forte@Sun.COM 	pProps->staticDiscoverySettable =
4637836SJohn.Forte@Sun.COM 	    discoveryProps.StaticDiscoverySettable;
4647836SJohn.Forte@Sun.COM 	pProps->staticDiscoveryEnabled = discoveryProps.StaticDiscoveryEnabled;
4657836SJohn.Forte@Sun.COM 	pProps->sendTargetsDiscoverySettable =
4667836SJohn.Forte@Sun.COM 	    discoveryProps.SendTargetsDiscoverySettable;
4677836SJohn.Forte@Sun.COM 	pProps->sendTargetsDiscoveryEnabled =
4687836SJohn.Forte@Sun.COM 	    discoveryProps.SendTargetsDiscoveryEnabled;
4697836SJohn.Forte@Sun.COM 
4707836SJohn.Forte@Sun.COM 	(void) close(fd);
4717836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
4727836SJohn.Forte@Sun.COM }
4737836SJohn.Forte@Sun.COM 
4747836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_FreeMemory(
4757836SJohn.Forte@Sun.COM 	void *pMemory
4767836SJohn.Forte@Sun.COM )
4777836SJohn.Forte@Sun.COM {
4787836SJohn.Forte@Sun.COM 	if (pMemory != NULL)
4797836SJohn.Forte@Sun.COM 		free(pMemory);
4807836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
4817836SJohn.Forte@Sun.COM }
4827836SJohn.Forte@Sun.COM 
4837836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetNonSharedNodeOidList(
4847836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
4857836SJohn.Forte@Sun.COM )
4867836SJohn.Forte@Sun.COM {
4877836SJohn.Forte@Sun.COM 	if (ppList == NULL)
4887836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
4897836SJohn.Forte@Sun.COM 
4907836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST*) calloc(1, sizeof (IMA_OID_LIST));
4917836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
4927836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
4937836SJohn.Forte@Sun.COM 	}
4947836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = 0;
4957836SJohn.Forte@Sun.COM 
4967836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
4977836SJohn.Forte@Sun.COM }
4987836SJohn.Forte@Sun.COM 
4997836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetFirstBurstLengthProperties(
5007836SJohn.Forte@Sun.COM 		IMA_OID Oid,
5017836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
5027836SJohn.Forte@Sun.COM )
5037836SJohn.Forte@Sun.COM {
5047836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
5057836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH));
5067836SJohn.Forte@Sun.COM }
5077836SJohn.Forte@Sun.COM 
5087836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetMaxBurstLengthProperties(
5097836SJohn.Forte@Sun.COM 		IMA_OID Oid,
5107836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
5117836SJohn.Forte@Sun.COM )
5127836SJohn.Forte@Sun.COM {
5137836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
5147836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH));
5157836SJohn.Forte@Sun.COM }
5167836SJohn.Forte@Sun.COM 
5177836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetMaxRecvDataSegmentLengthProperties(
5187836SJohn.Forte@Sun.COM 		IMA_OID Oid,
5197836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
5207836SJohn.Forte@Sun.COM )
5217836SJohn.Forte@Sun.COM {
5227836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
5237836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH));
5247836SJohn.Forte@Sun.COM }
5257836SJohn.Forte@Sun.COM 
5267836SJohn.Forte@Sun.COM /*ARGSUSED*/
5277836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_PluginIOCtl(
5287836SJohn.Forte@Sun.COM 		IMA_OID pluginOid,
5297836SJohn.Forte@Sun.COM 		IMA_UINT command,
5307836SJohn.Forte@Sun.COM 		const void *pInputBuffer,
5317836SJohn.Forte@Sun.COM 		IMA_UINT inputBufferLength,
5327836SJohn.Forte@Sun.COM 		void *pOutputBuffer,
5337836SJohn.Forte@Sun.COM 		IMA_UINT *pOutputBufferLength
5347836SJohn.Forte@Sun.COM )
5357836SJohn.Forte@Sun.COM {
5367836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
5377836SJohn.Forte@Sun.COM }
5387836SJohn.Forte@Sun.COM 
5397836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetFirstBurstLength(
5407836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
5417836SJohn.Forte@Sun.COM 		IMA_UINT firstBurstLength
5427836SJohn.Forte@Sun.COM )
5437836SJohn.Forte@Sun.COM {
5447836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
5457836SJohn.Forte@Sun.COM 
5467836SJohn.Forte@Sun.COM 	mv.currentValue = firstBurstLength;
5477836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
5487836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH));
5497836SJohn.Forte@Sun.COM }
5507836SJohn.Forte@Sun.COM 
5517836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetMaxBurstLength(
5527836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
5537836SJohn.Forte@Sun.COM 		IMA_UINT maxBurstLength
5547836SJohn.Forte@Sun.COM )
5557836SJohn.Forte@Sun.COM {
5567836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
5577836SJohn.Forte@Sun.COM 
5587836SJohn.Forte@Sun.COM 	mv.currentValue = maxBurstLength;
5597836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
5607836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH));
5617836SJohn.Forte@Sun.COM }
5627836SJohn.Forte@Sun.COM 
5637836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetMaxRecvDataSegmentLength(
5647836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
5657836SJohn.Forte@Sun.COM 		IMA_UINT maxRecvDataSegmentLength
5667836SJohn.Forte@Sun.COM )
5677836SJohn.Forte@Sun.COM {
5687836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
5697836SJohn.Forte@Sun.COM 
5707836SJohn.Forte@Sun.COM 	mv.currentValue = maxRecvDataSegmentLength;
5717836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
5727836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH));
5737836SJohn.Forte@Sun.COM }
5747836SJohn.Forte@Sun.COM 
5757836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetMaxConnectionsProperties(
5767836SJohn.Forte@Sun.COM 		IMA_OID Oid,
5777836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
5787836SJohn.Forte@Sun.COM )
5797836SJohn.Forte@Sun.COM {
5807836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
5817836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_MAX_CONNECTIONS));
5827836SJohn.Forte@Sun.COM }
5837836SJohn.Forte@Sun.COM 
5847836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetMaxConnections(
5857836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
5867836SJohn.Forte@Sun.COM 		IMA_UINT maxConnections
5877836SJohn.Forte@Sun.COM )
5887836SJohn.Forte@Sun.COM {
5897836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
5907836SJohn.Forte@Sun.COM 
5917836SJohn.Forte@Sun.COM 	mv.currentValue = maxConnections;
5927836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
5937836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_MAX_CONNECTIONS));
5947836SJohn.Forte@Sun.COM }
5957836SJohn.Forte@Sun.COM 
5967836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetDefaultTime2RetainProperties(
5977836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
5987836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
5997836SJohn.Forte@Sun.COM )
6007836SJohn.Forte@Sun.COM {
6017836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps,
6027836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN));
6037836SJohn.Forte@Sun.COM }
6047836SJohn.Forte@Sun.COM 
6057836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetDefaultTime2Retain(
6067836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
6077836SJohn.Forte@Sun.COM 		IMA_UINT defaultTime2Retain
6087836SJohn.Forte@Sun.COM )
6097836SJohn.Forte@Sun.COM {
6107836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
6117836SJohn.Forte@Sun.COM 
6127836SJohn.Forte@Sun.COM 	mv.currentValue = defaultTime2Retain;
6137836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
6147836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN));
6157836SJohn.Forte@Sun.COM }
6167836SJohn.Forte@Sun.COM 
6177836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetDefaultTime2WaitProperties(
6187836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
6197836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
6207836SJohn.Forte@Sun.COM )
6217836SJohn.Forte@Sun.COM {
6227836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps,
6237836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT));
6247836SJohn.Forte@Sun.COM }
6257836SJohn.Forte@Sun.COM 
6267836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetDefaultTime2Wait(
6277836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
6287836SJohn.Forte@Sun.COM 		IMA_UINT defaultTime2Wait
6297836SJohn.Forte@Sun.COM )
6307836SJohn.Forte@Sun.COM {
6317836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM 	mv.currentValue = defaultTime2Wait;
6347836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
6357836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT));
6367836SJohn.Forte@Sun.COM }
6377836SJohn.Forte@Sun.COM 
6387836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetMaxOutstandingR2TProperties(
6397836SJohn.Forte@Sun.COM 		IMA_OID Oid,
6407836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
6417836SJohn.Forte@Sun.COM )
6427836SJohn.Forte@Sun.COM {
6437836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
6447836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_OUTSTANDING_R2T));
6457836SJohn.Forte@Sun.COM }
6467836SJohn.Forte@Sun.COM 
6477836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetMaxOutstandingR2T(
6487836SJohn.Forte@Sun.COM 		IMA_OID lhbaId,
6497836SJohn.Forte@Sun.COM 		IMA_UINT maxOutstandingR2T
6507836SJohn.Forte@Sun.COM )
6517836SJohn.Forte@Sun.COM {
6527836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
6537836SJohn.Forte@Sun.COM 
6547836SJohn.Forte@Sun.COM 	mv.currentValue = maxOutstandingR2T;
6557836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv,
6567836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_OUTSTANDING_R2T));
6577836SJohn.Forte@Sun.COM }
6587836SJohn.Forte@Sun.COM 
6597836SJohn.Forte@Sun.COM 
6607836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetErrorRecoveryLevelProperties(
6617836SJohn.Forte@Sun.COM 		IMA_OID Oid,
6627836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *pProps
6637836SJohn.Forte@Sun.COM )
6647836SJohn.Forte@Sun.COM {
6657836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps,
6667836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL));
6677836SJohn.Forte@Sun.COM }
6687836SJohn.Forte@Sun.COM 
6697836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetErrorRecoveryLevel(
6707836SJohn.Forte@Sun.COM 		IMA_OID Oid,
6717836SJohn.Forte@Sun.COM 		IMA_UINT errorRecoveryLevel
6727836SJohn.Forte@Sun.COM )
6737836SJohn.Forte@Sun.COM {
6747836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE mv;
6757836SJohn.Forte@Sun.COM 
6767836SJohn.Forte@Sun.COM 	mv.currentValue = errorRecoveryLevel;
6777836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(MIN_MAX_PARAM, &Oid, &mv,
6787836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL));
6797836SJohn.Forte@Sun.COM }
6807836SJohn.Forte@Sun.COM 
6817836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetInitialR2TProperties(
6827836SJohn.Forte@Sun.COM 		IMA_OID Oid,
6837836SJohn.Forte@Sun.COM 		IMA_BOOL_VALUE *pProps
6847836SJohn.Forte@Sun.COM )
6857836SJohn.Forte@Sun.COM {
6867836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
6877836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_INITIAL_R2T));
6887836SJohn.Forte@Sun.COM }
6897836SJohn.Forte@Sun.COM 
6907836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetInitialR2T(
6917836SJohn.Forte@Sun.COM 		IMA_OID Oid,
6927836SJohn.Forte@Sun.COM 		IMA_BOOL initialR2T
6937836SJohn.Forte@Sun.COM )
6947836SJohn.Forte@Sun.COM {
6957836SJohn.Forte@Sun.COM 	IMA_BOOL_VALUE bv;
6967836SJohn.Forte@Sun.COM 
6977836SJohn.Forte@Sun.COM 	bv.currentValue = initialR2T;
6987836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
6997836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_INITIAL_R2T));
7007836SJohn.Forte@Sun.COM }
7017836SJohn.Forte@Sun.COM 
7027836SJohn.Forte@Sun.COM 
7037836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetImmediateDataProperties(
7047836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7057836SJohn.Forte@Sun.COM 		IMA_BOOL_VALUE *pProps
7067836SJohn.Forte@Sun.COM )
7077836SJohn.Forte@Sun.COM {
7087836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
7097836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_IMMEDIATE_DATA));
7107836SJohn.Forte@Sun.COM }
7117836SJohn.Forte@Sun.COM 
7127836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetImmediateData(
7137836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7147836SJohn.Forte@Sun.COM 		IMA_BOOL immediateData
7157836SJohn.Forte@Sun.COM )
7167836SJohn.Forte@Sun.COM {
7177836SJohn.Forte@Sun.COM 	IMA_BOOL_VALUE bv;
7187836SJohn.Forte@Sun.COM 
7197836SJohn.Forte@Sun.COM 	bv.currentValue = immediateData;
7207836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
7217836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_IMMEDIATE_DATA));
7227836SJohn.Forte@Sun.COM }
7237836SJohn.Forte@Sun.COM 
7247836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetDataPduInOrderProperties(
7257836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7267836SJohn.Forte@Sun.COM 		IMA_BOOL_VALUE *pProps
7277836SJohn.Forte@Sun.COM )
7287836SJohn.Forte@Sun.COM {
7297836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
7307836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER));
7317836SJohn.Forte@Sun.COM }
7327836SJohn.Forte@Sun.COM 
7337836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetDataPduInOrder(
7347836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7357836SJohn.Forte@Sun.COM 		IMA_BOOL dataPduInOrder
7367836SJohn.Forte@Sun.COM )
7377836SJohn.Forte@Sun.COM {
7387836SJohn.Forte@Sun.COM 	IMA_BOOL_VALUE bv;
7397836SJohn.Forte@Sun.COM 
7407836SJohn.Forte@Sun.COM 	bv.currentValue = dataPduInOrder;
7417836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
7427836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER));
7437836SJohn.Forte@Sun.COM }
7447836SJohn.Forte@Sun.COM 
7457836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetDataSequenceInOrderProperties(
7467836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7477836SJohn.Forte@Sun.COM 		IMA_BOOL_VALUE *pProps
7487836SJohn.Forte@Sun.COM )
7497836SJohn.Forte@Sun.COM {
7507836SJohn.Forte@Sun.COM 	return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps,
7517836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER));
7527836SJohn.Forte@Sun.COM }
7537836SJohn.Forte@Sun.COM 
7547836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetDataSequenceInOrder(
7557836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7567836SJohn.Forte@Sun.COM 		IMA_BOOL dataSequenceInOrder
7577836SJohn.Forte@Sun.COM )
7587836SJohn.Forte@Sun.COM {
7597836SJohn.Forte@Sun.COM 	IMA_BOOL_VALUE bv;
7607836SJohn.Forte@Sun.COM 
7617836SJohn.Forte@Sun.COM 	bv.currentValue = dataSequenceInOrder;
7627836SJohn.Forte@Sun.COM 	return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv,
7637836SJohn.Forte@Sun.COM 	    ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER));
7647836SJohn.Forte@Sun.COM }
7657836SJohn.Forte@Sun.COM 
7667836SJohn.Forte@Sun.COM 
7677836SJohn.Forte@Sun.COM /*ARGSUSED*/
7687836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetStatisticsCollection(
7697836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7707836SJohn.Forte@Sun.COM 		IMA_BOOL enableStatisticsCollection
7717836SJohn.Forte@Sun.COM )
7727836SJohn.Forte@Sun.COM {
7737836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
7747836SJohn.Forte@Sun.COM }
7757836SJohn.Forte@Sun.COM 
7767836SJohn.Forte@Sun.COM 
7777836SJohn.Forte@Sun.COM /*ARGSUSED*/
7787836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetDiscoveryAddressOidList(
7797836SJohn.Forte@Sun.COM 		IMA_OID Oid,
7807836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
7817836SJohn.Forte@Sun.COM )
7827836SJohn.Forte@Sun.COM {
7837836SJohn.Forte@Sun.COM 	int fd, i, addr_list_size;
7847836SJohn.Forte@Sun.COM 	iscsi_addr_list_t *idlp, al_info;
7857836SJohn.Forte@Sun.COM 
7867836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
7877836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
7887836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
7897836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
7907836SJohn.Forte@Sun.COM 	}
7917836SJohn.Forte@Sun.COM 
7927836SJohn.Forte@Sun.COM 	(void) memset(&al_info, 0, sizeof (al_info));
7937836SJohn.Forte@Sun.COM 	al_info.al_vers = ISCSI_INTERFACE_VERSION;
7947836SJohn.Forte@Sun.COM 	al_info.al_in_cnt = 0;
7957836SJohn.Forte@Sun.COM 
7967836SJohn.Forte@Sun.COM 	/*
7977836SJohn.Forte@Sun.COM 	 * Issue ioctl to obtain the number of targets.
7987836SJohn.Forte@Sun.COM 	 */
7997836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
8007836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
8017836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
8027836SJohn.Forte@Sun.COM 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
8037836SJohn.Forte@Sun.COM 		(void) close(fd);
8047836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
8057836SJohn.Forte@Sun.COM 	}
8067836SJohn.Forte@Sun.COM 
8077836SJohn.Forte@Sun.COM 	addr_list_size = sizeof (iscsi_addr_list_t);
8087836SJohn.Forte@Sun.COM 	if (al_info.al_out_cnt > 1) {
8097836SJohn.Forte@Sun.COM 		addr_list_size += (sizeof (iscsi_addr_list_t) *
8107836SJohn.Forte@Sun.COM 		    al_info.al_out_cnt - 1);
8117836SJohn.Forte@Sun.COM 	}
8127836SJohn.Forte@Sun.COM 
8137836SJohn.Forte@Sun.COM 	idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
8147836SJohn.Forte@Sun.COM 	if (idlp == NULL) {
8157836SJohn.Forte@Sun.COM 		(void) close(fd);
8167836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
8177836SJohn.Forte@Sun.COM 	}
8187836SJohn.Forte@Sun.COM 
8197836SJohn.Forte@Sun.COM 	idlp->al_vers = ISCSI_INTERFACE_VERSION;
8207836SJohn.Forte@Sun.COM 	idlp->al_in_cnt = al_info.al_out_cnt;
8217836SJohn.Forte@Sun.COM 	/* Issue the same ioctl again to obtain the OIDs. */
8227836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
8237836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
8247836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
8257836SJohn.Forte@Sun.COM 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
8267836SJohn.Forte@Sun.COM 		free(idlp);
8277836SJohn.Forte@Sun.COM 		(void) close(fd);
8287836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
8297836SJohn.Forte@Sun.COM 	}
8307836SJohn.Forte@Sun.COM 
8317836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) +
8327836SJohn.Forte@Sun.COM 	    idlp->al_out_cnt * sizeof (IMA_OID));
8337836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
8347836SJohn.Forte@Sun.COM 		free(idlp);
8357836SJohn.Forte@Sun.COM 		(void) close(fd);
8367836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
8377836SJohn.Forte@Sun.COM 	}
8387836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = idlp->al_out_cnt;
8397836SJohn.Forte@Sun.COM 
8407836SJohn.Forte@Sun.COM 	for (i = 0; i < idlp->al_out_cnt; i++) {
8417836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].objectType =
8427836SJohn.Forte@Sun.COM 		    IMA_OBJECT_TYPE_DISCOVERY_ADDRESS;
8437836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].ownerId = pluginOwnerId;
8447836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].objectSequenceNumber =
8457836SJohn.Forte@Sun.COM 		    idlp->al_addrs[i].a_oid;
8467836SJohn.Forte@Sun.COM 	}
8477836SJohn.Forte@Sun.COM 
8487836SJohn.Forte@Sun.COM 	free(idlp);
8497836SJohn.Forte@Sun.COM 	(void) close(fd);
8507836SJohn.Forte@Sun.COM 
8517836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
8527836SJohn.Forte@Sun.COM }
8537836SJohn.Forte@Sun.COM 
8547836SJohn.Forte@Sun.COM 
8557836SJohn.Forte@Sun.COM /* ARGSUSED */
8567836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetStaticDiscoveryTargetOidList(
8577836SJohn.Forte@Sun.COM 		IMA_OID Oid,
8587836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
8597836SJohn.Forte@Sun.COM )
8607836SJohn.Forte@Sun.COM {
8617836SJohn.Forte@Sun.COM 	if (Oid.objectType == IMA_OBJECT_TYPE_PNP) {
8627836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
8637836SJohn.Forte@Sun.COM 	}
8647836SJohn.Forte@Sun.COM 
8657836SJohn.Forte@Sun.COM 	return (get_target_oid_list(ISCSI_STATIC_TGT_OID_LIST, ppList));
8667836SJohn.Forte@Sun.COM }
8677836SJohn.Forte@Sun.COM 
8687836SJohn.Forte@Sun.COM /* ARGSUSED */
8697836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetTargetOidList(
8707836SJohn.Forte@Sun.COM 		IMA_OID Oid,
8717836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
8727836SJohn.Forte@Sun.COM )
8737836SJohn.Forte@Sun.COM {
8747836SJohn.Forte@Sun.COM 	return (get_target_oid_list(ISCSI_TGT_PARAM_OID_LIST, ppList));
8757836SJohn.Forte@Sun.COM }
8767836SJohn.Forte@Sun.COM 
8777836SJohn.Forte@Sun.COM /*ARGSUSED*/
8787836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetIsnsDiscovery(
8797836SJohn.Forte@Sun.COM 		IMA_OID phbaId,
8807836SJohn.Forte@Sun.COM 		IMA_BOOL enableIsnsDiscovery,
8817836SJohn.Forte@Sun.COM 		IMA_ISNS_DISCOVERY_METHOD discoveryMethod,
8827836SJohn.Forte@Sun.COM 		const IMA_HOST_ID *iSnsHost
8837836SJohn.Forte@Sun.COM )
8847836SJohn.Forte@Sun.COM {
8857836SJohn.Forte@Sun.COM 	/* XXX need to set discovery Method and domaineName */
8867836SJohn.Forte@Sun.COM 	return (configure_discovery_method(enableIsnsDiscovery,
8877836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodISNS));
8887836SJohn.Forte@Sun.COM }
8897836SJohn.Forte@Sun.COM 
8907836SJohn.Forte@Sun.COM 
8917836SJohn.Forte@Sun.COM /* ARGSUSED */
8927836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetSlpDiscovery(
8937836SJohn.Forte@Sun.COM 		IMA_OID phbaId,
8947836SJohn.Forte@Sun.COM 		IMA_BOOL enableSlpDiscovery
8957836SJohn.Forte@Sun.COM )
8967836SJohn.Forte@Sun.COM {
8977836SJohn.Forte@Sun.COM 	return (configure_discovery_method(enableSlpDiscovery,
8987836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodSLP));
8997836SJohn.Forte@Sun.COM }
9007836SJohn.Forte@Sun.COM 
9017836SJohn.Forte@Sun.COM 
9027836SJohn.Forte@Sun.COM /* ARGSUSED */
9037836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetStaticDiscovery(
9047836SJohn.Forte@Sun.COM 		IMA_OID phbaId,
9057836SJohn.Forte@Sun.COM 		IMA_BOOL enableStaticDiscovery
9067836SJohn.Forte@Sun.COM )
9077836SJohn.Forte@Sun.COM {
9087836SJohn.Forte@Sun.COM 	return (configure_discovery_method(enableStaticDiscovery,
9097836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodStatic));
9107836SJohn.Forte@Sun.COM }
9117836SJohn.Forte@Sun.COM 
9127836SJohn.Forte@Sun.COM /* ARGSUSED */
9137836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetSendTargetsDiscovery(
9147836SJohn.Forte@Sun.COM 		IMA_OID phbaId,
9157836SJohn.Forte@Sun.COM 		IMA_BOOL enableSendTargetsDiscovery
9167836SJohn.Forte@Sun.COM )
9177836SJohn.Forte@Sun.COM {
9187836SJohn.Forte@Sun.COM 	return (configure_discovery_method(enableSendTargetsDiscovery,
9197836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodSendTargets));
9207836SJohn.Forte@Sun.COM }
9217836SJohn.Forte@Sun.COM 
9227836SJohn.Forte@Sun.COM /*ARGSUSED*/
9237836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_RemoveDiscoveryAddress(
9247836SJohn.Forte@Sun.COM 		IMA_OID	discoveryAddressOid
9257836SJohn.Forte@Sun.COM )
9267836SJohn.Forte@Sun.COM {
9277836SJohn.Forte@Sun.COM 	int status, fd, i, addr_list_size;
9287836SJohn.Forte@Sun.COM 	iscsi_addr_list_t *idlp, al_info;
9297836SJohn.Forte@Sun.COM 	iscsi_addr_t *matched_addr = NULL;
9307836SJohn.Forte@Sun.COM 	entry_t	entry;
9317836SJohn.Forte@Sun.COM 
9327836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
9337836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
9347836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
9357836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
9367836SJohn.Forte@Sun.COM 	}
9377836SJohn.Forte@Sun.COM 
9387836SJohn.Forte@Sun.COM 	(void) memset(&al_info, 0, sizeof (al_info));
9397836SJohn.Forte@Sun.COM 	al_info.al_vers = ISCSI_INTERFACE_VERSION;
9407836SJohn.Forte@Sun.COM 	al_info.al_in_cnt = 0;
9417836SJohn.Forte@Sun.COM 
9427836SJohn.Forte@Sun.COM 	/*
9437836SJohn.Forte@Sun.COM 	 * Issue ioctl to obtain the number of discovery address.
9447836SJohn.Forte@Sun.COM 	 */
9457836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
9467836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
9477836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
9487836SJohn.Forte@Sun.COM 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
9497836SJohn.Forte@Sun.COM 		(void) close(fd);
9507836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
9517836SJohn.Forte@Sun.COM 	}
9527836SJohn.Forte@Sun.COM 
9537836SJohn.Forte@Sun.COM 	if (al_info.al_out_cnt == 0) {
9547836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
9557836SJohn.Forte@Sun.COM 	}
9567836SJohn.Forte@Sun.COM 
9577836SJohn.Forte@Sun.COM 	addr_list_size = sizeof (iscsi_addr_list_t);
9587836SJohn.Forte@Sun.COM 	if (al_info.al_out_cnt > 1) {
9597836SJohn.Forte@Sun.COM 		addr_list_size += (sizeof (iscsi_addr_list_t) *
9607836SJohn.Forte@Sun.COM 		    al_info.al_out_cnt - 1);
9617836SJohn.Forte@Sun.COM 	}
9627836SJohn.Forte@Sun.COM 
9637836SJohn.Forte@Sun.COM 	idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
9647836SJohn.Forte@Sun.COM 	if (idlp == NULL) {
9657836SJohn.Forte@Sun.COM 		(void) close(fd);
9667836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
9677836SJohn.Forte@Sun.COM 	}
9687836SJohn.Forte@Sun.COM 
9697836SJohn.Forte@Sun.COM 	idlp->al_vers = ISCSI_INTERFACE_VERSION;
9707836SJohn.Forte@Sun.COM 	idlp->al_in_cnt = al_info.al_out_cnt;
9717836SJohn.Forte@Sun.COM 
9727836SJohn.Forte@Sun.COM 	/* Issue the same ioctl again to obtain the OIDs. */
9737836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
9747836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
9757836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
9767836SJohn.Forte@Sun.COM 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
9777836SJohn.Forte@Sun.COM 		free(idlp);
9787836SJohn.Forte@Sun.COM 		(void) close(fd);
9797836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
9807836SJohn.Forte@Sun.COM 	}
9817836SJohn.Forte@Sun.COM 
9827836SJohn.Forte@Sun.COM 	for (i = 0; i < idlp->al_out_cnt; i++) {
9837836SJohn.Forte@Sun.COM 		if (discoveryAddressOid.objectSequenceNumber !=
9847836SJohn.Forte@Sun.COM 		    idlp->al_addrs[i].a_oid)
9857836SJohn.Forte@Sun.COM 			continue;
9867836SJohn.Forte@Sun.COM 		matched_addr = &(idlp->al_addrs[i]);
9877836SJohn.Forte@Sun.COM 	}
9887836SJohn.Forte@Sun.COM 
9897836SJohn.Forte@Sun.COM 	if (matched_addr == NULL) {
9907836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
9917836SJohn.Forte@Sun.COM 	}
9927836SJohn.Forte@Sun.COM 
9937836SJohn.Forte@Sun.COM 
9947836SJohn.Forte@Sun.COM 	(void) memset(&entry, 0, sizeof (entry_t));
9957836SJohn.Forte@Sun.COM 	entry.e_vers = ISCSI_INTERFACE_VERSION;
9967836SJohn.Forte@Sun.COM 	entry.e_oid  = discoveryAddressOid.objectSequenceNumber;
9977836SJohn.Forte@Sun.COM 	if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) {
9987836SJohn.Forte@Sun.COM 		bcopy(&matched_addr->a_addr.i_addr.in4,
9997836SJohn.Forte@Sun.COM 		    &entry.e_u.u_in4, sizeof (entry.e_u.u_in4));
10007836SJohn.Forte@Sun.COM 		entry.e_insize = sizeof (struct in_addr);
10017836SJohn.Forte@Sun.COM 	} else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) {
10027836SJohn.Forte@Sun.COM 		bcopy(&matched_addr->a_addr.i_addr.in6,
10037836SJohn.Forte@Sun.COM 		    &entry.e_u.u_in6, sizeof (entry.e_u.u_in6));
10047836SJohn.Forte@Sun.COM 		entry.e_insize = sizeof (struct in6_addr);
10057836SJohn.Forte@Sun.COM 	} else {
10067836SJohn.Forte@Sun.COM 		/* Should not happen */
10077836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
10087836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_GET returned bad address");
10097836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
10107836SJohn.Forte@Sun.COM 	}
10117836SJohn.Forte@Sun.COM 
10127836SJohn.Forte@Sun.COM 	entry.e_port = matched_addr->a_port;
10137836SJohn.Forte@Sun.COM 	entry.e_tpgt = 0;
10147836SJohn.Forte@Sun.COM 	entry.e_oid = discoveryAddressOid.objectSequenceNumber;
10157836SJohn.Forte@Sun.COM 
10167836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_CLEAR, &entry)) {
10177836SJohn.Forte@Sun.COM 		status = errno;
10187836SJohn.Forte@Sun.COM 		(void) close(fd);
10197836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
10207836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d",
10217836SJohn.Forte@Sun.COM 		    errno);
10227836SJohn.Forte@Sun.COM 		if (status == EBUSY) {
10237836SJohn.Forte@Sun.COM 			return (IMA_ERROR_LU_IN_USE);
10247836SJohn.Forte@Sun.COM 		} else {
10257836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
10267836SJohn.Forte@Sun.COM 		}
10277836SJohn.Forte@Sun.COM 	}
10287836SJohn.Forte@Sun.COM 
10297836SJohn.Forte@Sun.COM 	free(idlp);
10307836SJohn.Forte@Sun.COM 	(void) close(fd);
10317836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
10327836SJohn.Forte@Sun.COM }
10337836SJohn.Forte@Sun.COM 
10347836SJohn.Forte@Sun.COM 
10357836SJohn.Forte@Sun.COM /*ARGSUSED*/
10367836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_AddDiscoveryAddress(
10377836SJohn.Forte@Sun.COM 		IMA_OID	oid,
10387836SJohn.Forte@Sun.COM 		const IMA_TARGET_ADDRESS discoveryAddress,
10397836SJohn.Forte@Sun.COM 		IMA_OID	*pDiscoveryAddressOid
10407836SJohn.Forte@Sun.COM )
10417836SJohn.Forte@Sun.COM {
10427836SJohn.Forte@Sun.COM 	entry_t	    entry;
10437836SJohn.Forte@Sun.COM 	int	    fd;
10447836SJohn.Forte@Sun.COM 
10457836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
10467836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
10477836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
10487836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
10497836SJohn.Forte@Sun.COM 	}
10507836SJohn.Forte@Sun.COM 
10517836SJohn.Forte@Sun.COM 	if (prepare_discovery_entry(discoveryAddress, &entry) !=
10527836SJohn.Forte@Sun.COM 	    DISC_ADDR_OK) {
10537836SJohn.Forte@Sun.COM 		(void) close(fd);
10547836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
10557836SJohn.Forte@Sun.COM 	}
10567836SJohn.Forte@Sun.COM 
10577836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_SET, &entry)) {
10587836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
10597836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_SET ioctl failed, errno: %d",
10607836SJohn.Forte@Sun.COM 		    errno);
10617836SJohn.Forte@Sun.COM 		(void) close(fd);
10627836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
10637836SJohn.Forte@Sun.COM 	}
10647836SJohn.Forte@Sun.COM 
10657836SJohn.Forte@Sun.COM 	pDiscoveryAddressOid->ownerId = pluginOwnerId;
10667836SJohn.Forte@Sun.COM 	pDiscoveryAddressOid->objectType = IMA_OBJECT_TYPE_DISCOVERY_ADDRESS;
10677836SJohn.Forte@Sun.COM 	pDiscoveryAddressOid->objectSequenceNumber = entry.e_oid;
10687836SJohn.Forte@Sun.COM 
10697836SJohn.Forte@Sun.COM 	(void) close(fd);
10707836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
10717836SJohn.Forte@Sun.COM }
10727836SJohn.Forte@Sun.COM 
10737836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetProperties(
10747836SJohn.Forte@Sun.COM 		IMA_OID	staticTargetOid,
10757836SJohn.Forte@Sun.COM 		IMA_STATIC_DISCOVERY_TARGET_PROPERTIES *pProps
10767836SJohn.Forte@Sun.COM )
10777836SJohn.Forte@Sun.COM {
10787836SJohn.Forte@Sun.COM 	char static_target_addr_str[SUN_IMA_IP_ADDRESS_LEN];
10797836SJohn.Forte@Sun.COM 	char static_target_addr_port_str[SUN_IMA_IP_ADDRESS_LEN];
10807836SJohn.Forte@Sun.COM 	int af, fd, status;
10817836SJohn.Forte@Sun.COM 	iscsi_static_property_t prop;
10827836SJohn.Forte@Sun.COM 	/* LINTED */
10837836SJohn.Forte@Sun.COM 	IMA_HOST_ID *host;
10847836SJohn.Forte@Sun.COM 
10857836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
10867836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
10877836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
10887836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
10897836SJohn.Forte@Sun.COM 	}
10907836SJohn.Forte@Sun.COM 
10917836SJohn.Forte@Sun.COM 	(void) memset(&prop, 0, sizeof (iscsi_static_property_t));
10927836SJohn.Forte@Sun.COM 	prop.p_vers = ISCSI_INTERFACE_VERSION;
10937836SJohn.Forte@Sun.COM 	prop.p_oid = (uint32_t)staticTargetOid.objectSequenceNumber;
10947836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_STATIC_GET, &prop) != 0) {
10957836SJohn.Forte@Sun.COM 		status = errno;
10967836SJohn.Forte@Sun.COM 		(void) close(fd);
10977836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
10987836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_GET ioctl failed, errno: %d", status);
10997836SJohn.Forte@Sun.COM 		if (status == ENOENT) {
11007836SJohn.Forte@Sun.COM 			return (IMA_ERROR_OBJECT_NOT_FOUND);
11017836SJohn.Forte@Sun.COM 
11027836SJohn.Forte@Sun.COM 		} else {
11037836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
11047836SJohn.Forte@Sun.COM 		}
11057836SJohn.Forte@Sun.COM 	}
11067836SJohn.Forte@Sun.COM 	(void) close(fd);
11077836SJohn.Forte@Sun.COM 
11087836SJohn.Forte@Sun.COM 	(void) mbstowcs(pProps->staticTarget.targetName, (char *)prop.p_name,
11097836SJohn.Forte@Sun.COM 	    sizeof (pProps->staticTarget.targetName)/sizeof (IMA_WCHAR));
11107836SJohn.Forte@Sun.COM 
11117836SJohn.Forte@Sun.COM 	if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
11127836SJohn.Forte@Sun.COM 	    sizeof (struct in_addr)) {
11137836SJohn.Forte@Sun.COM 		/* IPv4 */
11147836SJohn.Forte@Sun.COM 		af = AF_INET;
11157836SJohn.Forte@Sun.COM 	} else if (prop.p_addr_list.al_addrs[0].a_addr.i_insize ==
11167836SJohn.Forte@Sun.COM 	    sizeof (struct in6_addr)) {
11177836SJohn.Forte@Sun.COM 		/* IPv6 */
11187836SJohn.Forte@Sun.COM 		af = AF_INET6;
11197836SJohn.Forte@Sun.COM 	} else {
11207836SJohn.Forte@Sun.COM 		/* Should not happen */
11217836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
11227836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_GET returned bad address");
11237836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
11247836SJohn.Forte@Sun.COM 	}
11257836SJohn.Forte@Sun.COM 
11267836SJohn.Forte@Sun.COM 	if (inet_ntop(af, &prop.p_addr_list.al_addrs[0].a_addr.i_addr,
11277836SJohn.Forte@Sun.COM 	    static_target_addr_str, sizeof (static_target_addr_str)) == NULL) {
11287836SJohn.Forte@Sun.COM 		/* Should not happen */
11297836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
11307836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_GET returned address that cannot "
11317836SJohn.Forte@Sun.COM 		    "be inet_ntop");
11327836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
11337836SJohn.Forte@Sun.COM 	} else {
11347836SJohn.Forte@Sun.COM 		if (af == AF_INET) {
11357836SJohn.Forte@Sun.COM 			(void) snprintf(static_target_addr_port_str,
11367836SJohn.Forte@Sun.COM 			    SUN_IMA_IP_ADDRESS_LEN,
11377836SJohn.Forte@Sun.COM 			    "%s:%ld",
11387836SJohn.Forte@Sun.COM 			    static_target_addr_str,
11397836SJohn.Forte@Sun.COM 			    prop.p_addr_list.al_addrs[0].a_port);
11407836SJohn.Forte@Sun.COM 		} else {
11417836SJohn.Forte@Sun.COM 			(void) snprintf(static_target_addr_port_str,
11427836SJohn.Forte@Sun.COM 			    SUN_IMA_IP_ADDRESS_LEN,
11437836SJohn.Forte@Sun.COM 			    "[%s]:%ld",
11447836SJohn.Forte@Sun.COM 			    static_target_addr_str,
11457836SJohn.Forte@Sun.COM 			    prop.p_addr_list.al_addrs[0].a_port);
11467836SJohn.Forte@Sun.COM 		}
11477836SJohn.Forte@Sun.COM 		host = &pProps->staticTarget.targetAddress.hostnameIpAddress;
11487836SJohn.Forte@Sun.COM 		(void) mbstowcs(pProps->staticTarget.
11497836SJohn.Forte@Sun.COM 		    targetAddress.hostnameIpAddress.
11507836SJohn.Forte@Sun.COM 		    id.hostname, static_target_addr_port_str,
11517836SJohn.Forte@Sun.COM 		    sizeof (host->id.hostname) / sizeof (IMA_WCHAR));
11527836SJohn.Forte@Sun.COM 	}
11537836SJohn.Forte@Sun.COM 
11547836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
11557836SJohn.Forte@Sun.COM }
11567836SJohn.Forte@Sun.COM 
11577836SJohn.Forte@Sun.COM /*ARGSUSED*/
11587836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetDiscoveryAddressProperties(
11597836SJohn.Forte@Sun.COM 		IMA_OID	discoveryAddressOid,
11607836SJohn.Forte@Sun.COM 		IMA_DISCOVERY_ADDRESS_PROPERTIES *pProps
11617836SJohn.Forte@Sun.COM )
11627836SJohn.Forte@Sun.COM {
11637836SJohn.Forte@Sun.COM 	int fd;
11647836SJohn.Forte@Sun.COM 	int i;
11657836SJohn.Forte@Sun.COM 	int addr_list_size;
11667836SJohn.Forte@Sun.COM 	iscsi_addr_list_t *idlp, al_info;
11677836SJohn.Forte@Sun.COM 	iscsi_addr_t *matched_addr = NULL;
11687836SJohn.Forte@Sun.COM 	/* LINTED */
11697836SJohn.Forte@Sun.COM 	IMA_TARGET_ADDRESS *addr;
11707836SJohn.Forte@Sun.COM 
11717836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
11727836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
11737836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
11747836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
11757836SJohn.Forte@Sun.COM 	}
11767836SJohn.Forte@Sun.COM 
11777836SJohn.Forte@Sun.COM 	(void) memset(&al_info, 0, sizeof (al_info));
11787836SJohn.Forte@Sun.COM 	al_info.al_vers = ISCSI_INTERFACE_VERSION;
11797836SJohn.Forte@Sun.COM 	al_info.al_in_cnt = 0;
11807836SJohn.Forte@Sun.COM 
11817836SJohn.Forte@Sun.COM 	/*
11827836SJohn.Forte@Sun.COM 	 * Issue ioctl to obtain the number of discovery addresses.
11837836SJohn.Forte@Sun.COM 	 */
11847836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
11857836SJohn.Forte@Sun.COM 		(void) close(fd);
11867836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
11877836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d",
11887836SJohn.Forte@Sun.COM 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
11897836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
11907836SJohn.Forte@Sun.COM 	}
11917836SJohn.Forte@Sun.COM 
11927836SJohn.Forte@Sun.COM 	if (al_info.al_out_cnt == 0) {
11937836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
11947836SJohn.Forte@Sun.COM 	}
11957836SJohn.Forte@Sun.COM 
11967836SJohn.Forte@Sun.COM 	addr_list_size = sizeof (iscsi_addr_list_t);
11977836SJohn.Forte@Sun.COM 	if (al_info.al_out_cnt > 1) {
11987836SJohn.Forte@Sun.COM 		addr_list_size += (sizeof (iscsi_addr_list_t) *
11997836SJohn.Forte@Sun.COM 		    al_info.al_out_cnt - 1);
12007836SJohn.Forte@Sun.COM 	}
12017836SJohn.Forte@Sun.COM 
12027836SJohn.Forte@Sun.COM 	idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size);
12037836SJohn.Forte@Sun.COM 	if (idlp == NULL) {
12047836SJohn.Forte@Sun.COM 		(void) close(fd);
12057836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
12067836SJohn.Forte@Sun.COM 	}
12077836SJohn.Forte@Sun.COM 
12087836SJohn.Forte@Sun.COM 	idlp->al_vers = ISCSI_INTERFACE_VERSION;
12097836SJohn.Forte@Sun.COM 	idlp->al_in_cnt = al_info.al_out_cnt;
12107836SJohn.Forte@Sun.COM 
12117836SJohn.Forte@Sun.COM 	/* Issue the same ioctl again to obtain the OIDs. */
12127836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) {
12137836SJohn.Forte@Sun.COM 		free(idlp);
12147836SJohn.Forte@Sun.COM 		(void) close(fd);
12157836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
12167836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
12177836SJohn.Forte@Sun.COM 		    ISCSI_DISCOVERY_ADDR_LIST_GET, errno);
12187836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
12197836SJohn.Forte@Sun.COM 	}
12207836SJohn.Forte@Sun.COM 
12217836SJohn.Forte@Sun.COM 	for (i = 0; i < idlp->al_out_cnt; i++) {
12227836SJohn.Forte@Sun.COM 		if (discoveryAddressOid.objectSequenceNumber !=
12237836SJohn.Forte@Sun.COM 		    idlp->al_addrs[i].a_oid)
12247836SJohn.Forte@Sun.COM 			continue;
12257836SJohn.Forte@Sun.COM 		matched_addr = &(idlp->al_addrs[i]);
12267836SJohn.Forte@Sun.COM 	}
12277836SJohn.Forte@Sun.COM 
12287836SJohn.Forte@Sun.COM 	if (matched_addr == NULL) {
12297836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
12307836SJohn.Forte@Sun.COM 	}
12317836SJohn.Forte@Sun.COM 
12327836SJohn.Forte@Sun.COM 	if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) {
12337836SJohn.Forte@Sun.COM 		pProps->discoveryAddress.hostnameIpAddress.id.
12347836SJohn.Forte@Sun.COM 		    ipAddress.ipv4Address = IMA_TRUE;
12357836SJohn.Forte@Sun.COM 	} else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) {
12367836SJohn.Forte@Sun.COM 		pProps->discoveryAddress.hostnameIpAddress.id.
12377836SJohn.Forte@Sun.COM 		    ipAddress.ipv4Address = IMA_FALSE;
12387836SJohn.Forte@Sun.COM 	} else {
12397836SJohn.Forte@Sun.COM 		/* Should not happen */
12407836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
12417836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_GET returned bad address");
12427836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
12437836SJohn.Forte@Sun.COM 	}
12447836SJohn.Forte@Sun.COM 
12457836SJohn.Forte@Sun.COM 	addr = &pProps->discoveryAddress;
12467836SJohn.Forte@Sun.COM 	bcopy(&(matched_addr->a_addr.i_addr), pProps->discoveryAddress.
12477836SJohn.Forte@Sun.COM 	    hostnameIpAddress.id.ipAddress.ipAddress,
12487836SJohn.Forte@Sun.COM 	    sizeof (addr->hostnameIpAddress.id.ipAddress.ipAddress));
12497836SJohn.Forte@Sun.COM 
12507836SJohn.Forte@Sun.COM 	pProps->discoveryAddress.portNumber = matched_addr->a_port;
12517836SJohn.Forte@Sun.COM 
12527836SJohn.Forte@Sun.COM 	pProps->associatedLhbaOid.objectType = IMA_OBJECT_TYPE_LHBA;
12537836SJohn.Forte@Sun.COM 	pProps->associatedLhbaOid.ownerId = pluginOwnerId;
12547836SJohn.Forte@Sun.COM 	pProps->associatedLhbaOid.objectSequenceNumber = ISCSI_INITIATOR_OID;
12557836SJohn.Forte@Sun.COM 
12567836SJohn.Forte@Sun.COM 	free(idlp);
12577836SJohn.Forte@Sun.COM 	(void) close(fd);
12587836SJohn.Forte@Sun.COM 
12597836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
12607836SJohn.Forte@Sun.COM }
12617836SJohn.Forte@Sun.COM 
12627836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_RemoveStaticDiscoveryTarget(
12637836SJohn.Forte@Sun.COM 		IMA_OID staticTargetOid
12647836SJohn.Forte@Sun.COM )
12657836SJohn.Forte@Sun.COM {
12667836SJohn.Forte@Sun.COM 	entry_t	entry;
12677836SJohn.Forte@Sun.COM 	int	status, fd;
12687836SJohn.Forte@Sun.COM 
12697836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
12707836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
12717836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
12727836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
12737836SJohn.Forte@Sun.COM 	}
12747836SJohn.Forte@Sun.COM 
12757836SJohn.Forte@Sun.COM 	(void) memset(&entry, 0, sizeof (entry_t));
12767836SJohn.Forte@Sun.COM 	entry.e_vers = ISCSI_INTERFACE_VERSION;
12777836SJohn.Forte@Sun.COM 	entry.e_oid = (uint32_t)staticTargetOid.objectSequenceNumber;
12787836SJohn.Forte@Sun.COM 
12797836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_STATIC_CLEAR, &entry)) {
12807836SJohn.Forte@Sun.COM 		status = errno;
12817836SJohn.Forte@Sun.COM 		(void) close(fd);
12827836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
12837836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_CLEAR ioctl failed, errno: %d", errno);
12847836SJohn.Forte@Sun.COM 		if (status == EBUSY) {
12857836SJohn.Forte@Sun.COM 			return (IMA_ERROR_LU_IN_USE);
12867836SJohn.Forte@Sun.COM 		} else {
12877836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
12887836SJohn.Forte@Sun.COM 		}
12897836SJohn.Forte@Sun.COM 	}
12907836SJohn.Forte@Sun.COM 
12917836SJohn.Forte@Sun.COM 	(void) close(fd);
12927836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
12937836SJohn.Forte@Sun.COM }
12947836SJohn.Forte@Sun.COM 
12957836SJohn.Forte@Sun.COM /*ARGSUSED*/
12967836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_AddStaticDiscoveryTarget(
12977836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
12987836SJohn.Forte@Sun.COM 		const IMA_STATIC_DISCOVERY_TARGET staticConfig,
12997836SJohn.Forte@Sun.COM 		IMA_OID *pTargetOid
13007836SJohn.Forte@Sun.COM )
13017836SJohn.Forte@Sun.COM {
13027836SJohn.Forte@Sun.COM 	char			tmp_target_str[SUN_IMA_IP_ADDRESS_LEN];
13037836SJohn.Forte@Sun.COM 	char			target_addr_str[SUN_IMA_IP_ADDRESS_LEN];
13047836SJohn.Forte@Sun.COM 	char			target_port_str[SUN_IMA_IP_PORT_LEN];
13057836SJohn.Forte@Sun.COM 	iscsi_target_entry_t	target;
13067836SJohn.Forte@Sun.COM 	int			fd;
13077836SJohn.Forte@Sun.COM 	int			target_in_addr_size;
13087836SJohn.Forte@Sun.COM 	int			target_port;
13097836SJohn.Forte@Sun.COM 	union {
13107836SJohn.Forte@Sun.COM 		struct in_addr	u_in4;
13117836SJohn.Forte@Sun.COM 		struct in6_addr	u_in6;
13127836SJohn.Forte@Sun.COM 	}			target_in;
13137836SJohn.Forte@Sun.COM 
13147836SJohn.Forte@Sun.COM 	/*
13157836SJohn.Forte@Sun.COM 	 * staticConfig.address may come in with port number at its trailer.
13167836SJohn.Forte@Sun.COM 	 * Parse it to separate the IP address and port number.
13177836SJohn.Forte@Sun.COM 	 * Also translate the hostname to IP address if needed.
13187836SJohn.Forte@Sun.COM 	 */
13197836SJohn.Forte@Sun.COM 	(void) wcstombs(tmp_target_str,
13207836SJohn.Forte@Sun.COM 	    staticConfig.targetAddress.hostnameIpAddress.
13217836SJohn.Forte@Sun.COM 	    id.hostname, sizeof (tmp_target_str));
13227836SJohn.Forte@Sun.COM 
13237836SJohn.Forte@Sun.COM 	if (tmp_target_str[0] == '[') {
13247836SJohn.Forte@Sun.COM 		/* IPv6 address */
13257836SJohn.Forte@Sun.COM 		char *closeBracketPos;
13267836SJohn.Forte@Sun.COM 		closeBracketPos = strchr(tmp_target_str, ']');
13277836SJohn.Forte@Sun.COM 		if (!closeBracketPos) {
13287836SJohn.Forte@Sun.COM 			return (IMA_ERROR_INVALID_PARAMETER);
13297836SJohn.Forte@Sun.COM 		}
13307836SJohn.Forte@Sun.COM 
13317836SJohn.Forte@Sun.COM 		*closeBracketPos = NULL;
13327836SJohn.Forte@Sun.COM 		(void) strlcpy(target_addr_str, &tmp_target_str[1],
13337836SJohn.Forte@Sun.COM 		    sizeof (target_addr_str));
13347836SJohn.Forte@Sun.COM 
13357836SJohn.Forte@Sun.COM 		if (inet_pton(AF_INET6, target_addr_str,
13367836SJohn.Forte@Sun.COM 		    &target_in.u_in6) != 1) {
13377836SJohn.Forte@Sun.COM 			return (IMA_ERROR_INVALID_PARAMETER);
13387836SJohn.Forte@Sun.COM 		}
13397836SJohn.Forte@Sun.COM 		target_in_addr_size = sizeof (struct in6_addr);
13407836SJohn.Forte@Sun.COM 
13417836SJohn.Forte@Sun.COM 		/* Extract the port number */
13427836SJohn.Forte@Sun.COM 		closeBracketPos++;
13437836SJohn.Forte@Sun.COM 		if (*closeBracketPos == ':') {
13447836SJohn.Forte@Sun.COM 			closeBracketPos++;
13457836SJohn.Forte@Sun.COM 
13467836SJohn.Forte@Sun.COM 			if (*closeBracketPos != NULL) {
13477836SJohn.Forte@Sun.COM 				(void) strlcpy(target_port_str, closeBracketPos,
13487836SJohn.Forte@Sun.COM 				    sizeof (target_port_str));
13497836SJohn.Forte@Sun.COM 				target_port = atoi(target_port_str);
13507836SJohn.Forte@Sun.COM 			} else {
13517836SJohn.Forte@Sun.COM 				target_port = ISCSI_LISTEN_PORT;
13527836SJohn.Forte@Sun.COM 			}
13537836SJohn.Forte@Sun.COM 		} else {
13547836SJohn.Forte@Sun.COM 			/* No port number specified; use default port */
13557836SJohn.Forte@Sun.COM 			target_port = ISCSI_LISTEN_PORT;
13567836SJohn.Forte@Sun.COM 		}
13577836SJohn.Forte@Sun.COM 	} else {
13587836SJohn.Forte@Sun.COM 		/* IPv4 address */
13597836SJohn.Forte@Sun.COM 		char *colonPos;
13607836SJohn.Forte@Sun.COM 		colonPos = strchr(tmp_target_str, ':');
13617836SJohn.Forte@Sun.COM 		if (!colonPos) {
13627836SJohn.Forte@Sun.COM 			/* No port number specified; use default port */
13637836SJohn.Forte@Sun.COM 			target_port = ISCSI_LISTEN_PORT;
13647836SJohn.Forte@Sun.COM 			(void) strlcpy(target_addr_str, tmp_target_str,
13657836SJohn.Forte@Sun.COM 			    sizeof (target_addr_str));
13667836SJohn.Forte@Sun.COM 		} else {
13677836SJohn.Forte@Sun.COM 			*colonPos = NULL;
13687836SJohn.Forte@Sun.COM 			(void) strlcpy(target_addr_str, tmp_target_str,
13697836SJohn.Forte@Sun.COM 			    sizeof (target_addr_str));
13707836SJohn.Forte@Sun.COM 			/* Extract the port number */
13717836SJohn.Forte@Sun.COM 			colonPos++;
13727836SJohn.Forte@Sun.COM 			if (*colonPos != NULL) {
13737836SJohn.Forte@Sun.COM 				(void) strlcpy(target_port_str, colonPos,
13747836SJohn.Forte@Sun.COM 				    sizeof (target_port_str));
13757836SJohn.Forte@Sun.COM 				target_port = atoi(target_port_str);
13767836SJohn.Forte@Sun.COM 			} else {
13777836SJohn.Forte@Sun.COM 				target_port = ISCSI_LISTEN_PORT;
13787836SJohn.Forte@Sun.COM 			}
13797836SJohn.Forte@Sun.COM 		}
13807836SJohn.Forte@Sun.COM 
13817836SJohn.Forte@Sun.COM 		if (inet_pton(AF_INET, target_addr_str,
13827836SJohn.Forte@Sun.COM 		    &target_in.u_in4) != 1) {
13837836SJohn.Forte@Sun.COM 			return (IMA_ERROR_INVALID_PARAMETER);
13847836SJohn.Forte@Sun.COM 		}
13857836SJohn.Forte@Sun.COM 
13867836SJohn.Forte@Sun.COM 		target_in_addr_size = sizeof (struct in_addr);
13877836SJohn.Forte@Sun.COM 	}
13887836SJohn.Forte@Sun.COM 
13897836SJohn.Forte@Sun.COM 
13907836SJohn.Forte@Sun.COM 	(void) memset(&target, 0, sizeof (iscsi_target_entry_t));
13917836SJohn.Forte@Sun.COM 	target.te_entry.e_vers = ISCSI_INTERFACE_VERSION;
13927836SJohn.Forte@Sun.COM 	target.te_entry.e_oid = ISCSI_OID_NOTSET;
13937836SJohn.Forte@Sun.COM 	target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT;
13947836SJohn.Forte@Sun.COM 
13957836SJohn.Forte@Sun.COM 	(void) wcstombs((char *)target.te_name, staticConfig.targetName,
13967836SJohn.Forte@Sun.COM 	    ISCSI_MAX_NAME_LEN);
13977836SJohn.Forte@Sun.COM 
13987836SJohn.Forte@Sun.COM 	target.te_entry.e_insize = target_in_addr_size;
13997836SJohn.Forte@Sun.COM 	if (target.te_entry.e_insize == sizeof (struct in_addr)) {
14007836SJohn.Forte@Sun.COM 		target.te_entry.e_u.u_in4.s_addr = target_in.u_in4.s_addr;
14017836SJohn.Forte@Sun.COM 	} else if (target.te_entry.e_insize == sizeof (struct in6_addr)) {
14027836SJohn.Forte@Sun.COM 		bcopy(target_in.u_in6.s6_addr,
14037836SJohn.Forte@Sun.COM 		    target.te_entry.e_u.u_in6.s6_addr,
14047836SJohn.Forte@Sun.COM 		    sizeof (struct in6_addr));
14057836SJohn.Forte@Sun.COM 	} else {
14067836SJohn.Forte@Sun.COM 		/* Should not happen */
14077836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
14087836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_GET returned bad address");
14097836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
14107836SJohn.Forte@Sun.COM 	}
14117836SJohn.Forte@Sun.COM 
14127836SJohn.Forte@Sun.COM 	target.te_entry.e_port = target_port;
14137836SJohn.Forte@Sun.COM 
14147836SJohn.Forte@Sun.COM 	/* No target portal group specified. Default to -1. */
14157836SJohn.Forte@Sun.COM 	target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT;
14167836SJohn.Forte@Sun.COM 
14177836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
14187836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
14197836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
14207836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
14217836SJohn.Forte@Sun.COM 	}
14227836SJohn.Forte@Sun.COM 
14237836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_STATIC_SET, &target)) {
14247836SJohn.Forte@Sun.COM 		/*
14257836SJohn.Forte@Sun.COM 		 * Encountered problem setting the IP address and port for
14267836SJohn.Forte@Sun.COM 		 * the target just added.
14277836SJohn.Forte@Sun.COM 		 */
14287836SJohn.Forte@Sun.COM 		(void) close(fd);
14297836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
14307836SJohn.Forte@Sun.COM 		    "ISCSI_STATIC_SET ioctl failed, errno: %d", errno);
14317836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
14327836SJohn.Forte@Sun.COM 	}
14337836SJohn.Forte@Sun.COM 
14347836SJohn.Forte@Sun.COM 	pTargetOid->objectType = IMA_OBJECT_TYPE_TARGET;
14357836SJohn.Forte@Sun.COM 	pTargetOid->ownerId = pluginOwnerId;
14367836SJohn.Forte@Sun.COM 	pTargetOid->objectSequenceNumber = target.te_entry.e_oid;
14377836SJohn.Forte@Sun.COM 
14387836SJohn.Forte@Sun.COM 	(void) close(fd);
14397836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
14407836SJohn.Forte@Sun.COM }
14417836SJohn.Forte@Sun.COM 
14427836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetTargetProperties(
14437836SJohn.Forte@Sun.COM 		IMA_OID targetId,
14447836SJohn.Forte@Sun.COM 		IMA_TARGET_PROPERTIES *pProps
14457836SJohn.Forte@Sun.COM )
14467836SJohn.Forte@Sun.COM {
14477836SJohn.Forte@Sun.COM 	return (getTargetProperties(targetId, pProps));
14487836SJohn.Forte@Sun.COM }
14497836SJohn.Forte@Sun.COM 
14507836SJohn.Forte@Sun.COM static IMA_STATUS getTargetProperties(
14517836SJohn.Forte@Sun.COM 		IMA_OID targetId,
14527836SJohn.Forte@Sun.COM 		IMA_TARGET_PROPERTIES *pProps
14537836SJohn.Forte@Sun.COM )
14547836SJohn.Forte@Sun.COM {
14557836SJohn.Forte@Sun.COM 	int		    fd;
14567836SJohn.Forte@Sun.COM 	iscsi_property_t    prop;
14577836SJohn.Forte@Sun.COM 
14587836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
14597836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
14607836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
14617836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
14627836SJohn.Forte@Sun.COM 	}
14637836SJohn.Forte@Sun.COM 
14647836SJohn.Forte@Sun.COM 	(void) memset(&prop, 0, sizeof (iscsi_property_t));
14657836SJohn.Forte@Sun.COM 	prop.p_vers = ISCSI_INTERFACE_VERSION;
14667836SJohn.Forte@Sun.COM 	prop.p_oid = (uint32_t)targetId.objectSequenceNumber;
14677836SJohn.Forte@Sun.COM 
14687836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_TARGET_PROPS_GET, &prop) != 0) {
14697836SJohn.Forte@Sun.COM 		(void) close(fd);
14707836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
14717836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
14727836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
14737836SJohn.Forte@Sun.COM 	}
14747836SJohn.Forte@Sun.COM 
14757836SJohn.Forte@Sun.COM 	(void) mbstowcs(pProps->name, (char *)prop.p_name, IMA_NODE_NAME_LEN);
14767836SJohn.Forte@Sun.COM 	(void) memset(pProps->alias, 0,
14777836SJohn.Forte@Sun.COM 	    sizeof (IMA_WCHAR) * IMA_NODE_ALIAS_LEN);
14787836SJohn.Forte@Sun.COM 	if (prop.p_alias_len > 0) {
14797836SJohn.Forte@Sun.COM 		(void) mbstowcs(pProps->alias, (char *)prop.p_alias,
14807836SJohn.Forte@Sun.COM 		    IMA_NODE_ALIAS_LEN);
14817836SJohn.Forte@Sun.COM 	}
14827836SJohn.Forte@Sun.COM 
14837836SJohn.Forte@Sun.COM 	/* Initialize the discovery method to unknown method. */
14847836SJohn.Forte@Sun.COM 	pProps->discoveryMethodFlags = IMA_TARGET_DISCOVERY_METHOD_UNKNOWN;
14857836SJohn.Forte@Sun.COM 	if (!((prop.p_discovery & iSCSIDiscoveryMethodStatic) ^
14867836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodStatic)) {
14877836SJohn.Forte@Sun.COM 		pProps->discoveryMethodFlags |=
14887836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_STATIC;
14897836SJohn.Forte@Sun.COM 	}
14907836SJohn.Forte@Sun.COM 
14917836SJohn.Forte@Sun.COM 	if (!((prop.p_discovery & iSCSIDiscoveryMethodSLP) ^
14927836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodSLP)) {
14937836SJohn.Forte@Sun.COM 		pProps->discoveryMethodFlags |=	IMA_TARGET_DISCOVERY_METHOD_SLP;
14947836SJohn.Forte@Sun.COM 	}
14957836SJohn.Forte@Sun.COM 
14967836SJohn.Forte@Sun.COM 	if (!((prop.p_discovery & iSCSIDiscoveryMethodISNS) ^
14977836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodISNS)) {
14987836SJohn.Forte@Sun.COM 		pProps->discoveryMethodFlags |=	iSCSIDiscoveryMethodISNS;
14997836SJohn.Forte@Sun.COM 	}
15007836SJohn.Forte@Sun.COM 
15017836SJohn.Forte@Sun.COM 	if (!((prop.p_discovery & iSCSIDiscoveryMethodSendTargets) ^
15027836SJohn.Forte@Sun.COM 	    iSCSIDiscoveryMethodSendTargets)) {
15037836SJohn.Forte@Sun.COM 		pProps->discoveryMethodFlags |= iSCSIDiscoveryMethodSendTargets;
15047836SJohn.Forte@Sun.COM 	}
15057836SJohn.Forte@Sun.COM 
15067836SJohn.Forte@Sun.COM 	(void) close(fd);
15077836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
15087836SJohn.Forte@Sun.COM }
15097836SJohn.Forte@Sun.COM 
15107836SJohn.Forte@Sun.COM /*ARGSUSED*/
15117836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetTargetErrorStatistics(
15127836SJohn.Forte@Sun.COM 		IMA_OID targetId,
15137836SJohn.Forte@Sun.COM 		IMA_TARGET_ERROR_STATISTICS *pStats
15147836SJohn.Forte@Sun.COM )
15157836SJohn.Forte@Sun.COM {
15167836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
15177836SJohn.Forte@Sun.COM }
15187836SJohn.Forte@Sun.COM 
15197836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetLuOidList(
15207836SJohn.Forte@Sun.COM 		IMA_OID oid,
15217836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
15227836SJohn.Forte@Sun.COM )
15237836SJohn.Forte@Sun.COM {
15247836SJohn.Forte@Sun.COM 	IMA_STATUS		status;
15257836SJohn.Forte@Sun.COM 	int			i;
15267836SJohn.Forte@Sun.COM 	iscsi_lun_list_t	*pLunList;
15277836SJohn.Forte@Sun.COM 
15287836SJohn.Forte@Sun.COM 	if (oid.objectType == IMA_OBJECT_TYPE_LHBA) {
15297836SJohn.Forte@Sun.COM 		status = get_target_lun_oid_list(NULL, &pLunList);
15307836SJohn.Forte@Sun.COM 	} else {
15317836SJohn.Forte@Sun.COM 		status = get_target_lun_oid_list(&oid, &pLunList);
15327836SJohn.Forte@Sun.COM 	}
15337836SJohn.Forte@Sun.COM 
15347836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
15357836SJohn.Forte@Sun.COM 		return (status);
15367836SJohn.Forte@Sun.COM 	}
15377836SJohn.Forte@Sun.COM 
15387836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST *) calloc(1, (sizeof (IMA_OID_LIST) +
15397836SJohn.Forte@Sun.COM 	    (pLunList->ll_out_cnt * sizeof (IMA_OID))));
15407836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
15417836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
15427836SJohn.Forte@Sun.COM 	}
15437836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = pLunList->ll_out_cnt;
15447836SJohn.Forte@Sun.COM 	for (i = 0; i < pLunList->ll_out_cnt; i++) {
15457836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_LU;
15467836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].ownerId = pluginOwnerId;
15477836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].objectSequenceNumber =
15487836SJohn.Forte@Sun.COM 		    pLunList->ll_luns[i].l_oid;
15497836SJohn.Forte@Sun.COM 	}
15507836SJohn.Forte@Sun.COM 
15517836SJohn.Forte@Sun.COM 	free(pLunList);
15527836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
15537836SJohn.Forte@Sun.COM }
15547836SJohn.Forte@Sun.COM 
15557836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetLuOid(
15567836SJohn.Forte@Sun.COM 		IMA_OID targetId,
15577836SJohn.Forte@Sun.COM 		IMA_UINT64 lun,
15587836SJohn.Forte@Sun.COM 		IMA_OID *pluId
15597836SJohn.Forte@Sun.COM )
15607836SJohn.Forte@Sun.COM {
15617836SJohn.Forte@Sun.COM 	IMA_STATUS		status;
15627836SJohn.Forte@Sun.COM 	int			i;
15637836SJohn.Forte@Sun.COM 	iscsi_lun_list_t	*pLunList;
15647836SJohn.Forte@Sun.COM 
15657836SJohn.Forte@Sun.COM 	status = get_target_lun_oid_list(&targetId, &pLunList);
15667836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
15677836SJohn.Forte@Sun.COM 		return (status);
15687836SJohn.Forte@Sun.COM 	}
15697836SJohn.Forte@Sun.COM 
15707836SJohn.Forte@Sun.COM 	for (i = 0; i < pLunList->ll_out_cnt; i++) {
15717836SJohn.Forte@Sun.COM 		if (pLunList->ll_luns[i].l_num == lun) {
15727836SJohn.Forte@Sun.COM 			pluId->objectType = IMA_OBJECT_TYPE_LU;
15737836SJohn.Forte@Sun.COM 			pluId->ownerId = pluginOwnerId;
15747836SJohn.Forte@Sun.COM 			pluId->objectSequenceNumber =
15757836SJohn.Forte@Sun.COM 			    pLunList->ll_luns[i].l_oid;
15767836SJohn.Forte@Sun.COM 			free(pLunList);
15777836SJohn.Forte@Sun.COM 			return (IMA_STATUS_SUCCESS);
15787836SJohn.Forte@Sun.COM 		}
15797836SJohn.Forte@Sun.COM 	}
15807836SJohn.Forte@Sun.COM 
15817836SJohn.Forte@Sun.COM 	free(pLunList);
15827836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
15837836SJohn.Forte@Sun.COM }
15847836SJohn.Forte@Sun.COM 
15857836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetLuProperties(
15867836SJohn.Forte@Sun.COM 		IMA_OID luId,
15877836SJohn.Forte@Sun.COM 		IMA_LU_PROPERTIES *pProps
15887836SJohn.Forte@Sun.COM )
15897836SJohn.Forte@Sun.COM {
15907836SJohn.Forte@Sun.COM 	return (getLuProperties(luId, pProps));
15917836SJohn.Forte@Sun.COM }
15927836SJohn.Forte@Sun.COM 
15937836SJohn.Forte@Sun.COM static IMA_STATUS getLuProperties(
15947836SJohn.Forte@Sun.COM 		IMA_OID luId,
15957836SJohn.Forte@Sun.COM 		IMA_LU_PROPERTIES *pProps
15967836SJohn.Forte@Sun.COM )
15977836SJohn.Forte@Sun.COM {
15987836SJohn.Forte@Sun.COM 	IMA_STATUS		status;
15997836SJohn.Forte@Sun.COM 	iscsi_lun_list_t	*pLunList;
16007836SJohn.Forte@Sun.COM 	int			j;
16017836SJohn.Forte@Sun.COM 	IMA_BOOL		lunMatch = IMA_FALSE;
16027836SJohn.Forte@Sun.COM 	int			fd;
16037836SJohn.Forte@Sun.COM 	iscsi_lun_props_t	lun;
16047836SJohn.Forte@Sun.COM 	di_devlink_handle_t	hdl;
16057836SJohn.Forte@Sun.COM 
16067836SJohn.Forte@Sun.COM 	if (luId.objectType != IMA_OBJECT_TYPE_LU) {
16077836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INCORRECT_OBJECT_TYPE);
16087836SJohn.Forte@Sun.COM 	}
16097836SJohn.Forte@Sun.COM 
16107836SJohn.Forte@Sun.COM 	/*
16117836SJohn.Forte@Sun.COM 	 * get list of lun oids for all targets
16127836SJohn.Forte@Sun.COM 	 */
16137836SJohn.Forte@Sun.COM 	status = get_target_lun_oid_list(NULL, &pLunList);
16147836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
16157836SJohn.Forte@Sun.COM 		return (status);
16167836SJohn.Forte@Sun.COM 	}
16177836SJohn.Forte@Sun.COM 	for (j = 0; j < pLunList->ll_out_cnt; j++) {
16187836SJohn.Forte@Sun.COM 		/*
16197836SJohn.Forte@Sun.COM 		 * for each lun, check if match is found
16207836SJohn.Forte@Sun.COM 		 */
16217836SJohn.Forte@Sun.COM 		if (pLunList->ll_luns[j].l_oid == luId.objectSequenceNumber) {
16227836SJohn.Forte@Sun.COM 			/*
16237836SJohn.Forte@Sun.COM 			 * match found, break out of lun loop
16247836SJohn.Forte@Sun.COM 			 */
16257836SJohn.Forte@Sun.COM 			lunMatch = IMA_TRUE;
16267836SJohn.Forte@Sun.COM 			break;
16277836SJohn.Forte@Sun.COM 		}
16287836SJohn.Forte@Sun.COM 	}
16297836SJohn.Forte@Sun.COM 
16307836SJohn.Forte@Sun.COM 	if (lunMatch == IMA_TRUE) {
16317836SJohn.Forte@Sun.COM 		(void) memset(&lun, 0, sizeof (iscsi_lun_props_t));
16327836SJohn.Forte@Sun.COM 		lun.lp_vers = ISCSI_INTERFACE_VERSION;
16337836SJohn.Forte@Sun.COM 		lun.lp_tgt_oid = pLunList->ll_luns[j].l_tgt_oid;
16347836SJohn.Forte@Sun.COM 		lun.lp_oid = pLunList->ll_luns[j].l_oid;
16357836SJohn.Forte@Sun.COM 	}
16367836SJohn.Forte@Sun.COM 
16377836SJohn.Forte@Sun.COM 	free(pLunList);
16387836SJohn.Forte@Sun.COM 
16397836SJohn.Forte@Sun.COM 	if (lunMatch == IMA_FALSE) {
16407836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
16417836SJohn.Forte@Sun.COM 	}
16427836SJohn.Forte@Sun.COM 
16437836SJohn.Forte@Sun.COM 	/*
16447836SJohn.Forte@Sun.COM 	 * get lun properties
16457836SJohn.Forte@Sun.COM 	 */
16467836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
16477836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
16487836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
16497836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
16507836SJohn.Forte@Sun.COM 	}
16517836SJohn.Forte@Sun.COM 
16527836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_LUN_PROPS_GET, &lun)) {
16537836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
16547836SJohn.Forte@Sun.COM 		    "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno);
16557836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
16567836SJohn.Forte@Sun.COM 	}
16577836SJohn.Forte@Sun.COM 	(void) close(fd);
16587836SJohn.Forte@Sun.COM 
16597836SJohn.Forte@Sun.COM 	/*
16607836SJohn.Forte@Sun.COM 	 * set property values
16617836SJohn.Forte@Sun.COM 	 */
16627836SJohn.Forte@Sun.COM 	pProps->associatedTargetOid.objectType = IMA_OBJECT_TYPE_TARGET;
16637836SJohn.Forte@Sun.COM 	pProps->associatedTargetOid.ownerId = pluginOwnerId;
16647836SJohn.Forte@Sun.COM 	pProps->associatedTargetOid.objectSequenceNumber = lun.lp_tgt_oid;
16657836SJohn.Forte@Sun.COM 	pProps->targetLun = (IMA_UINT64)lun.lp_num;
16667836SJohn.Forte@Sun.COM 	pProps->exposedToOs = IMA_TRUE;
16677836SJohn.Forte@Sun.COM 	(void) memset(&pProps->timeExposedToOs, 0,
16687836SJohn.Forte@Sun.COM 	    sizeof (pProps->timeExposedToOs));
16697836SJohn.Forte@Sun.COM 
16707836SJohn.Forte@Sun.COM 	if (lun.lp_status == LunValid) {
16717836SJohn.Forte@Sun.COM 
16727836SJohn.Forte@Sun.COM 		/* add minor device delimiter */
16737836SJohn.Forte@Sun.COM 		(void) strcat(lun.lp_pathname, ":");
16747836SJohn.Forte@Sun.COM 
16757836SJohn.Forte@Sun.COM 		if ((strstr(lun.lp_pathname, "sd@") != NULL) ||
16767836SJohn.Forte@Sun.COM 		    (strstr(lun.lp_pathname, "ssd@") != NULL) ||
16777836SJohn.Forte@Sun.COM 		    (strstr(lun.lp_pathname, "disk@") != NULL)) {
16787836SJohn.Forte@Sun.COM 			/*
16797836SJohn.Forte@Sun.COM 			 * modify returned pathname to obtain the 2nd slice
16807836SJohn.Forte@Sun.COM 			 * of the raw disk
16817836SJohn.Forte@Sun.COM 			 */
16827836SJohn.Forte@Sun.COM 			(void) strcat(lun.lp_pathname, "c,raw");
16837836SJohn.Forte@Sun.COM 		}
16847836SJohn.Forte@Sun.COM 
16857836SJohn.Forte@Sun.COM 		/*
16867836SJohn.Forte@Sun.COM 		 * Pathname returned by driver is the physical device path.
16877836SJohn.Forte@Sun.COM 		 * This name needs to be converted to the OS device name.
16887836SJohn.Forte@Sun.COM 		 */
16897836SJohn.Forte@Sun.COM 		if (hdl = di_devlink_init(lun.lp_pathname, DI_MAKE_LINK)) {
16907836SJohn.Forte@Sun.COM 			pProps->osDeviceName[0] = L'\0';
16917836SJohn.Forte@Sun.COM 			(void) di_devlink_walk(hdl, NULL, lun.lp_pathname,
16927836SJohn.Forte@Sun.COM 			    DI_PRIMARY_LINK, (void *)pProps->osDeviceName,
16937836SJohn.Forte@Sun.COM 			    get_lun_devlink);
16947836SJohn.Forte@Sun.COM 			if (pProps->osDeviceName[0] != L'\0') {
16957836SJohn.Forte@Sun.COM 				/* OS device name synchronously made */
16967836SJohn.Forte@Sun.COM 				pProps->osDeviceNameValid = IMA_TRUE;
16977836SJohn.Forte@Sun.COM 			} else {
16987836SJohn.Forte@Sun.COM 				pProps->osDeviceNameValid = IMA_FALSE;
16997836SJohn.Forte@Sun.COM 			}
17007836SJohn.Forte@Sun.COM 
17017836SJohn.Forte@Sun.COM 			(void) di_devlink_fini(&hdl);
17027836SJohn.Forte@Sun.COM 		} else {
17037836SJohn.Forte@Sun.COM 			pProps->osDeviceNameValid = IMA_FALSE;
17047836SJohn.Forte@Sun.COM 		}
17057836SJohn.Forte@Sun.COM 
17067836SJohn.Forte@Sun.COM 	} else {
17077836SJohn.Forte@Sun.COM 		pProps->osDeviceNameValid = IMA_FALSE;
17087836SJohn.Forte@Sun.COM 	}
17097836SJohn.Forte@Sun.COM 
17107836SJohn.Forte@Sun.COM 	pProps->osParallelIdsValid = IMA_FALSE;
17117836SJohn.Forte@Sun.COM 
17127836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
17137836SJohn.Forte@Sun.COM }
17147836SJohn.Forte@Sun.COM 
17157836SJohn.Forte@Sun.COM /*ARGSUSED*/
17167836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetStatisticsProperties(
17177836SJohn.Forte@Sun.COM 		IMA_OID oid,
17187836SJohn.Forte@Sun.COM 		IMA_STATISTICS_PROPERTIES *pProps
17197836SJohn.Forte@Sun.COM )
17207836SJohn.Forte@Sun.COM {
17217836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
17227836SJohn.Forte@Sun.COM }
17237836SJohn.Forte@Sun.COM 
17247836SJohn.Forte@Sun.COM /*ARGSUSED*/
17257836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetDeviceStatistics(
17267836SJohn.Forte@Sun.COM 		IMA_OID luId,
17277836SJohn.Forte@Sun.COM 		IMA_DEVICE_STATISTICS *pStats
17287836SJohn.Forte@Sun.COM )
17297836SJohn.Forte@Sun.COM {
17307836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
17317836SJohn.Forte@Sun.COM }
17327836SJohn.Forte@Sun.COM 
17337836SJohn.Forte@Sun.COM /*ARGSUSED*/
17347836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_LuInquiry(
17357836SJohn.Forte@Sun.COM 	IMA_OID deviceId,
17367836SJohn.Forte@Sun.COM 	IMA_BOOL evpd,
17377836SJohn.Forte@Sun.COM 	IMA_BOOL cmddt,
17387836SJohn.Forte@Sun.COM 	IMA_BYTE pageCode,
17397836SJohn.Forte@Sun.COM 	IMA_BYTE *pOutputBuffer,
17407836SJohn.Forte@Sun.COM 	IMA_UINT *pOutputBufferLength,
17417836SJohn.Forte@Sun.COM 	IMA_BYTE *pSenseBuffer,
17427836SJohn.Forte@Sun.COM 	IMA_UINT *pSenseBufferLength
17437836SJohn.Forte@Sun.COM )
17447836SJohn.Forte@Sun.COM {
17457836SJohn.Forte@Sun.COM 	IMA_LU_PROPERTIES luProps;
17467836SJohn.Forte@Sun.COM 	IMA_STATUS status;
17477836SJohn.Forte@Sun.COM 
17487836SJohn.Forte@Sun.COM 	char cmdblk [ INQUIRY_CMDLEN ] =
17497836SJohn.Forte@Sun.COM 	    { INQUIRY_CMD,   /* command */
17507836SJohn.Forte@Sun.COM 			0,   /* lun/reserved */
17517836SJohn.Forte@Sun.COM 			0,   /* page code */
17527836SJohn.Forte@Sun.COM 			0,   /* reserved */
17537836SJohn.Forte@Sun.COM 	INQUIRY_REPLY_LEN,   /* allocation length */
17547836SJohn.Forte@Sun.COM 			0 }; /* reserved/flag/link */
17557836SJohn.Forte@Sun.COM 
17567836SJohn.Forte@Sun.COM 
17577836SJohn.Forte@Sun.COM 	int fd;
17587836SJohn.Forte@Sun.COM 	iscsi_uscsi_t uscsi;
17597836SJohn.Forte@Sun.COM 
17607836SJohn.Forte@Sun.COM 	cmdblk[2] = pageCode;
17617836SJohn.Forte@Sun.COM 
17627836SJohn.Forte@Sun.COM 	(void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t));
17637836SJohn.Forte@Sun.COM 	uscsi.iu_vers 	= ISCSI_INTERFACE_VERSION;
17647836SJohn.Forte@Sun.COM 
17657836SJohn.Forte@Sun.COM 	/* iu_oid is a session oid in the driver */
17667836SJohn.Forte@Sun.COM 	if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) {
17677836SJohn.Forte@Sun.COM 		uscsi.iu_oid	= deviceId.objectSequenceNumber;
17687836SJohn.Forte@Sun.COM 		uscsi.iu_lun	= 0;
17697836SJohn.Forte@Sun.COM 	} else {
17707836SJohn.Forte@Sun.COM 		/*
17717836SJohn.Forte@Sun.COM 		 * Get LU properties and associated session oid
17727836SJohn.Forte@Sun.COM 		 * for this lun(deviceId) and put in uscsi.iu_oid
17737836SJohn.Forte@Sun.COM 		 */
17747836SJohn.Forte@Sun.COM 		status = getLuProperties(deviceId, &luProps);
17757836SJohn.Forte@Sun.COM 		if (status != IMA_STATUS_SUCCESS) {
17767836SJohn.Forte@Sun.COM 			return (status);
17777836SJohn.Forte@Sun.COM 		}
17787836SJohn.Forte@Sun.COM 		uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid.
17797836SJohn.Forte@Sun.COM 		    objectSequenceNumber;
17807836SJohn.Forte@Sun.COM 		uscsi.iu_lun = luProps.targetLun;
17817836SJohn.Forte@Sun.COM 	}
17827836SJohn.Forte@Sun.COM 
17837836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_flags = USCSI_READ;
17847836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_timeout = USCSI_TIMEOUT_IN_SEC;
17857836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer;
17867836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_buflen = *pOutputBufferLength;
17877836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer;
17887836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_rqlen = *pSenseBufferLength;
17897836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_cdb = &cmdblk[0];
17907836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_cdblen = INQUIRY_CMDLEN;
17917836SJohn.Forte@Sun.COM 
17927836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
17937836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
17947836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
17957836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
17967836SJohn.Forte@Sun.COM 	}
17977836SJohn.Forte@Sun.COM 
17987836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) {
17997836SJohn.Forte@Sun.COM 		(void) close(fd);
18007836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
18017836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
18027836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
18037836SJohn.Forte@Sun.COM 	}
18047836SJohn.Forte@Sun.COM 
18057836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
18067836SJohn.Forte@Sun.COM }
18077836SJohn.Forte@Sun.COM 
18087836SJohn.Forte@Sun.COM /*ARGSUSED*/
18097836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_LuReadCapacity(
18107836SJohn.Forte@Sun.COM 		IMA_OID deviceId,
18117836SJohn.Forte@Sun.COM 		IMA_UINT cdbLength,
18127836SJohn.Forte@Sun.COM 		IMA_BYTE *pOutputBuffer,
18137836SJohn.Forte@Sun.COM 		IMA_UINT *pOutputBufferLength,
18147836SJohn.Forte@Sun.COM 
18157836SJohn.Forte@Sun.COM 		IMA_BYTE *pSenseBuffer,
18167836SJohn.Forte@Sun.COM 		IMA_UINT *pSenseBufferLength
18177836SJohn.Forte@Sun.COM )
18187836SJohn.Forte@Sun.COM {
18197836SJohn.Forte@Sun.COM 	IMA_LU_PROPERTIES luProps;
18207836SJohn.Forte@Sun.COM 	IMA_STATUS status;
18217836SJohn.Forte@Sun.COM 	int fd;
18227836SJohn.Forte@Sun.COM 	iscsi_uscsi_t uscsi;
18237836SJohn.Forte@Sun.COM 
18247836SJohn.Forte@Sun.COM 	char cmdblk [ INQUIRY_CMDLEN ] =
18257836SJohn.Forte@Sun.COM 		{ GETCAPACITY_CMD,   /* command */
18267836SJohn.Forte@Sun.COM 				0,   /* lun/reserved */
18277836SJohn.Forte@Sun.COM 				0,   /* page code */
18287836SJohn.Forte@Sun.COM 				0,   /* reserved */
18297836SJohn.Forte@Sun.COM 		INQUIRY_REPLY_LEN,   /* allocation length */
18307836SJohn.Forte@Sun.COM 				0 }; /* reserved/flag/link */
18317836SJohn.Forte@Sun.COM 
18327836SJohn.Forte@Sun.COM 
18337836SJohn.Forte@Sun.COM 
18347836SJohn.Forte@Sun.COM 	(void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t));
18357836SJohn.Forte@Sun.COM 	uscsi.iu_vers 	= ISCSI_INTERFACE_VERSION;
18367836SJohn.Forte@Sun.COM 
18377836SJohn.Forte@Sun.COM 	/* iu_oid is a session oid in the driver */
18387836SJohn.Forte@Sun.COM 	if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) {
18397836SJohn.Forte@Sun.COM 		uscsi.iu_oid	= deviceId.objectSequenceNumber;
18407836SJohn.Forte@Sun.COM 		uscsi.iu_lun	= 0;
18417836SJohn.Forte@Sun.COM 	} else {
18427836SJohn.Forte@Sun.COM 		/*
18437836SJohn.Forte@Sun.COM 		 * Get LU properties and associated session oid
18447836SJohn.Forte@Sun.COM 		 * for this lun(deviceId) and put in uscsi.iu_oid
18457836SJohn.Forte@Sun.COM 		 */
18467836SJohn.Forte@Sun.COM 		status = getLuProperties(deviceId, &luProps);
18477836SJohn.Forte@Sun.COM 		if (status != IMA_STATUS_SUCCESS) {
18487836SJohn.Forte@Sun.COM 			return (status);
18497836SJohn.Forte@Sun.COM 		}
18507836SJohn.Forte@Sun.COM 		uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid.
18517836SJohn.Forte@Sun.COM 		    objectSequenceNumber;
18527836SJohn.Forte@Sun.COM 		uscsi.iu_lun = luProps.targetLun;
18537836SJohn.Forte@Sun.COM 	}
18547836SJohn.Forte@Sun.COM 
18557836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_flags = USCSI_READ;
18567836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_timeout = 10;
18577836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer;
18587836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_buflen = *pOutputBufferLength;
18597836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer;
18607836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_rqlen = *pSenseBufferLength;
18617836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_cdb = &cmdblk[0];
18627836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_cdblen = INQUIRY_CMDLEN;
18637836SJohn.Forte@Sun.COM 
18647836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
18657836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
18667836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
18677836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
18687836SJohn.Forte@Sun.COM 	}
18697836SJohn.Forte@Sun.COM 
18707836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) {
18717836SJohn.Forte@Sun.COM 		(void) close(fd);
18727836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
18737836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
18747836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
18757836SJohn.Forte@Sun.COM 	}
18767836SJohn.Forte@Sun.COM 
18777836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
18787836SJohn.Forte@Sun.COM }
18797836SJohn.Forte@Sun.COM 
18807836SJohn.Forte@Sun.COM /*ARGSUSED*/
18817836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_LuReportLuns(
18827836SJohn.Forte@Sun.COM 		IMA_OID deviceId,
18837836SJohn.Forte@Sun.COM 		IMA_BOOL sendToWellKnownLun,
18847836SJohn.Forte@Sun.COM 		IMA_BYTE selectReport,
18857836SJohn.Forte@Sun.COM 
18867836SJohn.Forte@Sun.COM 		IMA_BYTE *pOutputBuffer,
18877836SJohn.Forte@Sun.COM 		IMA_UINT *pOutputBufferLength,
18887836SJohn.Forte@Sun.COM 
18897836SJohn.Forte@Sun.COM 		IMA_BYTE *pSenseBuffer,
18907836SJohn.Forte@Sun.COM 		IMA_UINT *pSenseBufferLength
18917836SJohn.Forte@Sun.COM )
18927836SJohn.Forte@Sun.COM {
18937836SJohn.Forte@Sun.COM 	IMA_LU_PROPERTIES luProps;
18947836SJohn.Forte@Sun.COM 	IMA_STATUS status;
18957836SJohn.Forte@Sun.COM 	int fd;
18967836SJohn.Forte@Sun.COM 	iscsi_uscsi_t uscsi;
18977836SJohn.Forte@Sun.COM 
18987836SJohn.Forte@Sun.COM 	char cmdblk [ INQUIRY_CMDLEN ] =
18997836SJohn.Forte@Sun.COM 	    { INQUIRY_CMD,   /* command */
19007836SJohn.Forte@Sun.COM 			0,   /* lun/reserved */
19017836SJohn.Forte@Sun.COM 			0,   /* page code */
19027836SJohn.Forte@Sun.COM 			0,   /* reserved */
19037836SJohn.Forte@Sun.COM 	INQUIRY_REPLY_LEN,   /* allocation length */
19047836SJohn.Forte@Sun.COM 			0 }; /* reserved/flag/link */
19057836SJohn.Forte@Sun.COM 
19067836SJohn.Forte@Sun.COM 	(void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t));
19077836SJohn.Forte@Sun.COM 	uscsi.iu_vers 	= ISCSI_INTERFACE_VERSION;
19087836SJohn.Forte@Sun.COM 
19097836SJohn.Forte@Sun.COM 	/* iu_oid is a session oid in the driver */
19107836SJohn.Forte@Sun.COM 	if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) {
19117836SJohn.Forte@Sun.COM 		uscsi.iu_oid	= deviceId.objectSequenceNumber;
19127836SJohn.Forte@Sun.COM 		uscsi.iu_lun	= 0;
19137836SJohn.Forte@Sun.COM 	} else {
19147836SJohn.Forte@Sun.COM 		/*
19157836SJohn.Forte@Sun.COM 		 * Get LU properties and associated session oid
19167836SJohn.Forte@Sun.COM 		 * for this lun(deviceId) and put in uscsi.iu_oid
19177836SJohn.Forte@Sun.COM 		 */
19187836SJohn.Forte@Sun.COM 		status = getLuProperties(deviceId, &luProps);
19197836SJohn.Forte@Sun.COM 		if (status != IMA_STATUS_SUCCESS) {
19207836SJohn.Forte@Sun.COM 			return (status);
19217836SJohn.Forte@Sun.COM 		}
19227836SJohn.Forte@Sun.COM 		uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid.
19237836SJohn.Forte@Sun.COM 		    objectSequenceNumber;
19247836SJohn.Forte@Sun.COM 		uscsi.iu_lun = luProps.targetLun;
19257836SJohn.Forte@Sun.COM 	}
19267836SJohn.Forte@Sun.COM 
19277836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_flags = USCSI_READ;
19287836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_timeout = 10;
19297836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer;
19307836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_buflen = *pOutputBufferLength;
19317836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer;
19327836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_rqlen = *pSenseBufferLength;
19337836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_cdb = &cmdblk[0];
19347836SJohn.Forte@Sun.COM 	uscsi.iu_ucmd.uscsi_cdblen = INQUIRY_CMDLEN;
19357836SJohn.Forte@Sun.COM 
19367836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
19377836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
19387836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
19397836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
19407836SJohn.Forte@Sun.COM 	}
19417836SJohn.Forte@Sun.COM 
19427836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) {
19437836SJohn.Forte@Sun.COM 		(void) close(fd);
19447836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
19457836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno);
19467836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
19477836SJohn.Forte@Sun.COM 	}
19487836SJohn.Forte@Sun.COM 
19497836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
19507836SJohn.Forte@Sun.COM }
19517836SJohn.Forte@Sun.COM 
19527836SJohn.Forte@Sun.COM /*ARGSUSED*/
19537836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_ExposeLu(
19547836SJohn.Forte@Sun.COM 		IMA_OID luId
19557836SJohn.Forte@Sun.COM )
19567836SJohn.Forte@Sun.COM {
19577836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
19587836SJohn.Forte@Sun.COM }
19597836SJohn.Forte@Sun.COM 
19607836SJohn.Forte@Sun.COM /*ARGSUSED*/
19617836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_UnexposeLu(
19627836SJohn.Forte@Sun.COM 		IMA_OID luId
19637836SJohn.Forte@Sun.COM )
19647836SJohn.Forte@Sun.COM {
19657836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
19667836SJohn.Forte@Sun.COM }
19677836SJohn.Forte@Sun.COM 
19687836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetAddressKeys(
19697836SJohn.Forte@Sun.COM 		IMA_OID targetOid,
19707836SJohn.Forte@Sun.COM 		IMA_ADDRESS_KEYS **ppKeys
19717836SJohn.Forte@Sun.COM )
19727836SJohn.Forte@Sun.COM {
19737836SJohn.Forte@Sun.COM 	IMA_STATUS status;
19747836SJohn.Forte@Sun.COM 	IMA_TARGET_PROPERTIES targetProps;
19757836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDR_PROP_LIST *discAddressList;
19767836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList;
19777836SJohn.Forte@Sun.COM 	int i, j, addressKeyCount = 0;
19787836SJohn.Forte@Sun.COM 	int addressKeyIdx = 0;
19797836SJohn.Forte@Sun.COM 
19807836SJohn.Forte@Sun.COM 	status = getTargetProperties(targetOid, &targetProps);
19817836SJohn.Forte@Sun.COM 	if (status != IMA_STATUS_SUCCESS) {
19827836SJohn.Forte@Sun.COM 		return (status);
19837836SJohn.Forte@Sun.COM 	}
19847836SJohn.Forte@Sun.COM 
19857836SJohn.Forte@Sun.COM 	status = getDiscoveryAddressPropertiesList(&discAddressList);
19867836SJohn.Forte@Sun.COM 	if (status != IMA_STATUS_SUCCESS) {
19877836SJohn.Forte@Sun.COM 		return (status);
19887836SJohn.Forte@Sun.COM 	}
19897836SJohn.Forte@Sun.COM 
19907836SJohn.Forte@Sun.COM 	/* Get the number of addresses to allocate */
19917836SJohn.Forte@Sun.COM 	for (i = 0; i < discAddressList->discAddrCount; i++) {
19927836SJohn.Forte@Sun.COM 		(void) sendTargets(discAddressList->props[i].discoveryAddress,
19937836SJohn.Forte@Sun.COM 		    &pList);
19947836SJohn.Forte@Sun.COM 		for (j = 0; j < pList->keyCount; j++) {
19957836SJohn.Forte@Sun.COM 			if (wcsncmp(pList->keys[j].name, targetProps.name,
19967836SJohn.Forte@Sun.COM 			    wslen(pList->keys[j].name)) == 0) {
19977836SJohn.Forte@Sun.COM 				addressKeyCount++;
19987836SJohn.Forte@Sun.COM 			}
19997836SJohn.Forte@Sun.COM 		}
20007836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(pList);
20017836SJohn.Forte@Sun.COM 	}
20027836SJohn.Forte@Sun.COM 
20037836SJohn.Forte@Sun.COM 	*ppKeys = (IMA_ADDRESS_KEYS *)calloc(1, sizeof (IMA_ADDRESS_KEYS) +
20047836SJohn.Forte@Sun.COM 	    addressKeyCount * sizeof (IMA_ADDRESS_KEY));
20057836SJohn.Forte@Sun.COM 	if (*ppKeys == NULL) {
20067836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
20077836SJohn.Forte@Sun.COM 	}
20087836SJohn.Forte@Sun.COM 	(*ppKeys)->addressKeyCount = addressKeyCount;
20097836SJohn.Forte@Sun.COM 	addressKeyIdx = 0;
20107836SJohn.Forte@Sun.COM 
20117836SJohn.Forte@Sun.COM 	for (i = 0; i < discAddressList->discAddrCount; i++) {
20127836SJohn.Forte@Sun.COM 		(void) sendTargets(discAddressList->props[i].discoveryAddress,
20137836SJohn.Forte@Sun.COM 		    &pList);
20147836SJohn.Forte@Sun.COM 		for (j = 0; j < pList->keyCount; j++) {
20157836SJohn.Forte@Sun.COM 			if (wcsncmp(pList->keys[j].name, targetProps.name,
20167836SJohn.Forte@Sun.COM 			    wslen(pList->keys[j].name)) != 0) {
20177836SJohn.Forte@Sun.COM 				continue;
20187836SJohn.Forte@Sun.COM 			}
20197836SJohn.Forte@Sun.COM 
20207836SJohn.Forte@Sun.COM 			bcopy(&(pList->keys[j].address.ipAddress),
20217836SJohn.Forte@Sun.COM 			    &((*ppKeys)->addressKeys[addressKeyIdx].
20227836SJohn.Forte@Sun.COM 			    ipAddress), sizeof (IMA_IP_ADDRESS));
20237836SJohn.Forte@Sun.COM 
20247836SJohn.Forte@Sun.COM 			(*ppKeys)->addressKeys[addressKeyIdx++].portNumber =
20257836SJohn.Forte@Sun.COM 			    pList->keys[j].address.portNumber;
20267836SJohn.Forte@Sun.COM 
20277836SJohn.Forte@Sun.COM 		}
20287836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(pList);
20297836SJohn.Forte@Sun.COM 	}
20307836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
20317836SJohn.Forte@Sun.COM }
20327836SJohn.Forte@Sun.COM 
20337836SJohn.Forte@Sun.COM IMA_BOOL isAuthMethodValid(IMA_OID oid, IMA_AUTHMETHOD method) {
20347836SJohn.Forte@Sun.COM 	IMA_STATUS status;
20357836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD supportedList[MAX_AUTHMETHODS];
20367836SJohn.Forte@Sun.COM 	IMA_UINT i, supportedCount;
20377836SJohn.Forte@Sun.COM 	IMA_BOOL supported;
20387836SJohn.Forte@Sun.COM 	status = getSupportedAuthMethods(oid, IMA_FALSE, &supportedCount,
20397836SJohn.Forte@Sun.COM 			supportedList);
20407836SJohn.Forte@Sun.COM 	if (status != IMA_STATUS_SUCCESS)
20417836SJohn.Forte@Sun.COM 		return (IMA_FALSE);
20427836SJohn.Forte@Sun.COM 
20437836SJohn.Forte@Sun.COM 	supported = IMA_FALSE;
20447836SJohn.Forte@Sun.COM 	for (i = 0; i < supportedCount; i++) {
20457836SJohn.Forte@Sun.COM 		if (method == supportedList[i]) {
20467836SJohn.Forte@Sun.COM 			supported = IMA_TRUE;
20477836SJohn.Forte@Sun.COM 		}
20487836SJohn.Forte@Sun.COM 	}
20497836SJohn.Forte@Sun.COM 
20507836SJohn.Forte@Sun.COM 	return (supported);
20517836SJohn.Forte@Sun.COM }
20527836SJohn.Forte@Sun.COM 
20537836SJohn.Forte@Sun.COM IMA_BOOL isAuthMethodListValid(IMA_OID oid, const IMA_AUTHMETHOD *pMethodList,
20547836SJohn.Forte@Sun.COM 				IMA_UINT methodCount) {
20557836SJohn.Forte@Sun.COM 	IMA_UINT i, j;
20567836SJohn.Forte@Sun.COM 
20577836SJohn.Forte@Sun.COM 	if (pMethodList == NULL) {
20587836SJohn.Forte@Sun.COM 		return (IMA_FALSE);
20597836SJohn.Forte@Sun.COM 	}
20607836SJohn.Forte@Sun.COM 	/* Check list for duplicates */
20617836SJohn.Forte@Sun.COM 	for (i = 0; i < methodCount; i++) {
20627836SJohn.Forte@Sun.COM 		for (j = i + 1; j < methodCount; j++) {
20637836SJohn.Forte@Sun.COM 			if (pMethodList[i] == pMethodList[j]) {
20647836SJohn.Forte@Sun.COM 				return (IMA_FALSE);
20657836SJohn.Forte@Sun.COM 			}
20667836SJohn.Forte@Sun.COM 		}
20677836SJohn.Forte@Sun.COM 
20687836SJohn.Forte@Sun.COM 		if (isAuthMethodValid(oid, pMethodList[i]) == IMA_FALSE) {
20697836SJohn.Forte@Sun.COM 			return (IMA_FALSE);
20707836SJohn.Forte@Sun.COM 		}
20717836SJohn.Forte@Sun.COM 	}
20727836SJohn.Forte@Sun.COM 	return (IMA_TRUE);
20737836SJohn.Forte@Sun.COM }
20747836SJohn.Forte@Sun.COM 
20757836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetSupportedAuthMethods(
20767836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
20777836SJohn.Forte@Sun.COM 		IMA_BOOL getSettableMethods,
20787836SJohn.Forte@Sun.COM 		IMA_UINT *pMethodCount,
20797836SJohn.Forte@Sun.COM 		IMA_AUTHMETHOD *pMethodList
20807836SJohn.Forte@Sun.COM )
20817836SJohn.Forte@Sun.COM {
20827836SJohn.Forte@Sun.COM 	return (getSupportedAuthMethods(lhbaOid, getSettableMethods,
20837836SJohn.Forte@Sun.COM 	    pMethodCount, pMethodList));
20847836SJohn.Forte@Sun.COM }
20857836SJohn.Forte@Sun.COM 
20867836SJohn.Forte@Sun.COM 
20877836SJohn.Forte@Sun.COM /*ARGSUSED*/
20887836SJohn.Forte@Sun.COM static IMA_STATUS getSupportedAuthMethods(
20897836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
20907836SJohn.Forte@Sun.COM 		IMA_BOOL getSettableMethods,
20917836SJohn.Forte@Sun.COM 		IMA_UINT *pMethodCount,
20927836SJohn.Forte@Sun.COM 		IMA_AUTHMETHOD *pMethodList
20937836SJohn.Forte@Sun.COM )
20947836SJohn.Forte@Sun.COM {
20957836SJohn.Forte@Sun.COM 	if (pMethodList == NULL) {
20967836SJohn.Forte@Sun.COM 		*pMethodCount = 0;
20977836SJohn.Forte@Sun.COM 		return (IMA_STATUS_SUCCESS);
20987836SJohn.Forte@Sun.COM 	}
20997836SJohn.Forte@Sun.COM 
21007836SJohn.Forte@Sun.COM 	*pMethodCount = NUM_SUPPORTED_AUTH_METHODS;
21017836SJohn.Forte@Sun.COM 	if (*pMethodCount > 1) {
21027836SJohn.Forte@Sun.COM 		pMethodList[0] = IMA_AUTHMETHOD_NONE;
21037836SJohn.Forte@Sun.COM 		pMethodList[1] = IMA_AUTHMETHOD_CHAP;
21047836SJohn.Forte@Sun.COM 	}
21057836SJohn.Forte@Sun.COM 
21067836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
21077836SJohn.Forte@Sun.COM }
21087836SJohn.Forte@Sun.COM 
21097836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetInUseInitiatorAuthMethods(
21107836SJohn.Forte@Sun.COM 		IMA_OID		lhbaOid,
21117836SJohn.Forte@Sun.COM 		IMA_UINT	*pMethodCount,
21127836SJohn.Forte@Sun.COM 		IMA_AUTHMETHOD *pMethodList
21137836SJohn.Forte@Sun.COM )
21147836SJohn.Forte@Sun.COM {
21157836SJohn.Forte@Sun.COM 	return (getAuthMethods(lhbaOid, pMethodCount, pMethodList));
21167836SJohn.Forte@Sun.COM }
21177836SJohn.Forte@Sun.COM 
21187836SJohn.Forte@Sun.COM /*ARGSUSED*/
21197836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_GetInitiatorAuthParms(
21207836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
21217836SJohn.Forte@Sun.COM 		IMA_AUTHMETHOD method,
21227836SJohn.Forte@Sun.COM 		IMA_INITIATOR_AUTHPARMS *pParms
21237836SJohn.Forte@Sun.COM )
21247836SJohn.Forte@Sun.COM {
21257836SJohn.Forte@Sun.COM 	int fd;
21267836SJohn.Forte@Sun.COM 	iscsi_chap_props_t  chap_p;
21277836SJohn.Forte@Sun.COM 
21287836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
21297836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
21307836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
21317836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
21327836SJohn.Forte@Sun.COM 	}
21337836SJohn.Forte@Sun.COM 
21347836SJohn.Forte@Sun.COM 	(void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
21357836SJohn.Forte@Sun.COM 	chap_p.c_vers = ISCSI_INTERFACE_VERSION;
21367836SJohn.Forte@Sun.COM 	chap_p.c_oid = (uint32_t)lhbaOid.objectSequenceNumber;
21377836SJohn.Forte@Sun.COM 
21387836SJohn.Forte@Sun.COM 	if (method == IMA_AUTHMETHOD_CHAP) {
21397836SJohn.Forte@Sun.COM 		if (ioctl(fd, ISCSI_CHAP_GET, &chap_p) != 0) {
21407836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
21417836SJohn.Forte@Sun.COM 			"ISCSI_CHAP_GET ioctl failed, errno: %d", errno);
21427836SJohn.Forte@Sun.COM 			(void) close(fd);
21437836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
21447836SJohn.Forte@Sun.COM 		}
21457836SJohn.Forte@Sun.COM 	} else {
21467836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
21477836SJohn.Forte@Sun.COM 	}
21487836SJohn.Forte@Sun.COM 
21497836SJohn.Forte@Sun.COM 	(void) memcpy(pParms->chapParms.name, chap_p.c_user,
21507836SJohn.Forte@Sun.COM 	    chap_p.c_user_len);
21517836SJohn.Forte@Sun.COM 	pParms->chapParms.nameLength = chap_p.c_user_len;
21527836SJohn.Forte@Sun.COM 	(void) memcpy(pParms->chapParms.challengeSecret, chap_p.c_secret,
21537836SJohn.Forte@Sun.COM 	    chap_p.c_secret_len);
21547836SJohn.Forte@Sun.COM 	pParms->chapParms.challengeSecretLength = chap_p.c_secret_len;
21557836SJohn.Forte@Sun.COM 
21567836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
21577836SJohn.Forte@Sun.COM }
21587836SJohn.Forte@Sun.COM 
21597836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetInitiatorAuthMethods(
21607836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
21617836SJohn.Forte@Sun.COM 		IMA_UINT methodCount,
21627836SJohn.Forte@Sun.COM 		const IMA_AUTHMETHOD *pMethodList
21637836SJohn.Forte@Sun.COM )
21647836SJohn.Forte@Sun.COM {
21657836SJohn.Forte@Sun.COM 	if (isAuthMethodListValid(lhbaOid, pMethodList,
21667836SJohn.Forte@Sun.COM 	    methodCount) == IMA_FALSE)
21677836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
21687836SJohn.Forte@Sun.COM 	return (setAuthMethods(lhbaOid, &methodCount, pMethodList));
21697836SJohn.Forte@Sun.COM }
21707836SJohn.Forte@Sun.COM 
21717836SJohn.Forte@Sun.COM /*
21727836SJohn.Forte@Sun.COM  * This function only sets CHAP params since we only support CHAP for now.
21737836SJohn.Forte@Sun.COM  */
21747836SJohn.Forte@Sun.COM IMA_API	IMA_STATUS IMA_SetInitiatorAuthParms(
21757836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
21767836SJohn.Forte@Sun.COM 		IMA_AUTHMETHOD method,
21777836SJohn.Forte@Sun.COM 		const IMA_INITIATOR_AUTHPARMS *pParms
21787836SJohn.Forte@Sun.COM )
21797836SJohn.Forte@Sun.COM {
21807836SJohn.Forte@Sun.COM 	int fd;
21817836SJohn.Forte@Sun.COM 	iscsi_chap_props_t  chap_p;
21827836SJohn.Forte@Sun.COM 
21837836SJohn.Forte@Sun.COM 	if (method != IMA_AUTHMETHOD_CHAP)
21847836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
21857836SJohn.Forte@Sun.COM 
21867836SJohn.Forte@Sun.COM 	if (isAuthMethodValid(lhbaOid, method) == IMA_FALSE) {
21877836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
21887836SJohn.Forte@Sun.COM 	}
21897836SJohn.Forte@Sun.COM 
21907836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
21917836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
21927836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
21937836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
21947836SJohn.Forte@Sun.COM 	}
21957836SJohn.Forte@Sun.COM 
21967836SJohn.Forte@Sun.COM 	(void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t));
21977836SJohn.Forte@Sun.COM 	chap_p.c_vers = ISCSI_INTERFACE_VERSION;
21987836SJohn.Forte@Sun.COM 	chap_p.c_oid = (uint32_t)lhbaOid.objectSequenceNumber;
21997836SJohn.Forte@Sun.COM 
22007836SJohn.Forte@Sun.COM 	chap_p.c_user_len = pParms->chapParms.nameLength;
22017836SJohn.Forte@Sun.COM 	(void) memcpy(chap_p.c_user, pParms->chapParms.name, chap_p.c_user_len);
22027836SJohn.Forte@Sun.COM 
22037836SJohn.Forte@Sun.COM 	chap_p.c_secret_len = pParms->chapParms.challengeSecretLength;
22047836SJohn.Forte@Sun.COM 	(void) memcpy(chap_p.c_secret, pParms->chapParms.challengeSecret,
22057836SJohn.Forte@Sun.COM 	    chap_p.c_secret_len);
22067836SJohn.Forte@Sun.COM 
22077836SJohn.Forte@Sun.COM 	if (method == IMA_AUTHMETHOD_CHAP) {
22087836SJohn.Forte@Sun.COM 		if (ioctl(fd, ISCSI_CHAP_SET, &chap_p) != 0) {
22097836SJohn.Forte@Sun.COM 			(void) close(fd);
22107836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
22117836SJohn.Forte@Sun.COM 			    "ISCSI_CHAP_SET ioctl failed, errno: %d", errno);
22127836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
22137836SJohn.Forte@Sun.COM 		}
22147836SJohn.Forte@Sun.COM 	}
22157836SJohn.Forte@Sun.COM 
22167836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
22177836SJohn.Forte@Sun.COM }
22187836SJohn.Forte@Sun.COM 
22197836SJohn.Forte@Sun.COM /* A helper function to obtain iSCSI node parameters. */
22207836SJohn.Forte@Sun.COM static IMA_STATUS
22217836SJohn.Forte@Sun.COM getISCSINodeParameter(
22227836SJohn.Forte@Sun.COM     int paramType,
22237836SJohn.Forte@Sun.COM     IMA_OID *oid,
22247836SJohn.Forte@Sun.COM     void *pProps,
22257836SJohn.Forte@Sun.COM     uint32_t paramIndex
22267836SJohn.Forte@Sun.COM )
22277836SJohn.Forte@Sun.COM {
22287836SJohn.Forte@Sun.COM 	int		    fd;
22297836SJohn.Forte@Sun.COM 	iscsi_param_get_t   pg;
22307836SJohn.Forte@Sun.COM 
22317836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
22327836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
22337836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
22347836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
22357836SJohn.Forte@Sun.COM 	}
22367836SJohn.Forte@Sun.COM 
22377836SJohn.Forte@Sun.COM 	(void) memset(&pg, 0, sizeof (iscsi_param_get_t));
22387836SJohn.Forte@Sun.COM 	pg.g_vers = ISCSI_INTERFACE_VERSION;
22397836SJohn.Forte@Sun.COM 	pg.g_oid = (uint32_t)oid->objectSequenceNumber;
22407836SJohn.Forte@Sun.COM 	pg.g_param = paramIndex;
22417836SJohn.Forte@Sun.COM 	pg.g_param_type = ISCSI_SESS_PARAM;
22427836SJohn.Forte@Sun.COM 
22437836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) {
22447836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
22457836SJohn.Forte@Sun.COM 		    "ISCSI_PARAM_GET ioctl failed, errno: %d", errno);
22467836SJohn.Forte@Sun.COM 		(void) close(fd);
22477836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
22487836SJohn.Forte@Sun.COM 	}
22497836SJohn.Forte@Sun.COM 
22507836SJohn.Forte@Sun.COM 	switch (paramType) {
22517836SJohn.Forte@Sun.COM 		IMA_BOOL_VALUE *bp;
22527836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *mp;
22537836SJohn.Forte@Sun.COM 
22547836SJohn.Forte@Sun.COM 		case MIN_MAX_PARAM:
22557836SJohn.Forte@Sun.COM 			mp = (IMA_MIN_MAX_VALUE *)pProps;
22567836SJohn.Forte@Sun.COM 
22577836SJohn.Forte@Sun.COM 			mp->currentValueValid =
22587836SJohn.Forte@Sun.COM 			    (pg.g_value.v_valid == B_TRUE) ?
22597836SJohn.Forte@Sun.COM 			    IMA_TRUE : IMA_FALSE;
22607836SJohn.Forte@Sun.COM 			mp->currentValue = pg.g_value.v_integer.i_current;
22617836SJohn.Forte@Sun.COM 			mp->defaultValue = pg.g_value.v_integer.i_default;
22627836SJohn.Forte@Sun.COM 			mp->minimumValue = pg.g_value.v_integer.i_min;
22637836SJohn.Forte@Sun.COM 			mp->maximumValue = pg.g_value.v_integer.i_max;
22647836SJohn.Forte@Sun.COM 			mp->incrementValue = pg.g_value.v_integer.i_incr;
22657836SJohn.Forte@Sun.COM 			break;
22667836SJohn.Forte@Sun.COM 
22677836SJohn.Forte@Sun.COM 		case BOOL_PARAM:
22687836SJohn.Forte@Sun.COM 			bp = (IMA_BOOL_VALUE *)pProps;
22697836SJohn.Forte@Sun.COM 			bp->currentValueValid =
22707836SJohn.Forte@Sun.COM 			    (pg.g_value.v_valid == B_TRUE) ?
22717836SJohn.Forte@Sun.COM 			    IMA_TRUE : IMA_FALSE;
22727836SJohn.Forte@Sun.COM 			bp->currentValue = pg.g_value.v_bool.b_current;
22737836SJohn.Forte@Sun.COM 			bp->defaultValue = pg.g_value.v_bool.b_default;
22747836SJohn.Forte@Sun.COM 			break;
22757836SJohn.Forte@Sun.COM 
22767836SJohn.Forte@Sun.COM 		default:
22777836SJohn.Forte@Sun.COM 			break;
22787836SJohn.Forte@Sun.COM 	}
22797836SJohn.Forte@Sun.COM 
22807836SJohn.Forte@Sun.COM 	(void) close(fd);
22817836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
22827836SJohn.Forte@Sun.COM }
22837836SJohn.Forte@Sun.COM 
22847836SJohn.Forte@Sun.COM /* A helper function to set iSCSI node parameters. */
22857836SJohn.Forte@Sun.COM static IMA_STATUS
22867836SJohn.Forte@Sun.COM setISCSINodeParameter(
22877836SJohn.Forte@Sun.COM     int paramType,
22887836SJohn.Forte@Sun.COM     IMA_OID *oid,
22897836SJohn.Forte@Sun.COM     void *pProp,
22907836SJohn.Forte@Sun.COM     uint32_t paramIndex
22917836SJohn.Forte@Sun.COM )
22927836SJohn.Forte@Sun.COM {
22937836SJohn.Forte@Sun.COM 	int		    fd;
22947836SJohn.Forte@Sun.COM 	iscsi_param_set_t   ps;
22957836SJohn.Forte@Sun.COM 
22967836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
22977836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
22987836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
22997836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
23007836SJohn.Forte@Sun.COM 	}
23017836SJohn.Forte@Sun.COM 
23027836SJohn.Forte@Sun.COM 	(void) memset(&ps, 0, sizeof (iscsi_param_set_t));
23037836SJohn.Forte@Sun.COM 	ps.s_vers = ISCSI_INTERFACE_VERSION;
23047836SJohn.Forte@Sun.COM 	ps.s_oid = (uint32_t)oid->objectSequenceNumber;
23057836SJohn.Forte@Sun.COM 	ps.s_param = paramIndex;
23067836SJohn.Forte@Sun.COM 
23077836SJohn.Forte@Sun.COM 	switch (paramType) {
23087836SJohn.Forte@Sun.COM 		IMA_BOOL_VALUE *bp;
23097836SJohn.Forte@Sun.COM 		IMA_MIN_MAX_VALUE *mp;
23107836SJohn.Forte@Sun.COM 
23117836SJohn.Forte@Sun.COM 		case MIN_MAX_PARAM:
23127836SJohn.Forte@Sun.COM 			mp = (IMA_MIN_MAX_VALUE *)pProp;
23137836SJohn.Forte@Sun.COM 			ps.s_value.v_integer = mp->currentValue;
23147836SJohn.Forte@Sun.COM 			break;
23157836SJohn.Forte@Sun.COM 		case BOOL_PARAM:
23167836SJohn.Forte@Sun.COM 			bp = (IMA_BOOL_VALUE *)pProp;
23177836SJohn.Forte@Sun.COM 			ps.s_value.v_bool =
23187836SJohn.Forte@Sun.COM 			    (bp->currentValue == IMA_TRUE) ?
23197836SJohn.Forte@Sun.COM 			    B_TRUE : B_FALSE;
23207836SJohn.Forte@Sun.COM 			break;
23217836SJohn.Forte@Sun.COM 
23227836SJohn.Forte@Sun.COM 		default:
23237836SJohn.Forte@Sun.COM 			break;
23247836SJohn.Forte@Sun.COM 	}
23257836SJohn.Forte@Sun.COM 
23267836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_PARAM_SET, &ps)) {
23277836SJohn.Forte@Sun.COM 		int tmpErrno = errno;
23287836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
23297836SJohn.Forte@Sun.COM 		    "ISCSI_PARAM_SET ioctl failed, errno: %d", errno);
23307836SJohn.Forte@Sun.COM 		(void) close(fd);
23317836SJohn.Forte@Sun.COM 		switch (tmpErrno) {
23327836SJohn.Forte@Sun.COM 			case ENOTSUP :
23337836SJohn.Forte@Sun.COM 				return (IMA_ERROR_NOT_SUPPORTED);
23347836SJohn.Forte@Sun.COM 			default :
23357836SJohn.Forte@Sun.COM 				return (IMA_ERROR_UNEXPECTED_OS_ERROR);
23367836SJohn.Forte@Sun.COM 		}
23377836SJohn.Forte@Sun.COM 	}
23387836SJohn.Forte@Sun.COM 
23397836SJohn.Forte@Sun.COM 	(void) close(fd);
23407836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
23417836SJohn.Forte@Sun.COM }
23427836SJohn.Forte@Sun.COM 
23437836SJohn.Forte@Sun.COM static int
23447836SJohn.Forte@Sun.COM prepare_discovery_entry(
23457836SJohn.Forte@Sun.COM     IMA_TARGET_ADDRESS discoveryAddress,
23467836SJohn.Forte@Sun.COM     entry_t *entry
23477836SJohn.Forte@Sun.COM )
23487836SJohn.Forte@Sun.COM {
23497836SJohn.Forte@Sun.COM 	(void) memset(entry, 0, sizeof (entry_t));
23507836SJohn.Forte@Sun.COM 	entry->e_vers = ISCSI_INTERFACE_VERSION;
23517836SJohn.Forte@Sun.COM 	entry->e_oid = ISCSI_OID_NOTSET;
23527836SJohn.Forte@Sun.COM 
23537836SJohn.Forte@Sun.COM 	if (discoveryAddress.hostnameIpAddress.id.ipAddress.ipv4Address ==
23547836SJohn.Forte@Sun.COM 	    IMA_FALSE) {
23557836SJohn.Forte@Sun.COM 		bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress,
23567836SJohn.Forte@Sun.COM 		    entry->e_u.u_in6.s6_addr,
23577836SJohn.Forte@Sun.COM 		    sizeof (entry->e_u.u_in6.s6_addr));
23587836SJohn.Forte@Sun.COM 		entry->e_insize = sizeof (struct in6_addr);
23597836SJohn.Forte@Sun.COM 	} else {
23607836SJohn.Forte@Sun.COM 		bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress,
23617836SJohn.Forte@Sun.COM 		    &entry->e_u.u_in4.s_addr,
23627836SJohn.Forte@Sun.COM 		    sizeof (entry->e_u.u_in4.s_addr));
23637836SJohn.Forte@Sun.COM 		entry->e_insize = sizeof (struct in_addr);
23647836SJohn.Forte@Sun.COM 	}
23657836SJohn.Forte@Sun.COM 
23667836SJohn.Forte@Sun.COM 	entry->e_port = discoveryAddress.portNumber;
23677836SJohn.Forte@Sun.COM 	entry->e_tpgt = 0;
23687836SJohn.Forte@Sun.COM 	return (DISC_ADDR_OK);
23697836SJohn.Forte@Sun.COM }
23707836SJohn.Forte@Sun.COM 
23717836SJohn.Forte@Sun.COM static IMA_STATUS configure_discovery_method(
23727836SJohn.Forte@Sun.COM     IMA_BOOL enable,
23737836SJohn.Forte@Sun.COM     iSCSIDiscoveryMethod_t method
23747836SJohn.Forte@Sun.COM )
23757836SJohn.Forte@Sun.COM {
23767836SJohn.Forte@Sun.COM 	int fd, status;
23777836SJohn.Forte@Sun.COM 
23787836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
23797836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
23807836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
23817836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
23827836SJohn.Forte@Sun.COM 	}
23837836SJohn.Forte@Sun.COM 
23847836SJohn.Forte@Sun.COM 	if (enable == IMA_FALSE) {
23857836SJohn.Forte@Sun.COM 		if (ioctl(fd, ISCSI_DISCOVERY_CLEAR, &method)) {
23867836SJohn.Forte@Sun.COM 			status = errno;
23877836SJohn.Forte@Sun.COM 			(void) close(fd);
23887836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
23897836SJohn.Forte@Sun.COM 			    "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d",
23907836SJohn.Forte@Sun.COM 			    status);
23917836SJohn.Forte@Sun.COM 			if (status == EBUSY) {
23927836SJohn.Forte@Sun.COM 				return (IMA_ERROR_LU_IN_USE);
23937836SJohn.Forte@Sun.COM 			} else {
23947836SJohn.Forte@Sun.COM 				return (IMA_ERROR_UNEXPECTED_OS_ERROR);
23957836SJohn.Forte@Sun.COM 			}
23967836SJohn.Forte@Sun.COM 		}
23977836SJohn.Forte@Sun.COM 
23987836SJohn.Forte@Sun.COM 		(void) close(fd);
23997836SJohn.Forte@Sun.COM 		return (IMA_STATUS_SUCCESS);
24007836SJohn.Forte@Sun.COM 	} else {
24017836SJohn.Forte@Sun.COM 		/* Set the discovery method */
24027836SJohn.Forte@Sun.COM 		if (ioctl(fd, ISCSI_DISCOVERY_SET, &method)) {
24037836SJohn.Forte@Sun.COM 			(void) close(fd);
24047836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
24057836SJohn.Forte@Sun.COM 			    "ISCSI_DISCOVERY_SET ioctl failed, errno: %d",
24067836SJohn.Forte@Sun.COM 			    errno);
24077836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
24087836SJohn.Forte@Sun.COM 		}
24097836SJohn.Forte@Sun.COM 
24107836SJohn.Forte@Sun.COM 		(void) close(fd);
24117836SJohn.Forte@Sun.COM 		return (IMA_STATUS_SUCCESS);
24127836SJohn.Forte@Sun.COM 	}
24137836SJohn.Forte@Sun.COM }
24147836SJohn.Forte@Sun.COM 
24157836SJohn.Forte@Sun.COM static IMA_STATUS get_target_oid_list(
24167836SJohn.Forte@Sun.COM     uint32_t targetListType,
24177836SJohn.Forte@Sun.COM     IMA_OID_LIST **ppList)
24187836SJohn.Forte@Sun.COM {
24197836SJohn.Forte@Sun.COM 	int		    fd;
24207836SJohn.Forte@Sun.COM 	int		    i;
24217836SJohn.Forte@Sun.COM 	int		    target_list_size;
24227836SJohn.Forte@Sun.COM 	iscsi_target_list_t *idlp, tl_info;
24237836SJohn.Forte@Sun.COM 
24247836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
24257836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
24267836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
24277836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
24287836SJohn.Forte@Sun.COM 	}
24297836SJohn.Forte@Sun.COM 
24307836SJohn.Forte@Sun.COM 	(void) memset(&tl_info, 0, sizeof (tl_info));
24317836SJohn.Forte@Sun.COM 	tl_info.tl_vers = ISCSI_INTERFACE_VERSION;
24327836SJohn.Forte@Sun.COM 	tl_info.tl_in_cnt = 0;
24337836SJohn.Forte@Sun.COM 	tl_info.tl_tgt_list_type = targetListType;
24347836SJohn.Forte@Sun.COM 
24357836SJohn.Forte@Sun.COM 	/*
24367836SJohn.Forte@Sun.COM 	 * Issue ioctl to obtain the number of targets.
24377836SJohn.Forte@Sun.COM 	 */
24387836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, &tl_info) != 0) {
24397836SJohn.Forte@Sun.COM 		(void) close(fd);
24407836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
24417836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
24427836SJohn.Forte@Sun.COM 		    targetListType, errno);
24437836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
24447836SJohn.Forte@Sun.COM 	}
24457836SJohn.Forte@Sun.COM 
24467836SJohn.Forte@Sun.COM 	target_list_size = sizeof (iscsi_target_list_t);
24477836SJohn.Forte@Sun.COM 	if (tl_info.tl_out_cnt > 1) {
24487836SJohn.Forte@Sun.COM 		target_list_size += (sizeof (uint32_t) *
24497836SJohn.Forte@Sun.COM 		    tl_info.tl_out_cnt - 1);
24507836SJohn.Forte@Sun.COM 	}
24517836SJohn.Forte@Sun.COM 
24527836SJohn.Forte@Sun.COM 	idlp = (iscsi_target_list_t *)calloc(1, target_list_size);
24537836SJohn.Forte@Sun.COM 	if (idlp == NULL) {
24547836SJohn.Forte@Sun.COM 		(void) close(fd);
24557836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
24567836SJohn.Forte@Sun.COM 	}
24577836SJohn.Forte@Sun.COM 
24587836SJohn.Forte@Sun.COM 	idlp->tl_vers = ISCSI_INTERFACE_VERSION;
24597836SJohn.Forte@Sun.COM 	idlp->tl_in_cnt = tl_info.tl_out_cnt;
24607836SJohn.Forte@Sun.COM 	idlp->tl_tgt_list_type = targetListType;
24617836SJohn.Forte@Sun.COM 
24627836SJohn.Forte@Sun.COM 	/* Issue the same ioctl again to obtain the OIDs. */
24637836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) {
24647836SJohn.Forte@Sun.COM 		free(idlp);
24657836SJohn.Forte@Sun.COM 		(void) close(fd);
24667836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
24677836SJohn.Forte@Sun.COM 		    "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d",
24687836SJohn.Forte@Sun.COM 		    targetListType, errno);
24697836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
24707836SJohn.Forte@Sun.COM 	}
24717836SJohn.Forte@Sun.COM 
24727836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) +
24737836SJohn.Forte@Sun.COM 	    idlp->tl_out_cnt * sizeof (IMA_OID));
24747836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
24757836SJohn.Forte@Sun.COM 		free(idlp);
24767836SJohn.Forte@Sun.COM 		(void) close(fd);
24777836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
24787836SJohn.Forte@Sun.COM 	}
24797836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = idlp->tl_out_cnt;
24807836SJohn.Forte@Sun.COM 
24817836SJohn.Forte@Sun.COM 	for (i = 0; i < idlp->tl_out_cnt; i++) {
24827836SJohn.Forte@Sun.COM 
24837836SJohn.Forte@Sun.COM 		if (targetListType == ISCSI_STATIC_TGT_OID_LIST)
24847836SJohn.Forte@Sun.COM 			(*ppList)->oids[i].objectType =
24857836SJohn.Forte@Sun.COM 			    IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET;
24867836SJohn.Forte@Sun.COM 		else
24877836SJohn.Forte@Sun.COM 			(*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_TARGET;
24887836SJohn.Forte@Sun.COM 
24897836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].ownerId = pluginOwnerId;
24907836SJohn.Forte@Sun.COM 		(*ppList)->oids[i].objectSequenceNumber = idlp->tl_oid_list[i];
24917836SJohn.Forte@Sun.COM 	}
24927836SJohn.Forte@Sun.COM 
24937836SJohn.Forte@Sun.COM 	free(idlp);
24947836SJohn.Forte@Sun.COM 	(void) close(fd);
24957836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
24967836SJohn.Forte@Sun.COM }
24977836SJohn.Forte@Sun.COM 
24987836SJohn.Forte@Sun.COM static IMA_STATUS get_target_lun_oid_list(
24997836SJohn.Forte@Sun.COM     IMA_OID * targetOid,
25007836SJohn.Forte@Sun.COM     iscsi_lun_list_t  **ppLunList)
25017836SJohn.Forte@Sun.COM {
25027836SJohn.Forte@Sun.COM 	int			fd;
25037836SJohn.Forte@Sun.COM 	iscsi_lun_list_t	*illp, ll_info;
25047836SJohn.Forte@Sun.COM 	int			lun_list_size;
25057836SJohn.Forte@Sun.COM 
25067836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
25077836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
25087836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
25097836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
25107836SJohn.Forte@Sun.COM 	}
25117836SJohn.Forte@Sun.COM 
25127836SJohn.Forte@Sun.COM 	(void) memset(&ll_info, 0, sizeof (ll_info));
25137836SJohn.Forte@Sun.COM 	ll_info.ll_vers = ISCSI_INTERFACE_VERSION;
25147836SJohn.Forte@Sun.COM 	if (targetOid == NULL) {
25157836SJohn.Forte@Sun.COM 		/* get lun oid list for all targets */
25167836SJohn.Forte@Sun.COM 		ll_info.ll_all_tgts = B_TRUE;
25177836SJohn.Forte@Sun.COM 	} else {
25187836SJohn.Forte@Sun.COM 		/* get lun oid list for single target */
25197836SJohn.Forte@Sun.COM 		ll_info.ll_all_tgts = B_FALSE;
25207836SJohn.Forte@Sun.COM 		ll_info.ll_tgt_oid = (uint32_t)targetOid->objectSequenceNumber;
25217836SJohn.Forte@Sun.COM 	}
25227836SJohn.Forte@Sun.COM 	ll_info.ll_in_cnt = 0;
25237836SJohn.Forte@Sun.COM 
25247836SJohn.Forte@Sun.COM 	/*
25257836SJohn.Forte@Sun.COM 	 * Issue ioctl to obtain the number of target LUNs.
25267836SJohn.Forte@Sun.COM 	 */
25277836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, &ll_info) != 0) {
25287836SJohn.Forte@Sun.COM 		(void) close(fd);
25297836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
25307836SJohn.Forte@Sun.COM 		    "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno);
25317836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
25327836SJohn.Forte@Sun.COM 	}
25337836SJohn.Forte@Sun.COM 
25347836SJohn.Forte@Sun.COM 	lun_list_size = sizeof (iscsi_lun_list_t);
25357836SJohn.Forte@Sun.COM 	if (ll_info.ll_out_cnt > 1) {
25367836SJohn.Forte@Sun.COM 		lun_list_size += (sizeof (iscsi_if_lun_t) *
25377836SJohn.Forte@Sun.COM 		    (ll_info.ll_out_cnt - 1));
25387836SJohn.Forte@Sun.COM 	}
25397836SJohn.Forte@Sun.COM 
25407836SJohn.Forte@Sun.COM 	illp = (iscsi_lun_list_t *)calloc(1, lun_list_size);
25417836SJohn.Forte@Sun.COM 	if (illp == NULL) {
25427836SJohn.Forte@Sun.COM 		(void) close(fd);
25437836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
25447836SJohn.Forte@Sun.COM 	}
25457836SJohn.Forte@Sun.COM 	illp->ll_vers = ISCSI_INTERFACE_VERSION;
25467836SJohn.Forte@Sun.COM 	illp->ll_all_tgts = ll_info.ll_all_tgts;
25477836SJohn.Forte@Sun.COM 	illp->ll_tgt_oid = ll_info.ll_tgt_oid;
25487836SJohn.Forte@Sun.COM 	illp->ll_in_cnt = ll_info.ll_out_cnt;
25497836SJohn.Forte@Sun.COM 
25507836SJohn.Forte@Sun.COM 	/* Issue the same ioctl again to get the target LUN list */
25517836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) {
25527836SJohn.Forte@Sun.COM 		free(illp);
25537836SJohn.Forte@Sun.COM 		(void) close(fd);
25547836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
25557836SJohn.Forte@Sun.COM 		    "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno);
25567836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
25577836SJohn.Forte@Sun.COM 	}
25587836SJohn.Forte@Sun.COM 
25597836SJohn.Forte@Sun.COM 	*ppLunList = illp;
25607836SJohn.Forte@Sun.COM 
25617836SJohn.Forte@Sun.COM 	(void) close(fd);
25627836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
25637836SJohn.Forte@Sun.COM }
25647836SJohn.Forte@Sun.COM 
25657836SJohn.Forte@Sun.COM 
25667836SJohn.Forte@Sun.COM /* A helper function to set authentication method. */
25677836SJohn.Forte@Sun.COM static IMA_STATUS
25687836SJohn.Forte@Sun.COM setAuthMethods(
25697836SJohn.Forte@Sun.COM     IMA_OID oid,
25707836SJohn.Forte@Sun.COM     IMA_UINT *pMethodCount,
25717836SJohn.Forte@Sun.COM     const IMA_AUTHMETHOD *pMethodList
25727836SJohn.Forte@Sun.COM )
25737836SJohn.Forte@Sun.COM {
25747836SJohn.Forte@Sun.COM 	int fd;
25757836SJohn.Forte@Sun.COM 	int i;
25767836SJohn.Forte@Sun.COM 	iscsi_auth_props_t auth;
25777836SJohn.Forte@Sun.COM 
25787836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
25797836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
25807836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
25817836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
25827836SJohn.Forte@Sun.COM 	}
25837836SJohn.Forte@Sun.COM 	(void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
25847836SJohn.Forte@Sun.COM 	auth.a_vers = ISCSI_INTERFACE_VERSION;
25857836SJohn.Forte@Sun.COM 	auth.a_oid = (uint32_t)oid.objectSequenceNumber;
25867836SJohn.Forte@Sun.COM 	/* First do a get because other data fields may exist */
25877836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
25887836SJohn.Forte@Sun.COM 		/* EMPTY */
25897836SJohn.Forte@Sun.COM 		/* It is fine if there is no other data fields. */
25907836SJohn.Forte@Sun.COM 	}
25917836SJohn.Forte@Sun.COM 	auth.a_auth_method = authMethodNone;
25927836SJohn.Forte@Sun.COM 
25937836SJohn.Forte@Sun.COM 	for (i = 0; i < *pMethodCount; i++) {
25947836SJohn.Forte@Sun.COM 		switch (pMethodList[i]) {
25957836SJohn.Forte@Sun.COM 			case IMA_AUTHMETHOD_CHAP:
25967836SJohn.Forte@Sun.COM 				auth.a_auth_method |= authMethodCHAP;
25977836SJohn.Forte@Sun.COM 				break;
25987836SJohn.Forte@Sun.COM 			default:
25997836SJohn.Forte@Sun.COM 				break;
26007836SJohn.Forte@Sun.COM 		}
26017836SJohn.Forte@Sun.COM 	}
26027836SJohn.Forte@Sun.COM 
26037836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) {
26047836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
26057836SJohn.Forte@Sun.COM 		    "ISCSI_AUTH_SET failed, errno: %d", errno);
26067836SJohn.Forte@Sun.COM 		(void) close(fd);
26077836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
26087836SJohn.Forte@Sun.COM 	}
26097836SJohn.Forte@Sun.COM 
26107836SJohn.Forte@Sun.COM 	(void) close(fd);
26117836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
26127836SJohn.Forte@Sun.COM }
26137836SJohn.Forte@Sun.COM 
26147836SJohn.Forte@Sun.COM /* A helper function to get authentication method. */
26157836SJohn.Forte@Sun.COM static IMA_STATUS
26167836SJohn.Forte@Sun.COM getAuthMethods(
26177836SJohn.Forte@Sun.COM     IMA_OID oid,
26187836SJohn.Forte@Sun.COM     IMA_UINT	*pMethodCount,
26197836SJohn.Forte@Sun.COM     IMA_AUTHMETHOD *pMethodList
26207836SJohn.Forte@Sun.COM )
26217836SJohn.Forte@Sun.COM {
26227836SJohn.Forte@Sun.COM 	int fd, i;
26237836SJohn.Forte@Sun.COM 	iscsi_auth_props_t auth;
26247836SJohn.Forte@Sun.COM 
26257836SJohn.Forte@Sun.COM 	if (pMethodList == NULL) {
26267836SJohn.Forte@Sun.COM 		*pMethodCount = 0;
26277836SJohn.Forte@Sun.COM 		return (IMA_STATUS_SUCCESS);
26287836SJohn.Forte@Sun.COM 	}
26297836SJohn.Forte@Sun.COM 
26307836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
26317836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
26327836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
26337836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
26347836SJohn.Forte@Sun.COM 	}
26357836SJohn.Forte@Sun.COM 
26367836SJohn.Forte@Sun.COM 	(void) memset(&auth, 0, sizeof (iscsi_auth_props_t));
26377836SJohn.Forte@Sun.COM 	auth.a_vers = ISCSI_INTERFACE_VERSION;
26387836SJohn.Forte@Sun.COM 	auth.a_oid = (uint32_t)oid.objectSequenceNumber;
26397836SJohn.Forte@Sun.COM 
26407836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) {
26417836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
26427836SJohn.Forte@Sun.COM 		    "ISCSI_AUTH_GET failed, errno: %d", errno);
26437836SJohn.Forte@Sun.COM 		(void) close(fd);
26447836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
26457836SJohn.Forte@Sun.COM 	}
26467836SJohn.Forte@Sun.COM 
26477836SJohn.Forte@Sun.COM 	i = 0;
26487836SJohn.Forte@Sun.COM 	if (auth.a_auth_method == IMA_AUTHMETHOD_NONE) {
26497836SJohn.Forte@Sun.COM 		pMethodList[i++] = IMA_AUTHMETHOD_NONE;
26507836SJohn.Forte@Sun.COM 	} else if (auth.a_auth_method & authMethodCHAP) {
26517836SJohn.Forte@Sun.COM 		pMethodList[i++] = IMA_AUTHMETHOD_CHAP;
26527836SJohn.Forte@Sun.COM 	}
26537836SJohn.Forte@Sun.COM 	*pMethodCount = i;
26547836SJohn.Forte@Sun.COM 
26557836SJohn.Forte@Sun.COM 	(void) close(fd);
26567836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
26577836SJohn.Forte@Sun.COM }
26587836SJohn.Forte@Sun.COM 
26597836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPhbaOidList(
26607836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
26617836SJohn.Forte@Sun.COM )
26627836SJohn.Forte@Sun.COM {
26637836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST));
26647836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
26657836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
26667836SJohn.Forte@Sun.COM 	}
26677836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = 0;
26687836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
26697836SJohn.Forte@Sun.COM }
26707836SJohn.Forte@Sun.COM 
26717836SJohn.Forte@Sun.COM /* ARGSUSED */
26727836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPhbaProperties(
26737836SJohn.Forte@Sun.COM 		IMA_OID phbaOid,
26747836SJohn.Forte@Sun.COM 		IMA_PHBA_PROPERTIES *pProps
26757836SJohn.Forte@Sun.COM )
26767836SJohn.Forte@Sun.COM {
26777836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
26787836SJohn.Forte@Sun.COM }
26797836SJohn.Forte@Sun.COM 
26807836SJohn.Forte@Sun.COM /* ARGSUSED */
26817836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPhbaStatus(
26827836SJohn.Forte@Sun.COM 		IMA_OID phbaOid,
26837836SJohn.Forte@Sun.COM 		IMA_PHBA_STATUS *pStatus
26847836SJohn.Forte@Sun.COM )
26857836SJohn.Forte@Sun.COM {
26867836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
26877836SJohn.Forte@Sun.COM }
26887836SJohn.Forte@Sun.COM 
26897836SJohn.Forte@Sun.COM /* ARGSUSED */
26907836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPhbaDownloadProperties(
26917836SJohn.Forte@Sun.COM 		IMA_OID phbaOid,
26927836SJohn.Forte@Sun.COM 		IMA_PHBA_DOWNLOAD_PROPERTIES *pProps
26937836SJohn.Forte@Sun.COM )
26947836SJohn.Forte@Sun.COM {
26957836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
26967836SJohn.Forte@Sun.COM }
26977836SJohn.Forte@Sun.COM 
26987836SJohn.Forte@Sun.COM /* ARGSUSED */
26997836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_IsPhbaDownloadFile(
27007836SJohn.Forte@Sun.COM 		IMA_OID phbaOid,
27017836SJohn.Forte@Sun.COM 		const IMA_WCHAR *pFileName,
27027836SJohn.Forte@Sun.COM 		IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES *pProps
27037836SJohn.Forte@Sun.COM )
27047836SJohn.Forte@Sun.COM {
27057836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27067836SJohn.Forte@Sun.COM }
27077836SJohn.Forte@Sun.COM 
27087836SJohn.Forte@Sun.COM /* ARGSUSED */
27097836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_PhbaDownload(
27107836SJohn.Forte@Sun.COM 		IMA_OID phbaOid,
27117836SJohn.Forte@Sun.COM 		IMA_PHBA_DOWNLOAD_IMAGE_TYPE imageType,
27127836SJohn.Forte@Sun.COM 		const IMA_WCHAR *pFileName
27137836SJohn.Forte@Sun.COM )
27147836SJohn.Forte@Sun.COM {
27157836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27167836SJohn.Forte@Sun.COM }
27177836SJohn.Forte@Sun.COM 
27187836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPnpOidList(
27197836SJohn.Forte@Sun.COM 		IMA_OID pnpOid,
27207836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
27217836SJohn.Forte@Sun.COM )
27227836SJohn.Forte@Sun.COM {
27237836SJohn.Forte@Sun.COM 	/*
27247836SJohn.Forte@Sun.COM 	 * Always return the same object ID for the pnp as the spec
27257836SJohn.Forte@Sun.COM 	 * states that this function will always return a list of at least
27267836SJohn.Forte@Sun.COM 	 * one element
27277836SJohn.Forte@Sun.COM 	 */
27287836SJohn.Forte@Sun.COM 	pnpOid.objectType = IMA_OBJECT_TYPE_PNP;
27297836SJohn.Forte@Sun.COM 	pnpOid.ownerId = pluginOwnerId;
27307836SJohn.Forte@Sun.COM 	pnpOid.objectSequenceNumber = ISCSI_INITIATOR_OID;
27317836SJohn.Forte@Sun.COM 
27327836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) +
27337836SJohn.Forte@Sun.COM 	    (1* sizeof (IMA_OID)));
27347836SJohn.Forte@Sun.COM 
27357836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
27367836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
27377836SJohn.Forte@Sun.COM 	}
27387836SJohn.Forte@Sun.COM 
27397836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = 1;
27407836SJohn.Forte@Sun.COM 	(void) memcpy(&(*ppList)->oids[0], &pnpOid, sizeof (pnpOid));
27417836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
27427836SJohn.Forte@Sun.COM }
27437836SJohn.Forte@Sun.COM 
27447836SJohn.Forte@Sun.COM /* ARGSUSED */
27457836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPnpProperties(
27467836SJohn.Forte@Sun.COM 		IMA_OID pnpOid,
27477836SJohn.Forte@Sun.COM 		IMA_PNP_PROPERTIES *pProps
27487836SJohn.Forte@Sun.COM )
27497836SJohn.Forte@Sun.COM {
27507836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27517836SJohn.Forte@Sun.COM }
27527836SJohn.Forte@Sun.COM 
27537836SJohn.Forte@Sun.COM /* ARGSUSED */
27547836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPnpStatistics(
27557836SJohn.Forte@Sun.COM 		IMA_OID pnpOid,
27567836SJohn.Forte@Sun.COM 		IMA_PNP_STATISTICS *pStats
27577836SJohn.Forte@Sun.COM )
27587836SJohn.Forte@Sun.COM {
27597836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27607836SJohn.Forte@Sun.COM }
27617836SJohn.Forte@Sun.COM 
27627836SJohn.Forte@Sun.COM /* ARGSUSED */
27637836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetIpProperties(
27647836SJohn.Forte@Sun.COM 		IMA_OID oid,
27657836SJohn.Forte@Sun.COM 		IMA_IP_PROPERTIES *pProps
27667836SJohn.Forte@Sun.COM )
27677836SJohn.Forte@Sun.COM {
27687836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27697836SJohn.Forte@Sun.COM }
27707836SJohn.Forte@Sun.COM 
27717836SJohn.Forte@Sun.COM /* ARGSUSED */
27727836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetDefaultGateway(
27737836SJohn.Forte@Sun.COM 		IMA_OID oid,
27747836SJohn.Forte@Sun.COM 		IMA_IP_ADDRESS defaultGateway
27757836SJohn.Forte@Sun.COM )
27767836SJohn.Forte@Sun.COM {
27777836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27787836SJohn.Forte@Sun.COM }
27797836SJohn.Forte@Sun.COM 
27807836SJohn.Forte@Sun.COM /* ARGSUSED */
27817836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetDnsServerAddress(
27827836SJohn.Forte@Sun.COM 		IMA_OID oid,
27837836SJohn.Forte@Sun.COM 		const IMA_IP_ADDRESS *pPrimaryDnsServerAddress,
27847836SJohn.Forte@Sun.COM 		const IMA_IP_ADDRESS *pAlternateDnsServerAddress
27857836SJohn.Forte@Sun.COM )
27867836SJohn.Forte@Sun.COM {
27877836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27887836SJohn.Forte@Sun.COM }
27897836SJohn.Forte@Sun.COM 
27907836SJohn.Forte@Sun.COM /* ARGSUSED */
27917836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetSubnetMask(
27927836SJohn.Forte@Sun.COM 		IMA_OID oid,
27937836SJohn.Forte@Sun.COM 		IMA_IP_ADDRESS subnetMask
27947836SJohn.Forte@Sun.COM )
27957836SJohn.Forte@Sun.COM {
27967836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
27977836SJohn.Forte@Sun.COM }
27987836SJohn.Forte@Sun.COM 
27997836SJohn.Forte@Sun.COM /* ARGSUSED */
28007836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetIpConfigMethod(
28017836SJohn.Forte@Sun.COM 		IMA_OID oid,
28027836SJohn.Forte@Sun.COM 		IMA_BOOL enableDhcpIpConfiguration
28037836SJohn.Forte@Sun.COM )
28047836SJohn.Forte@Sun.COM {
28057836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
28067836SJohn.Forte@Sun.COM }
28077836SJohn.Forte@Sun.COM 
28087836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_RegisterForObjectPropertyChanges(
28097836SJohn.Forte@Sun.COM 		IMA_OBJECT_PROPERTY_FN pClientFn
28107836SJohn.Forte@Sun.COM )
28117836SJohn.Forte@Sun.COM {
28127836SJohn.Forte@Sun.COM 	pObjectPropertyCallback = pClientFn;
28137836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
28147836SJohn.Forte@Sun.COM }
28157836SJohn.Forte@Sun.COM 
28167836SJohn.Forte@Sun.COM /* ARGSUSED */
28177836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_DeregisterForObjectPropertyChanges(
28187836SJohn.Forte@Sun.COM 		IMA_OBJECT_PROPERTY_FN pClientFn
28197836SJohn.Forte@Sun.COM )
28207836SJohn.Forte@Sun.COM {
28217836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
28227836SJohn.Forte@Sun.COM }
28237836SJohn.Forte@Sun.COM 
28247836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_RegisterForObjectVisibilityChanges(
28257836SJohn.Forte@Sun.COM 		IMA_OBJECT_VISIBILITY_FN pClientFn
28267836SJohn.Forte@Sun.COM )
28277836SJohn.Forte@Sun.COM {
28287836SJohn.Forte@Sun.COM 	pObjectVisibilityCallback = pClientFn;
28297836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
28307836SJohn.Forte@Sun.COM }
28317836SJohn.Forte@Sun.COM 
28327836SJohn.Forte@Sun.COM /* ARGSUSED */
28337836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_DeregisterForObjectVisibilityChanges(
28347836SJohn.Forte@Sun.COM 		IMA_OBJECT_VISIBILITY_FN pClientFn
28357836SJohn.Forte@Sun.COM )
28367836SJohn.Forte@Sun.COM {
28377836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
28387836SJohn.Forte@Sun.COM }
28397836SJohn.Forte@Sun.COM 
28407836SJohn.Forte@Sun.COM /* ARGSUSED */
28417836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetNetworkPortStatus(
28427836SJohn.Forte@Sun.COM 		IMA_OID portOid,
28437836SJohn.Forte@Sun.COM 		IMA_NETWORK_PORT_STATUS *pStaus
28447836SJohn.Forte@Sun.COM )
28457836SJohn.Forte@Sun.COM {
28467836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
28477836SJohn.Forte@Sun.COM }
28487836SJohn.Forte@Sun.COM 
28497836SJohn.Forte@Sun.COM /* ARGSUSED */
28507836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetNetworkPortalOidList(
28517836SJohn.Forte@Sun.COM 		IMA_OID pnpOid,
28527836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
28537836SJohn.Forte@Sun.COM )
28547836SJohn.Forte@Sun.COM {
28557836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
28567836SJohn.Forte@Sun.COM }
28577836SJohn.Forte@Sun.COM 
28587836SJohn.Forte@Sun.COM /* ARGSUSED */
28597836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetNetworkPortalProperties(
28607836SJohn.Forte@Sun.COM 		IMA_OID networkPortalOid,
28617836SJohn.Forte@Sun.COM 		IMA_NETWORK_PORTAL_PROPERTIES *pProps
28627836SJohn.Forte@Sun.COM )
28637836SJohn.Forte@Sun.COM {
28647836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
28657836SJohn.Forte@Sun.COM }
28667836SJohn.Forte@Sun.COM 
28677836SJohn.Forte@Sun.COM /* ARGSUSED */
28687836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_SetNetworkPortalIpAddress(
28697836SJohn.Forte@Sun.COM 		IMA_OID networkPortalOid,
28707836SJohn.Forte@Sun.COM 		const IMA_IP_ADDRESS NewIpAddress
28717836SJohn.Forte@Sun.COM )
28727836SJohn.Forte@Sun.COM {
28737836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
28747836SJohn.Forte@Sun.COM }
28757836SJohn.Forte@Sun.COM 
28767836SJohn.Forte@Sun.COM /* ARGSUSED */
28777836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_RemoveStaleData(
28787836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid
28797836SJohn.Forte@Sun.COM )
28807836SJohn.Forte@Sun.COM {
28817836SJohn.Forte@Sun.COM 	return (IMA_ERROR_NOT_SUPPORTED);
28827836SJohn.Forte@Sun.COM }
28837836SJohn.Forte@Sun.COM 
28847836SJohn.Forte@Sun.COM /* ARGSUSED */
28857836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetIpsecProperties(
28867836SJohn.Forte@Sun.COM 		IMA_OID oid,
28877836SJohn.Forte@Sun.COM 		IMA_IPSEC_PROPERTIES *pProps
28887836SJohn.Forte@Sun.COM )
28897836SJohn.Forte@Sun.COM {
28907836SJohn.Forte@Sun.COM 	pProps->ipsecSupported = IMA_TRUE;
28917836SJohn.Forte@Sun.COM 	pProps->implementedInHardware = IMA_FALSE;
28927836SJohn.Forte@Sun.COM 	pProps->implementedInSoftware = IMA_TRUE;
28937836SJohn.Forte@Sun.COM 
28947836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
28957836SJohn.Forte@Sun.COM }
28967836SJohn.Forte@Sun.COM 
28977836SJohn.Forte@Sun.COM /* ARGSUSED */
28987836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetLhbaProperties(
28997836SJohn.Forte@Sun.COM 		IMA_OID lhbaOid,
29007836SJohn.Forte@Sun.COM 		IMA_LHBA_PROPERTIES *pProps
29017836SJohn.Forte@Sun.COM )
29027836SJohn.Forte@Sun.COM {
29037836SJohn.Forte@Sun.COM 
29047836SJohn.Forte@Sun.COM 	if (pProps == NULL) {
29057836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INVALID_PARAMETER);
29067836SJohn.Forte@Sun.COM 	}
29077836SJohn.Forte@Sun.COM 
29087836SJohn.Forte@Sun.COM 	if (lhbaObjectId.objectSequenceNumber != ISCSI_INITIATOR_OID) {
29097836SJohn.Forte@Sun.COM 		return (IMA_ERROR_OBJECT_NOT_FOUND);
29107836SJohn.Forte@Sun.COM 	}
29117836SJohn.Forte@Sun.COM 
29127836SJohn.Forte@Sun.COM 	(void) memset(pProps, 0, sizeof (IMA_LHBA_PROPERTIES));
29137836SJohn.Forte@Sun.COM 	(void) mbstowcs(pProps->osDeviceName, OS_DEVICE_NAME,
29147836SJohn.Forte@Sun.COM 	    OS_DEVICE_NAME_LEN);
29157836SJohn.Forte@Sun.COM 	pProps->luExposingSupported = IMA_FALSE;
29167836SJohn.Forte@Sun.COM 	pProps->isDestroyable = IMA_FALSE;
29177836SJohn.Forte@Sun.COM 	pProps->staleDataRemovable = IMA_FALSE;
29187836SJohn.Forte@Sun.COM 	pProps->staleDataSize = 0;
29197836SJohn.Forte@Sun.COM 	pProps->initiatorAuthMethodsSettable = IMA_TRUE;
29207836SJohn.Forte@Sun.COM 	pProps->targetAuthMethodsSettable = IMA_FALSE;
29217836SJohn.Forte@Sun.COM 
29227836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
29237836SJohn.Forte@Sun.COM }
29247836SJohn.Forte@Sun.COM 
29257836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetLnpOidList(
29267836SJohn.Forte@Sun.COM 		IMA_OID_LIST **ppList
29277836SJohn.Forte@Sun.COM )
29287836SJohn.Forte@Sun.COM {
29297836SJohn.Forte@Sun.COM 	*ppList = (IMA_OID_LIST *) calloc(1, (sizeof (IMA_OID_LIST)));
29307836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
29317836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
29327836SJohn.Forte@Sun.COM 	}
29337836SJohn.Forte@Sun.COM 	(*ppList)->oidCount = 0;
29347836SJohn.Forte@Sun.COM 
29357836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
29367836SJohn.Forte@Sun.COM }
29377836SJohn.Forte@Sun.COM 
29387836SJohn.Forte@Sun.COM /* ARGSUSED */
29397836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetLnpProperties(
29407836SJohn.Forte@Sun.COM 		IMA_OID lnpOid,
29417836SJohn.Forte@Sun.COM 		IMA_LNP_PROPERTIES *pProps
29427836SJohn.Forte@Sun.COM )
29437836SJohn.Forte@Sun.COM {
29447836SJohn.Forte@Sun.COM 	return (IMA_ERROR_OBJECT_NOT_FOUND);
29457836SJohn.Forte@Sun.COM }
29467836SJohn.Forte@Sun.COM 
29477836SJohn.Forte@Sun.COM #define	IMA_DISK_DEVICE_NAME_PREFIX	"/dev/rdsk/"
29487836SJohn.Forte@Sun.COM #define	IMA_TAPE_DEVICE_NAME_PREFIX	"/dev/rmt/"
29497836SJohn.Forte@Sun.COM static int
29507836SJohn.Forte@Sun.COM get_lun_devlink(di_devlink_t link, void *osDeviceName)
29517836SJohn.Forte@Sun.COM {
29527836SJohn.Forte@Sun.COM 	if ((strncmp(IMA_DISK_DEVICE_NAME_PREFIX, di_devlink_path(link),
29537836SJohn.Forte@Sun.COM 	    strlen(IMA_DISK_DEVICE_NAME_PREFIX)) == 0) ||
29547836SJohn.Forte@Sun.COM 	    (strncmp(IMA_TAPE_DEVICE_NAME_PREFIX, di_devlink_path(link),
29557836SJohn.Forte@Sun.COM 	    strlen(IMA_TAPE_DEVICE_NAME_PREFIX)) == 0)) {
29567836SJohn.Forte@Sun.COM 		(void) mbstowcs((wchar_t *)osDeviceName, di_devlink_path(link),
29577836SJohn.Forte@Sun.COM 		    MAXPATHLEN);
29587836SJohn.Forte@Sun.COM 		return (DI_WALK_TERMINATE);
29597836SJohn.Forte@Sun.COM 	}
29607836SJohn.Forte@Sun.COM 
29617836SJohn.Forte@Sun.COM 	return (DI_WALK_CONTINUE);
29627836SJohn.Forte@Sun.COM }
29637836SJohn.Forte@Sun.COM 
29647836SJohn.Forte@Sun.COM /* ARGSUSED */
29657836SJohn.Forte@Sun.COM IMA_API IMA_STATUS IMA_GetPluginProperties(
29667836SJohn.Forte@Sun.COM 	IMA_OID pluginOid,
29677836SJohn.Forte@Sun.COM 	IMA_PLUGIN_PROPERTIES *pProps
29687836SJohn.Forte@Sun.COM )
29697836SJohn.Forte@Sun.COM {
29707836SJohn.Forte@Sun.COM 	pProps->supportedImaVersion = 1;
29717836SJohn.Forte@Sun.COM 	libSwprintf(pProps->vendor, L"%ls", LIBRARY_PROPERTY_VENDOR);
29727836SJohn.Forte@Sun.COM 	libSwprintf(pProps->implementationVersion, L"%ls",
29737836SJohn.Forte@Sun.COM 	    LIBRARY_PROPERTY_IMPLEMENTATION_VERSION);
29747836SJohn.Forte@Sun.COM 	libSwprintf(pProps->fileName, L"%ls", LIBRARY_FILE_NAME);
29757836SJohn.Forte@Sun.COM 	GetBuildTime(&(pProps->buildTime));
29767836SJohn.Forte@Sun.COM 	pProps->lhbasCanBeCreatedAndDestroyed = IMA_FALSE;
29777836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
29787836SJohn.Forte@Sun.COM }
29797836SJohn.Forte@Sun.COM 
29807836SJohn.Forte@Sun.COM IMA_STATUS getDiscoveryAddressPropertiesList(
29817836SJohn.Forte@Sun.COM     SUN_IMA_DISC_ADDR_PROP_LIST **ppList
29827836SJohn.Forte@Sun.COM )
29837836SJohn.Forte@Sun.COM {
29847836SJohn.Forte@Sun.COM 	int		    fd;
29857836SJohn.Forte@Sun.COM 	int		    i;
29867836SJohn.Forte@Sun.COM 	int		    discovery_addr_list_size;
29877836SJohn.Forte@Sun.COM 	iscsi_addr_list_t   *ialp, al_info;
29887836SJohn.Forte@Sun.COM 
29897836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
29907836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
29917836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
29927836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
29937836SJohn.Forte@Sun.COM 	}
29947836SJohn.Forte@Sun.COM 
29957836SJohn.Forte@Sun.COM 	(void) memset(&al_info, 0, sizeof (al_info));
29967836SJohn.Forte@Sun.COM 	al_info.al_vers = ISCSI_INTERFACE_VERSION;
29977836SJohn.Forte@Sun.COM 	al_info.al_in_cnt = 0;
29987836SJohn.Forte@Sun.COM 
29997836SJohn.Forte@Sun.COM 	/*
30007836SJohn.Forte@Sun.COM 	 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl to obtain the number of
30017836SJohn.Forte@Sun.COM 	 * discovery addresses.
30027836SJohn.Forte@Sun.COM 	 */
30037836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) {
30047836SJohn.Forte@Sun.COM 		(void) close(fd);
30057836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
30067836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
30077836SJohn.Forte@Sun.COM 		    errno);
30087836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
30097836SJohn.Forte@Sun.COM 	}
30107836SJohn.Forte@Sun.COM 
30117836SJohn.Forte@Sun.COM 	discovery_addr_list_size = sizeof (iscsi_addr_list_t);
30127836SJohn.Forte@Sun.COM 	if (al_info.al_out_cnt > 1) {
30137836SJohn.Forte@Sun.COM 		discovery_addr_list_size += (sizeof (iscsi_addr_t) *
30147836SJohn.Forte@Sun.COM 		    al_info.al_out_cnt - 1);
30157836SJohn.Forte@Sun.COM 	}
30167836SJohn.Forte@Sun.COM 
30177836SJohn.Forte@Sun.COM 	ialp = (iscsi_addr_list_t *)calloc(1, discovery_addr_list_size);
30187836SJohn.Forte@Sun.COM 	if (ialp == NULL) {
30197836SJohn.Forte@Sun.COM 		(void) close(fd);
30207836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
30217836SJohn.Forte@Sun.COM 	}
30227836SJohn.Forte@Sun.COM 	ialp->al_vers = ISCSI_INTERFACE_VERSION;
30237836SJohn.Forte@Sun.COM 	ialp->al_in_cnt = al_info.al_out_cnt;
30247836SJohn.Forte@Sun.COM 
30257836SJohn.Forte@Sun.COM 	/*
30267836SJohn.Forte@Sun.COM 	 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain the
30277836SJohn.Forte@Sun.COM 	 * discovery addresses.
30287836SJohn.Forte@Sun.COM 	 */
30297836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) {
30307836SJohn.Forte@Sun.COM 		free(ialp);
30317836SJohn.Forte@Sun.COM 		(void) close(fd);
30327836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
30337836SJohn.Forte@Sun.COM 		    "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d",
30347836SJohn.Forte@Sun.COM 		    errno);
30357836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
30367836SJohn.Forte@Sun.COM 	}
30377836SJohn.Forte@Sun.COM 
30387836SJohn.Forte@Sun.COM 	*ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *)
30397836SJohn.Forte@Sun.COM 	    calloc(1, sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) +
30407836SJohn.Forte@Sun.COM 	    ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES));
30417836SJohn.Forte@Sun.COM 
30427836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
30437836SJohn.Forte@Sun.COM 		free(ialp);
30447836SJohn.Forte@Sun.COM 		(void) close(fd);
30457836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
30467836SJohn.Forte@Sun.COM 	}
30477836SJohn.Forte@Sun.COM 	(*ppList)->discAddrCount = ialp->al_out_cnt;
30487836SJohn.Forte@Sun.COM 
30497836SJohn.Forte@Sun.COM 	for (i = 0; i < ialp->al_out_cnt; i++) {
30507836SJohn.Forte@Sun.COM 		if (ialp->al_addrs[i].a_addr.i_insize ==
30517836SJohn.Forte@Sun.COM 		    sizeof (struct in_addr)) {
30527836SJohn.Forte@Sun.COM 			(*ppList)->props[i].discoveryAddress.hostnameIpAddress.
30537836SJohn.Forte@Sun.COM 			id.ipAddress.ipv4Address = IMA_TRUE;
30547836SJohn.Forte@Sun.COM 		} else if (ialp->al_addrs[i].a_addr.i_insize ==
30557836SJohn.Forte@Sun.COM 		    sizeof (struct in6_addr)) {
30567836SJohn.Forte@Sun.COM 			(*ppList)->props[i].discoveryAddress.
30577836SJohn.Forte@Sun.COM 			hostnameIpAddress.id.ipAddress.ipv4Address = IMA_FALSE;
30587836SJohn.Forte@Sun.COM 		} else {
30597836SJohn.Forte@Sun.COM 			/* Should not happen */
30607836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
30617836SJohn.Forte@Sun.COM 			"ISCSI_STATIC_GET returned bad address");
30627836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
30637836SJohn.Forte@Sun.COM 		}
30647836SJohn.Forte@Sun.COM 
30657836SJohn.Forte@Sun.COM 		bcopy(&ialp->al_addrs[i].a_addr.i_addr,	(*ppList)->props[i].
30667836SJohn.Forte@Sun.COM 		    discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress,
30677836SJohn.Forte@Sun.COM 		    sizeof ((*ppList)->props[i].discoveryAddress.
30687836SJohn.Forte@Sun.COM 		    hostnameIpAddress.id.ipAddress.ipAddress));
30697836SJohn.Forte@Sun.COM 
30707836SJohn.Forte@Sun.COM 		(*ppList)->props[i].discoveryAddress.portNumber =
30717836SJohn.Forte@Sun.COM 		    ialp->al_addrs[i].a_port;
30727836SJohn.Forte@Sun.COM 	}
30737836SJohn.Forte@Sun.COM 
30747836SJohn.Forte@Sun.COM 	free(ialp);
30757836SJohn.Forte@Sun.COM 	(void) close(fd);
30767836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
30777836SJohn.Forte@Sun.COM }
30787836SJohn.Forte@Sun.COM 
30797836SJohn.Forte@Sun.COM 
30807836SJohn.Forte@Sun.COM /* ARGSUSED */
30817836SJohn.Forte@Sun.COM IMA_STATUS sendTargets(
30827836SJohn.Forte@Sun.COM     IMA_TARGET_ADDRESS address,
30837836SJohn.Forte@Sun.COM     SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList
30847836SJohn.Forte@Sun.COM )
30857836SJohn.Forte@Sun.COM {
30867836SJohn.Forte@Sun.COM 	char	*colonPos;
30877836SJohn.Forte@Sun.COM 	char	discAddrStr[SUN_IMA_IP_ADDRESS_LEN];
30887836SJohn.Forte@Sun.COM 	int	fd;
30897836SJohn.Forte@Sun.COM 	int	ctr;
30907836SJohn.Forte@Sun.COM 	int	stl_sz;
30917836SJohn.Forte@Sun.COM 	iscsi_sendtgts_list_t	*stl_hdr = NULL;
30927836SJohn.Forte@Sun.COM 	IMA_BOOL		retry = IMA_TRUE;
30937836SJohn.Forte@Sun.COM 
30947836SJohn.Forte@Sun.COM #define	SENDTGTS_DEFAULT_NUM_TARGETS	10
30957836SJohn.Forte@Sun.COM 
30967836SJohn.Forte@Sun.COM 	stl_sz = sizeof (*stl_hdr) + ((SENDTGTS_DEFAULT_NUM_TARGETS - 1) *
30977836SJohn.Forte@Sun.COM 	    sizeof (iscsi_sendtgts_entry_t));
30987836SJohn.Forte@Sun.COM 	stl_hdr = (iscsi_sendtgts_list_t *)calloc(1, stl_sz);
30997836SJohn.Forte@Sun.COM 	if (stl_hdr == NULL) {
31007836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
31017836SJohn.Forte@Sun.COM 	}
31027836SJohn.Forte@Sun.COM 	stl_hdr->stl_entry.e_vers = ISCSI_INTERFACE_VERSION;
31037836SJohn.Forte@Sun.COM 	stl_hdr->stl_in_cnt = SENDTGTS_DEFAULT_NUM_TARGETS;
31047836SJohn.Forte@Sun.COM 
31057836SJohn.Forte@Sun.COM 	colonPos = strchr(discAddrStr, ':');
31067836SJohn.Forte@Sun.COM 	if (colonPos == NULL) {
31077836SJohn.Forte@Sun.COM 		/* IPv4 */
31087836SJohn.Forte@Sun.COM 		stl_hdr->stl_entry.e_insize = sizeof (struct in_addr);
31097836SJohn.Forte@Sun.COM 	} else {
31107836SJohn.Forte@Sun.COM 		/* IPv6 */
31117836SJohn.Forte@Sun.COM 		stl_hdr->stl_entry.e_insize = sizeof (struct in6_addr);
31127836SJohn.Forte@Sun.COM 	}
31137836SJohn.Forte@Sun.COM 
31147836SJohn.Forte@Sun.COM 
31157836SJohn.Forte@Sun.COM 	bcopy(address.hostnameIpAddress.id.ipAddress.ipAddress,
31167836SJohn.Forte@Sun.COM 	    &stl_hdr->stl_entry.e_u,
31177836SJohn.Forte@Sun.COM 	    sizeof (address.hostnameIpAddress.id.ipAddress.ipAddress));
31187836SJohn.Forte@Sun.COM 	stl_hdr->stl_entry.e_port = address.portNumber;
31197836SJohn.Forte@Sun.COM 
31207836SJohn.Forte@Sun.COM 	if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) {
31217836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)",
31227836SJohn.Forte@Sun.COM 		    ISCSI_DRIVER_DEVCTL, errno);
31237836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
31247836SJohn.Forte@Sun.COM 	}
31257836SJohn.Forte@Sun.COM 
31267836SJohn.Forte@Sun.COM retry_sendtgts:
31277836SJohn.Forte@Sun.COM 	/*
31287836SJohn.Forte@Sun.COM 	 * Issue ioctl to obtain the SendTargets list
31297836SJohn.Forte@Sun.COM 	 */
31307836SJohn.Forte@Sun.COM 	if (ioctl(fd, ISCSI_SENDTGTS_GET, stl_hdr) != 0) {
31317836SJohn.Forte@Sun.COM 		syslog(LOG_USER|LOG_DEBUG,
31327836SJohn.Forte@Sun.COM 		    "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno);
31337836SJohn.Forte@Sun.COM 		(void) close(fd);
31347836SJohn.Forte@Sun.COM 		free(stl_hdr);
31357836SJohn.Forte@Sun.COM 		return (IMA_ERROR_UNEXPECTED_OS_ERROR);
31367836SJohn.Forte@Sun.COM 	}
31377836SJohn.Forte@Sun.COM 
31387836SJohn.Forte@Sun.COM 	/* check if all targets received */
31397836SJohn.Forte@Sun.COM 	if (stl_hdr->stl_in_cnt < stl_hdr->stl_out_cnt) {
31407836SJohn.Forte@Sun.COM 		if (retry == IMA_TRUE) {
31417836SJohn.Forte@Sun.COM 			stl_sz = sizeof (*stl_hdr) +
31427836SJohn.Forte@Sun.COM 			    ((stl_hdr->stl_out_cnt - 1) *
31437836SJohn.Forte@Sun.COM 			    sizeof (iscsi_sendtgts_entry_t));
31447836SJohn.Forte@Sun.COM 			stl_hdr = (iscsi_sendtgts_list_t *)
31457836SJohn.Forte@Sun.COM 			    realloc(stl_hdr, stl_sz);
31467836SJohn.Forte@Sun.COM 			if (stl_hdr == NULL) {
31477836SJohn.Forte@Sun.COM 				(void) close(fd);
31487836SJohn.Forte@Sun.COM 				return (IMA_ERROR_INSUFFICIENT_MEMORY);
31497836SJohn.Forte@Sun.COM 			}
31507836SJohn.Forte@Sun.COM 			stl_hdr->stl_in_cnt = stl_hdr->stl_out_cnt;
31517836SJohn.Forte@Sun.COM 			retry = IMA_FALSE;
31527836SJohn.Forte@Sun.COM 			goto retry_sendtgts;
31537836SJohn.Forte@Sun.COM 		} else {
31547836SJohn.Forte@Sun.COM 			/*
31557836SJohn.Forte@Sun.COM 			 * don't retry after 2 attempts.  The target list
31567836SJohn.Forte@Sun.COM 			 * shouldn't continue to growing. Justs continue
31577836SJohn.Forte@Sun.COM 			 * on and display what was found.
31587836SJohn.Forte@Sun.COM 			 */
31597836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
31607836SJohn.Forte@Sun.COM 			    "ISCSI_SENDTGTS_GET overflow: "
31617836SJohn.Forte@Sun.COM 			    "failed to obtain all targets");
31627836SJohn.Forte@Sun.COM 			stl_hdr->stl_out_cnt = stl_hdr->stl_in_cnt;
31637836SJohn.Forte@Sun.COM 		}
31647836SJohn.Forte@Sun.COM 	}
31657836SJohn.Forte@Sun.COM 
31667836SJohn.Forte@Sun.COM 	(void) close(fd);
31677836SJohn.Forte@Sun.COM 
31687836SJohn.Forte@Sun.COM 	/* allocate for caller return buffer */
31697836SJohn.Forte@Sun.COM 	*ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1,
31707836SJohn.Forte@Sun.COM 	    sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) +
31717836SJohn.Forte@Sun.COM 	    stl_hdr->stl_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY));
31727836SJohn.Forte@Sun.COM 	if (*ppList == NULL) {
31737836SJohn.Forte@Sun.COM 		free(stl_hdr);
31747836SJohn.Forte@Sun.COM 		return (IMA_ERROR_INSUFFICIENT_MEMORY);
31757836SJohn.Forte@Sun.COM 	}
31767836SJohn.Forte@Sun.COM 
31777836SJohn.Forte@Sun.COM 	(*ppList)->keyCount = stl_hdr->stl_out_cnt;
31787836SJohn.Forte@Sun.COM 
31797836SJohn.Forte@Sun.COM 	for (ctr = 0; ctr < stl_hdr->stl_out_cnt; ctr++) {
31807836SJohn.Forte@Sun.COM 		(void) mbstowcs((*ppList)->keys[ctr].name,
31817836SJohn.Forte@Sun.COM 		    (char *)stl_hdr->stl_list[ctr].ste_name,
31827836SJohn.Forte@Sun.COM 		    IMA_NODE_NAME_LEN);
31837836SJohn.Forte@Sun.COM 
31847836SJohn.Forte@Sun.COM 		(*ppList)->keys[ctr].tpgt = stl_hdr->stl_list[ctr].ste_tpgt;
31857836SJohn.Forte@Sun.COM 
31867836SJohn.Forte@Sun.COM 		(*ppList)->keys[ctr].address.portNumber =
31877836SJohn.Forte@Sun.COM 		    stl_hdr->stl_list[ctr].ste_ipaddr.a_port;
31887836SJohn.Forte@Sun.COM 
31897836SJohn.Forte@Sun.COM 		if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize ==
31907836SJohn.Forte@Sun.COM 		    sizeof (struct in_addr)) {
31917836SJohn.Forte@Sun.COM 			(*ppList)->keys[ctr].address.ipAddress.ipv4Address =
31927836SJohn.Forte@Sun.COM 			    IMA_TRUE;
31937836SJohn.Forte@Sun.COM 		} else if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize ==
31947836SJohn.Forte@Sun.COM 		    sizeof (struct in6_addr)) {
31957836SJohn.Forte@Sun.COM 			(*ppList)->keys[ctr].address.ipAddress.ipv4Address =
31967836SJohn.Forte@Sun.COM 			    IMA_FALSE;
31977836SJohn.Forte@Sun.COM 		} else {
31987836SJohn.Forte@Sun.COM 			free(stl_hdr);
31997836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
32007836SJohn.Forte@Sun.COM 			"ISCSI_STATIC_GET returned bad address");
32017836SJohn.Forte@Sun.COM 			return (IMA_ERROR_UNEXPECTED_OS_ERROR);
32027836SJohn.Forte@Sun.COM 		}
32037836SJohn.Forte@Sun.COM 
32047836SJohn.Forte@Sun.COM 
32057836SJohn.Forte@Sun.COM 		(void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress,
32067836SJohn.Forte@Sun.COM 		    &(stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_addr),
32077836SJohn.Forte@Sun.COM 		    stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize);
32087836SJohn.Forte@Sun.COM 	}
32097836SJohn.Forte@Sun.COM 	free(stl_hdr);
32107836SJohn.Forte@Sun.COM 
32117836SJohn.Forte@Sun.COM 	return (IMA_STATUS_SUCCESS);
32127836SJohn.Forte@Sun.COM }
3213