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 /*
227836SJohn.Forte@Sun.COM  * Copyright 2008 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 <stdlib.h>
277836SJohn.Forte@Sun.COM #include <stdio.h>
287836SJohn.Forte@Sun.COM #include <wchar.h>
297836SJohn.Forte@Sun.COM #include <widec.h>
307836SJohn.Forte@Sun.COM #include <sys/types.h>
317836SJohn.Forte@Sun.COM #include <sys/socket.h>
327836SJohn.Forte@Sun.COM #include <arpa/inet.h>
337836SJohn.Forte@Sun.COM #include <netdb.h>
347836SJohn.Forte@Sun.COM #include <unistd.h>
357836SJohn.Forte@Sun.COM #include <libintl.h>
367836SJohn.Forte@Sun.COM #include <limits.h>
377836SJohn.Forte@Sun.COM #include <string.h>
387836SJohn.Forte@Sun.COM #include <strings.h>
397836SJohn.Forte@Sun.COM #include <syslog.h>
407836SJohn.Forte@Sun.COM #include <errno.h>
417836SJohn.Forte@Sun.COM #include <netinet/in.h>
427836SJohn.Forte@Sun.COM #include <sys/socket.h>
437836SJohn.Forte@Sun.COM #include <arpa/inet.h>
447836SJohn.Forte@Sun.COM #include <wctype.h>
457836SJohn.Forte@Sun.COM #include <assert.h>
467836SJohn.Forte@Sun.COM 
477836SJohn.Forte@Sun.COM #include <ima.h>
487836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_protocol.h>
497836SJohn.Forte@Sun.COM #include <sys/scsi/adapters/iscsi_if.h>
507836SJohn.Forte@Sun.COM 
517836SJohn.Forte@Sun.COM #include "cmdparse.h"
527836SJohn.Forte@Sun.COM #include "sun_ima.h"
537836SJohn.Forte@Sun.COM #include "iscsiadm.h"
547836SJohn.Forte@Sun.COM 
557836SJohn.Forte@Sun.COM #define	VERSION_STRING_MAX_LEN	10
567836SJohn.Forte@Sun.COM #define	MAX_LONG_CHAR_LEN 19
577836SJohn.Forte@Sun.COM 
587836SJohn.Forte@Sun.COM #define	MAX_AUTH_METHODS 5
597836SJohn.Forte@Sun.COM /*
607836SJohn.Forte@Sun.COM  * Version number:
617836SJohn.Forte@Sun.COM  *  MAJOR - This should only change when there is an incompatible change made
627836SJohn.Forte@Sun.COM  *  to the interfaces or the output.
637836SJohn.Forte@Sun.COM  *
647836SJohn.Forte@Sun.COM  *  MINOR - This should change whenever there is a new command or new feature
657836SJohn.Forte@Sun.COM  *  with no incompatible change.
667836SJohn.Forte@Sun.COM  */
677836SJohn.Forte@Sun.COM #define	VERSION_STRING_MAJOR	    "1"
687836SJohn.Forte@Sun.COM #define	VERSION_STRING_MINOR	    "0"
697836SJohn.Forte@Sun.COM 
707836SJohn.Forte@Sun.COM #define	OPTIONSTRING1	"yes|no"
717836SJohn.Forte@Sun.COM #define	OPTIONSTRING2	"initiator node name"
727836SJohn.Forte@Sun.COM #define	OPTIONSTRING3	"initiator node alias"
737836SJohn.Forte@Sun.COM #define	OPTIONSTRING4	"enable|disable"
747836SJohn.Forte@Sun.COM #define	OPTIONSTRING5	"key=value,..."
757836SJohn.Forte@Sun.COM #define	OPTIONSTRING6	"none|CRC32"
767836SJohn.Forte@Sun.COM #define	OPTIONSTRING7	"CHAP name"
777836SJohn.Forte@Sun.COM #define	OPTIONSTRING8	"<# sessions>|<IP Address>[,<IP Address>]*"
787836SJohn.Forte@Sun.COM #define	OPTIONVAL1	"0 to 3600"
797836SJohn.Forte@Sun.COM #define	OPTIONVAL2	"512 to 2**24 - 1"
807836SJohn.Forte@Sun.COM #define	OPTIONVAL3	"1 to 65535"
817836SJohn.Forte@Sun.COM #define	OPTIONVAL4	"<IP address>[:port]"
827836SJohn.Forte@Sun.COM 
837836SJohn.Forte@Sun.COM #define	MAX_ISCSI_NAME_LEN	    223
847836SJohn.Forte@Sun.COM #define	MAX_ADDRESS_LEN		    255
857836SJohn.Forte@Sun.COM #define	MIN_CHAP_SECRET_LEN	    12
867836SJohn.Forte@Sun.COM #define	MAX_CHAP_SECRET_LEN	    16
877836SJohn.Forte@Sun.COM #define	DEFAULT_ISCSI_PORT	    3260
887836SJohn.Forte@Sun.COM #define	ISNS_DEFAULT_SERVER_PORT    3205
897836SJohn.Forte@Sun.COM #define	DEFAULT_RADIUS_PORT	    1812
907836SJohn.Forte@Sun.COM #define	MAX_CHAP_NAME_LEN	    512
917836SJohn.Forte@Sun.COM 
927836SJohn.Forte@Sun.COM /* For listNode */
937836SJohn.Forte@Sun.COM #define	INF_ERROR		1
947836SJohn.Forte@Sun.COM #define	INVALID_NODE_NAME	2
957836SJohn.Forte@Sun.COM 
967836SJohn.Forte@Sun.COM #define	IMABOOLPRINT(prop, option)	 \
977836SJohn.Forte@Sun.COM 	if ((option) == PRINT_CONFIGURED_PARAMS) { \
987836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s/%s\n", \
997836SJohn.Forte@Sun.COM 		(prop).defaultValue == IMA_TRUE ? gettext("yes") : \
1007836SJohn.Forte@Sun.COM 			gettext("no"), \
1017836SJohn.Forte@Sun.COM 		(prop).currentValueValid == IMA_TRUE ? \
1027836SJohn.Forte@Sun.COM 			((prop).currentValue == IMA_TRUE ? \
1037836SJohn.Forte@Sun.COM 			gettext("yes"): gettext("no")) : "-"); \
1047836SJohn.Forte@Sun.COM 	} else if ((option) == PRINT_NEGOTIATED_PARAMS) { \
1057836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s\n", \
1067836SJohn.Forte@Sun.COM 		(prop).currentValueValid == IMA_TRUE ? \
1077836SJohn.Forte@Sun.COM 		(((prop).currentValue == IMA_TRUE) ? gettext("yes") : \
1087836SJohn.Forte@Sun.COM 		gettext("no")) : "-"); \
1097836SJohn.Forte@Sun.COM 	}
1107836SJohn.Forte@Sun.COM 
1117836SJohn.Forte@Sun.COM #define	IMAMINMAXPRINT(prop, option) \
1127836SJohn.Forte@Sun.COM 	if ((option) == PRINT_CONFIGURED_PARAMS) { \
1137836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%d/", (prop).defaultValue); \
1147836SJohn.Forte@Sun.COM 		if ((prop).currentValueValid == IMA_TRUE) { \
1157836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%d\n", (prop).currentValue); \
1167836SJohn.Forte@Sun.COM 		} else if ((prop).currentValueValid == IMA_FALSE) { \
1177836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s\n", "-"); \
1187836SJohn.Forte@Sun.COM 		} \
1197836SJohn.Forte@Sun.COM 	} else if ((option) == PRINT_NEGOTIATED_PARAMS) { \
1207836SJohn.Forte@Sun.COM 		if ((prop).currentValueValid == IMA_TRUE) { \
1217836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%d\n", (prop).currentValue); \
1227836SJohn.Forte@Sun.COM 		} else if ((prop).currentValueValid == IMA_FALSE) { \
1237836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s\n", "-"); \
1247836SJohn.Forte@Sun.COM 		} \
1257836SJohn.Forte@Sun.COM 	}
1267836SJohn.Forte@Sun.COM 
1277836SJohn.Forte@Sun.COM /* forward declarations */
1287836SJohn.Forte@Sun.COM #define	PARSE_ADDR_OK				0
1297836SJohn.Forte@Sun.COM #define	PARSE_ADDR_MISSING_CLOSING_BRACKET	1
1307836SJohn.Forte@Sun.COM #define	PARSE_ADDR_PORT_OUT_OF_RANGE		2
1317836SJohn.Forte@Sun.COM #define	PARSE_TARGET_OK				0
1327836SJohn.Forte@Sun.COM #define	PARSE_TARGET_INVALID_TPGT		1
1337836SJohn.Forte@Sun.COM #define	PARSE_TARGET_INVALID_ADDR		2
1347836SJohn.Forte@Sun.COM 
1357836SJohn.Forte@Sun.COM #define	PRINT_CONFIGURED_PARAMS			1
1367836SJohn.Forte@Sun.COM #define	PRINT_NEGOTIATED_PARAMS			2
1377836SJohn.Forte@Sun.COM 
1387836SJohn.Forte@Sun.COM typedef enum iSCSINameCheckStatus {
1397836SJohn.Forte@Sun.COM 	iSCSINameCheckOK,
1407836SJohn.Forte@Sun.COM 	iSCSINameLenZero,
1417836SJohn.Forte@Sun.COM 	iSCSINameLenExceededMax,
1427836SJohn.Forte@Sun.COM 	iSCSINameUnknownType,
1437836SJohn.Forte@Sun.COM 	iSCSINameInvalidCharacter,
1447836SJohn.Forte@Sun.COM 	iSCSINameIqnFormatError,
1457836SJohn.Forte@Sun.COM 	iSCSINameEUIFormatError,
1467836SJohn.Forte@Sun.COM 	iSCSINameIqnDateFormatError,
1477836SJohn.Forte@Sun.COM 	iSCSINameIqnSubdomainFormatError,
1487836SJohn.Forte@Sun.COM 	iSCSINameIqnInvalidYearError,
1497836SJohn.Forte@Sun.COM 	iSCSINameIqnInvalidMonthError,
1507836SJohn.Forte@Sun.COM 	iSCSINameIqnFQDNError
1517836SJohn.Forte@Sun.COM } iSCSINameCheckStatusType;
1527836SJohn.Forte@Sun.COM 
1537836SJohn.Forte@Sun.COM /* Utility functions */
1547836SJohn.Forte@Sun.COM iSCSINameCheckStatusType iSCSINameStringProfileCheck(wchar_t *name);
1557836SJohn.Forte@Sun.COM boolean_t isNaturalNumber(char *numberStr, uint32_t upperBound);
1567836SJohn.Forte@Sun.COM static int parseAddress(char *address_port_str, uint16_t defaultPort,
1577836SJohn.Forte@Sun.COM     char *address_str, size_t address_str_len,
1587836SJohn.Forte@Sun.COM     uint16_t *port, boolean_t *isIpv6);
1597836SJohn.Forte@Sun.COM int parseTarget(char *targetStr,
1607836SJohn.Forte@Sun.COM     wchar_t *targetNameStr,
1617836SJohn.Forte@Sun.COM     size_t targetNameStrLen,
1627836SJohn.Forte@Sun.COM     boolean_t *targetAddressSpecified,
1637836SJohn.Forte@Sun.COM     wchar_t *targetAddressStr,
1647836SJohn.Forte@Sun.COM     size_t targetAddressStrLen,
1657836SJohn.Forte@Sun.COM     uint16_t *port,
1667836SJohn.Forte@Sun.COM     boolean_t *tpgtSpecified,
1677836SJohn.Forte@Sun.COM     uint16_t *tpgt,
1687836SJohn.Forte@Sun.COM     boolean_t *isIpv6);
1697836SJohn.Forte@Sun.COM 
1707836SJohn.Forte@Sun.COM /* subcommand functions */
1717836SJohn.Forte@Sun.COM static int addFunc(int, char **, int, cmdOptions_t *, void *, int *);
1727836SJohn.Forte@Sun.COM static int listFunc(int, char **, int, cmdOptions_t *, void *, int *);
1737836SJohn.Forte@Sun.COM static int modifyFunc(int, char **, int, cmdOptions_t *, void *, int *);
1747836SJohn.Forte@Sun.COM static int removeFunc(int, char **, int, cmdOptions_t *, void *, int *);
1757836SJohn.Forte@Sun.COM 
1767836SJohn.Forte@Sun.COM /* helper functions */
1777836SJohn.Forte@Sun.COM static char *getExecBasename(char *);
1787836SJohn.Forte@Sun.COM static int getNodeProps(IMA_NODE_PROPERTIES *);
1797836SJohn.Forte@Sun.COM static int getSecret(char *, int *, int, int);
1807836SJohn.Forte@Sun.COM static int getTargetAddress(int, char *, IMA_TARGET_ADDRESS *);
1817836SJohn.Forte@Sun.COM static int printLoginParameters(char *, IMA_OID, int);
1827836SJohn.Forte@Sun.COM static void printDiscoveryMethod(char *, IMA_UINT32);
1837836SJohn.Forte@Sun.COM static void printTargetLuns(IMA_OID_LIST *);
1847836SJohn.Forte@Sun.COM static void printSendTargets(SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *);
1857836SJohn.Forte@Sun.COM static void printDigestAlgorithm(SUN_IMA_DIGEST_ALGORITHM_VALUE *, int);
1867836SJohn.Forte@Sun.COM static int setLoginParameter(IMA_OID, int, char *);
1877836SJohn.Forte@Sun.COM static int setLoginParameters(IMA_OID, char *);
1887836SJohn.Forte@Sun.COM static void printLibError(IMA_STATUS);
1897836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
1907836SJohn.Forte@Sun.COM static int sunPluginChk(IMA_OID, boolean_t *);
1917836SJohn.Forte@Sun.COM static int sunInitiatorFind(IMA_OID *);
1927836SJohn.Forte@Sun.COM static int getAuthMethodValue(char *, IMA_AUTHMETHOD *);
1937836SJohn.Forte@Sun.COM static int getLoginParam(char *);
1947836SJohn.Forte@Sun.COM static void iSCSINameCheckStatusDisplay(iSCSINameCheckStatusType status);
1957836SJohn.Forte@Sun.COM static int modifyIndividualTargetParam(cmdOptions_t *optionList,
1967836SJohn.Forte@Sun.COM     IMA_OID targetOid, int *);
1977836SJohn.Forte@Sun.COM static void listCHAPName(IMA_OID oid);
1987836SJohn.Forte@Sun.COM static int printConfiguredSessions(IMA_OID);
1997836SJohn.Forte@Sun.COM 
2007836SJohn.Forte@Sun.COM /* object functions per subcommand */
2017836SJohn.Forte@Sun.COM static int addAddress(int, int, char *[], int *);
2027836SJohn.Forte@Sun.COM static int addStaticConfig(int, char *[], int *);
2037836SJohn.Forte@Sun.COM static int listDiscovery(int *);
2047836SJohn.Forte@Sun.COM static int listDiscoveryAddress(int, char *[], cmdOptions_t *, int *);
2057836SJohn.Forte@Sun.COM static int listISNSServerAddress(int, char *[], cmdOptions_t *, int *);
2067836SJohn.Forte@Sun.COM static int listNode(int *);
2077836SJohn.Forte@Sun.COM static int listStaticConfig(int, char *[], int *);
2087836SJohn.Forte@Sun.COM static int listTarget(int, char *[], cmdOptions_t *, int *);
2097836SJohn.Forte@Sun.COM static int listTargetParam(int, char *[], cmdOptions_t *, int *);
2107836SJohn.Forte@Sun.COM static int modifyDiscovery(cmdOptions_t *, int *);
2117836SJohn.Forte@Sun.COM static int modifyNodeAuthMethod(IMA_OID, char *, int *);
2127836SJohn.Forte@Sun.COM static int modifyNodeAuthParam(IMA_OID oid, int, char *, int *);
2137836SJohn.Forte@Sun.COM static int modifyNodeRadiusConfig(IMA_OID, char *, int *);
2147836SJohn.Forte@Sun.COM static int modifyNodeRadiusAccess(IMA_OID, char *, int *);
2157836SJohn.Forte@Sun.COM static int modifyNodeRadiusSharedSecret(IMA_OID, int *);
2167836SJohn.Forte@Sun.COM static int modifyNode(cmdOptions_t *, int *);
2177836SJohn.Forte@Sun.COM static int modifyTargetAuthMethod(IMA_OID, char *, int *);
2187836SJohn.Forte@Sun.COM static int modifyTargetAuthParam(IMA_OID oid, int param, char *chapName, int *);
2197836SJohn.Forte@Sun.COM static int modifyTargetParam(cmdOptions_t *, char *, int *);
2207836SJohn.Forte@Sun.COM static int removeAddress(int, int, char *[], int *);
2217836SJohn.Forte@Sun.COM static int removeStaticConfig(int, char *[], int *);
2227836SJohn.Forte@Sun.COM static int removeTargetParam(int, char *[], int *);
2237836SJohn.Forte@Sun.COM static int modifyTargetBidirAuthFlag(IMA_OID, char *, int *);
2247836SJohn.Forte@Sun.COM static int modifyConfiguredSessions(IMA_OID targetOid, char *optarg);
2257836SJohn.Forte@Sun.COM 
2267836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
2277836SJohn.Forte@Sun.COM static IMA_STATUS getISCSINodeParameter(int paramType,
2287836SJohn.Forte@Sun.COM     IMA_OID *oid,
2297836SJohn.Forte@Sun.COM     void *pProps,
2307836SJohn.Forte@Sun.COM     uint32_t paramIndex);
2317836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
2327836SJohn.Forte@Sun.COM static IMA_STATUS setISCSINodeParameter(int paramType,
2337836SJohn.Forte@Sun.COM     IMA_OID *oid,
2347836SJohn.Forte@Sun.COM     void *pProps,
2357836SJohn.Forte@Sun.COM     uint32_t paramIndex);
2367836SJohn.Forte@Sun.COM /* LINTED E_STATIC_UNUSED */
2377836SJohn.Forte@Sun.COM static IMA_STATUS getDigest(IMA_OID oid, int ioctlCmd,
2387836SJohn.Forte@Sun.COM     SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm);
2397836SJohn.Forte@Sun.COM 
2407836SJohn.Forte@Sun.COM IMA_STATUS getNegotiatedDigest(int digestType,
2417836SJohn.Forte@Sun.COM 	SUN_IMA_DIGEST_ALGORITHM_VALUE *algorithm,
2427836SJohn.Forte@Sun.COM 	SUN_IMA_CONN_PROPERTIES *connProps);
2437836SJohn.Forte@Sun.COM 
2447836SJohn.Forte@Sun.COM /* globals */
2457836SJohn.Forte@Sun.COM static char *cmdName;
2467836SJohn.Forte@Sun.COM 
2477836SJohn.Forte@Sun.COM /*
2487836SJohn.Forte@Sun.COM  * Available option letters:
2497836SJohn.Forte@Sun.COM  *
2507836SJohn.Forte@Sun.COM  * bcefgijklmnoquwxyz
2517836SJohn.Forte@Sun.COM  *
2527836SJohn.Forte@Sun.COM  * DEFGHIJKLMOQTUVWXYZ
2537836SJohn.Forte@Sun.COM  */
2547836SJohn.Forte@Sun.COM 
2557836SJohn.Forte@Sun.COM /*
2567836SJohn.Forte@Sun.COM  * Add new options here
2577836SJohn.Forte@Sun.COM  */
2587836SJohn.Forte@Sun.COM optionTbl_t longOptions[] = {
2597836SJohn.Forte@Sun.COM 	{"static", required_arg, 's', OPTIONSTRING4},
2607836SJohn.Forte@Sun.COM 	{"sendtargets", required_arg, 't', OPTIONSTRING4},
2617836SJohn.Forte@Sun.COM 	{"iSNS", required_arg, 'i', OPTIONSTRING4},
2627836SJohn.Forte@Sun.COM 	{"headerdigest", required_arg, 'h', OPTIONSTRING6},
2637836SJohn.Forte@Sun.COM 	{"datadigest", required_arg, 'd', OPTIONSTRING6},
2647836SJohn.Forte@Sun.COM 	{"login-param", required_arg, 'p', OPTIONSTRING5},
2657836SJohn.Forte@Sun.COM 	{"authentication", required_arg, 'a', "CHAP|none"},
2667836SJohn.Forte@Sun.COM 	{"bi-directional-authentication", required_arg, 'B', OPTIONSTRING4},
2677836SJohn.Forte@Sun.COM 	{"CHAP-secret", no_arg, 'C', NULL},
2687836SJohn.Forte@Sun.COM 	{"CHAP-name", required_arg, 'H', OPTIONSTRING7},
2697836SJohn.Forte@Sun.COM 	{"node-name", required_arg, 'N', OPTIONSTRING2},
2707836SJohn.Forte@Sun.COM 	{"node-alias", required_arg, 'A', OPTIONSTRING3},
2717836SJohn.Forte@Sun.COM 	{"radius-server", required_arg, 'r', OPTIONVAL4},
2727836SJohn.Forte@Sun.COM 	{"radius-access", required_arg, 'R', OPTIONSTRING4},
2737836SJohn.Forte@Sun.COM 	{"radius-shared-secret", no_arg, 'P', NULL},
2747836SJohn.Forte@Sun.COM 	{"verbose", no_arg, 'v', NULL},
2757836SJohn.Forte@Sun.COM 	{"scsi-target", no_arg, 'S', NULL},
2767836SJohn.Forte@Sun.COM 	{"configured-sessions", required_arg, 'c', OPTIONSTRING8},
2777836SJohn.Forte@Sun.COM 	{NULL, 0, 0, 0}
2787836SJohn.Forte@Sun.COM };
2797836SJohn.Forte@Sun.COM 
2807836SJohn.Forte@Sun.COM parameterTbl_t loginParams[] = {
2817836SJohn.Forte@Sun.COM 	{"dataseqinorder", DATA_SEQ_IN_ORDER},
2827836SJohn.Forte@Sun.COM 	{"defaulttime2retain", DEFAULT_TIME_2_RETAIN},
2837836SJohn.Forte@Sun.COM 	{"defaulttime2wait", DEFAULT_TIME_2_WAIT},
2847836SJohn.Forte@Sun.COM 	{"firstburstlength", FIRST_BURST_LENGTH},
2857836SJohn.Forte@Sun.COM 	{"immediatedata", IMMEDIATE_DATA},
2867836SJohn.Forte@Sun.COM 	{"initialr2t", INITIAL_R2T},
2877836SJohn.Forte@Sun.COM 	{"maxburstlength", MAX_BURST_LENGTH},
2887836SJohn.Forte@Sun.COM 	{"datapduinorder", DATA_PDU_IN_ORDER},
2897836SJohn.Forte@Sun.COM 	{"maxoutstandingr2t", MAX_OUTSTANDING_R2T},
2907836SJohn.Forte@Sun.COM 	{"maxrecvdataseglen", MAX_RECV_DATA_SEG_LEN},
2917836SJohn.Forte@Sun.COM 	{"maxconnections", MAX_CONNECTIONS},
2927836SJohn.Forte@Sun.COM 	{"errorrecoverylevel", ERROR_RECOVERY_LEVEL},
2937836SJohn.Forte@Sun.COM 	{NULL, 0}
2947836SJohn.Forte@Sun.COM };
2957836SJohn.Forte@Sun.COM 
2967836SJohn.Forte@Sun.COM /*
2977836SJohn.Forte@Sun.COM  * Add new subcommands here
2987836SJohn.Forte@Sun.COM  */
2997836SJohn.Forte@Sun.COM subcommand_t subcommands[] = {
3007836SJohn.Forte@Sun.COM 	{"add", ADD, addFunc},
3017836SJohn.Forte@Sun.COM 	{"list", LIST, listFunc},
3027836SJohn.Forte@Sun.COM 	{"modify", MODIFY, modifyFunc},
3037836SJohn.Forte@Sun.COM 	{"remove", REMOVE, removeFunc},
3047836SJohn.Forte@Sun.COM 	{NULL, 0, NULL}
3057836SJohn.Forte@Sun.COM };
3067836SJohn.Forte@Sun.COM 
3077836SJohn.Forte@Sun.COM /*
3087836SJohn.Forte@Sun.COM  * Add objects here
3097836SJohn.Forte@Sun.COM  */
3107836SJohn.Forte@Sun.COM object_t objects[] = {
3117836SJohn.Forte@Sun.COM 	{"discovery", DISCOVERY},
3127836SJohn.Forte@Sun.COM 	{"discovery-address", DISCOVERY_ADDRESS},
3137836SJohn.Forte@Sun.COM 	{"isns-server", ISNS_SERVER_ADDRESS},
3147836SJohn.Forte@Sun.COM 	{"initiator-node", NODE},
3157836SJohn.Forte@Sun.COM 	{"static-config", STATIC_CONFIG},
3167836SJohn.Forte@Sun.COM 	{"target", TARGET},
3177836SJohn.Forte@Sun.COM 	{"target-param", TARGET_PARAM},
3187836SJohn.Forte@Sun.COM 	{NULL, 0}
3197836SJohn.Forte@Sun.COM };
3207836SJohn.Forte@Sun.COM 
3217836SJohn.Forte@Sun.COM /*
3227836SJohn.Forte@Sun.COM  * Rules for subcommands and objects
3237836SJohn.Forte@Sun.COM  */
3247836SJohn.Forte@Sun.COM objectRules_t objectRules[] = {
3257836SJohn.Forte@Sun.COM 	{TARGET, 0, LIST, 0, ADD|REMOVE|MODIFY, LIST,
3267836SJohn.Forte@Sun.COM 	"target-name"},
3277836SJohn.Forte@Sun.COM 	{TARGET_PARAM, MODIFY|REMOVE, LIST, 0, ADD, MODIFY,
3287836SJohn.Forte@Sun.COM 	"target-name"},
3297836SJohn.Forte@Sun.COM 	{DISCOVERY, 0, 0, LIST|MODIFY, ADD|REMOVE, 0, NULL},
3307836SJohn.Forte@Sun.COM 	{NODE, 0, 0, MODIFY|LIST, ADD|REMOVE, 0, NULL},
3317836SJohn.Forte@Sun.COM 	{STATIC_CONFIG, ADD|REMOVE, LIST, 0, MODIFY, ADD|REMOVE|LIST,
3327836SJohn.Forte@Sun.COM 	"target-name,target-address[:port-number][,tpgt]"},
3337836SJohn.Forte@Sun.COM 	{DISCOVERY_ADDRESS, ADD|REMOVE, LIST, 0, MODIFY,
3347836SJohn.Forte@Sun.COM 	ADD|REMOVE|LIST, "IP-address[:port-number]"},
3357836SJohn.Forte@Sun.COM 	{ISNS_SERVER_ADDRESS, ADD|REMOVE, LIST, 0, MODIFY,
3367836SJohn.Forte@Sun.COM 	ADD|REMOVE|LIST, "IP-address[:port-number]"},
3377836SJohn.Forte@Sun.COM 	{0, 0, 0, 0, 0, NULL}
3387836SJohn.Forte@Sun.COM };
3397836SJohn.Forte@Sun.COM 
3407836SJohn.Forte@Sun.COM /*
3417836SJohn.Forte@Sun.COM  * list of objects, subcommands, valid short options, required flag and
3427836SJohn.Forte@Sun.COM  * exclusive option string
3437836SJohn.Forte@Sun.COM  *
3447836SJohn.Forte@Sun.COM  * If it's not here, there are no options for that object.
3457836SJohn.Forte@Sun.COM  */
3467836SJohn.Forte@Sun.COM optionRules_t optionRules[] = {
3477836SJohn.Forte@Sun.COM 	{DISCOVERY, MODIFY, "sti", B_TRUE, NULL},
3487836SJohn.Forte@Sun.COM 	{DISCOVERY_ADDRESS, LIST, "v", B_FALSE, NULL},
3497836SJohn.Forte@Sun.COM 	{ISNS_SERVER_ADDRESS, LIST, "v", B_FALSE, NULL},
3507836SJohn.Forte@Sun.COM 	{TARGET, LIST, "vS", B_FALSE, NULL},
3517836SJohn.Forte@Sun.COM 	{NODE, MODIFY, "NAhdCaRrPHc", B_TRUE, "CP"},
3527836SJohn.Forte@Sun.COM 	{TARGET_PARAM, MODIFY, "ahdBCpcH", B_TRUE, "C"},
3537836SJohn.Forte@Sun.COM 	{TARGET_PARAM, LIST, "v", B_FALSE, NULL},
3547836SJohn.Forte@Sun.COM 	{0, 0, 0, 0, 0}
3557836SJohn.Forte@Sun.COM };
3567836SJohn.Forte@Sun.COM 
3577836SJohn.Forte@Sun.COM 
3587836SJohn.Forte@Sun.COM static boolean_t
3597836SJohn.Forte@Sun.COM targetNamesEqual(wchar_t *name1, wchar_t *name2)
3607836SJohn.Forte@Sun.COM {
3617836SJohn.Forte@Sun.COM 	int i;
3627836SJohn.Forte@Sun.COM 	wchar_t wchar1, wchar2;
3637836SJohn.Forte@Sun.COM 
3647836SJohn.Forte@Sun.COM 	if (name1 == NULL || name2 == NULL) {
3657836SJohn.Forte@Sun.COM 		return (B_FALSE);
3667836SJohn.Forte@Sun.COM 	}
3677836SJohn.Forte@Sun.COM 
3687836SJohn.Forte@Sun.COM 	if (wcslen(name1) != wcslen(name2)) {
3697836SJohn.Forte@Sun.COM 		return (B_FALSE);
3707836SJohn.Forte@Sun.COM 	}
3717836SJohn.Forte@Sun.COM 
3727836SJohn.Forte@Sun.COM 	/*
3737836SJohn.Forte@Sun.COM 	 * Convert names to lower case and compare
3747836SJohn.Forte@Sun.COM 	 */
3757836SJohn.Forte@Sun.COM 	for (i = 0; i < wcslen(name1); i++) {
3767836SJohn.Forte@Sun.COM 		wchar1 = towctrans((wint_t)name1[i], wctrans("tolower"));
3777836SJohn.Forte@Sun.COM 		wchar2 = towctrans((wint_t)name2[i], wctrans("tolower"));
3787836SJohn.Forte@Sun.COM 
3797836SJohn.Forte@Sun.COM 		if (wchar1 != wchar2) {
3807836SJohn.Forte@Sun.COM 			return (B_FALSE);
3817836SJohn.Forte@Sun.COM 		}
3827836SJohn.Forte@Sun.COM 	}
3837836SJohn.Forte@Sun.COM 
3847836SJohn.Forte@Sun.COM 	return (B_TRUE);
3857836SJohn.Forte@Sun.COM }
3867836SJohn.Forte@Sun.COM 
3877836SJohn.Forte@Sun.COM static boolean_t
3887836SJohn.Forte@Sun.COM ipAddressesEqual(IMA_TARGET_ADDRESS addr1, IMA_TARGET_ADDRESS addr2)
3897836SJohn.Forte@Sun.COM {
3907836SJohn.Forte@Sun.COM #define	IPV4_ADDR_BYTES 4
3917836SJohn.Forte@Sun.COM #define	IPV6_ADDR_BYTES 16
3927836SJohn.Forte@Sun.COM 
3937836SJohn.Forte@Sun.COM 	int compSize;
3947836SJohn.Forte@Sun.COM 
3957836SJohn.Forte@Sun.COM 	if (addr1.hostnameIpAddress.id.ipAddress.ipv4Address !=
3967836SJohn.Forte@Sun.COM 	    addr2.hostnameIpAddress.id.ipAddress.ipv4Address) {
3977836SJohn.Forte@Sun.COM 		return (B_FALSE);
3987836SJohn.Forte@Sun.COM 	}
3997836SJohn.Forte@Sun.COM 
4007836SJohn.Forte@Sun.COM 	compSize = IPV6_ADDR_BYTES;
4017836SJohn.Forte@Sun.COM 	if (addr1.hostnameIpAddress.id.ipAddress.ipv4Address) {
4027836SJohn.Forte@Sun.COM 		compSize = IPV4_ADDR_BYTES;
4037836SJohn.Forte@Sun.COM 	}
4047836SJohn.Forte@Sun.COM 
4057836SJohn.Forte@Sun.COM 	if (bcmp(addr1.hostnameIpAddress.id.ipAddress.ipAddress,
4067836SJohn.Forte@Sun.COM 	    addr2.hostnameIpAddress.id.ipAddress.ipAddress, compSize) == 0) {
4077836SJohn.Forte@Sun.COM 		return (B_TRUE);
4087836SJohn.Forte@Sun.COM 	}
4097836SJohn.Forte@Sun.COM 
4107836SJohn.Forte@Sun.COM 	return (B_FALSE);
4117836SJohn.Forte@Sun.COM }
4127836SJohn.Forte@Sun.COM 
4137836SJohn.Forte@Sun.COM static int
4147836SJohn.Forte@Sun.COM getLoginParam(char *arg)
4157836SJohn.Forte@Sun.COM {
4167836SJohn.Forte@Sun.COM 	parameterTbl_t *paramp;
4177836SJohn.Forte@Sun.COM 	int len;
4187836SJohn.Forte@Sun.COM 
4197836SJohn.Forte@Sun.COM 	for (paramp = loginParams; paramp->name; paramp++) {
4207836SJohn.Forte@Sun.COM 		len = strlen(arg);
4217836SJohn.Forte@Sun.COM 		if (len == strlen(paramp->name) &&
4227836SJohn.Forte@Sun.COM 		    strncasecmp(arg, paramp->name, len) == 0) {
4237836SJohn.Forte@Sun.COM 			return (paramp->val);
4247836SJohn.Forte@Sun.COM 		}
4257836SJohn.Forte@Sun.COM 	}
4267836SJohn.Forte@Sun.COM 	return (-1);
4277836SJohn.Forte@Sun.COM }
4287836SJohn.Forte@Sun.COM 
4297836SJohn.Forte@Sun.COM static void
4307836SJohn.Forte@Sun.COM printLibError(IMA_STATUS status)
4317836SJohn.Forte@Sun.COM {
4327836SJohn.Forte@Sun.COM 	char *errorString;
4337836SJohn.Forte@Sun.COM 	switch (status) {
4347836SJohn.Forte@Sun.COM 	case IMA_ERROR_NOT_SUPPORTED:
4357836SJohn.Forte@Sun.COM 		errorString =
4367836SJohn.Forte@Sun.COM 		gettext("Operation currently not supported");
4377836SJohn.Forte@Sun.COM 		break;
4387836SJohn.Forte@Sun.COM 	case IMA_ERROR_INSUFFICIENT_MEMORY:
4397836SJohn.Forte@Sun.COM 		errorString = gettext("Insufficient memory");
4407836SJohn.Forte@Sun.COM 		break;
4417836SJohn.Forte@Sun.COM 	case IMA_ERROR_UNEXPECTED_OS_ERROR:
4427836SJohn.Forte@Sun.COM 		errorString = gettext("unexpected OS error");
4437836SJohn.Forte@Sun.COM 		break;
4447836SJohn.Forte@Sun.COM 	case IMA_ERROR_UNKNOWN_ERROR:
4457836SJohn.Forte@Sun.COM 		errorString = gettext("Unknown error");
4467836SJohn.Forte@Sun.COM 		break;
4477836SJohn.Forte@Sun.COM 	case IMA_ERROR_LU_IN_USE:
4487836SJohn.Forte@Sun.COM 		errorString = gettext("Logical unit in use");
4497836SJohn.Forte@Sun.COM 		break;
4507836SJohn.Forte@Sun.COM 	case IMA_ERROR_INVALID_PARAMETER:
4517836SJohn.Forte@Sun.COM 		errorString = gettext("Invalid parameter specified");
4527836SJohn.Forte@Sun.COM 		break;
4537836SJohn.Forte@Sun.COM 	case IMA_ERROR_INVALID_OBJECT_TYPE:
4547836SJohn.Forte@Sun.COM 		errorString =
4557836SJohn.Forte@Sun.COM 		gettext("Internal library error: Invalid oid type specified");
4567836SJohn.Forte@Sun.COM 		break;
4577836SJohn.Forte@Sun.COM 	case IMA_ERROR_INCORRECT_OBJECT_TYPE:
4587836SJohn.Forte@Sun.COM 		errorString =
4597836SJohn.Forte@Sun.COM 		gettext("Internal library error: Incorrect oid type specified");
4607836SJohn.Forte@Sun.COM 		break;
4617836SJohn.Forte@Sun.COM 	case IMA_ERROR_OBJECT_NOT_FOUND:
4627836SJohn.Forte@Sun.COM 		errorString = gettext("Internal library error: Oid not found");
4637836SJohn.Forte@Sun.COM 		break;
4647836SJohn.Forte@Sun.COM 	case IMA_ERROR_NAME_TOO_LONG:
4657836SJohn.Forte@Sun.COM 		errorString = gettext("Name too long");
4667836SJohn.Forte@Sun.COM 		break;
4677836SJohn.Forte@Sun.COM 	default:
4687836SJohn.Forte@Sun.COM 		errorString = gettext("Unknown error");
4697836SJohn.Forte@Sun.COM 	}
4707836SJohn.Forte@Sun.COM 	(void) fprintf(stderr, "%s: %s\n", cmdName, errorString);
4717836SJohn.Forte@Sun.COM }
4727836SJohn.Forte@Sun.COM 
4737836SJohn.Forte@Sun.COM /*
4747836SJohn.Forte@Sun.COM  * input:
4757836SJohn.Forte@Sun.COM  *  execFullName - exec name of program (argv[0])
4767836SJohn.Forte@Sun.COM  *
4777836SJohn.Forte@Sun.COM  * Returns:
4787836SJohn.Forte@Sun.COM  *  command name portion of execFullName
4797836SJohn.Forte@Sun.COM  */
4807836SJohn.Forte@Sun.COM static char *
4817836SJohn.Forte@Sun.COM getExecBasename(char *execFullname)
4827836SJohn.Forte@Sun.COM {
4837836SJohn.Forte@Sun.COM 	char *lastSlash, *execBasename;
4847836SJohn.Forte@Sun.COM 
4857836SJohn.Forte@Sun.COM 	/* guard against '/' at end of command invocation */
4867836SJohn.Forte@Sun.COM 	for (;;) {
4877836SJohn.Forte@Sun.COM 		lastSlash = strrchr(execFullname, '/');
4887836SJohn.Forte@Sun.COM 		if (lastSlash == NULL) {
4897836SJohn.Forte@Sun.COM 			execBasename = execFullname;
4907836SJohn.Forte@Sun.COM 			break;
4917836SJohn.Forte@Sun.COM 		} else {
4927836SJohn.Forte@Sun.COM 			execBasename = lastSlash + 1;
4937836SJohn.Forte@Sun.COM 			if (*execBasename == '\0') {
4947836SJohn.Forte@Sun.COM 				*lastSlash = '\0';
4957836SJohn.Forte@Sun.COM 				continue;
4967836SJohn.Forte@Sun.COM 			}
4977836SJohn.Forte@Sun.COM 			break;
4987836SJohn.Forte@Sun.COM 		}
4997836SJohn.Forte@Sun.COM 	}
5007836SJohn.Forte@Sun.COM 	return (execBasename);
5017836SJohn.Forte@Sun.COM }
5027836SJohn.Forte@Sun.COM 
5037836SJohn.Forte@Sun.COM 
5047836SJohn.Forte@Sun.COM /*
5057836SJohn.Forte@Sun.COM  * input:
5067836SJohn.Forte@Sun.COM  *  nodeProps - pointer to caller allocated IMA_NODE_PROPERTIES
5077836SJohn.Forte@Sun.COM  *
5087836SJohn.Forte@Sun.COM  * returns:
5097836SJohn.Forte@Sun.COM  *  zero on success
5107836SJohn.Forte@Sun.COM  *  non-zero otherwise
5117836SJohn.Forte@Sun.COM  */
5127836SJohn.Forte@Sun.COM static int
5137836SJohn.Forte@Sun.COM getNodeProps(IMA_NODE_PROPERTIES *nodeProps)
5147836SJohn.Forte@Sun.COM {
5157836SJohn.Forte@Sun.COM 	IMA_OID sharedNodeOid;
5167836SJohn.Forte@Sun.COM 
5177836SJohn.Forte@Sun.COM 	IMA_STATUS status = IMA_GetSharedNodeOid(&sharedNodeOid);
5187836SJohn.Forte@Sun.COM 	if (!(IMA_SUCCESS(status))) {
5197836SJohn.Forte@Sun.COM 		printLibError(status);
5207836SJohn.Forte@Sun.COM 		return (INF_ERROR);
5217836SJohn.Forte@Sun.COM 	}
5227836SJohn.Forte@Sun.COM 
5237836SJohn.Forte@Sun.COM 	status = IMA_GetNodeProperties(sharedNodeOid, nodeProps);
5247836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
5257836SJohn.Forte@Sun.COM 		printLibError(status);
5267836SJohn.Forte@Sun.COM 		return (INF_ERROR);
5277836SJohn.Forte@Sun.COM 	}
5287836SJohn.Forte@Sun.COM 
5297836SJohn.Forte@Sun.COM 	return (0);
5307836SJohn.Forte@Sun.COM }
5317836SJohn.Forte@Sun.COM 
5327836SJohn.Forte@Sun.COM /*
5337836SJohn.Forte@Sun.COM  * sunInitiatorFind
5347836SJohn.Forte@Sun.COM  * Purpose:
5357836SJohn.Forte@Sun.COM  *  Finds the Sun iSCSI initiator (LHBA). This CLI currently supports only
5367836SJohn.Forte@Sun.COM  *  one initiator.
5377836SJohn.Forte@Sun.COM  *
5387836SJohn.Forte@Sun.COM  * output:
5397836SJohn.Forte@Sun.COM  *  oid of initiator
5407836SJohn.Forte@Sun.COM  *
5417836SJohn.Forte@Sun.COM  * Returns:
5427836SJohn.Forte@Sun.COM  *  zero on success with initiator found
5437836SJohn.Forte@Sun.COM  *  > 0 on success with no initiator found
5447836SJohn.Forte@Sun.COM  *  < 0 on failure
5457836SJohn.Forte@Sun.COM  */
5467836SJohn.Forte@Sun.COM static int
5477836SJohn.Forte@Sun.COM sunInitiatorFind(IMA_OID *oid)
5487836SJohn.Forte@Sun.COM {
5497836SJohn.Forte@Sun.COM 	IMA_OID_LIST *lhbaList;
5507836SJohn.Forte@Sun.COM 
5517836SJohn.Forte@Sun.COM 	IMA_STATUS status = IMA_GetLhbaOidList(&lhbaList);
5527836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
5537836SJohn.Forte@Sun.COM 		printLibError(status);
5547836SJohn.Forte@Sun.COM 		return (-1);
5557836SJohn.Forte@Sun.COM 	}
5567836SJohn.Forte@Sun.COM 
5577836SJohn.Forte@Sun.COM 	*oid = lhbaList->oids[0];
5587836SJohn.Forte@Sun.COM 
5597836SJohn.Forte@Sun.COM 	return (0);
5607836SJohn.Forte@Sun.COM }
5617836SJohn.Forte@Sun.COM 
5627836SJohn.Forte@Sun.COM /*
5637836SJohn.Forte@Sun.COM  * input:
5647836SJohn.Forte@Sun.COM  *  wcInput - wide character string containing discovery address
5657836SJohn.Forte@Sun.COM  * output:
5667836SJohn.Forte@Sun.COM  *  address - IMA_TARGET_ADDRESS structure containing valid
5677836SJohn.Forte@Sun.COM  *	discovery address
5687836SJohn.Forte@Sun.COM  * returns:
5697836SJohn.Forte@Sun.COM  *  zero on success
5707836SJohn.Forte@Sun.COM  *  non-zero on failure
5717836SJohn.Forte@Sun.COM  */
5727836SJohn.Forte@Sun.COM 
5737836SJohn.Forte@Sun.COM static int
5747836SJohn.Forte@Sun.COM getTargetAddress(int addrType, char *ipStr, IMA_TARGET_ADDRESS *address)
5757836SJohn.Forte@Sun.COM {
5767836SJohn.Forte@Sun.COM 	char cCol = ':';
5777836SJohn.Forte@Sun.COM 	char cBracketL = '['; /* Open Bracket '[' */
5787836SJohn.Forte@Sun.COM 	char cBracketR = ']'; /* Close Bracket ']' */
5797836SJohn.Forte@Sun.COM 	char *colPos;
5807836SJohn.Forte@Sun.COM 	char *startPos;
5817836SJohn.Forte@Sun.COM 	unsigned long inputPort;
5827836SJohn.Forte@Sun.COM 	int addressType = AF_INET;
5837836SJohn.Forte@Sun.COM 	char *tmpStrPtr, tmpStr[SUN_IMA_IP_ADDRESS_PORT_LEN];
5847836SJohn.Forte@Sun.COM 	int rval;
5857836SJohn.Forte@Sun.COM 
5867836SJohn.Forte@Sun.COM 	/* Check if this is a ipv6 address */
5877836SJohn.Forte@Sun.COM 	if (ipStr[0] == cBracketL) {
5887836SJohn.Forte@Sun.COM 		addressType = AF_INET6;
5897836SJohn.Forte@Sun.COM 		startPos = strchr(ipStr, cBracketR);
5907836SJohn.Forte@Sun.COM 		if (!startPos) {
5917836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s: ']' %s\n",
5927836SJohn.Forte@Sun.COM 			    cmdName, ipStr, gettext("missing"));
5937836SJohn.Forte@Sun.COM 			return (1);
5947836SJohn.Forte@Sun.COM 		}
5957836SJohn.Forte@Sun.COM 		(void) strlcpy(tmpStr, ipStr+1, startPos-ipStr);
5967836SJohn.Forte@Sun.COM 		address->hostnameIpAddress.id.ipAddress.ipv4Address = IMA_FALSE;
5977836SJohn.Forte@Sun.COM 		tmpStrPtr = tmpStr;
5987836SJohn.Forte@Sun.COM 	} else {
5997836SJohn.Forte@Sun.COM 		/* set start position to beginning of input object */
6007836SJohn.Forte@Sun.COM 		addressType = AF_INET;
6017836SJohn.Forte@Sun.COM 		startPos = ipStr;
6027836SJohn.Forte@Sun.COM 		address->hostnameIpAddress.id.ipAddress.ipv4Address = IMA_TRUE;
6037836SJohn.Forte@Sun.COM 		tmpStrPtr = ipStr;
6047836SJohn.Forte@Sun.COM 	}
6057836SJohn.Forte@Sun.COM 	/* wcschr for ':'. If not there, use default port */
6067836SJohn.Forte@Sun.COM 	colPos = strchr(startPos, cCol);
6077836SJohn.Forte@Sun.COM 
6087836SJohn.Forte@Sun.COM 	if (!colPos) {
6097836SJohn.Forte@Sun.COM 		if (addrType == DISCOVERY_ADDRESS) {
6107836SJohn.Forte@Sun.COM 			inputPort = DEFAULT_ISCSI_PORT;
6117836SJohn.Forte@Sun.COM 		} else if (addrType == ISNS_SERVER_ADDRESS) {
6127836SJohn.Forte@Sun.COM 			inputPort = ISNS_DEFAULT_SERVER_PORT;
6137836SJohn.Forte@Sun.COM 		} else {
6147836SJohn.Forte@Sun.COM 			*colPos = NULL;
6157836SJohn.Forte@Sun.COM 		}
6167836SJohn.Forte@Sun.COM 	} else {
6177836SJohn.Forte@Sun.COM 		*colPos = NULL;
6187836SJohn.Forte@Sun.COM 	}
6197836SJohn.Forte@Sun.COM 
6207836SJohn.Forte@Sun.COM 	rval = inet_pton(addressType, tmpStrPtr,
6217836SJohn.Forte@Sun.COM 	    address->hostnameIpAddress.id.ipAddress.ipAddress);
6227836SJohn.Forte@Sun.COM 	/* inet_pton returns 1 on success */
6237836SJohn.Forte@Sun.COM 	if (rval != 1) {
6247836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s: %s\n", cmdName, ipStr,
6257836SJohn.Forte@Sun.COM 		    gettext("invalid IP address"));
6267836SJohn.Forte@Sun.COM 		return (1);
6277836SJohn.Forte@Sun.COM 	}
6287836SJohn.Forte@Sun.COM 
6297836SJohn.Forte@Sun.COM 
6307836SJohn.Forte@Sun.COM 	if (colPos) {
6317836SJohn.Forte@Sun.COM 		char *errchr;
6327836SJohn.Forte@Sun.COM 
6337836SJohn.Forte@Sun.COM 		colPos++;
6347836SJohn.Forte@Sun.COM 		if (*colPos == NULL) {
6357836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s: %s\n",
6367836SJohn.Forte@Sun.COM 			    cmdName, ipStr,
6377836SJohn.Forte@Sun.COM 			    gettext("port number missing"));
6387836SJohn.Forte@Sun.COM 			return (1);
6397836SJohn.Forte@Sun.COM 		}
6407836SJohn.Forte@Sun.COM 
6417836SJohn.Forte@Sun.COM 		/*
6427836SJohn.Forte@Sun.COM 		 * convert port string to unsigned value
6437836SJohn.Forte@Sun.COM 		 * Note:  Don't remove errno = 0 as you may get false failures.
6447836SJohn.Forte@Sun.COM 		 */
6457836SJohn.Forte@Sun.COM 		errno = 0;
6467836SJohn.Forte@Sun.COM 		inputPort = strtol(colPos, &errchr, 10);
6477836SJohn.Forte@Sun.COM 		if (errno != 0 || inputPort == 0 && errchr != NULL) {
6487836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s:%s %s\n",
6497836SJohn.Forte@Sun.COM 			    cmdName, ipStr, colPos,
6507836SJohn.Forte@Sun.COM 			    gettext("port number invalid"));
6517836SJohn.Forte@Sun.COM 			return (1);
6527836SJohn.Forte@Sun.COM 		}
6537836SJohn.Forte@Sun.COM 		/* make sure it's in the range */
6547836SJohn.Forte@Sun.COM 		if (inputPort > USHRT_MAX) {
6557836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s: %s\n",
6567836SJohn.Forte@Sun.COM 			    cmdName, ipStr,
6577836SJohn.Forte@Sun.COM 			    gettext("port number out of range"));
6587836SJohn.Forte@Sun.COM 			return (1);
6597836SJohn.Forte@Sun.COM 		}
6607836SJohn.Forte@Sun.COM 	}
6617836SJohn.Forte@Sun.COM 	address->portNumber  = inputPort;
6627836SJohn.Forte@Sun.COM 
6637836SJohn.Forte@Sun.COM 	return (0);
6647836SJohn.Forte@Sun.COM }
6657836SJohn.Forte@Sun.COM 
6667836SJohn.Forte@Sun.COM /*
6677836SJohn.Forte@Sun.COM  * Print results of send targets command
6687836SJohn.Forte@Sun.COM  */
6697836SJohn.Forte@Sun.COM static void
6707836SJohn.Forte@Sun.COM printSendTargets(SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList)
6717836SJohn.Forte@Sun.COM {
6727836SJohn.Forte@Sun.COM 	char outBuf[INET6_ADDRSTRLEN];
6737836SJohn.Forte@Sun.COM 	int inetSize;
6747836SJohn.Forte@Sun.COM 	int af;
6757836SJohn.Forte@Sun.COM 	int i;
6767836SJohn.Forte@Sun.COM 
6777836SJohn.Forte@Sun.COM 	for (i = 0; i < pList->keyCount; i++) {
6787836SJohn.Forte@Sun.COM 		if (pList->keys[i].address.ipAddress.ipv4Address == IMA_TRUE) {
6797836SJohn.Forte@Sun.COM 			af = AF_INET;
6807836SJohn.Forte@Sun.COM 			inetSize = INET_ADDRSTRLEN;
6817836SJohn.Forte@Sun.COM 		} else {
6827836SJohn.Forte@Sun.COM 			af = AF_INET6;
6837836SJohn.Forte@Sun.COM 			inetSize = INET6_ADDRSTRLEN;
6847836SJohn.Forte@Sun.COM 		}
6857836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, gettext("\tTarget name: %ws\n"),
6867836SJohn.Forte@Sun.COM 		    pList->keys[i].name);
6877836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\t\t%s: %15s:%d", "Target address",
6887836SJohn.Forte@Sun.COM 		    inet_ntop(af, &(pList->keys[i].address.ipAddress.ipAddress),
6897836SJohn.Forte@Sun.COM 		    outBuf, inetSize), pList->keys[i].address.portNumber);
6907836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, ", %d", pList->keys[i].tpgt);
6917836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\n");
6927836SJohn.Forte@Sun.COM 	}
6937836SJohn.Forte@Sun.COM }
6947836SJohn.Forte@Sun.COM 
6957836SJohn.Forte@Sun.COM 
6967836SJohn.Forte@Sun.COM /*
6977836SJohn.Forte@Sun.COM  * Print all login parameters
6987836SJohn.Forte@Sun.COM  */
6997836SJohn.Forte@Sun.COM static int
7007836SJohn.Forte@Sun.COM printLoginParameters(char *prefix, IMA_OID oid, int printOption)
7017836SJohn.Forte@Sun.COM {
7027836SJohn.Forte@Sun.COM 	IMA_STATUS status;
7037836SJohn.Forte@Sun.COM 	IMA_BOOL_VALUE propBool;
7047836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE propMinMax;
7057836SJohn.Forte@Sun.COM 	char longString[MAX_LONG_CHAR_LEN + 1];
7067836SJohn.Forte@Sun.COM 	SUN_IMA_CONN_PROPERTIES	*connProps = NULL;
7077836SJohn.Forte@Sun.COM 	IMA_OID_LIST *pConnList;
7087836SJohn.Forte@Sun.COM 
7097836SJohn.Forte@Sun.COM 	(void) memset(longString, 0, sizeof (longString));
7107836SJohn.Forte@Sun.COM 
7117836SJohn.Forte@Sun.COM 	switch (printOption) {
7127836SJohn.Forte@Sun.COM 		case PRINT_CONFIGURED_PARAMS:
7137836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s%s:\n",
7147836SJohn.Forte@Sun.COM 			    prefix,
7157836SJohn.Forte@Sun.COM 			    gettext("Login Parameters (Default/Configured)"));
7167836SJohn.Forte@Sun.COM 			break;
7177836SJohn.Forte@Sun.COM 		case PRINT_NEGOTIATED_PARAMS:
7187836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s%s:\n",
7197836SJohn.Forte@Sun.COM 			    prefix,
7207836SJohn.Forte@Sun.COM 			    gettext("Login Parameters (Negotiated)"));
7217836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetConnOidList(
7227836SJohn.Forte@Sun.COM 			    &oid,
7237836SJohn.Forte@Sun.COM 			    &pConnList);
7247836SJohn.Forte@Sun.COM 
7257836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
7267836SJohn.Forte@Sun.COM 				printLibError(status);
7277836SJohn.Forte@Sun.COM 				return (1);
7287836SJohn.Forte@Sun.COM 			}
7297836SJohn.Forte@Sun.COM 
7307836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetConnProperties(&pConnList->oids[0],
7317836SJohn.Forte@Sun.COM 			    &connProps);
7327836SJohn.Forte@Sun.COM 			propBool.currentValueValid = connProps->valuesValid;
7337836SJohn.Forte@Sun.COM 			propMinMax.currentValueValid = connProps->valuesValid;
7347836SJohn.Forte@Sun.COM 			break;
7357836SJohn.Forte@Sun.COM 		default:
7367836SJohn.Forte@Sun.COM 			return (1);
7377836SJohn.Forte@Sun.COM 	}
7387836SJohn.Forte@Sun.COM 
7397836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
7407836SJohn.Forte@Sun.COM 		propBool.currentValue = connProps->dataSequenceInOrder;
7417836SJohn.Forte@Sun.COM 	} else {
7427836SJohn.Forte@Sun.COM 		status = IMA_GetDataSequenceInOrderProperties(oid, &propBool);
7437836SJohn.Forte@Sun.COM 	}
7447836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
7457836SJohn.Forte@Sun.COM 		printLibError(status);
7467836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
7477836SJohn.Forte@Sun.COM 		return (1);
7487836SJohn.Forte@Sun.COM 	}
7497836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
7507836SJohn.Forte@Sun.COM 	    gettext("Data Sequence In Order"));
7517836SJohn.Forte@Sun.COM 	IMABOOLPRINT(propBool, printOption);
7527836SJohn.Forte@Sun.COM 
7537836SJohn.Forte@Sun.COM 
7547836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
7557836SJohn.Forte@Sun.COM 		propBool.currentValue = connProps->dataPduInOrder;
7567836SJohn.Forte@Sun.COM 	} else {
7577836SJohn.Forte@Sun.COM 		status = IMA_GetDataPduInOrderProperties(oid, &propBool);
7587836SJohn.Forte@Sun.COM 	}
7597836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
7607836SJohn.Forte@Sun.COM 		printLibError(status);
7617836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
7627836SJohn.Forte@Sun.COM 		return (1);
7637836SJohn.Forte@Sun.COM 	}
7647836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
7657836SJohn.Forte@Sun.COM 	    gettext("Data PDU In Order"));
7667836SJohn.Forte@Sun.COM 	IMABOOLPRINT(propBool, printOption);
7677836SJohn.Forte@Sun.COM 
7687836SJohn.Forte@Sun.COM 
7697836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
7707836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->defaultTime2Retain;
7717836SJohn.Forte@Sun.COM 	} else {
7727836SJohn.Forte@Sun.COM 		status = IMA_GetDefaultTime2RetainProperties(oid, &propMinMax);
7737836SJohn.Forte@Sun.COM 	}
7747836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
7757836SJohn.Forte@Sun.COM 		printLibError(status);
7767836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
7777836SJohn.Forte@Sun.COM 		return (1);
7787836SJohn.Forte@Sun.COM 	}
7797836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
7807836SJohn.Forte@Sun.COM 	    gettext("Default Time To Retain"));
7817836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
7827836SJohn.Forte@Sun.COM 
7837836SJohn.Forte@Sun.COM 
7847836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
7857836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->defaultTime2Wait;
7867836SJohn.Forte@Sun.COM 	} else {
7877836SJohn.Forte@Sun.COM 		status = IMA_GetDefaultTime2WaitProperties(oid, &propMinMax);
7887836SJohn.Forte@Sun.COM 	}
7897836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
7907836SJohn.Forte@Sun.COM 		printLibError(status);
7917836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
7927836SJohn.Forte@Sun.COM 		return (1);
7937836SJohn.Forte@Sun.COM 	}
7947836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
7957836SJohn.Forte@Sun.COM 	    gettext("Default Time To Wait"));
7967836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
7977836SJohn.Forte@Sun.COM 
7987836SJohn.Forte@Sun.COM 
7997836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8007836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->errorRecoveryLevel;
8017836SJohn.Forte@Sun.COM 	} else {
8027836SJohn.Forte@Sun.COM 		status = IMA_GetErrorRecoveryLevelProperties(oid, &propMinMax);
8037836SJohn.Forte@Sun.COM 	}
8047836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8057836SJohn.Forte@Sun.COM 		printLibError(status);
8067836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8077836SJohn.Forte@Sun.COM 		return (1);
8087836SJohn.Forte@Sun.COM 	}
8097836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
8107836SJohn.Forte@Sun.COM 	    gettext("Error Recovery Level"));
8117836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
8127836SJohn.Forte@Sun.COM 
8137836SJohn.Forte@Sun.COM 
8147836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8157836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->firstBurstLength;
8167836SJohn.Forte@Sun.COM 	} else {
8177836SJohn.Forte@Sun.COM 		status = IMA_GetFirstBurstLengthProperties(oid,
8187836SJohn.Forte@Sun.COM 		    &propMinMax);
8197836SJohn.Forte@Sun.COM 	}
8207836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8217836SJohn.Forte@Sun.COM 		printLibError(status);
8227836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8237836SJohn.Forte@Sun.COM 		return (1);
8247836SJohn.Forte@Sun.COM 	}
8257836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ",
8267836SJohn.Forte@Sun.COM 	    prefix, gettext("First Burst Length"));
8277836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
8287836SJohn.Forte@Sun.COM 
8297836SJohn.Forte@Sun.COM 
8307836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8317836SJohn.Forte@Sun.COM 		propBool.currentValue = connProps->immediateData;
8327836SJohn.Forte@Sun.COM 	} else {
8337836SJohn.Forte@Sun.COM 		status = IMA_GetImmediateDataProperties(oid, &propBool);
8347836SJohn.Forte@Sun.COM 	}
8357836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8367836SJohn.Forte@Sun.COM 		printLibError(status);
8377836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8387836SJohn.Forte@Sun.COM 		return (1);
8397836SJohn.Forte@Sun.COM 	}
8407836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix, gettext("Immediate Data"));
8417836SJohn.Forte@Sun.COM 	IMABOOLPRINT(propBool, printOption);
8427836SJohn.Forte@Sun.COM 
8437836SJohn.Forte@Sun.COM 
8447836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8457836SJohn.Forte@Sun.COM 		propBool.currentValue = connProps->initialR2T;
8467836SJohn.Forte@Sun.COM 	} else {
8477836SJohn.Forte@Sun.COM 		status = IMA_GetInitialR2TProperties(oid, &propBool);
8487836SJohn.Forte@Sun.COM 	}
8497836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8507836SJohn.Forte@Sun.COM 		printLibError(status);
8517836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8527836SJohn.Forte@Sun.COM 		return (1);
8537836SJohn.Forte@Sun.COM 	}
8547836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
8557836SJohn.Forte@Sun.COM 	    gettext("Initial Ready To Transfer (R2T)"));
8567836SJohn.Forte@Sun.COM 	IMABOOLPRINT(propBool, printOption);
8577836SJohn.Forte@Sun.COM 
8587836SJohn.Forte@Sun.COM 
8597836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8607836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->maxBurstLength;
8617836SJohn.Forte@Sun.COM 	} else {
8627836SJohn.Forte@Sun.COM 		status = IMA_GetMaxBurstLengthProperties(oid, &propMinMax);
8637836SJohn.Forte@Sun.COM 	}
8647836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8657836SJohn.Forte@Sun.COM 		printLibError(status);
8667836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8677836SJohn.Forte@Sun.COM 		return (1);
8687836SJohn.Forte@Sun.COM 	}
8697836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix, gettext("Max Burst Length"));
8707836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
8717836SJohn.Forte@Sun.COM 
8727836SJohn.Forte@Sun.COM 
8737836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8747836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->maxOutstandingR2T;
8757836SJohn.Forte@Sun.COM 	} else {
8767836SJohn.Forte@Sun.COM 		status = IMA_GetMaxOutstandingR2TProperties(oid, &propMinMax);
8777836SJohn.Forte@Sun.COM 	}
8787836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8797836SJohn.Forte@Sun.COM 		printLibError(status);
8807836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8817836SJohn.Forte@Sun.COM 		return (1);
8827836SJohn.Forte@Sun.COM 	}
8837836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
8847836SJohn.Forte@Sun.COM 	    gettext("Max Outstanding R2T"));
8857836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
8867836SJohn.Forte@Sun.COM 
8877836SJohn.Forte@Sun.COM 
8887836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
8897836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->maxRecvDataSegmentLength;
8907836SJohn.Forte@Sun.COM 	} else {
8917836SJohn.Forte@Sun.COM 		status = IMA_GetMaxRecvDataSegmentLengthProperties(oid,
8927836SJohn.Forte@Sun.COM 		    &propMinMax);
8937836SJohn.Forte@Sun.COM 	}
8947836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
8957836SJohn.Forte@Sun.COM 		printLibError(status);
8967836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
8977836SJohn.Forte@Sun.COM 		return (1);
8987836SJohn.Forte@Sun.COM 	}
8997836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix,
9007836SJohn.Forte@Sun.COM 	    gettext("Max Receive Data Segment Length"));
9017836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
9027836SJohn.Forte@Sun.COM 
9037836SJohn.Forte@Sun.COM 
9047836SJohn.Forte@Sun.COM 	if (printOption == PRINT_NEGOTIATED_PARAMS) {
9057836SJohn.Forte@Sun.COM 		propMinMax.currentValue = connProps->maxConnections;
9067836SJohn.Forte@Sun.COM 	} else {
9077836SJohn.Forte@Sun.COM 		status = IMA_GetMaxConnectionsProperties(oid, &propMinMax);
9087836SJohn.Forte@Sun.COM 	}
9097836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
9107836SJohn.Forte@Sun.COM 		printLibError(status);
9117836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
9127836SJohn.Forte@Sun.COM 		return (1);
9137836SJohn.Forte@Sun.COM 	}
9147836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s\t%s: ", prefix, gettext("Max Connections"));
9157836SJohn.Forte@Sun.COM 	IMAMINMAXPRINT(propMinMax, printOption);
9167836SJohn.Forte@Sun.COM 
9177836SJohn.Forte@Sun.COM 	(void) IMA_FreeMemory(connProps);
9187836SJohn.Forte@Sun.COM 	return (0);
9197836SJohn.Forte@Sun.COM }
9207836SJohn.Forte@Sun.COM 
9217836SJohn.Forte@Sun.COM /*
9227836SJohn.Forte@Sun.COM  * Print discovery information.
9237836SJohn.Forte@Sun.COM  */
9247836SJohn.Forte@Sun.COM static void
9257836SJohn.Forte@Sun.COM printDiscoveryMethod(char *prefix, IMA_UINT32 discoveryMethodFlags)
9267836SJohn.Forte@Sun.COM {
9277836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s%s: ", prefix, gettext("Discovery Method"));
9287836SJohn.Forte@Sun.COM 	if (discoveryMethodFlags == IMA_TARGET_DISCOVERY_METHOD_UNKNOWN) {
9297836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s\n", gettext("NA"));
9307836SJohn.Forte@Sun.COM 	} else {
9317836SJohn.Forte@Sun.COM 		if (!((discoveryMethodFlags &
9327836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_STATIC) ^
9337836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_STATIC)) {
9347836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s ", gettext("Static"));
9357836SJohn.Forte@Sun.COM 		}
9367836SJohn.Forte@Sun.COM 		if (!((discoveryMethodFlags &
9377836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_SENDTARGETS) ^
9387836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_SENDTARGETS)) {
9397836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s ", gettext("SendTargets"));
9407836SJohn.Forte@Sun.COM 		}
9417836SJohn.Forte@Sun.COM 		if (!((discoveryMethodFlags &
9427836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_ISNS) ^
9437836SJohn.Forte@Sun.COM 		    IMA_TARGET_DISCOVERY_METHOD_ISNS)) {
9447836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s ", gettext("iSNS"));
9457836SJohn.Forte@Sun.COM 		}
9467836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\n");
9477836SJohn.Forte@Sun.COM 	}
9487836SJohn.Forte@Sun.COM }
9497836SJohn.Forte@Sun.COM 
9507836SJohn.Forte@Sun.COM /*
9517836SJohn.Forte@Sun.COM  * printConnectionList - Prints the conection list provided
9527836SJohn.Forte@Sun.COM  */
9537836SJohn.Forte@Sun.COM static void
9547836SJohn.Forte@Sun.COM printConnectionList(char *prefix, IMA_OID_LIST *pConnList)
9557836SJohn.Forte@Sun.COM {
9567836SJohn.Forte@Sun.COM 	IMA_STATUS		imaStatus;
9577836SJohn.Forte@Sun.COM 	int			i;
9587836SJohn.Forte@Sun.COM 	SUN_IMA_CONN_PROPERTIES	*connProps;
9597836SJohn.Forte@Sun.COM 	union {
9607836SJohn.Forte@Sun.COM 		char	ipv4[INET_ADDRSTRLEN+1];
9617836SJohn.Forte@Sun.COM 		char	ipv6[INET6_ADDRSTRLEN+1];
9627836SJohn.Forte@Sun.COM 	} tmp;
9637836SJohn.Forte@Sun.COM 
9647836SJohn.Forte@Sun.COM 	for (i = 0; i < pConnList->oidCount; i++) {
9657836SJohn.Forte@Sun.COM 		imaStatus = SUN_IMA_GetConnProperties(&pConnList->oids[i],
9667836SJohn.Forte@Sun.COM 		    &connProps);
9677836SJohn.Forte@Sun.COM 
9687836SJohn.Forte@Sun.COM 		if (imaStatus != IMA_STATUS_SUCCESS) {
9697836SJohn.Forte@Sun.COM 			continue;
9707836SJohn.Forte@Sun.COM 		}
9717836SJohn.Forte@Sun.COM 
9727836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%sCID: %d\n", prefix,
9737836SJohn.Forte@Sun.COM 		    connProps->connectionID);
9747836SJohn.Forte@Sun.COM 
9757836SJohn.Forte@Sun.COM 		(void) memset(&tmp, 0, sizeof (tmp));
9767836SJohn.Forte@Sun.COM 		if (connProps->local.ipAddress.ipv4Address == IMA_TRUE) {
9777836SJohn.Forte@Sun.COM 			if (inet_ntop(AF_INET,
9787836SJohn.Forte@Sun.COM 			    &connProps->local.ipAddress.ipAddress[0],
9797836SJohn.Forte@Sun.COM 			    &tmp.ipv4[0],
9807836SJohn.Forte@Sun.COM 			    INET_ADDRSTRLEN)) {
9817836SJohn.Forte@Sun.COM 				(void) fprintf(stdout,
9827836SJohn.Forte@Sun.COM 				    "%s  %s: %s:%u\n",
9837836SJohn.Forte@Sun.COM 				    prefix,
9847836SJohn.Forte@Sun.COM 				    gettext("IP address (Local)"),
9857836SJohn.Forte@Sun.COM 				    &tmp.ipv4[0],
9867836SJohn.Forte@Sun.COM 				    ntohs(connProps->local.portNumber));
9877836SJohn.Forte@Sun.COM 			}
9887836SJohn.Forte@Sun.COM 		} else {
9897836SJohn.Forte@Sun.COM 			if (inet_ntop(AF_INET6,
9907836SJohn.Forte@Sun.COM 			    &connProps->local.ipAddress.ipAddress[0],
9917836SJohn.Forte@Sun.COM 			    &tmp.ipv6[0],
9927836SJohn.Forte@Sun.COM 			    INET6_ADDRSTRLEN)) {
9937836SJohn.Forte@Sun.COM 				(void) fprintf(stdout,
9947836SJohn.Forte@Sun.COM 				    "%s  %s: [%s]:%u\n",
9957836SJohn.Forte@Sun.COM 				    prefix,
9967836SJohn.Forte@Sun.COM 				    gettext("IP address (Local)"),
9977836SJohn.Forte@Sun.COM 				    &tmp.ipv6[0],
9987836SJohn.Forte@Sun.COM 				    ntohs(connProps->local.portNumber));
9997836SJohn.Forte@Sun.COM 			}
10007836SJohn.Forte@Sun.COM 		}
10017836SJohn.Forte@Sun.COM 		if (connProps->peer.ipAddress.ipv4Address == IMA_TRUE) {
10027836SJohn.Forte@Sun.COM 			if (inet_ntop(AF_INET,
10037836SJohn.Forte@Sun.COM 			    &connProps->peer.ipAddress.ipAddress[0],
10047836SJohn.Forte@Sun.COM 			    &tmp.ipv4[0],
10057836SJohn.Forte@Sun.COM 			    INET_ADDRSTRLEN)) {
10067836SJohn.Forte@Sun.COM 				(void) fprintf(stdout,
10077836SJohn.Forte@Sun.COM 				    "%s  %s: %s:%u\n",
10087836SJohn.Forte@Sun.COM 				    prefix,
10097836SJohn.Forte@Sun.COM 				    gettext("IP address (Peer)"),
10107836SJohn.Forte@Sun.COM 				    &tmp.ipv4[0],
10117836SJohn.Forte@Sun.COM 				    ntohs(connProps->peer.portNumber));
10127836SJohn.Forte@Sun.COM 			}
10137836SJohn.Forte@Sun.COM 		} else {
10147836SJohn.Forte@Sun.COM 			if (inet_ntop(AF_INET6,
10157836SJohn.Forte@Sun.COM 			    &connProps->peer.ipAddress.ipAddress[0],
10167836SJohn.Forte@Sun.COM 			    &tmp.ipv6[0],
10177836SJohn.Forte@Sun.COM 			    INET6_ADDRSTRLEN)) {
10187836SJohn.Forte@Sun.COM 				(void) fprintf(stdout,
10197836SJohn.Forte@Sun.COM 				    "%s  %s: [%s]:%u\n",
10207836SJohn.Forte@Sun.COM 				    prefix,
10217836SJohn.Forte@Sun.COM 				    gettext("IP address (Peer)"),
10227836SJohn.Forte@Sun.COM 				    &tmp.ipv6[0],
10237836SJohn.Forte@Sun.COM 				    ntohs(connProps->peer.portNumber));
10247836SJohn.Forte@Sun.COM 			}
10257836SJohn.Forte@Sun.COM 		}
10267836SJohn.Forte@Sun.COM 
10277836SJohn.Forte@Sun.COM 		(void) IMA_FreeMemory(connProps);
10287836SJohn.Forte@Sun.COM 	}
10297836SJohn.Forte@Sun.COM }
10307836SJohn.Forte@Sun.COM 
10317836SJohn.Forte@Sun.COM /*
10327836SJohn.Forte@Sun.COM  * Set login parameters on a target or initiator
10337836SJohn.Forte@Sun.COM  */
10347836SJohn.Forte@Sun.COM static int
10357836SJohn.Forte@Sun.COM setLoginParameter(IMA_OID oid, int optval, char *optarg)
10367836SJohn.Forte@Sun.COM {
10377836SJohn.Forte@Sun.COM 	IMA_STATUS status = IMA_STATUS_SUCCESS;
10387836SJohn.Forte@Sun.COM 	IMA_UINT uintValue;
10397836SJohn.Forte@Sun.COM 	IMA_BOOL boolValue;
10407836SJohn.Forte@Sun.COM 	SUN_IMA_DIGEST_ALGORITHM digestAlgList[1];
10417836SJohn.Forte@Sun.COM 	IMA_MIN_MAX_VALUE propMinMax;
10427836SJohn.Forte@Sun.COM 	char *endptr;
10437836SJohn.Forte@Sun.COM 
10447836SJohn.Forte@Sun.COM 	/*
10457836SJohn.Forte@Sun.COM 	 * for clarity, there are two switch statements
10467836SJohn.Forte@Sun.COM 	 * The first loads the variable and the second
10477836SJohn.Forte@Sun.COM 	 * calls the appropriate API
10487836SJohn.Forte@Sun.COM 	 */
10497836SJohn.Forte@Sun.COM 	switch (optval) {
10507836SJohn.Forte@Sun.COM 		case DATA_SEQ_IN_ORDER:
10517836SJohn.Forte@Sun.COM 		case IMMEDIATE_DATA:
10527836SJohn.Forte@Sun.COM 		case INITIAL_R2T:
10537836SJohn.Forte@Sun.COM 		case DATA_PDU_IN_ORDER:
10547836SJohn.Forte@Sun.COM 			/* implement 'default'? */
10557836SJohn.Forte@Sun.COM 			if (strcasecmp(optarg, "yes") == 0) {
10567836SJohn.Forte@Sun.COM 				boolValue = IMA_TRUE;
10577836SJohn.Forte@Sun.COM 			} else if (strcasecmp(optarg, "no") == 0) {
10587836SJohn.Forte@Sun.COM 				boolValue = IMA_FALSE;
10597836SJohn.Forte@Sun.COM 			} else {
10607836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
10617836SJohn.Forte@Sun.COM 				    cmdName,
10627836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
10637836SJohn.Forte@Sun.COM 				    optarg);
10647836SJohn.Forte@Sun.COM 				return (1);
10657836SJohn.Forte@Sun.COM 			}
10667836SJohn.Forte@Sun.COM 			break;
10677836SJohn.Forte@Sun.COM 		case DEFAULT_TIME_2_RETAIN:
10687836SJohn.Forte@Sun.COM 		case DEFAULT_TIME_2_WAIT:
10697836SJohn.Forte@Sun.COM 			errno = 0;
10707836SJohn.Forte@Sun.COM 			uintValue = strtoul(optarg, &endptr, 0);
10717836SJohn.Forte@Sun.COM 			if (*endptr != '\0' || errno != 0) {
10727836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
10737836SJohn.Forte@Sun.COM 				    cmdName,
10747836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
10757836SJohn.Forte@Sun.COM 				    optarg);
10767836SJohn.Forte@Sun.COM 				return (1);
10777836SJohn.Forte@Sun.COM 			}
10787836SJohn.Forte@Sun.COM 			if (uintValue > 3600) {
10797836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
10807836SJohn.Forte@Sun.COM 				    cmdName,
10817836SJohn.Forte@Sun.COM gettext("value must be between 0 and 3600"));
10827836SJohn.Forte@Sun.COM 				return (1);
10837836SJohn.Forte@Sun.COM 			}
10847836SJohn.Forte@Sun.COM 			break;
10857836SJohn.Forte@Sun.COM 		case FIRST_BURST_LENGTH:
10867836SJohn.Forte@Sun.COM 		case MAX_BURST_LENGTH:
10877836SJohn.Forte@Sun.COM 		case MAX_RECV_DATA_SEG_LEN:
10887836SJohn.Forte@Sun.COM 			errno = 0;
10897836SJohn.Forte@Sun.COM 			/* implement 'default'? */
10907836SJohn.Forte@Sun.COM 			uintValue = strtoul(optarg, &endptr, 0);
10917836SJohn.Forte@Sun.COM 			if (*endptr != '\0' || errno != 0) {
10927836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
10937836SJohn.Forte@Sun.COM 				    cmdName,
10947836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
10957836SJohn.Forte@Sun.COM 				    optarg);
10967836SJohn.Forte@Sun.COM 				return (1);
10977836SJohn.Forte@Sun.COM 			}
10987836SJohn.Forte@Sun.COM 			if (uintValue < 512 || uintValue > 16777215) {
10997836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
11007836SJohn.Forte@Sun.COM 				    cmdName,
11017836SJohn.Forte@Sun.COM gettext("value must be between 512 and 16777215"));
11027836SJohn.Forte@Sun.COM 				return (1);
11037836SJohn.Forte@Sun.COM 			}
11047836SJohn.Forte@Sun.COM 			break;
11057836SJohn.Forte@Sun.COM 		case MAX_OUTSTANDING_R2T:
11067836SJohn.Forte@Sun.COM 			errno = 0;
11077836SJohn.Forte@Sun.COM 			uintValue = strtoul(optarg, &endptr, 0);
11087836SJohn.Forte@Sun.COM 			if (*endptr != '\0' || errno != 0) {
11097836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
11107836SJohn.Forte@Sun.COM 				    cmdName,
11117836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
11127836SJohn.Forte@Sun.COM 				    optarg);
11137836SJohn.Forte@Sun.COM 				return (1);
11147836SJohn.Forte@Sun.COM 			}
11157836SJohn.Forte@Sun.COM 			if (uintValue < 1 || uintValue > 65535) {
11167836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
11177836SJohn.Forte@Sun.COM 				    cmdName,
11187836SJohn.Forte@Sun.COM gettext("value must be between 1 and 65535"));
11197836SJohn.Forte@Sun.COM 				return (1);
11207836SJohn.Forte@Sun.COM 			}
11217836SJohn.Forte@Sun.COM 			break;
11227836SJohn.Forte@Sun.COM 		case HEADER_DIGEST:
11237836SJohn.Forte@Sun.COM 		case DATA_DIGEST:
11247836SJohn.Forte@Sun.COM 			if (strcasecmp(optarg, "none") == 0) {
11257836SJohn.Forte@Sun.COM 				digestAlgList[0] = SUN_IMA_DIGEST_NONE;
11267836SJohn.Forte@Sun.COM 			} else if (strcasecmp(optarg, "CRC32") == 0) {
11277836SJohn.Forte@Sun.COM 				digestAlgList[0] = SUN_IMA_DIGEST_CRC32;
11287836SJohn.Forte@Sun.COM 			} else {
11297836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
11307836SJohn.Forte@Sun.COM 				    cmdName,
11317836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
11327836SJohn.Forte@Sun.COM 				    optarg);
11337836SJohn.Forte@Sun.COM 				return (1);
11347836SJohn.Forte@Sun.COM 			}
11357836SJohn.Forte@Sun.COM 			break;
11367836SJohn.Forte@Sun.COM 		case MAX_CONNECTIONS:
11377836SJohn.Forte@Sun.COM 			errno = 0;
11387836SJohn.Forte@Sun.COM 			uintValue = strtoul(optarg, &endptr, 0);
11397836SJohn.Forte@Sun.COM 			if (*endptr != '\0' || errno != 0) {
11407836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
11417836SJohn.Forte@Sun.COM 				    cmdName,
11427836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
11437836SJohn.Forte@Sun.COM 				    optarg);
11447836SJohn.Forte@Sun.COM 				return (1);
11457836SJohn.Forte@Sun.COM 			}
11467836SJohn.Forte@Sun.COM 			if (uintValue < 1 || uintValue > 256) {
11477836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
11487836SJohn.Forte@Sun.COM 				    cmdName,
11497836SJohn.Forte@Sun.COM gettext("value must be between 1 and 256"));
11507836SJohn.Forte@Sun.COM 				return (1);
11517836SJohn.Forte@Sun.COM 			}
11527836SJohn.Forte@Sun.COM 			break;
11537836SJohn.Forte@Sun.COM 		case ERROR_RECOVERY_LEVEL:
11547836SJohn.Forte@Sun.COM 			errno = 0;
11557836SJohn.Forte@Sun.COM 			uintValue = strtoul(optarg, &endptr, 0);
11567836SJohn.Forte@Sun.COM 			if (*endptr != '\0' || errno != 0) {
11577836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s - %s\n",
11587836SJohn.Forte@Sun.COM 				    cmdName,
11597836SJohn.Forte@Sun.COM 				    gettext("invalid option argument"),
11607836SJohn.Forte@Sun.COM 				    optarg);
11617836SJohn.Forte@Sun.COM 				return (1);
11627836SJohn.Forte@Sun.COM 			}
11637836SJohn.Forte@Sun.COM 			if (uintValue > 2) {
11647836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
11657836SJohn.Forte@Sun.COM 				    cmdName,
11667836SJohn.Forte@Sun.COM gettext("value must be between 0 and 2"));
11677836SJohn.Forte@Sun.COM 				return (1);
11687836SJohn.Forte@Sun.COM 			}
11697836SJohn.Forte@Sun.COM 			break;
11707836SJohn.Forte@Sun.COM 		default:
11717836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %c: %s\n",
11727836SJohn.Forte@Sun.COM 			    cmdName, optval, gettext("unknown option"));
11737836SJohn.Forte@Sun.COM 			return (1);
11747836SJohn.Forte@Sun.COM 	}
11757836SJohn.Forte@Sun.COM 
11767836SJohn.Forte@Sun.COM 	switch (optval) {
11777836SJohn.Forte@Sun.COM 		case DATA_PDU_IN_ORDER:
11787836SJohn.Forte@Sun.COM 			status = IMA_SetDataPduInOrder(oid, boolValue);
11797836SJohn.Forte@Sun.COM 			break;
11807836SJohn.Forte@Sun.COM 		case DATA_SEQ_IN_ORDER:
11817836SJohn.Forte@Sun.COM 			status = IMA_SetDataSequenceInOrder(oid, boolValue);
11827836SJohn.Forte@Sun.COM 			break;
11837836SJohn.Forte@Sun.COM 		case DEFAULT_TIME_2_RETAIN:
11847836SJohn.Forte@Sun.COM 			status = IMA_SetDefaultTime2Retain(oid, uintValue);
11857836SJohn.Forte@Sun.COM 			break;
11867836SJohn.Forte@Sun.COM 		case DEFAULT_TIME_2_WAIT:
11877836SJohn.Forte@Sun.COM 			status = IMA_SetDefaultTime2Wait(oid, uintValue);
11887836SJohn.Forte@Sun.COM 			break;
11897836SJohn.Forte@Sun.COM 		case FIRST_BURST_LENGTH:
11907836SJohn.Forte@Sun.COM 			status = IMA_SetFirstBurstLength(oid, uintValue);
11917836SJohn.Forte@Sun.COM 
11927836SJohn.Forte@Sun.COM 			/*
11937836SJohn.Forte@Sun.COM 			 * If this call fails check to see if it's because
11947836SJohn.Forte@Sun.COM 			 * the requested value is > than maxBurstLength
11957836SJohn.Forte@Sun.COM 			 */
11967836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
11977836SJohn.Forte@Sun.COM 				status = IMA_GetMaxBurstLengthProperties(oid,
11987836SJohn.Forte@Sun.COM 				    &propMinMax);
11997836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
12007836SJohn.Forte@Sun.COM 					printLibError(status);
12017836SJohn.Forte@Sun.COM 					return (1);
12027836SJohn.Forte@Sun.COM 				}
12037836SJohn.Forte@Sun.COM 				if (uintValue > propMinMax.currentValue) {
12047836SJohn.Forte@Sun.COM 					(void) fprintf(stderr,
12057836SJohn.Forte@Sun.COM 					    "%s: %s\n", cmdName,
12067836SJohn.Forte@Sun.COM 					    gettext("firstBurstLength must " \
12077836SJohn.Forte@Sun.COM 					    "be less than or equal to than " \
12087836SJohn.Forte@Sun.COM 					    "maxBurstLength"));
12097836SJohn.Forte@Sun.COM 				}
12107836SJohn.Forte@Sun.COM 				return (1);
12117836SJohn.Forte@Sun.COM 			}
12127836SJohn.Forte@Sun.COM 
12137836SJohn.Forte@Sun.COM 			break;
12147836SJohn.Forte@Sun.COM 		case IMMEDIATE_DATA:
12157836SJohn.Forte@Sun.COM 			status = IMA_SetImmediateData(oid, boolValue);
12167836SJohn.Forte@Sun.COM 			break;
12177836SJohn.Forte@Sun.COM 		case INITIAL_R2T:
12187836SJohn.Forte@Sun.COM 			status = IMA_SetInitialR2T(oid, boolValue);
12197836SJohn.Forte@Sun.COM 			break;
12207836SJohn.Forte@Sun.COM 		case MAX_BURST_LENGTH:
12217836SJohn.Forte@Sun.COM 			status = IMA_SetMaxBurstLength(oid, uintValue);
12227836SJohn.Forte@Sun.COM 			/*
12237836SJohn.Forte@Sun.COM 			 * If this call fails check to see if it's because
12247836SJohn.Forte@Sun.COM 			 * the requested value is < than firstBurstLength
12257836SJohn.Forte@Sun.COM 			 */
12267836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
12277836SJohn.Forte@Sun.COM 				status = IMA_GetFirstBurstLengthProperties(oid,
12287836SJohn.Forte@Sun.COM 				    &propMinMax);
12297836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
12307836SJohn.Forte@Sun.COM 					printLibError(status);
12317836SJohn.Forte@Sun.COM 					return (1);
12327836SJohn.Forte@Sun.COM 				}
12337836SJohn.Forte@Sun.COM 				if (uintValue < propMinMax.currentValue) {
12347836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
12357836SJohn.Forte@Sun.COM 					    cmdName,
12367836SJohn.Forte@Sun.COM 					    gettext("maxBurstLength must be " \
12377836SJohn.Forte@Sun.COM 					    "greater than or equal to " \
12387836SJohn.Forte@Sun.COM 					    "firstBurstLength"));
12397836SJohn.Forte@Sun.COM 				}
12407836SJohn.Forte@Sun.COM 				return (1);
12417836SJohn.Forte@Sun.COM 			}
12427836SJohn.Forte@Sun.COM 			break;
12437836SJohn.Forte@Sun.COM 
12447836SJohn.Forte@Sun.COM 		case MAX_OUTSTANDING_R2T:
12457836SJohn.Forte@Sun.COM 			status = IMA_SetMaxOutstandingR2T(oid, uintValue);
12467836SJohn.Forte@Sun.COM 			break;
12477836SJohn.Forte@Sun.COM 		case MAX_RECV_DATA_SEG_LEN:
12487836SJohn.Forte@Sun.COM 			status = IMA_SetMaxRecvDataSegmentLength(oid,
12497836SJohn.Forte@Sun.COM 			    uintValue);
12507836SJohn.Forte@Sun.COM 			break;
12517836SJohn.Forte@Sun.COM 		case HEADER_DIGEST:
12527836SJohn.Forte@Sun.COM 			status = SUN_IMA_SetHeaderDigest(oid, 1,
12537836SJohn.Forte@Sun.COM 			    &digestAlgList[0]);
12547836SJohn.Forte@Sun.COM 			break;
12557836SJohn.Forte@Sun.COM 		case DATA_DIGEST:
12567836SJohn.Forte@Sun.COM 			status = SUN_IMA_SetDataDigest(oid, 1,
12577836SJohn.Forte@Sun.COM 			    &digestAlgList[0]);
12587836SJohn.Forte@Sun.COM 			break;
12597836SJohn.Forte@Sun.COM 		case MAX_CONNECTIONS:
12607836SJohn.Forte@Sun.COM 			status = IMA_SetMaxConnections(oid, uintValue);
12617836SJohn.Forte@Sun.COM 			break;
12627836SJohn.Forte@Sun.COM 		case ERROR_RECOVERY_LEVEL:
12637836SJohn.Forte@Sun.COM 			status = IMA_SetErrorRecoveryLevel(oid, uintValue);
12647836SJohn.Forte@Sun.COM 			break;
12657836SJohn.Forte@Sun.COM 	}
12667836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
12677836SJohn.Forte@Sun.COM 		printLibError(status);
12687836SJohn.Forte@Sun.COM 		return (1);
12697836SJohn.Forte@Sun.COM 	}
12707836SJohn.Forte@Sun.COM 	return (0);
12717836SJohn.Forte@Sun.COM }
12727836SJohn.Forte@Sun.COM 
12737836SJohn.Forte@Sun.COM static void
12747836SJohn.Forte@Sun.COM printDigestAlgorithm(SUN_IMA_DIGEST_ALGORITHM_VALUE *digestAlgorithms,
12757836SJohn.Forte@Sun.COM     int printOption)
12767836SJohn.Forte@Sun.COM {
12777836SJohn.Forte@Sun.COM 	int i;
12787836SJohn.Forte@Sun.COM 
12797836SJohn.Forte@Sun.COM 	if (printOption == PRINT_CONFIGURED_PARAMS) {
12807836SJohn.Forte@Sun.COM 		for (i = 0; i < digestAlgorithms->defaultAlgorithmCount; i++) {
12817836SJohn.Forte@Sun.COM 			if (i > 0) {
12827836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "|");
12837836SJohn.Forte@Sun.COM 			}
12847836SJohn.Forte@Sun.COM 			switch (digestAlgorithms->defaultAlgorithms[i]) {
12857836SJohn.Forte@Sun.COM 				case SUN_IMA_DIGEST_NONE:
12867836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
12877836SJohn.Forte@Sun.COM 					    gettext("NONE"));
12887836SJohn.Forte@Sun.COM 					break;
12897836SJohn.Forte@Sun.COM 				case SUN_IMA_DIGEST_CRC32:
12907836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
12917836SJohn.Forte@Sun.COM 					    gettext("CRC32"));
12927836SJohn.Forte@Sun.COM 					break;
12937836SJohn.Forte@Sun.COM 				default:
12947836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
12957836SJohn.Forte@Sun.COM 					    gettext("Unknown"));
12967836SJohn.Forte@Sun.COM 					break;
12977836SJohn.Forte@Sun.COM 			}
12987836SJohn.Forte@Sun.COM 		}
12997836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "/");
13007836SJohn.Forte@Sun.COM 		if (digestAlgorithms->currentValid == IMA_TRUE) {
13017836SJohn.Forte@Sun.COM 			for (i = 0;
13027836SJohn.Forte@Sun.COM 			    i < digestAlgorithms->currentAlgorithmCount; i++) {
13037836SJohn.Forte@Sun.COM 				if (i > 0) {
13047836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "|");
13057836SJohn.Forte@Sun.COM 				}
13067836SJohn.Forte@Sun.COM 				switch (digestAlgorithms->
13077836SJohn.Forte@Sun.COM 				    currentAlgorithms[i]) {
13087836SJohn.Forte@Sun.COM 					case SUN_IMA_DIGEST_NONE:
13097836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
13107836SJohn.Forte@Sun.COM 						    gettext("NONE"));
13117836SJohn.Forte@Sun.COM 						break;
13127836SJohn.Forte@Sun.COM 					case SUN_IMA_DIGEST_CRC32:
13137836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
13147836SJohn.Forte@Sun.COM 						    gettext("CRC32"));
13157836SJohn.Forte@Sun.COM 						break;
13167836SJohn.Forte@Sun.COM 					default:
13177836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
13187836SJohn.Forte@Sun.COM 						    gettext("Unknown"));
13197836SJohn.Forte@Sun.COM 						break;
13207836SJohn.Forte@Sun.COM 				}
13217836SJohn.Forte@Sun.COM 			}
13227836SJohn.Forte@Sun.COM 		} else {
13237836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "-");
13247836SJohn.Forte@Sun.COM 		}
13257836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\n");
13267836SJohn.Forte@Sun.COM 	} else if (printOption == PRINT_NEGOTIATED_PARAMS) {
13277836SJohn.Forte@Sun.COM 
13287836SJohn.Forte@Sun.COM 		if (digestAlgorithms->negotiatedValid == IMA_TRUE) {
13297836SJohn.Forte@Sun.COM 			for (i = 0;
13307836SJohn.Forte@Sun.COM 			    i < digestAlgorithms->negotiatedAlgorithmCount;
13317836SJohn.Forte@Sun.COM 			    i++) {
13327836SJohn.Forte@Sun.COM 				if (i > 0) {
13337836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "|");
13347836SJohn.Forte@Sun.COM 				}
13357836SJohn.Forte@Sun.COM 				switch (digestAlgorithms->
13367836SJohn.Forte@Sun.COM 				    negotiatedAlgorithms[i]) {
13377836SJohn.Forte@Sun.COM 					case SUN_IMA_DIGEST_NONE:
13387836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
13397836SJohn.Forte@Sun.COM 						    gettext("NONE"));
13407836SJohn.Forte@Sun.COM 						break;
13417836SJohn.Forte@Sun.COM 					case SUN_IMA_DIGEST_CRC32:
13427836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
13437836SJohn.Forte@Sun.COM 						    gettext("CRC32"));
13447836SJohn.Forte@Sun.COM 						break;
13457836SJohn.Forte@Sun.COM 					default:
13467836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
13477836SJohn.Forte@Sun.COM 						    gettext("Unknown"));
13487836SJohn.Forte@Sun.COM 						break;
13497836SJohn.Forte@Sun.COM 				}
13507836SJohn.Forte@Sun.COM 			}
13517836SJohn.Forte@Sun.COM 		} else {
13527836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "-");
13537836SJohn.Forte@Sun.COM 		}
13547836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\n");
13557836SJohn.Forte@Sun.COM 	}
13567836SJohn.Forte@Sun.COM }
13577836SJohn.Forte@Sun.COM 
13587836SJohn.Forte@Sun.COM static int
13597836SJohn.Forte@Sun.COM setLoginParameters(IMA_OID oid, char *optarg)
13607836SJohn.Forte@Sun.COM {
13617836SJohn.Forte@Sun.COM 	char keyp[MAXOPTARGLEN];
13627836SJohn.Forte@Sun.COM 	char valp[MAXOPTARGLEN];
13637836SJohn.Forte@Sun.COM 	int key;
13647836SJohn.Forte@Sun.COM 	char *nameValueString, *indexp, *delim = NULL;
13657836SJohn.Forte@Sun.COM 
13667836SJohn.Forte@Sun.COM 	if ((nameValueString = strdup(optarg)) == NULL) {
13677836SJohn.Forte@Sun.COM 		if (errno == ENOMEM) {
13687836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
13697836SJohn.Forte@Sun.COM 			    cmdName, strerror(errno));
13707836SJohn.Forte@Sun.COM 		} else {
13717836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n", cmdName,
13727836SJohn.Forte@Sun.COM 			    gettext("unknown error"));
13737836SJohn.Forte@Sun.COM 		}
13747836SJohn.Forte@Sun.COM 		return (1);
13757836SJohn.Forte@Sun.COM 	}
13767836SJohn.Forte@Sun.COM 
13777836SJohn.Forte@Sun.COM 	indexp = nameValueString;
13787836SJohn.Forte@Sun.COM 
13797836SJohn.Forte@Sun.COM 	/*
13807836SJohn.Forte@Sun.COM 	 * Retrieve all login params from option argument
13817836SJohn.Forte@Sun.COM 	 * Syntax <key=value,...>
13827836SJohn.Forte@Sun.COM 	 */
13837836SJohn.Forte@Sun.COM 	while (indexp) {
13847836SJohn.Forte@Sun.COM 		if (delim = strchr(indexp, ',')) {
13857836SJohn.Forte@Sun.COM 			delim[0] = '\0';
13867836SJohn.Forte@Sun.COM 		}
13877836SJohn.Forte@Sun.COM 		(void) memset(keyp, 0, sizeof (keyp));
13887836SJohn.Forte@Sun.COM 		(void) memset(valp, 0, sizeof (valp));
13897836SJohn.Forte@Sun.COM 		if (sscanf(indexp, gettext("%[^=]=%s"), keyp, valp) != 2) {
13907836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s: %s\n", cmdName,
13917836SJohn.Forte@Sun.COM 			    gettext("Unknown param"), indexp);
13927836SJohn.Forte@Sun.COM 			return (1);
13937836SJohn.Forte@Sun.COM 		}
13947836SJohn.Forte@Sun.COM 		if ((key = getLoginParam(keyp)) == -1) {
13957836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s: %s\n", cmdName,
13967836SJohn.Forte@Sun.COM 			    gettext("Unknown key"), keyp);
13977836SJohn.Forte@Sun.COM 			return (1);
13987836SJohn.Forte@Sun.COM 		}
13997836SJohn.Forte@Sun.COM 		if (setLoginParameter(oid, key, valp) != 0) {
14007836SJohn.Forte@Sun.COM 			return (1);
14017836SJohn.Forte@Sun.COM 		}
14027836SJohn.Forte@Sun.COM 		if (delim) {
14037836SJohn.Forte@Sun.COM 			indexp = delim + 1;
14047836SJohn.Forte@Sun.COM 		} else {
14057836SJohn.Forte@Sun.COM 			indexp = NULL;
14067836SJohn.Forte@Sun.COM 		}
14077836SJohn.Forte@Sun.COM 	}
14087836SJohn.Forte@Sun.COM 
14097836SJohn.Forte@Sun.COM 	return (0);
14107836SJohn.Forte@Sun.COM }
14117836SJohn.Forte@Sun.COM 
14127836SJohn.Forte@Sun.COM /*
14137836SJohn.Forte@Sun.COM  * Print logical unit information for a specific target
14147836SJohn.Forte@Sun.COM  */
14157836SJohn.Forte@Sun.COM static void
14167836SJohn.Forte@Sun.COM printTargetLuns(IMA_OID_LIST * lunList)
14177836SJohn.Forte@Sun.COM {
14187836SJohn.Forte@Sun.COM 	int	j;
14197836SJohn.Forte@Sun.COM 	IMA_STATUS status;
14207836SJohn.Forte@Sun.COM 	SUN_IMA_LU_PROPERTIES	lunProps;
14217836SJohn.Forte@Sun.COM 
14227836SJohn.Forte@Sun.COM 	for (j = 0; j < lunList->oidCount; j++) {
14237836SJohn.Forte@Sun.COM 		status = SUN_IMA_GetLuProperties(lunList->oids[j],
14247836SJohn.Forte@Sun.COM 		    &lunProps);
14257836SJohn.Forte@Sun.COM 		if (!IMA_SUCCESS(status)) {
14267836SJohn.Forte@Sun.COM 			printLibError(status);
14277836SJohn.Forte@Sun.COM 			return;
14287836SJohn.Forte@Sun.COM 		}
14297836SJohn.Forte@Sun.COM 
14307836SJohn.Forte@Sun.COM 		if (lunProps.imaProps.osDeviceNameValid == IMA_TRUE) {
14317836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "\tLUN: %lld\n",
14327836SJohn.Forte@Sun.COM 			    lunProps.imaProps.targetLun);
14337836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "\t     Vendor:  %s\n",
14347836SJohn.Forte@Sun.COM 			    lunProps.vendorId);
14357836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "\t     Product: %s\n",
14367836SJohn.Forte@Sun.COM 			    lunProps.productId);
14377836SJohn.Forte@Sun.COM 			(void) fprintf(stdout,
14387836SJohn.Forte@Sun.COM 			    gettext("\t     OS Device Name: %ws\n"),
14397836SJohn.Forte@Sun.COM 			    lunProps.imaProps.osDeviceName);
14407836SJohn.Forte@Sun.COM 		}
14417836SJohn.Forte@Sun.COM 	}
14427836SJohn.Forte@Sun.COM }
14437836SJohn.Forte@Sun.COM 
14447836SJohn.Forte@Sun.COM /*
14457836SJohn.Forte@Sun.COM  * Retrieve CHAP secret from input
14467836SJohn.Forte@Sun.COM  */
14477836SJohn.Forte@Sun.COM static int
14487836SJohn.Forte@Sun.COM getSecret(char *secret, int *secretLen, int minSecretLen, int maxSecretLen)
14497836SJohn.Forte@Sun.COM {
14507836SJohn.Forte@Sun.COM 	char *chapSecret;
14517836SJohn.Forte@Sun.COM 
14527836SJohn.Forte@Sun.COM 	/* get password */
14537836SJohn.Forte@Sun.COM 	chapSecret = getpassphrase(gettext("Enter secret:"));
14547836SJohn.Forte@Sun.COM 
14557836SJohn.Forte@Sun.COM 	if (strlen(chapSecret) > maxSecretLen) {
14567836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s %d\n", cmdName,
14577836SJohn.Forte@Sun.COM 		    gettext("secret too long, maximum length is"),
14587836SJohn.Forte@Sun.COM 		    maxSecretLen);
14597836SJohn.Forte@Sun.COM 		*secret = NULL;
14607836SJohn.Forte@Sun.COM 		return (1);
14617836SJohn.Forte@Sun.COM 	}
14627836SJohn.Forte@Sun.COM 
14637836SJohn.Forte@Sun.COM 	if (strlen(chapSecret) < minSecretLen) {
14647836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s %d\n", cmdName,
14657836SJohn.Forte@Sun.COM 		    gettext("secret too short, minimum length is"),
14667836SJohn.Forte@Sun.COM 		    minSecretLen);
14677836SJohn.Forte@Sun.COM 		*secret = NULL;
14687836SJohn.Forte@Sun.COM 		return (1);
14697836SJohn.Forte@Sun.COM 	}
14707836SJohn.Forte@Sun.COM 
14717836SJohn.Forte@Sun.COM 	(void) strcpy(secret, chapSecret);
14727836SJohn.Forte@Sun.COM 
14737836SJohn.Forte@Sun.COM 	chapSecret = getpassphrase(gettext("Re-enter secret:"));
14747836SJohn.Forte@Sun.COM 	if (strcmp(secret, chapSecret) != 0) {
14757836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n", cmdName,
14767836SJohn.Forte@Sun.COM 		    gettext("secrets do not match, secret not changed"));
14777836SJohn.Forte@Sun.COM 		*secret = NULL;
14787836SJohn.Forte@Sun.COM 		return (1);
14797836SJohn.Forte@Sun.COM 	}
14807836SJohn.Forte@Sun.COM 	*secretLen = strlen(chapSecret);
14817836SJohn.Forte@Sun.COM 	return (0);
14827836SJohn.Forte@Sun.COM }
14837836SJohn.Forte@Sun.COM 
14847836SJohn.Forte@Sun.COM /*
14857836SJohn.Forte@Sun.COM  * Lists the discovery attributes
14867836SJohn.Forte@Sun.COM  */
14877836SJohn.Forte@Sun.COM static int
14887836SJohn.Forte@Sun.COM listDiscovery(int *funcRet)
14897836SJohn.Forte@Sun.COM {
14907836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
14917836SJohn.Forte@Sun.COM 	IMA_DISCOVERY_PROPERTIES discProps;
14927836SJohn.Forte@Sun.COM 	int ret;
14937836SJohn.Forte@Sun.COM 	IMA_STATUS status;
14947836SJohn.Forte@Sun.COM 
14957836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
14967836SJohn.Forte@Sun.COM 
14977836SJohn.Forte@Sun.COM 
14987836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
14997836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
15007836SJohn.Forte@Sun.COM 	if (ret > 0) {
15017836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
15027836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
15037836SJohn.Forte@Sun.COM 	}
15047836SJohn.Forte@Sun.COM 
15057836SJohn.Forte@Sun.COM 	if (ret != 0) {
15067836SJohn.Forte@Sun.COM 		return (ret);
15077836SJohn.Forte@Sun.COM 	}
15087836SJohn.Forte@Sun.COM 
15097836SJohn.Forte@Sun.COM 	/* Get discovery attributes from IMA */
15107836SJohn.Forte@Sun.COM 	status = IMA_GetDiscoveryProperties(initiatorOid, &discProps);
15117836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
15127836SJohn.Forte@Sun.COM 		printLibError(status);
15137836SJohn.Forte@Sun.COM 		*funcRet = 1;
15147836SJohn.Forte@Sun.COM 		return (ret);
15157836SJohn.Forte@Sun.COM 	}
15167836SJohn.Forte@Sun.COM 
15177836SJohn.Forte@Sun.COM 
15187836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s:\n", "Discovery");
15197836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\tStatic: %s\n",
15207836SJohn.Forte@Sun.COM 	    discProps.staticDiscoveryEnabled == IMA_TRUE ? \
15217836SJohn.Forte@Sun.COM 	    gettext("enabled") : gettext("disabled"));
15227836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\tSend Targets: %s\n",
15237836SJohn.Forte@Sun.COM 	    discProps.sendTargetsDiscoveryEnabled == IMA_TRUE ? \
15247836SJohn.Forte@Sun.COM 	    gettext("enabled") : gettext("disabled"));
15257836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\tiSNS: %s\n",
15267836SJohn.Forte@Sun.COM 	    discProps.iSnsDiscoveryEnabled == IMA_TRUE ? \
15277836SJohn.Forte@Sun.COM 	    gettext("enabled") : gettext("disabled"));
15287836SJohn.Forte@Sun.COM 
15297836SJohn.Forte@Sun.COM 	return (0);
15307836SJohn.Forte@Sun.COM }
15317836SJohn.Forte@Sun.COM 
15327836SJohn.Forte@Sun.COM /*
15337836SJohn.Forte@Sun.COM  * Print all initiator node attributes
15347836SJohn.Forte@Sun.COM  */
15357836SJohn.Forte@Sun.COM static int
15367836SJohn.Forte@Sun.COM listNode(int *funcRet)
15377836SJohn.Forte@Sun.COM {
15387836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
15397836SJohn.Forte@Sun.COM 	IMA_NODE_PROPERTIES nodeProps;
15407836SJohn.Forte@Sun.COM 	IMA_STATUS status;
15417836SJohn.Forte@Sun.COM 	int ret;
15427836SJohn.Forte@Sun.COM 	IMA_UINT maxEntries = MAX_AUTH_METHODS;
15437836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD	methodList[MAX_AUTH_METHODS];
15447836SJohn.Forte@Sun.COM 	SUN_IMA_RADIUS_CONFIG radiusConfig;
15457836SJohn.Forte@Sun.COM 	SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms;
15467836SJohn.Forte@Sun.COM 	IMA_BOOL radiusAccess;
15477836SJohn.Forte@Sun.COM 
15487836SJohn.Forte@Sun.COM 	int i;
15497836SJohn.Forte@Sun.COM 
15507836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
15517836SJohn.Forte@Sun.COM 
15527836SJohn.Forte@Sun.COM 	ret = getNodeProps(&nodeProps);
15537836SJohn.Forte@Sun.COM 	if (ret != 0) {
15547836SJohn.Forte@Sun.COM 		return (ret);
15557836SJohn.Forte@Sun.COM 	}
15567836SJohn.Forte@Sun.COM 
15577836SJohn.Forte@Sun.COM 	if (nodeProps.nameValid == IMA_FALSE) {
15587836SJohn.Forte@Sun.COM 		return (INVALID_NODE_NAME);
15597836SJohn.Forte@Sun.COM 	}
15607836SJohn.Forte@Sun.COM 
15617836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
15627836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
15637836SJohn.Forte@Sun.COM 	if (ret > 0) {
15647836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
15657836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
15667836SJohn.Forte@Sun.COM 	}
15677836SJohn.Forte@Sun.COM 
15687836SJohn.Forte@Sun.COM 	if (ret != 0) {
15697836SJohn.Forte@Sun.COM 		return (ret);
15707836SJohn.Forte@Sun.COM 	}
15717836SJohn.Forte@Sun.COM 	/* Begin output */
15727836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, gettext("%s: %ws\n"),
15737836SJohn.Forte@Sun.COM 	    gettext("Initiator node name"),
15747836SJohn.Forte@Sun.COM 	    nodeProps.name);
15757836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, gettext("Initiator node alias: "));
15767836SJohn.Forte@Sun.COM 	if (nodeProps.aliasValid == IMA_TRUE) {
15777836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, gettext("%ws\n"), nodeProps.alias);
15787836SJohn.Forte@Sun.COM 	} else {
15797836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s\n", "-");
15807836SJohn.Forte@Sun.COM 	}
15817836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\t%s:\n",
15827836SJohn.Forte@Sun.COM 	    gettext("Login Parameters (Default/Configured)"));
15837836SJohn.Forte@Sun.COM 
15847836SJohn.Forte@Sun.COM 	/* Get Digest configuration */
15857836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetHeaderDigest(initiatorOid, &digestAlgorithms);
15867836SJohn.Forte@Sun.COM 	if (IMA_SUCCESS(status)) {
15877836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\t\t%s: ", gettext("Header Digest"));
15887836SJohn.Forte@Sun.COM 		printDigestAlgorithm(&digestAlgorithms,
15897836SJohn.Forte@Sun.COM 		    PRINT_CONFIGURED_PARAMS);
15907836SJohn.Forte@Sun.COM 	} else {
15917836SJohn.Forte@Sun.COM 		printLibError(status);
15927836SJohn.Forte@Sun.COM 		*funcRet = 1;
15937836SJohn.Forte@Sun.COM 		return (ret);
15947836SJohn.Forte@Sun.COM 	}
15957836SJohn.Forte@Sun.COM 
15967836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetDataDigest(initiatorOid, &digestAlgorithms);
15977836SJohn.Forte@Sun.COM 	if (IMA_SUCCESS(status)) {
15987836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\t\t%s: ", gettext("Data Digest"));
15997836SJohn.Forte@Sun.COM 		printDigestAlgorithm(&digestAlgorithms,
16007836SJohn.Forte@Sun.COM 		    PRINT_CONFIGURED_PARAMS);
16017836SJohn.Forte@Sun.COM 	} else {
16027836SJohn.Forte@Sun.COM 		printLibError(status);
16037836SJohn.Forte@Sun.COM 		*funcRet = 1;
16047836SJohn.Forte@Sun.COM 		return (ret);
16057836SJohn.Forte@Sun.COM 	}
16067836SJohn.Forte@Sun.COM 
16077836SJohn.Forte@Sun.COM 	/* Get authentication type for this lhba */
16087836SJohn.Forte@Sun.COM 	status = IMA_GetInUseInitiatorAuthMethods(initiatorOid, &maxEntries,
16097836SJohn.Forte@Sun.COM 	    &methodList[0]);
16107836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\t%s: ", gettext("Authentication Type"));
16117836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
16127836SJohn.Forte@Sun.COM 		/* No authentication method set - default is NONE */
16137836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, gettext("NONE"));
16147836SJohn.Forte@Sun.COM 	} else {
16157836SJohn.Forte@Sun.COM 		for (i = 0; i < maxEntries; i++) {
16167836SJohn.Forte@Sun.COM 			if (i > 0) {
16177836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "|");
16187836SJohn.Forte@Sun.COM 			}
16197836SJohn.Forte@Sun.COM 			switch (methodList[i]) {
16207836SJohn.Forte@Sun.COM 				case IMA_AUTHMETHOD_NONE:
16217836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, gettext("NONE"));
16227836SJohn.Forte@Sun.COM 					break;
16237836SJohn.Forte@Sun.COM 				case IMA_AUTHMETHOD_CHAP:
16247836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, gettext("CHAP"));
16257836SJohn.Forte@Sun.COM 					listCHAPName(initiatorOid);
16267836SJohn.Forte@Sun.COM 					break;
16277836SJohn.Forte@Sun.COM 				default:
16287836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
16297836SJohn.Forte@Sun.COM 					    gettext("unknown type"));
16307836SJohn.Forte@Sun.COM 					break;
16317836SJohn.Forte@Sun.COM 			}
16327836SJohn.Forte@Sun.COM 		}
16337836SJohn.Forte@Sun.COM 	}
16347836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\n");
16357836SJohn.Forte@Sun.COM 
16367836SJohn.Forte@Sun.COM 
16377836SJohn.Forte@Sun.COM 	/* Get RADIUS configuration */
16387836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetInitiatorRadiusConfig(initiatorOid, &radiusConfig);
16397836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\t%s: ", gettext("RADIUS Server"));
16407836SJohn.Forte@Sun.COM 	if (IMA_SUCCESS(status)) {
16417836SJohn.Forte@Sun.COM 		if (strlen(radiusConfig.hostnameIpAddress) > 0) {
16427836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s:%d",
16437836SJohn.Forte@Sun.COM 			    radiusConfig.hostnameIpAddress,
16447836SJohn.Forte@Sun.COM 			    radiusConfig.port);
16457836SJohn.Forte@Sun.COM 		} else {
16467836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s", gettext("NONE"));
16477836SJohn.Forte@Sun.COM 		}
16487836SJohn.Forte@Sun.COM 	} else {
16497836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s", gettext("NONE"));
16507836SJohn.Forte@Sun.COM 	}
16517836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\n");
16527836SJohn.Forte@Sun.COM 
16537836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetInitiatorRadiusAccess(initiatorOid,
16547836SJohn.Forte@Sun.COM 	    &radiusAccess);
16557836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\t%s: ", gettext("RADIUS Access"));
16567836SJohn.Forte@Sun.COM 	if (IMA_SUCCESS(status)) {
16577836SJohn.Forte@Sun.COM 		if (radiusAccess == IMA_TRUE) {
16587836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s", gettext("enabled"));
16597836SJohn.Forte@Sun.COM 		} else {
16607836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s", gettext("disabled"));
16617836SJohn.Forte@Sun.COM 		}
16627836SJohn.Forte@Sun.COM 	} else if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
16637836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s", gettext("disabled"));
16647836SJohn.Forte@Sun.COM 	} else {
16657836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s", gettext("unknown"));
16667836SJohn.Forte@Sun.COM 	}
16677836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\n");
16687836SJohn.Forte@Sun.COM 
16697836SJohn.Forte@Sun.COM 	/* print configured session information. */
16707836SJohn.Forte@Sun.COM 	ret = printConfiguredSessions(initiatorOid);
16717836SJohn.Forte@Sun.COM 
16727836SJohn.Forte@Sun.COM 	return (ret);
16737836SJohn.Forte@Sun.COM }
16747836SJohn.Forte@Sun.COM 
16757836SJohn.Forte@Sun.COM /*
16767836SJohn.Forte@Sun.COM  * Print discovery addresses
16777836SJohn.Forte@Sun.COM  */
16787836SJohn.Forte@Sun.COM static int
16797836SJohn.Forte@Sun.COM listDiscoveryAddress(int objectLen, char *objects[], cmdOptions_t *options,
16807836SJohn.Forte@Sun.COM     int *funcRet)
16817836SJohn.Forte@Sun.COM {
16827836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
16837836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDR_PROP_LIST *discoveryAddressPropertiesList;
16847836SJohn.Forte@Sun.COM 	IMA_DISCOVERY_ADDRESS_PROPERTIES discAddrProps;
16857836SJohn.Forte@Sun.COM 	IMA_TARGET_ADDRESS address;
16867836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList;
16877836SJohn.Forte@Sun.COM 	IMA_STATUS status;
16887836SJohn.Forte@Sun.COM 	wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
16897836SJohn.Forte@Sun.COM 	int ret;
16907836SJohn.Forte@Sun.COM 	boolean_t object = B_FALSE;
16917836SJohn.Forte@Sun.COM 	int outerLoop;
16927836SJohn.Forte@Sun.COM 	boolean_t found;
16937836SJohn.Forte@Sun.COM 	boolean_t verbose = B_FALSE;
16947836SJohn.Forte@Sun.COM 	int i, j;
16957836SJohn.Forte@Sun.COM 	cmdOptions_t *optionList = options;
16967836SJohn.Forte@Sun.COM 	char sAddr[SUN_IMA_IP_ADDRESS_PORT_LEN];
16977836SJohn.Forte@Sun.COM 
16987836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
16997836SJohn.Forte@Sun.COM 
17007836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
17017836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
17027836SJohn.Forte@Sun.COM 	if (ret > 0) {
17037836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
17047836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
17057836SJohn.Forte@Sun.COM 	}
17067836SJohn.Forte@Sun.COM 
17077836SJohn.Forte@Sun.COM 	if (ret != 0) {
17087836SJohn.Forte@Sun.COM 		return (ret);
17097836SJohn.Forte@Sun.COM 	}
17107836SJohn.Forte@Sun.COM 
17117836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
17127836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
17137836SJohn.Forte@Sun.COM 			case 'v':
17147836SJohn.Forte@Sun.COM 				verbose = B_TRUE;
17157836SJohn.Forte@Sun.COM 				break;
17167836SJohn.Forte@Sun.COM 			default:
17177836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %c: %s\n",
17187836SJohn.Forte@Sun.COM 				    cmdName, optionList->optval,
17197836SJohn.Forte@Sun.COM 				    gettext("unknown option"));
17207836SJohn.Forte@Sun.COM 				return (1);
17217836SJohn.Forte@Sun.COM 		}
17227836SJohn.Forte@Sun.COM 	}
17237836SJohn.Forte@Sun.COM 
17247836SJohn.Forte@Sun.COM 	/*
17257836SJohn.Forte@Sun.COM 	 * If there are multiple objects, execute outer 'for' loop that
17267836SJohn.Forte@Sun.COM 	 * many times for each target detail, otherwise, execute it only
17277836SJohn.Forte@Sun.COM 	 * once with summaries only
17287836SJohn.Forte@Sun.COM 	 */
17297836SJohn.Forte@Sun.COM 	if (objectLen > 0) {
17307836SJohn.Forte@Sun.COM 		object = B_TRUE;
17317836SJohn.Forte@Sun.COM 		outerLoop = objectLen;
17327836SJohn.Forte@Sun.COM 	} else {
17337836SJohn.Forte@Sun.COM 		object = B_FALSE;
17347836SJohn.Forte@Sun.COM 		outerLoop = 1;
17357836SJohn.Forte@Sun.COM 	}
17367836SJohn.Forte@Sun.COM 
17377836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetDiscoveryAddressPropertiesList(
17387836SJohn.Forte@Sun.COM 	    &discoveryAddressPropertiesList);
17397836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
17407836SJohn.Forte@Sun.COM 		printLibError(status);
17417836SJohn.Forte@Sun.COM 		*funcRet = 1;
17427836SJohn.Forte@Sun.COM 		return (ret);
17437836SJohn.Forte@Sun.COM 	}
17447836SJohn.Forte@Sun.COM 
17457836SJohn.Forte@Sun.COM 	for (i = 0; i < outerLoop; i++) {
17467836SJohn.Forte@Sun.COM 		if (object) {
17477836SJohn.Forte@Sun.COM 			/* initialize */
17487836SJohn.Forte@Sun.COM 			(void) memset(&wcInputObject[0], 0,
17497836SJohn.Forte@Sun.COM 			    sizeof (wcInputObject));
17507836SJohn.Forte@Sun.COM 			(void) memset(&address, 0, sizeof (address));
17517836SJohn.Forte@Sun.COM 			if (mbstowcs(wcInputObject, objects[i],
17527836SJohn.Forte@Sun.COM 			    (MAX_ADDRESS_LEN + 1)) == (size_t)-1) {
17537836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
17547836SJohn.Forte@Sun.COM 				    cmdName,
17557836SJohn.Forte@Sun.COM 				    gettext("conversion error"));
17567836SJohn.Forte@Sun.COM 				ret = 1;
17577836SJohn.Forte@Sun.COM 				continue;
17587836SJohn.Forte@Sun.COM 			}
17597836SJohn.Forte@Sun.COM 
17607836SJohn.Forte@Sun.COM 			/*
17617836SJohn.Forte@Sun.COM 			 * if one or more objects were input,
17627836SJohn.Forte@Sun.COM 			 * get the values
17637836SJohn.Forte@Sun.COM 			 */
17647836SJohn.Forte@Sun.COM 			if (getTargetAddress(DISCOVERY_ADDRESS,
17657836SJohn.Forte@Sun.COM 			    objects[i], &address) != 0) {
17667836SJohn.Forte@Sun.COM 				ret = 1;
17677836SJohn.Forte@Sun.COM 				continue;
17687836SJohn.Forte@Sun.COM 			}
17697836SJohn.Forte@Sun.COM 		}
17707836SJohn.Forte@Sun.COM 		for (found = B_FALSE, j = 0;
17717836SJohn.Forte@Sun.COM 		    j < discoveryAddressPropertiesList->discAddrCount;
17727836SJohn.Forte@Sun.COM 		    j++) {
17737836SJohn.Forte@Sun.COM 			discAddrProps =
17747836SJohn.Forte@Sun.COM 			    discoveryAddressPropertiesList->props[j];
17757836SJohn.Forte@Sun.COM 
17767836SJohn.Forte@Sun.COM 			/*
17777836SJohn.Forte@Sun.COM 			 * Compare the discovery address with the input if
17787836SJohn.Forte@Sun.COM 			 * one was input
17797836SJohn.Forte@Sun.COM 			 */
17807836SJohn.Forte@Sun.COM 			if (object &&
17817836SJohn.Forte@Sun.COM 			    ipAddressesEqual(discAddrProps.discoveryAddress,
17827836SJohn.Forte@Sun.COM 			    address) && (discAddrProps.discoveryAddress.
17837836SJohn.Forte@Sun.COM 			    portNumber == address.portNumber)) {
17847836SJohn.Forte@Sun.COM 				found = B_TRUE;
17857836SJohn.Forte@Sun.COM 			}
17867836SJohn.Forte@Sun.COM 
17877836SJohn.Forte@Sun.COM 			if (!object || found) {
17887836SJohn.Forte@Sun.COM 				/* Print summary - always */
17897836SJohn.Forte@Sun.COM 				if (discAddrProps.discoveryAddress.
17907836SJohn.Forte@Sun.COM 				    hostnameIpAddress.id.ipAddress.
17917836SJohn.Forte@Sun.COM 				    ipv4Address) {
17927836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET, discAddrProps.
17937836SJohn.Forte@Sun.COM 					    discoveryAddress.hostnameIpAddress.
17947836SJohn.Forte@Sun.COM 					    id.ipAddress.ipAddress, sAddr,
17957836SJohn.Forte@Sun.COM 					    sizeof (sAddr));
17967836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
17977836SJohn.Forte@Sun.COM 					    "Discovery Address: %s:%u\n",
17987836SJohn.Forte@Sun.COM 					    sAddr, discAddrProps.
17997836SJohn.Forte@Sun.COM 					    discoveryAddress.portNumber);
18007836SJohn.Forte@Sun.COM 				} else {
18017836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET6,
18027836SJohn.Forte@Sun.COM 					    discAddrProps.
18037836SJohn.Forte@Sun.COM 					    discoveryAddress.hostnameIpAddress.
18047836SJohn.Forte@Sun.COM 					    id.ipAddress.ipAddress, sAddr,
18057836SJohn.Forte@Sun.COM 					    sizeof (sAddr));
18067836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
18077836SJohn.Forte@Sun.COM 					    "DiscoveryAddress: [%s]:%u\n",
18087836SJohn.Forte@Sun.COM 					    sAddr, discAddrProps.
18097836SJohn.Forte@Sun.COM 					    discoveryAddress.portNumber);
18107836SJohn.Forte@Sun.COM 				}
18117836SJohn.Forte@Sun.COM 			}
18127836SJohn.Forte@Sun.COM 
18137836SJohn.Forte@Sun.COM 			if ((!object || found) && verbose) {
18147836SJohn.Forte@Sun.COM 				IMA_NODE_PROPERTIES nodeProps;
18157836SJohn.Forte@Sun.COM 
18167836SJohn.Forte@Sun.COM 				if (getNodeProps(&nodeProps) != 0) {
18177836SJohn.Forte@Sun.COM 					break;
18187836SJohn.Forte@Sun.COM 				}
18197836SJohn.Forte@Sun.COM 
18207836SJohn.Forte@Sun.COM 				/*
18217836SJohn.Forte@Sun.COM 				 * Issue sendTargets only when an addr is
18227836SJohn.Forte@Sun.COM 				 * specified.
18237836SJohn.Forte@Sun.COM 				 */
18247836SJohn.Forte@Sun.COM 				status = SUN_IMA_SendTargets(nodeProps.name,
18257836SJohn.Forte@Sun.COM 				    discAddrProps.discoveryAddress, &pList);
18267836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
18277836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s\n",
18287836SJohn.Forte@Sun.COM 					    gettext("\tUnable to get "\
18297836SJohn.Forte@Sun.COM 					    "targets."));
18307836SJohn.Forte@Sun.COM 					*funcRet = 1;
18317836SJohn.Forte@Sun.COM 					continue;
18327836SJohn.Forte@Sun.COM 				}
18337836SJohn.Forte@Sun.COM 				printSendTargets(pList);
18347836SJohn.Forte@Sun.COM 			}
18357836SJohn.Forte@Sun.COM 
18367836SJohn.Forte@Sun.COM 			if (found) {
18377836SJohn.Forte@Sun.COM 				/* we found the discovery address - break */
18387836SJohn.Forte@Sun.COM 				break;
18397836SJohn.Forte@Sun.COM 			}
18407836SJohn.Forte@Sun.COM 		}
18417836SJohn.Forte@Sun.COM 		/*
18427836SJohn.Forte@Sun.COM 		 * There was an object entered but we didn't
18437836SJohn.Forte@Sun.COM 		 * find it.
18447836SJohn.Forte@Sun.COM 		 */
18457836SJohn.Forte@Sun.COM 		if (object && !found) {
18467836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s: %s\n",
18477836SJohn.Forte@Sun.COM 			    objects[i], gettext("not found"));
18487836SJohn.Forte@Sun.COM 		}
18497836SJohn.Forte@Sun.COM 	}
18507836SJohn.Forte@Sun.COM 	return (ret);
18517836SJohn.Forte@Sun.COM }
18527836SJohn.Forte@Sun.COM 
18537836SJohn.Forte@Sun.COM /*
18547836SJohn.Forte@Sun.COM  * Print ISNS Server addresses
18557836SJohn.Forte@Sun.COM  */
18567836SJohn.Forte@Sun.COM static int
18577836SJohn.Forte@Sun.COM listISNSServerAddress(int objectLen, char *objects[], cmdOptions_t *options,
18587836SJohn.Forte@Sun.COM     int *funcRet)
18597836SJohn.Forte@Sun.COM {
18607836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
18617836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDR_PROP_LIST	    *discoveryAddressPropertiesList;
18627836SJohn.Forte@Sun.COM 	IMA_DISCOVERY_ADDRESS_PROPERTIES discAddrProps;
18637836SJohn.Forte@Sun.COM 	IMA_TARGET_ADDRESS address;
18647836SJohn.Forte@Sun.COM 	SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList;
18657836SJohn.Forte@Sun.COM 	IMA_STATUS status;
18667836SJohn.Forte@Sun.COM 	wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
18677836SJohn.Forte@Sun.COM 	int ret;
18687836SJohn.Forte@Sun.COM 	boolean_t object = B_FALSE;
18697836SJohn.Forte@Sun.COM 	int outerLoop;
18707836SJohn.Forte@Sun.COM 	boolean_t found;
18717836SJohn.Forte@Sun.COM 	boolean_t showTarget = B_FALSE;
18727836SJohn.Forte@Sun.COM 	int i, j;
18737836SJohn.Forte@Sun.COM 	cmdOptions_t *optionList = options;
18747836SJohn.Forte@Sun.COM 	char sAddr[SUN_IMA_IP_ADDRESS_PORT_LEN];
18757836SJohn.Forte@Sun.COM 
18767836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
18777836SJohn.Forte@Sun.COM 
18787836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
18797836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
18807836SJohn.Forte@Sun.COM 	if (ret > 0) {
18817836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
18827836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
18837836SJohn.Forte@Sun.COM 	}
18847836SJohn.Forte@Sun.COM 
18857836SJohn.Forte@Sun.COM 	if (ret != 0) {
18867836SJohn.Forte@Sun.COM 		return (ret);
18877836SJohn.Forte@Sun.COM 	}
18887836SJohn.Forte@Sun.COM 
18897836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
18907836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
18917836SJohn.Forte@Sun.COM 			case 'v':
18927836SJohn.Forte@Sun.COM 				showTarget = B_TRUE;
18937836SJohn.Forte@Sun.COM 				break;
18947836SJohn.Forte@Sun.COM 			default:
18957836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %c: %s\n",
18967836SJohn.Forte@Sun.COM 				    cmdName, optionList->optval,
18977836SJohn.Forte@Sun.COM 				    gettext("unknown option"));
18987836SJohn.Forte@Sun.COM 				return (1);
18997836SJohn.Forte@Sun.COM 		}
19007836SJohn.Forte@Sun.COM 	}
19017836SJohn.Forte@Sun.COM 
19027836SJohn.Forte@Sun.COM 	/*
19037836SJohn.Forte@Sun.COM 	 * If there are multiple objects, execute outer 'for' loop that
19047836SJohn.Forte@Sun.COM 	 * many times for each target detail, otherwise, execute it only
19057836SJohn.Forte@Sun.COM 	 * once with summaries only
19067836SJohn.Forte@Sun.COM 	 */
19077836SJohn.Forte@Sun.COM 	if (objectLen > 0) {
19087836SJohn.Forte@Sun.COM 		object = B_TRUE;
19097836SJohn.Forte@Sun.COM 		outerLoop = objectLen;
19107836SJohn.Forte@Sun.COM 	} else {
19117836SJohn.Forte@Sun.COM 		object = B_FALSE;
19127836SJohn.Forte@Sun.COM 		outerLoop = 1;
19137836SJohn.Forte@Sun.COM 	}
19147836SJohn.Forte@Sun.COM 
19157836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetISNSServerAddressPropertiesList(
19167836SJohn.Forte@Sun.COM 	    &discoveryAddressPropertiesList);
19177836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
19187836SJohn.Forte@Sun.COM 		printLibError(status);
19197836SJohn.Forte@Sun.COM 		*funcRet = 1;
19207836SJohn.Forte@Sun.COM 		return (ret);
19217836SJohn.Forte@Sun.COM 	}
19227836SJohn.Forte@Sun.COM 
19237836SJohn.Forte@Sun.COM 	for (i = 0; i < outerLoop; i++) {
19247836SJohn.Forte@Sun.COM 		if (object) {
19257836SJohn.Forte@Sun.COM 			/* initialize */
19267836SJohn.Forte@Sun.COM 			(void) memset(&wcInputObject[0], 0,
19277836SJohn.Forte@Sun.COM 			    sizeof (wcInputObject));
19287836SJohn.Forte@Sun.COM 			(void) memset(&address, 0, sizeof (address));
19297836SJohn.Forte@Sun.COM 			if (mbstowcs(wcInputObject, objects[i],
19307836SJohn.Forte@Sun.COM 			    (MAX_ADDRESS_LEN + 1)) == (size_t)-1) {
19317836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s\n",
19327836SJohn.Forte@Sun.COM 				    cmdName,
19337836SJohn.Forte@Sun.COM 				    gettext("conversion error"));
19347836SJohn.Forte@Sun.COM 				ret = 1;
19357836SJohn.Forte@Sun.COM 				continue;
19367836SJohn.Forte@Sun.COM 			}
19377836SJohn.Forte@Sun.COM 
19387836SJohn.Forte@Sun.COM 			/*
19397836SJohn.Forte@Sun.COM 			 * if one or more objects were input,
19407836SJohn.Forte@Sun.COM 			 * get the values
19417836SJohn.Forte@Sun.COM 			 */
19427836SJohn.Forte@Sun.COM 			if (getTargetAddress(ISNS_SERVER_ADDRESS,
19437836SJohn.Forte@Sun.COM 			    objects[i], &address) != 0) {
19447836SJohn.Forte@Sun.COM 				ret = 1;
19457836SJohn.Forte@Sun.COM 				continue;
19467836SJohn.Forte@Sun.COM 			}
19477836SJohn.Forte@Sun.COM 		}
19487836SJohn.Forte@Sun.COM 		for (found = B_FALSE, j = 0;
19497836SJohn.Forte@Sun.COM 		    j < discoveryAddressPropertiesList->discAddrCount;
19507836SJohn.Forte@Sun.COM 		    j++) {
19517836SJohn.Forte@Sun.COM 			discAddrProps =
19527836SJohn.Forte@Sun.COM 			    discoveryAddressPropertiesList->props[j];
19537836SJohn.Forte@Sun.COM 
19547836SJohn.Forte@Sun.COM 			/*
19557836SJohn.Forte@Sun.COM 			 * Compare the discovery address with the input if
19567836SJohn.Forte@Sun.COM 			 * one was input
19577836SJohn.Forte@Sun.COM 			 */
19587836SJohn.Forte@Sun.COM 			if (object &&
19597836SJohn.Forte@Sun.COM 			    ipAddressesEqual(discAddrProps.discoveryAddress,
19607836SJohn.Forte@Sun.COM 			    address) &&
19617836SJohn.Forte@Sun.COM 			    (discAddrProps.discoveryAddress.portNumber ==
19627836SJohn.Forte@Sun.COM 			    address.portNumber)) {
19637836SJohn.Forte@Sun.COM 				found = B_TRUE;
19647836SJohn.Forte@Sun.COM 			}
19657836SJohn.Forte@Sun.COM 
19667836SJohn.Forte@Sun.COM 			if (!object || found) {
19677836SJohn.Forte@Sun.COM 				/* Print summary - always */
19687836SJohn.Forte@Sun.COM 				if (discAddrProps.discoveryAddress.
19697836SJohn.Forte@Sun.COM 				    hostnameIpAddress.id.ipAddress.
19707836SJohn.Forte@Sun.COM 				    ipv4Address) {
19717836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET, discAddrProps.
19727836SJohn.Forte@Sun.COM 					    discoveryAddress.hostnameIpAddress.
19737836SJohn.Forte@Sun.COM 					    id.ipAddress.ipAddress, sAddr,
19747836SJohn.Forte@Sun.COM 					    sizeof (sAddr));
19757836SJohn.Forte@Sun.COM 				} else {
19767836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET6,
19777836SJohn.Forte@Sun.COM 					    discAddrProps.
19787836SJohn.Forte@Sun.COM 					    discoveryAddress.hostnameIpAddress.
19797836SJohn.Forte@Sun.COM 					    id.ipAddress.ipAddress, sAddr,
19807836SJohn.Forte@Sun.COM 					    sizeof (sAddr));
19817836SJohn.Forte@Sun.COM 				}
19827836SJohn.Forte@Sun.COM 				(void) fprintf(stdout,
19837836SJohn.Forte@Sun.COM 				    "iSNS Server IP Address: %s:%u\n",
19847836SJohn.Forte@Sun.COM 				    sAddr,
19857836SJohn.Forte@Sun.COM 				    discAddrProps.discoveryAddress.portNumber);
19867836SJohn.Forte@Sun.COM 			}
19877836SJohn.Forte@Sun.COM 
19887836SJohn.Forte@Sun.COM 			if ((!object || found) && showTarget) {
19897836SJohn.Forte@Sun.COM 				IMA_NODE_PROPERTIES nodeProps;
19907836SJohn.Forte@Sun.COM 
19917836SJohn.Forte@Sun.COM 				if (getNodeProps(&nodeProps) != 0) {
19927836SJohn.Forte@Sun.COM 					break;
19937836SJohn.Forte@Sun.COM 				}
19947836SJohn.Forte@Sun.COM 
19957836SJohn.Forte@Sun.COM 				/*
19967836SJohn.Forte@Sun.COM 				 * Issue sendTargets only when an addr is
19977836SJohn.Forte@Sun.COM 				 * specified.
19987836SJohn.Forte@Sun.COM 				 */
19997836SJohn.Forte@Sun.COM 				status = SUN_IMA_RetrieveISNSServerTargets(
20007836SJohn.Forte@Sun.COM 				    discAddrProps.discoveryAddress,
20017836SJohn.Forte@Sun.COM 				    &pList);
20027836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
20037836SJohn.Forte@Sun.COM 					/*
20047836SJohn.Forte@Sun.COM 					 * Check if the discovery mode is
20057836SJohn.Forte@Sun.COM 					 * disabled.
20067836SJohn.Forte@Sun.COM 					 */
20077836SJohn.Forte@Sun.COM 					if (status ==
20087836SJohn.Forte@Sun.COM 					    IMA_ERROR_OBJECT_NOT_FOUND) {
20097836SJohn.Forte@Sun.COM 						(void) fprintf(stderr, "%s\n",
20107836SJohn.Forte@Sun.COM 						    gettext("\tiSNS "\
20117836SJohn.Forte@Sun.COM 						    "discovery "\
20127836SJohn.Forte@Sun.COM 						    "mode "\
20137836SJohn.Forte@Sun.COM 						    "disabled. "\
20147836SJohn.Forte@Sun.COM 						    "No targets "\
20157836SJohn.Forte@Sun.COM 						    "to report."));
20167836SJohn.Forte@Sun.COM 
20177836SJohn.Forte@Sun.COM 					} else {
20187836SJohn.Forte@Sun.COM 						(void) fprintf(stderr, "%s\n",
20197836SJohn.Forte@Sun.COM 						    gettext("\tUnable "\
20207836SJohn.Forte@Sun.COM 						    "to get "\
20217836SJohn.Forte@Sun.COM 						    "targets."));
20227836SJohn.Forte@Sun.COM 					}
20237836SJohn.Forte@Sun.COM 					continue;
20247836SJohn.Forte@Sun.COM 				}
20257836SJohn.Forte@Sun.COM 				printSendTargets(pList);
20267836SJohn.Forte@Sun.COM 			}
20277836SJohn.Forte@Sun.COM 
20287836SJohn.Forte@Sun.COM 			if (found) {
20297836SJohn.Forte@Sun.COM 				/* we found the discovery address - break */
20307836SJohn.Forte@Sun.COM 				break;
20317836SJohn.Forte@Sun.COM 			}
20327836SJohn.Forte@Sun.COM 		}
20337836SJohn.Forte@Sun.COM 		/*
20347836SJohn.Forte@Sun.COM 		 * There was an object entered but we didn't
20357836SJohn.Forte@Sun.COM 		 * find it.
20367836SJohn.Forte@Sun.COM 		 */
20377836SJohn.Forte@Sun.COM 		if (object && !found) {
20387836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s: %s\n",
20397836SJohn.Forte@Sun.COM 			    objects[i], gettext("not found"));
20407836SJohn.Forte@Sun.COM 		}
20417836SJohn.Forte@Sun.COM 	}
20427836SJohn.Forte@Sun.COM 	return (ret);
20437836SJohn.Forte@Sun.COM }
20447836SJohn.Forte@Sun.COM 
20457836SJohn.Forte@Sun.COM /*
20467836SJohn.Forte@Sun.COM  * Print static configuration targets
20477836SJohn.Forte@Sun.COM  */
20487836SJohn.Forte@Sun.COM static int
20497836SJohn.Forte@Sun.COM listStaticConfig(int operandLen, char *operand[], int *funcRet)
20507836SJohn.Forte@Sun.COM {
20517836SJohn.Forte@Sun.COM 	IMA_STATUS status;
20527836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
20537836SJohn.Forte@Sun.COM 	IMA_OID_LIST *staticTargetList;
20547836SJohn.Forte@Sun.COM 	SUN_IMA_STATIC_TARGET_PROPERTIES staticTargetProps;
20557836SJohn.Forte@Sun.COM 	wchar_t staticTargetName[MAX_ISCSI_NAME_LEN + 1];
20567836SJohn.Forte@Sun.COM 	wchar_t staticTargetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
20577836SJohn.Forte@Sun.COM 	wchar_t wcCol;
20587836SJohn.Forte@Sun.COM 	char sAddr[SUN_IMA_IP_ADDRESS_PORT_LEN];
20597836SJohn.Forte@Sun.COM 	int ret;
20607836SJohn.Forte@Sun.COM 	boolean_t object = B_FALSE;
20617836SJohn.Forte@Sun.COM 	int outerLoop;
20627836SJohn.Forte@Sun.COM 	boolean_t found; /* B_TRUE if a target name is found */
20637836SJohn.Forte@Sun.COM 	boolean_t matched; /* B_TRUE if a specific target is found */
20647836SJohn.Forte@Sun.COM 	boolean_t targetAddressSpecified = B_FALSE;
20657836SJohn.Forte@Sun.COM 	boolean_t tpgtSpecified = B_FALSE;
20667836SJohn.Forte@Sun.COM 	boolean_t isIpv6;
20677836SJohn.Forte@Sun.COM 	int i, j;
20687836SJohn.Forte@Sun.COM 	IMA_UINT16 port = 0;
20697836SJohn.Forte@Sun.COM 	IMA_UINT16 tpgt = 0;
20707836SJohn.Forte@Sun.COM 	char tmpStr[SUN_IMA_IP_ADDRESS_PORT_LEN];
20717836SJohn.Forte@Sun.COM 	wchar_t tmpTargetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
20727836SJohn.Forte@Sun.COM 
20737836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
20747836SJohn.Forte@Sun.COM 
20757836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
20767836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
20777836SJohn.Forte@Sun.COM 	if (ret > 0) {
20787836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
20797836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
20807836SJohn.Forte@Sun.COM 	}
20817836SJohn.Forte@Sun.COM 
20827836SJohn.Forte@Sun.COM 	if (ret != 0) {
20837836SJohn.Forte@Sun.COM 		return (ret);
20847836SJohn.Forte@Sun.COM 	}
20857836SJohn.Forte@Sun.COM 
20867836SJohn.Forte@Sun.COM 	/*
20877836SJohn.Forte@Sun.COM 	 * If there are multiple objects, execute outer 'for' loop that
20887836SJohn.Forte@Sun.COM 	 * many times for each static config detail, otherwise, execute it only
20897836SJohn.Forte@Sun.COM 	 * once with summaries only
20907836SJohn.Forte@Sun.COM 	 */
20917836SJohn.Forte@Sun.COM 	if (operandLen > 0) {
20927836SJohn.Forte@Sun.COM 		object = B_TRUE;
20937836SJohn.Forte@Sun.COM 		outerLoop = operandLen;
20947836SJohn.Forte@Sun.COM 	} else {
20957836SJohn.Forte@Sun.COM 		object = B_FALSE;
20967836SJohn.Forte@Sun.COM 		outerLoop = 1;
20977836SJohn.Forte@Sun.COM 	}
20987836SJohn.Forte@Sun.COM 
20997836SJohn.Forte@Sun.COM 	/* convert ':' to wide char for wchar string search */
21007836SJohn.Forte@Sun.COM 	if (mbtowc(&wcCol, ":", sizeof (wcCol)) == -1) {
21017836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
21027836SJohn.Forte@Sun.COM 		    cmdName, gettext("conversion error"));
21037836SJohn.Forte@Sun.COM 		return (1);
21047836SJohn.Forte@Sun.COM 	}
21057836SJohn.Forte@Sun.COM 
21067836SJohn.Forte@Sun.COM 	status = IMA_GetStaticDiscoveryTargetOidList(initiatorOid,
21077836SJohn.Forte@Sun.COM 	    &staticTargetList);
21087836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
21097836SJohn.Forte@Sun.COM 		printLibError(status);
21107836SJohn.Forte@Sun.COM 		*funcRet = 1;
21117836SJohn.Forte@Sun.COM 		return (ret);
21127836SJohn.Forte@Sun.COM 	}
21137836SJohn.Forte@Sun.COM 
21147836SJohn.Forte@Sun.COM 	for (i = 0; i < outerLoop; i++) {
21157836SJohn.Forte@Sun.COM 		if (object) {
21167836SJohn.Forte@Sun.COM 			if (parseTarget(operand[i],
21177836SJohn.Forte@Sun.COM 			    &staticTargetName[0],
21187836SJohn.Forte@Sun.COM 			    MAX_ISCSI_NAME_LEN + 1,
21197836SJohn.Forte@Sun.COM 			    &targetAddressSpecified,
21207836SJohn.Forte@Sun.COM 			    &staticTargetAddress[0],
21217836SJohn.Forte@Sun.COM 			    SUN_IMA_IP_ADDRESS_PORT_LEN,
21227836SJohn.Forte@Sun.COM 			    &port,
21237836SJohn.Forte@Sun.COM 			    &tpgtSpecified,
21247836SJohn.Forte@Sun.COM 			    &tpgt,
21257836SJohn.Forte@Sun.COM 			    &isIpv6) != PARSE_TARGET_OK) {
21267836SJohn.Forte@Sun.COM 				ret = 1;
21277836SJohn.Forte@Sun.COM 				continue;
21287836SJohn.Forte@Sun.COM 			}
21297836SJohn.Forte@Sun.COM 		}
21307836SJohn.Forte@Sun.COM 
21317836SJohn.Forte@Sun.COM 		for (found = B_FALSE, j = 0; j < staticTargetList->oidCount;
21327836SJohn.Forte@Sun.COM 		    j++) {
21337836SJohn.Forte@Sun.COM 			boolean_t isIpv6 = B_FALSE;
21347836SJohn.Forte@Sun.COM 			IMA_UINT16 stpgt;
21357836SJohn.Forte@Sun.COM 			IMA_BOOL defaultTpgt;
21367836SJohn.Forte@Sun.COM 
21377836SJohn.Forte@Sun.COM 			matched = B_FALSE;
21387836SJohn.Forte@Sun.COM 			(void) memset(&staticTargetProps, 0,
21397836SJohn.Forte@Sun.COM 			    sizeof (staticTargetProps));
21407836SJohn.Forte@Sun.COM 
21417836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetStaticTargetProperties(
21427836SJohn.Forte@Sun.COM 			    staticTargetList->oids[j], &staticTargetProps);
21437836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
21447836SJohn.Forte@Sun.COM 				printLibError(status);
21457836SJohn.Forte@Sun.COM 				(void) IMA_FreeMemory(staticTargetList);
21467836SJohn.Forte@Sun.COM 				*funcRet = 1;
21477836SJohn.Forte@Sun.COM 				return (ret);
21487836SJohn.Forte@Sun.COM 			}
21497836SJohn.Forte@Sun.COM 
21507836SJohn.Forte@Sun.COM 			stpgt = staticTargetProps.staticTarget.targetAddress.
21517836SJohn.Forte@Sun.COM 			    tpgt;
21527836SJohn.Forte@Sun.COM 
21537836SJohn.Forte@Sun.COM 			defaultTpgt = staticTargetProps.staticTarget.
21547836SJohn.Forte@Sun.COM 			    targetAddress.defaultTpgt;
21557836SJohn.Forte@Sun.COM 
21567836SJohn.Forte@Sun.COM 			isIpv6 = !staticTargetProps.staticTarget.targetAddress.
21577836SJohn.Forte@Sun.COM 			    imaStruct.hostnameIpAddress.id.ipAddress.
21587836SJohn.Forte@Sun.COM 			    ipv4Address;
21597836SJohn.Forte@Sun.COM 
21607836SJohn.Forte@Sun.COM 			/*
21617836SJohn.Forte@Sun.COM 			 * Compare the static target name with the input if
21627836SJohn.Forte@Sun.COM 			 * one was input
21637836SJohn.Forte@Sun.COM 			 */
21647836SJohn.Forte@Sun.COM 
21657836SJohn.Forte@Sun.COM 			if (object &&
21667836SJohn.Forte@Sun.COM 			    (targetNamesEqual(
21677836SJohn.Forte@Sun.COM 			    staticTargetProps.staticTarget.targetName,
21687836SJohn.Forte@Sun.COM 			    staticTargetName) == B_TRUE)) {
21697836SJohn.Forte@Sun.COM 				/* targetName found - found = B_TRUE */
21707836SJohn.Forte@Sun.COM 				found = B_TRUE;
21717836SJohn.Forte@Sun.COM 				if (targetAddressSpecified == B_FALSE) {
21727836SJohn.Forte@Sun.COM 					matched = B_TRUE;
21737836SJohn.Forte@Sun.COM 				} else {
21747836SJohn.Forte@Sun.COM 
21757836SJohn.Forte@Sun.COM 				if (staticTargetProps.staticTarget.
21767836SJohn.Forte@Sun.COM 				    targetAddress.imaStruct.
21777836SJohn.Forte@Sun.COM 				    hostnameIpAddress.id.ipAddress.
21787836SJohn.Forte@Sun.COM 				    ipv4Address == IMA_TRUE) {
21797836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET,
21807836SJohn.Forte@Sun.COM 					    staticTargetProps.
21817836SJohn.Forte@Sun.COM 					    staticTarget.targetAddress.
21827836SJohn.Forte@Sun.COM 					    imaStruct.hostnameIpAddress.id.
21837836SJohn.Forte@Sun.COM 					    ipAddress.ipAddress, tmpStr,
21847836SJohn.Forte@Sun.COM 					    sizeof (tmpStr));
21857836SJohn.Forte@Sun.COM 				} else {
21867836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET6,
21877836SJohn.Forte@Sun.COM 					    staticTargetProps.
21887836SJohn.Forte@Sun.COM 					    staticTarget.targetAddress.
21897836SJohn.Forte@Sun.COM 					    imaStruct.hostnameIpAddress.id.
21907836SJohn.Forte@Sun.COM 					    ipAddress.ipAddress, tmpStr,
21917836SJohn.Forte@Sun.COM 					    sizeof (tmpStr));
21927836SJohn.Forte@Sun.COM 				}
21937836SJohn.Forte@Sun.COM 
21947836SJohn.Forte@Sun.COM 				if (mbstowcs(tmpTargetAddress, tmpStr,
21957836SJohn.Forte@Sun.COM 				    SUN_IMA_IP_ADDRESS_PORT_LEN) ==
21967836SJohn.Forte@Sun.COM 				    (size_t)-1) {
21977836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
21987836SJohn.Forte@Sun.COM 					    cmdName,
21997836SJohn.Forte@Sun.COM 					gettext("conversion error"));
22007836SJohn.Forte@Sun.COM 					ret = 1;
22017836SJohn.Forte@Sun.COM 					continue;
22027836SJohn.Forte@Sun.COM 				}
22037836SJohn.Forte@Sun.COM 
22047836SJohn.Forte@Sun.COM 				if (wcsncmp(tmpTargetAddress,
22057836SJohn.Forte@Sun.COM 				    staticTargetAddress,
22067836SJohn.Forte@Sun.COM 				    SUN_IMA_IP_ADDRESS_PORT_LEN)
22077836SJohn.Forte@Sun.COM 				    == 0 &&
22087836SJohn.Forte@Sun.COM 				    staticTargetProps.
22097836SJohn.Forte@Sun.COM 				    staticTarget.targetAddress.
22107836SJohn.Forte@Sun.COM 				    imaStruct.portNumber == port) {
22117836SJohn.Forte@Sun.COM 					/*
22127836SJohn.Forte@Sun.COM 					 * Since an object is
22137836SJohn.Forte@Sun.COM 					 * specified, it should also
22147836SJohn.Forte@Sun.COM 					 * have a tpgt specified. If
22157836SJohn.Forte@Sun.COM 					 * not, that means the object
22167836SJohn.Forte@Sun.COM 					 * specified is associated with
22177836SJohn.Forte@Sun.COM 					 * the default tpgt. In
22187836SJohn.Forte@Sun.COM 					 * either case, a tpgt
22197836SJohn.Forte@Sun.COM 					 * comparison should be done
22207836SJohn.Forte@Sun.COM 					 * before claiming that a
22217836SJohn.Forte@Sun.COM 					 * match is found.
22227836SJohn.Forte@Sun.COM 					 */
22237836SJohn.Forte@Sun.COM 					if ((tpgt == stpgt &&
22247836SJohn.Forte@Sun.COM 					    tpgtSpecified == B_TRUE &&
22257836SJohn.Forte@Sun.COM 					    defaultTpgt == IMA_FALSE) ||
22267836SJohn.Forte@Sun.COM 					    (tpgt == stpgt &&
22277836SJohn.Forte@Sun.COM 					    tpgtSpecified == B_FALSE &&
22287836SJohn.Forte@Sun.COM 					    defaultTpgt == IMA_TRUE)) {
22297836SJohn.Forte@Sun.COM 						matched = B_TRUE;
22307836SJohn.Forte@Sun.COM 					}
22317836SJohn.Forte@Sun.COM 				}
22327836SJohn.Forte@Sun.COM 
22337836SJohn.Forte@Sun.COM 				}
22347836SJohn.Forte@Sun.COM 			}
22357836SJohn.Forte@Sun.COM 
22367836SJohn.Forte@Sun.COM 			if (!object || matched) {
22377836SJohn.Forte@Sun.COM 				/* print summary - always */
22387836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, gettext("%s: %ws,"),
22397836SJohn.Forte@Sun.COM 				    "Static Configuration Target",
22407836SJohn.Forte@Sun.COM 				    staticTargetProps.staticTarget.targetName);
22417836SJohn.Forte@Sun.COM 
22427836SJohn.Forte@Sun.COM 				if (isIpv6 == B_FALSE) {
22437836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET,
22447836SJohn.Forte@Sun.COM 					    staticTargetProps.
22457836SJohn.Forte@Sun.COM 					    staticTarget.targetAddress.
22467836SJohn.Forte@Sun.COM 					    imaStruct.hostnameIpAddress.id.
22477836SJohn.Forte@Sun.COM 					    ipAddress.ipAddress, sAddr,
22487836SJohn.Forte@Sun.COM 					    sizeof (sAddr));
22497836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "%s:%d",
22507836SJohn.Forte@Sun.COM 					    sAddr,
22517836SJohn.Forte@Sun.COM 					    staticTargetProps.staticTarget.
22527836SJohn.Forte@Sun.COM 					    targetAddress.imaStruct.portNumber);
22537836SJohn.Forte@Sun.COM 				} else {
22547836SJohn.Forte@Sun.COM 					(void) inet_ntop(AF_INET6,
22557836SJohn.Forte@Sun.COM 					    staticTargetProps.
22567836SJohn.Forte@Sun.COM 					    staticTarget.targetAddress.
22577836SJohn.Forte@Sun.COM 					    imaStruct.hostnameIpAddress.id.
22587836SJohn.Forte@Sun.COM 					    ipAddress.ipAddress, sAddr,
22597836SJohn.Forte@Sun.COM 					    sizeof (sAddr));
22607836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "[%s]:%d",
22617836SJohn.Forte@Sun.COM 					    sAddr,
22627836SJohn.Forte@Sun.COM 					    staticTargetProps.staticTarget.
22637836SJohn.Forte@Sun.COM 					    targetAddress.imaStruct.portNumber);
22647836SJohn.Forte@Sun.COM 				}
22657836SJohn.Forte@Sun.COM 
22667836SJohn.Forte@Sun.COM 				if (staticTargetProps.staticTarget.
22677836SJohn.Forte@Sun.COM 				    targetAddress.
22687836SJohn.Forte@Sun.COM 				    defaultTpgt == IMA_FALSE) {
22697836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, ",%d\n",
22707836SJohn.Forte@Sun.COM 					    staticTargetProps.
22717836SJohn.Forte@Sun.COM 					    staticTarget.targetAddress.tpgt);
22727836SJohn.Forte@Sun.COM 				} else {
22737836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "\n");
22747836SJohn.Forte@Sun.COM 				}
22757836SJohn.Forte@Sun.COM 			}
22767836SJohn.Forte@Sun.COM 
22777836SJohn.Forte@Sun.COM 		}
22787836SJohn.Forte@Sun.COM 		/*
22797836SJohn.Forte@Sun.COM 		 * No details to display, but if there were:
22807836SJohn.Forte@Sun.COM 		 *  if (object && found)...
22817836SJohn.Forte@Sun.COM 		 *
22827836SJohn.Forte@Sun.COM 		 */
22837836SJohn.Forte@Sun.COM 
22847836SJohn.Forte@Sun.COM 		/*
22857836SJohn.Forte@Sun.COM 		 * There was an object entered but we didn't
22867836SJohn.Forte@Sun.COM 		 * find it.
22877836SJohn.Forte@Sun.COM 		 */
22887836SJohn.Forte@Sun.COM 		if (object && !found) {
22897836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s: %s\n",
22907836SJohn.Forte@Sun.COM 			    operand[i], gettext("not found"));
22917836SJohn.Forte@Sun.COM 			ret = 1; /* DIY test fix */
22927836SJohn.Forte@Sun.COM 		}
22937836SJohn.Forte@Sun.COM 	}
22947836SJohn.Forte@Sun.COM 	return (ret);
22957836SJohn.Forte@Sun.COM }
22967836SJohn.Forte@Sun.COM 
22977836SJohn.Forte@Sun.COM /*
22987836SJohn.Forte@Sun.COM  * Print targets
22997836SJohn.Forte@Sun.COM  */
23007836SJohn.Forte@Sun.COM /*ARGSUSED*/
23017836SJohn.Forte@Sun.COM static int
23027836SJohn.Forte@Sun.COM listTarget(int objectLen, char *objects[], cmdOptions_t *options, int *funcRet)
23037836SJohn.Forte@Sun.COM {
23047836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
23057836SJohn.Forte@Sun.COM 	IMA_OID_LIST *targetList;
23067836SJohn.Forte@Sun.COM 	IMA_OID_LIST *lunList;
23077836SJohn.Forte@Sun.COM 	SUN_IMA_TARGET_PROPERTIES targetProps;
23087836SJohn.Forte@Sun.COM 	IMA_STATUS status;
23097836SJohn.Forte@Sun.COM 	IMA_OID_LIST *pConnList;
23107836SJohn.Forte@Sun.COM 	SUN_IMA_CONN_PROPERTIES *connProps;
23117836SJohn.Forte@Sun.COM 
23127836SJohn.Forte@Sun.COM 	int ret;
23137836SJohn.Forte@Sun.COM 	wchar_t targetName[MAX_ISCSI_NAME_LEN + 1];
23147836SJohn.Forte@Sun.COM 	wchar_t targetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
23157836SJohn.Forte@Sun.COM 	int outerLoop;
23167836SJohn.Forte@Sun.COM 	boolean_t found;
23177836SJohn.Forte@Sun.COM 	boolean_t operandEntered = B_FALSE;
23187836SJohn.Forte@Sun.COM 	boolean_t verbose = B_FALSE;
23197836SJohn.Forte@Sun.COM 	boolean_t scsi_target = B_FALSE;
23207836SJohn.Forte@Sun.COM 	boolean_t targetAddressSpecified = B_FALSE;
23217836SJohn.Forte@Sun.COM 	boolean_t isIpv6 = B_FALSE;
23227836SJohn.Forte@Sun.COM 	int i, j;
23237836SJohn.Forte@Sun.COM 	cmdOptions_t *optionList = options;
23247836SJohn.Forte@Sun.COM 	boolean_t tpgtSpecified = B_FALSE;
23257836SJohn.Forte@Sun.COM 	IMA_UINT16 port = 0;
23267836SJohn.Forte@Sun.COM 	uint16_t tpgt;
23277836SJohn.Forte@Sun.COM 
23287836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
23297836SJohn.Forte@Sun.COM 
23307836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
23317836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
23327836SJohn.Forte@Sun.COM 	if (ret > 0) {
23337836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
23347836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
23357836SJohn.Forte@Sun.COM 	}
23367836SJohn.Forte@Sun.COM 
23377836SJohn.Forte@Sun.COM 	if (ret != 0) {
23387836SJohn.Forte@Sun.COM 		return (ret);
23397836SJohn.Forte@Sun.COM 	}
23407836SJohn.Forte@Sun.COM 
23417836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
23427836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
23437836SJohn.Forte@Sun.COM 			case 'S':
23447836SJohn.Forte@Sun.COM 				scsi_target = B_TRUE;
23457836SJohn.Forte@Sun.COM 				break;
23467836SJohn.Forte@Sun.COM 			case 'v':
23477836SJohn.Forte@Sun.COM 				verbose = B_TRUE;
23487836SJohn.Forte@Sun.COM 				break;
23497836SJohn.Forte@Sun.COM 			default:
23507836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %c: %s\n",
23517836SJohn.Forte@Sun.COM 				    cmdName, optionList->optval,
23527836SJohn.Forte@Sun.COM 				    gettext("unknown option"));
23537836SJohn.Forte@Sun.COM 				return (1);
23547836SJohn.Forte@Sun.COM 		}
23557836SJohn.Forte@Sun.COM 	}
23567836SJohn.Forte@Sun.COM 
23577836SJohn.Forte@Sun.COM 	/*
23587836SJohn.Forte@Sun.COM 	 * If there are multiple objects, execute outer 'for' loop that
23597836SJohn.Forte@Sun.COM 	 * many times for each target detail, otherwise, execute it only
23607836SJohn.Forte@Sun.COM 	 * once with summaries only
23617836SJohn.Forte@Sun.COM 	 */
23627836SJohn.Forte@Sun.COM 	if (objectLen > 0) {
23637836SJohn.Forte@Sun.COM 		operandEntered = B_TRUE;
23647836SJohn.Forte@Sun.COM 		outerLoop = objectLen;
23657836SJohn.Forte@Sun.COM 	} else {
23667836SJohn.Forte@Sun.COM 		operandEntered = B_FALSE;
23677836SJohn.Forte@Sun.COM 		outerLoop = 1;
23687836SJohn.Forte@Sun.COM 	}
23697836SJohn.Forte@Sun.COM 
23707836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetSessionOidList(initiatorOid, &targetList);
23717836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
23727836SJohn.Forte@Sun.COM 		printLibError(status);
23737836SJohn.Forte@Sun.COM 		*funcRet = 1;
23747836SJohn.Forte@Sun.COM 		return (ret);
23757836SJohn.Forte@Sun.COM 	}
23767836SJohn.Forte@Sun.COM 
23777836SJohn.Forte@Sun.COM 	for (i = 0; i < outerLoop; i++) {
23787836SJohn.Forte@Sun.COM 
23797836SJohn.Forte@Sun.COM 		tpgtSpecified = B_FALSE;
23807836SJohn.Forte@Sun.COM 		if (operandEntered) {
23817836SJohn.Forte@Sun.COM 			if (parseTarget(objects[i],
23827836SJohn.Forte@Sun.COM 			    &targetName[0],
23837836SJohn.Forte@Sun.COM 			    MAX_ISCSI_NAME_LEN + 1,
23847836SJohn.Forte@Sun.COM 			    &targetAddressSpecified,
23857836SJohn.Forte@Sun.COM 			    &targetAddress[0],
23867836SJohn.Forte@Sun.COM 			    SUN_IMA_IP_ADDRESS_PORT_LEN,
23877836SJohn.Forte@Sun.COM 			    &port,
23887836SJohn.Forte@Sun.COM 			    &tpgtSpecified,
23897836SJohn.Forte@Sun.COM 			    &tpgt,
23907836SJohn.Forte@Sun.COM 			    &isIpv6) != PARSE_TARGET_OK) {
23917836SJohn.Forte@Sun.COM 				ret = 1;
23927836SJohn.Forte@Sun.COM 				continue;
23937836SJohn.Forte@Sun.COM 			}
23947836SJohn.Forte@Sun.COM 		}
23957836SJohn.Forte@Sun.COM 		for (found = B_FALSE, j = 0; j < targetList->oidCount; j++) {
23967836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetTargetProperties(
23977836SJohn.Forte@Sun.COM 			    targetList->oids[j],
23987836SJohn.Forte@Sun.COM 			    &targetProps);
23997836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
24007836SJohn.Forte@Sun.COM 				printLibError(status);
24017836SJohn.Forte@Sun.COM 				(void) IMA_FreeMemory(targetList);
24027836SJohn.Forte@Sun.COM 				*funcRet = 1;
24037836SJohn.Forte@Sun.COM 				return (ret);
24047836SJohn.Forte@Sun.COM 			}
24057836SJohn.Forte@Sun.COM 
24067836SJohn.Forte@Sun.COM 			/*
24077836SJohn.Forte@Sun.COM 			 * Compare the target name with the input if
24087836SJohn.Forte@Sun.COM 			 * one was input, if they match, print the target's info
24097836SJohn.Forte@Sun.COM 			 *
24107836SJohn.Forte@Sun.COM 			 * if no target name was input, continue printing this
24117836SJohn.Forte@Sun.COM 			 * target
24127836SJohn.Forte@Sun.COM 			 */
24137836SJohn.Forte@Sun.COM 			if (operandEntered) {
24147836SJohn.Forte@Sun.COM 				if (targetNamesEqual(targetProps.imaProps.name,
24157836SJohn.Forte@Sun.COM 				    targetName) == B_TRUE) {
24167836SJohn.Forte@Sun.COM 					if (tpgtSpecified == B_TRUE) {
24177836SJohn.Forte@Sun.COM 						if (targetProps.
24187836SJohn.Forte@Sun.COM 						    defaultTpgtConf ==
24197836SJohn.Forte@Sun.COM 						    IMA_FALSE &&
24207836SJohn.Forte@Sun.COM 						    targetProps.
24217836SJohn.Forte@Sun.COM 						    tpgtConf == tpgt) {
24227836SJohn.Forte@Sun.COM 							found = B_TRUE;
24237836SJohn.Forte@Sun.COM 						} else {
24247836SJohn.Forte@Sun.COM 							/*
24257836SJohn.Forte@Sun.COM 							 * tpgt does not match,
24267836SJohn.Forte@Sun.COM 							 * move on to next
24277836SJohn.Forte@Sun.COM 							 * target
24287836SJohn.Forte@Sun.COM 							 */
24297836SJohn.Forte@Sun.COM 							continue;
24307836SJohn.Forte@Sun.COM 						}
24317836SJohn.Forte@Sun.COM 					} else {
24327836SJohn.Forte@Sun.COM 						found = B_TRUE;
24337836SJohn.Forte@Sun.COM 					}
24347836SJohn.Forte@Sun.COM 				} else {
24357836SJohn.Forte@Sun.COM 					/*
24367836SJohn.Forte@Sun.COM 					 * target name does not match, move on
24377836SJohn.Forte@Sun.COM 					 * to next target
24387836SJohn.Forte@Sun.COM 					 */
24397836SJohn.Forte@Sun.COM 					continue;
24407836SJohn.Forte@Sun.COM 				}
24417836SJohn.Forte@Sun.COM 			}
24427836SJohn.Forte@Sun.COM 
24437836SJohn.Forte@Sun.COM 			/* print summary - always */
24447836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, gettext("%s: %ws\n"),
24457836SJohn.Forte@Sun.COM 			    gettext("Target"), targetProps.imaProps.name);
24467836SJohn.Forte@Sun.COM 
24477836SJohn.Forte@Sun.COM 			/* Alias */
24487836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "\t%s: ", gettext("Alias"));
24497836SJohn.Forte@Sun.COM 			if (wslen(targetProps.imaProps.alias) > (size_t)0) {
24507836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, gettext("%ws\n"),
24517836SJohn.Forte@Sun.COM 				    targetProps.imaProps.alias);
24527836SJohn.Forte@Sun.COM 			} else {
24537836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "%s\n", "-");
24547836SJohn.Forte@Sun.COM 			}
24557836SJohn.Forte@Sun.COM 
24567836SJohn.Forte@Sun.COM 			if (targetProps.defaultTpgtNego != IMA_TRUE) {
24577836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "%s%s: %d\n",
24587836SJohn.Forte@Sun.COM 				    "\t", gettext("TPGT"),
24597836SJohn.Forte@Sun.COM 				    targetProps.tpgtNego);
24607836SJohn.Forte@Sun.COM 			} else if (targetProps.defaultTpgtConf != IMA_TRUE) {
24617836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "%s%s: %d\n",
24627836SJohn.Forte@Sun.COM 				    "\t", gettext("TPGT"),
24637836SJohn.Forte@Sun.COM 				    targetProps.tpgtConf);
24647836SJohn.Forte@Sun.COM 			}
24657836SJohn.Forte@Sun.COM 
24667836SJohn.Forte@Sun.COM 			(void) fprintf(stdout,
24677836SJohn.Forte@Sun.COM 			    "%s%s: %02x%02x%02x%02x%02x%02x\n",
24687836SJohn.Forte@Sun.COM 			    "\t", gettext("ISID"),
24697836SJohn.Forte@Sun.COM 			    targetProps.isid[0], targetProps.isid[1],
24707836SJohn.Forte@Sun.COM 			    targetProps.isid[2], targetProps.isid[3],
24717836SJohn.Forte@Sun.COM 			    targetProps.isid[4], targetProps.isid[5]);
24727836SJohn.Forte@Sun.COM 
24737836SJohn.Forte@Sun.COM 			pConnList = NULL;
24747836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetConnOidList(
24757836SJohn.Forte@Sun.COM 			    &targetList->oids[j],
24767836SJohn.Forte@Sun.COM 			    &pConnList);
24777836SJohn.Forte@Sun.COM 
24787836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
24797836SJohn.Forte@Sun.COM 				printLibError(status);
24807836SJohn.Forte@Sun.COM 				(void) IMA_FreeMemory(targetList);
24817836SJohn.Forte@Sun.COM 				*funcRet = 1;
24827836SJohn.Forte@Sun.COM 				return (ret);
24837836SJohn.Forte@Sun.COM 			}
24847836SJohn.Forte@Sun.COM 
24857836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s%s: %lu\n",
24867836SJohn.Forte@Sun.COM 			    "\t",
24877836SJohn.Forte@Sun.COM 			    gettext("Connections"),
24887836SJohn.Forte@Sun.COM 			    pConnList->oidCount);
24897836SJohn.Forte@Sun.COM 
24907836SJohn.Forte@Sun.COM 			if (verbose) {
24917836SJohn.Forte@Sun.COM 				SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms;
24927836SJohn.Forte@Sun.COM 
24937836SJohn.Forte@Sun.COM 				printConnectionList("\t\t", pConnList);
24947836SJohn.Forte@Sun.COM 				printDiscoveryMethod(
24957836SJohn.Forte@Sun.COM 				    "\t\t  ",
24967836SJohn.Forte@Sun.COM 				    targetProps.imaProps.discoveryMethodFlags);
24977836SJohn.Forte@Sun.COM 				(void) printLoginParameters(
24987836SJohn.Forte@Sun.COM 				    "\t\t  ",
24997836SJohn.Forte@Sun.COM 				    targetList->oids[j],
25007836SJohn.Forte@Sun.COM 				    PRINT_NEGOTIATED_PARAMS);
25017836SJohn.Forte@Sun.COM 
25027836SJohn.Forte@Sun.COM 				/* Get Digest configuration */
25037836SJohn.Forte@Sun.COM 				status = SUN_IMA_GetConnProperties(
25047836SJohn.Forte@Sun.COM 				    &pConnList->oids[0], &connProps);
25057836SJohn.Forte@Sun.COM 
25067836SJohn.Forte@Sun.COM 				(void) getNegotiatedDigest(
25077836SJohn.Forte@Sun.COM 				    ISCSI_LOGIN_PARAM_HEADER_DIGEST,
25087836SJohn.Forte@Sun.COM 				    &digestAlgorithms, connProps);
25097836SJohn.Forte@Sun.COM 
25107836SJohn.Forte@Sun.COM 				if (IMA_SUCCESS(status)) {
25117836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "\t\t  \t%s: ",
25127836SJohn.Forte@Sun.COM 					    gettext("Header Digest"));
25137836SJohn.Forte@Sun.COM 					printDigestAlgorithm(
25147836SJohn.Forte@Sun.COM 					    &digestAlgorithms,
25157836SJohn.Forte@Sun.COM 					    PRINT_NEGOTIATED_PARAMS);
25167836SJohn.Forte@Sun.COM 				} else {
25177836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(pConnList);
25187836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(targetList);
25197836SJohn.Forte@Sun.COM 					printLibError(status);
25207836SJohn.Forte@Sun.COM 					*funcRet = 1;
25217836SJohn.Forte@Sun.COM 					return (ret);
25227836SJohn.Forte@Sun.COM 				}
25237836SJohn.Forte@Sun.COM 
25247836SJohn.Forte@Sun.COM 				(void) getNegotiatedDigest(
25257836SJohn.Forte@Sun.COM 				    ISCSI_LOGIN_PARAM_DATA_DIGEST,
25267836SJohn.Forte@Sun.COM 				    &digestAlgorithms, connProps);
25277836SJohn.Forte@Sun.COM 
25287836SJohn.Forte@Sun.COM 				if (IMA_SUCCESS(status)) {
25297836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "\t\t  \t%s: ",
25307836SJohn.Forte@Sun.COM 					    gettext("Data Digest"));
25317836SJohn.Forte@Sun.COM 					printDigestAlgorithm(
25327836SJohn.Forte@Sun.COM 					    &digestAlgorithms,
25337836SJohn.Forte@Sun.COM 					    PRINT_NEGOTIATED_PARAMS);
25347836SJohn.Forte@Sun.COM 				} else {
25357836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(pConnList);
25367836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(targetList);
25377836SJohn.Forte@Sun.COM 					printLibError(status);
25387836SJohn.Forte@Sun.COM 					*funcRet = 1;
25397836SJohn.Forte@Sun.COM 					return (ret);
25407836SJohn.Forte@Sun.COM 				}
25417836SJohn.Forte@Sun.COM 
25427836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\n");
25437836SJohn.Forte@Sun.COM 			}
25447836SJohn.Forte@Sun.COM 
25457836SJohn.Forte@Sun.COM 			if (scsi_target) {
25467836SJohn.Forte@Sun.COM 				status = IMA_GetLuOidList(
25477836SJohn.Forte@Sun.COM 				    targetList->oids[j],
25487836SJohn.Forte@Sun.COM 				    &lunList);
25497836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
25507836SJohn.Forte@Sun.COM 					printLibError(status);
25517836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(targetList);
25527836SJohn.Forte@Sun.COM 					*funcRet = 1;
25537836SJohn.Forte@Sun.COM 					return (ret);
25547836SJohn.Forte@Sun.COM 				}
25557836SJohn.Forte@Sun.COM 				if (lunList->oidCount != 0) {
25567836SJohn.Forte@Sun.COM 					printTargetLuns(lunList);
25577836SJohn.Forte@Sun.COM 				}
25587836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\n");
25597836SJohn.Forte@Sun.COM 				(void) IMA_FreeMemory(lunList);
25607836SJohn.Forte@Sun.COM 			}
25617836SJohn.Forte@Sun.COM 		}
25627836SJohn.Forte@Sun.COM 		/*
25637836SJohn.Forte@Sun.COM 		 * did we find the object
25647836SJohn.Forte@Sun.COM 		 */
25657836SJohn.Forte@Sun.COM 
25667836SJohn.Forte@Sun.COM 		if (operandEntered && !found) {
25677836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s: %s\n",
25687836SJohn.Forte@Sun.COM 			    objects[i], gettext("not found"));
25697836SJohn.Forte@Sun.COM 		}
25707836SJohn.Forte@Sun.COM 	}
25717836SJohn.Forte@Sun.COM 
25727836SJohn.Forte@Sun.COM 	(void) IMA_FreeMemory(targetList);
25737836SJohn.Forte@Sun.COM 	return (ret);
25747836SJohn.Forte@Sun.COM }
25757836SJohn.Forte@Sun.COM 
25767836SJohn.Forte@Sun.COM 
25777836SJohn.Forte@Sun.COM /*
25787836SJohn.Forte@Sun.COM  * Print configured session information
25797836SJohn.Forte@Sun.COM  */
25807836SJohn.Forte@Sun.COM static int
25817836SJohn.Forte@Sun.COM printConfiguredSessions(IMA_OID oid)
25827836SJohn.Forte@Sun.COM {
25837836SJohn.Forte@Sun.COM 	IMA_STATUS		status;
25847836SJohn.Forte@Sun.COM 	const char		*rtn;
25857836SJohn.Forte@Sun.COM 	SUN_IMA_CONFIG_SESSIONS	*pConfigSessions;
25867836SJohn.Forte@Sun.COM 	char			address[MAX_ADDRESS_LEN];
25877836SJohn.Forte@Sun.COM 	int			out;
25887836SJohn.Forte@Sun.COM 
25897836SJohn.Forte@Sun.COM 	/* Get configured session information */
25907836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetConfigSessions(oid, &pConfigSessions);
25917836SJohn.Forte@Sun.COM 
25927836SJohn.Forte@Sun.COM 	if (IMA_SUCCESS(status)) {
25937836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "\t%s: ",
25947836SJohn.Forte@Sun.COM 		    gettext("Configured Sessions"));
25957836SJohn.Forte@Sun.COM 		if (pConfigSessions->bound == IMA_FALSE) {
25967836SJohn.Forte@Sun.COM 			/* default binding */
25977836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%lu\n", pConfigSessions->out);
25987836SJohn.Forte@Sun.COM 		} else {
25997836SJohn.Forte@Sun.COM 			/* hardcoded binding */
26007836SJohn.Forte@Sun.COM 			for (out = 0;
26017836SJohn.Forte@Sun.COM 			    out < pConfigSessions->out; out++) {
26027836SJohn.Forte@Sun.COM 				if (pConfigSessions->bindings[out].
26037836SJohn.Forte@Sun.COM 				    ipAddress.ipv4Address == IMA_TRUE) {
26047836SJohn.Forte@Sun.COM 					rtn = inet_ntop(AF_INET,
26057836SJohn.Forte@Sun.COM 					    pConfigSessions->bindings[out].
26067836SJohn.Forte@Sun.COM 					    ipAddress.ipAddress, address,
26077836SJohn.Forte@Sun.COM 					    MAX_ADDRESS_LEN);
26087836SJohn.Forte@Sun.COM 				} else {
26097836SJohn.Forte@Sun.COM 					rtn = inet_ntop(AF_INET6,
26107836SJohn.Forte@Sun.COM 					    pConfigSessions->bindings[out].
26117836SJohn.Forte@Sun.COM 					    ipAddress.ipAddress, address,
26127836SJohn.Forte@Sun.COM 					    MAX_ADDRESS_LEN);
26137836SJohn.Forte@Sun.COM 				}
26147836SJohn.Forte@Sun.COM 				if (rtn != NULL) {
26157836SJohn.Forte@Sun.COM 					(void) printf("%s ", address);
26167836SJohn.Forte@Sun.COM 				}
26177836SJohn.Forte@Sun.COM 			}
26187836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "\n");
26197836SJohn.Forte@Sun.COM 		}
26207836SJohn.Forte@Sun.COM 	} else {
26217836SJohn.Forte@Sun.COM 		free(pConfigSessions);
26227836SJohn.Forte@Sun.COM 		printLibError(status);
26237836SJohn.Forte@Sun.COM 		return (1);
26247836SJohn.Forte@Sun.COM 	}
26257836SJohn.Forte@Sun.COM 
26267836SJohn.Forte@Sun.COM 	free(pConfigSessions);
26277836SJohn.Forte@Sun.COM 	return (0);
26287836SJohn.Forte@Sun.COM }
26297836SJohn.Forte@Sun.COM 
26307836SJohn.Forte@Sun.COM /*
26317836SJohn.Forte@Sun.COM  * Print target parameters
26327836SJohn.Forte@Sun.COM  */
26337836SJohn.Forte@Sun.COM static int
26347836SJohn.Forte@Sun.COM listTargetParam(int operandLen, char *operand[], cmdOptions_t *options,
26357836SJohn.Forte@Sun.COM     int *funcRet)
26367836SJohn.Forte@Sun.COM {
26377836SJohn.Forte@Sun.COM 	IMA_STATUS status;
26387836SJohn.Forte@Sun.COM 	IMA_OID	initiatorOid;
26397836SJohn.Forte@Sun.COM 	IMA_OID_LIST *targetList;
26407836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD	methodList[MAX_AUTH_METHODS];
26417836SJohn.Forte@Sun.COM 	SUN_IMA_TARGET_PROPERTIES targetProps;
26427836SJohn.Forte@Sun.COM 	IMA_UINT maxEntries = MAX_AUTH_METHODS;
26437836SJohn.Forte@Sun.COM 	IMA_BOOL bidirAuth;
26447836SJohn.Forte@Sun.COM 	int ret;
26457836SJohn.Forte@Sun.COM 	wchar_t targetName[MAX_ISCSI_NAME_LEN + 1];
26467836SJohn.Forte@Sun.COM 	wchar_t targetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
26477836SJohn.Forte@Sun.COM 	boolean_t operandEntered = B_FALSE;
26487836SJohn.Forte@Sun.COM 	boolean_t targetAddressSpecified = B_FALSE;
26497836SJohn.Forte@Sun.COM 	boolean_t printObject = B_FALSE;
26507836SJohn.Forte@Sun.COM 	boolean_t tpgtSpecified = B_FALSE;
26517836SJohn.Forte@Sun.COM 	boolean_t isIpv6 = B_FALSE;
26527836SJohn.Forte@Sun.COM 	int outerLoop;
26537836SJohn.Forte@Sun.COM 	boolean_t found;
26547836SJohn.Forte@Sun.COM 	int i, j;
26557836SJohn.Forte@Sun.COM 	SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms;
26567836SJohn.Forte@Sun.COM 	boolean_t verbose = B_FALSE;
26577836SJohn.Forte@Sun.COM 	cmdOptions_t *optionList = options;
26587836SJohn.Forte@Sun.COM 	IMA_UINT16 port = 0;
26597836SJohn.Forte@Sun.COM 	IMA_UINT16 tpgt = 0;
26607836SJohn.Forte@Sun.COM 
26617836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
26627836SJohn.Forte@Sun.COM 
26637836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
26647836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
26657836SJohn.Forte@Sun.COM 	if (ret > 0) {
26667836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
26677836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
26687836SJohn.Forte@Sun.COM 	}
26697836SJohn.Forte@Sun.COM 
26707836SJohn.Forte@Sun.COM 	if (ret != 0) {
26717836SJohn.Forte@Sun.COM 		return (ret);
26727836SJohn.Forte@Sun.COM 	}
26737836SJohn.Forte@Sun.COM 
26747836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
26757836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
26767836SJohn.Forte@Sun.COM 			case 'v':
26777836SJohn.Forte@Sun.COM 				verbose = B_TRUE;
26787836SJohn.Forte@Sun.COM 				break;
26797836SJohn.Forte@Sun.COM 			default:
26807836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %c: %s\n",
26817836SJohn.Forte@Sun.COM 				    cmdName, optionList->optval,
26827836SJohn.Forte@Sun.COM 				    gettext("unknown option"));
26837836SJohn.Forte@Sun.COM 				return (1);
26847836SJohn.Forte@Sun.COM 		}
26857836SJohn.Forte@Sun.COM 	}
26867836SJohn.Forte@Sun.COM 
26877836SJohn.Forte@Sun.COM 	/*
26887836SJohn.Forte@Sun.COM 	 * If there are multiple operands, execute outer 'for' loop that
26897836SJohn.Forte@Sun.COM 	 * many times to find each target parameter operand entered, otherwise,
26907836SJohn.Forte@Sun.COM 	 * execute it only once for all target parameters returned.
26917836SJohn.Forte@Sun.COM 	 */
26927836SJohn.Forte@Sun.COM 	if (operandLen > 0) {
26937836SJohn.Forte@Sun.COM 		operandEntered = B_TRUE;
26947836SJohn.Forte@Sun.COM 		outerLoop = operandLen;
26957836SJohn.Forte@Sun.COM 	} else {
26967836SJohn.Forte@Sun.COM 		operandEntered = B_FALSE;
26977836SJohn.Forte@Sun.COM 		outerLoop = 1;
26987836SJohn.Forte@Sun.COM 	}
26997836SJohn.Forte@Sun.COM 
27007836SJohn.Forte@Sun.COM 	/*
27017836SJohn.Forte@Sun.COM 	 * Ideally there should be an interface available for obtaining
27027836SJohn.Forte@Sun.COM 	 * the list of target-param objects. Since the driver currently
27037836SJohn.Forte@Sun.COM 	 * creates a target OID and the associated session structure when
27047836SJohn.Forte@Sun.COM 	 * a target-param object is created, we can leverage the target
27057836SJohn.Forte@Sun.COM 	 * OID list and use it to manage the target-param objects. When
27067836SJohn.Forte@Sun.COM 	 * we stop creating a session for target-param object in the
27077836SJohn.Forte@Sun.COM 	 * driver, we will switch to using a different interface to
27087836SJohn.Forte@Sun.COM 	 * obtain target-param objects.
27097836SJohn.Forte@Sun.COM 	 */
27107836SJohn.Forte@Sun.COM 	status = IMA_GetTargetOidList(initiatorOid, &targetList);
27117836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
27127836SJohn.Forte@Sun.COM 		printLibError(status);
27137836SJohn.Forte@Sun.COM 		*funcRet = 1;
27147836SJohn.Forte@Sun.COM 		return (ret);
27157836SJohn.Forte@Sun.COM 	}
27167836SJohn.Forte@Sun.COM 
27177836SJohn.Forte@Sun.COM 	for (i = 0; i < outerLoop; i++) {
27187836SJohn.Forte@Sun.COM 		if (operandEntered) {
27197836SJohn.Forte@Sun.COM 			if (parseTarget(operand[i],
27207836SJohn.Forte@Sun.COM 			    &targetName[0],
27217836SJohn.Forte@Sun.COM 			    MAX_ISCSI_NAME_LEN + 1,
27227836SJohn.Forte@Sun.COM 			    &targetAddressSpecified,
27237836SJohn.Forte@Sun.COM 			    &targetAddress[0],
27247836SJohn.Forte@Sun.COM 			    SUN_IMA_IP_ADDRESS_PORT_LEN,
27257836SJohn.Forte@Sun.COM 			    &port,
27267836SJohn.Forte@Sun.COM 			    &tpgtSpecified,
27277836SJohn.Forte@Sun.COM 			    &tpgt,
27287836SJohn.Forte@Sun.COM 			    &isIpv6) != PARSE_TARGET_OK) {
27297836SJohn.Forte@Sun.COM 				ret = 1;
27307836SJohn.Forte@Sun.COM 				continue;
27317836SJohn.Forte@Sun.COM 			}
27327836SJohn.Forte@Sun.COM 		}
27337836SJohn.Forte@Sun.COM 		for (j = 0; j < targetList->oidCount; j++) {
27347836SJohn.Forte@Sun.COM 			found = B_FALSE;
27357836SJohn.Forte@Sun.COM 			printObject = B_FALSE;
27367836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetTargetProperties(
27377836SJohn.Forte@Sun.COM 			    targetList->oids[j],
27387836SJohn.Forte@Sun.COM 			    &targetProps);
27397836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
27407836SJohn.Forte@Sun.COM 				printLibError(status);
27417836SJohn.Forte@Sun.COM 				(void) IMA_FreeMemory(targetList);
27427836SJohn.Forte@Sun.COM 				*funcRet = 1;
27437836SJohn.Forte@Sun.COM 				return (ret);
27447836SJohn.Forte@Sun.COM 			}
27457836SJohn.Forte@Sun.COM 
27467836SJohn.Forte@Sun.COM 			/*
27477836SJohn.Forte@Sun.COM 			 * Compare the target name with the input if
27487836SJohn.Forte@Sun.COM 			 * one was input
27497836SJohn.Forte@Sun.COM 			 */
27507836SJohn.Forte@Sun.COM 			if (operandEntered &&
27517836SJohn.Forte@Sun.COM 			    (targetNamesEqual(targetProps.imaProps.name,
27527836SJohn.Forte@Sun.COM 			    targetName) == B_TRUE)) {
27537836SJohn.Forte@Sun.COM 				/*
27547836SJohn.Forte@Sun.COM 				 * For now, regardless of whether a target
27557836SJohn.Forte@Sun.COM 				 * address is specified, we return B_TRUE
27567836SJohn.Forte@Sun.COM 				 * because IMA_TARGET_PROPERTIES does not
27577836SJohn.Forte@Sun.COM 				 * have a field for specifying address.
27587836SJohn.Forte@Sun.COM 				 */
27597836SJohn.Forte@Sun.COM 				found = B_TRUE;
27607836SJohn.Forte@Sun.COM 			}
27617836SJohn.Forte@Sun.COM 
27627836SJohn.Forte@Sun.COM 			/*
27637836SJohn.Forte@Sun.COM 			 * if no operand was entered OR
27647836SJohn.Forte@Sun.COM 			 * an operand was entered and it was
27657836SJohn.Forte@Sun.COM 			 * found, we want to print
27667836SJohn.Forte@Sun.COM 			 */
27677836SJohn.Forte@Sun.COM 			if (!operandEntered || found) {
27687836SJohn.Forte@Sun.COM 				printObject = B_TRUE;
27697836SJohn.Forte@Sun.COM 			}
27707836SJohn.Forte@Sun.COM 
27717836SJohn.Forte@Sun.COM 			if (printObject) {
27727836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, gettext("%s: %ws\n"),
27737836SJohn.Forte@Sun.COM 				    gettext("Target"),
27747836SJohn.Forte@Sun.COM 				    targetProps.imaProps.name);
27757836SJohn.Forte@Sun.COM 
27767836SJohn.Forte@Sun.COM 				(void) fprintf(stdout,
27777836SJohn.Forte@Sun.COM 				    "\t%s: ", gettext("Alias"));
27787836SJohn.Forte@Sun.COM 				if (wslen(targetProps.imaProps.alias) >
27797836SJohn.Forte@Sun.COM 				    (size_t)0) {
27807836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
27817836SJohn.Forte@Sun.COM 					    gettext("%ws\n"),
27827836SJohn.Forte@Sun.COM 					    targetProps.imaProps.alias);
27837836SJohn.Forte@Sun.COM 				} else {
27847836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "%s\n", "-");
27857836SJohn.Forte@Sun.COM 				}
27867836SJohn.Forte@Sun.COM 			}
27877836SJohn.Forte@Sun.COM 
27887836SJohn.Forte@Sun.COM 			if (printObject && verbose) {
27897836SJohn.Forte@Sun.COM 				/* Get bidirectional authentication flag */
27907836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\t%s: ",
27917836SJohn.Forte@Sun.COM 				    gettext("Bi-directional Authentication"));
27927836SJohn.Forte@Sun.COM 				status = SUN_IMA_GetTargetBidirAuthFlag(
27937836SJohn.Forte@Sun.COM 				    targetList->oids[j],
27947836SJohn.Forte@Sun.COM 				    &bidirAuth);
27957836SJohn.Forte@Sun.COM 				if (IMA_SUCCESS(status)) {
27967836SJohn.Forte@Sun.COM 					if (bidirAuth == IMA_TRUE) {
27977836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
27987836SJohn.Forte@Sun.COM 						    gettext("enabled"));
27997836SJohn.Forte@Sun.COM 					} else {
28007836SJohn.Forte@Sun.COM 						(void) fprintf(stdout,
28017836SJohn.Forte@Sun.COM 						    gettext("disabled"));
28027836SJohn.Forte@Sun.COM 					}
28037836SJohn.Forte@Sun.COM 				} else {
28047836SJohn.Forte@Sun.COM 					(void) fprintf(stdout,
28057836SJohn.Forte@Sun.COM 					    gettext("disabled"));
28067836SJohn.Forte@Sun.COM 				}
28077836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\n");
28087836SJohn.Forte@Sun.COM 
28097836SJohn.Forte@Sun.COM 				/* Get authentication type for this target */
28107836SJohn.Forte@Sun.COM 				status = SUN_IMA_GetTargetAuthMethods(
28117836SJohn.Forte@Sun.COM 				    initiatorOid,
28127836SJohn.Forte@Sun.COM 				    targetList->oids[j],
28137836SJohn.Forte@Sun.COM 				    &maxEntries,
28147836SJohn.Forte@Sun.COM 				    &methodList[0]);
28157836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\t%s: ",
28167836SJohn.Forte@Sun.COM 				    gettext("Authentication Type"));
28177836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
28187836SJohn.Forte@Sun.COM 					/*
28197836SJohn.Forte@Sun.COM 					 * No authentication method define
28207836SJohn.Forte@Sun.COM 					 * NONE by default.
28217836SJohn.Forte@Sun.COM 					 */
28227836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, gettext("NONE"));
28237836SJohn.Forte@Sun.COM 				} else {
28247836SJohn.Forte@Sun.COM 					for (i = 0; i < maxEntries; i++) {
28257836SJohn.Forte@Sun.COM 						if (i > 0) {
28267836SJohn.Forte@Sun.COM 							(void) fprintf(stdout,
28277836SJohn.Forte@Sun.COM 							    "|");
28287836SJohn.Forte@Sun.COM 						}
28297836SJohn.Forte@Sun.COM 						switch (methodList[i]) {
28307836SJohn.Forte@Sun.COM 						case IMA_AUTHMETHOD_NONE:
28317836SJohn.Forte@Sun.COM 							(void) fprintf(stdout,
28327836SJohn.Forte@Sun.COM 							    gettext("NONE"));
28337836SJohn.Forte@Sun.COM 							break;
28347836SJohn.Forte@Sun.COM 
28357836SJohn.Forte@Sun.COM 						case IMA_AUTHMETHOD_CHAP:
28367836SJohn.Forte@Sun.COM 							(void) fprintf(stdout,
28377836SJohn.Forte@Sun.COM 							    gettext("CHAP"));
28387836SJohn.Forte@Sun.COM 							listCHAPName(
28397836SJohn.Forte@Sun.COM 							    targetList->
28407836SJohn.Forte@Sun.COM 							    oids[j]);
28417836SJohn.Forte@Sun.COM 							break;
28427836SJohn.Forte@Sun.COM 
28437836SJohn.Forte@Sun.COM 						default:
28447836SJohn.Forte@Sun.COM 							(void) fprintf(stdout,
28457836SJohn.Forte@Sun.COM 							    gettext(
28467836SJohn.Forte@Sun.COM 							    "unknown "
28477836SJohn.Forte@Sun.COM 							    "type"));
28487836SJohn.Forte@Sun.COM 							break;
28497836SJohn.Forte@Sun.COM 						}
28507836SJohn.Forte@Sun.COM 					}
28517836SJohn.Forte@Sun.COM 				}
28527836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\n");
28537836SJohn.Forte@Sun.COM 				if (printLoginParameters("\t",
28547836SJohn.Forte@Sun.COM 				    targetList->oids[j],
28557836SJohn.Forte@Sun.COM 				    PRINT_CONFIGURED_PARAMS)
28567836SJohn.Forte@Sun.COM 				    != 0) {
28577836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(targetList);
28587836SJohn.Forte@Sun.COM 					*funcRet = 1;
28597836SJohn.Forte@Sun.COM 					return (ret);
28607836SJohn.Forte@Sun.COM 				}
28617836SJohn.Forte@Sun.COM 
28627836SJohn.Forte@Sun.COM 				/* Get Digest configuration */
28637836SJohn.Forte@Sun.COM 				status = SUN_IMA_GetHeaderDigest(
28647836SJohn.Forte@Sun.COM 				    targetList->oids[j],
28657836SJohn.Forte@Sun.COM 				    &digestAlgorithms);
28667836SJohn.Forte@Sun.COM 				if (IMA_SUCCESS(status)) {
28677836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "\t\t%s: ",
28687836SJohn.Forte@Sun.COM 					    gettext("Header Digest"));
28697836SJohn.Forte@Sun.COM 					printDigestAlgorithm(&digestAlgorithms,
28707836SJohn.Forte@Sun.COM 					    PRINT_CONFIGURED_PARAMS);
28717836SJohn.Forte@Sun.COM 				} else {
28727836SJohn.Forte@Sun.COM 					printLibError(status);
28737836SJohn.Forte@Sun.COM 					*funcRet = 1;
28747836SJohn.Forte@Sun.COM 					return (ret);
28757836SJohn.Forte@Sun.COM 				}
28767836SJohn.Forte@Sun.COM 
28777836SJohn.Forte@Sun.COM 				status = SUN_IMA_GetDataDigest(
28787836SJohn.Forte@Sun.COM 				    targetList->oids[j],
28797836SJohn.Forte@Sun.COM 				    &digestAlgorithms);
28807836SJohn.Forte@Sun.COM 				if (IMA_SUCCESS(status)) {
28817836SJohn.Forte@Sun.COM 					(void) fprintf(stdout, "\t\t%s: ",
28827836SJohn.Forte@Sun.COM 					    gettext("Data Digest"));
28837836SJohn.Forte@Sun.COM 					printDigestAlgorithm(&digestAlgorithms,
28847836SJohn.Forte@Sun.COM 					    PRINT_CONFIGURED_PARAMS);
28857836SJohn.Forte@Sun.COM 				} else {
28867836SJohn.Forte@Sun.COM 					printLibError(status);
28877836SJohn.Forte@Sun.COM 					*funcRet = 1;
28887836SJohn.Forte@Sun.COM 					return (ret);
28897836SJohn.Forte@Sun.COM 				}
28907836SJohn.Forte@Sun.COM 
28917836SJohn.Forte@Sun.COM 				/* print configured session information */
28927836SJohn.Forte@Sun.COM 				if (printConfiguredSessions(
28937836SJohn.Forte@Sun.COM 				    targetList->oids[j]) != 0) {
28947836SJohn.Forte@Sun.COM 					*funcRet = 1;
28957836SJohn.Forte@Sun.COM 					return (ret);
28967836SJohn.Forte@Sun.COM 				}
28977836SJohn.Forte@Sun.COM 
28987836SJohn.Forte@Sun.COM 				(void) fprintf(stdout, "\n");
28997836SJohn.Forte@Sun.COM 			}
29007836SJohn.Forte@Sun.COM 
29017836SJohn.Forte@Sun.COM 			if (found) {
29027836SJohn.Forte@Sun.COM 				break;
29037836SJohn.Forte@Sun.COM 			}
29047836SJohn.Forte@Sun.COM 		}
29057836SJohn.Forte@Sun.COM 		if (operandEntered && !found) {
29067836SJohn.Forte@Sun.COM 			*funcRet = 1; /* DIY message fix */
29077836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s: %s\n",
29087836SJohn.Forte@Sun.COM 			    operand[i], gettext("not found"));
29097836SJohn.Forte@Sun.COM 		}
29107836SJohn.Forte@Sun.COM 	}
29117836SJohn.Forte@Sun.COM 
29127836SJohn.Forte@Sun.COM 	(void) IMA_FreeMemory(targetList);
29137836SJohn.Forte@Sun.COM 	return (ret);
29147836SJohn.Forte@Sun.COM }
29157836SJohn.Forte@Sun.COM 
29167836SJohn.Forte@Sun.COM /*
29177836SJohn.Forte@Sun.COM  * Modify discovery attributes
29187836SJohn.Forte@Sun.COM  */
29197836SJohn.Forte@Sun.COM static int
29207836SJohn.Forte@Sun.COM modifyDiscovery(cmdOptions_t *options, int *funcRet)
29217836SJohn.Forte@Sun.COM {
29227836SJohn.Forte@Sun.COM 	IMA_OID oid;
29237836SJohn.Forte@Sun.COM 	IMA_STATUS status;
29247836SJohn.Forte@Sun.COM 	IMA_BOOL setDiscovery;
29257836SJohn.Forte@Sun.COM 	IMA_HOST_ID hostId;
29267836SJohn.Forte@Sun.COM 
29277836SJohn.Forte@Sun.COM 	int ret;
29287836SJohn.Forte@Sun.COM 	cmdOptions_t *optionList = options;
29297836SJohn.Forte@Sun.COM 
29307836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
29317836SJohn.Forte@Sun.COM 
29327836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
29337836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&oid);
29347836SJohn.Forte@Sun.COM 	if (ret > 0) {
29357836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
29367836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
29377836SJohn.Forte@Sun.COM 	}
29387836SJohn.Forte@Sun.COM 
29397836SJohn.Forte@Sun.COM 	if (ret != 0) {
29407836SJohn.Forte@Sun.COM 		return (ret);
29417836SJohn.Forte@Sun.COM 	}
29427836SJohn.Forte@Sun.COM 
29437836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
29447836SJohn.Forte@Sun.COM 		/* check optarg and set bool accordingly */
29457836SJohn.Forte@Sun.COM 		if (strcasecmp(optionList->optarg, ISCSIADM_ARG_ENABLE) == 0) {
29467836SJohn.Forte@Sun.COM 			setDiscovery = IMA_TRUE;
29477836SJohn.Forte@Sun.COM 		} else if (strcasecmp(optionList->optarg, ISCSIADM_ARG_DISABLE)
29487836SJohn.Forte@Sun.COM 		    == 0) {
29497836SJohn.Forte@Sun.COM 			setDiscovery = IMA_FALSE;
29507836SJohn.Forte@Sun.COM 		} else {
29517836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
29527836SJohn.Forte@Sun.COM 			    cmdName, gettext("invalid option argument"));
29537836SJohn.Forte@Sun.COM 			return (1);
29547836SJohn.Forte@Sun.COM 		}
29557836SJohn.Forte@Sun.COM 
29567836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
29577836SJohn.Forte@Sun.COM 			case 's':
29587836SJohn.Forte@Sun.COM 				/* Set static discovery */
29597836SJohn.Forte@Sun.COM 				status = IMA_SetStaticDiscovery(oid,
29607836SJohn.Forte@Sun.COM 				    setDiscovery);
29617836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
29627836SJohn.Forte@Sun.COM 					printLibError(status);
29637836SJohn.Forte@Sun.COM 					*funcRet = 1;
29647836SJohn.Forte@Sun.COM 					return (ret);
29657836SJohn.Forte@Sun.COM 				}
29667836SJohn.Forte@Sun.COM 				break;
29677836SJohn.Forte@Sun.COM 			case 't':
29687836SJohn.Forte@Sun.COM 				/* Set send targets discovery */
29697836SJohn.Forte@Sun.COM 				status = IMA_SetSendTargetsDiscovery(oid,
29707836SJohn.Forte@Sun.COM 				    setDiscovery);
29717836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
29727836SJohn.Forte@Sun.COM 					printLibError(status);
29737836SJohn.Forte@Sun.COM 					*funcRet = 1;
29747836SJohn.Forte@Sun.COM 					return (ret);
29757836SJohn.Forte@Sun.COM 				}
29767836SJohn.Forte@Sun.COM 				break;
29777836SJohn.Forte@Sun.COM 			case 'i':
29787836SJohn.Forte@Sun.COM 				/* Set iSNS discovery */
29797836SJohn.Forte@Sun.COM 				(void) memset(&hostId, 0, sizeof (hostId));
29807836SJohn.Forte@Sun.COM 				status = IMA_SetIsnsDiscovery(oid, setDiscovery,
29817836SJohn.Forte@Sun.COM 				    IMA_ISNS_DISCOVERY_METHOD_STATIC, &hostId);
29827836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
29837836SJohn.Forte@Sun.COM 					printLibError(status);
29847836SJohn.Forte@Sun.COM 					*funcRet = 1;
29857836SJohn.Forte@Sun.COM 					return (ret);
29867836SJohn.Forte@Sun.COM 				}
29877836SJohn.Forte@Sun.COM 				break;
29887836SJohn.Forte@Sun.COM 			default:
29897836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %c: %s\n",
29907836SJohn.Forte@Sun.COM 				    cmdName, optionList->optval,
29917836SJohn.Forte@Sun.COM 				    gettext("unknown option"));
29927836SJohn.Forte@Sun.COM 				return (1);
29937836SJohn.Forte@Sun.COM 		}
29947836SJohn.Forte@Sun.COM 	}
29957836SJohn.Forte@Sun.COM 
29967836SJohn.Forte@Sun.COM 	return (ret);
29977836SJohn.Forte@Sun.COM }
29987836SJohn.Forte@Sun.COM 
29997836SJohn.Forte@Sun.COM /*
30007836SJohn.Forte@Sun.COM  * Set the initiator node's authentication method
30017836SJohn.Forte@Sun.COM  */
30027836SJohn.Forte@Sun.COM static int
30037836SJohn.Forte@Sun.COM modifyNodeAuthParam(IMA_OID oid, int param, char *chapName, int *funcRet)
30047836SJohn.Forte@Sun.COM {
30057836SJohn.Forte@Sun.COM 	IMA_INITIATOR_AUTHPARMS authParams;
30067836SJohn.Forte@Sun.COM 	IMA_STATUS status;
30077836SJohn.Forte@Sun.COM 	int ret;
30087836SJohn.Forte@Sun.COM 	int secretLen = MAX_CHAP_SECRET_LEN;
30097836SJohn.Forte@Sun.COM 
30107836SJohn.Forte@Sun.COM 	IMA_BYTE chapSecret[MAX_CHAP_SECRET_LEN + 1];
30117836SJohn.Forte@Sun.COM 
30127836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
30137836SJohn.Forte@Sun.COM 
30147836SJohn.Forte@Sun.COM 	/*
30157836SJohn.Forte@Sun.COM 	 * Start with existing parameters and modify with the desired change
30167836SJohn.Forte@Sun.COM 	 * before passing along.  We ignore any failures as they probably
30177836SJohn.Forte@Sun.COM 	 * are caused by non-existence of auth params for the given node.
30187836SJohn.Forte@Sun.COM 	 */
30197836SJohn.Forte@Sun.COM 	status = IMA_GetInitiatorAuthParms(oid, IMA_AUTHMETHOD_CHAP,
30207836SJohn.Forte@Sun.COM 	    &authParams);
30217836SJohn.Forte@Sun.COM 
30227836SJohn.Forte@Sun.COM 	switch (param) {
30237836SJohn.Forte@Sun.COM 	case AUTH_NAME:
30247836SJohn.Forte@Sun.COM 		if (chapName == NULL) {
30257836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "CHAP name cannot be NULL.\n");
30267836SJohn.Forte@Sun.COM 			return (1);
30277836SJohn.Forte@Sun.COM 		}
30287836SJohn.Forte@Sun.COM 		(void) memset(&authParams.chapParms.name, 0,
30297836SJohn.Forte@Sun.COM 		    sizeof (authParams.chapParms.name));
30307836SJohn.Forte@Sun.COM 		(void) memcpy(&authParams.chapParms.name,
30317836SJohn.Forte@Sun.COM 		    &chapName[0], strlen(chapName));
30327836SJohn.Forte@Sun.COM 		authParams.chapParms.nameLength = strlen(chapName);
30337836SJohn.Forte@Sun.COM 		break;
30347836SJohn.Forte@Sun.COM 
30357836SJohn.Forte@Sun.COM 	case AUTH_PASSWORD :
30367836SJohn.Forte@Sun.COM 		ret = getSecret((char *)&chapSecret[0], &secretLen,
30377836SJohn.Forte@Sun.COM 		    MIN_CHAP_SECRET_LEN, MAX_CHAP_SECRET_LEN);
30387836SJohn.Forte@Sun.COM 
30397836SJohn.Forte@Sun.COM 		if (ret != 0) {
30407836SJohn.Forte@Sun.COM 			return (ret);
30417836SJohn.Forte@Sun.COM 		}
30427836SJohn.Forte@Sun.COM 
30437836SJohn.Forte@Sun.COM 		(void) memset(&authParams.chapParms.challengeSecret, 0,
30447836SJohn.Forte@Sun.COM 		    sizeof (authParams.chapParms.challengeSecret));
30457836SJohn.Forte@Sun.COM 		(void) memcpy(&authParams.chapParms.challengeSecret,
30467836SJohn.Forte@Sun.COM 		    &chapSecret[0], secretLen);
30477836SJohn.Forte@Sun.COM 		authParams.chapParms.challengeSecretLength = secretLen;
30487836SJohn.Forte@Sun.COM 		break;
30497836SJohn.Forte@Sun.COM 
30507836SJohn.Forte@Sun.COM 	default:
30517836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "Invalid auth parameter %d\n", param);
30527836SJohn.Forte@Sun.COM 		return (1);
30537836SJohn.Forte@Sun.COM 	}
30547836SJohn.Forte@Sun.COM 
30557836SJohn.Forte@Sun.COM 	status = IMA_SetInitiatorAuthParms(oid, IMA_AUTHMETHOD_CHAP,
30567836SJohn.Forte@Sun.COM 	    &authParams);
30577836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
30587836SJohn.Forte@Sun.COM 		printLibError(status);
30597836SJohn.Forte@Sun.COM 		*funcRet = 1;
30607836SJohn.Forte@Sun.COM 	}
30617836SJohn.Forte@Sun.COM 	return (ret);
30627836SJohn.Forte@Sun.COM }
30637836SJohn.Forte@Sun.COM 
30647836SJohn.Forte@Sun.COM /*
30657836SJohn.Forte@Sun.COM  * Set the target's authentication method
30667836SJohn.Forte@Sun.COM  */
30677836SJohn.Forte@Sun.COM static int
30687836SJohn.Forte@Sun.COM modifyTargetAuthParam(IMA_OID oid, int param, char *chapName, int *funcRet)
30697836SJohn.Forte@Sun.COM {
30707836SJohn.Forte@Sun.COM 	IMA_INITIATOR_AUTHPARMS authParams;
30717836SJohn.Forte@Sun.COM 	IMA_STATUS status;
30727836SJohn.Forte@Sun.COM 	int ret;
30737836SJohn.Forte@Sun.COM 	int secretLen = MAX_CHAP_SECRET_LEN;
30747836SJohn.Forte@Sun.COM 
30757836SJohn.Forte@Sun.COM 	IMA_BYTE chapSecret[MAX_CHAP_SECRET_LEN + 1];
30767836SJohn.Forte@Sun.COM 
30777836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
30787836SJohn.Forte@Sun.COM 
30797836SJohn.Forte@Sun.COM 	/*
30807836SJohn.Forte@Sun.COM 	 * Start with existing parameters and modify with the desired change
30817836SJohn.Forte@Sun.COM 	 * before passing along.  We ignore any get failures as they probably
30827836SJohn.Forte@Sun.COM 	 * are caused by non-existence of auth params for the given target.
30837836SJohn.Forte@Sun.COM 	 */
30847836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetTargetAuthParms(oid, IMA_AUTHMETHOD_CHAP,
30857836SJohn.Forte@Sun.COM 	    &authParams);
30867836SJohn.Forte@Sun.COM 
30877836SJohn.Forte@Sun.COM 	switch (param) {
30887836SJohn.Forte@Sun.COM 	case AUTH_NAME:
30897836SJohn.Forte@Sun.COM 		if (chapName == NULL) {
30907836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "CHAP name cannot be NULL.\n");
30917836SJohn.Forte@Sun.COM 			return (1);
30927836SJohn.Forte@Sun.COM 		}
30937836SJohn.Forte@Sun.COM 		(void) memset(&authParams.chapParms.name, 0,
30947836SJohn.Forte@Sun.COM 		    sizeof (authParams.chapParms.name));
30957836SJohn.Forte@Sun.COM 		(void) memcpy(&authParams.chapParms.name,
30967836SJohn.Forte@Sun.COM 		    &chapName[0], strlen(chapName));
30977836SJohn.Forte@Sun.COM 		authParams.chapParms.nameLength = strlen(chapName);
30987836SJohn.Forte@Sun.COM 		break;
30997836SJohn.Forte@Sun.COM 
31007836SJohn.Forte@Sun.COM 	case AUTH_PASSWORD :
31017836SJohn.Forte@Sun.COM 		ret = getSecret((char *)&chapSecret[0], &secretLen,
31027836SJohn.Forte@Sun.COM 		    1, MAX_CHAP_SECRET_LEN);
31037836SJohn.Forte@Sun.COM 
31047836SJohn.Forte@Sun.COM 		if (ret != 0) {
31057836SJohn.Forte@Sun.COM 			return (ret);
31067836SJohn.Forte@Sun.COM 		}
31077836SJohn.Forte@Sun.COM 
31087836SJohn.Forte@Sun.COM 		(void) memset(&authParams.chapParms.challengeSecret, 0,
31097836SJohn.Forte@Sun.COM 		    sizeof (authParams.chapParms.challengeSecret));
31107836SJohn.Forte@Sun.COM 		(void) memcpy(&authParams.chapParms.challengeSecret,
31117836SJohn.Forte@Sun.COM 		    &chapSecret[0], secretLen);
31127836SJohn.Forte@Sun.COM 		authParams.chapParms.challengeSecretLength = secretLen;
31137836SJohn.Forte@Sun.COM 		break;
31147836SJohn.Forte@Sun.COM 
31157836SJohn.Forte@Sun.COM 	default:
31167836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "Invalid auth parameter %d\n", param);
31177836SJohn.Forte@Sun.COM 		return (1);
31187836SJohn.Forte@Sun.COM 	}
31197836SJohn.Forte@Sun.COM 
31207836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetTargetAuthParams(oid, IMA_AUTHMETHOD_CHAP,
31217836SJohn.Forte@Sun.COM 	    &authParams);
31227836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
31237836SJohn.Forte@Sun.COM 		printLibError(status);
31247836SJohn.Forte@Sun.COM 		*funcRet = 1;
31257836SJohn.Forte@Sun.COM 	}
31267836SJohn.Forte@Sun.COM 	return (0);
31277836SJohn.Forte@Sun.COM }
31287836SJohn.Forte@Sun.COM 
31297836SJohn.Forte@Sun.COM static int
31307836SJohn.Forte@Sun.COM modifyTargetBidirAuthFlag(IMA_OID targetOid, char *optarg, int *funcRet)
31317836SJohn.Forte@Sun.COM {
31327836SJohn.Forte@Sun.COM 	IMA_BOOL boolValue;
31337836SJohn.Forte@Sun.COM 	IMA_STATUS status;
31347836SJohn.Forte@Sun.COM 
31357836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
31367836SJohn.Forte@Sun.COM 
31377836SJohn.Forte@Sun.COM 	if (strcasecmp(optarg, ISCSIADM_ARG_ENABLE) == 0) {
31387836SJohn.Forte@Sun.COM 		boolValue = IMA_TRUE;
31397836SJohn.Forte@Sun.COM 	} else if (strcasecmp(optarg, ISCSIADM_ARG_DISABLE) == 0) {
31407836SJohn.Forte@Sun.COM 		boolValue = IMA_FALSE;
31417836SJohn.Forte@Sun.COM 	} else {
31427836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s %s\n",
31437836SJohn.Forte@Sun.COM 		    cmdName, gettext("invalid option argument"), optarg);
31447836SJohn.Forte@Sun.COM 		return (1);
31457836SJohn.Forte@Sun.COM 	}
31467836SJohn.Forte@Sun.COM 
31477836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetTargetBidirAuthFlag(targetOid, &boolValue);
31487836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
31497836SJohn.Forte@Sun.COM 		printLibError(status);
31507836SJohn.Forte@Sun.COM 		*funcRet = 1;
31517836SJohn.Forte@Sun.COM 	}
31527836SJohn.Forte@Sun.COM 	return (0);
31537836SJohn.Forte@Sun.COM }
31547836SJohn.Forte@Sun.COM 
31557836SJohn.Forte@Sun.COM static int
31567836SJohn.Forte@Sun.COM modifyConfiguredSessions(IMA_OID targetOid, char *optarg)
31577836SJohn.Forte@Sun.COM {
31587836SJohn.Forte@Sun.COM 	SUN_IMA_CONFIG_SESSIONS *pConfigSessions;
31597836SJohn.Forte@Sun.COM 	IMA_STATUS		status;
31607836SJohn.Forte@Sun.COM 	int			sessions;
31617836SJohn.Forte@Sun.COM 	int			size;
31627836SJohn.Forte@Sun.COM 	char			tmp[1024];
31637836SJohn.Forte@Sun.COM 	boolean_t		isIpv6 = B_FALSE;
31647836SJohn.Forte@Sun.COM 	uint16_t		port;
31657836SJohn.Forte@Sun.COM 	char			address[MAX_ADDRESS_LEN];
31667836SJohn.Forte@Sun.COM 	char			*commaPos;
31677836SJohn.Forte@Sun.COM 	char			*addressPos;
31687836SJohn.Forte@Sun.COM 	int			rtn;
31697836SJohn.Forte@Sun.COM 
31707836SJohn.Forte@Sun.COM 	/*
31717836SJohn.Forte@Sun.COM 	 * Strip the first int value from the string.  If we sprintf
31727836SJohn.Forte@Sun.COM 	 * this back to a string and it matches the original string
31737836SJohn.Forte@Sun.COM 	 * then this command is using default binding.  If not a
31747836SJohn.Forte@Sun.COM 	 * match we have hard coded binding or a usage error.
31757836SJohn.Forte@Sun.COM 	 */
31767836SJohn.Forte@Sun.COM 	sessions = atoi(optarg);
31777836SJohn.Forte@Sun.COM 	(void) sprintf(tmp, "%d", sessions);
31787836SJohn.Forte@Sun.COM 	if (strcmp(optarg, tmp) == 0) {
31797836SJohn.Forte@Sun.COM 		/* default binding */
31807836SJohn.Forte@Sun.COM 
31817836SJohn.Forte@Sun.COM 		/* allocate the required pConfigSessions */
31827836SJohn.Forte@Sun.COM 		size = sizeof (SUN_IMA_CONFIG_SESSIONS);
31837836SJohn.Forte@Sun.COM 		pConfigSessions = (SUN_IMA_CONFIG_SESSIONS *)calloc(1, size);
31847836SJohn.Forte@Sun.COM 		if (pConfigSessions == NULL) {
31857836SJohn.Forte@Sun.COM 			return (1);
31867836SJohn.Forte@Sun.COM 		}
31877836SJohn.Forte@Sun.COM 
31887836SJohn.Forte@Sun.COM 		/* setup pConfigSessions */
31897836SJohn.Forte@Sun.COM 		pConfigSessions->bound	= IMA_FALSE;
31907836SJohn.Forte@Sun.COM 		pConfigSessions->in	= sessions;
31917836SJohn.Forte@Sun.COM 		pConfigSessions->out	= 0;
31927836SJohn.Forte@Sun.COM 	} else {
31937836SJohn.Forte@Sun.COM 		/* hardcoded binding */
31947836SJohn.Forte@Sun.COM 
31957836SJohn.Forte@Sun.COM 		/*
31967836SJohn.Forte@Sun.COM 		 * First we need to determine how many bindings
31977836SJohn.Forte@Sun.COM 		 * are available.  This can be done by scanning
31987836SJohn.Forte@Sun.COM 		 * for the number of ',' + 1.
31997836SJohn.Forte@Sun.COM 		 */
32007836SJohn.Forte@Sun.COM 		sessions = 1;
32017836SJohn.Forte@Sun.COM 		commaPos = strchr(optarg, ',');
32027836SJohn.Forte@Sun.COM 		while (commaPos != NULL) {
32037836SJohn.Forte@Sun.COM 			sessions++;
32047836SJohn.Forte@Sun.COM 			commaPos = strchr(++commaPos, ',');
32057836SJohn.Forte@Sun.COM 		}
32067836SJohn.Forte@Sun.COM 
32077836SJohn.Forte@Sun.COM 		/* allocate the required pConfigSessions */
32087836SJohn.Forte@Sun.COM 		size = sizeof (SUN_IMA_CONFIG_SESSIONS) + ((sessions - 1) *
32097836SJohn.Forte@Sun.COM 		    sizeof (IMA_ADDRESS_KEY));
32107836SJohn.Forte@Sun.COM 		pConfigSessions = (SUN_IMA_CONFIG_SESSIONS *)calloc(1, size);
32117836SJohn.Forte@Sun.COM 		if (pConfigSessions == NULL) {
32127836SJohn.Forte@Sun.COM 			return (1);
32137836SJohn.Forte@Sun.COM 		}
32147836SJohn.Forte@Sun.COM 
32157836SJohn.Forte@Sun.COM 		/* setup pConfigSessions */
32167836SJohn.Forte@Sun.COM 		pConfigSessions->bound	= IMA_TRUE;
32177836SJohn.Forte@Sun.COM 		pConfigSessions->in	= sessions;
32187836SJohn.Forte@Sun.COM 		pConfigSessions->out	= 0;
32197836SJohn.Forte@Sun.COM 
32207836SJohn.Forte@Sun.COM 		/* Now fill in the binding information.  */
32217836SJohn.Forte@Sun.COM 		sessions = 0;
32227836SJohn.Forte@Sun.COM 		addressPos = optarg;
32237836SJohn.Forte@Sun.COM 		/*
32247836SJohn.Forte@Sun.COM 		 * Walk thru possible address strings
32257836SJohn.Forte@Sun.COM 		 * stop once all strings are processed.
32267836SJohn.Forte@Sun.COM 		 */
32277836SJohn.Forte@Sun.COM 		while (addressPos != NULL) {
32287836SJohn.Forte@Sun.COM 			/*
32297836SJohn.Forte@Sun.COM 			 * Check if there is another address after this
32307836SJohn.Forte@Sun.COM 			 * one. If so terminate the current address and
32317836SJohn.Forte@Sun.COM 			 * keep a pointer to the next one.
32327836SJohn.Forte@Sun.COM 			 */
32337836SJohn.Forte@Sun.COM 			commaPos = strchr(addressPos, ',');
32347836SJohn.Forte@Sun.COM 			if (commaPos != NULL) {
32357836SJohn.Forte@Sun.COM 				*commaPos++ = 0x00;
32367836SJohn.Forte@Sun.COM 			}
32377836SJohn.Forte@Sun.COM 
32387836SJohn.Forte@Sun.COM 			/*
32397836SJohn.Forte@Sun.COM 			 * Parse current address.  If invalid abort
32407836SJohn.Forte@Sun.COM 			 * processing of addresses and free memory.
32417836SJohn.Forte@Sun.COM 			 */
32427836SJohn.Forte@Sun.COM 			if (parseAddress(addressPos, 0, address,
32437836SJohn.Forte@Sun.COM 			    MAX_ADDRESS_LEN, &port, &isIpv6) != PARSE_ADDR_OK) {
32447836SJohn.Forte@Sun.COM 				free(pConfigSessions);
32457836SJohn.Forte@Sun.COM 				printLibError(IMA_ERROR_INVALID_PARAMETER);
32467836SJohn.Forte@Sun.COM 				return (1);
32477836SJohn.Forte@Sun.COM 			}
32487836SJohn.Forte@Sun.COM 
32497836SJohn.Forte@Sun.COM 			/* Convert address into binary form */
32507836SJohn.Forte@Sun.COM 			if (isIpv6 == B_FALSE) {
32517836SJohn.Forte@Sun.COM 				pConfigSessions->bindings[sessions].
32527836SJohn.Forte@Sun.COM 				    ipAddress.ipv4Address = IMA_TRUE;
32537836SJohn.Forte@Sun.COM 				rtn = inet_pton(AF_INET, address,
32547836SJohn.Forte@Sun.COM 				    pConfigSessions->bindings[sessions].
32557836SJohn.Forte@Sun.COM 				    ipAddress.ipAddress);
32567836SJohn.Forte@Sun.COM 			} else {
32577836SJohn.Forte@Sun.COM 				pConfigSessions->bindings[sessions].ipAddress.
32587836SJohn.Forte@Sun.COM 				    ipv4Address =
32597836SJohn.Forte@Sun.COM 				    IMA_FALSE;
32607836SJohn.Forte@Sun.COM 				rtn = inet_pton(AF_INET6, address,
32617836SJohn.Forte@Sun.COM 				    pConfigSessions->bindings[sessions].
32627836SJohn.Forte@Sun.COM 				    ipAddress.ipAddress);
32637836SJohn.Forte@Sun.COM 			}
32647836SJohn.Forte@Sun.COM 			if (rtn == 0) {
32657836SJohn.Forte@Sun.COM 				/* inet_pton found address invalid */
32667836SJohn.Forte@Sun.COM 				free(pConfigSessions);
32677836SJohn.Forte@Sun.COM 				printLibError(IMA_ERROR_INVALID_PARAMETER);
32687836SJohn.Forte@Sun.COM 				return (1);
32697836SJohn.Forte@Sun.COM 			}
32707836SJohn.Forte@Sun.COM 
32717836SJohn.Forte@Sun.COM 			/* update addressPos to next address */
32727836SJohn.Forte@Sun.COM 			sessions++;
32737836SJohn.Forte@Sun.COM 			addressPos = commaPos;
32747836SJohn.Forte@Sun.COM 		}
32757836SJohn.Forte@Sun.COM 	}
32767836SJohn.Forte@Sun.COM 
32777836SJohn.Forte@Sun.COM 	/* issue SUN_IMA request */
32787836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetConfigSessions(targetOid,
32797836SJohn.Forte@Sun.COM 	    pConfigSessions);
32807836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
32817836SJohn.Forte@Sun.COM 		printLibError(status);
32827836SJohn.Forte@Sun.COM 		free(pConfigSessions);
32837836SJohn.Forte@Sun.COM 		return (1);
32847836SJohn.Forte@Sun.COM 	}
32857836SJohn.Forte@Sun.COM 
32867836SJohn.Forte@Sun.COM 	free(pConfigSessions);
32877836SJohn.Forte@Sun.COM 	return (0);
32887836SJohn.Forte@Sun.COM }
32897836SJohn.Forte@Sun.COM 
32907836SJohn.Forte@Sun.COM static int
32917836SJohn.Forte@Sun.COM getAuthMethodValue(char *method, IMA_AUTHMETHOD *value)
32927836SJohn.Forte@Sun.COM {
32937836SJohn.Forte@Sun.COM 	if (strcasecmp(method, "chap") == 0) {
32947836SJohn.Forte@Sun.COM 		*value = IMA_AUTHMETHOD_CHAP;
32957836SJohn.Forte@Sun.COM 		return (0);
32967836SJohn.Forte@Sun.COM 	}
32977836SJohn.Forte@Sun.COM 
32987836SJohn.Forte@Sun.COM 	if (strcasecmp(method, "none") == 0) {
32997836SJohn.Forte@Sun.COM 		*value =  IMA_AUTHMETHOD_NONE;
33007836SJohn.Forte@Sun.COM 		return (0);
33017836SJohn.Forte@Sun.COM 	}
33027836SJohn.Forte@Sun.COM 
33037836SJohn.Forte@Sun.COM 	return (1);
33047836SJohn.Forte@Sun.COM }
33057836SJohn.Forte@Sun.COM 
33067836SJohn.Forte@Sun.COM 
33077836SJohn.Forte@Sun.COM /*
33087836SJohn.Forte@Sun.COM  * Set the authentication method
33097836SJohn.Forte@Sun.COM  * Currently only supports CHAP and NONE
33107836SJohn.Forte@Sun.COM  */
33117836SJohn.Forte@Sun.COM static int
33127836SJohn.Forte@Sun.COM modifyNodeAuthMethod(IMA_OID oid, char *optarg, int *funcRet)
33137836SJohn.Forte@Sun.COM {
33147836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD methodList[MAX_AUTH_METHODS];
33157836SJohn.Forte@Sun.COM 	IMA_UINT methodCount = 0;
33167836SJohn.Forte@Sun.COM 	IMA_STATUS status;
33177836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD value;
33187836SJohn.Forte@Sun.COM 	char *method;
33197836SJohn.Forte@Sun.COM 	char *commaPos;
33207836SJohn.Forte@Sun.COM 
33217836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
33227836SJohn.Forte@Sun.COM 
33237836SJohn.Forte@Sun.COM 	/*
33247836SJohn.Forte@Sun.COM 	 * optarg will be a , delimited set of auth methods, in order
33257836SJohn.Forte@Sun.COM 	 * of preference
33267836SJohn.Forte@Sun.COM 	 * if any values here are incorrect, return without setting
33277836SJohn.Forte@Sun.COM 	 * anything.
33287836SJohn.Forte@Sun.COM 	 */
33297836SJohn.Forte@Sun.COM 	method = optarg;
33307836SJohn.Forte@Sun.COM 
33317836SJohn.Forte@Sun.COM 	commaPos = strchr(optarg, ',');
33327836SJohn.Forte@Sun.COM 
33337836SJohn.Forte@Sun.COM 	while (commaPos && methodCount < MAX_AUTH_METHODS) {
33347836SJohn.Forte@Sun.COM 		*commaPos = NULL;
33357836SJohn.Forte@Sun.COM 		if (getAuthMethodValue(method, &value) != 0) {
33367836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: a: %s\n",
33377836SJohn.Forte@Sun.COM 			    cmdName, gettext("invalid option argument"));
33387836SJohn.Forte@Sun.COM 			return (1);
33397836SJohn.Forte@Sun.COM 		}
33407836SJohn.Forte@Sun.COM 		methodList[methodCount++] = value;
33417836SJohn.Forte@Sun.COM 		commaPos++;
33427836SJohn.Forte@Sun.COM 		method = commaPos;
33437836SJohn.Forte@Sun.COM 		commaPos = strchr(method, ',');
33447836SJohn.Forte@Sun.COM 	}
33457836SJohn.Forte@Sun.COM 	/* Should not find more method specified - if found, error */
33467836SJohn.Forte@Sun.COM 	if (commaPos) {
33477836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: -a: %s\n",
33487836SJohn.Forte@Sun.COM 		    cmdName, gettext("invalid option argument"));
33497836SJohn.Forte@Sun.COM 		return (1);
33507836SJohn.Forte@Sun.COM 	}
33517836SJohn.Forte@Sun.COM 	if (getAuthMethodValue(method, &value) != 0) {
33527836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: -a: %s\n",
33537836SJohn.Forte@Sun.COM 		    cmdName, gettext("invalid option argument"));
33547836SJohn.Forte@Sun.COM 		return (1);
33557836SJohn.Forte@Sun.COM 	}
33567836SJohn.Forte@Sun.COM 	methodList[methodCount++] = value;
33577836SJohn.Forte@Sun.COM 
33587836SJohn.Forte@Sun.COM 	status = IMA_SetInitiatorAuthMethods(oid, methodCount, &methodList[0]);
33597836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
33607836SJohn.Forte@Sun.COM 		printLibError(status);
33617836SJohn.Forte@Sun.COM 		*funcRet = 1;
33627836SJohn.Forte@Sun.COM 	}
33637836SJohn.Forte@Sun.COM 	return (0);
33647836SJohn.Forte@Sun.COM }
33657836SJohn.Forte@Sun.COM 
33667836SJohn.Forte@Sun.COM static int
33677836SJohn.Forte@Sun.COM modifyTargetAuthMethod(IMA_OID oid, char *optarg, int *funcRet)
33687836SJohn.Forte@Sun.COM {
33697836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD methodList[MAX_AUTH_METHODS];
33707836SJohn.Forte@Sun.COM 	IMA_UINT methodCount = 0;
33717836SJohn.Forte@Sun.COM 	IMA_STATUS status;
33727836SJohn.Forte@Sun.COM 	IMA_AUTHMETHOD value;
33737836SJohn.Forte@Sun.COM 	char *method;
33747836SJohn.Forte@Sun.COM 	char *commaPos;
33757836SJohn.Forte@Sun.COM 
33767836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
33777836SJohn.Forte@Sun.COM 
33787836SJohn.Forte@Sun.COM 	/*
33797836SJohn.Forte@Sun.COM 	 * optarg will be a , delimited set of auth methods, in order
33807836SJohn.Forte@Sun.COM 	 * of preference
33817836SJohn.Forte@Sun.COM 	 * if any values here are incorrect, return without setting
33827836SJohn.Forte@Sun.COM 	 * anything.
33837836SJohn.Forte@Sun.COM 	 */
33847836SJohn.Forte@Sun.COM 	method = optarg;
33857836SJohn.Forte@Sun.COM 
33867836SJohn.Forte@Sun.COM 	commaPos = strchr(optarg, ',');
33877836SJohn.Forte@Sun.COM 
33887836SJohn.Forte@Sun.COM 	while (commaPos && methodCount < MAX_AUTH_METHODS) {
33897836SJohn.Forte@Sun.COM 		*commaPos = NULL;
33907836SJohn.Forte@Sun.COM 		if (getAuthMethodValue(method, &value) != 0) {
33917836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: a: %s\n",
33927836SJohn.Forte@Sun.COM 			    cmdName, gettext("invalid option argument"));
33937836SJohn.Forte@Sun.COM 			return (1);
33947836SJohn.Forte@Sun.COM 		}
33957836SJohn.Forte@Sun.COM 		methodList[methodCount++] = value;
33967836SJohn.Forte@Sun.COM 		commaPos++;
33977836SJohn.Forte@Sun.COM 		method = commaPos;
33987836SJohn.Forte@Sun.COM 		commaPos = strchr(method, ',');
33997836SJohn.Forte@Sun.COM 	}
34007836SJohn.Forte@Sun.COM 	/* Should not find more method specified - if found, error */
34017836SJohn.Forte@Sun.COM 	if (commaPos) {
34027836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: -a: %s\n",
34037836SJohn.Forte@Sun.COM 		    cmdName, gettext("invalid option argument"));
34047836SJohn.Forte@Sun.COM 		return (1);
34057836SJohn.Forte@Sun.COM 	}
34067836SJohn.Forte@Sun.COM 	if (getAuthMethodValue(method, &value) != 0) {
34077836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: -a: %s\n",
34087836SJohn.Forte@Sun.COM 		    cmdName, gettext("invalid option argument"));
34097836SJohn.Forte@Sun.COM 		return (1);
34107836SJohn.Forte@Sun.COM 	}
34117836SJohn.Forte@Sun.COM 	methodList[methodCount++] = value;
34127836SJohn.Forte@Sun.COM 
34137836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetTargetAuthMethods(oid, &methodCount,
34147836SJohn.Forte@Sun.COM 	    &methodList[0]);
34157836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
34167836SJohn.Forte@Sun.COM 		printLibError(status);
34177836SJohn.Forte@Sun.COM 		*funcRet = 1;
34187836SJohn.Forte@Sun.COM 	}
34197836SJohn.Forte@Sun.COM 	return (0);
34207836SJohn.Forte@Sun.COM }
34217836SJohn.Forte@Sun.COM 
34227836SJohn.Forte@Sun.COM /*
34237836SJohn.Forte@Sun.COM  * Modify the RADIUS configuration of the initiator node.
34247836SJohn.Forte@Sun.COM  *
34257836SJohn.Forte@Sun.COM  * Return 0 on success.
34267836SJohn.Forte@Sun.COM  */
34277836SJohn.Forte@Sun.COM static int
34287836SJohn.Forte@Sun.COM modifyNodeRadiusConfig(IMA_OID oid, char *optarg, int *funcRet)
34297836SJohn.Forte@Sun.COM {
34307836SJohn.Forte@Sun.COM 	SUN_IMA_RADIUS_CONFIG config;
34317836SJohn.Forte@Sun.COM 	IMA_STATUS status;
34327836SJohn.Forte@Sun.COM 	boolean_t isIpv6 = B_FALSE;
34337836SJohn.Forte@Sun.COM 	uint16_t port;
34347836SJohn.Forte@Sun.COM 
34357836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
34367836SJohn.Forte@Sun.COM 
34377836SJohn.Forte@Sun.COM 	(void) memset(&config, 0, sizeof (SUN_IMA_RADIUS_CONFIG));
34387836SJohn.Forte@Sun.COM 	if (parseAddress(optarg, DEFAULT_RADIUS_PORT,
34397836SJohn.Forte@Sun.COM 	    &config.hostnameIpAddress[0], SUN_IMA_IP_ADDRESS_PORT_LEN,
34407836SJohn.Forte@Sun.COM 	    &port, &isIpv6) !=
34417836SJohn.Forte@Sun.COM 	    PARSE_ADDR_OK) {
34427836SJohn.Forte@Sun.COM 		return (1);
34437836SJohn.Forte@Sun.COM 	}
34447836SJohn.Forte@Sun.COM 	config.port = (IMA_UINT16)port;
34457836SJohn.Forte@Sun.COM 	config.isIpv6 = (isIpv6 == B_TRUE) ? IMA_TRUE : IMA_FALSE;
34467836SJohn.Forte@Sun.COM 	/* Not setting shared secret here. */
34477836SJohn.Forte@Sun.COM 	config.sharedSecretValid = IMA_FALSE;
34487836SJohn.Forte@Sun.COM 
34497836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetInitiatorRadiusConfig(oid, &config);
34507836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
34517836SJohn.Forte@Sun.COM 		printLibError(status);
34527836SJohn.Forte@Sun.COM 		*funcRet = 1;
34537836SJohn.Forte@Sun.COM 	}
34547836SJohn.Forte@Sun.COM 
34557836SJohn.Forte@Sun.COM 	return (0);
34567836SJohn.Forte@Sun.COM }
34577836SJohn.Forte@Sun.COM 
34587836SJohn.Forte@Sun.COM /*
34597836SJohn.Forte@Sun.COM  * Modify the RADIUS access flag of the initiator node.
34607836SJohn.Forte@Sun.COM  *
34617836SJohn.Forte@Sun.COM  * Return 0 on success.
34627836SJohn.Forte@Sun.COM  */
34637836SJohn.Forte@Sun.COM static int
34647836SJohn.Forte@Sun.COM modifyNodeRadiusAccess(IMA_OID oid, char *optarg, int *funcRet)
34657836SJohn.Forte@Sun.COM {
34667836SJohn.Forte@Sun.COM 	IMA_BOOL radiusAccess;
34677836SJohn.Forte@Sun.COM 	IMA_OID initiatorOid;
34687836SJohn.Forte@Sun.COM 	IMA_STATUS status;
34697836SJohn.Forte@Sun.COM 	SUN_IMA_RADIUS_CONFIG radiusConfig;
34707836SJohn.Forte@Sun.COM 	int ret;
34717836SJohn.Forte@Sun.COM 
34727836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
34737836SJohn.Forte@Sun.COM 
34747836SJohn.Forte@Sun.COM 	/* Check if Radius Config is there */
34757836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
34767836SJohn.Forte@Sun.COM 	if (ret != 0) {
34777836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
34787836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
34797836SJohn.Forte@Sun.COM 		return (1);
34807836SJohn.Forte@Sun.COM 	}
34817836SJohn.Forte@Sun.COM 	(void) memset(&radiusConfig, 0, sizeof (SUN_IMA_RADIUS_CONFIG));
34827836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetInitiatorRadiusConfig(initiatorOid, &radiusConfig);
34837836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
34847836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
34857836SJohn.Forte@Sun.COM 		    cmdName, gettext("RADIUS server not configured yet"));
34867836SJohn.Forte@Sun.COM 		*funcRet = 1;
34877836SJohn.Forte@Sun.COM 		return (ret);
34887836SJohn.Forte@Sun.COM 	}
34897836SJohn.Forte@Sun.COM 
34907836SJohn.Forte@Sun.COM 	/* Check if Radius Shared is set */
34917836SJohn.Forte@Sun.COM 	if (radiusConfig.sharedSecretValid == IMA_FALSE) {
34927836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n", cmdName,
34937836SJohn.Forte@Sun.COM 		    gettext("RADIUS server secret not configured yet"));
34947836SJohn.Forte@Sun.COM 		return (1);
34957836SJohn.Forte@Sun.COM 	}
34967836SJohn.Forte@Sun.COM 
34977836SJohn.Forte@Sun.COM 	if (strcasecmp(optarg, ISCSIADM_ARG_ENABLE) == 0) {
34987836SJohn.Forte@Sun.COM 		radiusAccess = IMA_TRUE;
34997836SJohn.Forte@Sun.COM 	} else if (strcasecmp(optarg, ISCSIADM_ARG_DISABLE) == 0) {
35007836SJohn.Forte@Sun.COM 		radiusAccess = IMA_FALSE;
35017836SJohn.Forte@Sun.COM 	} else {
35027836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s %s\n",
35037836SJohn.Forte@Sun.COM 		    cmdName,
35047836SJohn.Forte@Sun.COM 		    gettext("invalid option argument"),
35057836SJohn.Forte@Sun.COM 		    optarg);
35067836SJohn.Forte@Sun.COM 		return (1);
35077836SJohn.Forte@Sun.COM 	}
35087836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetInitiatorRadiusAccess(oid, radiusAccess);
35097836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
35107836SJohn.Forte@Sun.COM 		printLibError(status);
35117836SJohn.Forte@Sun.COM 		*funcRet = 1;
35127836SJohn.Forte@Sun.COM 	}
35137836SJohn.Forte@Sun.COM 
35147836SJohn.Forte@Sun.COM 	return (ret);
35157836SJohn.Forte@Sun.COM }
35167836SJohn.Forte@Sun.COM 
35177836SJohn.Forte@Sun.COM /*
35187836SJohn.Forte@Sun.COM  * Modify the RADIUS shared secret.
35197836SJohn.Forte@Sun.COM  *
35207836SJohn.Forte@Sun.COM  * Returns:
35217836SJohn.Forte@Sun.COM  *  zero on success.
35227836SJohn.Forte@Sun.COM  *  > 0 on failure.
35237836SJohn.Forte@Sun.COM  */
35247836SJohn.Forte@Sun.COM static int
35257836SJohn.Forte@Sun.COM modifyNodeRadiusSharedSecret(IMA_OID oid, int *funcRet)
35267836SJohn.Forte@Sun.COM {
35277836SJohn.Forte@Sun.COM 	IMA_BYTE radiusSharedSecret[SUN_IMA_MAX_RADIUS_SECRET_LEN + 1];
35287836SJohn.Forte@Sun.COM 	IMA_OID initiatorOid;
35297836SJohn.Forte@Sun.COM 	IMA_STATUS status;
35307836SJohn.Forte@Sun.COM 	SUN_IMA_RADIUS_CONFIG radiusConfig;
35317836SJohn.Forte@Sun.COM 	int ret;
35327836SJohn.Forte@Sun.COM 	int secretLen = SUN_IMA_MAX_RADIUS_SECRET_LEN;
35337836SJohn.Forte@Sun.COM 
35347836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
35357836SJohn.Forte@Sun.COM 
35367836SJohn.Forte@Sun.COM 	ret = getSecret((char *)&radiusSharedSecret[0], &secretLen,
35377836SJohn.Forte@Sun.COM 	    0, SUN_IMA_MAX_RADIUS_SECRET_LEN);
35387836SJohn.Forte@Sun.COM 	if (ret != 0) {
35397836SJohn.Forte@Sun.COM 		return (1);
35407836SJohn.Forte@Sun.COM 	}
35417836SJohn.Forte@Sun.COM 
35427836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
35437836SJohn.Forte@Sun.COM 	if (ret > 0) {
35447836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
35457836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
35467836SJohn.Forte@Sun.COM 	}
35477836SJohn.Forte@Sun.COM 	if (ret != 0) {
35487836SJohn.Forte@Sun.COM 		return (1);
35497836SJohn.Forte@Sun.COM 	}
35507836SJohn.Forte@Sun.COM 	/* First obtain existing RADIUS configuration (if any) */
35517836SJohn.Forte@Sun.COM 	(void) memset(&radiusConfig, 0, sizeof (SUN_IMA_RADIUS_CONFIG));
35527836SJohn.Forte@Sun.COM 	status = SUN_IMA_GetInitiatorRadiusConfig(initiatorOid, &radiusConfig);
35537836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
35547836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
35557836SJohn.Forte@Sun.COM 		    cmdName, gettext("RADIUS server not configured yet"));
35567836SJohn.Forte@Sun.COM 		return (1);
35577836SJohn.Forte@Sun.COM 	}
35587836SJohn.Forte@Sun.COM 
35597836SJohn.Forte@Sun.COM 	/* Modify the shared secret only */
35607836SJohn.Forte@Sun.COM 	radiusConfig.sharedSecretLength = secretLen;
35617836SJohn.Forte@Sun.COM 	(void) memcpy(&radiusConfig.sharedSecret,
35627836SJohn.Forte@Sun.COM 	    &radiusSharedSecret[0], secretLen);
35637836SJohn.Forte@Sun.COM 	radiusConfig.sharedSecretValid = IMA_TRUE;
35647836SJohn.Forte@Sun.COM 	status = SUN_IMA_SetInitiatorRadiusConfig(oid, &radiusConfig);
35657836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
35667836SJohn.Forte@Sun.COM 		printLibError(status);
35677836SJohn.Forte@Sun.COM 		*funcRet = 1;
35687836SJohn.Forte@Sun.COM 	}
35697836SJohn.Forte@Sun.COM 
35707836SJohn.Forte@Sun.COM 	return (0);
35717836SJohn.Forte@Sun.COM }
35727836SJohn.Forte@Sun.COM 
35737836SJohn.Forte@Sun.COM /*
35747836SJohn.Forte@Sun.COM  * Set initiator node attributes.
35757836SJohn.Forte@Sun.COM  */
35767836SJohn.Forte@Sun.COM static int
35777836SJohn.Forte@Sun.COM modifyNode(cmdOptions_t *options, int *funcRet)
35787836SJohn.Forte@Sun.COM {
35797836SJohn.Forte@Sun.COM 	IMA_NODE_NAME	nodeName;
35807836SJohn.Forte@Sun.COM 	IMA_NODE_ALIAS	nodeAlias;
35817836SJohn.Forte@Sun.COM 	IMA_OID		oid;
35827836SJohn.Forte@Sun.COM 	IMA_STATUS	status;
35837836SJohn.Forte@Sun.COM 	cmdOptions_t	*optionList = options;
35847836SJohn.Forte@Sun.COM 	int		ret;
35857836SJohn.Forte@Sun.COM 	iSCSINameCheckStatusType nameCheckStatus;
35867836SJohn.Forte@Sun.COM 	IMA_OID sharedNodeOid;
3587*8265SBing.Zhao@Sun.COM 	int 		i;
3588*8265SBing.Zhao@Sun.COM 	int 		lowerCase;
35898194SJack.Meng@Sun.COM 	IMA_BOOL	iscsiBoot = IMA_FALSE;
35908194SJack.Meng@Sun.COM 	IMA_BOOL	mpxioEnabled = IMA_FALSE;
3591*8265SBing.Zhao@Sun.COM 	char		*mb_name = NULL;
3592*8265SBing.Zhao@Sun.COM 	int		prefixlen = 0;
35937836SJohn.Forte@Sun.COM 
35947836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
35957836SJohn.Forte@Sun.COM 
35968194SJack.Meng@Sun.COM 	/* Get boot session's info */
35978194SJack.Meng@Sun.COM 	(void) SUN_IMA_GetBootIscsi(&iscsiBoot);
35988194SJack.Meng@Sun.COM 	if (iscsiBoot == IMA_TRUE) {
35998194SJack.Meng@Sun.COM 		status = SUN_IMA_GetBootMpxio(&mpxioEnabled);
36008194SJack.Meng@Sun.COM 		if (!IMA_SUCCESS(status)) {
36018194SJack.Meng@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
36028194SJack.Meng@Sun.COM 			    cmdName, gettext("unable to get MPxIO info"
36038194SJack.Meng@Sun.COM 			    " of root disk"));
36048194SJack.Meng@Sun.COM 			*funcRet = 1;
36058194SJack.Meng@Sun.COM 			return (1);
36068194SJack.Meng@Sun.COM 		}
36078194SJack.Meng@Sun.COM 	}
36088194SJack.Meng@Sun.COM 
36097836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
36107836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&oid);
36117836SJohn.Forte@Sun.COM 	if (ret > 0) {
36127836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
36137836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
36147836SJohn.Forte@Sun.COM 	}
36157836SJohn.Forte@Sun.COM 
36167836SJohn.Forte@Sun.COM 	if (ret != 0) {
36177836SJohn.Forte@Sun.COM 		return (ret);
36187836SJohn.Forte@Sun.COM 	}
36197836SJohn.Forte@Sun.COM 
36207836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
36217836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
36227836SJohn.Forte@Sun.COM 			case 'N':
36237836SJohn.Forte@Sun.COM 				if (strlen(optionList->optarg) >=
36247836SJohn.Forte@Sun.COM 				    MAX_ISCSI_NAME_LEN) {
36257836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s %d\n",
36267836SJohn.Forte@Sun.COM 					    cmdName,
36277836SJohn.Forte@Sun.COM 					    gettext("name too long, \
36287836SJohn.Forte@Sun.COM 					    maximum length is:"),
36297836SJohn.Forte@Sun.COM 					    MAX_ISCSI_NAME_LEN);
36307836SJohn.Forte@Sun.COM 				}
36317836SJohn.Forte@Sun.COM 
36327836SJohn.Forte@Sun.COM 				/* Take the first operand as node name. */
36337836SJohn.Forte@Sun.COM 				(void) memset(&nodeName, 0,
36347836SJohn.Forte@Sun.COM 				    sizeof (IMA_NODE_NAME));
36357836SJohn.Forte@Sun.COM 				if (mbstowcs(nodeName, optionList->optarg,
36367836SJohn.Forte@Sun.COM 				    IMA_NODE_NAME_LEN) == (size_t)-1) {
36377836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
36387836SJohn.Forte@Sun.COM 					    cmdName,
36397836SJohn.Forte@Sun.COM 					    gettext("conversion error"));
36407836SJohn.Forte@Sun.COM 					return (1);
36417836SJohn.Forte@Sun.COM 				}
36427836SJohn.Forte@Sun.COM 
3643*8265SBing.Zhao@Sun.COM 				prefixlen = strlen(ISCSI_IQN_NAME_PREFIX);
3644*8265SBing.Zhao@Sun.COM 				mb_name = (char *)calloc(1, prefixlen + 1);
3645*8265SBing.Zhao@Sun.COM 				if (mb_name == NULL) {
3646*8265SBing.Zhao@Sun.COM 					return (1);
3647*8265SBing.Zhao@Sun.COM 				}
3648*8265SBing.Zhao@Sun.COM 
3649*8265SBing.Zhao@Sun.COM 				if (wcstombs(mb_name, nodeName,
3650*8265SBing.Zhao@Sun.COM 				    prefixlen) == (size_t)-1) {
3651*8265SBing.Zhao@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
3652*8265SBing.Zhao@Sun.COM 					    cmdName,
3653*8265SBing.Zhao@Sun.COM 					    gettext("conversion error"));
3654*8265SBing.Zhao@Sun.COM 					(void) IMA_FreeMemory(mb_name);
3655*8265SBing.Zhao@Sun.COM 					return (1);
36567836SJohn.Forte@Sun.COM 				}
3657*8265SBing.Zhao@Sun.COM 				if (strncmp(mb_name, ISCSI_IQN_NAME_PREFIX,
3658*8265SBing.Zhao@Sun.COM 				    prefixlen) == 0) {
3659*8265SBing.Zhao@Sun.COM 					/*
3660*8265SBing.Zhao@Sun.COM 					 * For iqn format, we should map
3661*8265SBing.Zhao@Sun.COM 					 * the upper-case characters to
3662*8265SBing.Zhao@Sun.COM 					 * their lower-case equivalents.
3663*8265SBing.Zhao@Sun.COM 					 */
3664*8265SBing.Zhao@Sun.COM 					for (i = 0; nodeName[i] != 0; i++) {
3665*8265SBing.Zhao@Sun.COM 						lowerCase =
3666*8265SBing.Zhao@Sun.COM 						    tolower(nodeName[i]);
3667*8265SBing.Zhao@Sun.COM 						nodeName[i] = lowerCase;
3668*8265SBing.Zhao@Sun.COM 					}
3669*8265SBing.Zhao@Sun.COM 				}
3670*8265SBing.Zhao@Sun.COM 				(void) IMA_FreeMemory(mb_name);
3671*8265SBing.Zhao@Sun.COM 
36727836SJohn.Forte@Sun.COM 				/* Perform string profile checks */
36737836SJohn.Forte@Sun.COM 				nameCheckStatus =
36747836SJohn.Forte@Sun.COM 				    iSCSINameStringProfileCheck(nodeName);
36757836SJohn.Forte@Sun.COM 				iSCSINameCheckStatusDisplay(nameCheckStatus);
36767836SJohn.Forte@Sun.COM 				if (nameCheckStatus != iSCSINameCheckOK) {
36777836SJohn.Forte@Sun.COM 					*funcRet = 1; /* DIY message fix */
36787836SJohn.Forte@Sun.COM 					return (1);
36797836SJohn.Forte@Sun.COM 				}
36807836SJohn.Forte@Sun.COM 
36817836SJohn.Forte@Sun.COM 				/*
36827836SJohn.Forte@Sun.COM 				 * IMA_GetSharedNodeOid(&sharedNodeOid);
36837836SJohn.Forte@Sun.COM 				 * if (!IMA_SUCCESS(status)) {
36847836SJohn.Forte@Sun.COM 				 *   printLibError(status);
36857836SJohn.Forte@Sun.COM 				 *   return (INF_ERROR);
36867836SJohn.Forte@Sun.COM 				 * }
36877836SJohn.Forte@Sun.COM 				 */
36888194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
36898194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
36908194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot, not"
36918194SJack.Meng@Sun.COM 					    " allowed to change"
36928194SJack.Meng@Sun.COM 					    " initiator's name"));
36938194SJack.Meng@Sun.COM 					return (1);
36948194SJack.Meng@Sun.COM 				}
36957836SJohn.Forte@Sun.COM 				oid.objectType = IMA_OBJECT_TYPE_NODE;
36967836SJohn.Forte@Sun.COM 				status = IMA_SetNodeName(oid, nodeName);
36977836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
36987836SJohn.Forte@Sun.COM 					printLibError(status);
36997836SJohn.Forte@Sun.COM 					*funcRet = 1;
37007836SJohn.Forte@Sun.COM 					return (ret);
37017836SJohn.Forte@Sun.COM 				}
37027836SJohn.Forte@Sun.COM 				break;
37037836SJohn.Forte@Sun.COM 
37047836SJohn.Forte@Sun.COM 			case 'A':
37058194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
37068194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
37078194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot, not"
37088194SJack.Meng@Sun.COM 					    " allowed to change"
37098194SJack.Meng@Sun.COM 					    " initiator's alias"));
37108194SJack.Meng@Sun.COM 					return (1);
37118194SJack.Meng@Sun.COM 				}
37127836SJohn.Forte@Sun.COM 				/* Take the first operand as node alias. */
37137836SJohn.Forte@Sun.COM 				if (strlen(optionList->optarg) >=
37147836SJohn.Forte@Sun.COM 				    MAX_ISCSI_NAME_LEN) {
37157836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s %d\n",
37167836SJohn.Forte@Sun.COM 					    cmdName,
37177836SJohn.Forte@Sun.COM 					    gettext("alias too long, maximum  \
37187836SJohn.Forte@Sun.COM 					    length is:"),
37197836SJohn.Forte@Sun.COM 					    MAX_ISCSI_NAME_LEN);
37207836SJohn.Forte@Sun.COM 				}
37217836SJohn.Forte@Sun.COM 
37227836SJohn.Forte@Sun.COM 				(void) memset(&nodeAlias, 0,
37237836SJohn.Forte@Sun.COM 				    sizeof (IMA_NODE_ALIAS));
37247836SJohn.Forte@Sun.COM 				if (mbstowcs(nodeAlias, optionList->optarg,
37257836SJohn.Forte@Sun.COM 				    IMA_NODE_ALIAS_LEN) == (size_t)-1) {
37267836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
37277836SJohn.Forte@Sun.COM 					    cmdName,
37287836SJohn.Forte@Sun.COM 					    gettext("conversion error"));
37297836SJohn.Forte@Sun.COM 					return (1);
37307836SJohn.Forte@Sun.COM 				}
37317836SJohn.Forte@Sun.COM 
37327836SJohn.Forte@Sun.COM 				status = IMA_GetSharedNodeOid(&sharedNodeOid);
37337836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
37347836SJohn.Forte@Sun.COM 					printLibError(status);
37357836SJohn.Forte@Sun.COM 					*funcRet = 1;
37367836SJohn.Forte@Sun.COM 					return (ret);
37377836SJohn.Forte@Sun.COM 				}
37387836SJohn.Forte@Sun.COM 
37397836SJohn.Forte@Sun.COM 				status = IMA_SetNodeAlias(sharedNodeOid,
37407836SJohn.Forte@Sun.COM 				    nodeAlias);
37417836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
37427836SJohn.Forte@Sun.COM 					printLibError(status);
37437836SJohn.Forte@Sun.COM 					*funcRet = 1;
37447836SJohn.Forte@Sun.COM 					return (ret);
37457836SJohn.Forte@Sun.COM 				}
37467836SJohn.Forte@Sun.COM 				break;
37477836SJohn.Forte@Sun.COM 
37487836SJohn.Forte@Sun.COM 			case 'a':
37498194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
37508194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
37518194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot, not"
37528194SJack.Meng@Sun.COM 					    " allowed to change authentication"
37538194SJack.Meng@Sun.COM 					    " method"));
37548194SJack.Meng@Sun.COM 					return (1);
37558194SJack.Meng@Sun.COM 				}
37567836SJohn.Forte@Sun.COM 				if (modifyNodeAuthMethod(oid, options->optarg,
37577836SJohn.Forte@Sun.COM 				    funcRet) != 0) {
37587836SJohn.Forte@Sun.COM 					return (1);
37597836SJohn.Forte@Sun.COM 				}
37607836SJohn.Forte@Sun.COM 				break;
37617836SJohn.Forte@Sun.COM 
37627836SJohn.Forte@Sun.COM 			case 'R':
37637836SJohn.Forte@Sun.COM 				if (modifyNodeRadiusAccess(oid, options->optarg,
37647836SJohn.Forte@Sun.COM 				    funcRet) != 0) {
37657836SJohn.Forte@Sun.COM 					return (1);
37667836SJohn.Forte@Sun.COM 				}
37677836SJohn.Forte@Sun.COM 				break;
37687836SJohn.Forte@Sun.COM 
37697836SJohn.Forte@Sun.COM 			case 'r':
37707836SJohn.Forte@Sun.COM 				if (modifyNodeRadiusConfig(oid, options->optarg,
37717836SJohn.Forte@Sun.COM 				    funcRet) != 0) {
37727836SJohn.Forte@Sun.COM 					return (1);
37737836SJohn.Forte@Sun.COM 				}
37747836SJohn.Forte@Sun.COM 				break;
37757836SJohn.Forte@Sun.COM 
37767836SJohn.Forte@Sun.COM 			case 'P':
37777836SJohn.Forte@Sun.COM 				if (modifyNodeRadiusSharedSecret(oid, funcRet)
37787836SJohn.Forte@Sun.COM 				    != 0) {
37797836SJohn.Forte@Sun.COM 					return (1);
37807836SJohn.Forte@Sun.COM 				}
37817836SJohn.Forte@Sun.COM 				break;
37827836SJohn.Forte@Sun.COM 
37837836SJohn.Forte@Sun.COM 			case 'C':
37848194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
37858194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
37868194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot, not"
37878194SJack.Meng@Sun.COM 					    " allowed to change CHAP secret"));
37888194SJack.Meng@Sun.COM 					return (1);
37898194SJack.Meng@Sun.COM 				}
37907836SJohn.Forte@Sun.COM 				if (modifyNodeAuthParam(oid, AUTH_PASSWORD,
37917836SJohn.Forte@Sun.COM 				    NULL, funcRet) != 0) {
37927836SJohn.Forte@Sun.COM 					return (1);
37937836SJohn.Forte@Sun.COM 				}
37947836SJohn.Forte@Sun.COM 				break;
37957836SJohn.Forte@Sun.COM 
37967836SJohn.Forte@Sun.COM 			case 'c':
37978194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
37988194SJack.Meng@Sun.COM 					if (mpxioEnabled == IMA_FALSE) {
37998194SJack.Meng@Sun.COM 						(void) fprintf(stderr,
38008194SJack.Meng@Sun.COM 						    "%s: %s\n", cmdName,
38018194SJack.Meng@Sun.COM 						    gettext("iscsi"
38028194SJack.Meng@Sun.COM 						    " boot and MPxIO"
38038194SJack.Meng@Sun.COM 						    " is disabled, not allowed"
38048194SJack.Meng@Sun.COM 						    " to change number of"
38058194SJack.Meng@Sun.COM 						    " sessions to be"
38068194SJack.Meng@Sun.COM 						    " configured"));
38078194SJack.Meng@Sun.COM 						return (1);
38088194SJack.Meng@Sun.COM 					}
38098194SJack.Meng@Sun.COM 				}
38107836SJohn.Forte@Sun.COM 				if (modifyConfiguredSessions(oid,
38117836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
38128194SJack.Meng@Sun.COM 					if (iscsiBoot == IMA_TRUE) {
38138194SJack.Meng@Sun.COM 						(void) fprintf(stderr,
38148194SJack.Meng@Sun.COM 						    "%s: %s\n", cmdName,
38158194SJack.Meng@Sun.COM 						    gettext("iscsi boot,"
38168194SJack.Meng@Sun.COM 						    " fail to set configured"
38178194SJack.Meng@Sun.COM 						    " session"));
38188194SJack.Meng@Sun.COM 					}
38197836SJohn.Forte@Sun.COM 					return (1);
38207836SJohn.Forte@Sun.COM 				}
38217836SJohn.Forte@Sun.COM 				break;
38227836SJohn.Forte@Sun.COM 
38238194SJack.Meng@Sun.COM 
38247836SJohn.Forte@Sun.COM 			case 'H':
38258194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
38268194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
38278194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot, not"
38288194SJack.Meng@Sun.COM 					    " allowed to change CHAP name"));
38298194SJack.Meng@Sun.COM 					return (1);
38308194SJack.Meng@Sun.COM 				}
38317836SJohn.Forte@Sun.COM 				if (modifyNodeAuthParam(oid, AUTH_NAME,
38327836SJohn.Forte@Sun.COM 				    optionList->optarg, funcRet) != 0) {
38337836SJohn.Forte@Sun.COM 					return (1);
38347836SJohn.Forte@Sun.COM 				}
38357836SJohn.Forte@Sun.COM 				break;
38367836SJohn.Forte@Sun.COM 
38378194SJack.Meng@Sun.COM 
38387836SJohn.Forte@Sun.COM 			case 'd':
38398194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
38408194SJack.Meng@Sun.COM 					if (mpxioEnabled == IMA_FALSE) {
38418194SJack.Meng@Sun.COM 						(void) fprintf(stderr,
38428194SJack.Meng@Sun.COM 						    "%s: %s\n", cmdName,
38438194SJack.Meng@Sun.COM 						    gettext("iscsi"
38448194SJack.Meng@Sun.COM 						    " boot and MPxIO"
38458194SJack.Meng@Sun.COM 						    " is disabled, not"
38468194SJack.Meng@Sun.COM 						    " allowed to"
38478194SJack.Meng@Sun.COM 						    " change initiator's"
38488194SJack.Meng@Sun.COM 						    " login params"));
38498194SJack.Meng@Sun.COM 						return (1);
38508194SJack.Meng@Sun.COM 					}
38518194SJack.Meng@Sun.COM 				}
38527836SJohn.Forte@Sun.COM 				if (setLoginParameter(oid, DATA_DIGEST,
38537836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
38547836SJohn.Forte@Sun.COM 					return (1);
38557836SJohn.Forte@Sun.COM 				}
38567836SJohn.Forte@Sun.COM 				break;
38577836SJohn.Forte@Sun.COM 
38587836SJohn.Forte@Sun.COM 			case 'h':
38598194SJack.Meng@Sun.COM 				if (iscsiBoot == IMA_TRUE) {
38608194SJack.Meng@Sun.COM 					if (mpxioEnabled == IMA_FALSE) {
38618194SJack.Meng@Sun.COM 						(void) fprintf(stderr,
38628194SJack.Meng@Sun.COM 						    "%s: %s\n", cmdName,
38638194SJack.Meng@Sun.COM 						    gettext("iscsi"
38648194SJack.Meng@Sun.COM 						    " boot and MPxIO"
38658194SJack.Meng@Sun.COM 						    " is disabled, not"
38668194SJack.Meng@Sun.COM 						    " allowed to"
38678194SJack.Meng@Sun.COM 						    " change initiator's"
38688194SJack.Meng@Sun.COM 						    " login params"));
38698194SJack.Meng@Sun.COM 						return (1);
38708194SJack.Meng@Sun.COM 					}
38718194SJack.Meng@Sun.COM 				}
38727836SJohn.Forte@Sun.COM 				if (setLoginParameter(oid, HEADER_DIGEST,
38737836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
38747836SJohn.Forte@Sun.COM 					return (1);
38757836SJohn.Forte@Sun.COM 				}
38767836SJohn.Forte@Sun.COM 				break;
38777836SJohn.Forte@Sun.COM 
38787836SJohn.Forte@Sun.COM 			default:
38797836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %c: %s\n",
38807836SJohn.Forte@Sun.COM 				    cmdName, optionList->optval,
38817836SJohn.Forte@Sun.COM 				    gettext("unknown option"));
38827836SJohn.Forte@Sun.COM 				break;
38837836SJohn.Forte@Sun.COM 		}
38847836SJohn.Forte@Sun.COM 	}
38857836SJohn.Forte@Sun.COM 
38867836SJohn.Forte@Sun.COM 	return (ret);
38877836SJohn.Forte@Sun.COM }
38887836SJohn.Forte@Sun.COM 
38897836SJohn.Forte@Sun.COM /*
38907836SJohn.Forte@Sun.COM  * Modify target parameters
38917836SJohn.Forte@Sun.COM  */
38927836SJohn.Forte@Sun.COM static int
38937836SJohn.Forte@Sun.COM modifyTargetParam(cmdOptions_t *options, char *targetName, int *funcRet)
38947836SJohn.Forte@Sun.COM {
38957836SJohn.Forte@Sun.COM 	IMA_OID oid;
38967836SJohn.Forte@Sun.COM 	IMA_OID targetOid;
38977836SJohn.Forte@Sun.COM 	IMA_STATUS status;
38987836SJohn.Forte@Sun.COM 	IMA_OID_LIST *targetList;
38997836SJohn.Forte@Sun.COM 	SUN_IMA_TARGET_PROPERTIES targetProps;
39007836SJohn.Forte@Sun.COM 	wchar_t wcInputObject[MAX_ISCSI_NAME_LEN + 1];
39017836SJohn.Forte@Sun.COM 	wchar_t targetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
39027836SJohn.Forte@Sun.COM 	int ret;
39037836SJohn.Forte@Sun.COM 	boolean_t found;
39047836SJohn.Forte@Sun.COM 	boolean_t targetAddressSpecified = B_TRUE;
39057836SJohn.Forte@Sun.COM 	boolean_t tpgtSpecified = B_FALSE;
39067836SJohn.Forte@Sun.COM 	boolean_t isIpv6 = B_FALSE;
39077836SJohn.Forte@Sun.COM 	int i;
39087836SJohn.Forte@Sun.COM 	iSCSINameCheckStatusType nameCheckStatus;
39097836SJohn.Forte@Sun.COM 	IMA_UINT16 port = 0;
39107836SJohn.Forte@Sun.COM 	IMA_UINT16 tpgt = 0;
39117836SJohn.Forte@Sun.COM 
39128194SJack.Meng@Sun.COM 	IMA_NODE_NAME bootTargetName;
39138194SJack.Meng@Sun.COM 	IMA_INITIATOR_AUTHPARMS bootTargetCHAP;
39148194SJack.Meng@Sun.COM 	IMA_BOOL  iscsiBoot;
39158194SJack.Meng@Sun.COM 	IMA_BOOL  mpxioEnabled;
39168194SJack.Meng@Sun.COM 
39177836SJohn.Forte@Sun.COM 	cmdOptions_t *optionList = options;
39187836SJohn.Forte@Sun.COM 
39197836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
39207836SJohn.Forte@Sun.COM 
39217836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
39227836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&oid);
39237836SJohn.Forte@Sun.COM 	if (ret > 0) {
39247836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
39257836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
39267836SJohn.Forte@Sun.COM 	}
39277836SJohn.Forte@Sun.COM 
39287836SJohn.Forte@Sun.COM 	if (ret != 0) {
39297836SJohn.Forte@Sun.COM 		return (ret);
39307836SJohn.Forte@Sun.COM 	}
39317836SJohn.Forte@Sun.COM 
39327836SJohn.Forte@Sun.COM 	if (parseTarget(targetName,
39337836SJohn.Forte@Sun.COM 	    &wcInputObject[0],
39347836SJohn.Forte@Sun.COM 	    MAX_ISCSI_NAME_LEN + 1,
39357836SJohn.Forte@Sun.COM 	    &targetAddressSpecified,
39367836SJohn.Forte@Sun.COM 	    &targetAddress[0],
39377836SJohn.Forte@Sun.COM 	    SUN_IMA_IP_ADDRESS_PORT_LEN,
39387836SJohn.Forte@Sun.COM 	    &port,
39397836SJohn.Forte@Sun.COM 	    &tpgtSpecified,
39407836SJohn.Forte@Sun.COM 	    &tpgt,
39417836SJohn.Forte@Sun.COM 	    &isIpv6) != PARSE_TARGET_OK) {
39427836SJohn.Forte@Sun.COM 		return (1);
39437836SJohn.Forte@Sun.COM 	}
39447836SJohn.Forte@Sun.COM 
39457836SJohn.Forte@Sun.COM 	/* Perform string profile checks */
39467836SJohn.Forte@Sun.COM 	nameCheckStatus = iSCSINameStringProfileCheck(wcInputObject);
39477836SJohn.Forte@Sun.COM 	iSCSINameCheckStatusDisplay(nameCheckStatus);
39487836SJohn.Forte@Sun.COM 	if (nameCheckStatus != iSCSINameCheckOK) {
39497836SJohn.Forte@Sun.COM 		return (1);
39507836SJohn.Forte@Sun.COM 	}
39517836SJohn.Forte@Sun.COM 
39527836SJohn.Forte@Sun.COM 	status = IMA_GetTargetOidList(oid, &targetList);
39537836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
39547836SJohn.Forte@Sun.COM 		printLibError(status);
39557836SJohn.Forte@Sun.COM 		*funcRet = 1;
39567836SJohn.Forte@Sun.COM 		return (0);
39577836SJohn.Forte@Sun.COM 	}
39587836SJohn.Forte@Sun.COM 
39598194SJack.Meng@Sun.COM 	(void) SUN_IMA_GetBootIscsi(&iscsiBoot);
39608194SJack.Meng@Sun.COM 	if (iscsiBoot == IMA_TRUE) {
39618194SJack.Meng@Sun.COM 		status = SUN_IMA_GetBootMpxio(&mpxioEnabled);
39628194SJack.Meng@Sun.COM 		if (!IMA_SUCCESS(status)) {
39638194SJack.Meng@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
39648194SJack.Meng@Sun.COM 			    cmdName, gettext("unable to get MPxIO info"
39658194SJack.Meng@Sun.COM 			    " of root disk"));
39668194SJack.Meng@Sun.COM 			*funcRet = 1;
39678194SJack.Meng@Sun.COM 			return (ret);
39688194SJack.Meng@Sun.COM 		}
39698194SJack.Meng@Sun.COM 		status = SUN_IMA_GetBootTargetName(bootTargetName);
39708194SJack.Meng@Sun.COM 		if (!IMA_SUCCESS(status)) {
39718194SJack.Meng@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
39728194SJack.Meng@Sun.COM 			    cmdName, gettext("unable to get boot target's"
39738194SJack.Meng@Sun.COM 			    " name"));
39748194SJack.Meng@Sun.COM 			*funcRet = 1;
39758194SJack.Meng@Sun.COM 			return (ret);
39768194SJack.Meng@Sun.COM 		}
39778194SJack.Meng@Sun.COM 		status = SUN_IMA_GetBootTargetAuthParams(&bootTargetCHAP);
39788194SJack.Meng@Sun.COM 		if (!IMA_SUCCESS(status)) {
39798194SJack.Meng@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
39808194SJack.Meng@Sun.COM 			    cmdName, gettext("unable to get boot target's"
39818194SJack.Meng@Sun.COM 			    " auth param"));
39828194SJack.Meng@Sun.COM 			*funcRet = 1;
39838194SJack.Meng@Sun.COM 			return (ret);
39848194SJack.Meng@Sun.COM 		}
39858194SJack.Meng@Sun.COM 	}
39868194SJack.Meng@Sun.COM 
39877836SJohn.Forte@Sun.COM 	/* find target oid */
39887836SJohn.Forte@Sun.COM 	for (found = B_FALSE, i = 0; i < targetList->oidCount; i++) {
39897836SJohn.Forte@Sun.COM 		status = SUN_IMA_GetTargetProperties(targetList->oids[i],
39907836SJohn.Forte@Sun.COM 		    &targetProps);
39917836SJohn.Forte@Sun.COM 		if (!IMA_SUCCESS(status)) {
39927836SJohn.Forte@Sun.COM 			printLibError(status);
39937836SJohn.Forte@Sun.COM 			(void) IMA_FreeMemory(targetList);
39947836SJohn.Forte@Sun.COM 			*funcRet = 1;
39957836SJohn.Forte@Sun.COM 			return (ret);
39967836SJohn.Forte@Sun.COM 		}
39977836SJohn.Forte@Sun.COM 
39987836SJohn.Forte@Sun.COM 		/*
39997836SJohn.Forte@Sun.COM 		 * Compare the target name with the input name
40007836SJohn.Forte@Sun.COM 		 */
40017836SJohn.Forte@Sun.COM 		if ((targetNamesEqual(wcInputObject, targetProps.imaProps.name)
40027836SJohn.Forte@Sun.COM 		    == B_TRUE)) {
40037836SJohn.Forte@Sun.COM 			/*
40047836SJohn.Forte@Sun.COM 			 * For now, regardless of whether a target address
40057836SJohn.Forte@Sun.COM 			 * is specified, we return B_TRUE because
40067836SJohn.Forte@Sun.COM 			 * IMA_TARGET_PROPERTIES does not have a field for
40077836SJohn.Forte@Sun.COM 			 * specifying address.
40087836SJohn.Forte@Sun.COM 			 */
40097836SJohn.Forte@Sun.COM 			found = B_TRUE;
40107836SJohn.Forte@Sun.COM 			targetOid = targetList->oids[i];
40118194SJack.Meng@Sun.COM 
40128194SJack.Meng@Sun.COM 			if ((targetNamesEqual(bootTargetName, wcInputObject)
40138194SJack.Meng@Sun.COM 			    == B_TRUE) && (iscsiBoot == IMA_TRUE)) {
40148194SJack.Meng@Sun.COM 				/*
40158194SJack.Meng@Sun.COM 				 * iscsi booting, need changed target param is
40168194SJack.Meng@Sun.COM 				 * booting target, for auth param, not allow
40178194SJack.Meng@Sun.COM 				 * to change, for others dependent on mpxio
40188194SJack.Meng@Sun.COM 				 */
40198194SJack.Meng@Sun.COM 
40208194SJack.Meng@Sun.COM 				if ((optionList->optval == 'C') ||
40218194SJack.Meng@Sun.COM 				    (optionList->optval == 'H') ||
40228194SJack.Meng@Sun.COM 				    (optionList->optval == 'B') ||
40238194SJack.Meng@Sun.COM 				    (optionList->optval == 'a')) {
40248194SJack.Meng@Sun.COM 					/*
40258194SJack.Meng@Sun.COM 					 * -C CHAP secret set
40268194SJack.Meng@Sun.COM 					 * -H CHAP name set
40278194SJack.Meng@Sun.COM 					 * -a authentication
40288194SJack.Meng@Sun.COM 					 * -B bi-directional-authentication
40298194SJack.Meng@Sun.COM 					 */
40308194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
40318194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot,"
40328194SJack.Meng@Sun.COM 					    " not allowed to modify"
40338194SJack.Meng@Sun.COM 					    " authentication parameters"
40348194SJack.Meng@Sun.COM 					    "  of boot target"));
40358194SJack.Meng@Sun.COM 					return (1);
40368194SJack.Meng@Sun.COM 				}
40378194SJack.Meng@Sun.COM 				if (mpxioEnabled == IMA_FALSE) {
40388194SJack.Meng@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
40398194SJack.Meng@Sun.COM 					    cmdName, gettext("iscsi boot and"
40408194SJack.Meng@Sun.COM 					    " MPxIO is disabled, not allowed"
40418194SJack.Meng@Sun.COM 					    " to modify boot target's"
40428194SJack.Meng@Sun.COM 					    " parameters"));
40438194SJack.Meng@Sun.COM 					return (1);
40448194SJack.Meng@Sun.COM 				}
40458194SJack.Meng@Sun.COM 
40468194SJack.Meng@Sun.COM 			}
40478194SJack.Meng@Sun.COM 
40487836SJohn.Forte@Sun.COM 			if (modifyIndividualTargetParam(optionList, targetOid,
40497836SJohn.Forte@Sun.COM 			    funcRet) != 0) {
40507836SJohn.Forte@Sun.COM 				return (ret);
40517836SJohn.Forte@Sun.COM 			}
40527836SJohn.Forte@Sun.COM 
40537836SJohn.Forte@Sun.COM 			/*
40547836SJohn.Forte@Sun.COM 			 * Even after finding a matched target, keep going
40557836SJohn.Forte@Sun.COM 			 * since there could be multiple target objects
40567836SJohn.Forte@Sun.COM 			 * associated with one target name in the system
40577836SJohn.Forte@Sun.COM 			 * because of different TPGTs.
40587836SJohn.Forte@Sun.COM 			 */
40597836SJohn.Forte@Sun.COM 		}
40607836SJohn.Forte@Sun.COM 	}
40617836SJohn.Forte@Sun.COM 
40627836SJohn.Forte@Sun.COM 	/* If the target OID cannot be found create one */
40637836SJohn.Forte@Sun.COM 	if (!found) {
40647836SJohn.Forte@Sun.COM 		status = SUN_IMA_CreateTargetOid(wcInputObject, &targetOid);
40657836SJohn.Forte@Sun.COM 		if (!IMA_SUCCESS(status)) {
40667836SJohn.Forte@Sun.COM 			printLibError(status);
40677836SJohn.Forte@Sun.COM 			(void) IMA_FreeMemory(targetList);
40687836SJohn.Forte@Sun.COM 			*funcRet = 1;
40697836SJohn.Forte@Sun.COM 			return (ret);
40707836SJohn.Forte@Sun.COM 		}
40717836SJohn.Forte@Sun.COM 		if (modifyIndividualTargetParam(optionList, targetOid,
40727836SJohn.Forte@Sun.COM 		    funcRet) != 0) {
40737836SJohn.Forte@Sun.COM 				return (ret);
40747836SJohn.Forte@Sun.COM 		}
40757836SJohn.Forte@Sun.COM 	}
40767836SJohn.Forte@Sun.COM 
40777836SJohn.Forte@Sun.COM 	(void) IMA_FreeMemory(targetList);
40787836SJohn.Forte@Sun.COM 	return (ret);
40797836SJohn.Forte@Sun.COM }
40807836SJohn.Forte@Sun.COM 
40817836SJohn.Forte@Sun.COM /*
40827836SJohn.Forte@Sun.COM  * Add one or more addresses
40837836SJohn.Forte@Sun.COM  */
40847836SJohn.Forte@Sun.COM static int
40857836SJohn.Forte@Sun.COM addAddress(int addrType, int operandLen, char *operand[], int *funcRet)
40867836SJohn.Forte@Sun.COM {
40877836SJohn.Forte@Sun.COM 	IMA_STATUS status;
40887836SJohn.Forte@Sun.COM 	IMA_OID oid, addressOid;
40897836SJohn.Forte@Sun.COM 	SUN_IMA_TARGET_ADDRESS address;
40907836SJohn.Forte@Sun.COM 	wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
40917836SJohn.Forte@Sun.COM 	int ret;
40927836SJohn.Forte@Sun.COM 	int i;
40937836SJohn.Forte@Sun.COM 
40947836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
40957836SJohn.Forte@Sun.COM 
40967836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
40977836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&oid);
40987836SJohn.Forte@Sun.COM 	if (ret > 0) {
40997836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
41007836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
41017836SJohn.Forte@Sun.COM 	}
41027836SJohn.Forte@Sun.COM 
41037836SJohn.Forte@Sun.COM 	if (ret != 0) {
41047836SJohn.Forte@Sun.COM 		return (ret);
41057836SJohn.Forte@Sun.COM 	}
41067836SJohn.Forte@Sun.COM 
41077836SJohn.Forte@Sun.COM 	/*
41087836SJohn.Forte@Sun.COM 	 * Format of discovery address operand:
41097836SJohn.Forte@Sun.COM 	 *
41107836SJohn.Forte@Sun.COM 	 * <IP address|hostname>:<port>
41117836SJohn.Forte@Sun.COM 	 */
41127836SJohn.Forte@Sun.COM 	for (i = 0; i < operandLen; i++) {
41137836SJohn.Forte@Sun.COM 		/* initialize */
41147836SJohn.Forte@Sun.COM 		(void) memset(&wcInputObject[0], 0, sizeof (wcInputObject));
41157836SJohn.Forte@Sun.COM 		(void) memset(&address, 0, sizeof (address));
41167836SJohn.Forte@Sun.COM 
41177836SJohn.Forte@Sun.COM 		if (mbstowcs(wcInputObject, operand[i],
41187836SJohn.Forte@Sun.COM 		    (MAX_ADDRESS_LEN + 1)) == (size_t)-1) {
41197836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
41207836SJohn.Forte@Sun.COM 			    cmdName, gettext("conversion error"));
41217836SJohn.Forte@Sun.COM 			ret = 1;
41227836SJohn.Forte@Sun.COM 			continue;
41237836SJohn.Forte@Sun.COM 		}
41247836SJohn.Forte@Sun.COM 		if (getTargetAddress(addrType, operand[i], &address.imaStruct)
41257836SJohn.Forte@Sun.COM 		    != 0) {
41267836SJohn.Forte@Sun.COM 			ret = 1;
41277836SJohn.Forte@Sun.COM 			continue;
41287836SJohn.Forte@Sun.COM 		}
41297836SJohn.Forte@Sun.COM 		if (addrType == DISCOVERY_ADDRESS) {
41307836SJohn.Forte@Sun.COM 			status = IMA_AddDiscoveryAddress(oid,
41317836SJohn.Forte@Sun.COM 			    address.imaStruct, &addressOid);
41327836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
41337836SJohn.Forte@Sun.COM 				printLibError(status);
41347836SJohn.Forte@Sun.COM 				*funcRet = 1;
41357836SJohn.Forte@Sun.COM 				return (ret);
41367836SJohn.Forte@Sun.COM 			}
41377836SJohn.Forte@Sun.COM 		} else if (addrType == ISNS_SERVER_ADDRESS) {
41387836SJohn.Forte@Sun.COM 			status = SUN_IMA_AddISNSServerAddress(address);
41397836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
41407836SJohn.Forte@Sun.COM 				printLibError(status);
41417836SJohn.Forte@Sun.COM 				*funcRet = 1;
41427836SJohn.Forte@Sun.COM 				return (ret);
41437836SJohn.Forte@Sun.COM 			}
41447836SJohn.Forte@Sun.COM 		}
41457836SJohn.Forte@Sun.COM 	}
41467836SJohn.Forte@Sun.COM 	return (ret);
41477836SJohn.Forte@Sun.COM }
41487836SJohn.Forte@Sun.COM 
41497836SJohn.Forte@Sun.COM /*
41507836SJohn.Forte@Sun.COM  * Add one or more static configuration targets
41517836SJohn.Forte@Sun.COM  */
41527836SJohn.Forte@Sun.COM static int
41537836SJohn.Forte@Sun.COM addStaticConfig(int operandLen, char *operand[], int *funcRet)
41547836SJohn.Forte@Sun.COM {
41557836SJohn.Forte@Sun.COM 	int i;
41567836SJohn.Forte@Sun.COM 	boolean_t targetAddressSpecified = B_FALSE;
41577836SJohn.Forte@Sun.COM 	boolean_t tpgtSpecified = B_FALSE;
41587836SJohn.Forte@Sun.COM 	boolean_t isIpv6 = B_FALSE;
41597836SJohn.Forte@Sun.COM 	int ret;
41607836SJohn.Forte@Sun.COM 	int addrType;
41617836SJohn.Forte@Sun.COM 	IMA_STATUS status;
41627836SJohn.Forte@Sun.COM 	IMA_OID oid;
41637836SJohn.Forte@Sun.COM 	SUN_IMA_STATIC_DISCOVERY_TARGET staticConfig;
41647836SJohn.Forte@Sun.COM 	IMA_UINT16 port = 0;
41657836SJohn.Forte@Sun.COM 	IMA_UINT16 tpgt = 0;
41667836SJohn.Forte@Sun.COM 	wchar_t staticTargetName[MAX_ISCSI_NAME_LEN + 1];
41677836SJohn.Forte@Sun.COM 	wchar_t staticTargetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
41687836SJohn.Forte@Sun.COM 	iSCSINameCheckStatusType nameCheckStatus;
41697836SJohn.Forte@Sun.COM 	char sAddr[SUN_IMA_IP_ADDRESS_PORT_LEN];
41707836SJohn.Forte@Sun.COM 
41717836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
41727836SJohn.Forte@Sun.COM 
41737836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
41747836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&oid);
41757836SJohn.Forte@Sun.COM 	if (ret > 0) {
41767836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
41777836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
41787836SJohn.Forte@Sun.COM 	}
41797836SJohn.Forte@Sun.COM 
41807836SJohn.Forte@Sun.COM 	if (ret != 0) {
41817836SJohn.Forte@Sun.COM 		return (ret);
41827836SJohn.Forte@Sun.COM 	}
41837836SJohn.Forte@Sun.COM 
41847836SJohn.Forte@Sun.COM 	/*
41857836SJohn.Forte@Sun.COM 	 * Format of static config operand:
41867836SJohn.Forte@Sun.COM 	 *  <target-name>,<IP address|hostname>[:port][,tpgt]
41877836SJohn.Forte@Sun.COM 	 */
41887836SJohn.Forte@Sun.COM 	for (i = 0; i < operandLen; i++) {
41897836SJohn.Forte@Sun.COM 		if (parseTarget(operand[i],
41907836SJohn.Forte@Sun.COM 		    &staticTargetName[0],
41917836SJohn.Forte@Sun.COM 		    MAX_ISCSI_NAME_LEN + 1,
41927836SJohn.Forte@Sun.COM 		    &targetAddressSpecified,
41937836SJohn.Forte@Sun.COM 		    &staticTargetAddress[0],
41947836SJohn.Forte@Sun.COM 		    SUN_IMA_IP_ADDRESS_PORT_LEN,
41957836SJohn.Forte@Sun.COM 		    &port,
41967836SJohn.Forte@Sun.COM 		    &tpgtSpecified,
41977836SJohn.Forte@Sun.COM 		    &tpgt,
41987836SJohn.Forte@Sun.COM 		    &isIpv6) != PARSE_TARGET_OK) {
41997836SJohn.Forte@Sun.COM 			ret = 1;
42007836SJohn.Forte@Sun.COM 			continue;
42017836SJohn.Forte@Sun.COM 		}
42027836SJohn.Forte@Sun.COM 
42037836SJohn.Forte@Sun.COM 		if (targetAddressSpecified != B_TRUE) {
42047836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
42057836SJohn.Forte@Sun.COM 			    cmdName, gettext("missing target address"));
42067836SJohn.Forte@Sun.COM 			*funcRet = 1; /* DIY message fix */
42077836SJohn.Forte@Sun.COM 			return (1);
42087836SJohn.Forte@Sun.COM 		}
42097836SJohn.Forte@Sun.COM 		/* Perform string profile checks */
42107836SJohn.Forte@Sun.COM 		nameCheckStatus = iSCSINameStringProfileCheck(staticTargetName);
42117836SJohn.Forte@Sun.COM 		iSCSINameCheckStatusDisplay(nameCheckStatus);
42127836SJohn.Forte@Sun.COM 		if (nameCheckStatus != iSCSINameCheckOK) {
42137836SJohn.Forte@Sun.COM 			*funcRet = 1; /* DIY message fix */
42147836SJohn.Forte@Sun.COM 			return (1);
42157836SJohn.Forte@Sun.COM 		}
42167836SJohn.Forte@Sun.COM 		(void) wcsncpy(staticConfig.targetName, staticTargetName,
42177836SJohn.Forte@Sun.COM 		    MAX_ISCSI_NAME_LEN + 1);
42187836SJohn.Forte@Sun.COM 
42197836SJohn.Forte@Sun.COM 		(void) wcstombs(sAddr, staticTargetAddress, sizeof (sAddr));
42207836SJohn.Forte@Sun.COM 
42217836SJohn.Forte@Sun.COM 		if (isIpv6 == B_TRUE) {
42227836SJohn.Forte@Sun.COM 			staticConfig.targetAddress.imaStruct.hostnameIpAddress.
42237836SJohn.Forte@Sun.COM 			    id.ipAddress.ipv4Address = B_FALSE;
42247836SJohn.Forte@Sun.COM 			addrType = AF_INET6;
42257836SJohn.Forte@Sun.COM 		} else {
42267836SJohn.Forte@Sun.COM 			staticConfig.targetAddress.imaStruct.hostnameIpAddress.
42277836SJohn.Forte@Sun.COM 			    id.ipAddress.ipv4Address = B_TRUE;
42287836SJohn.Forte@Sun.COM 			addrType = AF_INET;
42297836SJohn.Forte@Sun.COM 		}
42307836SJohn.Forte@Sun.COM 
42317836SJohn.Forte@Sun.COM 		if (inet_pton(addrType, sAddr, staticConfig.targetAddress.
42327836SJohn.Forte@Sun.COM 		    imaStruct.hostnameIpAddress.id.ipAddress.ipAddress) != 1) {
42337836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
42347836SJohn.Forte@Sun.COM 			    cmdName, gettext("static config conversion error"));
42357836SJohn.Forte@Sun.COM 			ret = 1;
42367836SJohn.Forte@Sun.COM 			continue;
42377836SJohn.Forte@Sun.COM 		}
42387836SJohn.Forte@Sun.COM 
42397836SJohn.Forte@Sun.COM 		staticConfig.targetAddress.imaStruct.portNumber = port;
42407836SJohn.Forte@Sun.COM 		if (tpgtSpecified == B_TRUE) {
42417836SJohn.Forte@Sun.COM 			staticConfig.targetAddress.defaultTpgt = B_FALSE;
42427836SJohn.Forte@Sun.COM 			staticConfig.targetAddress.tpgt = tpgt;
42437836SJohn.Forte@Sun.COM 		} else {
42447836SJohn.Forte@Sun.COM 			staticConfig.targetAddress.defaultTpgt = B_TRUE;
42457836SJohn.Forte@Sun.COM 			staticConfig.targetAddress.tpgt = 0;
42467836SJohn.Forte@Sun.COM 		}
42477836SJohn.Forte@Sun.COM 
42487836SJohn.Forte@Sun.COM 		status = SUN_IMA_AddStaticTarget(oid, staticConfig, &oid);
42497836SJohn.Forte@Sun.COM 		if (!IMA_SUCCESS(status)) {
42507836SJohn.Forte@Sun.COM 			printLibError(status);
42517836SJohn.Forte@Sun.COM 			*funcRet = 1;
42527836SJohn.Forte@Sun.COM 			return (1);
42537836SJohn.Forte@Sun.COM 		}
42547836SJohn.Forte@Sun.COM 	}
42557836SJohn.Forte@Sun.COM 	return (ret);
42567836SJohn.Forte@Sun.COM }
42577836SJohn.Forte@Sun.COM 
42587836SJohn.Forte@Sun.COM /*
42597836SJohn.Forte@Sun.COM  * Remove one or more addresses
42607836SJohn.Forte@Sun.COM  */
42617836SJohn.Forte@Sun.COM static int
42627836SJohn.Forte@Sun.COM removeAddress(int addrType, int operandLen, char *operand[], int *funcRet)
42637836SJohn.Forte@Sun.COM {
42647836SJohn.Forte@Sun.COM 	IMA_STATUS status;
42657836SJohn.Forte@Sun.COM 	IMA_OID initiatorOid;
42667836SJohn.Forte@Sun.COM 	SUN_IMA_TARGET_ADDRESS address;
42677836SJohn.Forte@Sun.COM 	wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
42687836SJohn.Forte@Sun.COM 	int ret;
42697836SJohn.Forte@Sun.COM 	int i;
42707836SJohn.Forte@Sun.COM 
42717836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
42727836SJohn.Forte@Sun.COM 
42737836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
42747836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
42757836SJohn.Forte@Sun.COM 	if (ret > 0) {
42767836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
42777836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
42787836SJohn.Forte@Sun.COM 	}
42797836SJohn.Forte@Sun.COM 
42807836SJohn.Forte@Sun.COM 	if (ret != 0) {
42817836SJohn.Forte@Sun.COM 		return (ret);
42827836SJohn.Forte@Sun.COM 	}
42837836SJohn.Forte@Sun.COM 
42847836SJohn.Forte@Sun.COM 	for (i = 0; i < operandLen; i++) {
42857836SJohn.Forte@Sun.COM 		/* initialize */
42867836SJohn.Forte@Sun.COM 		(void) memset(&wcInputObject[0], 0, sizeof (wcInputObject));
42877836SJohn.Forte@Sun.COM 		(void) memset(&address, 0, sizeof (address));
42887836SJohn.Forte@Sun.COM 
42897836SJohn.Forte@Sun.COM 		if (mbstowcs(wcInputObject, operand[i],
42907836SJohn.Forte@Sun.COM 		    MAX_ADDRESS_LEN + 1) == (size_t)-1) {
42917836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
42927836SJohn.Forte@Sun.COM 			    cmdName, gettext("conversion error"));
42937836SJohn.Forte@Sun.COM 			ret = 1;
42947836SJohn.Forte@Sun.COM 			continue;
42957836SJohn.Forte@Sun.COM 		}
42967836SJohn.Forte@Sun.COM 
42977836SJohn.Forte@Sun.COM 		if (getTargetAddress(addrType, operand[i], &address.imaStruct)
42987836SJohn.Forte@Sun.COM 		    != 0) {
42997836SJohn.Forte@Sun.COM 			ret = 1;
43007836SJohn.Forte@Sun.COM 			continue;
43017836SJohn.Forte@Sun.COM 		}
43027836SJohn.Forte@Sun.COM 
43037836SJohn.Forte@Sun.COM 		if (addrType == DISCOVERY_ADDRESS) {
43047836SJohn.Forte@Sun.COM 			status = SUN_IMA_RemoveDiscoveryAddress(address);
43057836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
43067836SJohn.Forte@Sun.COM 				if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
43077836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s\n",
43087836SJohn.Forte@Sun.COM 					    operand[i], gettext("not found"));
43097836SJohn.Forte@Sun.COM 				} else {
43107836SJohn.Forte@Sun.COM 					printLibError(status);
43117836SJohn.Forte@Sun.COM 				}
43127836SJohn.Forte@Sun.COM 				*funcRet = 1;
43137836SJohn.Forte@Sun.COM 			}
43147836SJohn.Forte@Sun.COM 		} else {
43157836SJohn.Forte@Sun.COM 			status = SUN_IMA_RemoveISNSServerAddress(address);
43167836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
43177836SJohn.Forte@Sun.COM 				printLibError(status);
43187836SJohn.Forte@Sun.COM 				*funcRet = 1;
43197836SJohn.Forte@Sun.COM 			}
43207836SJohn.Forte@Sun.COM 		}
43217836SJohn.Forte@Sun.COM 	}
43227836SJohn.Forte@Sun.COM 	return (ret);
43237836SJohn.Forte@Sun.COM }
43247836SJohn.Forte@Sun.COM 
43257836SJohn.Forte@Sun.COM /*
43267836SJohn.Forte@Sun.COM  * Remove one or more static configuration targets
43277836SJohn.Forte@Sun.COM  */
43287836SJohn.Forte@Sun.COM static int
43297836SJohn.Forte@Sun.COM removeStaticConfig(int operandLen, char *operand[], int *funcRet)
43307836SJohn.Forte@Sun.COM {
43317836SJohn.Forte@Sun.COM 	IMA_STATUS status;
43327836SJohn.Forte@Sun.COM 	IMA_OID initiatorOid;
43337836SJohn.Forte@Sun.COM 	IMA_OID_LIST *staticTargetList;
43347836SJohn.Forte@Sun.COM 	SUN_IMA_STATIC_TARGET_PROPERTIES staticTargetProps;
43357836SJohn.Forte@Sun.COM 	wchar_t staticTargetName[MAX_ISCSI_NAME_LEN + 1];
43367836SJohn.Forte@Sun.COM 	wchar_t staticTargetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
43377836SJohn.Forte@Sun.COM 	int ret;
43387836SJohn.Forte@Sun.COM 	boolean_t atLeastFoundOne;
43397836SJohn.Forte@Sun.COM 	boolean_t matched;
43407836SJohn.Forte@Sun.COM 	boolean_t targetAddressSpecified = B_TRUE;
43417836SJohn.Forte@Sun.COM 	boolean_t tpgtSpecified = B_FALSE;
43427836SJohn.Forte@Sun.COM 	boolean_t isIpv6 = B_FALSE;
43437836SJohn.Forte@Sun.COM 	int i, j;
43447836SJohn.Forte@Sun.COM 	IMA_UINT16 port = 0;
43457836SJohn.Forte@Sun.COM 	IMA_UINT16 tpgt = 0;
43467836SJohn.Forte@Sun.COM 	iSCSINameCheckStatusType nameCheckStatus;
43477836SJohn.Forte@Sun.COM 	char tmpStr[SUN_IMA_IP_ADDRESS_PORT_LEN];
43487836SJohn.Forte@Sun.COM 	wchar_t tmpTargetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
43497836SJohn.Forte@Sun.COM 
43507836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
43517836SJohn.Forte@Sun.COM 
43527836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
43537836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
43547836SJohn.Forte@Sun.COM 	if (ret > 0) {
43557836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
43567836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
43577836SJohn.Forte@Sun.COM 	}
43587836SJohn.Forte@Sun.COM 
43597836SJohn.Forte@Sun.COM 	if (ret != 0) {
43607836SJohn.Forte@Sun.COM 		return (ret);
43617836SJohn.Forte@Sun.COM 	}
43627836SJohn.Forte@Sun.COM 
43637836SJohn.Forte@Sun.COM 	status = IMA_GetStaticDiscoveryTargetOidList(initiatorOid,
43647836SJohn.Forte@Sun.COM 	    &staticTargetList);
43657836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
43667836SJohn.Forte@Sun.COM 		printLibError(status);
43677836SJohn.Forte@Sun.COM 		*funcRet = 1;
43687836SJohn.Forte@Sun.COM 		return (ret);
43697836SJohn.Forte@Sun.COM 	}
43707836SJohn.Forte@Sun.COM 
43717836SJohn.Forte@Sun.COM 	for (i = 0; i < operandLen; i++) {
43727836SJohn.Forte@Sun.COM 		if (parseTarget(operand[i],
43737836SJohn.Forte@Sun.COM 		    &staticTargetName[0],
43747836SJohn.Forte@Sun.COM 		    MAX_ISCSI_NAME_LEN + 1,
43757836SJohn.Forte@Sun.COM 		    &targetAddressSpecified,
43767836SJohn.Forte@Sun.COM 		    &staticTargetAddress[0],
43777836SJohn.Forte@Sun.COM 		    SUN_IMA_IP_ADDRESS_PORT_LEN,
43787836SJohn.Forte@Sun.COM 		    &port,
43797836SJohn.Forte@Sun.COM 		    &tpgtSpecified,
43807836SJohn.Forte@Sun.COM 		    &tpgt,
43817836SJohn.Forte@Sun.COM 		    &isIpv6) != PARSE_TARGET_OK) {
43827836SJohn.Forte@Sun.COM 			ret = 1;
43837836SJohn.Forte@Sun.COM 			continue;
43847836SJohn.Forte@Sun.COM 		}
43857836SJohn.Forte@Sun.COM 
43867836SJohn.Forte@Sun.COM 		/* Perform string profile checks */
43877836SJohn.Forte@Sun.COM 		nameCheckStatus = iSCSINameStringProfileCheck(staticTargetName);
43887836SJohn.Forte@Sun.COM 		iSCSINameCheckStatusDisplay(nameCheckStatus);
43897836SJohn.Forte@Sun.COM 		if (nameCheckStatus != iSCSINameCheckOK) {
43907836SJohn.Forte@Sun.COM 			return (1);
43917836SJohn.Forte@Sun.COM 		}
43927836SJohn.Forte@Sun.COM 
43937836SJohn.Forte@Sun.COM 		for (atLeastFoundOne = B_FALSE, j = 0;
43947836SJohn.Forte@Sun.COM 		    j < staticTargetList->oidCount;
43957836SJohn.Forte@Sun.COM 		    j++) {
43967836SJohn.Forte@Sun.COM 			IMA_UINT16 stpgt;
43977836SJohn.Forte@Sun.COM 
43987836SJohn.Forte@Sun.COM 			matched = B_FALSE;
43997836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetStaticTargetProperties(
44007836SJohn.Forte@Sun.COM 			    staticTargetList->oids[j], &staticTargetProps);
44017836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
44027836SJohn.Forte@Sun.COM 				if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
44037836SJohn.Forte@Sun.COM 					/*
44047836SJohn.Forte@Sun.COM 					 * When removing multiple static-config
44057836SJohn.Forte@Sun.COM 					 * entries we need to expect get
44067836SJohn.Forte@Sun.COM 					 * failures. These failures occur when
44077836SJohn.Forte@Sun.COM 					 * we are trying to get entry
44087836SJohn.Forte@Sun.COM 					 * information we have just removed.
44097836SJohn.Forte@Sun.COM 					 * Ignore the failure and continue.
44107836SJohn.Forte@Sun.COM 					 */
44117836SJohn.Forte@Sun.COM 					ret = 1;
44127836SJohn.Forte@Sun.COM 					continue;
44137836SJohn.Forte@Sun.COM 				} else {
44147836SJohn.Forte@Sun.COM 					printLibError(status);
44157836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(staticTargetList);
44167836SJohn.Forte@Sun.COM 					*funcRet = 1;
44177836SJohn.Forte@Sun.COM 					return (ret);
44187836SJohn.Forte@Sun.COM 				}
44197836SJohn.Forte@Sun.COM 			}
44207836SJohn.Forte@Sun.COM 
44217836SJohn.Forte@Sun.COM 			stpgt =
44227836SJohn.Forte@Sun.COM 			    staticTargetProps.staticTarget.targetAddress.tpgt;
44237836SJohn.Forte@Sun.COM 
44247836SJohn.Forte@Sun.COM 			/*
44257836SJohn.Forte@Sun.COM 			 * Compare the static target name with the input if
44267836SJohn.Forte@Sun.COM 			 * one was input
44277836SJohn.Forte@Sun.COM 			 */
44287836SJohn.Forte@Sun.COM 			if ((targetNamesEqual(
44297836SJohn.Forte@Sun.COM 			    staticTargetProps.staticTarget.targetName,
44307836SJohn.Forte@Sun.COM 			    staticTargetName) == B_TRUE)) {
44317836SJohn.Forte@Sun.COM 				if (targetAddressSpecified == B_FALSE) {
44327836SJohn.Forte@Sun.COM 					matched = B_TRUE;
44337836SJohn.Forte@Sun.COM 				} else {
44347836SJohn.Forte@Sun.COM 
44357836SJohn.Forte@Sun.COM 					if (staticTargetProps.staticTarget.
44367836SJohn.Forte@Sun.COM 					    targetAddress.imaStruct.
44377836SJohn.Forte@Sun.COM 					    hostnameIpAddress.
44387836SJohn.Forte@Sun.COM 					    id.ipAddress.ipv4Address ==
44397836SJohn.Forte@Sun.COM 					    IMA_TRUE) {
44407836SJohn.Forte@Sun.COM 						(void) inet_ntop(AF_INET,
44417836SJohn.Forte@Sun.COM 						    staticTargetProps.
44427836SJohn.Forte@Sun.COM 						    staticTarget.targetAddress.
44437836SJohn.Forte@Sun.COM 						    imaStruct.hostnameIpAddress.
44447836SJohn.Forte@Sun.COM 						    id.ipAddress.ipAddress,
44457836SJohn.Forte@Sun.COM 						    tmpStr,
44467836SJohn.Forte@Sun.COM 						    sizeof (tmpStr));
44477836SJohn.Forte@Sun.COM 					} else {
44487836SJohn.Forte@Sun.COM 						(void) inet_ntop(AF_INET6,
44497836SJohn.Forte@Sun.COM 						    staticTargetProps.
44507836SJohn.Forte@Sun.COM 						    staticTarget.targetAddress.
44517836SJohn.Forte@Sun.COM 						    imaStruct.hostnameIpAddress.
44527836SJohn.Forte@Sun.COM 						    id.ipAddress.ipAddress,
44537836SJohn.Forte@Sun.COM 						    tmpStr,
44547836SJohn.Forte@Sun.COM 						    sizeof (tmpStr));
44557836SJohn.Forte@Sun.COM 					}
44567836SJohn.Forte@Sun.COM 
44577836SJohn.Forte@Sun.COM 					if (mbstowcs(tmpTargetAddress, tmpStr,
44587836SJohn.Forte@Sun.COM 					    SUN_IMA_IP_ADDRESS_PORT_LEN) ==
44597836SJohn.Forte@Sun.COM 					    (size_t)-1) {
44607836SJohn.Forte@Sun.COM 						(void) fprintf(stderr,
44617836SJohn.Forte@Sun.COM 						    "%s: %s\n",
44627836SJohn.Forte@Sun.COM 						    cmdName, gettext(
44637836SJohn.Forte@Sun.COM 						    "conversion error"));
44647836SJohn.Forte@Sun.COM 						ret = 1;
44657836SJohn.Forte@Sun.COM 						continue;
44667836SJohn.Forte@Sun.COM 					}
44677836SJohn.Forte@Sun.COM 
44687836SJohn.Forte@Sun.COM 					if ((wcsncmp(tmpTargetAddress,
44697836SJohn.Forte@Sun.COM 					    staticTargetAddress,
44707836SJohn.Forte@Sun.COM 					    SUN_IMA_IP_ADDRESS_PORT_LEN) ==
44717836SJohn.Forte@Sun.COM 					    0) && (staticTargetProps.
44727836SJohn.Forte@Sun.COM 					    staticTarget.targetAddress.
44737836SJohn.Forte@Sun.COM 					    imaStruct.portNumber == port)) {
44747836SJohn.Forte@Sun.COM 						if (tpgtSpecified == B_FALSE) {
44757836SJohn.Forte@Sun.COM 							matched = B_TRUE;
44767836SJohn.Forte@Sun.COM 						} else {
44777836SJohn.Forte@Sun.COM 							if (tpgt == stpgt) {
44787836SJohn.Forte@Sun.COM 								matched =
44797836SJohn.Forte@Sun.COM 								    B_TRUE;
44807836SJohn.Forte@Sun.COM 							}
44817836SJohn.Forte@Sun.COM 						}
44827836SJohn.Forte@Sun.COM 					}
44837836SJohn.Forte@Sun.COM 				}
44847836SJohn.Forte@Sun.COM 
44857836SJohn.Forte@Sun.COM 				if (matched) {
44867836SJohn.Forte@Sun.COM 					status =
44877836SJohn.Forte@Sun.COM 					    IMA_RemoveStaticDiscoveryTarget(
44887836SJohn.Forte@Sun.COM 					    staticTargetList->oids[j]);
44897836SJohn.Forte@Sun.COM 					if (!IMA_SUCCESS(status)) {
44907836SJohn.Forte@Sun.COM 						printLibError(status);
44917836SJohn.Forte@Sun.COM 						*funcRet = 1;
44927836SJohn.Forte@Sun.COM 						return (ret);
44937836SJohn.Forte@Sun.COM 					}
44947836SJohn.Forte@Sun.COM 					atLeastFoundOne = B_TRUE;
44957836SJohn.Forte@Sun.COM 				}
44967836SJohn.Forte@Sun.COM 			}
44977836SJohn.Forte@Sun.COM 		}
44987836SJohn.Forte@Sun.COM 		if (!atLeastFoundOne) {
44997836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, gettext("%ws,%ws: %s\n"),
45007836SJohn.Forte@Sun.COM 			    staticTargetName, staticTargetAddress,
45017836SJohn.Forte@Sun.COM 			    gettext("not found"));
45027836SJohn.Forte@Sun.COM 		}
45037836SJohn.Forte@Sun.COM 	}
45047836SJohn.Forte@Sun.COM 	return (ret);
45057836SJohn.Forte@Sun.COM }
45067836SJohn.Forte@Sun.COM 
45077836SJohn.Forte@Sun.COM /*
45087836SJohn.Forte@Sun.COM  * Remove one or more target params.
45097836SJohn.Forte@Sun.COM  */
45107836SJohn.Forte@Sun.COM static int
45117836SJohn.Forte@Sun.COM removeTargetParam(int operandLen, char *operand[], int *funcRet)
45127836SJohn.Forte@Sun.COM {
45137836SJohn.Forte@Sun.COM 	char *commaPos;
45147836SJohn.Forte@Sun.COM 	IMA_STATUS status;
45157836SJohn.Forte@Sun.COM 	IMA_OID initiatorOid;
45167836SJohn.Forte@Sun.COM 	IMA_OID_LIST *targetList;
45177836SJohn.Forte@Sun.COM 	SUN_IMA_TARGET_PROPERTIES targetProps;
45187836SJohn.Forte@Sun.COM 	wchar_t wcInputObject[MAX_ISCSI_NAME_LEN + 1];
45197836SJohn.Forte@Sun.COM 	int ret;
45207836SJohn.Forte@Sun.COM 	boolean_t found;
45217836SJohn.Forte@Sun.COM 	int i, j;
45228194SJack.Meng@Sun.COM 	IMA_NODE_NAME bootTargetName;
45238194SJack.Meng@Sun.COM 	IMA_BOOL	iscsiBoot = IMA_FALSE;
45248194SJack.Meng@Sun.COM 	IMA_BOOL	mpxioEnabled = IMA_FALSE;
45258194SJack.Meng@Sun.COM 
45268194SJack.Meng@Sun.COM 	/* Get boot session's info */
45278194SJack.Meng@Sun.COM 	(void) SUN_IMA_GetBootIscsi(&iscsiBoot);
45288194SJack.Meng@Sun.COM 	if (iscsiBoot == IMA_TRUE) {
45298194SJack.Meng@Sun.COM 		status = SUN_IMA_GetBootMpxio(&mpxioEnabled);
45308194SJack.Meng@Sun.COM 		if (!IMA_SUCCESS(status)) {
45318194SJack.Meng@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
45328194SJack.Meng@Sun.COM 			    cmdName, gettext("unable to get MPxIO info of"
45338194SJack.Meng@Sun.COM 			    " root disk"));
45348194SJack.Meng@Sun.COM 			*funcRet = 1;
45358194SJack.Meng@Sun.COM 			return (1);
45368194SJack.Meng@Sun.COM 		}
45378194SJack.Meng@Sun.COM 		status = SUN_IMA_GetBootTargetName(bootTargetName);
45388194SJack.Meng@Sun.COM 		if (!IMA_SUCCESS(status)) {
45398194SJack.Meng@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
45408194SJack.Meng@Sun.COM 			    cmdName, gettext("unable to get boot"
45418194SJack.Meng@Sun.COM 			    " target's name"));
45428194SJack.Meng@Sun.COM 			*funcRet = 1;
45438194SJack.Meng@Sun.COM 			return (1);
45448194SJack.Meng@Sun.COM 		}
45458194SJack.Meng@Sun.COM 	}
45467836SJohn.Forte@Sun.COM 
45477836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
45487836SJohn.Forte@Sun.COM 
45497836SJohn.Forte@Sun.COM 	/* Find Sun initiator */
45507836SJohn.Forte@Sun.COM 	ret = sunInitiatorFind(&initiatorOid);
45517836SJohn.Forte@Sun.COM 	if (ret > 0) {
45527836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
45537836SJohn.Forte@Sun.COM 		    cmdName, gettext("no initiator found"));
45547836SJohn.Forte@Sun.COM 	}
45557836SJohn.Forte@Sun.COM 
45567836SJohn.Forte@Sun.COM 	if (ret != 0) {
45577836SJohn.Forte@Sun.COM 		return (ret);
45587836SJohn.Forte@Sun.COM 	}
45597836SJohn.Forte@Sun.COM 
45607836SJohn.Forte@Sun.COM 	status = IMA_GetTargetOidList(initiatorOid, &targetList);
45617836SJohn.Forte@Sun.COM 	if (!IMA_SUCCESS(status)) {
45627836SJohn.Forte@Sun.COM 		printLibError(status);
45637836SJohn.Forte@Sun.COM 		*funcRet = 1;
45647836SJohn.Forte@Sun.COM 		return (ret);
45657836SJohn.Forte@Sun.COM 	}
45667836SJohn.Forte@Sun.COM 
45677836SJohn.Forte@Sun.COM 	for (i = 0; i < operandLen; i++) {
45687836SJohn.Forte@Sun.COM 		/* initialize */
45697836SJohn.Forte@Sun.COM 		commaPos = strchr(operand[i], ',');
45707836SJohn.Forte@Sun.COM 		if (commaPos) {
45717836SJohn.Forte@Sun.COM 			/* Ignore IP address. */
45727836SJohn.Forte@Sun.COM 			*commaPos = NULL;
45737836SJohn.Forte@Sun.COM 		}
45747836SJohn.Forte@Sun.COM 		(void) memset(&wcInputObject[0], 0, sizeof (wcInputObject));
45757836SJohn.Forte@Sun.COM 		if (mbstowcs(wcInputObject, operand[i],
45767836SJohn.Forte@Sun.COM 		    MAX_ISCSI_NAME_LEN + 1) == (size_t)-1) {
45777836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n", cmdName,
45787836SJohn.Forte@Sun.COM 			    gettext("conversion error"));
45797836SJohn.Forte@Sun.COM 			ret = 1;
45807836SJohn.Forte@Sun.COM 			continue;
45817836SJohn.Forte@Sun.COM 		}
45827836SJohn.Forte@Sun.COM 
45837836SJohn.Forte@Sun.COM 		for (found = B_FALSE, j = 0; j < targetList->oidCount;
45847836SJohn.Forte@Sun.COM 		    j++) {
45857836SJohn.Forte@Sun.COM 			status = SUN_IMA_GetTargetProperties(
45867836SJohn.Forte@Sun.COM 			    targetList->oids[j], &targetProps);
45877836SJohn.Forte@Sun.COM 			if (!IMA_SUCCESS(status)) {
45887836SJohn.Forte@Sun.COM 				printLibError(status);
45897836SJohn.Forte@Sun.COM 				(void) IMA_FreeMemory(targetList);
45907836SJohn.Forte@Sun.COM 				*funcRet = 1;
45917836SJohn.Forte@Sun.COM 				return (ret);
45927836SJohn.Forte@Sun.COM 			}
45937836SJohn.Forte@Sun.COM 
45947836SJohn.Forte@Sun.COM 			/*
45957836SJohn.Forte@Sun.COM 			 * Compare the target name with the input if
45967836SJohn.Forte@Sun.COM 			 * one was input
45977836SJohn.Forte@Sun.COM 			 */
45987836SJohn.Forte@Sun.COM 			if (targetNamesEqual(targetProps.imaProps.name,
45997836SJohn.Forte@Sun.COM 			    wcInputObject) == B_TRUE) {
46007836SJohn.Forte@Sun.COM 				found = B_TRUE;
46018194SJack.Meng@Sun.COM 				if ((targetNamesEqual(bootTargetName,
46028194SJack.Meng@Sun.COM 				    wcInputObject) == B_TRUE) &&
46038194SJack.Meng@Sun.COM 				    (iscsiBoot == IMA_TRUE)) {
46048194SJack.Meng@Sun.COM 					/*
46058194SJack.Meng@Sun.COM 					 * iscsi booting, need changed target
46068194SJack.Meng@Sun.COM 					 * param is booting target, booting
46078194SJack.Meng@Sun.COM 					 * session mpxio disabled, not
46088194SJack.Meng@Sun.COM 					 * allow to update
46098194SJack.Meng@Sun.COM 					 */
46108194SJack.Meng@Sun.COM 					if (mpxioEnabled == IMA_FALSE) {
46118194SJack.Meng@Sun.COM 						(void) fprintf(stderr,
46128194SJack.Meng@Sun.COM 						    "%s: %s\n", cmdName,
46138194SJack.Meng@Sun.COM 						    gettext("iscsi boot"
46148194SJack.Meng@Sun.COM 						    " with MPxIO disabled,"
46158194SJack.Meng@Sun.COM 						    " not allowed to remove"
46168194SJack.Meng@Sun.COM 						    " boot sess param"));
46178194SJack.Meng@Sun.COM 						continue;
46188194SJack.Meng@Sun.COM 					}
46198194SJack.Meng@Sun.COM 
46208194SJack.Meng@Sun.COM 				}
46218194SJack.Meng@Sun.COM 
46227836SJohn.Forte@Sun.COM 				status = SUN_IMA_RemoveTargetParam(
46237836SJohn.Forte@Sun.COM 				    targetList->oids[j]);
46247836SJohn.Forte@Sun.COM 				if (!IMA_SUCCESS(status)) {
46257836SJohn.Forte@Sun.COM 					printLibError(status);
46267836SJohn.Forte@Sun.COM 					(void) IMA_FreeMemory(targetList);
46277836SJohn.Forte@Sun.COM 					*funcRet = 1;
46287836SJohn.Forte@Sun.COM 					return (ret);
46297836SJohn.Forte@Sun.COM 				}
46307836SJohn.Forte@Sun.COM 			}
46317836SJohn.Forte@Sun.COM 		}
46327836SJohn.Forte@Sun.COM 		if (!found) {
46337836SJohn.Forte@Sun.COM 			/* Silently ignoring it? */
46347836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, gettext("%ws: %s\n"),
46357836SJohn.Forte@Sun.COM 			    wcInputObject, gettext("not found"));
46367836SJohn.Forte@Sun.COM 		}
46377836SJohn.Forte@Sun.COM 	}
46387836SJohn.Forte@Sun.COM 
46397836SJohn.Forte@Sun.COM 	(void) IMA_FreeMemory(targetList);
46407836SJohn.Forte@Sun.COM 	return (ret);
46417836SJohn.Forte@Sun.COM }
46427836SJohn.Forte@Sun.COM 
46437836SJohn.Forte@Sun.COM /*ARGSUSED*/
46447836SJohn.Forte@Sun.COM static int
46457836SJohn.Forte@Sun.COM addFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
46467836SJohn.Forte@Sun.COM     void *addArgs, int *funcRet)
46477836SJohn.Forte@Sun.COM {
46487836SJohn.Forte@Sun.COM 	int ret;
46497836SJohn.Forte@Sun.COM 
46507836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
46517836SJohn.Forte@Sun.COM 
46527836SJohn.Forte@Sun.COM 	switch (object) {
46537836SJohn.Forte@Sun.COM 		case DISCOVERY_ADDRESS:
46547836SJohn.Forte@Sun.COM 		case ISNS_SERVER_ADDRESS:
46557836SJohn.Forte@Sun.COM 			ret = addAddress(object, operandLen, operand, funcRet);
46567836SJohn.Forte@Sun.COM 			break;
46577836SJohn.Forte@Sun.COM 		case STATIC_CONFIG:
46587836SJohn.Forte@Sun.COM 			ret = addStaticConfig(operandLen, operand, funcRet);
46597836SJohn.Forte@Sun.COM 			break;
46607836SJohn.Forte@Sun.COM 		default:
46617836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
46627836SJohn.Forte@Sun.COM 			    cmdName, gettext("unknown object"));
46637836SJohn.Forte@Sun.COM 			ret = 1;
46647836SJohn.Forte@Sun.COM 			break;
46657836SJohn.Forte@Sun.COM 	}
46667836SJohn.Forte@Sun.COM 	return (ret);
46677836SJohn.Forte@Sun.COM }
46687836SJohn.Forte@Sun.COM 
46697836SJohn.Forte@Sun.COM /*ARGSUSED*/
46707836SJohn.Forte@Sun.COM static int
46717836SJohn.Forte@Sun.COM listFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
46727836SJohn.Forte@Sun.COM     void *addArgs, int *funcRet)
46737836SJohn.Forte@Sun.COM {
46747836SJohn.Forte@Sun.COM 	int ret;
46757836SJohn.Forte@Sun.COM 
46767836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
46777836SJohn.Forte@Sun.COM 
46787836SJohn.Forte@Sun.COM 	switch (object) {
46797836SJohn.Forte@Sun.COM 	case DISCOVERY:
46807836SJohn.Forte@Sun.COM 		ret = listDiscovery(funcRet);
46817836SJohn.Forte@Sun.COM 		break;
46827836SJohn.Forte@Sun.COM 	case DISCOVERY_ADDRESS:
46837836SJohn.Forte@Sun.COM 		ret = listDiscoveryAddress(operandLen, operand, options,
46847836SJohn.Forte@Sun.COM 		    funcRet);
46857836SJohn.Forte@Sun.COM 		break;
46867836SJohn.Forte@Sun.COM 	case ISNS_SERVER_ADDRESS:
46877836SJohn.Forte@Sun.COM 		ret = listISNSServerAddress(operandLen, operand, options,
46887836SJohn.Forte@Sun.COM 		    funcRet);
46897836SJohn.Forte@Sun.COM 		break;
46907836SJohn.Forte@Sun.COM 	case NODE:
46917836SJohn.Forte@Sun.COM 		ret = listNode(funcRet);
46927836SJohn.Forte@Sun.COM 		break;
46937836SJohn.Forte@Sun.COM 	case STATIC_CONFIG:
46947836SJohn.Forte@Sun.COM 		ret = listStaticConfig(operandLen, operand, funcRet);
46957836SJohn.Forte@Sun.COM 		break;
46967836SJohn.Forte@Sun.COM 	case TARGET:
46977836SJohn.Forte@Sun.COM 		ret = listTarget(operandLen, operand, options, funcRet);
46987836SJohn.Forte@Sun.COM 		break;
46997836SJohn.Forte@Sun.COM 	case TARGET_PARAM:
47007836SJohn.Forte@Sun.COM 		ret = listTargetParam(operandLen, operand, options, funcRet);
47017836SJohn.Forte@Sun.COM 		break;
47027836SJohn.Forte@Sun.COM 	default:
47037836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
47047836SJohn.Forte@Sun.COM 		    cmdName, gettext("unknown object"));
47057836SJohn.Forte@Sun.COM 		ret = 1;
47067836SJohn.Forte@Sun.COM 		break;
47077836SJohn.Forte@Sun.COM 	}
47087836SJohn.Forte@Sun.COM 	return (ret);
47097836SJohn.Forte@Sun.COM }
47107836SJohn.Forte@Sun.COM 
47117836SJohn.Forte@Sun.COM /*ARGSUSED*/
47127836SJohn.Forte@Sun.COM static int
47137836SJohn.Forte@Sun.COM modifyFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
47147836SJohn.Forte@Sun.COM     void *addArgs, int *funcRet)
47157836SJohn.Forte@Sun.COM {
47167836SJohn.Forte@Sun.COM 	int ret, i;
47177836SJohn.Forte@Sun.COM 
47187836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
47197836SJohn.Forte@Sun.COM 
47207836SJohn.Forte@Sun.COM 	switch (object) {
47217836SJohn.Forte@Sun.COM 	case DISCOVERY:
47227836SJohn.Forte@Sun.COM 		ret = modifyDiscovery(options, funcRet);
47237836SJohn.Forte@Sun.COM 		break;
47247836SJohn.Forte@Sun.COM 	case NODE:
47257836SJohn.Forte@Sun.COM 		ret = modifyNode(options, funcRet);
47267836SJohn.Forte@Sun.COM 		break;
47277836SJohn.Forte@Sun.COM 	case TARGET_PARAM:
47287836SJohn.Forte@Sun.COM 		i = 0;
47297836SJohn.Forte@Sun.COM 		while (operand[i]) {
47307836SJohn.Forte@Sun.COM 			ret = modifyTargetParam(options, operand[i], funcRet);
47317836SJohn.Forte@Sun.COM 
47327836SJohn.Forte@Sun.COM 			if (ret) {
47337836SJohn.Forte@Sun.COM 				(void) fprintf(stderr, "%s: %s: %s\n",
47347836SJohn.Forte@Sun.COM 				    cmdName, gettext("modify failed"),
47357836SJohn.Forte@Sun.COM 				    operand[i]);
47367836SJohn.Forte@Sun.COM 				return (ret);
47377836SJohn.Forte@Sun.COM 			}
47387836SJohn.Forte@Sun.COM 			i++;
47397836SJohn.Forte@Sun.COM 		}
47407836SJohn.Forte@Sun.COM 
47417836SJohn.Forte@Sun.COM 		break;
47427836SJohn.Forte@Sun.COM 	default:
47437836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
47447836SJohn.Forte@Sun.COM 		    cmdName, gettext("unknown object"));
47457836SJohn.Forte@Sun.COM 		ret = 1;
47467836SJohn.Forte@Sun.COM 		break;
47477836SJohn.Forte@Sun.COM 	}
47487836SJohn.Forte@Sun.COM 	return (ret);
47497836SJohn.Forte@Sun.COM }
47507836SJohn.Forte@Sun.COM 
47517836SJohn.Forte@Sun.COM /*ARGSUSED*/
47527836SJohn.Forte@Sun.COM static int
47537836SJohn.Forte@Sun.COM removeFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
47547836SJohn.Forte@Sun.COM     void *addArgs, int *funcRet)
47557836SJohn.Forte@Sun.COM {
47567836SJohn.Forte@Sun.COM 	int ret;
47577836SJohn.Forte@Sun.COM 
47587836SJohn.Forte@Sun.COM 	switch (object) {
47597836SJohn.Forte@Sun.COM 		case DISCOVERY_ADDRESS:
47607836SJohn.Forte@Sun.COM 		case ISNS_SERVER_ADDRESS:
47617836SJohn.Forte@Sun.COM 			ret = removeAddress(object, operandLen, operand,
47627836SJohn.Forte@Sun.COM 			    funcRet);
47637836SJohn.Forte@Sun.COM 			break;
47647836SJohn.Forte@Sun.COM 		case STATIC_CONFIG:
47657836SJohn.Forte@Sun.COM 			ret = removeStaticConfig(operandLen, operand, funcRet);
47667836SJohn.Forte@Sun.COM 			break;
47677836SJohn.Forte@Sun.COM 		case TARGET_PARAM:
47687836SJohn.Forte@Sun.COM 			ret = removeTargetParam(operandLen, operand, funcRet);
47697836SJohn.Forte@Sun.COM 			break;
47707836SJohn.Forte@Sun.COM 		default:
47717836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
47727836SJohn.Forte@Sun.COM 			    cmdName, gettext("unknown object"));
47737836SJohn.Forte@Sun.COM 			ret = 1;
47747836SJohn.Forte@Sun.COM 			break;
47757836SJohn.Forte@Sun.COM 	}
47767836SJohn.Forte@Sun.COM 	return (ret);
47777836SJohn.Forte@Sun.COM }
47787836SJohn.Forte@Sun.COM 
47797836SJohn.Forte@Sun.COM static void
47807836SJohn.Forte@Sun.COM iSCSINameCheckStatusDisplay(iSCSINameCheckStatusType status)
47817836SJohn.Forte@Sun.COM {
47827836SJohn.Forte@Sun.COM 	switch (status) {
47837836SJohn.Forte@Sun.COM 		case iSCSINameLenZero:
47847836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
47857836SJohn.Forte@Sun.COM 			    cmdName, gettext("empty iSCSI name."));
47867836SJohn.Forte@Sun.COM 			break;
47877836SJohn.Forte@Sun.COM 		case iSCSINameLenExceededMax:
47887836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n", cmdName,
47897836SJohn.Forte@Sun.COM 			    gettext("iSCSI name exceeded maximum length."));
47907836SJohn.Forte@Sun.COM 			break;
47917836SJohn.Forte@Sun.COM 		case iSCSINameUnknownType:
47927836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n", cmdName,
47937836SJohn.Forte@Sun.COM 			    gettext("unknown iSCSI name type."));
47947836SJohn.Forte@Sun.COM 			break;
47957836SJohn.Forte@Sun.COM 		case iSCSINameInvalidCharacter:
47967836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
47977836SJohn.Forte@Sun.COM 			    cmdName,
47987836SJohn.Forte@Sun.COM 			    gettext("iSCSI name invalid character used"));
47997836SJohn.Forte@Sun.COM 			break;
48007836SJohn.Forte@Sun.COM 		case iSCSINameIqnFormatError:
48017836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n", cmdName,
48027836SJohn.Forte@Sun.COM 			    gettext("iqn formatting error."));
48037836SJohn.Forte@Sun.COM 			break;
48047836SJohn.Forte@Sun.COM 		case iSCSINameIqnDateFormatError:
48057836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
48067836SJohn.Forte@Sun.COM 			    cmdName, gettext("invalid iqn date." \
48077836SJohn.Forte@Sun.COM 			    "  format is: YYYY-MM"));
48087836SJohn.Forte@Sun.COM 			break;
48097836SJohn.Forte@Sun.COM 		case iSCSINameIqnSubdomainFormatError:
48107836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
48117836SJohn.Forte@Sun.COM 			    cmdName, gettext("missing subdomain after \":\""));
48127836SJohn.Forte@Sun.COM 			break;
48137836SJohn.Forte@Sun.COM 		case iSCSINameIqnInvalidYearError:
48147836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
48157836SJohn.Forte@Sun.COM 			    cmdName, gettext("invalid year"));
48167836SJohn.Forte@Sun.COM 			break;
48177836SJohn.Forte@Sun.COM 		case iSCSINameIqnInvalidMonthError:
48187836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
48197836SJohn.Forte@Sun.COM 			    cmdName, gettext("invalid month"));
48207836SJohn.Forte@Sun.COM 			break;
48217836SJohn.Forte@Sun.COM 		case iSCSINameIqnFQDNError:
48227836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
48237836SJohn.Forte@Sun.COM 			    cmdName, gettext("missing reversed fully qualified"\
48247836SJohn.Forte@Sun.COM 			    " domain name"));
48257836SJohn.Forte@Sun.COM 			break;
48267836SJohn.Forte@Sun.COM 		case iSCSINameEUIFormatError:
48277836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n", cmdName,
48287836SJohn.Forte@Sun.COM 			    gettext("eui formatting error."));
48297836SJohn.Forte@Sun.COM 			break;
48307836SJohn.Forte@Sun.COM 	}
48317836SJohn.Forte@Sun.COM }
48327836SJohn.Forte@Sun.COM 
48337836SJohn.Forte@Sun.COM /*
48347836SJohn.Forte@Sun.COM  * A convenient function to modify the target parameters of an individual
48357836SJohn.Forte@Sun.COM  * target.
48367836SJohn.Forte@Sun.COM  *
48377836SJohn.Forte@Sun.COM  * Return 0 if successful
48387836SJohn.Forte@Sun.COM  * Return 1 if failed
48397836SJohn.Forte@Sun.COM  */
48407836SJohn.Forte@Sun.COM static int
48417836SJohn.Forte@Sun.COM modifyIndividualTargetParam(cmdOptions_t *optionList, IMA_OID targetOid,
48427836SJohn.Forte@Sun.COM     int *funcRet)
48437836SJohn.Forte@Sun.COM {
48447836SJohn.Forte@Sun.COM 	assert(funcRet != NULL);
48457836SJohn.Forte@Sun.COM 
48467836SJohn.Forte@Sun.COM 	for (; optionList->optval; optionList++) {
48477836SJohn.Forte@Sun.COM 		switch (optionList->optval) {
48487836SJohn.Forte@Sun.COM 			case 'a':
48497836SJohn.Forte@Sun.COM 				if (modifyTargetAuthMethod(targetOid,
48507836SJohn.Forte@Sun.COM 				    optionList->optarg, funcRet) != 0) {
48517836SJohn.Forte@Sun.COM 					return (1);
48527836SJohn.Forte@Sun.COM 				}
48537836SJohn.Forte@Sun.COM 				break;
48547836SJohn.Forte@Sun.COM 			case 'B':
48557836SJohn.Forte@Sun.COM 				if (modifyTargetBidirAuthFlag(targetOid,
48567836SJohn.Forte@Sun.COM 				    optionList->optarg, funcRet) != 0) {
48577836SJohn.Forte@Sun.COM 					return (1);
48587836SJohn.Forte@Sun.COM 				}
48597836SJohn.Forte@Sun.COM 				break;
48607836SJohn.Forte@Sun.COM 			case 'C':
48617836SJohn.Forte@Sun.COM 				if (modifyTargetAuthParam(targetOid,
48627836SJohn.Forte@Sun.COM 				    AUTH_PASSWORD, NULL, funcRet) != 0) {
48637836SJohn.Forte@Sun.COM 					return (1);
48647836SJohn.Forte@Sun.COM 				}
48657836SJohn.Forte@Sun.COM 				break;
48667836SJohn.Forte@Sun.COM 			case 'd':
48677836SJohn.Forte@Sun.COM 				if (setLoginParameter(targetOid, DATA_DIGEST,
48687836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
48697836SJohn.Forte@Sun.COM 					return (1);
48707836SJohn.Forte@Sun.COM 				}
48717836SJohn.Forte@Sun.COM 				break;
48727836SJohn.Forte@Sun.COM 			case 'h':
48737836SJohn.Forte@Sun.COM 				if (setLoginParameter(targetOid, HEADER_DIGEST,
48747836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
48757836SJohn.Forte@Sun.COM 					return (1);
48767836SJohn.Forte@Sun.COM 				}
48777836SJohn.Forte@Sun.COM 				break;
48787836SJohn.Forte@Sun.COM 			case 'p':
48797836SJohn.Forte@Sun.COM 				/* Login parameter */
48807836SJohn.Forte@Sun.COM 				if (setLoginParameters(targetOid,
48817836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
48827836SJohn.Forte@Sun.COM 					return (1);
48837836SJohn.Forte@Sun.COM 				}
48847836SJohn.Forte@Sun.COM 				break;
48857836SJohn.Forte@Sun.COM 			case 'c':
48867836SJohn.Forte@Sun.COM 				/* Modify configure sessions */
48877836SJohn.Forte@Sun.COM 				if (modifyConfiguredSessions(targetOid,
48887836SJohn.Forte@Sun.COM 				    optionList->optarg) != 0) {
48897836SJohn.Forte@Sun.COM 					return (1);
48907836SJohn.Forte@Sun.COM 				}
48917836SJohn.Forte@Sun.COM 				break;
48927836SJohn.Forte@Sun.COM 			case 'H':
48937836SJohn.Forte@Sun.COM 				if (modifyTargetAuthParam(targetOid, AUTH_NAME,
48947836SJohn.Forte@Sun.COM 				    optionList->optarg, funcRet) != 0) {
48957836SJohn.Forte@Sun.COM 					return (1);
48967836SJohn.Forte@Sun.COM 				}
48977836SJohn.Forte@Sun.COM 				break;
48987836SJohn.Forte@Sun.COM 		}
48997836SJohn.Forte@Sun.COM 	}
49007836SJohn.Forte@Sun.COM 
49017836SJohn.Forte@Sun.COM 	return (0);
49027836SJohn.Forte@Sun.COM }
49037836SJohn.Forte@Sun.COM 
49047836SJohn.Forte@Sun.COM /*
49057836SJohn.Forte@Sun.COM  * This helper function could go into a utility module for general use.
49067836SJohn.Forte@Sun.COM  */
49077836SJohn.Forte@Sun.COM static int
49087836SJohn.Forte@Sun.COM parseAddress(char *address_port_str,
49097836SJohn.Forte@Sun.COM     uint16_t defaultPort,
49107836SJohn.Forte@Sun.COM     char *address_str,
49117836SJohn.Forte@Sun.COM     size_t address_str_len,
49127836SJohn.Forte@Sun.COM     uint16_t *port,
49137836SJohn.Forte@Sun.COM     boolean_t *isIpv6)
49147836SJohn.Forte@Sun.COM {
49157836SJohn.Forte@Sun.COM 	char port_str[64];
49167836SJohn.Forte@Sun.COM 	int tmp_port;
49177836SJohn.Forte@Sun.COM 	char *errchr;
49187836SJohn.Forte@Sun.COM 
49197836SJohn.Forte@Sun.COM 	if (address_port_str[0] == '[') {
49207836SJohn.Forte@Sun.COM 		/* IPv6 address */
49217836SJohn.Forte@Sun.COM 		char *close_bracket_pos;
49227836SJohn.Forte@Sun.COM 		close_bracket_pos = strchr(address_port_str, ']');
49237836SJohn.Forte@Sun.COM 		if (!close_bracket_pos) {
49247836SJohn.Forte@Sun.COM 			syslog(LOG_USER|LOG_DEBUG,
49257836SJohn.Forte@Sun.COM 			    "IP address format error: %s\n", address_str);
49267836SJohn.Forte@Sun.COM 			return (PARSE_ADDR_MISSING_CLOSING_BRACKET);
49277836SJohn.Forte@Sun.COM 		}
49287836SJohn.Forte@Sun.COM 
49297836SJohn.Forte@Sun.COM 		*close_bracket_pos = NULL;
49307836SJohn.Forte@Sun.COM 		(void) strlcpy(address_str, &address_port_str[1],
49317836SJohn.Forte@Sun.COM 		    address_str_len);
49327836SJohn.Forte@Sun.COM 
49337836SJohn.Forte@Sun.COM 		/* Extract the port number */
49347836SJohn.Forte@Sun.COM 		close_bracket_pos++;
49357836SJohn.Forte@Sun.COM 		if (*close_bracket_pos == ':') {
49367836SJohn.Forte@Sun.COM 			close_bracket_pos++;
49377836SJohn.Forte@Sun.COM 			if (*close_bracket_pos != NULL) {
49387836SJohn.Forte@Sun.COM 				(void) strlcpy(port_str, close_bracket_pos, 64);
49397836SJohn.Forte@Sun.COM 				tmp_port = strtol(port_str, &errchr, 10);
49407836SJohn.Forte@Sun.COM 				if (tmp_port == 0 && errchr != NULL) {
49417836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s:%s %s\n",
49427836SJohn.Forte@Sun.COM 					    cmdName, address_str,
49437836SJohn.Forte@Sun.COM 					    close_bracket_pos,
49447836SJohn.Forte@Sun.COM 					    gettext("port number invalid"));
49457836SJohn.Forte@Sun.COM 					return (PARSE_ADDR_PORT_OUT_OF_RANGE);
49467836SJohn.Forte@Sun.COM 				}
49477836SJohn.Forte@Sun.COM 				if ((tmp_port > 0) && (tmp_port > USHRT_MAX) ||
49487836SJohn.Forte@Sun.COM 				    (tmp_port < 0)) {
49497836SJohn.Forte@Sun.COM 					/* Port number out of range */
49507836SJohn.Forte@Sun.COM 					syslog(LOG_USER|LOG_DEBUG,
49517836SJohn.Forte@Sun.COM 					    "Specified port out of range: %d",
49527836SJohn.Forte@Sun.COM 					    tmp_port);
49537836SJohn.Forte@Sun.COM 					return (PARSE_ADDR_PORT_OUT_OF_RANGE);
49547836SJohn.Forte@Sun.COM 				} else {
49557836SJohn.Forte@Sun.COM 					*port = (uint16_t)tmp_port;
49567836SJohn.Forte@Sun.COM 				}
49577836SJohn.Forte@Sun.COM 			} else {
49587836SJohn.Forte@Sun.COM 				*port = defaultPort;
49597836SJohn.Forte@Sun.COM 			}
49607836SJohn.Forte@Sun.COM 		} else {
49617836SJohn.Forte@Sun.COM 			*port = defaultPort;
49627836SJohn.Forte@Sun.COM 		}
49637836SJohn.Forte@Sun.COM 
49647836SJohn.Forte@Sun.COM 		*isIpv6 = B_TRUE;
49657836SJohn.Forte@Sun.COM 	} else {
49667836SJohn.Forte@Sun.COM 		/* IPv4 address */
49677836SJohn.Forte@Sun.COM 		char *colon_pos;
49687836SJohn.Forte@Sun.COM 		colon_pos = strchr(address_port_str, ':');
49697836SJohn.Forte@Sun.COM 		if (!colon_pos) {
49707836SJohn.Forte@Sun.COM 			/* No port number specified. */
49717836SJohn.Forte@Sun.COM 			*port = defaultPort;
49727836SJohn.Forte@Sun.COM 			(void) strlcpy(address_str, address_port_str,
49737836SJohn.Forte@Sun.COM 			    address_str_len);
49747836SJohn.Forte@Sun.COM 		} else {
49757836SJohn.Forte@Sun.COM 			*colon_pos = (char)NULL;
49767836SJohn.Forte@Sun.COM 			(void) strlcpy(address_str, address_port_str,
49777836SJohn.Forte@Sun.COM 			    address_str_len);
49787836SJohn.Forte@Sun.COM 
49797836SJohn.Forte@Sun.COM 			/* Extract the port number */
49807836SJohn.Forte@Sun.COM 			colon_pos++;
49817836SJohn.Forte@Sun.COM 			if (*colon_pos != NULL) {
49827836SJohn.Forte@Sun.COM 
49837836SJohn.Forte@Sun.COM 				(void) strlcpy(port_str, colon_pos, 64);
49847836SJohn.Forte@Sun.COM 				tmp_port = strtol(port_str, &errchr, 10);
49857836SJohn.Forte@Sun.COM 				if (tmp_port == 0 && errchr != NULL) {
49867836SJohn.Forte@Sun.COM 					(void) fprintf(stderr, "%s: %s:%s %s\n",
49877836SJohn.Forte@Sun.COM 					    cmdName, address_str, colon_pos,
49887836SJohn.Forte@Sun.COM 					    gettext("port number invalid"));
49897836SJohn.Forte@Sun.COM 					return (PARSE_ADDR_PORT_OUT_OF_RANGE);
49907836SJohn.Forte@Sun.COM 				}
49917836SJohn.Forte@Sun.COM 				if ((tmp_port > 0) && (tmp_port > USHRT_MAX) ||
49927836SJohn.Forte@Sun.COM 				    (tmp_port < 0)) {
49937836SJohn.Forte@Sun.COM 					/* Port number out of range */
49947836SJohn.Forte@Sun.COM 					syslog(LOG_USER|LOG_DEBUG,
49957836SJohn.Forte@Sun.COM 					    "Specified port out of range: %d",
49967836SJohn.Forte@Sun.COM 					    tmp_port);
49977836SJohn.Forte@Sun.COM 					return (PARSE_ADDR_PORT_OUT_OF_RANGE);
49987836SJohn.Forte@Sun.COM 				} else {
49997836SJohn.Forte@Sun.COM 					*port = (uint16_t)tmp_port;
50007836SJohn.Forte@Sun.COM 				}
50017836SJohn.Forte@Sun.COM 			} else {
50027836SJohn.Forte@Sun.COM 				*port = defaultPort;
50037836SJohn.Forte@Sun.COM 			}
50047836SJohn.Forte@Sun.COM 		}
50057836SJohn.Forte@Sun.COM 
50067836SJohn.Forte@Sun.COM 		*isIpv6 = B_FALSE;
50077836SJohn.Forte@Sun.COM 	}
50087836SJohn.Forte@Sun.COM 
50097836SJohn.Forte@Sun.COM 	return (PARSE_ADDR_OK);
50107836SJohn.Forte@Sun.COM }
50117836SJohn.Forte@Sun.COM 
50127836SJohn.Forte@Sun.COM /*
50137836SJohn.Forte@Sun.COM  * This helper function could go into a utility module for general use.
50147836SJohn.Forte@Sun.COM  */
50157836SJohn.Forte@Sun.COM iSCSINameCheckStatusType
50167836SJohn.Forte@Sun.COM iSCSINameStringProfileCheck(wchar_t *name)
50177836SJohn.Forte@Sun.COM {
50187836SJohn.Forte@Sun.COM 	char mb_name[MAX_ISCSI_NAME_LEN + 1];
50197836SJohn.Forte@Sun.COM 	size_t name_len;
50207836SJohn.Forte@Sun.COM 	char *tmp;
50217836SJohn.Forte@Sun.COM 
50227836SJohn.Forte@Sun.COM 	(void) wcstombs(mb_name, name, MAX_ISCSI_NAME_LEN + 1);
50237836SJohn.Forte@Sun.COM 
50247836SJohn.Forte@Sun.COM 	if ((name_len = strlen(mb_name)) == 0) {
50257836SJohn.Forte@Sun.COM 		return (iSCSINameLenZero);
50267836SJohn.Forte@Sun.COM 	} else if (name_len > MAX_ISCSI_NAME_LEN) {
50277836SJohn.Forte@Sun.COM 		return (iSCSINameLenExceededMax);
50287836SJohn.Forte@Sun.COM 	}
50297836SJohn.Forte@Sun.COM 
50307836SJohn.Forte@Sun.COM 	/*
50317836SJohn.Forte@Sun.COM 	 * check for invalid characters
50327836SJohn.Forte@Sun.COM 	 * According to RFC 3722 iSCSI name must be either a letter,
50337836SJohn.Forte@Sun.COM 	 * a digit or one of the following '-' '.' ':'
50347836SJohn.Forte@Sun.COM 	 */
50357836SJohn.Forte@Sun.COM 	for (tmp = mb_name; *tmp != NULL; tmp++) {
50367836SJohn.Forte@Sun.COM 		if ((isalnum(*tmp) == 0) &&
50377836SJohn.Forte@Sun.COM 		    (*tmp != '-') &&
50387836SJohn.Forte@Sun.COM 		    (*tmp != '.') &&
50397836SJohn.Forte@Sun.COM 		    (*tmp != ':')) {
50407836SJohn.Forte@Sun.COM 			return (iSCSINameInvalidCharacter);
50417836SJohn.Forte@Sun.COM 		}
50427836SJohn.Forte@Sun.COM 	}
50437836SJohn.Forte@Sun.COM 
50447836SJohn.Forte@Sun.COM 	if (strncmp(mb_name, ISCSI_IQN_NAME_PREFIX,
50457836SJohn.Forte@Sun.COM 	    strlen(ISCSI_IQN_NAME_PREFIX)) == 0) {
50467836SJohn.Forte@Sun.COM 		/*
50477836SJohn.Forte@Sun.COM 		 * If name is of type iqn, check date string and naming
50487836SJohn.Forte@Sun.COM 		 * authority.
50497836SJohn.Forte@Sun.COM 		 */
50507836SJohn.Forte@Sun.COM 		char *strp = NULL;
50517836SJohn.Forte@Sun.COM 
50527836SJohn.Forte@Sun.COM 		/*
50537836SJohn.Forte@Sun.COM 		 * Don't allow the string to end with a colon.  If there is a
50547836SJohn.Forte@Sun.COM 		 * colon then there must be a subdomain provided.
50557836SJohn.Forte@Sun.COM 		 */
50567836SJohn.Forte@Sun.COM 		if (mb_name[strlen(mb_name) - 1] == ':') {
50577836SJohn.Forte@Sun.COM 			return (iSCSINameIqnSubdomainFormatError);
50587836SJohn.Forte@Sun.COM 		}
50597836SJohn.Forte@Sun.COM 
50607836SJohn.Forte@Sun.COM 		/* Date string */
50617836SJohn.Forte@Sun.COM 		strp = strtok(&mb_name[3], ".");
50627836SJohn.Forte@Sun.COM 		if (strp) {
50637836SJohn.Forte@Sun.COM 			char tmpYear[5], tmpMonth[3], *endPtr = NULL;
50647836SJohn.Forte@Sun.COM 			int year, month;
50657836SJohn.Forte@Sun.COM 
50667836SJohn.Forte@Sun.COM 			/* Date string should be in YYYY-MM format */
50677836SJohn.Forte@Sun.COM 			if (strlen(strp) != strlen("YYYY-MM") ||
50687836SJohn.Forte@Sun.COM 			    strp[4] != '-') {
50697836SJohn.Forte@Sun.COM 				return (iSCSINameIqnDateFormatError);
50707836SJohn.Forte@Sun.COM 			}
50717836SJohn.Forte@Sun.COM 
50727836SJohn.Forte@Sun.COM 			/*
50737836SJohn.Forte@Sun.COM 			 * Validate year.  Only validating that the
50747836SJohn.Forte@Sun.COM 			 * year can be converted to a number.  No
50757836SJohn.Forte@Sun.COM 			 * validation will be done on year's actual
50767836SJohn.Forte@Sun.COM 			 * value.
50777836SJohn.Forte@Sun.COM 			 */
50787836SJohn.Forte@Sun.COM 			(void) strncpy(tmpYear, strp, 4);
50797836SJohn.Forte@Sun.COM 			tmpYear[4] = '\0';
50807836SJohn.Forte@Sun.COM 
50817836SJohn.Forte@Sun.COM 			errno = 0;
50827836SJohn.Forte@Sun.COM 			year = strtol(tmpYear, &endPtr, 10);
50837836SJohn.Forte@Sun.COM 			if (errno != 0 || *endPtr != '\0' ||
50847836SJohn.Forte@Sun.COM 			    year < 0 || year > 9999) {
50857836SJohn.Forte@Sun.COM 				return (iSCSINameIqnInvalidYearError);
50867836SJohn.Forte@Sun.COM 			}
50877836SJohn.Forte@Sun.COM 
50887836SJohn.Forte@Sun.COM 			/*
50897836SJohn.Forte@Sun.COM 			 * Validate month is valid.
50907836SJohn.Forte@Sun.COM 			 */
50917836SJohn.Forte@Sun.COM 			(void) strncpy(tmpMonth, &strp[5], 2);
50927836SJohn.Forte@Sun.COM 			tmpMonth[2] = '\0';
50937836SJohn.Forte@Sun.COM 			errno = 0;
50947836SJohn.Forte@Sun.COM 			month = strtol(tmpMonth, &endPtr, 10);
50957836SJohn.Forte@Sun.COM 
50967836SJohn.Forte@Sun.COM 			if (errno != 0 || *endPtr != '\0' ||
50977836SJohn.Forte@Sun.COM 			    month < 1 || month > 12) {
50987836SJohn.Forte@Sun.COM 				return (iSCSINameIqnInvalidMonthError);
50997836SJohn.Forte@Sun.COM 			}
51007836SJohn.Forte@Sun.COM 
51017836SJohn.Forte@Sun.COM 			/*
51027836SJohn.Forte@Sun.COM 			 * A reversed FQDN needs to be provided.  We
51037836SJohn.Forte@Sun.COM 			 * will only check for a "." followed by more
51047836SJohn.Forte@Sun.COM 			 * than two or more characters.  The list of domains is
51057836SJohn.Forte@Sun.COM 			 * too large and changes too frequently to
51067836SJohn.Forte@Sun.COM 			 * add validation for.
51077836SJohn.Forte@Sun.COM 			 */
51087836SJohn.Forte@Sun.COM 			strp = strtok(NULL, ".");
51097836SJohn.Forte@Sun.COM 			if (!strp || strlen(strp) < 2) {
51107836SJohn.Forte@Sun.COM 				return (iSCSINameIqnFQDNError);
51117836SJohn.Forte@Sun.COM 			}
51127836SJohn.Forte@Sun.COM 
51137836SJohn.Forte@Sun.COM 			/* Name authority string */
51147836SJohn.Forte@Sun.COM 			strp = strtok(NULL, ":");
51157836SJohn.Forte@Sun.COM 			if (strp) {
51167836SJohn.Forte@Sun.COM 				return (iSCSINameCheckOK);
51177836SJohn.Forte@Sun.COM 			} else {
51187836SJohn.Forte@Sun.COM 				return (iSCSINameIqnFQDNError);
51197836SJohn.Forte@Sun.COM 			}
51207836SJohn.Forte@Sun.COM 		} else {
51217836SJohn.Forte@Sun.COM 			return (iSCSINameIqnFormatError);
51227836SJohn.Forte@Sun.COM 		}
51237836SJohn.Forte@Sun.COM 	} else if (strncmp(mb_name, ISCSI_EUI_NAME_PREFIX,
51247836SJohn.Forte@Sun.COM 	    strlen(ISCSI_EUI_NAME_PREFIX)) == 0) {
51257836SJohn.Forte@Sun.COM 		/* If name is of type EUI, change its length */
51267836SJohn.Forte@Sun.COM 
51277836SJohn.Forte@Sun.COM 		if (strlen(mb_name) != ISCSI_EUI_NAME_LEN) {
51287836SJohn.Forte@Sun.COM 			return (iSCSINameEUIFormatError);
51297836SJohn.Forte@Sun.COM 		}
51307836SJohn.Forte@Sun.COM 
51317836SJohn.Forte@Sun.COM 		for (tmp = mb_name + strlen(ISCSI_EUI_NAME_PREFIX) + 1;
51327836SJohn.Forte@Sun.COM 		    *tmp != '\0'; tmp++) {
51337836SJohn.Forte@Sun.COM 			if (isxdigit(*tmp)) {
51347836SJohn.Forte@Sun.COM 				continue;
51357836SJohn.Forte@Sun.COM 			}
51367836SJohn.Forte@Sun.COM 			return (iSCSINameEUIFormatError);
51377836SJohn.Forte@Sun.COM 		}
51387836SJohn.Forte@Sun.COM 
51397836SJohn.Forte@Sun.COM 		return (iSCSINameCheckOK);
51407836SJohn.Forte@Sun.COM 	} else {
51417836SJohn.Forte@Sun.COM 		return (iSCSINameUnknownType);
51427836SJohn.Forte@Sun.COM 	}
51437836SJohn.Forte@Sun.COM }
51447836SJohn.Forte@Sun.COM 
51457836SJohn.Forte@Sun.COM /*
51467836SJohn.Forte@Sun.COM  * This helper function could go into a utility module for general use.
51477836SJohn.Forte@Sun.COM  *
51487836SJohn.Forte@Sun.COM  * Returns:
51497836SJohn.Forte@Sun.COM  * B_TRUE is the numberStr is an unsigned natural number and within the
51507836SJohn.Forte@Sun.COM  * specified bound.
51517836SJohn.Forte@Sun.COM  * B_FALSE otherwise.
51527836SJohn.Forte@Sun.COM  */
51537836SJohn.Forte@Sun.COM boolean_t
51547836SJohn.Forte@Sun.COM isNaturalNumber(char *numberStr, uint32_t upperBound)
51557836SJohn.Forte@Sun.COM {
51567836SJohn.Forte@Sun.COM 	int i;
51577836SJohn.Forte@Sun.COM 	int number_str_len;
51587836SJohn.Forte@Sun.COM 
51597836SJohn.Forte@Sun.COM 	if ((number_str_len = strlen(numberStr)) == 0) {
51607836SJohn.Forte@Sun.COM 		return (B_FALSE);
51617836SJohn.Forte@Sun.COM 	}
51627836SJohn.Forte@Sun.COM 
51637836SJohn.Forte@Sun.COM 	for (i = 0; i < number_str_len; i++) {
51647836SJohn.Forte@Sun.COM 		if (numberStr[i] < 060 || numberStr[i] > 071) {
51657836SJohn.Forte@Sun.COM 			return (B_FALSE);
51667836SJohn.Forte@Sun.COM 		}
51677836SJohn.Forte@Sun.COM 	}
51687836SJohn.Forte@Sun.COM 
51697836SJohn.Forte@Sun.COM 	if (atoi(numberStr) > upperBound) {
51707836SJohn.Forte@Sun.COM 		return (B_FALSE);
51717836SJohn.Forte@Sun.COM 	}
51727836SJohn.Forte@Sun.COM 
51737836SJohn.Forte@Sun.COM 	return (B_TRUE);
51747836SJohn.Forte@Sun.COM }
51757836SJohn.Forte@Sun.COM 
51767836SJohn.Forte@Sun.COM /*
51777836SJohn.Forte@Sun.COM  * This helper function could go into a utility module for general use.
51787836SJohn.Forte@Sun.COM  * It parses a target string in the format of:
51797836SJohn.Forte@Sun.COM  *
51807836SJohn.Forte@Sun.COM  * 	<target_name>,[<ip_address>[:port][,tpgt]]
51817836SJohn.Forte@Sun.COM  *
51827836SJohn.Forte@Sun.COM  * and creates wchar strings for target name and target address. It
51837836SJohn.Forte@Sun.COM  * also populates port and tpgt if found.
51847836SJohn.Forte@Sun.COM  *
51857836SJohn.Forte@Sun.COM  * Returns:
51867836SJohn.Forte@Sun.COM  * 	PARSE_TARGET_OK if parsing is successful.
51877836SJohn.Forte@Sun.COM  *	PARSE_TARGET_INVALID_TPGT if the specified tpgt is
51887836SJohn.Forte@Sun.COM  *	invalid.
51897836SJohn.Forte@Sun.COM  * 	PARSE_TARGET_INVALID_ADDR if the address specified is
51907836SJohn.Forte@Sun.COM  *	invalid.
51917836SJohn.Forte@Sun.COM  */
51927836SJohn.Forte@Sun.COM int
51937836SJohn.Forte@Sun.COM parseTarget(char *targetStr,
51947836SJohn.Forte@Sun.COM 		wchar_t *targetNameStr,
51957836SJohn.Forte@Sun.COM 		size_t targetNameStrLen,
51967836SJohn.Forte@Sun.COM 		boolean_t *targetAddressSpecified,
51977836SJohn.Forte@Sun.COM 		wchar_t *targetAddressStr,
51987836SJohn.Forte@Sun.COM 		size_t targetAddressStrLen,
51997836SJohn.Forte@Sun.COM 		uint16_t *port,
52007836SJohn.Forte@Sun.COM 		boolean_t *tpgtSpecified,
52017836SJohn.Forte@Sun.COM 		uint16_t *tpgt,
52027836SJohn.Forte@Sun.COM 		boolean_t *isIpv6)
52037836SJohn.Forte@Sun.COM {
52047836SJohn.Forte@Sun.COM 	char *commaPos;
52057836SJohn.Forte@Sun.COM 	char *commaPos2;
52067836SJohn.Forte@Sun.COM 	char targetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
52077836SJohn.Forte@Sun.COM 	int i;
52087836SJohn.Forte@Sun.COM 	int lowerCase;
52097836SJohn.Forte@Sun.COM 
52107836SJohn.Forte@Sun.COM 	(void) memset(targetNameStr, 0,
52117836SJohn.Forte@Sun.COM 	    targetNameStrLen * sizeof (wchar_t));
52127836SJohn.Forte@Sun.COM 	(void) memset(targetAddressStr, 0,
52137836SJohn.Forte@Sun.COM 	    targetAddressStrLen * sizeof (wchar_t));
52147836SJohn.Forte@Sun.COM 
52157836SJohn.Forte@Sun.COM 	commaPos = strchr(targetStr, ',');
52167836SJohn.Forte@Sun.COM 	if (commaPos != NULL) {
52177836SJohn.Forte@Sun.COM 		*commaPos = NULL;
52187836SJohn.Forte@Sun.COM 		commaPos++;
52197836SJohn.Forte@Sun.COM 		*targetAddressSpecified = B_TRUE;
52207836SJohn.Forte@Sun.COM 
52217836SJohn.Forte@Sun.COM 		/*
52227836SJohn.Forte@Sun.COM 		 * Checking of tpgt makes sense only when
52237836SJohn.Forte@Sun.COM 		 * the target address/port are specified.
52247836SJohn.Forte@Sun.COM 		 */
52257836SJohn.Forte@Sun.COM 		commaPos2 = strchr(commaPos, ',');
52267836SJohn.Forte@Sun.COM 		if (commaPos2 != NULL) {
52277836SJohn.Forte@Sun.COM 			*commaPos2 = NULL;
52287836SJohn.Forte@Sun.COM 			commaPos2++;
52297836SJohn.Forte@Sun.COM 			if (isNaturalNumber(commaPos2, ISCSI_MAX_TPGT_VALUE) ==
52307836SJohn.Forte@Sun.COM 			    B_TRUE) {
52317836SJohn.Forte@Sun.COM 				*tpgt = atoi(commaPos2);
52327836SJohn.Forte@Sun.COM 				*tpgtSpecified = B_TRUE;
52337836SJohn.Forte@Sun.COM 			} else {
52347836SJohn.Forte@Sun.COM 				return (PARSE_TARGET_INVALID_TPGT);
52357836SJohn.Forte@Sun.COM 			}
52367836SJohn.Forte@Sun.COM 		}
52377836SJohn.Forte@Sun.COM 
52387836SJohn.Forte@Sun.COM 		switch (parseAddress(commaPos, ISCSI_LISTEN_PORT,
52397836SJohn.Forte@Sun.COM 		    &targetAddress[0], MAX_ADDRESS_LEN + 1, port, isIpv6)) {
52407836SJohn.Forte@Sun.COM 		case PARSE_ADDR_PORT_OUT_OF_RANGE:
52417836SJohn.Forte@Sun.COM 			return (PARSE_TARGET_INVALID_ADDR);
52427836SJohn.Forte@Sun.COM 		case PARSE_ADDR_OK:
52437836SJohn.Forte@Sun.COM 			break;
52447836SJohn.Forte@Sun.COM 		default:
52457836SJohn.Forte@Sun.COM 			(void) fprintf(stderr, "%s: %s\n",
52467836SJohn.Forte@Sun.COM 			    cmdName, gettext("cannot parse target name"));
52477836SJohn.Forte@Sun.COM 			return (PARSE_TARGET_INVALID_ADDR);
52487836SJohn.Forte@Sun.COM 		}
52497836SJohn.Forte@Sun.COM 		(void) mbstowcs(targetAddressStr, targetAddress,
52507836SJohn.Forte@Sun.COM 		    targetAddressStrLen);
52517836SJohn.Forte@Sun.COM 		for (i = 0; targetAddressStr[i] != 0; i++) {
52527836SJohn.Forte@Sun.COM 			lowerCase = tolower(targetAddressStr[i]);
52537836SJohn.Forte@Sun.COM 			targetAddressStr[i] = lowerCase;
52547836SJohn.Forte@Sun.COM 		}
52557836SJohn.Forte@Sun.COM 	} else {
52567836SJohn.Forte@Sun.COM 		*targetAddressSpecified = B_FALSE;
52577836SJohn.Forte@Sun.COM 		*tpgtSpecified = B_FALSE;
52587836SJohn.Forte@Sun.COM 	}
52597836SJohn.Forte@Sun.COM 
52607836SJohn.Forte@Sun.COM 	(void) mbstowcs(targetNameStr, targetStr, targetNameStrLen);
52617836SJohn.Forte@Sun.COM 	for (i = 0; targetNameStr[i] != 0; i++) {
52627836SJohn.Forte@Sun.COM 		lowerCase = tolower(targetNameStr[i]);
52637836SJohn.Forte@Sun.COM 		targetNameStr[i] = lowerCase;
52647836SJohn.Forte@Sun.COM 	}
52657836SJohn.Forte@Sun.COM 
52667836SJohn.Forte@Sun.COM 	return (PARSE_TARGET_OK);
52677836SJohn.Forte@Sun.COM }
52687836SJohn.Forte@Sun.COM 
52697836SJohn.Forte@Sun.COM /*ARGSUSED*/
52707836SJohn.Forte@Sun.COM static void
52717836SJohn.Forte@Sun.COM listCHAPName(IMA_OID oid)
52727836SJohn.Forte@Sun.COM {
52737836SJohn.Forte@Sun.COM 	IMA_INITIATOR_AUTHPARMS authParams;
52747836SJohn.Forte@Sun.COM 	IMA_STATUS status;
52757836SJohn.Forte@Sun.COM 	IMA_BYTE chapName [MAX_CHAP_NAME_LEN + 1];
52767836SJohn.Forte@Sun.COM 
52777836SJohn.Forte@Sun.COM 	/* Get Chap Name depending upon oid object type */
52787836SJohn.Forte@Sun.COM 	if (oid.objectType == IMA_OBJECT_TYPE_LHBA) {
52797836SJohn.Forte@Sun.COM 		status = IMA_GetInitiatorAuthParms(oid,
52807836SJohn.Forte@Sun.COM 		    IMA_AUTHMETHOD_CHAP, &authParams);
52817836SJohn.Forte@Sun.COM 	} else {
52827836SJohn.Forte@Sun.COM 		status = SUN_IMA_GetTargetAuthParms(oid,
52837836SJohn.Forte@Sun.COM 		    IMA_AUTHMETHOD_CHAP, &authParams);
52847836SJohn.Forte@Sun.COM 	}
52857836SJohn.Forte@Sun.COM 
52867836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "\n\t\t%s: ", gettext("CHAP Name"));
52877836SJohn.Forte@Sun.COM 
52887836SJohn.Forte@Sun.COM 	if (IMA_SUCCESS(status)) {
52897836SJohn.Forte@Sun.COM 		/*
52907836SJohn.Forte@Sun.COM 		 * Default chap name will be the node name.  The default will
52917836SJohn.Forte@Sun.COM 		 * be set by the driver.
52927836SJohn.Forte@Sun.COM 		 */
52937836SJohn.Forte@Sun.COM 		if (authParams.chapParms.nameLength != 0) {
52947836SJohn.Forte@Sun.COM 			(void) memset(chapName, 0, sizeof (chapName));
52957836SJohn.Forte@Sun.COM 			(void) memcpy(chapName, authParams.chapParms.name,
52967836SJohn.Forte@Sun.COM 			    authParams.chapParms.nameLength);
52977836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s", chapName);
52987836SJohn.Forte@Sun.COM 
52997836SJohn.Forte@Sun.COM 		} else {
53007836SJohn.Forte@Sun.COM 			(void) fprintf(stdout, "%s", "-");
53017836SJohn.Forte@Sun.COM 		}
53027836SJohn.Forte@Sun.COM 	} else {
53037836SJohn.Forte@Sun.COM 		(void) fprintf(stdout, "%s", "-");
53047836SJohn.Forte@Sun.COM 	}
53057836SJohn.Forte@Sun.COM }
53067836SJohn.Forte@Sun.COM 
53077836SJohn.Forte@Sun.COM /*
53087836SJohn.Forte@Sun.COM  * Prints out see manual page.
53097836SJohn.Forte@Sun.COM  * Called out through atexit(3C) so is always last thing displayed.
53107836SJohn.Forte@Sun.COM  */
53117836SJohn.Forte@Sun.COM void
53127836SJohn.Forte@Sun.COM seeMan(void)
53137836SJohn.Forte@Sun.COM {
53147836SJohn.Forte@Sun.COM 	static int sent = 0;
53157836SJohn.Forte@Sun.COM 
53167836SJohn.Forte@Sun.COM 	if (sent)
53177836SJohn.Forte@Sun.COM 		return;
53187836SJohn.Forte@Sun.COM 
53197836SJohn.Forte@Sun.COM 	(void) fprintf(stdout, "%s %s(1M)\n",
53207836SJohn.Forte@Sun.COM 	    gettext("For more information, please see"), cmdName);
53217836SJohn.Forte@Sun.COM 
53227836SJohn.Forte@Sun.COM 	sent = 1;
53237836SJohn.Forte@Sun.COM }
53247836SJohn.Forte@Sun.COM 
53257836SJohn.Forte@Sun.COM 
53267836SJohn.Forte@Sun.COM /*
53277836SJohn.Forte@Sun.COM  * main calls a parser that checks syntax of the input command against
53287836SJohn.Forte@Sun.COM  * various rules tables.
53297836SJohn.Forte@Sun.COM  *
53307836SJohn.Forte@Sun.COM  * The parser provides usage feedback based upon same tables by calling
53317836SJohn.Forte@Sun.COM  * two usage functions, usage and subUsage, handling command and subcommand
53327836SJohn.Forte@Sun.COM  * usage respectively.
53337836SJohn.Forte@Sun.COM  *
53347836SJohn.Forte@Sun.COM  * The parser handles all printing of usage syntactical errors
53357836SJohn.Forte@Sun.COM  *
53367836SJohn.Forte@Sun.COM  * When syntax is successfully validated, the parser calls the associated
53377836SJohn.Forte@Sun.COM  * function using the subcommands table functions.
53387836SJohn.Forte@Sun.COM  *
53397836SJohn.Forte@Sun.COM  * Syntax is as follows:
53407836SJohn.Forte@Sun.COM  *	command subcommand [options] resource-type [<object>]
53417836SJohn.Forte@Sun.COM  *
53427836SJohn.Forte@Sun.COM  * The return value from the function is placed in funcRet
53437836SJohn.Forte@Sun.COM  */
53447836SJohn.Forte@Sun.COM int
53457836SJohn.Forte@Sun.COM main(int argc, char *argv[])
53467836SJohn.Forte@Sun.COM {
53477836SJohn.Forte@Sun.COM 	synTables_t synTables;
53487836SJohn.Forte@Sun.COM 	char versionString[VERSION_STRING_MAX_LEN];
53497836SJohn.Forte@Sun.COM 	int ret;
53507836SJohn.Forte@Sun.COM 	int funcRet = 0;
53517836SJohn.Forte@Sun.COM 	void *subcommandArgs = NULL;
53527836SJohn.Forte@Sun.COM 
53537836SJohn.Forte@Sun.COM 	if (geteuid() != 0) {
53547836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s\n", gettext("permission denied"));
53557836SJohn.Forte@Sun.COM 		return (1);
53567836SJohn.Forte@Sun.COM 	}
53577836SJohn.Forte@Sun.COM 
53587836SJohn.Forte@Sun.COM 	/* set global command name */
53597836SJohn.Forte@Sun.COM 	cmdName = getExecBasename(argv[0]);
53607836SJohn.Forte@Sun.COM 
53617836SJohn.Forte@Sun.COM 	(void) snprintf(versionString, sizeof (versionString), "%s.%s",
53627836SJohn.Forte@Sun.COM 	    VERSION_STRING_MAJOR, VERSION_STRING_MINOR);
53637836SJohn.Forte@Sun.COM 	synTables.versionString = versionString;
53647836SJohn.Forte@Sun.COM 	synTables.longOptionTbl = &longOptions[0];
53657836SJohn.Forte@Sun.COM 	synTables.subcommandTbl = &subcommands[0];
53667836SJohn.Forte@Sun.COM 	synTables.objectTbl = &objects[0];
53677836SJohn.Forte@Sun.COM 	synTables.objectRulesTbl = &objectRules[0];
53687836SJohn.Forte@Sun.COM 	synTables.optionRulesTbl = &optionRules[0];
53697836SJohn.Forte@Sun.COM 
53707836SJohn.Forte@Sun.COM 	/* call the CLI parser */
53717836SJohn.Forte@Sun.COM 	ret = cmdParse(argc, argv, synTables, subcommandArgs, &funcRet);
53727836SJohn.Forte@Sun.COM 	if (ret == -1) {
53737836SJohn.Forte@Sun.COM 		perror(cmdName);
53747836SJohn.Forte@Sun.COM 		ret = 1;
53757836SJohn.Forte@Sun.COM 	}
53767836SJohn.Forte@Sun.COM 
53777836SJohn.Forte@Sun.COM 	if (funcRet != 0) {
53787836SJohn.Forte@Sun.COM 		(void) fprintf(stderr, "%s: %s\n",
53797836SJohn.Forte@Sun.COM 		    cmdName, gettext("Unable to complete operation"));
53807836SJohn.Forte@Sun.COM 		ret = 1;
53817836SJohn.Forte@Sun.COM 	}
53827836SJohn.Forte@Sun.COM 	return (ret);
53837836SJohn.Forte@Sun.COM }
5384