4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <arpa/inet.h>
40 #include <netinet/in.h>
41 #include <sys/socket.h>
42 #include <arpa/inet.h>
47 #include <libsun_ima.h>
48 #include <sys/iscsi_protocol.h>
49 #include <sys/scsi/adapters/iscsi_if.h>
55 #define VERSION_STRING_MAX_LEN 10
56 #define MAX_LONG_CHAR_LEN 19
58 #define MAX_AUTH_METHODS 5
61 * MAJOR - This should only change when there is an incompatible change made
62 * to the interfaces or the output.
64 * MINOR - This should change whenever there is a new command or new feature
65 * with no incompatible change.
67 #define VERSION_STRING_MAJOR "1"
68 #define VERSION_STRING_MINOR "0"
70 #define OPTIONSTRING1 "yes|no"
71 #define OPTIONSTRING2 "initiator node name"
72 #define OPTIONSTRING3 "initiator node alias"
73 #define OPTIONSTRING4 "enable|disable"
74 #define OPTIONSTRING5 "key=value,..."
75 #define OPTIONSTRING6 "none|CRC32"
76 #define OPTIONSTRING7 "CHAP name"
77 #define OPTIONSTRING8 "<# sessions>|<IP Address>[,<IP Address>]*"
78 #define OPTIONSTRING9 "tunable-prop=value"
79 #define OPTIONVAL1 "0 to 3600"
80 #define OPTIONVAL2 "512 to 2**24 - 1"
81 #define OPTIONVAL3 "1 to 65535"
82 #define OPTIONVAL4 "<IP address>[:port]"
84 #define MAX_ISCSI_NAME_LEN 223
85 #define MAX_ADDRESS_LEN 255
86 #define MIN_CHAP_SECRET_LEN 12
87 #define MAX_CHAP_SECRET_LEN 16
88 #define DEFAULT_ISCSI_PORT 3260
89 #define ISNS_DEFAULT_SERVER_PORT 3205
90 #define DEFAULT_RADIUS_PORT 1812
91 #define MAX_CHAP_NAME_LEN 512
92 #define ISCSI_DEFAULT_RX_TIMEOUT_VALUE "60"
93 #define ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX "180"
94 #define ISCSI_DEFAULT_LOGIN_POLLING_DELAY "60"
98 #define INVALID_NODE_NAME 2
100 #define IMABOOLPRINT(prop, option) \
101 if ((option) == PRINT_CONFIGURED_PARAMS) { \
102 (void) fprintf(stdout, "%s/%s\n", \
103 (prop).defaultValue == IMA_TRUE ? gettext("yes") : \
105 (prop).currentValueValid == IMA_TRUE ? \
106 ((prop).currentValue == IMA_TRUE ? \
107 gettext("yes"): gettext("no")) : "-"); \
108 } else if ((option) == PRINT_NEGOTIATED_PARAMS) { \
109 (void) fprintf(stdout, "%s\n", \
110 (prop).currentValueValid == IMA_TRUE ? \
111 (((prop).currentValue == IMA_TRUE) ? gettext("yes") : \
112 gettext("no")) : "-"); \
115 #define IMAMINMAXPRINT(prop, option) \
116 if ((option) == PRINT_CONFIGURED_PARAMS) { \
117 (void) fprintf(stdout, "%d/", (prop).defaultValue); \
118 if ((prop).currentValueValid == IMA_TRUE) { \
119 (void) fprintf(stdout, "%d\n", (prop).currentValue); \
120 } else if ((prop).currentValueValid == IMA_FALSE) { \
121 (void) fprintf(stdout, "%s\n", "-"); \
123 } else if ((option) == PRINT_NEGOTIATED_PARAMS) { \
124 if ((prop).currentValueValid == IMA_TRUE) { \
125 (void) fprintf(stdout, "%d\n", (prop).currentValue); \
126 } else if ((prop).currentValueValid == IMA_FALSE) { \
127 (void) fprintf(stdout, "%s\n", "-"); \
131 /* forward declarations */
132 #define PARSE_ADDR_OK 0
133 #define PARSE_ADDR_MISSING_CLOSING_BRACKET 1
134 #define PARSE_ADDR_PORT_OUT_OF_RANGE 2
135 #define PARSE_TARGET_OK 0
136 #define PARSE_TARGET_INVALID_TPGT 1
137 #define PARSE_TARGET_INVALID_ADDR 2
139 #define PRINT_CONFIGURED_PARAMS 1
140 #define PRINT_NEGOTIATED_PARAMS 2
142 typedef enum iSCSINameCheckStatus
{
145 iSCSINameLenExceededMax
,
146 iSCSINameUnknownType
,
147 iSCSINameInvalidCharacter
,
148 iSCSINameIqnFormatError
,
149 iSCSINameEUIFormatError
,
150 iSCSINameIqnDateFormatError
,
151 iSCSINameIqnSubdomainFormatError
,
152 iSCSINameIqnInvalidYearError
,
153 iSCSINameIqnInvalidMonthError
,
154 iSCSINameIqnFQDNError
155 } iSCSINameCheckStatusType
;
157 /* Utility functions */
158 iSCSINameCheckStatusType
iSCSINameStringProfileCheck(wchar_t *name
);
159 boolean_t
isNaturalNumber(char *numberStr
, uint32_t upperBound
);
160 static int parseAddress(char *address_port_str
, uint16_t defaultPort
,
161 char *address_str
, size_t address_str_len
,
162 uint16_t *port
, boolean_t
*isIpv6
);
163 int parseTarget(char *targetStr
,
164 wchar_t *targetNameStr
,
165 size_t targetNameStrLen
,
166 boolean_t
*targetAddressSpecified
,
167 wchar_t *targetAddressStr
,
168 size_t targetAddressStrLen
,
170 boolean_t
*tpgtSpecified
,
173 static int chkConnLoginMaxPollingLoginDelay(IMA_OID oid
,
174 int key
, int uintValue
);
176 /* subcommand functions */
177 static int addFunc(int, char **, int, cmdOptions_t
*, void *, int *);
178 static int listFunc(int, char **, int, cmdOptions_t
*, void *, int *);
179 static int modifyFunc(int, char **, int, cmdOptions_t
*, void *, int *);
180 static int removeFunc(int, char **, int, cmdOptions_t
*, void *, int *);
182 /* helper functions */
183 static char *getExecBasename(char *);
184 static int getNodeProps(IMA_NODE_PROPERTIES
*);
185 static int getSecret(char *, int *, int, int);
186 static int getTargetAddress(int, char *, IMA_TARGET_ADDRESS
*);
187 static int printLoginParameters(char *, IMA_OID
, int);
188 static void printDiscoveryMethod(char *, IMA_UINT32
);
189 static void printTargetLuns(IMA_OID_LIST
*);
190 static void printSendTargets(SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*);
191 static void printDigestAlgorithm(SUN_IMA_DIGEST_ALGORITHM_VALUE
*, int);
192 static int setLoginParameter(IMA_OID
, int, char *);
193 static int setLoginParameters(IMA_OID
, char *);
194 static int setTunableParameters(IMA_OID
, char *);
195 static void printLibError(IMA_STATUS
);
196 /* LINTED E_STATIC_UNUSED */
197 static int sunPluginChk(IMA_OID
, boolean_t
*);
198 static int sunInitiatorFind(IMA_OID
*);
199 static int getAuthMethodValue(char *, IMA_AUTHMETHOD
*);
200 static int getLoginParam(char *);
201 static int getTunableParam(char *);
202 static void iSCSINameCheckStatusDisplay(iSCSINameCheckStatusType status
);
203 static int modifyIndividualTargetParam(cmdOptions_t
*optionList
,
204 IMA_OID targetOid
, int *);
205 static void listCHAPName(IMA_OID oid
);
206 static int printConfiguredSessions(IMA_OID
);
207 static int printTunableParameters(IMA_OID oid
);
209 /* object functions per subcommand */
210 static int addAddress(int, int, char *[], int *);
211 static int addStaticConfig(int, char *[], int *);
212 static int listDiscovery(int *);
213 static int listDiscoveryAddress(int, char *[], cmdOptions_t
*, int *);
214 static int listISNSServerAddress(int, char *[], cmdOptions_t
*, int *);
215 static int listNode(int *);
216 static int listStaticConfig(int, char *[], int *);
217 static int listTarget(int, char *[], cmdOptions_t
*, int *);
218 static int listTargetParam(int, char *[], cmdOptions_t
*, int *);
219 static int modifyDiscovery(cmdOptions_t
*, int *);
220 static int modifyNodeAuthMethod(IMA_OID
, char *, int *);
221 static int modifyNodeAuthParam(IMA_OID oid
, int, char *, int *);
222 static int modifyNodeRadiusConfig(IMA_OID
, char *, int *);
223 static int modifyNodeRadiusAccess(IMA_OID
, char *, int *);
224 static int modifyNodeRadiusSharedSecret(IMA_OID
, int *);
225 static int modifyNode(cmdOptions_t
*, int *);
226 static int modifyTargetAuthMethod(IMA_OID
, char *, int *);
227 static int modifyTargetAuthParam(IMA_OID oid
, int param
, char *chapName
, int *);
228 static int modifyTargetParam(cmdOptions_t
*, char *, int *);
229 static int removeAddress(int, int, char *[], int *);
230 static int removeStaticConfig(int, char *[], int *);
231 static int removeTargetParam(int, char *[], int *);
232 static int modifyTargetBidirAuthFlag(IMA_OID
, char *, int *);
233 static int modifyConfiguredSessions(IMA_OID targetOid
, char *optarg
);
235 /* LINTED E_STATIC_UNUSED */
236 static IMA_STATUS
getISCSINodeParameter(int paramType
,
239 uint32_t paramIndex
);
240 /* LINTED E_STATIC_UNUSED */
241 static IMA_STATUS
setISCSINodeParameter(int paramType
,
244 uint32_t paramIndex
);
245 /* LINTED E_STATIC_UNUSED */
246 static IMA_STATUS
getDigest(IMA_OID oid
, int ioctlCmd
,
247 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
);
249 IMA_STATUS
getNegotiatedDigest(int digestType
,
250 SUN_IMA_DIGEST_ALGORITHM_VALUE
*algorithm
,
251 SUN_IMA_CONN_PROPERTIES
*connProps
);
254 static char *cmdName
;
257 * Available option letters:
265 * Add new options here
267 optionTbl_t longOptions
[] = {
268 {"static", required_arg
, 's', OPTIONSTRING4
},
269 {"sendtargets", required_arg
, 't', OPTIONSTRING4
},
270 {"iSNS", required_arg
, 'i', OPTIONSTRING4
},
271 {"headerdigest", required_arg
, 'h', OPTIONSTRING6
},
272 {"datadigest", required_arg
, 'd', OPTIONSTRING6
},
273 {"login-param", required_arg
, 'p', OPTIONSTRING5
},
274 {"authentication", required_arg
, 'a', "CHAP|none"},
275 {"bi-directional-authentication", required_arg
, 'B', OPTIONSTRING4
},
276 {"CHAP-secret", no_arg
, 'C', NULL
},
277 {"CHAP-name", required_arg
, 'H', OPTIONSTRING7
},
278 {"node-name", required_arg
, 'N', OPTIONSTRING2
},
279 {"node-alias", required_arg
, 'A', OPTIONSTRING3
},
280 {"radius-server", required_arg
, 'r', OPTIONVAL4
},
281 {"radius-access", required_arg
, 'R', OPTIONSTRING4
},
282 {"radius-shared-secret", no_arg
, 'P', NULL
},
283 {"verbose", no_arg
, 'v', NULL
},
284 {"scsi-target", no_arg
, 'S', NULL
},
285 {"configured-sessions", required_arg
, 'c', OPTIONSTRING8
},
286 {"tunable-param", required_arg
, 'T', OPTIONSTRING9
},
290 parameterTbl_t loginParams
[] = {
291 {"dataseqinorder", DATA_SEQ_IN_ORDER
},
292 {"defaulttime2retain", DEFAULT_TIME_2_RETAIN
},
293 {"defaulttime2wait", DEFAULT_TIME_2_WAIT
},
294 {"firstburstlength", FIRST_BURST_LENGTH
},
295 {"immediatedata", IMMEDIATE_DATA
},
296 {"initialr2t", INITIAL_R2T
},
297 {"maxburstlength", MAX_BURST_LENGTH
},
298 {"datapduinorder", DATA_PDU_IN_ORDER
},
299 {"maxoutstandingr2t", MAX_OUTSTANDING_R2T
},
300 {"maxrecvdataseglen", MAX_RECV_DATA_SEG_LEN
},
301 {"maxconnections", MAX_CONNECTIONS
},
302 {"errorrecoverylevel", ERROR_RECOVERY_LEVEL
},
306 parameterTbl_t tunableParams
[] = {
307 {"recv-login-rsp-timeout", RECV_LOGIN_RSP_TIMEOUT
},
308 {"conn-login-max", CONN_LOGIN_MAX
},
309 {"polling-login-delay", POLLING_LOGIN_DELAY
},
314 * Add new subcommands here
316 subcommand_t subcommands
[] = {
317 {"add", ADD
, addFunc
},
318 {"list", LIST
, listFunc
},
319 {"modify", MODIFY
, modifyFunc
},
320 {"remove", REMOVE
, removeFunc
},
327 object_t objects
[] = {
328 {"discovery", DISCOVERY
},
329 {"discovery-address", DISCOVERY_ADDRESS
},
330 {"isns-server", ISNS_SERVER_ADDRESS
},
331 {"initiator-node", NODE
},
332 {"static-config", STATIC_CONFIG
},
334 {"target-param", TARGET_PARAM
},
339 * Rules for subcommands and objects
341 objectRules_t objectRules
[] = {
342 {TARGET
, 0, LIST
, 0, ADD
|REMOVE
|MODIFY
, LIST
,
344 {TARGET_PARAM
, MODIFY
|REMOVE
, LIST
, 0, ADD
, MODIFY
,
346 {DISCOVERY
, 0, 0, LIST
|MODIFY
, ADD
|REMOVE
, 0, NULL
},
347 {NODE
, 0, 0, MODIFY
|LIST
, ADD
|REMOVE
, 0, NULL
},
348 {STATIC_CONFIG
, ADD
|REMOVE
, LIST
, 0, MODIFY
, ADD
|REMOVE
|LIST
,
349 "target-name,target-address[:port-number][,tpgt]"},
350 {DISCOVERY_ADDRESS
, ADD
|REMOVE
, LIST
, 0, MODIFY
,
351 ADD
|REMOVE
|LIST
, "IP-address[:port-number]"},
352 {ISNS_SERVER_ADDRESS
, ADD
|REMOVE
, LIST
, 0, MODIFY
,
353 ADD
|REMOVE
|LIST
, "IP-address[:port-number]"},
354 {0, 0, 0, 0, 0, 0, NULL
}
358 * list of objects, subcommands, valid short options, required flag and
359 * exclusive option string
361 * If it's not here, there are no options for that object.
363 optionRules_t optionRules
[] = {
364 {DISCOVERY
, MODIFY
, "sti", B_TRUE
, NULL
},
365 {DISCOVERY_ADDRESS
, LIST
, "v", B_FALSE
, NULL
},
366 {ISNS_SERVER_ADDRESS
, LIST
, "v", B_FALSE
, NULL
},
367 {TARGET
, LIST
, "vS", B_FALSE
, NULL
},
368 {NODE
, MODIFY
, "NAhdCaRrPHcT", B_TRUE
, "CP"},
369 {TARGET_PARAM
, MODIFY
, "ahdBCpcHT", B_TRUE
, "C"},
370 {TARGET_PARAM
, LIST
, "v", B_FALSE
, NULL
},
376 targetNamesEqual(wchar_t *name1
, wchar_t *name2
)
379 wchar_t wchar1
, wchar2
;
381 if (name1
== NULL
|| name2
== NULL
) {
385 if (wcslen(name1
) != wcslen(name2
)) {
390 * Convert names to lower case and compare
392 for (i
= 0; i
< wcslen(name1
); i
++) {
393 wchar1
= towctrans((wint_t)name1
[i
], wctrans("tolower"));
394 wchar2
= towctrans((wint_t)name2
[i
], wctrans("tolower"));
396 if (wchar1
!= wchar2
) {
405 ipAddressesEqual(IMA_TARGET_ADDRESS addr1
, IMA_TARGET_ADDRESS addr2
)
407 #define IPV4_ADDR_BYTES 4
408 #define IPV6_ADDR_BYTES 16
412 if (addr1
.hostnameIpAddress
.id
.ipAddress
.ipv4Address
!=
413 addr2
.hostnameIpAddress
.id
.ipAddress
.ipv4Address
) {
417 compSize
= IPV6_ADDR_BYTES
;
418 if (addr1
.hostnameIpAddress
.id
.ipAddress
.ipv4Address
) {
419 compSize
= IPV4_ADDR_BYTES
;
422 if (bcmp(addr1
.hostnameIpAddress
.id
.ipAddress
.ipAddress
,
423 addr2
.hostnameIpAddress
.id
.ipAddress
.ipAddress
, compSize
) == 0) {
431 getLoginParam(char *arg
)
433 parameterTbl_t
*paramp
;
436 for (paramp
= loginParams
; paramp
->name
; paramp
++) {
438 if (len
== strlen(paramp
->name
) &&
439 strncasecmp(arg
, paramp
->name
, len
) == 0) {
440 return (paramp
->val
);
447 getTunableParam(char *arg
)
449 parameterTbl_t
*paramp
;
452 for (paramp
= tunableParams
; paramp
->name
!= NULL
; paramp
++) {
454 if (len
== strlen(paramp
->name
) &&
455 strncasecmp(arg
, paramp
->name
, len
) == 0) {
456 return (paramp
->val
);
463 printLibError(IMA_STATUS status
)
467 case IMA_ERROR_NOT_SUPPORTED
:
469 gettext("Operation currently not supported");
471 case IMA_ERROR_INSUFFICIENT_MEMORY
:
472 errorString
= gettext("Insufficient memory");
474 case IMA_ERROR_UNEXPECTED_OS_ERROR
:
475 errorString
= gettext("unexpected OS error");
477 case IMA_ERROR_UNKNOWN_ERROR
:
478 errorString
= gettext("Unknown error");
480 case IMA_ERROR_LU_IN_USE
:
481 errorString
= gettext("Logical unit in use");
483 case IMA_ERROR_INVALID_PARAMETER
:
484 errorString
= gettext("Invalid parameter specified");
486 case IMA_ERROR_INVALID_OBJECT_TYPE
:
488 gettext("Internal library error: Invalid oid type specified");
490 case IMA_ERROR_INCORRECT_OBJECT_TYPE
:
492 gettext("Internal library error: Incorrect oid type specified");
494 case IMA_ERROR_OBJECT_NOT_FOUND
:
495 errorString
= gettext("Internal library error: Oid not found");
497 case IMA_ERROR_NAME_TOO_LONG
:
498 errorString
= gettext("Name too long");
501 errorString
= gettext("Unknown error");
503 (void) fprintf(stderr
, "%s: %s\n", cmdName
, errorString
);
508 * execFullName - exec name of program (argv[0])
511 * command name portion of execFullName
514 getExecBasename(char *execFullname
)
516 char *lastSlash
, *execBasename
;
518 /* guard against '/' at end of command invocation */
520 lastSlash
= strrchr(execFullname
, '/');
521 if (lastSlash
== NULL
) {
522 execBasename
= execFullname
;
525 execBasename
= lastSlash
+ 1;
526 if (*execBasename
== '\0') {
533 return (execBasename
);
539 * nodeProps - pointer to caller allocated IMA_NODE_PROPERTIES
546 getNodeProps(IMA_NODE_PROPERTIES
*nodeProps
)
548 IMA_OID sharedNodeOid
;
550 IMA_STATUS status
= IMA_GetSharedNodeOid(&sharedNodeOid
);
551 if (!(IMA_SUCCESS(status
))) {
552 printLibError(status
);
556 status
= IMA_GetNodeProperties(sharedNodeOid
, nodeProps
);
557 if (!IMA_SUCCESS(status
)) {
558 printLibError(status
);
568 * Finds the Sun iSCSI initiator (LHBA). This CLI currently supports only
575 * zero on success with initiator found
576 * > 0 on success with no initiator found
580 sunInitiatorFind(IMA_OID
*oid
)
582 IMA_OID_LIST
*lhbaList
= NULL
;
584 IMA_STATUS status
= IMA_GetLhbaOidList(&lhbaList
);
585 if (!IMA_SUCCESS(status
)) {
586 printLibError(status
);
590 if ((lhbaList
== NULL
) || (lhbaList
->oidCount
== 0)) {
591 printLibError(IMA_ERROR_OBJECT_NOT_FOUND
);
592 if (lhbaList
!= NULL
)
593 (void) IMA_FreeMemory(lhbaList
);
597 *oid
= lhbaList
->oids
[0];
598 (void) IMA_FreeMemory(lhbaList
);
605 * wcInput - wide character string containing discovery address
607 * address - IMA_TARGET_ADDRESS structure containing valid
611 * non-zero on failure
615 getTargetAddress(int addrType
, char *ipStr
, IMA_TARGET_ADDRESS
*address
)
618 char cBracketL
= '['; /* Open Bracket '[' */
619 char cBracketR
= ']'; /* Close Bracket ']' */
622 unsigned long inputPort
;
623 int addressType
= AF_INET
;
624 char *tmpStrPtr
, tmpStr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
627 /* Check if this is a ipv6 address */
628 if (ipStr
[0] == cBracketL
) {
629 addressType
= AF_INET6
;
630 startPos
= strchr(ipStr
, cBracketR
);
632 (void) fprintf(stderr
, "%s: %s: ']' %s\n",
633 cmdName
, ipStr
, gettext("missing"));
636 (void) strlcpy(tmpStr
, ipStr
+1, startPos
-ipStr
);
637 address
->hostnameIpAddress
.id
.ipAddress
.ipv4Address
= IMA_FALSE
;
640 /* set start position to beginning of input object */
641 addressType
= AF_INET
;
643 address
->hostnameIpAddress
.id
.ipAddress
.ipv4Address
= IMA_TRUE
;
646 /* wcschr for ':'. If not there, use default port */
647 colPos
= strchr(startPos
, cCol
);
650 if (addrType
== DISCOVERY_ADDRESS
) {
651 inputPort
= DEFAULT_ISCSI_PORT
;
652 } else if (addrType
== ISNS_SERVER_ADDRESS
) {
653 inputPort
= ISNS_DEFAULT_SERVER_PORT
;
661 rval
= inet_pton(addressType
, tmpStrPtr
,
662 address
->hostnameIpAddress
.id
.ipAddress
.ipAddress
);
663 /* inet_pton returns 1 on success */
665 (void) fprintf(stderr
, "%s: %s: %s\n", cmdName
, ipStr
,
666 gettext("invalid IP address"));
675 if (*colPos
== '\0') {
676 (void) fprintf(stderr
, "%s: %s: %s\n",
678 gettext("port number missing"));
683 * convert port string to unsigned value
684 * Note: Don't remove errno = 0 as you may get false failures.
687 inputPort
= strtol(colPos
, &errchr
, 10);
688 if (errno
!= 0 || inputPort
== 0 && errchr
!= NULL
) {
689 (void) fprintf(stderr
, "%s: %s:%s %s\n",
690 cmdName
, ipStr
, colPos
,
691 gettext("port number invalid"));
694 /* make sure it's in the range */
695 if (inputPort
> USHRT_MAX
) {
696 (void) fprintf(stderr
, "%s: %s: %s\n",
698 gettext("port number out of range"));
702 address
->portNumber
= inputPort
;
708 * Print results of send targets command
711 printSendTargets(SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*pList
)
713 char outBuf
[INET6_ADDRSTRLEN
];
718 for (i
= 0; i
< pList
->keyCount
; i
++) {
719 if (pList
->keys
[i
].address
.ipAddress
.ipv4Address
== IMA_TRUE
) {
721 inetSize
= INET_ADDRSTRLEN
;
724 inetSize
= INET6_ADDRSTRLEN
;
726 (void) fprintf(stdout
, gettext("\tTarget name: %ws\n"),
727 pList
->keys
[i
].name
);
728 (void) fprintf(stdout
, "\t\t%s: %15s:%d", "Target address",
729 inet_ntop(af
, &(pList
->keys
[i
].address
.ipAddress
.ipAddress
),
730 outBuf
, inetSize
), pList
->keys
[i
].address
.portNumber
);
731 (void) fprintf(stdout
, ", %d", pList
->keys
[i
].tpgt
);
732 (void) fprintf(stdout
, "\n");
738 * Print all login parameters
741 printLoginParameters(char *prefix
, IMA_OID oid
, int printOption
)
744 IMA_BOOL_VALUE propBool
;
745 IMA_MIN_MAX_VALUE propMinMax
;
746 char longString
[MAX_LONG_CHAR_LEN
+ 1];
747 SUN_IMA_CONN_PROPERTIES
*connProps
= NULL
;
748 IMA_OID_LIST
*pConnList
;
750 (void) memset(longString
, 0, sizeof (longString
));
752 switch (printOption
) {
753 case PRINT_CONFIGURED_PARAMS
:
754 (void) fprintf(stdout
, "%s%s:\n",
756 gettext("Login Parameters (Default/Configured)"));
758 case PRINT_NEGOTIATED_PARAMS
:
759 (void) fprintf(stdout
, "%s%s:\n",
761 gettext("Login Parameters (Negotiated)"));
762 status
= SUN_IMA_GetConnOidList(
766 if (!IMA_SUCCESS(status
)) {
767 printLibError(status
);
771 status
= SUN_IMA_GetConnProperties(&pConnList
->oids
[0],
773 propBool
.currentValueValid
= connProps
->valuesValid
;
774 propMinMax
.currentValueValid
= connProps
->valuesValid
;
780 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
781 propBool
.currentValue
= connProps
->dataSequenceInOrder
;
783 status
= IMA_GetDataSequenceInOrderProperties(oid
, &propBool
);
785 if (!IMA_SUCCESS(status
)) {
786 printLibError(status
);
787 (void) IMA_FreeMemory(connProps
);
790 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
791 gettext("Data Sequence In Order"));
792 IMABOOLPRINT(propBool
, printOption
);
795 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
796 propBool
.currentValue
= connProps
->dataPduInOrder
;
798 status
= IMA_GetDataPduInOrderProperties(oid
, &propBool
);
800 if (!IMA_SUCCESS(status
)) {
801 printLibError(status
);
802 (void) IMA_FreeMemory(connProps
);
805 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
806 gettext("Data PDU In Order"));
807 IMABOOLPRINT(propBool
, printOption
);
810 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
811 propMinMax
.currentValue
= connProps
->defaultTime2Retain
;
813 status
= IMA_GetDefaultTime2RetainProperties(oid
, &propMinMax
);
815 if (!IMA_SUCCESS(status
)) {
816 printLibError(status
);
817 (void) IMA_FreeMemory(connProps
);
820 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
821 gettext("Default Time To Retain"));
822 IMAMINMAXPRINT(propMinMax
, printOption
);
825 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
826 propMinMax
.currentValue
= connProps
->defaultTime2Wait
;
828 status
= IMA_GetDefaultTime2WaitProperties(oid
, &propMinMax
);
830 if (!IMA_SUCCESS(status
)) {
831 printLibError(status
);
832 (void) IMA_FreeMemory(connProps
);
835 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
836 gettext("Default Time To Wait"));
837 IMAMINMAXPRINT(propMinMax
, printOption
);
840 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
841 propMinMax
.currentValue
= connProps
->errorRecoveryLevel
;
843 status
= IMA_GetErrorRecoveryLevelProperties(oid
, &propMinMax
);
845 if (!IMA_SUCCESS(status
)) {
846 printLibError(status
);
847 (void) IMA_FreeMemory(connProps
);
850 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
851 gettext("Error Recovery Level"));
852 IMAMINMAXPRINT(propMinMax
, printOption
);
855 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
856 propMinMax
.currentValue
= connProps
->firstBurstLength
;
858 status
= IMA_GetFirstBurstLengthProperties(oid
,
861 if (!IMA_SUCCESS(status
)) {
862 printLibError(status
);
863 (void) IMA_FreeMemory(connProps
);
866 (void) fprintf(stdout
, "%s\t%s: ",
867 prefix
, gettext("First Burst Length"));
868 IMAMINMAXPRINT(propMinMax
, printOption
);
871 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
872 propBool
.currentValue
= connProps
->immediateData
;
874 status
= IMA_GetImmediateDataProperties(oid
, &propBool
);
876 if (!IMA_SUCCESS(status
)) {
877 printLibError(status
);
878 (void) IMA_FreeMemory(connProps
);
881 (void) fprintf(stdout
, "%s\t%s: ", prefix
, gettext("Immediate Data"));
882 IMABOOLPRINT(propBool
, printOption
);
885 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
886 propBool
.currentValue
= connProps
->initialR2T
;
888 status
= IMA_GetInitialR2TProperties(oid
, &propBool
);
890 if (!IMA_SUCCESS(status
)) {
891 printLibError(status
);
892 (void) IMA_FreeMemory(connProps
);
895 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
896 gettext("Initial Ready To Transfer (R2T)"));
897 IMABOOLPRINT(propBool
, printOption
);
900 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
901 propMinMax
.currentValue
= connProps
->maxBurstLength
;
903 status
= IMA_GetMaxBurstLengthProperties(oid
, &propMinMax
);
905 if (!IMA_SUCCESS(status
)) {
906 printLibError(status
);
907 (void) IMA_FreeMemory(connProps
);
910 (void) fprintf(stdout
, "%s\t%s: ", prefix
, gettext("Max Burst Length"));
911 IMAMINMAXPRINT(propMinMax
, printOption
);
914 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
915 propMinMax
.currentValue
= connProps
->maxOutstandingR2T
;
917 status
= IMA_GetMaxOutstandingR2TProperties(oid
, &propMinMax
);
919 if (!IMA_SUCCESS(status
)) {
920 printLibError(status
);
921 (void) IMA_FreeMemory(connProps
);
924 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
925 gettext("Max Outstanding R2T"));
926 IMAMINMAXPRINT(propMinMax
, printOption
);
929 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
930 propMinMax
.currentValue
= connProps
->maxRecvDataSegmentLength
;
932 status
= IMA_GetMaxRecvDataSegmentLengthProperties(oid
,
935 if (!IMA_SUCCESS(status
)) {
936 printLibError(status
);
937 (void) IMA_FreeMemory(connProps
);
940 (void) fprintf(stdout
, "%s\t%s: ", prefix
,
941 gettext("Max Receive Data Segment Length"));
942 IMAMINMAXPRINT(propMinMax
, printOption
);
945 if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
946 propMinMax
.currentValue
= connProps
->maxConnections
;
948 status
= IMA_GetMaxConnectionsProperties(oid
, &propMinMax
);
950 if (!IMA_SUCCESS(status
)) {
951 printLibError(status
);
952 (void) IMA_FreeMemory(connProps
);
955 (void) fprintf(stdout
, "%s\t%s: ", prefix
, gettext("Max Connections"));
956 IMAMINMAXPRINT(propMinMax
, printOption
);
958 (void) IMA_FreeMemory(connProps
);
963 * Print discovery information.
966 printDiscoveryMethod(char *prefix
, IMA_UINT32 discoveryMethodFlags
)
968 (void) fprintf(stdout
, "%s%s: ", prefix
, gettext("Discovery Method"));
969 if (discoveryMethodFlags
== IMA_TARGET_DISCOVERY_METHOD_UNKNOWN
) {
970 (void) fprintf(stdout
, "%s\n", gettext("NA"));
972 if (!((discoveryMethodFlags
&
973 IMA_TARGET_DISCOVERY_METHOD_STATIC
) ^
974 IMA_TARGET_DISCOVERY_METHOD_STATIC
)) {
975 (void) fprintf(stdout
, "%s ", gettext("Static"));
977 if (!((discoveryMethodFlags
&
978 IMA_TARGET_DISCOVERY_METHOD_SENDTARGETS
) ^
979 IMA_TARGET_DISCOVERY_METHOD_SENDTARGETS
)) {
980 (void) fprintf(stdout
, "%s ", gettext("SendTargets"));
982 if (!((discoveryMethodFlags
&
983 IMA_TARGET_DISCOVERY_METHOD_ISNS
) ^
984 IMA_TARGET_DISCOVERY_METHOD_ISNS
)) {
985 (void) fprintf(stdout
, "%s ", gettext("iSNS"));
987 (void) fprintf(stdout
, "\n");
992 * printConnectionList - Prints the conection list provided
995 printConnectionList(char *prefix
, IMA_OID_LIST
*pConnList
)
997 IMA_STATUS imaStatus
;
999 SUN_IMA_CONN_PROPERTIES
*connProps
;
1001 char ipv4
[INET_ADDRSTRLEN
+1];
1002 char ipv6
[INET6_ADDRSTRLEN
+1];
1005 for (i
= 0; i
< pConnList
->oidCount
; i
++) {
1006 imaStatus
= SUN_IMA_GetConnProperties(&pConnList
->oids
[i
],
1009 if (imaStatus
!= IMA_STATUS_SUCCESS
) {
1013 (void) fprintf(stdout
, "%sCID: %d\n", prefix
,
1014 connProps
->connectionID
);
1016 (void) memset(&tmp
, 0, sizeof (tmp
));
1017 if (connProps
->local
.ipAddress
.ipv4Address
== IMA_TRUE
) {
1018 if (inet_ntop(AF_INET
,
1019 &connProps
->local
.ipAddress
.ipAddress
[0],
1022 (void) fprintf(stdout
,
1025 gettext("IP address (Local)"),
1027 ntohs(connProps
->local
.portNumber
));
1030 if (inet_ntop(AF_INET6
,
1031 &connProps
->local
.ipAddress
.ipAddress
[0],
1033 INET6_ADDRSTRLEN
)) {
1034 (void) fprintf(stdout
,
1037 gettext("IP address (Local)"),
1039 ntohs(connProps
->local
.portNumber
));
1042 if (connProps
->peer
.ipAddress
.ipv4Address
== IMA_TRUE
) {
1043 if (inet_ntop(AF_INET
,
1044 &connProps
->peer
.ipAddress
.ipAddress
[0],
1047 (void) fprintf(stdout
,
1050 gettext("IP address (Peer)"),
1052 ntohs(connProps
->peer
.portNumber
));
1055 if (inet_ntop(AF_INET6
,
1056 &connProps
->peer
.ipAddress
.ipAddress
[0],
1058 INET6_ADDRSTRLEN
)) {
1059 (void) fprintf(stdout
,
1062 gettext("IP address (Peer)"),
1064 ntohs(connProps
->peer
.portNumber
));
1068 (void) IMA_FreeMemory(connProps
);
1073 * Set login parameters on a target or initiator
1076 setLoginParameter(IMA_OID oid
, int optval
, char *optarg
)
1078 IMA_STATUS status
= IMA_STATUS_SUCCESS
;
1081 SUN_IMA_DIGEST_ALGORITHM digestAlgList
[1];
1082 IMA_MIN_MAX_VALUE propMinMax
;
1086 * for clarity, there are two switch statements
1087 * The first loads the variable and the second
1088 * calls the appropriate API
1091 case DATA_SEQ_IN_ORDER
:
1092 case IMMEDIATE_DATA
:
1094 case DATA_PDU_IN_ORDER
:
1095 /* implement 'default'? */
1096 if (strcasecmp(optarg
, "yes") == 0) {
1097 boolValue
= IMA_TRUE
;
1098 } else if (strcasecmp(optarg
, "no") == 0) {
1099 boolValue
= IMA_FALSE
;
1101 (void) fprintf(stderr
, "%s: %s - %s\n",
1103 gettext("invalid option argument"),
1108 case DEFAULT_TIME_2_RETAIN
:
1109 case DEFAULT_TIME_2_WAIT
:
1111 uintValue
= strtoul(optarg
, &endptr
, 0);
1112 if (*endptr
!= '\0' || errno
!= 0) {
1113 (void) fprintf(stderr
, "%s: %s - %s\n",
1115 gettext("invalid option argument"),
1119 if (uintValue
> 3600) {
1120 (void) fprintf(stderr
, "%s: %s\n",
1122 gettext("value must be between 0 and 3600"));
1126 case FIRST_BURST_LENGTH
:
1127 case MAX_BURST_LENGTH
:
1128 case MAX_RECV_DATA_SEG_LEN
:
1130 /* implement 'default'? */
1131 uintValue
= strtoul(optarg
, &endptr
, 0);
1132 if (*endptr
!= '\0' || errno
!= 0) {
1133 (void) fprintf(stderr
, "%s: %s - %s\n",
1135 gettext("invalid option argument"),
1139 if (uintValue
< 512 || uintValue
> 16777215) {
1140 (void) fprintf(stderr
, "%s: %s\n",
1142 gettext("value must be between 512 and 16777215"));
1146 case MAX_OUTSTANDING_R2T
:
1148 uintValue
= strtoul(optarg
, &endptr
, 0);
1149 if (*endptr
!= '\0' || errno
!= 0) {
1150 (void) fprintf(stderr
, "%s: %s - %s\n",
1152 gettext("invalid option argument"),
1156 if (uintValue
< 1 || uintValue
> 65535) {
1157 (void) fprintf(stderr
, "%s: %s\n",
1159 gettext("value must be between 1 and 65535"));
1165 if (strcasecmp(optarg
, "none") == 0) {
1166 digestAlgList
[0] = SUN_IMA_DIGEST_NONE
;
1167 } else if (strcasecmp(optarg
, "CRC32") == 0) {
1168 digestAlgList
[0] = SUN_IMA_DIGEST_CRC32
;
1170 (void) fprintf(stderr
, "%s: %s - %s\n",
1172 gettext("invalid option argument"),
1177 case MAX_CONNECTIONS
:
1179 uintValue
= strtoul(optarg
, &endptr
, 0);
1180 if (*endptr
!= '\0' || errno
!= 0) {
1181 (void) fprintf(stderr
, "%s: %s - %s\n",
1183 gettext("invalid option argument"),
1187 if (uintValue
< 1 || uintValue
> 256) {
1188 (void) fprintf(stderr
, "%s: %s\n",
1190 gettext("value must be between 1 and 256"));
1194 case ERROR_RECOVERY_LEVEL
:
1196 uintValue
= strtoul(optarg
, &endptr
, 0);
1197 if (*endptr
!= '\0' || errno
!= 0) {
1198 (void) fprintf(stderr
, "%s: %s - %s\n",
1200 gettext("invalid option argument"),
1204 if (uintValue
> 2) {
1205 (void) fprintf(stderr
, "%s: %s\n",
1207 gettext("value must be between 0 and 2"));
1212 (void) fprintf(stderr
, "%s: %c: %s\n",
1213 cmdName
, optval
, gettext("unknown option"));
1218 case DATA_PDU_IN_ORDER
:
1219 status
= IMA_SetDataPduInOrder(oid
, boolValue
);
1221 case DATA_SEQ_IN_ORDER
:
1222 status
= IMA_SetDataSequenceInOrder(oid
, boolValue
);
1224 case DEFAULT_TIME_2_RETAIN
:
1225 status
= IMA_SetDefaultTime2Retain(oid
, uintValue
);
1227 case DEFAULT_TIME_2_WAIT
:
1228 status
= IMA_SetDefaultTime2Wait(oid
, uintValue
);
1230 case FIRST_BURST_LENGTH
:
1231 status
= IMA_SetFirstBurstLength(oid
, uintValue
);
1234 * If this call fails check to see if it's because
1235 * the requested value is > than maxBurstLength
1237 if (!IMA_SUCCESS(status
)) {
1238 status
= IMA_GetMaxBurstLengthProperties(oid
,
1240 if (!IMA_SUCCESS(status
)) {
1241 printLibError(status
);
1244 if (uintValue
> propMinMax
.currentValue
) {
1245 (void) fprintf(stderr
,
1246 "%s: %s\n", cmdName
,
1247 gettext("firstBurstLength must " \
1248 "be less than or equal to than " \
1255 case IMMEDIATE_DATA
:
1256 status
= IMA_SetImmediateData(oid
, boolValue
);
1259 status
= IMA_SetInitialR2T(oid
, boolValue
);
1261 case MAX_BURST_LENGTH
:
1262 status
= IMA_SetMaxBurstLength(oid
, uintValue
);
1264 * If this call fails check to see if it's because
1265 * the requested value is < than firstBurstLength
1267 if (!IMA_SUCCESS(status
)) {
1268 status
= IMA_GetFirstBurstLengthProperties(oid
,
1270 if (!IMA_SUCCESS(status
)) {
1271 printLibError(status
);
1274 if (uintValue
< propMinMax
.currentValue
) {
1275 (void) fprintf(stderr
, "%s: %s\n",
1277 gettext("maxBurstLength must be " \
1278 "greater than or equal to " \
1279 "firstBurstLength"));
1285 case MAX_OUTSTANDING_R2T
:
1286 status
= IMA_SetMaxOutstandingR2T(oid
, uintValue
);
1288 case MAX_RECV_DATA_SEG_LEN
:
1289 status
= IMA_SetMaxRecvDataSegmentLength(oid
,
1293 status
= SUN_IMA_SetHeaderDigest(oid
, 1,
1297 status
= SUN_IMA_SetDataDigest(oid
, 1,
1300 case MAX_CONNECTIONS
:
1301 status
= IMA_SetMaxConnections(oid
, uintValue
);
1303 case ERROR_RECOVERY_LEVEL
:
1304 status
= IMA_SetErrorRecoveryLevel(oid
, uintValue
);
1307 if (!IMA_SUCCESS(status
)) {
1308 printLibError(status
);
1315 printDigestAlgorithm(SUN_IMA_DIGEST_ALGORITHM_VALUE
*digestAlgorithms
,
1320 if (printOption
== PRINT_CONFIGURED_PARAMS
) {
1321 for (i
= 0; i
< digestAlgorithms
->defaultAlgorithmCount
; i
++) {
1323 (void) fprintf(stdout
, "|");
1325 switch (digestAlgorithms
->defaultAlgorithms
[i
]) {
1326 case SUN_IMA_DIGEST_NONE
:
1327 (void) fprintf(stdout
,
1330 case SUN_IMA_DIGEST_CRC32
:
1331 (void) fprintf(stdout
,
1335 (void) fprintf(stdout
,
1336 gettext("Unknown"));
1340 (void) fprintf(stdout
, "/");
1341 if (digestAlgorithms
->currentValid
== IMA_TRUE
) {
1343 i
< digestAlgorithms
->currentAlgorithmCount
; i
++) {
1345 (void) fprintf(stdout
, "|");
1347 switch (digestAlgorithms
->
1348 currentAlgorithms
[i
]) {
1349 case SUN_IMA_DIGEST_NONE
:
1350 (void) fprintf(stdout
,
1353 case SUN_IMA_DIGEST_CRC32
:
1354 (void) fprintf(stdout
,
1358 (void) fprintf(stdout
,
1359 gettext("Unknown"));
1364 (void) fprintf(stdout
, "-");
1366 (void) fprintf(stdout
, "\n");
1367 } else if (printOption
== PRINT_NEGOTIATED_PARAMS
) {
1369 if (digestAlgorithms
->negotiatedValid
== IMA_TRUE
) {
1371 i
< digestAlgorithms
->negotiatedAlgorithmCount
;
1374 (void) fprintf(stdout
, "|");
1376 switch (digestAlgorithms
->
1377 negotiatedAlgorithms
[i
]) {
1378 case SUN_IMA_DIGEST_NONE
:
1379 (void) fprintf(stdout
,
1382 case SUN_IMA_DIGEST_CRC32
:
1383 (void) fprintf(stdout
,
1387 (void) fprintf(stdout
,
1388 gettext("Unknown"));
1393 (void) fprintf(stdout
, "-");
1395 (void) fprintf(stdout
, "\n");
1400 setLoginParameters(IMA_OID oid
, char *optarg
)
1402 char keyp
[MAXOPTARGLEN
];
1403 char valp
[MAXOPTARGLEN
];
1405 char *nameValueString
, *indexp
, *delim
= NULL
;
1407 if ((nameValueString
= strdup(optarg
)) == NULL
) {
1408 if (errno
== ENOMEM
) {
1409 (void) fprintf(stderr
, "%s: %s\n",
1410 cmdName
, strerror(errno
));
1412 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1413 gettext("unknown error"));
1418 indexp
= nameValueString
;
1421 * Retrieve all login params from option argument
1422 * Syntax <key=value,...>
1425 if (delim
= strchr(indexp
, ',')) {
1428 (void) memset(keyp
, 0, sizeof (keyp
));
1429 (void) memset(valp
, 0, sizeof (valp
));
1430 if (sscanf(indexp
, gettext("%[^=]=%s"), keyp
, valp
) != 2) {
1431 (void) fprintf(stderr
, "%s: %s: %s\n", cmdName
,
1432 gettext("Unknown param"), indexp
);
1433 if (nameValueString
) {
1434 free(nameValueString
);
1435 nameValueString
= NULL
;
1439 if ((key
= getLoginParam(keyp
)) == -1) {
1440 (void) fprintf(stderr
, "%s: %s: %s\n", cmdName
,
1441 gettext("Unknown key"), keyp
);
1442 if (nameValueString
) {
1443 free(nameValueString
);
1444 nameValueString
= NULL
;
1448 if (setLoginParameter(oid
, key
, valp
) != 0) {
1449 if (nameValueString
) {
1450 free(nameValueString
);
1451 nameValueString
= NULL
;
1462 if (nameValueString
) {
1463 free(nameValueString
);
1464 nameValueString
= NULL
;
1470 * Print logical unit information for a specific target
1473 printTargetLuns(IMA_OID_LIST
* lunList
)
1477 SUN_IMA_LU_PROPERTIES lunProps
;
1479 for (j
= 0; j
< lunList
->oidCount
; j
++) {
1480 status
= SUN_IMA_GetLuProperties(lunList
->oids
[j
],
1482 if (!IMA_SUCCESS(status
)) {
1483 printLibError(status
);
1487 (void) fprintf(stdout
, "\tLUN: %lld\n",
1488 lunProps
.imaProps
.targetLun
);
1489 (void) fprintf(stdout
, "\t Vendor: %s\n",
1491 (void) fprintf(stdout
, "\t Product: %s\n",
1492 lunProps
.productId
);
1494 * The lun is valid though the os Device Name is not.
1495 * Give this information to users for judgement.
1497 if (lunProps
.imaProps
.osDeviceNameValid
== IMA_TRUE
) {
1498 (void) fprintf(stdout
,
1499 gettext("\t OS Device Name: %ws\n"),
1500 lunProps
.imaProps
.osDeviceName
);
1502 (void) fprintf(stdout
,
1503 gettext("\t OS Device Name: Not"
1510 * Retrieve CHAP secret from input
1513 getSecret(char *secret
, int *secretLen
, int minSecretLen
, int maxSecretLen
)
1518 chapSecret
= getpassphrase(gettext("Enter secret:"));
1520 if (chapSecret
== NULL
) {
1521 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1522 gettext("Unable to get secret"));
1527 if (strlen(chapSecret
) > maxSecretLen
) {
1528 (void) fprintf(stderr
, "%s: %s %d\n", cmdName
,
1529 gettext("secret too long, maximum length is"),
1535 if (strlen(chapSecret
) < minSecretLen
) {
1536 (void) fprintf(stderr
, "%s: %s %d\n", cmdName
,
1537 gettext("secret too short, minimum length is"),
1543 (void) strcpy(secret
, chapSecret
);
1545 chapSecret
= getpassphrase(gettext("Re-enter secret:"));
1547 if (chapSecret
== NULL
) {
1548 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1549 gettext("Unable to get secret"));
1554 if (strcmp(secret
, chapSecret
) != 0) {
1555 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
1556 gettext("secrets do not match, secret not changed"));
1560 *secretLen
= strlen(chapSecret
);
1565 * Lists the discovery attributes
1568 listDiscovery(int *funcRet
)
1570 IMA_OID initiatorOid
;
1571 IMA_DISCOVERY_PROPERTIES discProps
;
1575 assert(funcRet
!= NULL
);
1578 /* Find Sun initiator */
1579 ret
= sunInitiatorFind(&initiatorOid
);
1581 (void) fprintf(stderr
, "%s: %s\n",
1582 cmdName
, gettext("no initiator found"));
1589 /* Get discovery attributes from IMA */
1590 status
= IMA_GetDiscoveryProperties(initiatorOid
, &discProps
);
1591 if (!IMA_SUCCESS(status
)) {
1592 printLibError(status
);
1598 (void) fprintf(stdout
, "%s:\n", "Discovery");
1599 (void) fprintf(stdout
, "\tStatic: %s\n",
1600 discProps
.staticDiscoveryEnabled
== IMA_TRUE
? \
1601 gettext("enabled") : gettext("disabled"));
1602 (void) fprintf(stdout
, "\tSend Targets: %s\n",
1603 discProps
.sendTargetsDiscoveryEnabled
== IMA_TRUE
? \
1604 gettext("enabled") : gettext("disabled"));
1605 (void) fprintf(stdout
, "\tiSNS: %s\n",
1606 discProps
.iSnsDiscoveryEnabled
== IMA_TRUE
? \
1607 gettext("enabled") : gettext("disabled"));
1613 * Print all initiator node attributes
1616 listNode(int *funcRet
)
1618 IMA_OID initiatorOid
;
1619 IMA_NODE_PROPERTIES nodeProps
;
1622 IMA_UINT maxEntries
= MAX_AUTH_METHODS
;
1623 IMA_AUTHMETHOD methodList
[MAX_AUTH_METHODS
];
1624 SUN_IMA_RADIUS_CONFIG radiusConfig
;
1625 SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms
;
1626 IMA_BOOL radiusAccess
;
1630 assert(funcRet
!= NULL
);
1632 ret
= getNodeProps(&nodeProps
);
1637 if (nodeProps
.nameValid
== IMA_FALSE
) {
1638 return (INVALID_NODE_NAME
);
1641 /* Find Sun initiator */
1642 ret
= sunInitiatorFind(&initiatorOid
);
1644 (void) fprintf(stderr
, "%s: %s\n",
1645 cmdName
, gettext("no initiator found"));
1652 (void) fprintf(stdout
, gettext("%s: %ws\n"),
1653 gettext("Initiator node name"),
1655 (void) fprintf(stdout
, gettext("Initiator node alias: "));
1656 if (nodeProps
.aliasValid
== IMA_TRUE
) {
1657 (void) fprintf(stdout
, gettext("%ws\n"), nodeProps
.alias
);
1659 (void) fprintf(stdout
, "%s\n", "-");
1661 (void) fprintf(stdout
, "\t%s:\n",
1662 gettext("Login Parameters (Default/Configured)"));
1664 /* Get Digest configuration */
1665 status
= SUN_IMA_GetHeaderDigest(initiatorOid
, &digestAlgorithms
);
1666 if (IMA_SUCCESS(status
)) {
1667 (void) fprintf(stdout
, "\t\t%s: ", gettext("Header Digest"));
1668 printDigestAlgorithm(&digestAlgorithms
,
1669 PRINT_CONFIGURED_PARAMS
);
1671 printLibError(status
);
1676 status
= SUN_IMA_GetDataDigest(initiatorOid
, &digestAlgorithms
);
1677 if (IMA_SUCCESS(status
)) {
1678 (void) fprintf(stdout
, "\t\t%s: ", gettext("Data Digest"));
1679 printDigestAlgorithm(&digestAlgorithms
,
1680 PRINT_CONFIGURED_PARAMS
);
1682 printLibError(status
);
1687 /* Get authentication type for this lhba */
1688 status
= IMA_GetInUseInitiatorAuthMethods(initiatorOid
, &maxEntries
,
1690 (void) fprintf(stdout
, "\t%s: ", gettext("Authentication Type"));
1691 if (!IMA_SUCCESS(status
)) {
1692 /* No authentication method set - default is NONE */
1693 (void) fprintf(stdout
, gettext("NONE"));
1695 for (i
= 0; i
< maxEntries
; i
++) {
1697 (void) fprintf(stdout
, "|");
1699 switch (methodList
[i
]) {
1700 case IMA_AUTHMETHOD_NONE
:
1701 (void) fprintf(stdout
, gettext("NONE"));
1703 case IMA_AUTHMETHOD_CHAP
:
1704 (void) fprintf(stdout
, gettext("CHAP"));
1705 listCHAPName(initiatorOid
);
1708 (void) fprintf(stdout
,
1709 gettext("unknown type"));
1714 (void) fprintf(stdout
, "\n");
1717 /* Get RADIUS configuration */
1718 status
= SUN_IMA_GetInitiatorRadiusConfig(initiatorOid
, &radiusConfig
);
1719 (void) fprintf(stdout
, "\t%s: ", gettext("RADIUS Server"));
1720 if (IMA_SUCCESS(status
)) {
1721 if (strlen(radiusConfig
.hostnameIpAddress
) > 0) {
1722 (void) fprintf(stdout
, "%s:%d",
1723 radiusConfig
.hostnameIpAddress
,
1726 (void) fprintf(stdout
, "%s", gettext("NONE"));
1729 (void) fprintf(stdout
, "%s", gettext("NONE"));
1731 (void) fprintf(stdout
, "\n");
1733 status
= SUN_IMA_GetInitiatorRadiusAccess(initiatorOid
,
1735 (void) fprintf(stdout
, "\t%s: ", gettext("RADIUS Access"));
1736 if (IMA_SUCCESS(status
)) {
1737 if (radiusAccess
== IMA_TRUE
) {
1738 (void) fprintf(stdout
, "%s", gettext("enabled"));
1740 (void) fprintf(stdout
, "%s", gettext("disabled"));
1742 } else if (status
== IMA_ERROR_OBJECT_NOT_FOUND
) {
1743 (void) fprintf(stdout
, "%s", gettext("disabled"));
1745 (void) fprintf(stdout
, "%s", gettext("unknown"));
1747 (void) fprintf(stdout
, "\n");
1749 /* print tunable parameters information. */
1750 ret
= printTunableParameters(initiatorOid
);
1752 /* print configured session information. */
1753 ret
= printConfiguredSessions(initiatorOid
);
1759 * Print discovery addresses
1762 listDiscoveryAddress(int objectLen
, char *objects
[], cmdOptions_t
*options
,
1765 IMA_OID initiatorOid
;
1766 SUN_IMA_DISC_ADDR_PROP_LIST
*discoveryAddressPropertiesList
;
1767 IMA_DISCOVERY_ADDRESS_PROPERTIES discAddrProps
;
1768 IMA_TARGET_ADDRESS address
;
1769 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*pList
;
1771 wchar_t wcInputObject
[MAX_ADDRESS_LEN
+ 1];
1773 boolean_t object
= B_FALSE
;
1776 boolean_t verbose
= B_FALSE
;
1778 cmdOptions_t
*optionList
= options
;
1779 char sAddr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
1781 assert(funcRet
!= NULL
);
1783 /* Find Sun initiator */
1784 ret
= sunInitiatorFind(&initiatorOid
);
1786 (void) fprintf(stderr
, "%s: %s\n",
1787 cmdName
, gettext("no initiator found"));
1794 for (; optionList
->optval
; optionList
++) {
1795 switch (optionList
->optval
) {
1800 (void) fprintf(stderr
, "%s: %c: %s\n",
1801 cmdName
, optionList
->optval
,
1802 gettext("unknown option"));
1808 * If there are multiple objects, execute outer 'for' loop that
1809 * many times for each target detail, otherwise, execute it only
1810 * once with summaries only
1812 if (objectLen
> 0) {
1814 outerLoop
= objectLen
;
1820 status
= SUN_IMA_GetDiscoveryAddressPropertiesList(
1821 &discoveryAddressPropertiesList
);
1822 if (!IMA_SUCCESS(status
)) {
1823 printLibError(status
);
1828 for (i
= 0; i
< outerLoop
; i
++) {
1831 (void) memset(&wcInputObject
[0], 0,
1832 sizeof (wcInputObject
));
1833 (void) memset(&address
, 0, sizeof (address
));
1834 if (mbstowcs(wcInputObject
, objects
[i
],
1835 (MAX_ADDRESS_LEN
+ 1)) == (size_t)-1) {
1836 (void) fprintf(stderr
, "%s: %s\n",
1838 gettext("conversion error"));
1844 * if one or more objects were input,
1847 if (getTargetAddress(DISCOVERY_ADDRESS
,
1848 objects
[i
], &address
) != 0) {
1853 for (found
= B_FALSE
, j
= 0;
1854 j
< discoveryAddressPropertiesList
->discAddrCount
;
1857 discoveryAddressPropertiesList
->props
[j
];
1860 * Compare the discovery address with the input if
1864 ipAddressesEqual(discAddrProps
.discoveryAddress
,
1865 address
) && (discAddrProps
.discoveryAddress
.
1866 portNumber
== address
.portNumber
)) {
1870 if (!object
|| found
) {
1871 /* Print summary - always */
1872 if (discAddrProps
.discoveryAddress
.
1873 hostnameIpAddress
.id
.ipAddress
.
1875 (void) inet_ntop(AF_INET
, discAddrProps
.
1876 discoveryAddress
.hostnameIpAddress
.
1877 id
.ipAddress
.ipAddress
, sAddr
,
1879 (void) fprintf(stdout
,
1880 "Discovery Address: %s:%u\n",
1881 sAddr
, discAddrProps
.
1882 discoveryAddress
.portNumber
);
1884 (void) inet_ntop(AF_INET6
,
1886 discoveryAddress
.hostnameIpAddress
.
1887 id
.ipAddress
.ipAddress
, sAddr
,
1889 (void) fprintf(stdout
,
1890 "DiscoveryAddress: [%s]:%u\n",
1891 sAddr
, discAddrProps
.
1892 discoveryAddress
.portNumber
);
1896 if ((!object
|| found
) && verbose
) {
1897 IMA_NODE_PROPERTIES nodeProps
;
1899 if (getNodeProps(&nodeProps
) != 0) {
1904 * Issue sendTargets only when an addr is
1907 status
= SUN_IMA_SendTargets(nodeProps
.name
,
1908 discAddrProps
.discoveryAddress
, &pList
);
1909 if (!IMA_SUCCESS(status
)) {
1910 (void) fprintf(stderr
, "%s\n",
1911 gettext("\tUnable to get "\
1916 printSendTargets(pList
);
1920 /* we found the discovery address - break */
1925 * There was an object entered but we didn't
1928 if (object
&& !found
) {
1929 (void) fprintf(stdout
, "%s: %s\n",
1930 objects
[i
], gettext("not found"));
1937 * Print ISNS Server addresses
1940 listISNSServerAddress(int objectLen
, char *objects
[], cmdOptions_t
*options
,
1943 IMA_OID initiatorOid
;
1944 SUN_IMA_DISC_ADDR_PROP_LIST
*discoveryAddressPropertiesList
;
1945 IMA_DISCOVERY_ADDRESS_PROPERTIES discAddrProps
;
1946 IMA_TARGET_ADDRESS address
;
1947 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES
*pList
;
1949 wchar_t wcInputObject
[MAX_ADDRESS_LEN
+ 1];
1951 boolean_t object
= B_FALSE
;
1954 boolean_t showTarget
= B_FALSE
;
1956 cmdOptions_t
*optionList
= options
;
1957 char sAddr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
1959 assert(funcRet
!= NULL
);
1961 /* Find Sun initiator */
1962 ret
= sunInitiatorFind(&initiatorOid
);
1964 (void) fprintf(stderr
, "%s: %s\n",
1965 cmdName
, gettext("no initiator found"));
1972 for (; optionList
->optval
; optionList
++) {
1973 switch (optionList
->optval
) {
1975 showTarget
= B_TRUE
;
1978 (void) fprintf(stderr
, "%s: %c: %s\n",
1979 cmdName
, optionList
->optval
,
1980 gettext("unknown option"));
1986 * If there are multiple objects, execute outer 'for' loop that
1987 * many times for each target detail, otherwise, execute it only
1988 * once with summaries only
1990 if (objectLen
> 0) {
1992 outerLoop
= objectLen
;
1998 status
= SUN_IMA_GetISNSServerAddressPropertiesList(
1999 &discoveryAddressPropertiesList
);
2000 if (!IMA_SUCCESS(status
)) {
2001 printLibError(status
);
2006 for (i
= 0; i
< outerLoop
; i
++) {
2009 (void) memset(&wcInputObject
[0], 0,
2010 sizeof (wcInputObject
));
2011 (void) memset(&address
, 0, sizeof (address
));
2012 if (mbstowcs(wcInputObject
, objects
[i
],
2013 (MAX_ADDRESS_LEN
+ 1)) == (size_t)-1) {
2014 (void) fprintf(stderr
, "%s: %s\n",
2016 gettext("conversion error"));
2022 * if one or more objects were input,
2025 if (getTargetAddress(ISNS_SERVER_ADDRESS
,
2026 objects
[i
], &address
) != 0) {
2031 for (found
= B_FALSE
, j
= 0;
2032 j
< discoveryAddressPropertiesList
->discAddrCount
;
2035 discoveryAddressPropertiesList
->props
[j
];
2038 * Compare the discovery address with the input if
2042 ipAddressesEqual(discAddrProps
.discoveryAddress
,
2044 (discAddrProps
.discoveryAddress
.portNumber
==
2045 address
.portNumber
)) {
2049 if (!object
|| found
) {
2050 /* Print summary - always */
2051 if (discAddrProps
.discoveryAddress
.
2052 hostnameIpAddress
.id
.ipAddress
.
2054 (void) inet_ntop(AF_INET
, discAddrProps
.
2055 discoveryAddress
.hostnameIpAddress
.
2056 id
.ipAddress
.ipAddress
, sAddr
,
2059 (void) inet_ntop(AF_INET6
,
2061 discoveryAddress
.hostnameIpAddress
.
2062 id
.ipAddress
.ipAddress
, sAddr
,
2065 (void) fprintf(stdout
,
2066 "iSNS Server IP Address: %s:%u\n",
2068 discAddrProps
.discoveryAddress
.portNumber
);
2071 if ((!object
|| found
) && showTarget
) {
2072 IMA_NODE_PROPERTIES nodeProps
;
2074 if (getNodeProps(&nodeProps
) != 0) {
2079 * Issue sendTargets only when an addr is
2082 status
= SUN_IMA_RetrieveISNSServerTargets(
2083 discAddrProps
.discoveryAddress
,
2085 if (!IMA_SUCCESS(status
)) {
2087 * Check if the discovery mode is
2091 IMA_ERROR_OBJECT_NOT_FOUND
) {
2092 (void) fprintf(stderr
, "%s\n",
2101 (void) fprintf(stderr
, "%s\n",
2102 gettext("\tUnable "\
2108 printSendTargets(pList
);
2112 /* we found the discovery address - break */
2117 * There was an object entered but we didn't
2120 if (object
&& !found
) {
2121 (void) fprintf(stdout
, "%s: %s\n",
2122 objects
[i
], gettext("not found"));
2129 * Print static configuration targets
2132 listStaticConfig(int operandLen
, char *operand
[], int *funcRet
)
2135 IMA_OID initiatorOid
;
2136 IMA_OID_LIST
*staticTargetList
;
2137 SUN_IMA_STATIC_TARGET_PROPERTIES staticTargetProps
;
2138 wchar_t staticTargetName
[MAX_ISCSI_NAME_LEN
+ 1];
2139 wchar_t staticTargetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
2141 char sAddr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
2143 boolean_t object
= B_FALSE
;
2145 boolean_t found
; /* B_TRUE if a target name is found */
2146 boolean_t matched
; /* B_TRUE if a specific target is found */
2147 boolean_t targetAddressSpecified
= B_FALSE
;
2148 boolean_t tpgtSpecified
= B_FALSE
;
2151 IMA_UINT16 port
= 0;
2152 IMA_UINT16 tpgt
= 0;
2153 char tmpStr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
2154 wchar_t tmpTargetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
2156 assert(funcRet
!= NULL
);
2158 /* Find Sun initiator */
2159 ret
= sunInitiatorFind(&initiatorOid
);
2161 (void) fprintf(stderr
, "%s: %s\n",
2162 cmdName
, gettext("no initiator found"));
2170 * If there are multiple objects, execute outer 'for' loop that
2171 * many times for each static config detail, otherwise, execute it only
2172 * once with summaries only
2174 if (operandLen
> 0) {
2176 outerLoop
= operandLen
;
2182 /* convert ':' to wide char for wchar string search */
2183 if (mbtowc(&wcCol
, ":", sizeof (wcCol
)) == -1) {
2184 (void) fprintf(stderr
, "%s: %s\n",
2185 cmdName
, gettext("conversion error"));
2189 status
= IMA_GetStaticDiscoveryTargetOidList(initiatorOid
,
2191 if (!IMA_SUCCESS(status
)) {
2192 printLibError(status
);
2197 for (i
= 0; i
< outerLoop
; i
++) {
2199 if (parseTarget(operand
[i
],
2200 &staticTargetName
[0],
2201 MAX_ISCSI_NAME_LEN
+ 1,
2202 &targetAddressSpecified
,
2203 &staticTargetAddress
[0],
2204 SUN_IMA_IP_ADDRESS_PORT_LEN
,
2208 &isIpv6
) != PARSE_TARGET_OK
) {
2214 for (found
= B_FALSE
, j
= 0; j
< staticTargetList
->oidCount
;
2216 boolean_t isIpv6
= B_FALSE
;
2218 IMA_BOOL defaultTpgt
;
2221 (void) memset(&staticTargetProps
, 0,
2222 sizeof (staticTargetProps
));
2224 status
= SUN_IMA_GetStaticTargetProperties(
2225 staticTargetList
->oids
[j
], &staticTargetProps
);
2226 if (!IMA_SUCCESS(status
)) {
2227 printLibError(status
);
2228 (void) IMA_FreeMemory(staticTargetList
);
2233 stpgt
= staticTargetProps
.staticTarget
.targetAddress
.
2236 defaultTpgt
= staticTargetProps
.staticTarget
.
2237 targetAddress
.defaultTpgt
;
2239 isIpv6
= !staticTargetProps
.staticTarget
.targetAddress
.
2240 imaStruct
.hostnameIpAddress
.id
.ipAddress
.
2244 * Compare the static target name with the input if
2250 staticTargetProps
.staticTarget
.targetName
,
2251 staticTargetName
) == B_TRUE
)) {
2252 /* targetName found - found = B_TRUE */
2254 if (targetAddressSpecified
== B_FALSE
) {
2258 if (staticTargetProps
.staticTarget
.
2259 targetAddress
.imaStruct
.
2260 hostnameIpAddress
.id
.ipAddress
.
2261 ipv4Address
== IMA_TRUE
) {
2262 (void) inet_ntop(AF_INET
,
2264 staticTarget
.targetAddress
.
2265 imaStruct
.hostnameIpAddress
.id
.
2266 ipAddress
.ipAddress
, tmpStr
,
2269 (void) inet_ntop(AF_INET6
,
2271 staticTarget
.targetAddress
.
2272 imaStruct
.hostnameIpAddress
.id
.
2273 ipAddress
.ipAddress
, tmpStr
,
2277 if (mbstowcs(tmpTargetAddress
, tmpStr
,
2278 SUN_IMA_IP_ADDRESS_PORT_LEN
) ==
2280 (void) fprintf(stderr
, "%s: %s\n",
2282 gettext("conversion error"));
2287 if (wcsncmp(tmpTargetAddress
,
2288 staticTargetAddress
,
2289 SUN_IMA_IP_ADDRESS_PORT_LEN
)
2292 staticTarget
.targetAddress
.
2293 imaStruct
.portNumber
== port
) {
2295 * Since an object is
2296 * specified, it should also
2297 * have a tpgt specified. If
2298 * not, that means the object
2299 * specified is associated with
2300 * the default tpgt. In
2301 * either case, a tpgt
2302 * comparison should be done
2303 * before claiming that a
2306 if ((tpgt
== stpgt
&&
2307 tpgtSpecified
== B_TRUE
&&
2308 defaultTpgt
== IMA_FALSE
) ||
2310 tpgtSpecified
== B_FALSE
&&
2311 defaultTpgt
== IMA_TRUE
)) {
2319 if (!object
|| matched
) {
2320 /* print summary - always */
2321 (void) fprintf(stdout
, gettext("%s: %ws,"),
2322 "Static Configuration Target",
2323 staticTargetProps
.staticTarget
.targetName
);
2325 if (isIpv6
== B_FALSE
) {
2326 (void) inet_ntop(AF_INET
,
2328 staticTarget
.targetAddress
.
2329 imaStruct
.hostnameIpAddress
.id
.
2330 ipAddress
.ipAddress
, sAddr
,
2332 (void) fprintf(stdout
, "%s:%d",
2334 staticTargetProps
.staticTarget
.
2335 targetAddress
.imaStruct
.portNumber
);
2337 (void) inet_ntop(AF_INET6
,
2339 staticTarget
.targetAddress
.
2340 imaStruct
.hostnameIpAddress
.id
.
2341 ipAddress
.ipAddress
, sAddr
,
2343 (void) fprintf(stdout
, "[%s]:%d",
2345 staticTargetProps
.staticTarget
.
2346 targetAddress
.imaStruct
.portNumber
);
2349 if (staticTargetProps
.staticTarget
.
2351 defaultTpgt
== IMA_FALSE
) {
2352 (void) fprintf(stdout
, ",%d\n",
2354 staticTarget
.targetAddress
.tpgt
);
2356 (void) fprintf(stdout
, "\n");
2362 * No details to display, but if there were:
2363 * if (object && found)...
2368 * There was an object entered but we didn't
2371 if (object
&& !found
) {
2372 (void) fprintf(stdout
, "%s: %s\n",
2373 operand
[i
], gettext("not found"));
2374 ret
= 1; /* DIY test fix */
2385 listTarget(int objectLen
, char *objects
[], cmdOptions_t
*options
, int *funcRet
)
2387 IMA_OID initiatorOid
;
2388 IMA_OID_LIST
*targetList
;
2389 IMA_OID_LIST
*lunList
;
2390 SUN_IMA_TARGET_PROPERTIES targetProps
;
2392 IMA_OID_LIST
*pConnList
;
2393 SUN_IMA_CONN_PROPERTIES
*connProps
;
2396 wchar_t targetName
[MAX_ISCSI_NAME_LEN
+ 1];
2397 wchar_t targetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
2400 boolean_t operandEntered
= B_FALSE
;
2401 boolean_t verbose
= B_FALSE
;
2402 boolean_t scsi_target
= B_FALSE
;
2403 boolean_t targetAddressSpecified
= B_FALSE
;
2404 boolean_t isIpv6
= B_FALSE
;
2406 cmdOptions_t
*optionList
= options
;
2407 boolean_t tpgtSpecified
= B_FALSE
;
2408 IMA_UINT16 port
= 0;
2411 assert(funcRet
!= NULL
);
2413 /* Find Sun initiator */
2414 ret
= sunInitiatorFind(&initiatorOid
);
2416 (void) fprintf(stderr
, "%s: %s\n",
2417 cmdName
, gettext("no initiator found"));
2424 for (; optionList
->optval
; optionList
++) {
2425 switch (optionList
->optval
) {
2427 scsi_target
= B_TRUE
;
2433 (void) fprintf(stderr
, "%s: %c: %s\n",
2434 cmdName
, optionList
->optval
,
2435 gettext("unknown option"));
2441 * If there are multiple objects, execute outer 'for' loop that
2442 * many times for each target detail, otherwise, execute it only
2443 * once with summaries only
2445 if (objectLen
> 0) {
2446 operandEntered
= B_TRUE
;
2447 outerLoop
= objectLen
;
2449 operandEntered
= B_FALSE
;
2453 status
= SUN_IMA_GetSessionOidList(initiatorOid
, &targetList
);
2454 if (!IMA_SUCCESS(status
)) {
2455 printLibError(status
);
2460 for (i
= 0; i
< outerLoop
; i
++) {
2462 tpgtSpecified
= B_FALSE
;
2463 if (operandEntered
) {
2464 if (parseTarget(objects
[i
],
2466 MAX_ISCSI_NAME_LEN
+ 1,
2467 &targetAddressSpecified
,
2469 SUN_IMA_IP_ADDRESS_PORT_LEN
,
2473 &isIpv6
) != PARSE_TARGET_OK
) {
2478 for (found
= B_FALSE
, j
= 0; j
< targetList
->oidCount
; j
++) {
2479 status
= SUN_IMA_GetTargetProperties(
2480 targetList
->oids
[j
],
2482 if (!IMA_SUCCESS(status
)) {
2483 printLibError(status
);
2484 (void) IMA_FreeMemory(targetList
);
2490 * Compare the target name with the input if
2491 * one was input, if they match, print the target's info
2493 * if no target name was input, continue printing this
2496 if (operandEntered
) {
2497 if (targetNamesEqual(targetProps
.imaProps
.name
,
2498 targetName
) == B_TRUE
) {
2499 if (tpgtSpecified
== B_TRUE
) {
2508 * tpgt does not match,
2519 * target name does not match, move on
2526 /* print summary - always */
2527 (void) fprintf(stdout
, gettext("%s: %ws\n"),
2528 gettext("Target"), targetProps
.imaProps
.name
);
2531 (void) fprintf(stdout
, "\t%s: ", gettext("Alias"));
2532 if (wslen(targetProps
.imaProps
.alias
) > (size_t)0) {
2533 (void) fprintf(stdout
, gettext("%ws\n"),
2534 targetProps
.imaProps
.alias
);
2536 (void) fprintf(stdout
, "%s\n", "-");
2539 if (targetProps
.defaultTpgtNego
!= IMA_TRUE
) {
2540 (void) fprintf(stdout
, "%s%s: %d\n",
2541 "\t", gettext("TPGT"),
2542 targetProps
.tpgtNego
);
2543 } else if (targetProps
.defaultTpgtConf
!= IMA_TRUE
) {
2544 (void) fprintf(stdout
, "%s%s: %d\n",
2545 "\t", gettext("TPGT"),
2546 targetProps
.tpgtConf
);
2549 (void) fprintf(stdout
,
2550 "%s%s: %02x%02x%02x%02x%02x%02x\n",
2551 "\t", gettext("ISID"),
2552 targetProps
.isid
[0], targetProps
.isid
[1],
2553 targetProps
.isid
[2], targetProps
.isid
[3],
2554 targetProps
.isid
[4], targetProps
.isid
[5]);
2557 status
= SUN_IMA_GetConnOidList(
2558 &targetList
->oids
[j
],
2561 if (!IMA_SUCCESS(status
)) {
2562 printLibError(status
);
2563 (void) IMA_FreeMemory(targetList
);
2568 (void) fprintf(stdout
, "%s%s: %lu\n",
2570 gettext("Connections"),
2571 pConnList
->oidCount
);
2574 SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms
;
2576 printConnectionList("\t\t", pConnList
);
2577 printDiscoveryMethod(
2579 targetProps
.imaProps
.discoveryMethodFlags
);
2580 (void) printLoginParameters(
2582 targetList
->oids
[j
],
2583 PRINT_NEGOTIATED_PARAMS
);
2585 /* Get Digest configuration */
2586 status
= SUN_IMA_GetConnProperties(
2587 &pConnList
->oids
[0], &connProps
);
2589 (void) getNegotiatedDigest(
2590 ISCSI_LOGIN_PARAM_HEADER_DIGEST
,
2591 &digestAlgorithms
, connProps
);
2593 if (IMA_SUCCESS(status
)) {
2594 (void) fprintf(stdout
, "\t\t \t%s: ",
2595 gettext("Header Digest"));
2596 printDigestAlgorithm(
2598 PRINT_NEGOTIATED_PARAMS
);
2600 (void) IMA_FreeMemory(pConnList
);
2601 (void) IMA_FreeMemory(targetList
);
2602 printLibError(status
);
2607 (void) getNegotiatedDigest(
2608 ISCSI_LOGIN_PARAM_DATA_DIGEST
,
2609 &digestAlgorithms
, connProps
);
2611 if (IMA_SUCCESS(status
)) {
2612 (void) fprintf(stdout
, "\t\t \t%s: ",
2613 gettext("Data Digest"));
2614 printDigestAlgorithm(
2616 PRINT_NEGOTIATED_PARAMS
);
2618 (void) IMA_FreeMemory(pConnList
);
2619 (void) IMA_FreeMemory(targetList
);
2620 printLibError(status
);
2625 (void) fprintf(stdout
, "\n");
2629 status
= SUN_IMA_ReEnumeration(
2630 targetList
->oids
[j
]);
2631 if (!IMA_SUCCESS(status
)) {
2633 * Proceeds the listing
2635 * error in return value
2640 status
= IMA_GetLuOidList(
2641 targetList
->oids
[j
],
2643 if (!IMA_SUCCESS(status
)) {
2644 printLibError(status
);
2645 (void) IMA_FreeMemory(targetList
);
2649 if (lunList
->oidCount
!= 0) {
2650 printTargetLuns(lunList
);
2652 (void) fprintf(stdout
, "\n");
2653 (void) IMA_FreeMemory(lunList
);
2657 * did we find the object
2660 if (operandEntered
&& !found
) {
2661 (void) fprintf(stdout
, "%s: %s\n",
2662 objects
[i
], gettext("not found"));
2666 (void) IMA_FreeMemory(targetList
);
2672 * Print configured session information
2675 printConfiguredSessions(IMA_OID oid
)
2679 SUN_IMA_CONFIG_SESSIONS
*pConfigSessions
;
2680 char address
[MAX_ADDRESS_LEN
];
2683 /* Get configured session information */
2684 status
= SUN_IMA_GetConfigSessions(oid
, &pConfigSessions
);
2686 if (IMA_SUCCESS(status
)) {
2687 (void) fprintf(stdout
, "\t%s: ",
2688 gettext("Configured Sessions"));
2689 if (pConfigSessions
->bound
== IMA_FALSE
) {
2690 /* default binding */
2691 (void) fprintf(stdout
, "%lu\n", pConfigSessions
->out
);
2693 /* hardcoded binding */
2695 out
< pConfigSessions
->out
; out
++) {
2696 if (pConfigSessions
->bindings
[out
].
2697 ipAddress
.ipv4Address
== IMA_TRUE
) {
2698 rtn
= inet_ntop(AF_INET
,
2699 pConfigSessions
->bindings
[out
].
2700 ipAddress
.ipAddress
, address
,
2703 rtn
= inet_ntop(AF_INET6
,
2704 pConfigSessions
->bindings
[out
].
2705 ipAddress
.ipAddress
, address
,
2709 (void) printf("%s ", address
);
2712 (void) fprintf(stdout
, "\n");
2715 free(pConfigSessions
);
2716 printLibError(status
);
2720 free(pConfigSessions
);
2725 * Print target parameters
2728 listTargetParam(int operandLen
, char *operand
[], cmdOptions_t
*options
,
2732 IMA_OID initiatorOid
;
2733 IMA_OID_LIST
*targetList
;
2734 IMA_AUTHMETHOD methodList
[MAX_AUTH_METHODS
];
2735 SUN_IMA_TARGET_PROPERTIES targetProps
;
2736 IMA_UINT maxEntries
= MAX_AUTH_METHODS
;
2739 wchar_t targetName
[MAX_ISCSI_NAME_LEN
+ 1];
2740 wchar_t targetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
2741 boolean_t operandEntered
= B_FALSE
;
2742 boolean_t targetAddressSpecified
= B_FALSE
;
2743 boolean_t printObject
= B_FALSE
;
2744 boolean_t tpgtSpecified
= B_FALSE
;
2745 boolean_t isIpv6
= B_FALSE
;
2749 SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms
;
2750 boolean_t verbose
= B_FALSE
;
2751 cmdOptions_t
*optionList
= options
;
2752 IMA_UINT16 port
= 0;
2753 IMA_UINT16 tpgt
= 0;
2755 assert(funcRet
!= NULL
);
2757 /* Find Sun initiator */
2758 ret
= sunInitiatorFind(&initiatorOid
);
2760 (void) fprintf(stderr
, "%s: %s\n",
2761 cmdName
, gettext("no initiator found"));
2768 for (; optionList
->optval
; optionList
++) {
2769 switch (optionList
->optval
) {
2774 (void) fprintf(stderr
, "%s: %c: %s\n",
2775 cmdName
, optionList
->optval
,
2776 gettext("unknown option"));
2782 * If there are multiple operands, execute outer 'for' loop that
2783 * many times to find each target parameter operand entered, otherwise,
2784 * execute it only once for all target parameters returned.
2786 if (operandLen
> 0) {
2787 operandEntered
= B_TRUE
;
2788 outerLoop
= operandLen
;
2790 operandEntered
= B_FALSE
;
2795 * Ideally there should be an interface available for obtaining
2796 * the list of target-param objects. Since the driver currently
2797 * creates a target OID and the associated session structure when
2798 * a target-param object is created, we can leverage the target
2799 * OID list and use it to manage the target-param objects. When
2800 * we stop creating a session for target-param object in the
2801 * driver, we will switch to using a different interface to
2802 * obtain target-param objects.
2804 status
= IMA_GetTargetOidList(initiatorOid
, &targetList
);
2805 if (!IMA_SUCCESS(status
)) {
2806 printLibError(status
);
2811 for (i
= 0; i
< outerLoop
; i
++) {
2812 if (operandEntered
) {
2813 if (parseTarget(operand
[i
],
2815 MAX_ISCSI_NAME_LEN
+ 1,
2816 &targetAddressSpecified
,
2818 SUN_IMA_IP_ADDRESS_PORT_LEN
,
2822 &isIpv6
) != PARSE_TARGET_OK
) {
2827 for (j
= 0; j
< targetList
->oidCount
; j
++) {
2829 printObject
= B_FALSE
;
2830 status
= SUN_IMA_GetTargetProperties(
2831 targetList
->oids
[j
],
2833 if (!IMA_SUCCESS(status
)) {
2834 printLibError(status
);
2835 (void) IMA_FreeMemory(targetList
);
2841 * Compare the target name with the input if
2844 if (operandEntered
&&
2845 (targetNamesEqual(targetProps
.imaProps
.name
,
2846 targetName
) == B_TRUE
)) {
2848 * For now, regardless of whether a target
2849 * address is specified, we return B_TRUE
2850 * because IMA_TARGET_PROPERTIES does not
2851 * have a field for specifying address.
2857 * if no operand was entered OR
2858 * an operand was entered and it was
2859 * found, we want to print
2861 if (!operandEntered
|| found
) {
2862 printObject
= B_TRUE
;
2866 (void) fprintf(stdout
, gettext("%s: %ws\n"),
2868 targetProps
.imaProps
.name
);
2870 (void) fprintf(stdout
,
2871 "\t%s: ", gettext("Alias"));
2872 if (wslen(targetProps
.imaProps
.alias
) >
2874 (void) fprintf(stdout
,
2876 targetProps
.imaProps
.alias
);
2878 (void) fprintf(stdout
, "%s\n", "-");
2882 if (printObject
&& verbose
) {
2883 /* Get bidirectional authentication flag */
2884 (void) fprintf(stdout
, "\t%s: ",
2885 gettext("Bi-directional Authentication"));
2886 status
= SUN_IMA_GetTargetBidirAuthFlag(
2887 targetList
->oids
[j
],
2889 if (IMA_SUCCESS(status
)) {
2890 if (bidirAuth
== IMA_TRUE
) {
2891 (void) fprintf(stdout
,
2892 gettext("enabled"));
2894 (void) fprintf(stdout
,
2895 gettext("disabled"));
2898 (void) fprintf(stdout
,
2899 gettext("disabled"));
2901 (void) fprintf(stdout
, "\n");
2903 /* Get authentication type for this target */
2904 status
= SUN_IMA_GetTargetAuthMethods(
2906 targetList
->oids
[j
],
2909 (void) fprintf(stdout
, "\t%s: ",
2910 gettext("Authentication Type"));
2911 if (!IMA_SUCCESS(status
)) {
2913 * No authentication method define
2916 (void) fprintf(stdout
, gettext("NONE"));
2918 for (i
= 0; i
< maxEntries
; i
++) {
2920 (void) fprintf(stdout
,
2923 switch (methodList
[i
]) {
2924 case IMA_AUTHMETHOD_NONE
:
2925 (void) fprintf(stdout
,
2929 case IMA_AUTHMETHOD_CHAP
:
2930 (void) fprintf(stdout
,
2938 (void) fprintf(stdout
,
2946 (void) fprintf(stdout
, "\n");
2947 if (printLoginParameters("\t",
2948 targetList
->oids
[j
],
2949 PRINT_CONFIGURED_PARAMS
)
2951 (void) IMA_FreeMemory(targetList
);
2956 /* Get Digest configuration */
2957 status
= SUN_IMA_GetHeaderDigest(
2958 targetList
->oids
[j
],
2960 if (IMA_SUCCESS(status
)) {
2961 (void) fprintf(stdout
, "\t\t%s: ",
2962 gettext("Header Digest"));
2963 printDigestAlgorithm(&digestAlgorithms
,
2964 PRINT_CONFIGURED_PARAMS
);
2966 printLibError(status
);
2971 status
= SUN_IMA_GetDataDigest(
2972 targetList
->oids
[j
],
2974 if (IMA_SUCCESS(status
)) {
2975 (void) fprintf(stdout
, "\t\t%s: ",
2976 gettext("Data Digest"));
2977 printDigestAlgorithm(&digestAlgorithms
,
2978 PRINT_CONFIGURED_PARAMS
);
2980 printLibError(status
);
2985 /* print tunable parameters infomation */
2986 if (printTunableParameters(
2987 targetList
->oids
[j
]) != 0) {
2992 /* print configured session information */
2993 if (printConfiguredSessions(
2994 targetList
->oids
[j
]) != 0) {
2999 (void) fprintf(stdout
, "\n");
3006 if (operandEntered
&& !found
) {
3007 *funcRet
= 1; /* DIY message fix */
3008 (void) fprintf(stdout
, "%s: %s\n",
3009 operand
[i
], gettext("not found"));
3013 (void) IMA_FreeMemory(targetList
);
3018 * Modify discovery attributes
3021 modifyDiscovery(cmdOptions_t
*options
, int *funcRet
)
3025 IMA_BOOL setDiscovery
;
3029 cmdOptions_t
*optionList
= options
;
3031 assert(funcRet
!= NULL
);
3033 /* Find Sun initiator */
3034 ret
= sunInitiatorFind(&oid
);
3036 (void) fprintf(stderr
, "%s: %s\n",
3037 cmdName
, gettext("no initiator found"));
3044 for (; optionList
->optval
; optionList
++) {
3045 /* check optarg and set bool accordingly */
3046 if (strcasecmp(optionList
->optarg
, ISCSIADM_ARG_ENABLE
) == 0) {
3047 setDiscovery
= IMA_TRUE
;
3048 } else if (strcasecmp(optionList
->optarg
, ISCSIADM_ARG_DISABLE
)
3050 setDiscovery
= IMA_FALSE
;
3052 (void) fprintf(stderr
, "%s: %s\n",
3053 cmdName
, gettext("invalid option argument"));
3057 switch (optionList
->optval
) {
3059 /* Set static discovery */
3060 status
= IMA_SetStaticDiscovery(oid
,
3062 if (!IMA_SUCCESS(status
)) {
3063 printLibError(status
);
3069 /* Set send targets discovery */
3070 status
= IMA_SetSendTargetsDiscovery(oid
,
3072 if (!IMA_SUCCESS(status
)) {
3073 printLibError(status
);
3079 /* Set iSNS discovery */
3080 (void) memset(&hostId
, 0, sizeof (hostId
));
3081 status
= IMA_SetIsnsDiscovery(oid
, setDiscovery
,
3082 IMA_ISNS_DISCOVERY_METHOD_STATIC
, &hostId
);
3083 if (!IMA_SUCCESS(status
)) {
3084 printLibError(status
);
3090 (void) fprintf(stderr
, "%s: %c: %s\n",
3091 cmdName
, optionList
->optval
,
3092 gettext("unknown option"));
3101 * Set the initiator node's authentication method
3104 modifyNodeAuthParam(IMA_OID oid
, int param
, char *chapName
, int *funcRet
)
3106 IMA_INITIATOR_AUTHPARMS authParams
;
3109 int secretLen
= MAX_CHAP_SECRET_LEN
;
3112 IMA_BYTE chapSecret
[MAX_CHAP_SECRET_LEN
+ 1];
3114 assert(funcRet
!= NULL
);
3117 * Start with existing parameters and modify with the desired change
3118 * before passing along. We ignore any failures as they probably
3119 * are caused by non-existence of auth params for the given node.
3121 status
= IMA_GetInitiatorAuthParms(oid
, IMA_AUTHMETHOD_CHAP
,
3126 if (chapName
== NULL
) {
3127 (void) fprintf(stderr
, "CHAP name cannot be NULL.\n");
3130 nameLen
= strlen(chapName
);
3132 (void) fprintf(stderr
, "CHAP name cannot be empty.\n");
3135 if (nameLen
> ISCSI_MAX_C_USER_LEN
) {
3136 (void) fprintf(stderr
, "CHAP name is too long.\n");
3139 (void) memset(&authParams
.chapParms
.name
, 0,
3140 sizeof (authParams
.chapParms
.name
));
3141 (void) memcpy(&authParams
.chapParms
.name
,
3142 &chapName
[0], nameLen
);
3143 authParams
.chapParms
.nameLength
= nameLen
;
3146 case AUTH_PASSWORD
:
3147 ret
= getSecret((char *)&chapSecret
[0], &secretLen
,
3148 MIN_CHAP_SECRET_LEN
, MAX_CHAP_SECRET_LEN
);
3154 (void) memset(&authParams
.chapParms
.challengeSecret
, 0,
3155 sizeof (authParams
.chapParms
.challengeSecret
));
3156 (void) memcpy(&authParams
.chapParms
.challengeSecret
,
3157 &chapSecret
[0], secretLen
);
3158 authParams
.chapParms
.challengeSecretLength
= secretLen
;
3162 (void) fprintf(stderr
, "Invalid auth parameter %d\n", param
);
3166 status
= IMA_SetInitiatorAuthParms(oid
, IMA_AUTHMETHOD_CHAP
,
3168 if (!IMA_SUCCESS(status
)) {
3169 printLibError(status
);
3176 * Set the target's authentication method
3179 modifyTargetAuthParam(IMA_OID oid
, int param
, char *chapName
, int *funcRet
)
3181 IMA_INITIATOR_AUTHPARMS authParams
;
3184 int secretLen
= MAX_CHAP_SECRET_LEN
;
3187 IMA_BYTE chapSecret
[MAX_CHAP_SECRET_LEN
+ 1];
3189 assert(funcRet
!= NULL
);
3192 * Start with existing parameters and modify with the desired change
3193 * before passing along. We ignore any get failures as they probably
3194 * are caused by non-existence of auth params for the given target.
3196 status
= SUN_IMA_GetTargetAuthParms(oid
, IMA_AUTHMETHOD_CHAP
,
3201 if (chapName
== NULL
) {
3202 (void) fprintf(stderr
, "CHAP name cannot be NULL.\n");
3205 nameLen
= strlen(chapName
);
3207 (void) fprintf(stderr
, "CHAP name cannot be empty.\n");
3210 if (nameLen
> ISCSI_MAX_C_USER_LEN
) {
3211 (void) fprintf(stderr
, "CHAP name is too long.\n");
3214 (void) memset(&authParams
.chapParms
.name
, 0,
3215 sizeof (authParams
.chapParms
.name
));
3216 (void) memcpy(&authParams
.chapParms
.name
,
3217 &chapName
[0], nameLen
);
3218 authParams
.chapParms
.nameLength
= nameLen
;
3221 case AUTH_PASSWORD
:
3222 ret
= getSecret((char *)&chapSecret
[0], &secretLen
,
3223 1, MAX_CHAP_SECRET_LEN
);
3229 (void) memset(&authParams
.chapParms
.challengeSecret
, 0,
3230 sizeof (authParams
.chapParms
.challengeSecret
));
3231 (void) memcpy(&authParams
.chapParms
.challengeSecret
,
3232 &chapSecret
[0], secretLen
);
3233 authParams
.chapParms
.challengeSecretLength
= secretLen
;
3237 (void) fprintf(stderr
, "Invalid auth parameter %d\n", param
);
3241 status
= SUN_IMA_SetTargetAuthParams(oid
, IMA_AUTHMETHOD_CHAP
,
3243 if (!IMA_SUCCESS(status
)) {
3244 printLibError(status
);
3251 modifyTargetBidirAuthFlag(IMA_OID targetOid
, char *optarg
, int *funcRet
)
3256 assert(funcRet
!= NULL
);
3258 if (strcasecmp(optarg
, ISCSIADM_ARG_ENABLE
) == 0) {
3259 boolValue
= IMA_TRUE
;
3260 } else if (strcasecmp(optarg
, ISCSIADM_ARG_DISABLE
) == 0) {
3261 boolValue
= IMA_FALSE
;
3263 (void) fprintf(stderr
, "%s: %s %s\n",
3264 cmdName
, gettext("invalid option argument"), optarg
);
3268 status
= SUN_IMA_SetTargetBidirAuthFlag(targetOid
, &boolValue
);
3269 if (!IMA_SUCCESS(status
)) {
3270 printLibError(status
);
3277 modifyConfiguredSessions(IMA_OID targetOid
, char *optarg
)
3279 SUN_IMA_CONFIG_SESSIONS
*pConfigSessions
;
3284 boolean_t isIpv6
= B_FALSE
;
3286 char address
[MAX_ADDRESS_LEN
];
3292 * Strip the first int value from the string. If we sprintf
3293 * this back to a string and it matches the original string
3294 * then this command is using default binding. If not a
3295 * match we have hard coded binding or a usage error.
3297 sessions
= atoi(optarg
);
3298 (void) sprintf(tmp
, "%d", sessions
);
3299 if (strcmp(optarg
, tmp
) == 0) {
3300 /* default binding */
3302 /* allocate the required pConfigSessions */
3303 size
= sizeof (SUN_IMA_CONFIG_SESSIONS
);
3304 pConfigSessions
= (SUN_IMA_CONFIG_SESSIONS
*)calloc(1, size
);
3305 if (pConfigSessions
== NULL
) {
3309 /* setup pConfigSessions */
3310 pConfigSessions
->bound
= IMA_FALSE
;
3311 pConfigSessions
->in
= sessions
;
3312 pConfigSessions
->out
= 0;
3314 /* hardcoded binding */
3317 * First we need to determine how many bindings
3318 * are available. This can be done by scanning
3319 * for the number of ',' + 1.
3322 commaPos
= strchr(optarg
, ',');
3323 while (commaPos
!= NULL
) {
3325 commaPos
= strchr(++commaPos
, ',');
3328 /* allocate the required pConfigSessions */
3329 size
= sizeof (SUN_IMA_CONFIG_SESSIONS
) + ((sessions
- 1) *
3330 sizeof (IMA_ADDRESS_KEY
));
3331 pConfigSessions
= (SUN_IMA_CONFIG_SESSIONS
*)calloc(1, size
);
3332 if (pConfigSessions
== NULL
) {
3336 /* setup pConfigSessions */
3337 pConfigSessions
->bound
= IMA_TRUE
;
3338 pConfigSessions
->in
= sessions
;
3339 pConfigSessions
->out
= 0;
3341 /* Now fill in the binding information. */
3343 addressPos
= optarg
;
3345 * Walk thru possible address strings
3346 * stop once all strings are processed.
3348 while (addressPos
!= NULL
) {
3350 * Check if there is another address after this
3351 * one. If so terminate the current address and
3352 * keep a pointer to the next one.
3354 commaPos
= strchr(addressPos
, ',');
3355 if (commaPos
!= NULL
) {
3360 * Parse current address. If invalid abort
3361 * processing of addresses and free memory.
3363 if (parseAddress(addressPos
, 0, address
,
3364 MAX_ADDRESS_LEN
, &port
, &isIpv6
) != PARSE_ADDR_OK
) {
3365 free(pConfigSessions
);
3366 printLibError(IMA_ERROR_INVALID_PARAMETER
);
3370 /* Convert address into binary form */
3371 if (isIpv6
== B_FALSE
) {
3372 pConfigSessions
->bindings
[sessions
].
3373 ipAddress
.ipv4Address
= IMA_TRUE
;
3374 rtn
= inet_pton(AF_INET
, address
,
3375 pConfigSessions
->bindings
[sessions
].
3376 ipAddress
.ipAddress
);
3378 pConfigSessions
->bindings
[sessions
].ipAddress
.
3381 rtn
= inet_pton(AF_INET6
, address
,
3382 pConfigSessions
->bindings
[sessions
].
3383 ipAddress
.ipAddress
);
3386 /* inet_pton found address invalid */
3387 free(pConfigSessions
);
3388 printLibError(IMA_ERROR_INVALID_PARAMETER
);
3392 /* update addressPos to next address */
3394 addressPos
= commaPos
;
3398 /* issue SUN_IMA request */
3399 status
= SUN_IMA_SetConfigSessions(targetOid
,
3401 if (!IMA_SUCCESS(status
)) {
3402 printLibError(status
);
3403 free(pConfigSessions
);
3407 free(pConfigSessions
);
3412 getAuthMethodValue(char *method
, IMA_AUTHMETHOD
*value
)
3414 if (strcasecmp(method
, "chap") == 0) {
3415 *value
= IMA_AUTHMETHOD_CHAP
;
3419 if (strcasecmp(method
, "none") == 0) {
3420 *value
= IMA_AUTHMETHOD_NONE
;
3429 * Set the authentication method
3430 * Currently only supports CHAP and NONE
3433 modifyNodeAuthMethod(IMA_OID oid
, char *optarg
, int *funcRet
)
3435 IMA_AUTHMETHOD methodList
[MAX_AUTH_METHODS
];
3436 IMA_UINT methodCount
= 0;
3438 IMA_AUTHMETHOD value
;
3442 assert(funcRet
!= NULL
);
3445 * optarg will be a , delimited set of auth methods, in order
3447 * if any values here are incorrect, return without setting
3452 commaPos
= strchr(optarg
, ',');
3454 while (commaPos
&& methodCount
< MAX_AUTH_METHODS
) {
3456 if (getAuthMethodValue(method
, &value
) != 0) {
3457 (void) fprintf(stderr
, "%s: a: %s\n",
3458 cmdName
, gettext("invalid option argument"));
3461 methodList
[methodCount
++] = value
;
3464 commaPos
= strchr(method
, ',');
3466 /* Should not find more method specified - if found, error */
3468 (void) fprintf(stderr
, "%s: -a: %s\n",
3469 cmdName
, gettext("invalid option argument"));
3472 if (getAuthMethodValue(method
, &value
) != 0) {
3473 (void) fprintf(stderr
, "%s: -a: %s\n",
3474 cmdName
, gettext("invalid option argument"));
3477 methodList
[methodCount
++] = value
;
3479 status
= IMA_SetInitiatorAuthMethods(oid
, methodCount
, &methodList
[0]);
3480 if (!IMA_SUCCESS(status
)) {
3481 printLibError(status
);
3488 modifyTargetAuthMethod(IMA_OID oid
, char *optarg
, int *funcRet
)
3490 IMA_AUTHMETHOD methodList
[MAX_AUTH_METHODS
];
3491 IMA_UINT methodCount
= 0;
3493 IMA_AUTHMETHOD value
;
3497 assert(funcRet
!= NULL
);
3500 * optarg will be a , delimited set of auth methods, in order
3502 * if any values here are incorrect, return without setting
3507 commaPos
= strchr(optarg
, ',');
3509 while (commaPos
&& methodCount
< MAX_AUTH_METHODS
) {
3511 if (getAuthMethodValue(method
, &value
) != 0) {
3512 (void) fprintf(stderr
, "%s: a: %s\n",
3513 cmdName
, gettext("invalid option argument"));
3516 methodList
[methodCount
++] = value
;
3519 commaPos
= strchr(method
, ',');
3521 /* Should not find more method specified - if found, error */
3523 (void) fprintf(stderr
, "%s: -a: %s\n",
3524 cmdName
, gettext("invalid option argument"));
3527 if (getAuthMethodValue(method
, &value
) != 0) {
3528 (void) fprintf(stderr
, "%s: -a: %s\n",
3529 cmdName
, gettext("invalid option argument"));
3532 methodList
[methodCount
++] = value
;
3534 status
= SUN_IMA_SetTargetAuthMethods(oid
, &methodCount
,
3536 if (!IMA_SUCCESS(status
)) {
3537 printLibError(status
);
3544 * Modify the RADIUS configuration of the initiator node.
3546 * Return 0 on success.
3549 modifyNodeRadiusConfig(IMA_OID oid
, char *optarg
, int *funcRet
)
3551 SUN_IMA_RADIUS_CONFIG config
;
3553 boolean_t isIpv6
= B_FALSE
;
3556 assert(funcRet
!= NULL
);
3558 (void) memset(&config
, 0, sizeof (SUN_IMA_RADIUS_CONFIG
));
3559 if (parseAddress(optarg
, DEFAULT_RADIUS_PORT
,
3560 &config
.hostnameIpAddress
[0], SUN_IMA_IP_ADDRESS_PORT_LEN
,
3565 config
.port
= (IMA_UINT16
)port
;
3566 config
.isIpv6
= (isIpv6
== B_TRUE
) ? IMA_TRUE
: IMA_FALSE
;
3567 /* Not setting shared secret here. */
3568 config
.sharedSecretValid
= IMA_FALSE
;
3570 status
= SUN_IMA_SetInitiatorRadiusConfig(oid
, &config
);
3571 if (!IMA_SUCCESS(status
)) {
3572 printLibError(status
);
3580 * Modify the RADIUS access flag of the initiator node.
3582 * Return 0 on success.
3585 modifyNodeRadiusAccess(IMA_OID oid
, char *optarg
, int *funcRet
)
3587 IMA_BOOL radiusAccess
;
3588 IMA_OID initiatorOid
;
3590 SUN_IMA_RADIUS_CONFIG radiusConfig
;
3593 assert(funcRet
!= NULL
);
3595 /* Check if Radius Config is there */
3596 ret
= sunInitiatorFind(&initiatorOid
);
3598 (void) fprintf(stderr
, "%s: %s\n",
3599 cmdName
, gettext("no initiator found"));
3602 (void) memset(&radiusConfig
, 0, sizeof (SUN_IMA_RADIUS_CONFIG
));
3603 status
= SUN_IMA_GetInitiatorRadiusConfig(initiatorOid
, &radiusConfig
);
3604 if (!IMA_SUCCESS(status
)) {
3605 (void) fprintf(stderr
, "%s: %s\n",
3606 cmdName
, gettext("RADIUS server not configured yet"));
3611 /* Check if Radius Shared is set */
3612 if (radiusConfig
.sharedSecretValid
== IMA_FALSE
) {
3613 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
3614 gettext("RADIUS server secret not configured yet"));
3618 if (strcasecmp(optarg
, ISCSIADM_ARG_ENABLE
) == 0) {
3619 radiusAccess
= IMA_TRUE
;
3620 } else if (strcasecmp(optarg
, ISCSIADM_ARG_DISABLE
) == 0) {
3621 radiusAccess
= IMA_FALSE
;
3623 (void) fprintf(stderr
, "%s: %s %s\n",
3625 gettext("invalid option argument"),
3629 status
= SUN_IMA_SetInitiatorRadiusAccess(oid
, radiusAccess
);
3630 if (!IMA_SUCCESS(status
)) {
3631 printLibError(status
);
3639 * Modify the RADIUS shared secret.
3646 modifyNodeRadiusSharedSecret(IMA_OID oid
, int *funcRet
)
3648 IMA_BYTE radiusSharedSecret
[SUN_IMA_MAX_RADIUS_SECRET_LEN
+ 1];
3649 IMA_OID initiatorOid
;
3651 SUN_IMA_RADIUS_CONFIG radiusConfig
;
3653 int secretLen
= SUN_IMA_MAX_RADIUS_SECRET_LEN
;
3655 assert(funcRet
!= NULL
);
3657 ret
= getSecret((char *)&radiusSharedSecret
[0], &secretLen
,
3658 0, SUN_IMA_MAX_RADIUS_SECRET_LEN
);
3663 ret
= sunInitiatorFind(&initiatorOid
);
3665 (void) fprintf(stderr
, "%s: %s\n",
3666 cmdName
, gettext("no initiator found"));
3671 /* First obtain existing RADIUS configuration (if any) */
3672 (void) memset(&radiusConfig
, 0, sizeof (SUN_IMA_RADIUS_CONFIG
));
3673 status
= SUN_IMA_GetInitiatorRadiusConfig(initiatorOid
, &radiusConfig
);
3674 if (!IMA_SUCCESS(status
)) {
3675 (void) fprintf(stderr
, "%s: %s\n",
3676 cmdName
, gettext("RADIUS server not configured yet"));
3680 /* Modify the shared secret only */
3681 radiusConfig
.sharedSecretLength
= secretLen
;
3682 (void) memcpy(&radiusConfig
.sharedSecret
,
3683 &radiusSharedSecret
[0], secretLen
);
3684 radiusConfig
.sharedSecretValid
= IMA_TRUE
;
3685 status
= SUN_IMA_SetInitiatorRadiusConfig(oid
, &radiusConfig
);
3686 if (!IMA_SUCCESS(status
)) {
3687 printLibError(status
);
3695 * Set initiator node attributes.
3698 modifyNode(cmdOptions_t
*options
, int *funcRet
)
3700 IMA_NODE_NAME nodeName
;
3701 IMA_NODE_ALIAS nodeAlias
;
3704 cmdOptions_t
*optionList
= options
;
3706 iSCSINameCheckStatusType nameCheckStatus
;
3707 IMA_OID sharedNodeOid
;
3710 IMA_BOOL iscsiBoot
= IMA_FALSE
;
3711 IMA_BOOL mpxioEnabled
= IMA_FALSE
;
3712 char *mb_name
= NULL
;
3715 assert(funcRet
!= NULL
);
3717 /* Get boot session's info */
3718 (void) SUN_IMA_GetBootIscsi(&iscsiBoot
);
3719 if (iscsiBoot
== IMA_TRUE
) {
3720 status
= SUN_IMA_GetBootMpxio(&mpxioEnabled
);
3721 if (!IMA_SUCCESS(status
)) {
3722 (void) fprintf(stderr
, "%s: %s\n",
3723 cmdName
, gettext("unable to get MPxIO info"
3730 /* Find Sun initiator */
3731 ret
= sunInitiatorFind(&oid
);
3733 (void) fprintf(stderr
, "%s: %s\n",
3734 cmdName
, gettext("no initiator found"));
3738 for (; optionList
->optval
; optionList
++) {
3739 switch (optionList
->optval
) {
3741 if (strlen(optionList
->optarg
) >=
3742 MAX_ISCSI_NAME_LEN
) {
3743 (void) fprintf(stderr
, "%s: %s %d\n",
3745 gettext("name too long, \
3746 maximum length is:"),
3747 MAX_ISCSI_NAME_LEN
);
3750 /* Take the first operand as node name. */
3751 (void) memset(&nodeName
, 0,
3752 sizeof (IMA_NODE_NAME
));
3753 if (mbstowcs(nodeName
, optionList
->optarg
,
3754 IMA_NODE_NAME_LEN
) == (size_t)-1) {
3755 (void) fprintf(stderr
, "%s: %s\n",
3757 gettext("conversion error"));
3761 prefixlen
= strlen(ISCSI_IQN_NAME_PREFIX
);
3762 mb_name
= (char *)calloc(1, prefixlen
+ 1);
3763 if (mb_name
== NULL
) {
3767 if (wcstombs(mb_name
, nodeName
,
3768 prefixlen
) == (size_t)-1) {
3769 (void) fprintf(stderr
, "%s: %s\n",
3771 gettext("conversion error"));
3772 (void) IMA_FreeMemory(mb_name
);
3775 if (strncmp(mb_name
, ISCSI_IQN_NAME_PREFIX
,
3778 * For iqn format, we should map
3779 * the upper-case characters to
3780 * their lower-case equivalents.
3782 for (i
= 0; nodeName
[i
] != 0; i
++) {
3784 tolower(nodeName
[i
]);
3785 nodeName
[i
] = lowerCase
;
3788 (void) IMA_FreeMemory(mb_name
);
3790 /* Perform string profile checks */
3792 iSCSINameStringProfileCheck(nodeName
);
3793 iSCSINameCheckStatusDisplay(nameCheckStatus
);
3794 if (nameCheckStatus
!= iSCSINameCheckOK
) {
3795 *funcRet
= 1; /* DIY message fix */
3800 * IMA_GetSharedNodeOid(&sharedNodeOid);
3801 * if (!IMA_SUCCESS(status)) {
3802 * printLibError(status);
3803 * return (INF_ERROR);
3806 if (iscsiBoot
== IMA_TRUE
) {
3807 (void) fprintf(stderr
, "%s: %s\n",
3808 cmdName
, gettext("iscsi boot, not"
3809 " allowed to change"
3810 " initiator's name"));
3813 oid
.objectType
= IMA_OBJECT_TYPE_NODE
;
3814 status
= IMA_SetNodeName(oid
, nodeName
);
3815 if (!IMA_SUCCESS(status
)) {
3816 printLibError(status
);
3823 if (iscsiBoot
== IMA_TRUE
) {
3824 (void) fprintf(stderr
, "%s: %s\n",
3825 cmdName
, gettext("iscsi boot, not"
3826 " allowed to change"
3827 " initiator's alias"));
3830 /* Take the first operand as node alias. */
3831 if (strlen(optionList
->optarg
) >=
3832 MAX_ISCSI_NAME_LEN
) {
3833 (void) fprintf(stderr
, "%s: %s %d\n",
3835 gettext("alias too long, maximum \
3837 MAX_ISCSI_NAME_LEN
);
3840 (void) memset(&nodeAlias
, 0,
3841 sizeof (IMA_NODE_ALIAS
));
3842 if (mbstowcs(nodeAlias
, optionList
->optarg
,
3843 IMA_NODE_ALIAS_LEN
) == (size_t)-1) {
3844 (void) fprintf(stderr
, "%s: %s\n",
3846 gettext("conversion error"));
3850 status
= IMA_GetSharedNodeOid(&sharedNodeOid
);
3851 if (!IMA_SUCCESS(status
)) {
3852 printLibError(status
);
3857 status
= IMA_SetNodeAlias(sharedNodeOid
,
3859 if (!IMA_SUCCESS(status
)) {
3860 printLibError(status
);
3867 if (iscsiBoot
== IMA_TRUE
) {
3868 (void) fprintf(stderr
, "%s: %s\n",
3869 cmdName
, gettext("iscsi boot, not"
3870 " allowed to change authentication"
3874 if (modifyNodeAuthMethod(oid
, options
->optarg
,
3881 if (modifyNodeRadiusAccess(oid
, options
->optarg
,
3888 if (modifyNodeRadiusConfig(oid
, options
->optarg
,
3895 if (modifyNodeRadiusSharedSecret(oid
, funcRet
)
3902 if (iscsiBoot
== IMA_TRUE
) {
3903 (void) fprintf(stderr
, "%s: %s\n",
3904 cmdName
, gettext("iscsi boot, not"
3905 " allowed to change CHAP secret"));
3908 if (modifyNodeAuthParam(oid
, AUTH_PASSWORD
,
3909 NULL
, funcRet
) != 0) {
3915 if (iscsiBoot
== IMA_TRUE
) {
3916 if (mpxioEnabled
== IMA_FALSE
) {
3917 (void) fprintf(stderr
,
3918 "%s: %s\n", cmdName
,
3921 " is disabled, not allowed"
3922 " to change number of"
3928 if (modifyConfiguredSessions(oid
,
3929 optionList
->optarg
) != 0) {
3930 if (iscsiBoot
== IMA_TRUE
) {
3931 (void) fprintf(stderr
,
3932 "%s: %s\n", cmdName
,
3933 gettext("iscsi boot,"
3934 " fail to set configured"
3943 if (iscsiBoot
== IMA_TRUE
) {
3944 (void) fprintf(stderr
, "%s: %s\n",
3945 cmdName
, gettext("iscsi boot, not"
3946 " allowed to change CHAP name"));
3949 if (modifyNodeAuthParam(oid
, AUTH_NAME
,
3950 optionList
->optarg
, funcRet
) != 0) {
3957 if (iscsiBoot
== IMA_TRUE
) {
3958 if (mpxioEnabled
== IMA_FALSE
) {
3959 (void) fprintf(stderr
,
3960 "%s: %s\n", cmdName
,
3965 " change initiator's"
3970 if (setLoginParameter(oid
, DATA_DIGEST
,
3971 optionList
->optarg
) != 0) {
3977 if (iscsiBoot
== IMA_TRUE
) {
3978 if (mpxioEnabled
== IMA_FALSE
) {
3979 (void) fprintf(stderr
,
3980 "%s: %s\n", cmdName
,
3985 " change initiator's"
3990 if (setLoginParameter(oid
, HEADER_DIGEST
,
3991 optionList
->optarg
) != 0) {
3997 if (setTunableParameters(oid
,
3998 optionList
->optarg
) != 0) {
4003 (void) fprintf(stderr
, "%s: %c: %s\n",
4004 cmdName
, optionList
->optval
,
4005 gettext("unknown option"));
4014 * Modify target parameters
4017 modifyTargetParam(cmdOptions_t
*options
, char *targetName
, int *funcRet
)
4022 IMA_OID_LIST
*targetList
;
4023 SUN_IMA_TARGET_PROPERTIES targetProps
;
4024 wchar_t wcInputObject
[MAX_ISCSI_NAME_LEN
+ 1];
4025 wchar_t targetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
4028 boolean_t targetAddressSpecified
= B_TRUE
;
4029 boolean_t tpgtSpecified
= B_FALSE
;
4030 boolean_t isIpv6
= B_FALSE
;
4032 iSCSINameCheckStatusType nameCheckStatus
;
4033 IMA_UINT16 port
= 0;
4034 IMA_UINT16 tpgt
= 0;
4036 IMA_NODE_NAME bootTargetName
;
4037 IMA_INITIATOR_AUTHPARMS bootTargetCHAP
;
4039 IMA_BOOL mpxioEnabled
;
4041 cmdOptions_t
*optionList
= options
;
4043 assert(funcRet
!= NULL
);
4045 /* Find Sun initiator */
4046 ret
= sunInitiatorFind(&oid
);
4048 (void) fprintf(stderr
, "%s: %s\n",
4049 cmdName
, gettext("no initiator found"));
4056 if (parseTarget(targetName
,
4058 MAX_ISCSI_NAME_LEN
+ 1,
4059 &targetAddressSpecified
,
4061 SUN_IMA_IP_ADDRESS_PORT_LEN
,
4065 &isIpv6
) != PARSE_TARGET_OK
) {
4069 /* Perform string profile checks */
4070 nameCheckStatus
= iSCSINameStringProfileCheck(wcInputObject
);
4071 iSCSINameCheckStatusDisplay(nameCheckStatus
);
4072 if (nameCheckStatus
!= iSCSINameCheckOK
) {
4076 status
= IMA_GetTargetOidList(oid
, &targetList
);
4077 if (!IMA_SUCCESS(status
)) {
4078 printLibError(status
);
4083 (void) SUN_IMA_GetBootIscsi(&iscsiBoot
);
4084 if (iscsiBoot
== IMA_TRUE
) {
4085 status
= SUN_IMA_GetBootMpxio(&mpxioEnabled
);
4086 if (!IMA_SUCCESS(status
)) {
4087 (void) fprintf(stderr
, "%s: %s\n",
4088 cmdName
, gettext("unable to get MPxIO info"
4093 status
= SUN_IMA_GetBootTargetName(bootTargetName
);
4094 if (!IMA_SUCCESS(status
)) {
4095 (void) fprintf(stderr
, "%s: %s\n",
4096 cmdName
, gettext("unable to get boot target's"
4101 status
= SUN_IMA_GetBootTargetAuthParams(&bootTargetCHAP
);
4102 if (!IMA_SUCCESS(status
)) {
4103 (void) fprintf(stderr
, "%s: %s\n",
4104 cmdName
, gettext("unable to get boot target's"
4111 /* find target oid */
4112 for (found
= B_FALSE
, i
= 0; i
< targetList
->oidCount
; i
++) {
4113 status
= SUN_IMA_GetTargetProperties(targetList
->oids
[i
],
4115 if (!IMA_SUCCESS(status
)) {
4116 printLibError(status
);
4117 (void) IMA_FreeMemory(targetList
);
4123 * Compare the target name with the input name
4125 if ((targetNamesEqual(wcInputObject
, targetProps
.imaProps
.name
)
4128 * For now, regardless of whether a target address
4129 * is specified, we return B_TRUE because
4130 * IMA_TARGET_PROPERTIES does not have a field for
4131 * specifying address.
4134 targetOid
= targetList
->oids
[i
];
4136 if ((targetNamesEqual(bootTargetName
, wcInputObject
)
4137 == B_TRUE
) && (iscsiBoot
== IMA_TRUE
)) {
4139 * iscsi booting, need changed target param is
4140 * booting target, for auth param, not allow
4141 * to change, for others dependent on mpxio
4144 if ((optionList
->optval
== 'C') ||
4145 (optionList
->optval
== 'H') ||
4146 (optionList
->optval
== 'B') ||
4147 (optionList
->optval
== 'a')) {
4149 * -C CHAP secret set
4152 * -B bi-directional-authentication
4154 (void) fprintf(stderr
, "%s: %s\n",
4155 cmdName
, gettext("iscsi boot,"
4156 " not allowed to modify"
4157 " authentication parameters"
4158 " of boot target"));
4161 if (mpxioEnabled
== IMA_FALSE
) {
4162 (void) fprintf(stderr
, "%s: %s\n",
4163 cmdName
, gettext("iscsi boot and"
4164 " MPxIO is disabled, not allowed"
4165 " to modify boot target's"
4172 if (modifyIndividualTargetParam(optionList
, targetOid
,
4178 * Even after finding a matched target, keep going
4179 * since there could be multiple target objects
4180 * associated with one target name in the system
4181 * because of different TPGTs.
4186 /* If the target OID cannot be found create one */
4188 status
= SUN_IMA_CreateTargetOid(wcInputObject
, &targetOid
);
4189 if (!IMA_SUCCESS(status
)) {
4190 printLibError(status
);
4191 (void) IMA_FreeMemory(targetList
);
4195 if (modifyIndividualTargetParam(optionList
, targetOid
,
4201 (void) IMA_FreeMemory(targetList
);
4206 * Add one or more addresses
4209 addAddress(int addrType
, int operandLen
, char *operand
[], int *funcRet
)
4212 IMA_OID oid
, addressOid
;
4213 SUN_IMA_TARGET_ADDRESS address
;
4214 wchar_t wcInputObject
[MAX_ADDRESS_LEN
+ 1];
4218 assert(funcRet
!= NULL
);
4220 /* Find Sun initiator */
4221 ret
= sunInitiatorFind(&oid
);
4223 (void) fprintf(stderr
, "%s: %s\n",
4224 cmdName
, gettext("no initiator found"));
4232 * Format of discovery address operand:
4234 * <IP address|hostname>:<port>
4236 for (i
= 0; i
< operandLen
; i
++) {
4238 (void) memset(&wcInputObject
[0], 0, sizeof (wcInputObject
));
4239 (void) memset(&address
, 0, sizeof (address
));
4241 if (mbstowcs(wcInputObject
, operand
[i
],
4242 (MAX_ADDRESS_LEN
+ 1)) == (size_t)-1) {
4243 (void) fprintf(stderr
, "%s: %s\n",
4244 cmdName
, gettext("conversion error"));
4248 if (getTargetAddress(addrType
, operand
[i
], &address
.imaStruct
)
4253 if (addrType
== DISCOVERY_ADDRESS
) {
4254 status
= IMA_AddDiscoveryAddress(oid
,
4255 address
.imaStruct
, &addressOid
);
4256 if (!IMA_SUCCESS(status
)) {
4257 printLibError(status
);
4261 } else if (addrType
== ISNS_SERVER_ADDRESS
) {
4262 status
= SUN_IMA_AddISNSServerAddress(address
);
4263 if (!IMA_SUCCESS(status
)) {
4264 printLibError(status
);
4274 * Add one or more static configuration targets
4277 addStaticConfig(int operandLen
, char *operand
[], int *funcRet
)
4280 boolean_t targetAddressSpecified
= B_FALSE
;
4281 boolean_t tpgtSpecified
= B_FALSE
;
4282 boolean_t isIpv6
= B_FALSE
;
4287 SUN_IMA_STATIC_DISCOVERY_TARGET staticConfig
;
4288 IMA_UINT16 port
= 0;
4289 IMA_UINT16 tpgt
= 0;
4290 wchar_t staticTargetName
[MAX_ISCSI_NAME_LEN
+ 1];
4291 wchar_t staticTargetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
4292 iSCSINameCheckStatusType nameCheckStatus
;
4293 char sAddr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
4295 assert(funcRet
!= NULL
);
4297 /* Find Sun initiator */
4298 ret
= sunInitiatorFind(&oid
);
4300 (void) fprintf(stderr
, "%s: %s\n",
4301 cmdName
, gettext("no initiator found"));
4309 * Format of static config operand:
4310 * <target-name>,<IP address|hostname>[:port][,tpgt]
4312 for (i
= 0; i
< operandLen
; i
++) {
4313 if (parseTarget(operand
[i
],
4314 &staticTargetName
[0],
4315 MAX_ISCSI_NAME_LEN
+ 1,
4316 &targetAddressSpecified
,
4317 &staticTargetAddress
[0],
4318 SUN_IMA_IP_ADDRESS_PORT_LEN
,
4322 &isIpv6
) != PARSE_TARGET_OK
) {
4327 if (targetAddressSpecified
!= B_TRUE
) {
4328 (void) fprintf(stderr
, "%s: %s\n",
4329 cmdName
, gettext("missing target address"));
4330 *funcRet
= 1; /* DIY message fix */
4333 /* Perform string profile checks */
4334 nameCheckStatus
= iSCSINameStringProfileCheck(staticTargetName
);
4335 iSCSINameCheckStatusDisplay(nameCheckStatus
);
4336 if (nameCheckStatus
!= iSCSINameCheckOK
) {
4337 *funcRet
= 1; /* DIY message fix */
4340 (void) wcsncpy(staticConfig
.targetName
, staticTargetName
,
4341 MAX_ISCSI_NAME_LEN
+ 1);
4343 (void) wcstombs(sAddr
, staticTargetAddress
, sizeof (sAddr
));
4345 if (isIpv6
== B_TRUE
) {
4346 staticConfig
.targetAddress
.imaStruct
.hostnameIpAddress
.
4347 id
.ipAddress
.ipv4Address
= B_FALSE
;
4348 addrType
= AF_INET6
;
4350 staticConfig
.targetAddress
.imaStruct
.hostnameIpAddress
.
4351 id
.ipAddress
.ipv4Address
= B_TRUE
;
4355 if (inet_pton(addrType
, sAddr
, staticConfig
.targetAddress
.
4356 imaStruct
.hostnameIpAddress
.id
.ipAddress
.ipAddress
) != 1) {
4357 (void) fprintf(stderr
, "%s: %s\n",
4358 cmdName
, gettext("static config conversion error"));
4363 staticConfig
.targetAddress
.imaStruct
.portNumber
= port
;
4364 if (tpgtSpecified
== B_TRUE
) {
4365 staticConfig
.targetAddress
.defaultTpgt
= B_FALSE
;
4366 staticConfig
.targetAddress
.tpgt
= tpgt
;
4368 staticConfig
.targetAddress
.defaultTpgt
= B_TRUE
;
4369 staticConfig
.targetAddress
.tpgt
= 0;
4372 status
= SUN_IMA_AddStaticTarget(oid
, staticConfig
, &oid
);
4373 if (!IMA_SUCCESS(status
)) {
4374 printLibError(status
);
4388 * Remove one or more addresses
4391 removeAddress(int addrType
, int operandLen
, char *operand
[], int *funcRet
)
4394 IMA_OID initiatorOid
;
4395 SUN_IMA_TARGET_ADDRESS address
;
4396 wchar_t wcInputObject
[MAX_ADDRESS_LEN
+ 1];
4400 assert(funcRet
!= NULL
);
4402 /* Find Sun initiator */
4403 ret
= sunInitiatorFind(&initiatorOid
);
4405 (void) fprintf(stderr
, "%s: %s\n",
4406 cmdName
, gettext("no initiator found"));
4413 for (i
= 0; i
< operandLen
; i
++) {
4415 (void) memset(&wcInputObject
[0], 0, sizeof (wcInputObject
));
4416 (void) memset(&address
, 0, sizeof (address
));
4418 if (mbstowcs(wcInputObject
, operand
[i
],
4419 MAX_ADDRESS_LEN
+ 1) == (size_t)-1) {
4420 (void) fprintf(stderr
, "%s: %s\n",
4421 cmdName
, gettext("conversion error"));
4426 if (getTargetAddress(addrType
, operand
[i
], &address
.imaStruct
)
4432 if (addrType
== DISCOVERY_ADDRESS
) {
4433 status
= SUN_IMA_RemoveDiscoveryAddress(address
);
4434 if (!IMA_SUCCESS(status
)) {
4435 if (status
== IMA_ERROR_OBJECT_NOT_FOUND
) {
4436 (void) fprintf(stderr
, "%s: %s\n",
4437 operand
[i
], gettext("not found"));
4439 printLibError(status
);
4444 status
= SUN_IMA_RemoveISNSServerAddress(address
);
4445 if (!IMA_SUCCESS(status
)) {
4446 printLibError(status
);
4455 * Remove one or more static configuration targets
4458 removeStaticConfig(int operandLen
, char *operand
[], int *funcRet
)
4461 IMA_OID initiatorOid
;
4462 IMA_OID_LIST
*staticTargetList
;
4463 SUN_IMA_STATIC_TARGET_PROPERTIES staticTargetProps
;
4464 wchar_t staticTargetName
[MAX_ISCSI_NAME_LEN
+ 1];
4465 wchar_t staticTargetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
4467 boolean_t atLeastFoundOne
;
4469 boolean_t targetAddressSpecified
= B_TRUE
;
4470 boolean_t tpgtSpecified
= B_FALSE
;
4471 boolean_t isIpv6
= B_FALSE
;
4473 IMA_UINT16 port
= 0;
4474 IMA_UINT16 tpgt
= 0;
4475 iSCSINameCheckStatusType nameCheckStatus
;
4476 char tmpStr
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
4477 wchar_t tmpTargetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
4479 assert(funcRet
!= NULL
);
4481 /* Find Sun initiator */
4482 ret
= sunInitiatorFind(&initiatorOid
);
4484 (void) fprintf(stderr
, "%s: %s\n",
4485 cmdName
, gettext("no initiator found"));
4492 status
= IMA_GetStaticDiscoveryTargetOidList(initiatorOid
,
4494 if (!IMA_SUCCESS(status
)) {
4495 printLibError(status
);
4500 for (i
= 0; i
< operandLen
; i
++) {
4501 if (parseTarget(operand
[i
],
4502 &staticTargetName
[0],
4503 MAX_ISCSI_NAME_LEN
+ 1,
4504 &targetAddressSpecified
,
4505 &staticTargetAddress
[0],
4506 SUN_IMA_IP_ADDRESS_PORT_LEN
,
4510 &isIpv6
) != PARSE_TARGET_OK
) {
4515 /* Perform string profile checks */
4516 nameCheckStatus
= iSCSINameStringProfileCheck(staticTargetName
);
4517 iSCSINameCheckStatusDisplay(nameCheckStatus
);
4518 if (nameCheckStatus
!= iSCSINameCheckOK
) {
4522 for (atLeastFoundOne
= B_FALSE
, j
= 0;
4523 j
< staticTargetList
->oidCount
;
4528 status
= SUN_IMA_GetStaticTargetProperties(
4529 staticTargetList
->oids
[j
], &staticTargetProps
);
4530 if (!IMA_SUCCESS(status
)) {
4531 if (status
== IMA_ERROR_OBJECT_NOT_FOUND
) {
4533 * When removing multiple static-config
4534 * entries we need to expect get
4535 * failures. These failures occur when
4536 * we are trying to get entry
4537 * information we have just removed.
4538 * Ignore the failure and continue.
4543 printLibError(status
);
4544 (void) IMA_FreeMemory(staticTargetList
);
4551 staticTargetProps
.staticTarget
.targetAddress
.tpgt
;
4554 * Compare the static target name with the input if
4557 if ((targetNamesEqual(
4558 staticTargetProps
.staticTarget
.targetName
,
4559 staticTargetName
) == B_TRUE
)) {
4560 if (targetAddressSpecified
== B_FALSE
) {
4564 if (staticTargetProps
.staticTarget
.
4565 targetAddress
.imaStruct
.
4567 id
.ipAddress
.ipv4Address
==
4569 (void) inet_ntop(AF_INET
,
4571 staticTarget
.targetAddress
.
4572 imaStruct
.hostnameIpAddress
.
4573 id
.ipAddress
.ipAddress
,
4577 (void) inet_ntop(AF_INET6
,
4579 staticTarget
.targetAddress
.
4580 imaStruct
.hostnameIpAddress
.
4581 id
.ipAddress
.ipAddress
,
4586 if (mbstowcs(tmpTargetAddress
, tmpStr
,
4587 SUN_IMA_IP_ADDRESS_PORT_LEN
) ==
4589 (void) fprintf(stderr
,
4592 "conversion error"));
4597 if ((wcsncmp(tmpTargetAddress
,
4598 staticTargetAddress
,
4599 SUN_IMA_IP_ADDRESS_PORT_LEN
) ==
4600 0) && (staticTargetProps
.
4601 staticTarget
.targetAddress
.
4602 imaStruct
.portNumber
== port
)) {
4603 if (tpgtSpecified
== B_FALSE
) {
4606 if (tpgt
== stpgt
) {
4616 IMA_RemoveStaticDiscoveryTarget(
4617 staticTargetList
->oids
[j
]);
4618 if (!IMA_SUCCESS(status
)) {
4619 printLibError(status
);
4623 atLeastFoundOne
= B_TRUE
;
4627 if (!atLeastFoundOne
) {
4628 (void) fprintf(stderr
, gettext("%ws,%ws: %s\n"),
4629 staticTargetName
, staticTargetAddress
,
4630 gettext("not found"));
4637 * Remove one or more target params.
4640 removeTargetParam(int operandLen
, char *operand
[], int *funcRet
)
4644 IMA_OID initiatorOid
;
4645 IMA_OID_LIST
*targetList
;
4646 SUN_IMA_TARGET_PROPERTIES targetProps
;
4647 wchar_t wcInputObject
[MAX_ISCSI_NAME_LEN
+ 1];
4651 IMA_NODE_NAME bootTargetName
;
4652 IMA_BOOL iscsiBoot
= IMA_FALSE
;
4653 IMA_BOOL mpxioEnabled
= IMA_FALSE
;
4655 /* Get boot session's info */
4656 (void) SUN_IMA_GetBootIscsi(&iscsiBoot
);
4657 if (iscsiBoot
== IMA_TRUE
) {
4658 status
= SUN_IMA_GetBootMpxio(&mpxioEnabled
);
4659 if (!IMA_SUCCESS(status
)) {
4660 (void) fprintf(stderr
, "%s: %s\n",
4661 cmdName
, gettext("unable to get MPxIO info of"
4666 status
= SUN_IMA_GetBootTargetName(bootTargetName
);
4667 if (!IMA_SUCCESS(status
)) {
4668 (void) fprintf(stderr
, "%s: %s\n",
4669 cmdName
, gettext("unable to get boot"
4676 assert(funcRet
!= NULL
);
4678 /* Find Sun initiator */
4679 ret
= sunInitiatorFind(&initiatorOid
);
4681 (void) fprintf(stderr
, "%s: %s\n",
4682 cmdName
, gettext("no initiator found"));
4689 status
= IMA_GetTargetOidList(initiatorOid
, &targetList
);
4690 if (!IMA_SUCCESS(status
)) {
4691 printLibError(status
);
4696 for (i
= 0; i
< operandLen
; i
++) {
4698 commaPos
= strchr(operand
[i
], ',');
4700 /* Ignore IP address. */
4703 (void) memset(&wcInputObject
[0], 0, sizeof (wcInputObject
));
4704 if (mbstowcs(wcInputObject
, operand
[i
],
4705 MAX_ISCSI_NAME_LEN
+ 1) == (size_t)-1) {
4706 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
4707 gettext("conversion error"));
4712 for (found
= B_FALSE
, j
= 0; j
< targetList
->oidCount
;
4714 status
= SUN_IMA_GetTargetProperties(
4715 targetList
->oids
[j
], &targetProps
);
4716 if (!IMA_SUCCESS(status
)) {
4717 printLibError(status
);
4718 (void) IMA_FreeMemory(targetList
);
4724 * Compare the target name with the input if
4727 if (targetNamesEqual(targetProps
.imaProps
.name
,
4728 wcInputObject
) == B_TRUE
) {
4730 if ((targetNamesEqual(bootTargetName
,
4731 wcInputObject
) == B_TRUE
) &&
4732 (iscsiBoot
== IMA_TRUE
)) {
4734 * iscsi booting, need changed target
4735 * param is booting target, booting
4736 * session mpxio disabled, not
4739 if (mpxioEnabled
== IMA_FALSE
) {
4740 (void) fprintf(stderr
,
4741 "%s: %s\n", cmdName
,
4742 gettext("iscsi boot"
4743 " with MPxIO disabled,"
4744 " not allowed to remove"
4745 " boot sess param"));
4752 status
= SUN_IMA_RemoveTargetParam(
4753 targetList
->oids
[j
]);
4754 if (!IMA_SUCCESS(status
)) {
4755 printLibError(status
);
4756 (void) IMA_FreeMemory(targetList
);
4763 /* Silently ignoring it? */
4764 (void) fprintf(stderr
, gettext("%ws: %s\n"),
4765 wcInputObject
, gettext("not found"));
4769 (void) IMA_FreeMemory(targetList
);
4775 addFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
4776 void *addArgs
, int *funcRet
)
4780 assert(funcRet
!= NULL
);
4783 case DISCOVERY_ADDRESS
:
4784 case ISNS_SERVER_ADDRESS
:
4785 ret
= addAddress(object
, operandLen
, operand
, funcRet
);
4788 ret
= addStaticConfig(operandLen
, operand
, funcRet
);
4791 (void) fprintf(stderr
, "%s: %s\n",
4792 cmdName
, gettext("unknown object"));
4801 listFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
4802 void *addArgs
, int *funcRet
)
4806 assert(funcRet
!= NULL
);
4810 ret
= listDiscovery(funcRet
);
4812 case DISCOVERY_ADDRESS
:
4813 ret
= listDiscoveryAddress(operandLen
, operand
, options
,
4816 case ISNS_SERVER_ADDRESS
:
4817 ret
= listISNSServerAddress(operandLen
, operand
, options
,
4821 ret
= listNode(funcRet
);
4824 ret
= listStaticConfig(operandLen
, operand
, funcRet
);
4827 ret
= listTarget(operandLen
, operand
, options
, funcRet
);
4830 ret
= listTargetParam(operandLen
, operand
, options
, funcRet
);
4833 (void) fprintf(stderr
, "%s: %s\n",
4834 cmdName
, gettext("unknown object"));
4843 modifyFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
4844 void *addArgs
, int *funcRet
)
4848 assert(funcRet
!= NULL
);
4852 ret
= modifyDiscovery(options
, funcRet
);
4855 ret
= modifyNode(options
, funcRet
);
4859 while (operand
[i
]) {
4860 ret
= modifyTargetParam(options
, operand
[i
], funcRet
);
4863 (void) fprintf(stderr
, "%s: %s: %s\n",
4864 cmdName
, gettext("modify failed"),
4873 (void) fprintf(stderr
, "%s: %s\n",
4874 cmdName
, gettext("unknown object"));
4883 removeFunc(int operandLen
, char *operand
[], int object
, cmdOptions_t
*options
,
4884 void *addArgs
, int *funcRet
)
4889 case DISCOVERY_ADDRESS
:
4890 case ISNS_SERVER_ADDRESS
:
4891 ret
= removeAddress(object
, operandLen
, operand
,
4895 ret
= removeStaticConfig(operandLen
, operand
, funcRet
);
4898 ret
= removeTargetParam(operandLen
, operand
, funcRet
);
4901 (void) fprintf(stderr
, "%s: %s\n",
4902 cmdName
, gettext("unknown object"));
4910 iSCSINameCheckStatusDisplay(iSCSINameCheckStatusType status
)
4913 case iSCSINameLenZero
:
4914 (void) fprintf(stderr
, "%s: %s\n",
4915 cmdName
, gettext("empty iSCSI name."));
4917 case iSCSINameLenExceededMax
:
4918 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
4919 gettext("iSCSI name exceeded maximum length."));
4921 case iSCSINameUnknownType
:
4922 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
4923 gettext("unknown iSCSI name type."));
4925 case iSCSINameInvalidCharacter
:
4926 (void) fprintf(stderr
, "%s: %s\n",
4928 gettext("iSCSI name invalid character used"));
4930 case iSCSINameIqnFormatError
:
4931 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
4932 gettext("iqn formatting error."));
4934 case iSCSINameIqnDateFormatError
:
4935 (void) fprintf(stderr
, "%s: %s\n",
4936 cmdName
, gettext("invalid iqn date." \
4937 " format is: YYYY-MM"));
4939 case iSCSINameIqnSubdomainFormatError
:
4940 (void) fprintf(stderr
, "%s: %s\n",
4941 cmdName
, gettext("missing subdomain after \":\""));
4943 case iSCSINameIqnInvalidYearError
:
4944 (void) fprintf(stderr
, "%s: %s\n",
4945 cmdName
, gettext("invalid year"));
4947 case iSCSINameIqnInvalidMonthError
:
4948 (void) fprintf(stderr
, "%s: %s\n",
4949 cmdName
, gettext("invalid month"));
4951 case iSCSINameIqnFQDNError
:
4952 (void) fprintf(stderr
, "%s: %s\n",
4953 cmdName
, gettext("missing reversed fully qualified"\
4956 case iSCSINameEUIFormatError
:
4957 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
4958 gettext("eui formatting error."));
4964 * A convenient function to modify the target parameters of an individual
4967 * Return 0 if successful
4968 * Return 1 if failed
4971 modifyIndividualTargetParam(cmdOptions_t
*optionList
, IMA_OID targetOid
,
4974 assert(funcRet
!= NULL
);
4976 for (; optionList
->optval
; optionList
++) {
4977 switch (optionList
->optval
) {
4979 if (modifyTargetAuthMethod(targetOid
,
4980 optionList
->optarg
, funcRet
) != 0) {
4985 if (modifyTargetBidirAuthFlag(targetOid
,
4986 optionList
->optarg
, funcRet
) != 0) {
4991 if (modifyTargetAuthParam(targetOid
,
4992 AUTH_PASSWORD
, NULL
, funcRet
) != 0) {
4997 if (setLoginParameter(targetOid
, DATA_DIGEST
,
4998 optionList
->optarg
) != 0) {
5003 if (setLoginParameter(targetOid
, HEADER_DIGEST
,
5004 optionList
->optarg
) != 0) {
5009 /* Login parameter */
5010 if (setLoginParameters(targetOid
,
5011 optionList
->optarg
) != 0) {
5016 /* Modify configure sessions */
5017 if (modifyConfiguredSessions(targetOid
,
5018 optionList
->optarg
) != 0) {
5023 if (modifyTargetAuthParam(targetOid
, AUTH_NAME
,
5024 optionList
->optarg
, funcRet
) != 0) {
5029 if (setTunableParameters(targetOid
,
5030 optionList
->optarg
) != 0) {
5041 * This helper function could go into a utility module for general use.
5044 parseAddress(char *address_port_str
,
5045 uint16_t defaultPort
,
5047 size_t address_str_len
,
5055 if (address_port_str
[0] == '[') {
5057 char *close_bracket_pos
;
5058 close_bracket_pos
= strchr(address_port_str
, ']');
5059 if (!close_bracket_pos
) {
5060 syslog(LOG_USER
|LOG_DEBUG
,
5061 "IP address format error: %s\n", address_str
);
5062 return (PARSE_ADDR_MISSING_CLOSING_BRACKET
);
5065 *close_bracket_pos
= '\0';
5066 (void) strlcpy(address_str
, &address_port_str
[1],
5069 /* Extract the port number */
5070 close_bracket_pos
++;
5071 if (*close_bracket_pos
== ':') {
5072 close_bracket_pos
++;
5073 if (*close_bracket_pos
!= '\0') {
5074 (void) strlcpy(port_str
, close_bracket_pos
, 64);
5075 tmp_port
= strtol(port_str
, &errchr
, 10);
5076 if (tmp_port
== 0 && errchr
!= NULL
) {
5077 (void) fprintf(stderr
, "%s: %s:%s %s\n",
5078 cmdName
, address_str
,
5080 gettext("port number invalid"));
5081 return (PARSE_ADDR_PORT_OUT_OF_RANGE
);
5083 if ((tmp_port
> 0) && (tmp_port
> USHRT_MAX
) ||
5085 /* Port number out of range */
5086 syslog(LOG_USER
|LOG_DEBUG
,
5087 "Specified port out of range: %d",
5089 return (PARSE_ADDR_PORT_OUT_OF_RANGE
);
5091 *port
= (uint16_t)tmp_port
;
5094 *port
= defaultPort
;
5097 *port
= defaultPort
;
5104 colon_pos
= strchr(address_port_str
, ':');
5106 /* No port number specified. */
5107 *port
= defaultPort
;
5108 (void) strlcpy(address_str
, address_port_str
,
5112 (void) strlcpy(address_str
, address_port_str
,
5115 /* Extract the port number */
5117 if (*colon_pos
!= '\0') {
5119 (void) strlcpy(port_str
, colon_pos
, 64);
5120 tmp_port
= strtol(port_str
, &errchr
, 10);
5121 if (tmp_port
== 0 && errchr
!= NULL
) {
5122 (void) fprintf(stderr
, "%s: %s:%s %s\n",
5123 cmdName
, address_str
, colon_pos
,
5124 gettext("port number invalid"));
5125 return (PARSE_ADDR_PORT_OUT_OF_RANGE
);
5127 if ((tmp_port
> 0) && (tmp_port
> USHRT_MAX
) ||
5129 /* Port number out of range */
5130 syslog(LOG_USER
|LOG_DEBUG
,
5131 "Specified port out of range: %d",
5133 return (PARSE_ADDR_PORT_OUT_OF_RANGE
);
5135 *port
= (uint16_t)tmp_port
;
5138 *port
= defaultPort
;
5145 return (PARSE_ADDR_OK
);
5149 * This helper function could go into a utility module for general use.
5151 iSCSINameCheckStatusType
5152 iSCSINameStringProfileCheck(wchar_t *name
)
5154 char mb_name
[MAX_ISCSI_NAME_LEN
+ 1];
5158 (void) wcstombs(mb_name
, name
, MAX_ISCSI_NAME_LEN
+ 1);
5160 if ((name_len
= strlen(mb_name
)) == 0) {
5161 return (iSCSINameLenZero
);
5162 } else if (name_len
> MAX_ISCSI_NAME_LEN
) {
5163 return (iSCSINameLenExceededMax
);
5167 * check for invalid characters
5168 * According to RFC 3722 iSCSI name must be either a letter,
5169 * a digit or one of the following '-' '.' ':'
5171 for (tmp
= mb_name
; *tmp
!= '\0'; tmp
++) {
5172 if ((isalnum(*tmp
) == 0) &&
5176 return (iSCSINameInvalidCharacter
);
5180 if (strncmp(mb_name
, ISCSI_IQN_NAME_PREFIX
,
5181 strlen(ISCSI_IQN_NAME_PREFIX
)) == 0) {
5183 * If name is of type iqn, check date string and naming
5189 * Don't allow the string to end with a colon. If there is a
5190 * colon then there must be a subdomain provided.
5192 if (mb_name
[strlen(mb_name
) - 1] == ':') {
5193 return (iSCSINameIqnSubdomainFormatError
);
5197 strp
= strtok(&mb_name
[3], ".");
5199 char tmpYear
[5], tmpMonth
[3], *endPtr
= NULL
;
5202 /* Date string should be in YYYY-MM format */
5203 if (strlen(strp
) != strlen("YYYY-MM") ||
5205 return (iSCSINameIqnDateFormatError
);
5209 * Validate year. Only validating that the
5210 * year can be converted to a number. No
5211 * validation will be done on year's actual
5214 (void) strncpy(tmpYear
, strp
, 4);
5218 year
= strtol(tmpYear
, &endPtr
, 10);
5219 if (errno
!= 0 || *endPtr
!= '\0' ||
5220 year
< 0 || year
> 9999) {
5221 return (iSCSINameIqnInvalidYearError
);
5225 * Validate month is valid.
5227 (void) strncpy(tmpMonth
, &strp
[5], 2);
5230 month
= strtol(tmpMonth
, &endPtr
, 10);
5232 if (errno
!= 0 || *endPtr
!= '\0' ||
5233 month
< 1 || month
> 12) {
5234 return (iSCSINameIqnInvalidMonthError
);
5238 * A reversed FQDN needs to be provided. We
5239 * will only check for a "." followed by more
5240 * than two or more characters. The list of domains is
5241 * too large and changes too frequently to
5242 * add validation for.
5244 strp
= strtok(NULL
, ".");
5245 if (!strp
|| strlen(strp
) < 2) {
5246 return (iSCSINameIqnFQDNError
);
5249 /* Name authority string */
5250 strp
= strtok(NULL
, ":");
5252 return (iSCSINameCheckOK
);
5254 return (iSCSINameIqnFQDNError
);
5257 return (iSCSINameIqnFormatError
);
5259 } else if (strncmp(mb_name
, ISCSI_EUI_NAME_PREFIX
,
5260 strlen(ISCSI_EUI_NAME_PREFIX
)) == 0) {
5261 /* If name is of type EUI, change its length */
5263 if (strlen(mb_name
) != ISCSI_EUI_NAME_LEN
) {
5264 return (iSCSINameEUIFormatError
);
5267 for (tmp
= mb_name
+ strlen(ISCSI_EUI_NAME_PREFIX
) + 1;
5268 *tmp
!= '\0'; tmp
++) {
5269 if (isxdigit(*tmp
)) {
5272 return (iSCSINameEUIFormatError
);
5275 return (iSCSINameCheckOK
);
5277 return (iSCSINameUnknownType
);
5282 * This helper function could go into a utility module for general use.
5285 * B_TRUE is the numberStr is an unsigned natural number and within the
5287 * B_FALSE otherwise.
5290 isNaturalNumber(char *numberStr
, uint32_t upperBound
)
5295 if ((number_str_len
= strlen(numberStr
)) == 0) {
5299 for (i
= 0; i
< number_str_len
; i
++) {
5300 if (numberStr
[i
] < 060 || numberStr
[i
] > 071) {
5305 if (atoi(numberStr
) > upperBound
) {
5313 * This helper function could go into a utility module for general use.
5314 * It parses a target string in the format of:
5316 * <target_name>,[<ip_address>[:port][,tpgt]]
5318 * and creates wchar strings for target name and target address. It
5319 * also populates port and tpgt if found.
5322 * PARSE_TARGET_OK if parsing is successful.
5323 * PARSE_TARGET_INVALID_TPGT if the specified tpgt is
5325 * PARSE_TARGET_INVALID_ADDR if the address specified is
5329 parseTarget(char *targetStr
,
5330 wchar_t *targetNameStr
,
5331 size_t targetNameStrLen
,
5332 boolean_t
*targetAddressSpecified
,
5333 wchar_t *targetAddressStr
,
5334 size_t targetAddressStrLen
,
5336 boolean_t
*tpgtSpecified
,
5342 char targetAddress
[SUN_IMA_IP_ADDRESS_PORT_LEN
];
5346 (void) memset(targetNameStr
, 0,
5347 targetNameStrLen
* sizeof (wchar_t));
5348 (void) memset(targetAddressStr
, 0,
5349 targetAddressStrLen
* sizeof (wchar_t));
5351 commaPos
= strchr(targetStr
, ',');
5352 if (commaPos
!= NULL
) {
5355 *targetAddressSpecified
= B_TRUE
;
5358 * Checking of tpgt makes sense only when
5359 * the target address/port are specified.
5361 commaPos2
= strchr(commaPos
, ',');
5362 if (commaPos2
!= NULL
) {
5365 if (isNaturalNumber(commaPos2
, ISCSI_MAX_TPGT_VALUE
) ==
5367 *tpgt
= atoi(commaPos2
);
5368 *tpgtSpecified
= B_TRUE
;
5370 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
5371 gettext("parse target invalid TPGT"));
5372 return (PARSE_TARGET_INVALID_TPGT
);
5376 switch (parseAddress(commaPos
, ISCSI_LISTEN_PORT
,
5377 &targetAddress
[0], MAX_ADDRESS_LEN
+ 1, port
, isIpv6
)) {
5378 case PARSE_ADDR_PORT_OUT_OF_RANGE
:
5379 return (PARSE_TARGET_INVALID_ADDR
);
5383 (void) fprintf(stderr
, "%s: %s\n",
5384 cmdName
, gettext("cannot parse target name"));
5385 return (PARSE_TARGET_INVALID_ADDR
);
5387 (void) mbstowcs(targetAddressStr
, targetAddress
,
5388 targetAddressStrLen
);
5389 for (i
= 0; targetAddressStr
[i
] != 0; i
++) {
5390 lowerCase
= tolower(targetAddressStr
[i
]);
5391 targetAddressStr
[i
] = lowerCase
;
5394 *targetAddressSpecified
= B_FALSE
;
5395 *tpgtSpecified
= B_FALSE
;
5398 (void) mbstowcs(targetNameStr
, targetStr
, targetNameStrLen
);
5399 for (i
= 0; targetNameStr
[i
] != 0; i
++) {
5400 lowerCase
= tolower(targetNameStr
[i
]);
5401 targetNameStr
[i
] = lowerCase
;
5404 return (PARSE_TARGET_OK
);
5409 listCHAPName(IMA_OID oid
)
5411 IMA_INITIATOR_AUTHPARMS authParams
;
5413 IMA_BYTE chapName
[MAX_CHAP_NAME_LEN
+ 1];
5415 /* Get Chap Name depending upon oid object type */
5416 if (oid
.objectType
== IMA_OBJECT_TYPE_LHBA
) {
5417 status
= IMA_GetInitiatorAuthParms(oid
,
5418 IMA_AUTHMETHOD_CHAP
, &authParams
);
5420 status
= SUN_IMA_GetTargetAuthParms(oid
,
5421 IMA_AUTHMETHOD_CHAP
, &authParams
);
5424 (void) fprintf(stdout
, "\n\t\t%s: ", gettext("CHAP Name"));
5426 if (IMA_SUCCESS(status
)) {
5428 * Default chap name will be the node name. The default will
5429 * be set by the driver.
5431 if (authParams
.chapParms
.nameLength
!= 0) {
5432 (void) memset(chapName
, 0, sizeof (chapName
));
5433 (void) memcpy(chapName
, authParams
.chapParms
.name
,
5434 authParams
.chapParms
.nameLength
);
5435 (void) fprintf(stdout
, "%s", chapName
);
5438 (void) fprintf(stdout
, "%s", "-");
5441 (void) fprintf(stdout
, "%s", "-");
5446 checkServiceStatus(void)
5448 IMA_STATUS status
= IMA_ERROR_UNKNOWN_ERROR
;
5449 IMA_BOOL enabled
= 0;
5451 status
= SUN_IMA_GetSvcStatus(&enabled
);
5453 if (status
!= IMA_STATUS_SUCCESS
) {
5454 (void) fprintf(stdout
, "%s\n%s\n",
5455 gettext("Unable to query the service status of"
5456 " iSCSI initiator."),
5457 gettext("For more information, please refer to"
5463 (void) fprintf(stdout
, "%s\n%s\n",
5464 gettext("iSCSI Initiator Service is disabled,"
5465 " try 'svcadm enable network/iscsi/initiator' to"
5466 " enable the service."),
5467 gettext("For more information, please refer to"
5476 * Prints out see manual page.
5477 * Called out through atexit(3C) so is always last thing displayed.
5482 static int sent
= 0;
5487 (void) fprintf(stdout
, "%s %s(8)\n",
5488 gettext("For more information, please see"), cmdName
);
5495 * main calls a parser that checks syntax of the input command against
5496 * various rules tables.
5498 * The parser provides usage feedback based upon same tables by calling
5499 * two usage functions, usage and subUsage, handling command and subcommand
5500 * usage respectively.
5502 * The parser handles all printing of usage syntactical errors
5504 * When syntax is successfully validated, the parser calls the associated
5505 * function using the subcommands table functions.
5507 * Syntax is as follows:
5508 * command subcommand [options] resource-type [<object>]
5510 * The return value from the function is placed in funcRet
5513 main(int argc
, char *argv
[])
5515 synTables_t synTables
;
5516 char versionString
[VERSION_STRING_MAX_LEN
];
5519 void *subcommandArgs
= NULL
;
5521 if (geteuid() != 0) {
5522 (void) fprintf(stderr
, "%s\n", gettext("permission denied"));
5526 if (checkServiceStatus() == B_FALSE
) {
5530 /* set global command name */
5531 cmdName
= getExecBasename(argv
[0]);
5533 (void) snprintf(versionString
, sizeof (versionString
), "%s.%s",
5534 VERSION_STRING_MAJOR
, VERSION_STRING_MINOR
);
5535 synTables
.versionString
= versionString
;
5536 synTables
.longOptionTbl
= &longOptions
[0];
5537 synTables
.subcommandTbl
= &subcommands
[0];
5538 synTables
.objectTbl
= &objects
[0];
5539 synTables
.objectRulesTbl
= &objectRules
[0];
5540 synTables
.optionRulesTbl
= &optionRules
[0];
5542 /* call the CLI parser */
5543 ret
= cmdParse(argc
, argv
, synTables
, subcommandArgs
, &funcRet
);
5550 (void) fprintf(stderr
, "%s: %s\n",
5551 cmdName
, gettext("Unable to complete operation"));
5558 setTunableParameters(IMA_OID oid
, char *optarg
)
5560 char keyp
[MAXOPTARGLEN
];
5561 char valp
[MAXOPTARGLEN
];
5565 ISCSI_TUNABLE_PARAM tunableObj
;
5566 char *nameValueString
, *endptr
;
5568 if ((nameValueString
= strdup(optarg
)) == NULL
) {
5569 if (errno
== ENOMEM
) {
5570 (void) fprintf(stderr
, "%s: %s\n",
5571 cmdName
, strerror(errno
));
5573 (void) fprintf(stderr
, "%s: %s\n", cmdName
,
5574 gettext("unknown error"));
5579 (void) memset(keyp
, 0, sizeof (keyp
));
5580 (void) memset(valp
, 0, sizeof (valp
));
5581 if (sscanf(nameValueString
, gettext("%[^=]=%s"), keyp
, valp
) != 2) {
5582 (void) fprintf(stderr
, "%s: %s: %s\n", cmdName
,
5583 gettext("Unknown param"), nameValueString
);
5584 if (nameValueString
) {
5585 free(nameValueString
);
5586 nameValueString
= NULL
;
5590 if ((key
= getTunableParam(keyp
)) == -1) {
5591 (void) fprintf(stderr
, "%s: %s: %s\n", cmdName
,
5592 gettext("Unknown key"), keyp
);
5593 if (nameValueString
) {
5594 free(nameValueString
);
5595 nameValueString
= NULL
;
5600 case RECV_LOGIN_RSP_TIMEOUT
:
5601 case CONN_LOGIN_MAX
:
5602 case POLLING_LOGIN_DELAY
:
5604 uintValue
= strtoul(valp
, &endptr
, 0);
5605 if (*endptr
!= '\0' || errno
!= 0) {
5606 (void) fprintf(stderr
, "%s: %s - %s\n",
5608 gettext("invalid option argument"),
5610 if (nameValueString
) {
5611 free(nameValueString
);
5612 nameValueString
= NULL
;
5616 if (uintValue
> 3600) {
5617 (void) fprintf(stderr
, "%s: %s\n",
5619 gettext("value must be between 0 and 3600"));
5620 if (nameValueString
) {
5621 free(nameValueString
);
5622 nameValueString
= NULL
;
5627 if (chkConnLoginMaxPollingLoginDelay(oid
, key
, uintValue
) > 0) {
5628 if (nameValueString
) {
5629 free(nameValueString
);
5630 nameValueString
= NULL
;
5635 if (key
== RECV_LOGIN_RSP_TIMEOUT
) {
5636 tunableObj
.tunable_objectType
=
5637 ISCSI_RX_TIMEOUT_VALUE
;
5638 } else if (key
== CONN_LOGIN_MAX
) {
5639 tunableObj
.tunable_objectType
=
5640 ISCSI_CONN_DEFAULT_LOGIN_MAX
;
5641 } else if (key
== POLLING_LOGIN_DELAY
) {
5642 tunableObj
.tunable_objectType
=
5643 ISCSI_LOGIN_POLLING_DELAY
;
5645 tunableObj
.tunable_objectValue
= valp
;
5646 status
= SUN_IMA_SetTunableProperties(oid
, &tunableObj
);
5649 (void) fprintf(stderr
, "%s: %s: %s\n", cmdName
,
5650 gettext("Unsupported key"), keyp
);
5651 if (nameValueString
) {
5652 free(nameValueString
);
5653 nameValueString
= NULL
;
5657 if (!IMA_SUCCESS(status
)) {
5658 printLibError(status
);
5659 if (nameValueString
) {
5660 free(nameValueString
);
5661 nameValueString
= NULL
;
5666 if (nameValueString
) {
5667 free(nameValueString
);
5668 nameValueString
= NULL
;
5674 * Print tunable parameters information
5677 printTunableParameters(IMA_OID oid
)
5679 ISCSI_TUNABLE_PARAM tunableObj
;
5680 char value
[MAXOPTARGLEN
] = "\0";
5683 tunableObj
.tunable_objectValue
= value
;
5684 (void) fprintf(stdout
, "\t%s:\n",
5685 gettext("Tunable Parameters (Default/Configured)"));
5686 tunableObj
.tunable_objectType
= ISCSI_RX_TIMEOUT_VALUE
;
5687 status
= SUN_IMA_GetTunableProperties(oid
, &tunableObj
);
5688 if (!IMA_SUCCESS(status
)) {
5689 printLibError(status
);
5692 if (value
[0] == '\0') {
5696 (void) fprintf(stdout
, "\t\t%s: ",
5697 gettext("Session Login Response Time"));
5698 (void) fprintf(stdout
, "%s/%s\n", ISCSI_DEFAULT_RX_TIMEOUT_VALUE
,
5699 tunableObj
.tunable_objectValue
);
5702 tunableObj
.tunable_objectType
= ISCSI_CONN_DEFAULT_LOGIN_MAX
;
5703 status
= SUN_IMA_GetTunableProperties(oid
, &tunableObj
);
5704 if (!IMA_SUCCESS(status
)) {
5705 printLibError(status
);
5708 if (value
[0] == '\0') {
5712 (void) fprintf(stdout
, "\t\t%s: ",
5713 gettext("Maximum Connection Retry Time"));
5714 (void) fprintf(stdout
, "%s/%s\n", ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX
,
5715 tunableObj
.tunable_objectValue
);
5718 tunableObj
.tunable_objectType
= ISCSI_LOGIN_POLLING_DELAY
;
5719 status
= SUN_IMA_GetTunableProperties(oid
, &tunableObj
);
5720 if (!IMA_SUCCESS(status
)) {
5721 printLibError(status
);
5724 if (value
[0] == '\0') {
5728 (void) fprintf(stdout
, "\t\t%s: ",
5729 gettext("Login Retry Time Interval"));
5730 (void) fprintf(stdout
, "%s/%s\n", ISCSI_DEFAULT_LOGIN_POLLING_DELAY
,
5731 tunableObj
.tunable_objectValue
);
5736 * This is helper function to check conn_login_max and polling_login_delay.
5739 chkConnLoginMaxPollingLoginDelay(IMA_OID oid
, int key
, int uintValue
)
5741 char valuep
[MAXOPTARGLEN
];
5744 ISCSI_TUNABLE_PARAM getObj
;
5747 if (key
== CONN_LOGIN_MAX
) {
5748 getObj
.tunable_objectType
= ISCSI_LOGIN_POLLING_DELAY
;
5749 } else if (key
== POLLING_LOGIN_DELAY
) {
5750 getObj
.tunable_objectType
= ISCSI_CONN_DEFAULT_LOGIN_MAX
;
5755 getObj
.tunable_objectValue
= valuep
;
5756 status
= SUN_IMA_GetTunableProperties(oid
, &getObj
);
5757 if (!IMA_SUCCESS(status
)) {
5758 printLibError(status
);
5761 if (valuep
[0] == '\0') {
5762 if (key
== CONN_LOGIN_MAX
) {
5763 (void) strlcpy(valuep
,
5764 ISCSI_DEFAULT_LOGIN_POLLING_DELAY
,
5765 strlen(ISCSI_DEFAULT_LOGIN_POLLING_DELAY
) +1);
5767 (void) strlcpy(valuep
,
5768 ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX
,
5769 strlen(ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX
) +1);
5774 getValue
= strtoul(valuep
, &endptr
, 0);
5775 if (*endptr
!= '\0' || errno
!= 0) {
5776 (void) fprintf(stderr
, "%s: %s - %s\n",
5778 gettext("cannot convert tunable string"),
5782 if (key
== CONN_LOGIN_MAX
) {
5783 if (uintValue
< getValue
) {
5784 (void) fprintf(stderr
, "%s: %s %ld\n",
5785 cmdName
, gettext("value must larger than"),
5790 if (uintValue
> getValue
) {
5791 (void) fprintf(stderr
, "%s: %s %ld\n",
5792 cmdName
, gettext("value must smaller than"),