libuutil: move under bmake
[unleashed.git] / usr / src / cmd / iscsiadm / iscsiadm_main.c
blob2c2f763890f18de98b95eb90acddde21785fe419
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <wchar.h>
28 #include <widec.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <arpa/inet.h>
32 #include <netdb.h>
33 #include <unistd.h>
34 #include <libintl.h>
35 #include <limits.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <syslog.h>
39 #include <errno.h>
40 #include <netinet/in.h>
41 #include <sys/socket.h>
42 #include <arpa/inet.h>
43 #include <wctype.h>
44 #include <assert.h>
46 #include <ima.h>
47 #include <libsun_ima.h>
48 #include <sys/iscsi_protocol.h>
49 #include <sys/scsi/adapters/iscsi_if.h>
51 #include "cmdparse.h"
52 #include "sun_ima.h"
53 #include "iscsiadm.h"
55 #define VERSION_STRING_MAX_LEN 10
56 #define MAX_LONG_CHAR_LEN 19
58 #define MAX_AUTH_METHODS 5
60 * Version number:
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"
96 /* For listNode */
97 #define INF_ERROR 1
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") : \
104 gettext("no"), \
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 {
143 iSCSINameCheckOK,
144 iSCSINameLenZero,
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,
169 uint16_t *port,
170 boolean_t *tpgtSpecified,
171 uint16_t *tpgt,
172 boolean_t *isIpv6);
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,
237 IMA_OID *oid,
238 void *pProps,
239 uint32_t paramIndex);
240 /* LINTED E_STATIC_UNUSED */
241 static IMA_STATUS setISCSINodeParameter(int paramType,
242 IMA_OID *oid,
243 void *pProps,
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);
253 /* globals */
254 static char *cmdName;
257 * Available option letters:
259 * befgijklmnoquwxyz
261 * DEFGHIJKLMOQUVWXYZ
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},
287 {NULL, 0, 0, 0}
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},
303 {NULL, 0}
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},
310 {NULL, 0}
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},
321 {NULL, 0, NULL}
325 * Add objects here
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},
333 {"target", TARGET},
334 {"target-param", TARGET_PARAM},
335 {NULL, 0}
339 * Rules for subcommands and objects
341 objectRules_t objectRules[] = {
342 {TARGET, 0, LIST, 0, ADD|REMOVE|MODIFY, LIST,
343 "target-name"},
344 {TARGET_PARAM, MODIFY|REMOVE, LIST, 0, ADD, MODIFY,
345 "target-name"},
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},
371 {0, 0, 0, 0, 0}
375 static boolean_t
376 targetNamesEqual(wchar_t *name1, wchar_t *name2)
378 int i;
379 wchar_t wchar1, wchar2;
381 if (name1 == NULL || name2 == NULL) {
382 return (B_FALSE);
385 if (wcslen(name1) != wcslen(name2)) {
386 return (B_FALSE);
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) {
397 return (B_FALSE);
401 return (B_TRUE);
404 static boolean_t
405 ipAddressesEqual(IMA_TARGET_ADDRESS addr1, IMA_TARGET_ADDRESS addr2)
407 #define IPV4_ADDR_BYTES 4
408 #define IPV6_ADDR_BYTES 16
410 int compSize;
412 if (addr1.hostnameIpAddress.id.ipAddress.ipv4Address !=
413 addr2.hostnameIpAddress.id.ipAddress.ipv4Address) {
414 return (B_FALSE);
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) {
424 return (B_TRUE);
427 return (B_FALSE);
430 static int
431 getLoginParam(char *arg)
433 parameterTbl_t *paramp;
434 int len;
436 for (paramp = loginParams; paramp->name; paramp++) {
437 len = strlen(arg);
438 if (len == strlen(paramp->name) &&
439 strncasecmp(arg, paramp->name, len) == 0) {
440 return (paramp->val);
443 return (-1);
446 static int
447 getTunableParam(char *arg)
449 parameterTbl_t *paramp;
450 int len;
452 for (paramp = tunableParams; paramp->name != NULL; paramp++) {
453 len = strlen(arg);
454 if (len == strlen(paramp->name) &&
455 strncasecmp(arg, paramp->name, len) == 0) {
456 return (paramp->val);
459 return (-1);
462 static void
463 printLibError(IMA_STATUS status)
465 char *errorString;
466 switch (status) {
467 case IMA_ERROR_NOT_SUPPORTED:
468 errorString =
469 gettext("Operation currently not supported");
470 break;
471 case IMA_ERROR_INSUFFICIENT_MEMORY:
472 errorString = gettext("Insufficient memory");
473 break;
474 case IMA_ERROR_UNEXPECTED_OS_ERROR:
475 errorString = gettext("unexpected OS error");
476 break;
477 case IMA_ERROR_UNKNOWN_ERROR:
478 errorString = gettext("Unknown error");
479 break;
480 case IMA_ERROR_LU_IN_USE:
481 errorString = gettext("Logical unit in use");
482 break;
483 case IMA_ERROR_INVALID_PARAMETER:
484 errorString = gettext("Invalid parameter specified");
485 break;
486 case IMA_ERROR_INVALID_OBJECT_TYPE:
487 errorString =
488 gettext("Internal library error: Invalid oid type specified");
489 break;
490 case IMA_ERROR_INCORRECT_OBJECT_TYPE:
491 errorString =
492 gettext("Internal library error: Incorrect oid type specified");
493 break;
494 case IMA_ERROR_OBJECT_NOT_FOUND:
495 errorString = gettext("Internal library error: Oid not found");
496 break;
497 case IMA_ERROR_NAME_TOO_LONG:
498 errorString = gettext("Name too long");
499 break;
500 default:
501 errorString = gettext("Unknown error");
503 (void) fprintf(stderr, "%s: %s\n", cmdName, errorString);
507 * input:
508 * execFullName - exec name of program (argv[0])
510 * Returns:
511 * command name portion of execFullName
513 static char *
514 getExecBasename(char *execFullname)
516 char *lastSlash, *execBasename;
518 /* guard against '/' at end of command invocation */
519 for (;;) {
520 lastSlash = strrchr(execFullname, '/');
521 if (lastSlash == NULL) {
522 execBasename = execFullname;
523 break;
524 } else {
525 execBasename = lastSlash + 1;
526 if (*execBasename == '\0') {
527 *lastSlash = '\0';
528 continue;
530 break;
533 return (execBasename);
538 * input:
539 * nodeProps - pointer to caller allocated IMA_NODE_PROPERTIES
541 * returns:
542 * zero on success
543 * non-zero otherwise
545 static int
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);
553 return (INF_ERROR);
556 status = IMA_GetNodeProperties(sharedNodeOid, nodeProps);
557 if (!IMA_SUCCESS(status)) {
558 printLibError(status);
559 return (INF_ERROR);
562 return (0);
566 * sunInitiatorFind
567 * Purpose:
568 * Finds the Sun iSCSI initiator (LHBA). This CLI currently supports only
569 * one initiator.
571 * output:
572 * oid of initiator
574 * Returns:
575 * zero on success with initiator found
576 * > 0 on success with no initiator found
577 * < 0 on failure
579 static int
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);
587 return (-1);
590 if ((lhbaList == NULL) || (lhbaList->oidCount == 0)) {
591 printLibError(IMA_ERROR_OBJECT_NOT_FOUND);
592 if (lhbaList != NULL)
593 (void) IMA_FreeMemory(lhbaList);
594 return (-1);
597 *oid = lhbaList->oids[0];
598 (void) IMA_FreeMemory(lhbaList);
600 return (0);
604 * input:
605 * wcInput - wide character string containing discovery address
606 * output:
607 * address - IMA_TARGET_ADDRESS structure containing valid
608 * discovery address
609 * returns:
610 * zero on success
611 * non-zero on failure
614 static int
615 getTargetAddress(int addrType, char *ipStr, IMA_TARGET_ADDRESS *address)
617 char cCol = ':';
618 char cBracketL = '['; /* Open Bracket '[' */
619 char cBracketR = ']'; /* Close Bracket ']' */
620 char *colPos;
621 char *startPos;
622 unsigned long inputPort;
623 int addressType = AF_INET;
624 char *tmpStrPtr, tmpStr[SUN_IMA_IP_ADDRESS_PORT_LEN];
625 int rval;
627 /* Check if this is a ipv6 address */
628 if (ipStr[0] == cBracketL) {
629 addressType = AF_INET6;
630 startPos = strchr(ipStr, cBracketR);
631 if (!startPos) {
632 (void) fprintf(stderr, "%s: %s: ']' %s\n",
633 cmdName, ipStr, gettext("missing"));
634 return (1);
636 (void) strlcpy(tmpStr, ipStr+1, startPos-ipStr);
637 address->hostnameIpAddress.id.ipAddress.ipv4Address = IMA_FALSE;
638 tmpStrPtr = tmpStr;
639 } else {
640 /* set start position to beginning of input object */
641 addressType = AF_INET;
642 startPos = ipStr;
643 address->hostnameIpAddress.id.ipAddress.ipv4Address = IMA_TRUE;
644 tmpStrPtr = ipStr;
646 /* wcschr for ':'. If not there, use default port */
647 colPos = strchr(startPos, cCol);
649 if (!colPos) {
650 if (addrType == DISCOVERY_ADDRESS) {
651 inputPort = DEFAULT_ISCSI_PORT;
652 } else if (addrType == ISNS_SERVER_ADDRESS) {
653 inputPort = ISNS_DEFAULT_SERVER_PORT;
654 } else {
655 *colPos = '\0';
657 } else {
658 *colPos = '\0';
661 rval = inet_pton(addressType, tmpStrPtr,
662 address->hostnameIpAddress.id.ipAddress.ipAddress);
663 /* inet_pton returns 1 on success */
664 if (rval != 1) {
665 (void) fprintf(stderr, "%s: %s: %s\n", cmdName, ipStr,
666 gettext("invalid IP address"));
667 return (1);
671 if (colPos) {
672 char *errchr;
674 colPos++;
675 if (*colPos == '\0') {
676 (void) fprintf(stderr, "%s: %s: %s\n",
677 cmdName, ipStr,
678 gettext("port number missing"));
679 return (1);
683 * convert port string to unsigned value
684 * Note: Don't remove errno = 0 as you may get false failures.
686 errno = 0;
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"));
692 return (1);
694 /* make sure it's in the range */
695 if (inputPort > USHRT_MAX) {
696 (void) fprintf(stderr, "%s: %s: %s\n",
697 cmdName, ipStr,
698 gettext("port number out of range"));
699 return (1);
702 address->portNumber = inputPort;
704 return (0);
708 * Print results of send targets command
710 static void
711 printSendTargets(SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList)
713 char outBuf[INET6_ADDRSTRLEN];
714 int inetSize;
715 int af;
716 int i;
718 for (i = 0; i < pList->keyCount; i++) {
719 if (pList->keys[i].address.ipAddress.ipv4Address == IMA_TRUE) {
720 af = AF_INET;
721 inetSize = INET_ADDRSTRLEN;
722 } else {
723 af = AF_INET6;
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
740 static int
741 printLoginParameters(char *prefix, IMA_OID oid, int printOption)
743 IMA_STATUS status;
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",
755 prefix,
756 gettext("Login Parameters (Default/Configured)"));
757 break;
758 case PRINT_NEGOTIATED_PARAMS:
759 (void) fprintf(stdout, "%s%s:\n",
760 prefix,
761 gettext("Login Parameters (Negotiated)"));
762 status = SUN_IMA_GetConnOidList(
763 &oid,
764 &pConnList);
766 if (!IMA_SUCCESS(status)) {
767 printLibError(status);
768 return (1);
771 status = SUN_IMA_GetConnProperties(&pConnList->oids[0],
772 &connProps);
773 propBool.currentValueValid = connProps->valuesValid;
774 propMinMax.currentValueValid = connProps->valuesValid;
775 break;
776 default:
777 return (1);
780 if (printOption == PRINT_NEGOTIATED_PARAMS) {
781 propBool.currentValue = connProps->dataSequenceInOrder;
782 } else {
783 status = IMA_GetDataSequenceInOrderProperties(oid, &propBool);
785 if (!IMA_SUCCESS(status)) {
786 printLibError(status);
787 (void) IMA_FreeMemory(connProps);
788 return (1);
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;
797 } else {
798 status = IMA_GetDataPduInOrderProperties(oid, &propBool);
800 if (!IMA_SUCCESS(status)) {
801 printLibError(status);
802 (void) IMA_FreeMemory(connProps);
803 return (1);
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;
812 } else {
813 status = IMA_GetDefaultTime2RetainProperties(oid, &propMinMax);
815 if (!IMA_SUCCESS(status)) {
816 printLibError(status);
817 (void) IMA_FreeMemory(connProps);
818 return (1);
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;
827 } else {
828 status = IMA_GetDefaultTime2WaitProperties(oid, &propMinMax);
830 if (!IMA_SUCCESS(status)) {
831 printLibError(status);
832 (void) IMA_FreeMemory(connProps);
833 return (1);
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;
842 } else {
843 status = IMA_GetErrorRecoveryLevelProperties(oid, &propMinMax);
845 if (!IMA_SUCCESS(status)) {
846 printLibError(status);
847 (void) IMA_FreeMemory(connProps);
848 return (1);
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;
857 } else {
858 status = IMA_GetFirstBurstLengthProperties(oid,
859 &propMinMax);
861 if (!IMA_SUCCESS(status)) {
862 printLibError(status);
863 (void) IMA_FreeMemory(connProps);
864 return (1);
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;
873 } else {
874 status = IMA_GetImmediateDataProperties(oid, &propBool);
876 if (!IMA_SUCCESS(status)) {
877 printLibError(status);
878 (void) IMA_FreeMemory(connProps);
879 return (1);
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;
887 } else {
888 status = IMA_GetInitialR2TProperties(oid, &propBool);
890 if (!IMA_SUCCESS(status)) {
891 printLibError(status);
892 (void) IMA_FreeMemory(connProps);
893 return (1);
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;
902 } else {
903 status = IMA_GetMaxBurstLengthProperties(oid, &propMinMax);
905 if (!IMA_SUCCESS(status)) {
906 printLibError(status);
907 (void) IMA_FreeMemory(connProps);
908 return (1);
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;
916 } else {
917 status = IMA_GetMaxOutstandingR2TProperties(oid, &propMinMax);
919 if (!IMA_SUCCESS(status)) {
920 printLibError(status);
921 (void) IMA_FreeMemory(connProps);
922 return (1);
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;
931 } else {
932 status = IMA_GetMaxRecvDataSegmentLengthProperties(oid,
933 &propMinMax);
935 if (!IMA_SUCCESS(status)) {
936 printLibError(status);
937 (void) IMA_FreeMemory(connProps);
938 return (1);
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;
947 } else {
948 status = IMA_GetMaxConnectionsProperties(oid, &propMinMax);
950 if (!IMA_SUCCESS(status)) {
951 printLibError(status);
952 (void) IMA_FreeMemory(connProps);
953 return (1);
955 (void) fprintf(stdout, "%s\t%s: ", prefix, gettext("Max Connections"));
956 IMAMINMAXPRINT(propMinMax, printOption);
958 (void) IMA_FreeMemory(connProps);
959 return (0);
963 * Print discovery information.
965 static void
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"));
971 } else {
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
994 static void
995 printConnectionList(char *prefix, IMA_OID_LIST *pConnList)
997 IMA_STATUS imaStatus;
998 int i;
999 SUN_IMA_CONN_PROPERTIES *connProps;
1000 union {
1001 char ipv4[INET_ADDRSTRLEN+1];
1002 char ipv6[INET6_ADDRSTRLEN+1];
1003 } tmp;
1005 for (i = 0; i < pConnList->oidCount; i++) {
1006 imaStatus = SUN_IMA_GetConnProperties(&pConnList->oids[i],
1007 &connProps);
1009 if (imaStatus != IMA_STATUS_SUCCESS) {
1010 continue;
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],
1020 &tmp.ipv4[0],
1021 INET_ADDRSTRLEN)) {
1022 (void) fprintf(stdout,
1023 "%s %s: %s:%u\n",
1024 prefix,
1025 gettext("IP address (Local)"),
1026 &tmp.ipv4[0],
1027 ntohs(connProps->local.portNumber));
1029 } else {
1030 if (inet_ntop(AF_INET6,
1031 &connProps->local.ipAddress.ipAddress[0],
1032 &tmp.ipv6[0],
1033 INET6_ADDRSTRLEN)) {
1034 (void) fprintf(stdout,
1035 "%s %s: [%s]:%u\n",
1036 prefix,
1037 gettext("IP address (Local)"),
1038 &tmp.ipv6[0],
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],
1045 &tmp.ipv4[0],
1046 INET_ADDRSTRLEN)) {
1047 (void) fprintf(stdout,
1048 "%s %s: %s:%u\n",
1049 prefix,
1050 gettext("IP address (Peer)"),
1051 &tmp.ipv4[0],
1052 ntohs(connProps->peer.portNumber));
1054 } else {
1055 if (inet_ntop(AF_INET6,
1056 &connProps->peer.ipAddress.ipAddress[0],
1057 &tmp.ipv6[0],
1058 INET6_ADDRSTRLEN)) {
1059 (void) fprintf(stdout,
1060 "%s %s: [%s]:%u\n",
1061 prefix,
1062 gettext("IP address (Peer)"),
1063 &tmp.ipv6[0],
1064 ntohs(connProps->peer.portNumber));
1068 (void) IMA_FreeMemory(connProps);
1073 * Set login parameters on a target or initiator
1075 static int
1076 setLoginParameter(IMA_OID oid, int optval, char *optarg)
1078 IMA_STATUS status = IMA_STATUS_SUCCESS;
1079 IMA_UINT uintValue;
1080 IMA_BOOL boolValue;
1081 SUN_IMA_DIGEST_ALGORITHM digestAlgList[1];
1082 IMA_MIN_MAX_VALUE propMinMax;
1083 char *endptr;
1086 * for clarity, there are two switch statements
1087 * The first loads the variable and the second
1088 * calls the appropriate API
1090 switch (optval) {
1091 case DATA_SEQ_IN_ORDER:
1092 case IMMEDIATE_DATA:
1093 case INITIAL_R2T:
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;
1100 } else {
1101 (void) fprintf(stderr, "%s: %s - %s\n",
1102 cmdName,
1103 gettext("invalid option argument"),
1104 optarg);
1105 return (1);
1107 break;
1108 case DEFAULT_TIME_2_RETAIN:
1109 case DEFAULT_TIME_2_WAIT:
1110 errno = 0;
1111 uintValue = strtoul(optarg, &endptr, 0);
1112 if (*endptr != '\0' || errno != 0) {
1113 (void) fprintf(stderr, "%s: %s - %s\n",
1114 cmdName,
1115 gettext("invalid option argument"),
1116 optarg);
1117 return (1);
1119 if (uintValue > 3600) {
1120 (void) fprintf(stderr, "%s: %s\n",
1121 cmdName,
1122 gettext("value must be between 0 and 3600"));
1123 return (1);
1125 break;
1126 case FIRST_BURST_LENGTH:
1127 case MAX_BURST_LENGTH:
1128 case MAX_RECV_DATA_SEG_LEN:
1129 errno = 0;
1130 /* implement 'default'? */
1131 uintValue = strtoul(optarg, &endptr, 0);
1132 if (*endptr != '\0' || errno != 0) {
1133 (void) fprintf(stderr, "%s: %s - %s\n",
1134 cmdName,
1135 gettext("invalid option argument"),
1136 optarg);
1137 return (1);
1139 if (uintValue < 512 || uintValue > 16777215) {
1140 (void) fprintf(stderr, "%s: %s\n",
1141 cmdName,
1142 gettext("value must be between 512 and 16777215"));
1143 return (1);
1145 break;
1146 case MAX_OUTSTANDING_R2T:
1147 errno = 0;
1148 uintValue = strtoul(optarg, &endptr, 0);
1149 if (*endptr != '\0' || errno != 0) {
1150 (void) fprintf(stderr, "%s: %s - %s\n",
1151 cmdName,
1152 gettext("invalid option argument"),
1153 optarg);
1154 return (1);
1156 if (uintValue < 1 || uintValue > 65535) {
1157 (void) fprintf(stderr, "%s: %s\n",
1158 cmdName,
1159 gettext("value must be between 1 and 65535"));
1160 return (1);
1162 break;
1163 case HEADER_DIGEST:
1164 case DATA_DIGEST:
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;
1169 } else {
1170 (void) fprintf(stderr, "%s: %s - %s\n",
1171 cmdName,
1172 gettext("invalid option argument"),
1173 optarg);
1174 return (1);
1176 break;
1177 case MAX_CONNECTIONS:
1178 errno = 0;
1179 uintValue = strtoul(optarg, &endptr, 0);
1180 if (*endptr != '\0' || errno != 0) {
1181 (void) fprintf(stderr, "%s: %s - %s\n",
1182 cmdName,
1183 gettext("invalid option argument"),
1184 optarg);
1185 return (1);
1187 if (uintValue < 1 || uintValue > 256) {
1188 (void) fprintf(stderr, "%s: %s\n",
1189 cmdName,
1190 gettext("value must be between 1 and 256"));
1191 return (1);
1193 break;
1194 case ERROR_RECOVERY_LEVEL:
1195 errno = 0;
1196 uintValue = strtoul(optarg, &endptr, 0);
1197 if (*endptr != '\0' || errno != 0) {
1198 (void) fprintf(stderr, "%s: %s - %s\n",
1199 cmdName,
1200 gettext("invalid option argument"),
1201 optarg);
1202 return (1);
1204 if (uintValue > 2) {
1205 (void) fprintf(stderr, "%s: %s\n",
1206 cmdName,
1207 gettext("value must be between 0 and 2"));
1208 return (1);
1210 break;
1211 default:
1212 (void) fprintf(stderr, "%s: %c: %s\n",
1213 cmdName, optval, gettext("unknown option"));
1214 return (1);
1217 switch (optval) {
1218 case DATA_PDU_IN_ORDER:
1219 status = IMA_SetDataPduInOrder(oid, boolValue);
1220 break;
1221 case DATA_SEQ_IN_ORDER:
1222 status = IMA_SetDataSequenceInOrder(oid, boolValue);
1223 break;
1224 case DEFAULT_TIME_2_RETAIN:
1225 status = IMA_SetDefaultTime2Retain(oid, uintValue);
1226 break;
1227 case DEFAULT_TIME_2_WAIT:
1228 status = IMA_SetDefaultTime2Wait(oid, uintValue);
1229 break;
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,
1239 &propMinMax);
1240 if (!IMA_SUCCESS(status)) {
1241 printLibError(status);
1242 return (1);
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 " \
1249 "maxBurstLength"));
1251 return (1);
1254 break;
1255 case IMMEDIATE_DATA:
1256 status = IMA_SetImmediateData(oid, boolValue);
1257 break;
1258 case INITIAL_R2T:
1259 status = IMA_SetInitialR2T(oid, boolValue);
1260 break;
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,
1269 &propMinMax);
1270 if (!IMA_SUCCESS(status)) {
1271 printLibError(status);
1272 return (1);
1274 if (uintValue < propMinMax.currentValue) {
1275 (void) fprintf(stderr, "%s: %s\n",
1276 cmdName,
1277 gettext("maxBurstLength must be " \
1278 "greater than or equal to " \
1279 "firstBurstLength"));
1281 return (1);
1283 break;
1285 case MAX_OUTSTANDING_R2T:
1286 status = IMA_SetMaxOutstandingR2T(oid, uintValue);
1287 break;
1288 case MAX_RECV_DATA_SEG_LEN:
1289 status = IMA_SetMaxRecvDataSegmentLength(oid,
1290 uintValue);
1291 break;
1292 case HEADER_DIGEST:
1293 status = SUN_IMA_SetHeaderDigest(oid, 1,
1294 &digestAlgList[0]);
1295 break;
1296 case DATA_DIGEST:
1297 status = SUN_IMA_SetDataDigest(oid, 1,
1298 &digestAlgList[0]);
1299 break;
1300 case MAX_CONNECTIONS:
1301 status = IMA_SetMaxConnections(oid, uintValue);
1302 break;
1303 case ERROR_RECOVERY_LEVEL:
1304 status = IMA_SetErrorRecoveryLevel(oid, uintValue);
1305 break;
1307 if (!IMA_SUCCESS(status)) {
1308 printLibError(status);
1309 return (1);
1311 return (0);
1314 static void
1315 printDigestAlgorithm(SUN_IMA_DIGEST_ALGORITHM_VALUE *digestAlgorithms,
1316 int printOption)
1318 int i;
1320 if (printOption == PRINT_CONFIGURED_PARAMS) {
1321 for (i = 0; i < digestAlgorithms->defaultAlgorithmCount; i++) {
1322 if (i > 0) {
1323 (void) fprintf(stdout, "|");
1325 switch (digestAlgorithms->defaultAlgorithms[i]) {
1326 case SUN_IMA_DIGEST_NONE:
1327 (void) fprintf(stdout,
1328 gettext("NONE"));
1329 break;
1330 case SUN_IMA_DIGEST_CRC32:
1331 (void) fprintf(stdout,
1332 gettext("CRC32"));
1333 break;
1334 default:
1335 (void) fprintf(stdout,
1336 gettext("Unknown"));
1337 break;
1340 (void) fprintf(stdout, "/");
1341 if (digestAlgorithms->currentValid == IMA_TRUE) {
1342 for (i = 0;
1343 i < digestAlgorithms->currentAlgorithmCount; i++) {
1344 if (i > 0) {
1345 (void) fprintf(stdout, "|");
1347 switch (digestAlgorithms->
1348 currentAlgorithms[i]) {
1349 case SUN_IMA_DIGEST_NONE:
1350 (void) fprintf(stdout,
1351 gettext("NONE"));
1352 break;
1353 case SUN_IMA_DIGEST_CRC32:
1354 (void) fprintf(stdout,
1355 gettext("CRC32"));
1356 break;
1357 default:
1358 (void) fprintf(stdout,
1359 gettext("Unknown"));
1360 break;
1363 } else {
1364 (void) fprintf(stdout, "-");
1366 (void) fprintf(stdout, "\n");
1367 } else if (printOption == PRINT_NEGOTIATED_PARAMS) {
1369 if (digestAlgorithms->negotiatedValid == IMA_TRUE) {
1370 for (i = 0;
1371 i < digestAlgorithms->negotiatedAlgorithmCount;
1372 i++) {
1373 if (i > 0) {
1374 (void) fprintf(stdout, "|");
1376 switch (digestAlgorithms->
1377 negotiatedAlgorithms[i]) {
1378 case SUN_IMA_DIGEST_NONE:
1379 (void) fprintf(stdout,
1380 gettext("NONE"));
1381 break;
1382 case SUN_IMA_DIGEST_CRC32:
1383 (void) fprintf(stdout,
1384 gettext("CRC32"));
1385 break;
1386 default:
1387 (void) fprintf(stdout,
1388 gettext("Unknown"));
1389 break;
1392 } else {
1393 (void) fprintf(stdout, "-");
1395 (void) fprintf(stdout, "\n");
1399 static int
1400 setLoginParameters(IMA_OID oid, char *optarg)
1402 char keyp[MAXOPTARGLEN];
1403 char valp[MAXOPTARGLEN];
1404 int key;
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));
1411 } else {
1412 (void) fprintf(stderr, "%s: %s\n", cmdName,
1413 gettext("unknown error"));
1415 return (1);
1418 indexp = nameValueString;
1421 * Retrieve all login params from option argument
1422 * Syntax <key=value,...>
1424 while (indexp) {
1425 if (delim = strchr(indexp, ',')) {
1426 delim[0] = '\0';
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;
1437 return (1);
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;
1446 return (1);
1448 if (setLoginParameter(oid, key, valp) != 0) {
1449 if (nameValueString) {
1450 free(nameValueString);
1451 nameValueString = NULL;
1453 return (1);
1455 if (delim) {
1456 indexp = delim + 1;
1457 } else {
1458 indexp = NULL;
1462 if (nameValueString) {
1463 free(nameValueString);
1464 nameValueString = NULL;
1466 return (0);
1470 * Print logical unit information for a specific target
1472 static void
1473 printTargetLuns(IMA_OID_LIST * lunList)
1475 int j;
1476 IMA_STATUS status;
1477 SUN_IMA_LU_PROPERTIES lunProps;
1479 for (j = 0; j < lunList->oidCount; j++) {
1480 status = SUN_IMA_GetLuProperties(lunList->oids[j],
1481 &lunProps);
1482 if (!IMA_SUCCESS(status)) {
1483 printLibError(status);
1484 return;
1487 (void) fprintf(stdout, "\tLUN: %lld\n",
1488 lunProps.imaProps.targetLun);
1489 (void) fprintf(stdout, "\t Vendor: %s\n",
1490 lunProps.vendorId);
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);
1501 } else {
1502 (void) fprintf(stdout,
1503 gettext("\t OS Device Name: Not"
1504 " Available\n"));
1510 * Retrieve CHAP secret from input
1512 static int
1513 getSecret(char *secret, int *secretLen, int minSecretLen, int maxSecretLen)
1515 char *chapSecret;
1517 /* get password */
1518 chapSecret = getpassphrase(gettext("Enter secret:"));
1520 if (chapSecret == NULL) {
1521 (void) fprintf(stderr, "%s: %s\n", cmdName,
1522 gettext("Unable to get secret"));
1523 *secret = '\0';
1524 return (1);
1527 if (strlen(chapSecret) > maxSecretLen) {
1528 (void) fprintf(stderr, "%s: %s %d\n", cmdName,
1529 gettext("secret too long, maximum length is"),
1530 maxSecretLen);
1531 *secret = '\0';
1532 return (1);
1535 if (strlen(chapSecret) < minSecretLen) {
1536 (void) fprintf(stderr, "%s: %s %d\n", cmdName,
1537 gettext("secret too short, minimum length is"),
1538 minSecretLen);
1539 *secret = '\0';
1540 return (1);
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"));
1550 *secret = '\0';
1551 return (1);
1554 if (strcmp(secret, chapSecret) != 0) {
1555 (void) fprintf(stderr, "%s: %s\n", cmdName,
1556 gettext("secrets do not match, secret not changed"));
1557 *secret = '\0';
1558 return (1);
1560 *secretLen = strlen(chapSecret);
1561 return (0);
1565 * Lists the discovery attributes
1567 static int
1568 listDiscovery(int *funcRet)
1570 IMA_OID initiatorOid;
1571 IMA_DISCOVERY_PROPERTIES discProps;
1572 int ret;
1573 IMA_STATUS status;
1575 assert(funcRet != NULL);
1578 /* Find Sun initiator */
1579 ret = sunInitiatorFind(&initiatorOid);
1580 if (ret > 0) {
1581 (void) fprintf(stderr, "%s: %s\n",
1582 cmdName, gettext("no initiator found"));
1585 if (ret != 0) {
1586 return (ret);
1589 /* Get discovery attributes from IMA */
1590 status = IMA_GetDiscoveryProperties(initiatorOid, &discProps);
1591 if (!IMA_SUCCESS(status)) {
1592 printLibError(status);
1593 *funcRet = 1;
1594 return (ret);
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"));
1609 return (0);
1613 * Print all initiator node attributes
1615 static int
1616 listNode(int *funcRet)
1618 IMA_OID initiatorOid;
1619 IMA_NODE_PROPERTIES nodeProps;
1620 IMA_STATUS status;
1621 int ret;
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;
1628 int i;
1630 assert(funcRet != NULL);
1632 ret = getNodeProps(&nodeProps);
1633 if (ret != 0) {
1634 return (ret);
1637 if (nodeProps.nameValid == IMA_FALSE) {
1638 return (INVALID_NODE_NAME);
1641 /* Find Sun initiator */
1642 ret = sunInitiatorFind(&initiatorOid);
1643 if (ret > 0) {
1644 (void) fprintf(stderr, "%s: %s\n",
1645 cmdName, gettext("no initiator found"));
1648 if (ret != 0) {
1649 return (ret);
1651 /* Begin output */
1652 (void) fprintf(stdout, gettext("%s: %ws\n"),
1653 gettext("Initiator node name"),
1654 nodeProps.name);
1655 (void) fprintf(stdout, gettext("Initiator node alias: "));
1656 if (nodeProps.aliasValid == IMA_TRUE) {
1657 (void) fprintf(stdout, gettext("%ws\n"), nodeProps.alias);
1658 } else {
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);
1670 } else {
1671 printLibError(status);
1672 *funcRet = 1;
1673 return (ret);
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);
1681 } else {
1682 printLibError(status);
1683 *funcRet = 1;
1684 return (ret);
1687 /* Get authentication type for this lhba */
1688 status = IMA_GetInUseInitiatorAuthMethods(initiatorOid, &maxEntries,
1689 &methodList[0]);
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"));
1694 } else {
1695 for (i = 0; i < maxEntries; i++) {
1696 if (i > 0) {
1697 (void) fprintf(stdout, "|");
1699 switch (methodList[i]) {
1700 case IMA_AUTHMETHOD_NONE:
1701 (void) fprintf(stdout, gettext("NONE"));
1702 break;
1703 case IMA_AUTHMETHOD_CHAP:
1704 (void) fprintf(stdout, gettext("CHAP"));
1705 listCHAPName(initiatorOid);
1706 break;
1707 default:
1708 (void) fprintf(stdout,
1709 gettext("unknown type"));
1710 break;
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,
1724 radiusConfig.port);
1725 } else {
1726 (void) fprintf(stdout, "%s", gettext("NONE"));
1728 } else {
1729 (void) fprintf(stdout, "%s", gettext("NONE"));
1731 (void) fprintf(stdout, "\n");
1733 status = SUN_IMA_GetInitiatorRadiusAccess(initiatorOid,
1734 &radiusAccess);
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"));
1739 } else {
1740 (void) fprintf(stdout, "%s", gettext("disabled"));
1742 } else if (status == IMA_ERROR_OBJECT_NOT_FOUND) {
1743 (void) fprintf(stdout, "%s", gettext("disabled"));
1744 } else {
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);
1755 return (ret);
1759 * Print discovery addresses
1761 static int
1762 listDiscoveryAddress(int objectLen, char *objects[], cmdOptions_t *options,
1763 int *funcRet)
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;
1770 IMA_STATUS status;
1771 wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
1772 int ret;
1773 boolean_t object = B_FALSE;
1774 int outerLoop;
1775 boolean_t found;
1776 boolean_t verbose = B_FALSE;
1777 int i, j;
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);
1785 if (ret > 0) {
1786 (void) fprintf(stderr, "%s: %s\n",
1787 cmdName, gettext("no initiator found"));
1790 if (ret != 0) {
1791 return (ret);
1794 for (; optionList->optval; optionList++) {
1795 switch (optionList->optval) {
1796 case 'v':
1797 verbose = B_TRUE;
1798 break;
1799 default:
1800 (void) fprintf(stderr, "%s: %c: %s\n",
1801 cmdName, optionList->optval,
1802 gettext("unknown option"));
1803 return (1);
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) {
1813 object = B_TRUE;
1814 outerLoop = objectLen;
1815 } else {
1816 object = B_FALSE;
1817 outerLoop = 1;
1820 status = SUN_IMA_GetDiscoveryAddressPropertiesList(
1821 &discoveryAddressPropertiesList);
1822 if (!IMA_SUCCESS(status)) {
1823 printLibError(status);
1824 *funcRet = 1;
1825 return (ret);
1828 for (i = 0; i < outerLoop; i++) {
1829 if (object) {
1830 /* initialize */
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",
1837 cmdName,
1838 gettext("conversion error"));
1839 ret = 1;
1840 continue;
1844 * if one or more objects were input,
1845 * get the values
1847 if (getTargetAddress(DISCOVERY_ADDRESS,
1848 objects[i], &address) != 0) {
1849 ret = 1;
1850 continue;
1853 for (found = B_FALSE, j = 0;
1854 j < discoveryAddressPropertiesList->discAddrCount;
1855 j++) {
1856 discAddrProps =
1857 discoveryAddressPropertiesList->props[j];
1860 * Compare the discovery address with the input if
1861 * one was input
1863 if (object &&
1864 ipAddressesEqual(discAddrProps.discoveryAddress,
1865 address) && (discAddrProps.discoveryAddress.
1866 portNumber == address.portNumber)) {
1867 found = B_TRUE;
1870 if (!object || found) {
1871 /* Print summary - always */
1872 if (discAddrProps.discoveryAddress.
1873 hostnameIpAddress.id.ipAddress.
1874 ipv4Address) {
1875 (void) inet_ntop(AF_INET, discAddrProps.
1876 discoveryAddress.hostnameIpAddress.
1877 id.ipAddress.ipAddress, sAddr,
1878 sizeof (sAddr));
1879 (void) fprintf(stdout,
1880 "Discovery Address: %s:%u\n",
1881 sAddr, discAddrProps.
1882 discoveryAddress.portNumber);
1883 } else {
1884 (void) inet_ntop(AF_INET6,
1885 discAddrProps.
1886 discoveryAddress.hostnameIpAddress.
1887 id.ipAddress.ipAddress, sAddr,
1888 sizeof (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) {
1900 break;
1904 * Issue sendTargets only when an addr is
1905 * specified.
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 "\
1912 "targets."));
1913 *funcRet = 1;
1914 continue;
1916 printSendTargets(pList);
1919 if (found) {
1920 /* we found the discovery address - break */
1921 break;
1925 * There was an object entered but we didn't
1926 * find it.
1928 if (object && !found) {
1929 (void) fprintf(stdout, "%s: %s\n",
1930 objects[i], gettext("not found"));
1933 return (ret);
1937 * Print ISNS Server addresses
1939 static int
1940 listISNSServerAddress(int objectLen, char *objects[], cmdOptions_t *options,
1941 int *funcRet)
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;
1948 IMA_STATUS status;
1949 wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
1950 int ret;
1951 boolean_t object = B_FALSE;
1952 int outerLoop;
1953 boolean_t found;
1954 boolean_t showTarget = B_FALSE;
1955 int i, j;
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);
1963 if (ret > 0) {
1964 (void) fprintf(stderr, "%s: %s\n",
1965 cmdName, gettext("no initiator found"));
1968 if (ret != 0) {
1969 return (ret);
1972 for (; optionList->optval; optionList++) {
1973 switch (optionList->optval) {
1974 case 'v':
1975 showTarget = B_TRUE;
1976 break;
1977 default:
1978 (void) fprintf(stderr, "%s: %c: %s\n",
1979 cmdName, optionList->optval,
1980 gettext("unknown option"));
1981 return (1);
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) {
1991 object = B_TRUE;
1992 outerLoop = objectLen;
1993 } else {
1994 object = B_FALSE;
1995 outerLoop = 1;
1998 status = SUN_IMA_GetISNSServerAddressPropertiesList(
1999 &discoveryAddressPropertiesList);
2000 if (!IMA_SUCCESS(status)) {
2001 printLibError(status);
2002 *funcRet = 1;
2003 return (ret);
2006 for (i = 0; i < outerLoop; i++) {
2007 if (object) {
2008 /* initialize */
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",
2015 cmdName,
2016 gettext("conversion error"));
2017 ret = 1;
2018 continue;
2022 * if one or more objects were input,
2023 * get the values
2025 if (getTargetAddress(ISNS_SERVER_ADDRESS,
2026 objects[i], &address) != 0) {
2027 ret = 1;
2028 continue;
2031 for (found = B_FALSE, j = 0;
2032 j < discoveryAddressPropertiesList->discAddrCount;
2033 j++) {
2034 discAddrProps =
2035 discoveryAddressPropertiesList->props[j];
2038 * Compare the discovery address with the input if
2039 * one was input
2041 if (object &&
2042 ipAddressesEqual(discAddrProps.discoveryAddress,
2043 address) &&
2044 (discAddrProps.discoveryAddress.portNumber ==
2045 address.portNumber)) {
2046 found = B_TRUE;
2049 if (!object || found) {
2050 /* Print summary - always */
2051 if (discAddrProps.discoveryAddress.
2052 hostnameIpAddress.id.ipAddress.
2053 ipv4Address) {
2054 (void) inet_ntop(AF_INET, discAddrProps.
2055 discoveryAddress.hostnameIpAddress.
2056 id.ipAddress.ipAddress, sAddr,
2057 sizeof (sAddr));
2058 } else {
2059 (void) inet_ntop(AF_INET6,
2060 discAddrProps.
2061 discoveryAddress.hostnameIpAddress.
2062 id.ipAddress.ipAddress, sAddr,
2063 sizeof (sAddr));
2065 (void) fprintf(stdout,
2066 "iSNS Server IP Address: %s:%u\n",
2067 sAddr,
2068 discAddrProps.discoveryAddress.portNumber);
2071 if ((!object || found) && showTarget) {
2072 IMA_NODE_PROPERTIES nodeProps;
2074 if (getNodeProps(&nodeProps) != 0) {
2075 break;
2079 * Issue sendTargets only when an addr is
2080 * specified.
2082 status = SUN_IMA_RetrieveISNSServerTargets(
2083 discAddrProps.discoveryAddress,
2084 &pList);
2085 if (!IMA_SUCCESS(status)) {
2087 * Check if the discovery mode is
2088 * disabled.
2090 if (status ==
2091 IMA_ERROR_OBJECT_NOT_FOUND) {
2092 (void) fprintf(stderr, "%s\n",
2093 gettext("\tiSNS "\
2094 "discovery "\
2095 "mode "\
2096 "disabled. "\
2097 "No targets "\
2098 "to report."));
2100 } else {
2101 (void) fprintf(stderr, "%s\n",
2102 gettext("\tUnable "\
2103 "to get "\
2104 "targets."));
2106 continue;
2108 printSendTargets(pList);
2111 if (found) {
2112 /* we found the discovery address - break */
2113 break;
2117 * There was an object entered but we didn't
2118 * find it.
2120 if (object && !found) {
2121 (void) fprintf(stdout, "%s: %s\n",
2122 objects[i], gettext("not found"));
2125 return (ret);
2129 * Print static configuration targets
2131 static int
2132 listStaticConfig(int operandLen, char *operand[], int *funcRet)
2134 IMA_STATUS status;
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];
2140 wchar_t wcCol;
2141 char sAddr[SUN_IMA_IP_ADDRESS_PORT_LEN];
2142 int ret;
2143 boolean_t object = B_FALSE;
2144 int outerLoop;
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;
2149 boolean_t isIpv6;
2150 int i, j;
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);
2160 if (ret > 0) {
2161 (void) fprintf(stderr, "%s: %s\n",
2162 cmdName, gettext("no initiator found"));
2165 if (ret != 0) {
2166 return (ret);
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) {
2175 object = B_TRUE;
2176 outerLoop = operandLen;
2177 } else {
2178 object = B_FALSE;
2179 outerLoop = 1;
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"));
2186 return (1);
2189 status = IMA_GetStaticDiscoveryTargetOidList(initiatorOid,
2190 &staticTargetList);
2191 if (!IMA_SUCCESS(status)) {
2192 printLibError(status);
2193 *funcRet = 1;
2194 return (ret);
2197 for (i = 0; i < outerLoop; i++) {
2198 if (object) {
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,
2205 &port,
2206 &tpgtSpecified,
2207 &tpgt,
2208 &isIpv6) != PARSE_TARGET_OK) {
2209 ret = 1;
2210 continue;
2214 for (found = B_FALSE, j = 0; j < staticTargetList->oidCount;
2215 j++) {
2216 boolean_t isIpv6 = B_FALSE;
2217 IMA_UINT16 stpgt;
2218 IMA_BOOL defaultTpgt;
2220 matched = B_FALSE;
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);
2229 *funcRet = 1;
2230 return (ret);
2233 stpgt = staticTargetProps.staticTarget.targetAddress.
2234 tpgt;
2236 defaultTpgt = staticTargetProps.staticTarget.
2237 targetAddress.defaultTpgt;
2239 isIpv6 = !staticTargetProps.staticTarget.targetAddress.
2240 imaStruct.hostnameIpAddress.id.ipAddress.
2241 ipv4Address;
2244 * Compare the static target name with the input if
2245 * one was input
2248 if (object &&
2249 (targetNamesEqual(
2250 staticTargetProps.staticTarget.targetName,
2251 staticTargetName) == B_TRUE)) {
2252 /* targetName found - found = B_TRUE */
2253 found = B_TRUE;
2254 if (targetAddressSpecified == B_FALSE) {
2255 matched = B_TRUE;
2256 } else {
2258 if (staticTargetProps.staticTarget.
2259 targetAddress.imaStruct.
2260 hostnameIpAddress.id.ipAddress.
2261 ipv4Address == IMA_TRUE) {
2262 (void) inet_ntop(AF_INET,
2263 staticTargetProps.
2264 staticTarget.targetAddress.
2265 imaStruct.hostnameIpAddress.id.
2266 ipAddress.ipAddress, tmpStr,
2267 sizeof (tmpStr));
2268 } else {
2269 (void) inet_ntop(AF_INET6,
2270 staticTargetProps.
2271 staticTarget.targetAddress.
2272 imaStruct.hostnameIpAddress.id.
2273 ipAddress.ipAddress, tmpStr,
2274 sizeof (tmpStr));
2277 if (mbstowcs(tmpTargetAddress, tmpStr,
2278 SUN_IMA_IP_ADDRESS_PORT_LEN) ==
2279 (size_t)-1) {
2280 (void) fprintf(stderr, "%s: %s\n",
2281 cmdName,
2282 gettext("conversion error"));
2283 ret = 1;
2284 continue;
2287 if (wcsncmp(tmpTargetAddress,
2288 staticTargetAddress,
2289 SUN_IMA_IP_ADDRESS_PORT_LEN)
2290 == 0 &&
2291 staticTargetProps.
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
2304 * match is found.
2306 if ((tpgt == stpgt &&
2307 tpgtSpecified == B_TRUE &&
2308 defaultTpgt == IMA_FALSE) ||
2309 (tpgt == stpgt &&
2310 tpgtSpecified == B_FALSE &&
2311 defaultTpgt == IMA_TRUE)) {
2312 matched = B_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,
2327 staticTargetProps.
2328 staticTarget.targetAddress.
2329 imaStruct.hostnameIpAddress.id.
2330 ipAddress.ipAddress, sAddr,
2331 sizeof (sAddr));
2332 (void) fprintf(stdout, "%s:%d",
2333 sAddr,
2334 staticTargetProps.staticTarget.
2335 targetAddress.imaStruct.portNumber);
2336 } else {
2337 (void) inet_ntop(AF_INET6,
2338 staticTargetProps.
2339 staticTarget.targetAddress.
2340 imaStruct.hostnameIpAddress.id.
2341 ipAddress.ipAddress, sAddr,
2342 sizeof (sAddr));
2343 (void) fprintf(stdout, "[%s]:%d",
2344 sAddr,
2345 staticTargetProps.staticTarget.
2346 targetAddress.imaStruct.portNumber);
2349 if (staticTargetProps.staticTarget.
2350 targetAddress.
2351 defaultTpgt == IMA_FALSE) {
2352 (void) fprintf(stdout, ",%d\n",
2353 staticTargetProps.
2354 staticTarget.targetAddress.tpgt);
2355 } else {
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
2369 * find it.
2371 if (object && !found) {
2372 (void) fprintf(stdout, "%s: %s\n",
2373 operand[i], gettext("not found"));
2374 ret = 1; /* DIY test fix */
2377 return (ret);
2381 * Print targets
2383 /*ARGSUSED*/
2384 static int
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;
2391 IMA_STATUS status;
2392 IMA_OID_LIST *pConnList;
2393 SUN_IMA_CONN_PROPERTIES *connProps;
2395 int ret;
2396 wchar_t targetName[MAX_ISCSI_NAME_LEN + 1];
2397 wchar_t targetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
2398 int outerLoop;
2399 boolean_t found;
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;
2405 int i, j;
2406 cmdOptions_t *optionList = options;
2407 boolean_t tpgtSpecified = B_FALSE;
2408 IMA_UINT16 port = 0;
2409 uint16_t tpgt;
2411 assert(funcRet != NULL);
2413 /* Find Sun initiator */
2414 ret = sunInitiatorFind(&initiatorOid);
2415 if (ret > 0) {
2416 (void) fprintf(stderr, "%s: %s\n",
2417 cmdName, gettext("no initiator found"));
2420 if (ret != 0) {
2421 return (ret);
2424 for (; optionList->optval; optionList++) {
2425 switch (optionList->optval) {
2426 case 'S':
2427 scsi_target = B_TRUE;
2428 break;
2429 case 'v':
2430 verbose = B_TRUE;
2431 break;
2432 default:
2433 (void) fprintf(stderr, "%s: %c: %s\n",
2434 cmdName, optionList->optval,
2435 gettext("unknown option"));
2436 return (1);
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;
2448 } else {
2449 operandEntered = B_FALSE;
2450 outerLoop = 1;
2453 status = SUN_IMA_GetSessionOidList(initiatorOid, &targetList);
2454 if (!IMA_SUCCESS(status)) {
2455 printLibError(status);
2456 *funcRet = 1;
2457 return (ret);
2460 for (i = 0; i < outerLoop; i++) {
2462 tpgtSpecified = B_FALSE;
2463 if (operandEntered) {
2464 if (parseTarget(objects[i],
2465 &targetName[0],
2466 MAX_ISCSI_NAME_LEN + 1,
2467 &targetAddressSpecified,
2468 &targetAddress[0],
2469 SUN_IMA_IP_ADDRESS_PORT_LEN,
2470 &port,
2471 &tpgtSpecified,
2472 &tpgt,
2473 &isIpv6) != PARSE_TARGET_OK) {
2474 ret = 1;
2475 continue;
2478 for (found = B_FALSE, j = 0; j < targetList->oidCount; j++) {
2479 status = SUN_IMA_GetTargetProperties(
2480 targetList->oids[j],
2481 &targetProps);
2482 if (!IMA_SUCCESS(status)) {
2483 printLibError(status);
2484 (void) IMA_FreeMemory(targetList);
2485 *funcRet = 1;
2486 return (ret);
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
2494 * target
2496 if (operandEntered) {
2497 if (targetNamesEqual(targetProps.imaProps.name,
2498 targetName) == B_TRUE) {
2499 if (tpgtSpecified == B_TRUE) {
2500 if (targetProps.
2501 defaultTpgtConf ==
2502 IMA_FALSE &&
2503 targetProps.
2504 tpgtConf == tpgt) {
2505 found = B_TRUE;
2506 } else {
2508 * tpgt does not match,
2509 * move on to next
2510 * target
2512 continue;
2514 } else {
2515 found = B_TRUE;
2517 } else {
2519 * target name does not match, move on
2520 * to next target
2522 continue;
2526 /* print summary - always */
2527 (void) fprintf(stdout, gettext("%s: %ws\n"),
2528 gettext("Target"), targetProps.imaProps.name);
2530 /* Alias */
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);
2535 } else {
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]);
2556 pConnList = NULL;
2557 status = SUN_IMA_GetConnOidList(
2558 &targetList->oids[j],
2559 &pConnList);
2561 if (!IMA_SUCCESS(status)) {
2562 printLibError(status);
2563 (void) IMA_FreeMemory(targetList);
2564 *funcRet = 1;
2565 return (ret);
2568 (void) fprintf(stdout, "%s%s: %lu\n",
2569 "\t",
2570 gettext("Connections"),
2571 pConnList->oidCount);
2573 if (verbose) {
2574 SUN_IMA_DIGEST_ALGORITHM_VALUE digestAlgorithms;
2576 printConnectionList("\t\t", pConnList);
2577 printDiscoveryMethod(
2578 "\t\t ",
2579 targetProps.imaProps.discoveryMethodFlags);
2580 (void) printLoginParameters(
2581 "\t\t ",
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(
2597 &digestAlgorithms,
2598 PRINT_NEGOTIATED_PARAMS);
2599 } else {
2600 (void) IMA_FreeMemory(pConnList);
2601 (void) IMA_FreeMemory(targetList);
2602 printLibError(status);
2603 *funcRet = 1;
2604 return (ret);
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(
2615 &digestAlgorithms,
2616 PRINT_NEGOTIATED_PARAMS);
2617 } else {
2618 (void) IMA_FreeMemory(pConnList);
2619 (void) IMA_FreeMemory(targetList);
2620 printLibError(status);
2621 *funcRet = 1;
2622 return (ret);
2625 (void) fprintf(stdout, "\n");
2628 if (scsi_target) {
2629 status = SUN_IMA_ReEnumeration(
2630 targetList->oids[j]);
2631 if (!IMA_SUCCESS(status)) {
2633 * Proceeds the listing
2634 * but indicates the
2635 * error in return value
2637 ret = 1;
2640 status = IMA_GetLuOidList(
2641 targetList->oids[j],
2642 &lunList);
2643 if (!IMA_SUCCESS(status)) {
2644 printLibError(status);
2645 (void) IMA_FreeMemory(targetList);
2646 *funcRet = 1;
2647 return (ret);
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);
2667 return (ret);
2672 * Print configured session information
2674 static int
2675 printConfiguredSessions(IMA_OID oid)
2677 IMA_STATUS status;
2678 const char *rtn;
2679 SUN_IMA_CONFIG_SESSIONS *pConfigSessions;
2680 char address[MAX_ADDRESS_LEN];
2681 int out;
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);
2692 } else {
2693 /* hardcoded binding */
2694 for (out = 0;
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,
2701 MAX_ADDRESS_LEN);
2702 } else {
2703 rtn = inet_ntop(AF_INET6,
2704 pConfigSessions->bindings[out].
2705 ipAddress.ipAddress, address,
2706 MAX_ADDRESS_LEN);
2708 if (rtn != NULL) {
2709 (void) printf("%s ", address);
2712 (void) fprintf(stdout, "\n");
2714 } else {
2715 free(pConfigSessions);
2716 printLibError(status);
2717 return (1);
2720 free(pConfigSessions);
2721 return (0);
2725 * Print target parameters
2727 static int
2728 listTargetParam(int operandLen, char *operand[], cmdOptions_t *options,
2729 int *funcRet)
2731 IMA_STATUS status;
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;
2737 IMA_BOOL bidirAuth;
2738 int ret;
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;
2746 int outerLoop;
2747 boolean_t found;
2748 int i, j;
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);
2759 if (ret > 0) {
2760 (void) fprintf(stderr, "%s: %s\n",
2761 cmdName, gettext("no initiator found"));
2764 if (ret != 0) {
2765 return (ret);
2768 for (; optionList->optval; optionList++) {
2769 switch (optionList->optval) {
2770 case 'v':
2771 verbose = B_TRUE;
2772 break;
2773 default:
2774 (void) fprintf(stderr, "%s: %c: %s\n",
2775 cmdName, optionList->optval,
2776 gettext("unknown option"));
2777 return (1);
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;
2789 } else {
2790 operandEntered = B_FALSE;
2791 outerLoop = 1;
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);
2807 *funcRet = 1;
2808 return (ret);
2811 for (i = 0; i < outerLoop; i++) {
2812 if (operandEntered) {
2813 if (parseTarget(operand[i],
2814 &targetName[0],
2815 MAX_ISCSI_NAME_LEN + 1,
2816 &targetAddressSpecified,
2817 &targetAddress[0],
2818 SUN_IMA_IP_ADDRESS_PORT_LEN,
2819 &port,
2820 &tpgtSpecified,
2821 &tpgt,
2822 &isIpv6) != PARSE_TARGET_OK) {
2823 ret = 1;
2824 continue;
2827 for (j = 0; j < targetList->oidCount; j++) {
2828 found = B_FALSE;
2829 printObject = B_FALSE;
2830 status = SUN_IMA_GetTargetProperties(
2831 targetList->oids[j],
2832 &targetProps);
2833 if (!IMA_SUCCESS(status)) {
2834 printLibError(status);
2835 (void) IMA_FreeMemory(targetList);
2836 *funcRet = 1;
2837 return (ret);
2841 * Compare the target name with the input if
2842 * one was input
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.
2853 found = B_TRUE;
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;
2865 if (printObject) {
2866 (void) fprintf(stdout, gettext("%s: %ws\n"),
2867 gettext("Target"),
2868 targetProps.imaProps.name);
2870 (void) fprintf(stdout,
2871 "\t%s: ", gettext("Alias"));
2872 if (wslen(targetProps.imaProps.alias) >
2873 (size_t)0) {
2874 (void) fprintf(stdout,
2875 gettext("%ws\n"),
2876 targetProps.imaProps.alias);
2877 } else {
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],
2888 &bidirAuth);
2889 if (IMA_SUCCESS(status)) {
2890 if (bidirAuth == IMA_TRUE) {
2891 (void) fprintf(stdout,
2892 gettext("enabled"));
2893 } else {
2894 (void) fprintf(stdout,
2895 gettext("disabled"));
2897 } else {
2898 (void) fprintf(stdout,
2899 gettext("disabled"));
2901 (void) fprintf(stdout, "\n");
2903 /* Get authentication type for this target */
2904 status = SUN_IMA_GetTargetAuthMethods(
2905 initiatorOid,
2906 targetList->oids[j],
2907 &maxEntries,
2908 &methodList[0]);
2909 (void) fprintf(stdout, "\t%s: ",
2910 gettext("Authentication Type"));
2911 if (!IMA_SUCCESS(status)) {
2913 * No authentication method define
2914 * NONE by default.
2916 (void) fprintf(stdout, gettext("NONE"));
2917 } else {
2918 for (i = 0; i < maxEntries; i++) {
2919 if (i > 0) {
2920 (void) fprintf(stdout,
2921 "|");
2923 switch (methodList[i]) {
2924 case IMA_AUTHMETHOD_NONE:
2925 (void) fprintf(stdout,
2926 gettext("NONE"));
2927 break;
2929 case IMA_AUTHMETHOD_CHAP:
2930 (void) fprintf(stdout,
2931 gettext("CHAP"));
2932 listCHAPName(
2933 targetList->
2934 oids[j]);
2935 break;
2937 default:
2938 (void) fprintf(stdout,
2939 gettext(
2940 "unknown "
2941 "type"));
2942 break;
2946 (void) fprintf(stdout, "\n");
2947 if (printLoginParameters("\t",
2948 targetList->oids[j],
2949 PRINT_CONFIGURED_PARAMS)
2950 != 0) {
2951 (void) IMA_FreeMemory(targetList);
2952 *funcRet = 1;
2953 return (ret);
2956 /* Get Digest configuration */
2957 status = SUN_IMA_GetHeaderDigest(
2958 targetList->oids[j],
2959 &digestAlgorithms);
2960 if (IMA_SUCCESS(status)) {
2961 (void) fprintf(stdout, "\t\t%s: ",
2962 gettext("Header Digest"));
2963 printDigestAlgorithm(&digestAlgorithms,
2964 PRINT_CONFIGURED_PARAMS);
2965 } else {
2966 printLibError(status);
2967 *funcRet = 1;
2968 return (ret);
2971 status = SUN_IMA_GetDataDigest(
2972 targetList->oids[j],
2973 &digestAlgorithms);
2974 if (IMA_SUCCESS(status)) {
2975 (void) fprintf(stdout, "\t\t%s: ",
2976 gettext("Data Digest"));
2977 printDigestAlgorithm(&digestAlgorithms,
2978 PRINT_CONFIGURED_PARAMS);
2979 } else {
2980 printLibError(status);
2981 *funcRet = 1;
2982 return (ret);
2985 /* print tunable parameters infomation */
2986 if (printTunableParameters(
2987 targetList->oids[j]) != 0) {
2988 *funcRet = 1;
2989 return (ret);
2992 /* print configured session information */
2993 if (printConfiguredSessions(
2994 targetList->oids[j]) != 0) {
2995 *funcRet = 1;
2996 return (ret);
2999 (void) fprintf(stdout, "\n");
3002 if (found) {
3003 break;
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);
3014 return (ret);
3018 * Modify discovery attributes
3020 static int
3021 modifyDiscovery(cmdOptions_t *options, int *funcRet)
3023 IMA_OID oid;
3024 IMA_STATUS status;
3025 IMA_BOOL setDiscovery;
3026 IMA_HOST_ID hostId;
3028 int ret;
3029 cmdOptions_t *optionList = options;
3031 assert(funcRet != NULL);
3033 /* Find Sun initiator */
3034 ret = sunInitiatorFind(&oid);
3035 if (ret > 0) {
3036 (void) fprintf(stderr, "%s: %s\n",
3037 cmdName, gettext("no initiator found"));
3040 if (ret != 0) {
3041 return (ret);
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)
3049 == 0) {
3050 setDiscovery = IMA_FALSE;
3051 } else {
3052 (void) fprintf(stderr, "%s: %s\n",
3053 cmdName, gettext("invalid option argument"));
3054 return (1);
3057 switch (optionList->optval) {
3058 case 's':
3059 /* Set static discovery */
3060 status = IMA_SetStaticDiscovery(oid,
3061 setDiscovery);
3062 if (!IMA_SUCCESS(status)) {
3063 printLibError(status);
3064 *funcRet = 1;
3065 return (ret);
3067 break;
3068 case 't':
3069 /* Set send targets discovery */
3070 status = IMA_SetSendTargetsDiscovery(oid,
3071 setDiscovery);
3072 if (!IMA_SUCCESS(status)) {
3073 printLibError(status);
3074 *funcRet = 1;
3075 return (ret);
3077 break;
3078 case 'i':
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);
3085 *funcRet = 1;
3086 return (ret);
3088 break;
3089 default:
3090 (void) fprintf(stderr, "%s: %c: %s\n",
3091 cmdName, optionList->optval,
3092 gettext("unknown option"));
3093 return (1);
3097 return (ret);
3101 * Set the initiator node's authentication method
3103 static int
3104 modifyNodeAuthParam(IMA_OID oid, int param, char *chapName, int *funcRet)
3106 IMA_INITIATOR_AUTHPARMS authParams;
3107 IMA_STATUS status;
3108 int ret;
3109 int secretLen = MAX_CHAP_SECRET_LEN;
3110 int nameLen = 0;
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,
3122 &authParams);
3124 switch (param) {
3125 case AUTH_NAME:
3126 if (chapName == NULL) {
3127 (void) fprintf(stderr, "CHAP name cannot be NULL.\n");
3128 return (1);
3130 nameLen = strlen(chapName);
3131 if (nameLen == 0) {
3132 (void) fprintf(stderr, "CHAP name cannot be empty.\n");
3133 return (1);
3135 if (nameLen > ISCSI_MAX_C_USER_LEN) {
3136 (void) fprintf(stderr, "CHAP name is too long.\n");
3137 return (1);
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;
3144 break;
3146 case AUTH_PASSWORD :
3147 ret = getSecret((char *)&chapSecret[0], &secretLen,
3148 MIN_CHAP_SECRET_LEN, MAX_CHAP_SECRET_LEN);
3150 if (ret != 0) {
3151 return (ret);
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;
3159 break;
3161 default:
3162 (void) fprintf(stderr, "Invalid auth parameter %d\n", param);
3163 return (1);
3166 status = IMA_SetInitiatorAuthParms(oid, IMA_AUTHMETHOD_CHAP,
3167 &authParams);
3168 if (!IMA_SUCCESS(status)) {
3169 printLibError(status);
3170 *funcRet = 1;
3172 return (ret);
3176 * Set the target's authentication method
3178 static int
3179 modifyTargetAuthParam(IMA_OID oid, int param, char *chapName, int *funcRet)
3181 IMA_INITIATOR_AUTHPARMS authParams;
3182 IMA_STATUS status;
3183 int ret;
3184 int secretLen = MAX_CHAP_SECRET_LEN;
3185 int nameLen = 0;
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,
3197 &authParams);
3199 switch (param) {
3200 case AUTH_NAME:
3201 if (chapName == NULL) {
3202 (void) fprintf(stderr, "CHAP name cannot be NULL.\n");
3203 return (1);
3205 nameLen = strlen(chapName);
3206 if (nameLen == 0) {
3207 (void) fprintf(stderr, "CHAP name cannot be empty.\n");
3208 return (1);
3210 if (nameLen > ISCSI_MAX_C_USER_LEN) {
3211 (void) fprintf(stderr, "CHAP name is too long.\n");
3212 return (1);
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;
3219 break;
3221 case AUTH_PASSWORD :
3222 ret = getSecret((char *)&chapSecret[0], &secretLen,
3223 1, MAX_CHAP_SECRET_LEN);
3225 if (ret != 0) {
3226 return (ret);
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;
3234 break;
3236 default:
3237 (void) fprintf(stderr, "Invalid auth parameter %d\n", param);
3238 return (1);
3241 status = SUN_IMA_SetTargetAuthParams(oid, IMA_AUTHMETHOD_CHAP,
3242 &authParams);
3243 if (!IMA_SUCCESS(status)) {
3244 printLibError(status);
3245 *funcRet = 1;
3247 return (0);
3250 static int
3251 modifyTargetBidirAuthFlag(IMA_OID targetOid, char *optarg, int *funcRet)
3253 IMA_BOOL boolValue;
3254 IMA_STATUS status;
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;
3262 } else {
3263 (void) fprintf(stderr, "%s: %s %s\n",
3264 cmdName, gettext("invalid option argument"), optarg);
3265 return (1);
3268 status = SUN_IMA_SetTargetBidirAuthFlag(targetOid, &boolValue);
3269 if (!IMA_SUCCESS(status)) {
3270 printLibError(status);
3271 *funcRet = 1;
3273 return (0);
3276 static int
3277 modifyConfiguredSessions(IMA_OID targetOid, char *optarg)
3279 SUN_IMA_CONFIG_SESSIONS *pConfigSessions;
3280 IMA_STATUS status;
3281 int sessions;
3282 int size;
3283 char tmp[1024];
3284 boolean_t isIpv6 = B_FALSE;
3285 uint16_t port;
3286 char address[MAX_ADDRESS_LEN];
3287 char *commaPos;
3288 char *addressPos;
3289 int rtn;
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) {
3306 return (1);
3309 /* setup pConfigSessions */
3310 pConfigSessions->bound = IMA_FALSE;
3311 pConfigSessions->in = sessions;
3312 pConfigSessions->out = 0;
3313 } else {
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.
3321 sessions = 1;
3322 commaPos = strchr(optarg, ',');
3323 while (commaPos != NULL) {
3324 sessions++;
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) {
3333 return (1);
3336 /* setup pConfigSessions */
3337 pConfigSessions->bound = IMA_TRUE;
3338 pConfigSessions->in = sessions;
3339 pConfigSessions->out = 0;
3341 /* Now fill in the binding information. */
3342 sessions = 0;
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) {
3356 *commaPos++ = 0x00;
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);
3367 return (1);
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);
3377 } else {
3378 pConfigSessions->bindings[sessions].ipAddress.
3379 ipv4Address =
3380 IMA_FALSE;
3381 rtn = inet_pton(AF_INET6, address,
3382 pConfigSessions->bindings[sessions].
3383 ipAddress.ipAddress);
3385 if (rtn == 0) {
3386 /* inet_pton found address invalid */
3387 free(pConfigSessions);
3388 printLibError(IMA_ERROR_INVALID_PARAMETER);
3389 return (1);
3392 /* update addressPos to next address */
3393 sessions++;
3394 addressPos = commaPos;
3398 /* issue SUN_IMA request */
3399 status = SUN_IMA_SetConfigSessions(targetOid,
3400 pConfigSessions);
3401 if (!IMA_SUCCESS(status)) {
3402 printLibError(status);
3403 free(pConfigSessions);
3404 return (1);
3407 free(pConfigSessions);
3408 return (0);
3411 static int
3412 getAuthMethodValue(char *method, IMA_AUTHMETHOD *value)
3414 if (strcasecmp(method, "chap") == 0) {
3415 *value = IMA_AUTHMETHOD_CHAP;
3416 return (0);
3419 if (strcasecmp(method, "none") == 0) {
3420 *value = IMA_AUTHMETHOD_NONE;
3421 return (0);
3424 return (1);
3429 * Set the authentication method
3430 * Currently only supports CHAP and NONE
3432 static int
3433 modifyNodeAuthMethod(IMA_OID oid, char *optarg, int *funcRet)
3435 IMA_AUTHMETHOD methodList[MAX_AUTH_METHODS];
3436 IMA_UINT methodCount = 0;
3437 IMA_STATUS status;
3438 IMA_AUTHMETHOD value;
3439 char *method;
3440 char *commaPos;
3442 assert(funcRet != NULL);
3445 * optarg will be a , delimited set of auth methods, in order
3446 * of preference
3447 * if any values here are incorrect, return without setting
3448 * anything.
3450 method = optarg;
3452 commaPos = strchr(optarg, ',');
3454 while (commaPos && methodCount < MAX_AUTH_METHODS) {
3455 *commaPos = '\0';
3456 if (getAuthMethodValue(method, &value) != 0) {
3457 (void) fprintf(stderr, "%s: a: %s\n",
3458 cmdName, gettext("invalid option argument"));
3459 return (1);
3461 methodList[methodCount++] = value;
3462 commaPos++;
3463 method = commaPos;
3464 commaPos = strchr(method, ',');
3466 /* Should not find more method specified - if found, error */
3467 if (commaPos) {
3468 (void) fprintf(stderr, "%s: -a: %s\n",
3469 cmdName, gettext("invalid option argument"));
3470 return (1);
3472 if (getAuthMethodValue(method, &value) != 0) {
3473 (void) fprintf(stderr, "%s: -a: %s\n",
3474 cmdName, gettext("invalid option argument"));
3475 return (1);
3477 methodList[methodCount++] = value;
3479 status = IMA_SetInitiatorAuthMethods(oid, methodCount, &methodList[0]);
3480 if (!IMA_SUCCESS(status)) {
3481 printLibError(status);
3482 *funcRet = 1;
3484 return (0);
3487 static int
3488 modifyTargetAuthMethod(IMA_OID oid, char *optarg, int *funcRet)
3490 IMA_AUTHMETHOD methodList[MAX_AUTH_METHODS];
3491 IMA_UINT methodCount = 0;
3492 IMA_STATUS status;
3493 IMA_AUTHMETHOD value;
3494 char *method;
3495 char *commaPos;
3497 assert(funcRet != NULL);
3500 * optarg will be a , delimited set of auth methods, in order
3501 * of preference
3502 * if any values here are incorrect, return without setting
3503 * anything.
3505 method = optarg;
3507 commaPos = strchr(optarg, ',');
3509 while (commaPos && methodCount < MAX_AUTH_METHODS) {
3510 *commaPos = '\0';
3511 if (getAuthMethodValue(method, &value) != 0) {
3512 (void) fprintf(stderr, "%s: a: %s\n",
3513 cmdName, gettext("invalid option argument"));
3514 return (1);
3516 methodList[methodCount++] = value;
3517 commaPos++;
3518 method = commaPos;
3519 commaPos = strchr(method, ',');
3521 /* Should not find more method specified - if found, error */
3522 if (commaPos) {
3523 (void) fprintf(stderr, "%s: -a: %s\n",
3524 cmdName, gettext("invalid option argument"));
3525 return (1);
3527 if (getAuthMethodValue(method, &value) != 0) {
3528 (void) fprintf(stderr, "%s: -a: %s\n",
3529 cmdName, gettext("invalid option argument"));
3530 return (1);
3532 methodList[methodCount++] = value;
3534 status = SUN_IMA_SetTargetAuthMethods(oid, &methodCount,
3535 &methodList[0]);
3536 if (!IMA_SUCCESS(status)) {
3537 printLibError(status);
3538 *funcRet = 1;
3540 return (0);
3544 * Modify the RADIUS configuration of the initiator node.
3546 * Return 0 on success.
3548 static int
3549 modifyNodeRadiusConfig(IMA_OID oid, char *optarg, int *funcRet)
3551 SUN_IMA_RADIUS_CONFIG config;
3552 IMA_STATUS status;
3553 boolean_t isIpv6 = B_FALSE;
3554 uint16_t port;
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,
3561 &port, &isIpv6) !=
3562 PARSE_ADDR_OK) {
3563 return (1);
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);
3573 *funcRet = 1;
3576 return (0);
3580 * Modify the RADIUS access flag of the initiator node.
3582 * Return 0 on success.
3584 static int
3585 modifyNodeRadiusAccess(IMA_OID oid, char *optarg, int *funcRet)
3587 IMA_BOOL radiusAccess;
3588 IMA_OID initiatorOid;
3589 IMA_STATUS status;
3590 SUN_IMA_RADIUS_CONFIG radiusConfig;
3591 int ret;
3593 assert(funcRet != NULL);
3595 /* Check if Radius Config is there */
3596 ret = sunInitiatorFind(&initiatorOid);
3597 if (ret != 0) {
3598 (void) fprintf(stderr, "%s: %s\n",
3599 cmdName, gettext("no initiator found"));
3600 return (1);
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"));
3607 *funcRet = 1;
3608 return (ret);
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"));
3615 return (1);
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;
3622 } else {
3623 (void) fprintf(stderr, "%s: %s %s\n",
3624 cmdName,
3625 gettext("invalid option argument"),
3626 optarg);
3627 return (1);
3629 status = SUN_IMA_SetInitiatorRadiusAccess(oid, radiusAccess);
3630 if (!IMA_SUCCESS(status)) {
3631 printLibError(status);
3632 *funcRet = 1;
3635 return (ret);
3639 * Modify the RADIUS shared secret.
3641 * Returns:
3642 * zero on success.
3643 * > 0 on failure.
3645 static int
3646 modifyNodeRadiusSharedSecret(IMA_OID oid, int *funcRet)
3648 IMA_BYTE radiusSharedSecret[SUN_IMA_MAX_RADIUS_SECRET_LEN + 1];
3649 IMA_OID initiatorOid;
3650 IMA_STATUS status;
3651 SUN_IMA_RADIUS_CONFIG radiusConfig;
3652 int ret;
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);
3659 if (ret != 0) {
3660 return (1);
3663 ret = sunInitiatorFind(&initiatorOid);
3664 if (ret > 0) {
3665 (void) fprintf(stderr, "%s: %s\n",
3666 cmdName, gettext("no initiator found"));
3668 if (ret != 0) {
3669 return (1);
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"));
3677 return (1);
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);
3688 *funcRet = 1;
3691 return (0);
3695 * Set initiator node attributes.
3697 static int
3698 modifyNode(cmdOptions_t *options, int *funcRet)
3700 IMA_NODE_NAME nodeName;
3701 IMA_NODE_ALIAS nodeAlias;
3702 IMA_OID oid;
3703 IMA_STATUS status;
3704 cmdOptions_t *optionList = options;
3705 int ret;
3706 iSCSINameCheckStatusType nameCheckStatus;
3707 IMA_OID sharedNodeOid;
3708 int i;
3709 int lowerCase;
3710 IMA_BOOL iscsiBoot = IMA_FALSE;
3711 IMA_BOOL mpxioEnabled = IMA_FALSE;
3712 char *mb_name = NULL;
3713 int prefixlen = 0;
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"
3724 " of root disk"));
3725 *funcRet = 1;
3726 return (1);
3730 /* Find Sun initiator */
3731 ret = sunInitiatorFind(&oid);
3732 if (ret != 0) {
3733 (void) fprintf(stderr, "%s: %s\n",
3734 cmdName, gettext("no initiator found"));
3735 return (ret);
3738 for (; optionList->optval; optionList++) {
3739 switch (optionList->optval) {
3740 case 'N':
3741 if (strlen(optionList->optarg) >=
3742 MAX_ISCSI_NAME_LEN) {
3743 (void) fprintf(stderr, "%s: %s %d\n",
3744 cmdName,
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",
3756 cmdName,
3757 gettext("conversion error"));
3758 return (1);
3761 prefixlen = strlen(ISCSI_IQN_NAME_PREFIX);
3762 mb_name = (char *)calloc(1, prefixlen + 1);
3763 if (mb_name == NULL) {
3764 return (1);
3767 if (wcstombs(mb_name, nodeName,
3768 prefixlen) == (size_t)-1) {
3769 (void) fprintf(stderr, "%s: %s\n",
3770 cmdName,
3771 gettext("conversion error"));
3772 (void) IMA_FreeMemory(mb_name);
3773 return (1);
3775 if (strncmp(mb_name, ISCSI_IQN_NAME_PREFIX,
3776 prefixlen) == 0) {
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++) {
3783 lowerCase =
3784 tolower(nodeName[i]);
3785 nodeName[i] = lowerCase;
3788 (void) IMA_FreeMemory(mb_name);
3790 /* Perform string profile checks */
3791 nameCheckStatus =
3792 iSCSINameStringProfileCheck(nodeName);
3793 iSCSINameCheckStatusDisplay(nameCheckStatus);
3794 if (nameCheckStatus != iSCSINameCheckOK) {
3795 *funcRet = 1; /* DIY message fix */
3796 return (1);
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"));
3811 return (1);
3813 oid.objectType = IMA_OBJECT_TYPE_NODE;
3814 status = IMA_SetNodeName(oid, nodeName);
3815 if (!IMA_SUCCESS(status)) {
3816 printLibError(status);
3817 *funcRet = 1;
3818 return (ret);
3820 break;
3822 case 'A':
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"));
3828 return (1);
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",
3834 cmdName,
3835 gettext("alias too long, maximum \
3836 length is:"),
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",
3845 cmdName,
3846 gettext("conversion error"));
3847 return (1);
3850 status = IMA_GetSharedNodeOid(&sharedNodeOid);
3851 if (!IMA_SUCCESS(status)) {
3852 printLibError(status);
3853 *funcRet = 1;
3854 return (ret);
3857 status = IMA_SetNodeAlias(sharedNodeOid,
3858 nodeAlias);
3859 if (!IMA_SUCCESS(status)) {
3860 printLibError(status);
3861 *funcRet = 1;
3862 return (ret);
3864 break;
3866 case 'a':
3867 if (iscsiBoot == IMA_TRUE) {
3868 (void) fprintf(stderr, "%s: %s\n",
3869 cmdName, gettext("iscsi boot, not"
3870 " allowed to change authentication"
3871 " method"));
3872 return (1);
3874 if (modifyNodeAuthMethod(oid, options->optarg,
3875 funcRet) != 0) {
3876 return (1);
3878 break;
3880 case 'R':
3881 if (modifyNodeRadiusAccess(oid, options->optarg,
3882 funcRet) != 0) {
3883 return (1);
3885 break;
3887 case 'r':
3888 if (modifyNodeRadiusConfig(oid, options->optarg,
3889 funcRet) != 0) {
3890 return (1);
3892 break;
3894 case 'P':
3895 if (modifyNodeRadiusSharedSecret(oid, funcRet)
3896 != 0) {
3897 return (1);
3899 break;
3901 case 'C':
3902 if (iscsiBoot == IMA_TRUE) {
3903 (void) fprintf(stderr, "%s: %s\n",
3904 cmdName, gettext("iscsi boot, not"
3905 " allowed to change CHAP secret"));
3906 return (1);
3908 if (modifyNodeAuthParam(oid, AUTH_PASSWORD,
3909 NULL, funcRet) != 0) {
3910 return (1);
3912 break;
3914 case 'c':
3915 if (iscsiBoot == IMA_TRUE) {
3916 if (mpxioEnabled == IMA_FALSE) {
3917 (void) fprintf(stderr,
3918 "%s: %s\n", cmdName,
3919 gettext("iscsi"
3920 " boot and MPxIO"
3921 " is disabled, not allowed"
3922 " to change number of"
3923 " sessions to be"
3924 " configured"));
3925 return (1);
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"
3935 " session"));
3937 return (1);
3939 break;
3942 case 'H':
3943 if (iscsiBoot == IMA_TRUE) {
3944 (void) fprintf(stderr, "%s: %s\n",
3945 cmdName, gettext("iscsi boot, not"
3946 " allowed to change CHAP name"));
3947 return (1);
3949 if (modifyNodeAuthParam(oid, AUTH_NAME,
3950 optionList->optarg, funcRet) != 0) {
3951 return (1);
3953 break;
3956 case 'd':
3957 if (iscsiBoot == IMA_TRUE) {
3958 if (mpxioEnabled == IMA_FALSE) {
3959 (void) fprintf(stderr,
3960 "%s: %s\n", cmdName,
3961 gettext("iscsi"
3962 " boot and MPxIO"
3963 " is disabled, not"
3964 " allowed to"
3965 " change initiator's"
3966 " login params"));
3967 return (1);
3970 if (setLoginParameter(oid, DATA_DIGEST,
3971 optionList->optarg) != 0) {
3972 return (1);
3974 break;
3976 case 'h':
3977 if (iscsiBoot == IMA_TRUE) {
3978 if (mpxioEnabled == IMA_FALSE) {
3979 (void) fprintf(stderr,
3980 "%s: %s\n", cmdName,
3981 gettext("iscsi"
3982 " boot and MPxIO"
3983 " is disabled, not"
3984 " allowed to"
3985 " change initiator's"
3986 " login params"));
3987 return (1);
3990 if (setLoginParameter(oid, HEADER_DIGEST,
3991 optionList->optarg) != 0) {
3992 return (1);
3994 break;
3996 case 'T':
3997 if (setTunableParameters(oid,
3998 optionList->optarg) != 0) {
3999 return (1);
4001 break;
4002 default:
4003 (void) fprintf(stderr, "%s: %c: %s\n",
4004 cmdName, optionList->optval,
4005 gettext("unknown option"));
4006 break;
4010 return (ret);
4014 * Modify target parameters
4016 static int
4017 modifyTargetParam(cmdOptions_t *options, char *targetName, int *funcRet)
4019 IMA_OID oid;
4020 IMA_OID targetOid;
4021 IMA_STATUS status;
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];
4026 int ret;
4027 boolean_t found;
4028 boolean_t targetAddressSpecified = B_TRUE;
4029 boolean_t tpgtSpecified = B_FALSE;
4030 boolean_t isIpv6 = B_FALSE;
4031 int i;
4032 iSCSINameCheckStatusType nameCheckStatus;
4033 IMA_UINT16 port = 0;
4034 IMA_UINT16 tpgt = 0;
4036 IMA_NODE_NAME bootTargetName;
4037 IMA_INITIATOR_AUTHPARMS bootTargetCHAP;
4038 IMA_BOOL iscsiBoot;
4039 IMA_BOOL mpxioEnabled;
4041 cmdOptions_t *optionList = options;
4043 assert(funcRet != NULL);
4045 /* Find Sun initiator */
4046 ret = sunInitiatorFind(&oid);
4047 if (ret > 0) {
4048 (void) fprintf(stderr, "%s: %s\n",
4049 cmdName, gettext("no initiator found"));
4052 if (ret != 0) {
4053 return (ret);
4056 if (parseTarget(targetName,
4057 &wcInputObject[0],
4058 MAX_ISCSI_NAME_LEN + 1,
4059 &targetAddressSpecified,
4060 &targetAddress[0],
4061 SUN_IMA_IP_ADDRESS_PORT_LEN,
4062 &port,
4063 &tpgtSpecified,
4064 &tpgt,
4065 &isIpv6) != PARSE_TARGET_OK) {
4066 return (1);
4069 /* Perform string profile checks */
4070 nameCheckStatus = iSCSINameStringProfileCheck(wcInputObject);
4071 iSCSINameCheckStatusDisplay(nameCheckStatus);
4072 if (nameCheckStatus != iSCSINameCheckOK) {
4073 return (1);
4076 status = IMA_GetTargetOidList(oid, &targetList);
4077 if (!IMA_SUCCESS(status)) {
4078 printLibError(status);
4079 *funcRet = 1;
4080 return (0);
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"
4089 " of root disk"));
4090 *funcRet = 1;
4091 return (ret);
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"
4097 " name"));
4098 *funcRet = 1;
4099 return (ret);
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"
4105 " auth param"));
4106 *funcRet = 1;
4107 return (ret);
4111 /* find target oid */
4112 for (found = B_FALSE, i = 0; i < targetList->oidCount; i++) {
4113 status = SUN_IMA_GetTargetProperties(targetList->oids[i],
4114 &targetProps);
4115 if (!IMA_SUCCESS(status)) {
4116 printLibError(status);
4117 (void) IMA_FreeMemory(targetList);
4118 *funcRet = 1;
4119 return (ret);
4123 * Compare the target name with the input name
4125 if ((targetNamesEqual(wcInputObject, targetProps.imaProps.name)
4126 == B_TRUE)) {
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.
4133 found = B_TRUE;
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
4150 * -H CHAP name set
4151 * -a authentication
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"));
4159 return (1);
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"
4166 " parameters"));
4167 return (1);
4172 if (modifyIndividualTargetParam(optionList, targetOid,
4173 funcRet) != 0) {
4174 return (ret);
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 */
4187 if (!found) {
4188 status = SUN_IMA_CreateTargetOid(wcInputObject, &targetOid);
4189 if (!IMA_SUCCESS(status)) {
4190 printLibError(status);
4191 (void) IMA_FreeMemory(targetList);
4192 *funcRet = 1;
4193 return (ret);
4195 if (modifyIndividualTargetParam(optionList, targetOid,
4196 funcRet) != 0) {
4197 return (ret);
4201 (void) IMA_FreeMemory(targetList);
4202 return (ret);
4206 * Add one or more addresses
4208 static int
4209 addAddress(int addrType, int operandLen, char *operand[], int *funcRet)
4211 IMA_STATUS status;
4212 IMA_OID oid, addressOid;
4213 SUN_IMA_TARGET_ADDRESS address;
4214 wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
4215 int ret;
4216 int i;
4218 assert(funcRet != NULL);
4220 /* Find Sun initiator */
4221 ret = sunInitiatorFind(&oid);
4222 if (ret > 0) {
4223 (void) fprintf(stderr, "%s: %s\n",
4224 cmdName, gettext("no initiator found"));
4227 if (ret != 0) {
4228 return (ret);
4232 * Format of discovery address operand:
4234 * <IP address|hostname>:<port>
4236 for (i = 0; i < operandLen; i++) {
4237 /* initialize */
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"));
4245 ret = 1;
4246 continue;
4248 if (getTargetAddress(addrType, operand[i], &address.imaStruct)
4249 != 0) {
4250 ret = 1;
4251 continue;
4253 if (addrType == DISCOVERY_ADDRESS) {
4254 status = IMA_AddDiscoveryAddress(oid,
4255 address.imaStruct, &addressOid);
4256 if (!IMA_SUCCESS(status)) {
4257 printLibError(status);
4258 *funcRet = 1;
4259 return (ret);
4261 } else if (addrType == ISNS_SERVER_ADDRESS) {
4262 status = SUN_IMA_AddISNSServerAddress(address);
4263 if (!IMA_SUCCESS(status)) {
4264 printLibError(status);
4265 *funcRet = 1;
4266 return (ret);
4270 return (ret);
4274 * Add one or more static configuration targets
4276 static int
4277 addStaticConfig(int operandLen, char *operand[], int *funcRet)
4279 int i;
4280 boolean_t targetAddressSpecified = B_FALSE;
4281 boolean_t tpgtSpecified = B_FALSE;
4282 boolean_t isIpv6 = B_FALSE;
4283 int ret;
4284 int addrType;
4285 IMA_STATUS status;
4286 IMA_OID oid;
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);
4299 if (ret > 0) {
4300 (void) fprintf(stderr, "%s: %s\n",
4301 cmdName, gettext("no initiator found"));
4304 if (ret != 0) {
4305 return (ret);
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,
4319 &port,
4320 &tpgtSpecified,
4321 &tpgt,
4322 &isIpv6) != PARSE_TARGET_OK) {
4323 ret = 1;
4324 continue;
4327 if (targetAddressSpecified != B_TRUE) {
4328 (void) fprintf(stderr, "%s: %s\n",
4329 cmdName, gettext("missing target address"));
4330 *funcRet = 1; /* DIY message fix */
4331 return (1);
4333 /* Perform string profile checks */
4334 nameCheckStatus = iSCSINameStringProfileCheck(staticTargetName);
4335 iSCSINameCheckStatusDisplay(nameCheckStatus);
4336 if (nameCheckStatus != iSCSINameCheckOK) {
4337 *funcRet = 1; /* DIY message fix */
4338 return (1);
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;
4349 } else {
4350 staticConfig.targetAddress.imaStruct.hostnameIpAddress.
4351 id.ipAddress.ipv4Address = B_TRUE;
4352 addrType = AF_INET;
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"));
4359 ret = 1;
4360 continue;
4363 staticConfig.targetAddress.imaStruct.portNumber = port;
4364 if (tpgtSpecified == B_TRUE) {
4365 staticConfig.targetAddress.defaultTpgt = B_FALSE;
4366 staticConfig.targetAddress.tpgt = tpgt;
4367 } else {
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);
4375 *funcRet = 1;
4376 return (1);
4380 if (ret != 0) {
4381 *funcRet = 1;
4384 return (ret);
4388 * Remove one or more addresses
4390 static int
4391 removeAddress(int addrType, int operandLen, char *operand[], int *funcRet)
4393 IMA_STATUS status;
4394 IMA_OID initiatorOid;
4395 SUN_IMA_TARGET_ADDRESS address;
4396 wchar_t wcInputObject[MAX_ADDRESS_LEN + 1];
4397 int ret;
4398 int i;
4400 assert(funcRet != NULL);
4402 /* Find Sun initiator */
4403 ret = sunInitiatorFind(&initiatorOid);
4404 if (ret > 0) {
4405 (void) fprintf(stderr, "%s: %s\n",
4406 cmdName, gettext("no initiator found"));
4409 if (ret != 0) {
4410 return (ret);
4413 for (i = 0; i < operandLen; i++) {
4414 /* initialize */
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"));
4422 ret = 1;
4423 continue;
4426 if (getTargetAddress(addrType, operand[i], &address.imaStruct)
4427 != 0) {
4428 ret = 1;
4429 continue;
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"));
4438 } else {
4439 printLibError(status);
4441 *funcRet = 1;
4443 } else {
4444 status = SUN_IMA_RemoveISNSServerAddress(address);
4445 if (!IMA_SUCCESS(status)) {
4446 printLibError(status);
4447 *funcRet = 1;
4451 return (ret);
4455 * Remove one or more static configuration targets
4457 static int
4458 removeStaticConfig(int operandLen, char *operand[], int *funcRet)
4460 IMA_STATUS status;
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];
4466 int ret;
4467 boolean_t atLeastFoundOne;
4468 boolean_t matched;
4469 boolean_t targetAddressSpecified = B_TRUE;
4470 boolean_t tpgtSpecified = B_FALSE;
4471 boolean_t isIpv6 = B_FALSE;
4472 int i, j;
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);
4483 if (ret > 0) {
4484 (void) fprintf(stderr, "%s: %s\n",
4485 cmdName, gettext("no initiator found"));
4488 if (ret != 0) {
4489 return (ret);
4492 status = IMA_GetStaticDiscoveryTargetOidList(initiatorOid,
4493 &staticTargetList);
4494 if (!IMA_SUCCESS(status)) {
4495 printLibError(status);
4496 *funcRet = 1;
4497 return (ret);
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,
4507 &port,
4508 &tpgtSpecified,
4509 &tpgt,
4510 &isIpv6) != PARSE_TARGET_OK) {
4511 ret = 1;
4512 continue;
4515 /* Perform string profile checks */
4516 nameCheckStatus = iSCSINameStringProfileCheck(staticTargetName);
4517 iSCSINameCheckStatusDisplay(nameCheckStatus);
4518 if (nameCheckStatus != iSCSINameCheckOK) {
4519 return (1);
4522 for (atLeastFoundOne = B_FALSE, j = 0;
4523 j < staticTargetList->oidCount;
4524 j++) {
4525 IMA_UINT16 stpgt;
4527 matched = B_FALSE;
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.
4540 ret = 1;
4541 continue;
4542 } else {
4543 printLibError(status);
4544 (void) IMA_FreeMemory(staticTargetList);
4545 *funcRet = 1;
4546 return (ret);
4550 stpgt =
4551 staticTargetProps.staticTarget.targetAddress.tpgt;
4554 * Compare the static target name with the input if
4555 * one was input
4557 if ((targetNamesEqual(
4558 staticTargetProps.staticTarget.targetName,
4559 staticTargetName) == B_TRUE)) {
4560 if (targetAddressSpecified == B_FALSE) {
4561 matched = B_TRUE;
4562 } else {
4564 if (staticTargetProps.staticTarget.
4565 targetAddress.imaStruct.
4566 hostnameIpAddress.
4567 id.ipAddress.ipv4Address ==
4568 IMA_TRUE) {
4569 (void) inet_ntop(AF_INET,
4570 staticTargetProps.
4571 staticTarget.targetAddress.
4572 imaStruct.hostnameIpAddress.
4573 id.ipAddress.ipAddress,
4574 tmpStr,
4575 sizeof (tmpStr));
4576 } else {
4577 (void) inet_ntop(AF_INET6,
4578 staticTargetProps.
4579 staticTarget.targetAddress.
4580 imaStruct.hostnameIpAddress.
4581 id.ipAddress.ipAddress,
4582 tmpStr,
4583 sizeof (tmpStr));
4586 if (mbstowcs(tmpTargetAddress, tmpStr,
4587 SUN_IMA_IP_ADDRESS_PORT_LEN) ==
4588 (size_t)-1) {
4589 (void) fprintf(stderr,
4590 "%s: %s\n",
4591 cmdName, gettext(
4592 "conversion error"));
4593 ret = 1;
4594 continue;
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) {
4604 matched = B_TRUE;
4605 } else {
4606 if (tpgt == stpgt) {
4607 matched =
4608 B_TRUE;
4614 if (matched) {
4615 status =
4616 IMA_RemoveStaticDiscoveryTarget(
4617 staticTargetList->oids[j]);
4618 if (!IMA_SUCCESS(status)) {
4619 printLibError(status);
4620 *funcRet = 1;
4621 return (ret);
4623 atLeastFoundOne = B_TRUE;
4627 if (!atLeastFoundOne) {
4628 (void) fprintf(stderr, gettext("%ws,%ws: %s\n"),
4629 staticTargetName, staticTargetAddress,
4630 gettext("not found"));
4633 return (ret);
4637 * Remove one or more target params.
4639 static int
4640 removeTargetParam(int operandLen, char *operand[], int *funcRet)
4642 char *commaPos;
4643 IMA_STATUS status;
4644 IMA_OID initiatorOid;
4645 IMA_OID_LIST *targetList;
4646 SUN_IMA_TARGET_PROPERTIES targetProps;
4647 wchar_t wcInputObject[MAX_ISCSI_NAME_LEN + 1];
4648 int ret;
4649 boolean_t found;
4650 int i, j;
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"
4662 " root disk"));
4663 *funcRet = 1;
4664 return (1);
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"
4670 " target's name"));
4671 *funcRet = 1;
4672 return (1);
4676 assert(funcRet != NULL);
4678 /* Find Sun initiator */
4679 ret = sunInitiatorFind(&initiatorOid);
4680 if (ret > 0) {
4681 (void) fprintf(stderr, "%s: %s\n",
4682 cmdName, gettext("no initiator found"));
4685 if (ret != 0) {
4686 return (ret);
4689 status = IMA_GetTargetOidList(initiatorOid, &targetList);
4690 if (!IMA_SUCCESS(status)) {
4691 printLibError(status);
4692 *funcRet = 1;
4693 return (ret);
4696 for (i = 0; i < operandLen; i++) {
4697 /* initialize */
4698 commaPos = strchr(operand[i], ',');
4699 if (commaPos) {
4700 /* Ignore IP address. */
4701 *commaPos = '\0';
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"));
4708 ret = 1;
4709 continue;
4712 for (found = B_FALSE, j = 0; j < targetList->oidCount;
4713 j++) {
4714 status = SUN_IMA_GetTargetProperties(
4715 targetList->oids[j], &targetProps);
4716 if (!IMA_SUCCESS(status)) {
4717 printLibError(status);
4718 (void) IMA_FreeMemory(targetList);
4719 *funcRet = 1;
4720 return (ret);
4724 * Compare the target name with the input if
4725 * one was input
4727 if (targetNamesEqual(targetProps.imaProps.name,
4728 wcInputObject) == B_TRUE) {
4729 found = 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
4737 * allow to update
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"));
4746 ret = 1;
4747 continue;
4752 status = SUN_IMA_RemoveTargetParam(
4753 targetList->oids[j]);
4754 if (!IMA_SUCCESS(status)) {
4755 printLibError(status);
4756 (void) IMA_FreeMemory(targetList);
4757 *funcRet = 1;
4758 return (ret);
4762 if (!found) {
4763 /* Silently ignoring it? */
4764 (void) fprintf(stderr, gettext("%ws: %s\n"),
4765 wcInputObject, gettext("not found"));
4769 (void) IMA_FreeMemory(targetList);
4770 return (ret);
4773 /*ARGSUSED*/
4774 static int
4775 addFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
4776 void *addArgs, int *funcRet)
4778 int ret;
4780 assert(funcRet != NULL);
4782 switch (object) {
4783 case DISCOVERY_ADDRESS:
4784 case ISNS_SERVER_ADDRESS:
4785 ret = addAddress(object, operandLen, operand, funcRet);
4786 break;
4787 case STATIC_CONFIG:
4788 ret = addStaticConfig(operandLen, operand, funcRet);
4789 break;
4790 default:
4791 (void) fprintf(stderr, "%s: %s\n",
4792 cmdName, gettext("unknown object"));
4793 ret = 1;
4794 break;
4796 return (ret);
4799 /*ARGSUSED*/
4800 static int
4801 listFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
4802 void *addArgs, int *funcRet)
4804 int ret;
4806 assert(funcRet != NULL);
4808 switch (object) {
4809 case DISCOVERY:
4810 ret = listDiscovery(funcRet);
4811 break;
4812 case DISCOVERY_ADDRESS:
4813 ret = listDiscoveryAddress(operandLen, operand, options,
4814 funcRet);
4815 break;
4816 case ISNS_SERVER_ADDRESS:
4817 ret = listISNSServerAddress(operandLen, operand, options,
4818 funcRet);
4819 break;
4820 case NODE:
4821 ret = listNode(funcRet);
4822 break;
4823 case STATIC_CONFIG:
4824 ret = listStaticConfig(operandLen, operand, funcRet);
4825 break;
4826 case TARGET:
4827 ret = listTarget(operandLen, operand, options, funcRet);
4828 break;
4829 case TARGET_PARAM:
4830 ret = listTargetParam(operandLen, operand, options, funcRet);
4831 break;
4832 default:
4833 (void) fprintf(stderr, "%s: %s\n",
4834 cmdName, gettext("unknown object"));
4835 ret = 1;
4836 break;
4838 return (ret);
4841 /*ARGSUSED*/
4842 static int
4843 modifyFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
4844 void *addArgs, int *funcRet)
4846 int ret, i;
4848 assert(funcRet != NULL);
4850 switch (object) {
4851 case DISCOVERY:
4852 ret = modifyDiscovery(options, funcRet);
4853 break;
4854 case NODE:
4855 ret = modifyNode(options, funcRet);
4856 break;
4857 case TARGET_PARAM:
4858 i = 0;
4859 while (operand[i]) {
4860 ret = modifyTargetParam(options, operand[i], funcRet);
4862 if (ret) {
4863 (void) fprintf(stderr, "%s: %s: %s\n",
4864 cmdName, gettext("modify failed"),
4865 operand[i]);
4866 return (ret);
4868 i++;
4871 break;
4872 default:
4873 (void) fprintf(stderr, "%s: %s\n",
4874 cmdName, gettext("unknown object"));
4875 ret = 1;
4876 break;
4878 return (ret);
4881 /*ARGSUSED*/
4882 static int
4883 removeFunc(int operandLen, char *operand[], int object, cmdOptions_t *options,
4884 void *addArgs, int *funcRet)
4886 int ret;
4888 switch (object) {
4889 case DISCOVERY_ADDRESS:
4890 case ISNS_SERVER_ADDRESS:
4891 ret = removeAddress(object, operandLen, operand,
4892 funcRet);
4893 break;
4894 case STATIC_CONFIG:
4895 ret = removeStaticConfig(operandLen, operand, funcRet);
4896 break;
4897 case TARGET_PARAM:
4898 ret = removeTargetParam(operandLen, operand, funcRet);
4899 break;
4900 default:
4901 (void) fprintf(stderr, "%s: %s\n",
4902 cmdName, gettext("unknown object"));
4903 ret = 1;
4904 break;
4906 return (ret);
4909 static void
4910 iSCSINameCheckStatusDisplay(iSCSINameCheckStatusType status)
4912 switch (status) {
4913 case iSCSINameLenZero:
4914 (void) fprintf(stderr, "%s: %s\n",
4915 cmdName, gettext("empty iSCSI name."));
4916 break;
4917 case iSCSINameLenExceededMax:
4918 (void) fprintf(stderr, "%s: %s\n", cmdName,
4919 gettext("iSCSI name exceeded maximum length."));
4920 break;
4921 case iSCSINameUnknownType:
4922 (void) fprintf(stderr, "%s: %s\n", cmdName,
4923 gettext("unknown iSCSI name type."));
4924 break;
4925 case iSCSINameInvalidCharacter:
4926 (void) fprintf(stderr, "%s: %s\n",
4927 cmdName,
4928 gettext("iSCSI name invalid character used"));
4929 break;
4930 case iSCSINameIqnFormatError:
4931 (void) fprintf(stderr, "%s: %s\n", cmdName,
4932 gettext("iqn formatting error."));
4933 break;
4934 case iSCSINameIqnDateFormatError:
4935 (void) fprintf(stderr, "%s: %s\n",
4936 cmdName, gettext("invalid iqn date." \
4937 " format is: YYYY-MM"));
4938 break;
4939 case iSCSINameIqnSubdomainFormatError:
4940 (void) fprintf(stderr, "%s: %s\n",
4941 cmdName, gettext("missing subdomain after \":\""));
4942 break;
4943 case iSCSINameIqnInvalidYearError:
4944 (void) fprintf(stderr, "%s: %s\n",
4945 cmdName, gettext("invalid year"));
4946 break;
4947 case iSCSINameIqnInvalidMonthError:
4948 (void) fprintf(stderr, "%s: %s\n",
4949 cmdName, gettext("invalid month"));
4950 break;
4951 case iSCSINameIqnFQDNError:
4952 (void) fprintf(stderr, "%s: %s\n",
4953 cmdName, gettext("missing reversed fully qualified"\
4954 " domain name"));
4955 break;
4956 case iSCSINameEUIFormatError:
4957 (void) fprintf(stderr, "%s: %s\n", cmdName,
4958 gettext("eui formatting error."));
4959 break;
4964 * A convenient function to modify the target parameters of an individual
4965 * target.
4967 * Return 0 if successful
4968 * Return 1 if failed
4970 static int
4971 modifyIndividualTargetParam(cmdOptions_t *optionList, IMA_OID targetOid,
4972 int *funcRet)
4974 assert(funcRet != NULL);
4976 for (; optionList->optval; optionList++) {
4977 switch (optionList->optval) {
4978 case 'a':
4979 if (modifyTargetAuthMethod(targetOid,
4980 optionList->optarg, funcRet) != 0) {
4981 return (1);
4983 break;
4984 case 'B':
4985 if (modifyTargetBidirAuthFlag(targetOid,
4986 optionList->optarg, funcRet) != 0) {
4987 return (1);
4989 break;
4990 case 'C':
4991 if (modifyTargetAuthParam(targetOid,
4992 AUTH_PASSWORD, NULL, funcRet) != 0) {
4993 return (1);
4995 break;
4996 case 'd':
4997 if (setLoginParameter(targetOid, DATA_DIGEST,
4998 optionList->optarg) != 0) {
4999 return (1);
5001 break;
5002 case 'h':
5003 if (setLoginParameter(targetOid, HEADER_DIGEST,
5004 optionList->optarg) != 0) {
5005 return (1);
5007 break;
5008 case 'p':
5009 /* Login parameter */
5010 if (setLoginParameters(targetOid,
5011 optionList->optarg) != 0) {
5012 return (1);
5014 break;
5015 case 'c':
5016 /* Modify configure sessions */
5017 if (modifyConfiguredSessions(targetOid,
5018 optionList->optarg) != 0) {
5019 return (1);
5021 break;
5022 case 'H':
5023 if (modifyTargetAuthParam(targetOid, AUTH_NAME,
5024 optionList->optarg, funcRet) != 0) {
5025 return (1);
5027 break;
5028 case 'T':
5029 if (setTunableParameters(targetOid,
5030 optionList->optarg) != 0) {
5031 return (1);
5033 break;
5037 return (0);
5041 * This helper function could go into a utility module for general use.
5043 static int
5044 parseAddress(char *address_port_str,
5045 uint16_t defaultPort,
5046 char *address_str,
5047 size_t address_str_len,
5048 uint16_t *port,
5049 boolean_t *isIpv6)
5051 char port_str[64];
5052 int tmp_port;
5053 char *errchr;
5055 if (address_port_str[0] == '[') {
5056 /* IPv6 address */
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],
5067 address_str_len);
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,
5079 close_bracket_pos,
5080 gettext("port number invalid"));
5081 return (PARSE_ADDR_PORT_OUT_OF_RANGE);
5083 if ((tmp_port > 0) && (tmp_port > USHRT_MAX) ||
5084 (tmp_port < 0)) {
5085 /* Port number out of range */
5086 syslog(LOG_USER|LOG_DEBUG,
5087 "Specified port out of range: %d",
5088 tmp_port);
5089 return (PARSE_ADDR_PORT_OUT_OF_RANGE);
5090 } else {
5091 *port = (uint16_t)tmp_port;
5093 } else {
5094 *port = defaultPort;
5096 } else {
5097 *port = defaultPort;
5100 *isIpv6 = B_TRUE;
5101 } else {
5102 /* IPv4 address */
5103 char *colon_pos;
5104 colon_pos = strchr(address_port_str, ':');
5105 if (!colon_pos) {
5106 /* No port number specified. */
5107 *port = defaultPort;
5108 (void) strlcpy(address_str, address_port_str,
5109 address_str_len);
5110 } else {
5111 *colon_pos = '\0';
5112 (void) strlcpy(address_str, address_port_str,
5113 address_str_len);
5115 /* Extract the port number */
5116 colon_pos++;
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) ||
5128 (tmp_port < 0)) {
5129 /* Port number out of range */
5130 syslog(LOG_USER|LOG_DEBUG,
5131 "Specified port out of range: %d",
5132 tmp_port);
5133 return (PARSE_ADDR_PORT_OUT_OF_RANGE);
5134 } else {
5135 *port = (uint16_t)tmp_port;
5137 } else {
5138 *port = defaultPort;
5142 *isIpv6 = B_FALSE;
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];
5155 size_t name_len;
5156 char *tmp;
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) &&
5173 (*tmp != '-') &&
5174 (*tmp != '.') &&
5175 (*tmp != ':')) {
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
5184 * authority.
5186 char *strp = NULL;
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);
5196 /* Date string */
5197 strp = strtok(&mb_name[3], ".");
5198 if (strp) {
5199 char tmpYear[5], tmpMonth[3], *endPtr = NULL;
5200 int year, month;
5202 /* Date string should be in YYYY-MM format */
5203 if (strlen(strp) != strlen("YYYY-MM") ||
5204 strp[4] != '-') {
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
5212 * value.
5214 (void) strncpy(tmpYear, strp, 4);
5215 tmpYear[4] = '\0';
5217 errno = 0;
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);
5228 tmpMonth[2] = '\0';
5229 errno = 0;
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, ":");
5251 if (strp) {
5252 return (iSCSINameCheckOK);
5253 } else {
5254 return (iSCSINameIqnFQDNError);
5256 } else {
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)) {
5270 continue;
5272 return (iSCSINameEUIFormatError);
5275 return (iSCSINameCheckOK);
5276 } else {
5277 return (iSCSINameUnknownType);
5282 * This helper function could go into a utility module for general use.
5284 * Returns:
5285 * B_TRUE is the numberStr is an unsigned natural number and within the
5286 * specified bound.
5287 * B_FALSE otherwise.
5289 boolean_t
5290 isNaturalNumber(char *numberStr, uint32_t upperBound)
5292 int i;
5293 int number_str_len;
5295 if ((number_str_len = strlen(numberStr)) == 0) {
5296 return (B_FALSE);
5299 for (i = 0; i < number_str_len; i++) {
5300 if (numberStr[i] < 060 || numberStr[i] > 071) {
5301 return (B_FALSE);
5305 if (atoi(numberStr) > upperBound) {
5306 return (B_FALSE);
5309 return (B_TRUE);
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.
5321 * Returns:
5322 * PARSE_TARGET_OK if parsing is successful.
5323 * PARSE_TARGET_INVALID_TPGT if the specified tpgt is
5324 * invalid.
5325 * PARSE_TARGET_INVALID_ADDR if the address specified is
5326 * invalid.
5329 parseTarget(char *targetStr,
5330 wchar_t *targetNameStr,
5331 size_t targetNameStrLen,
5332 boolean_t *targetAddressSpecified,
5333 wchar_t *targetAddressStr,
5334 size_t targetAddressStrLen,
5335 uint16_t *port,
5336 boolean_t *tpgtSpecified,
5337 uint16_t *tpgt,
5338 boolean_t *isIpv6)
5340 char *commaPos;
5341 char *commaPos2;
5342 char targetAddress[SUN_IMA_IP_ADDRESS_PORT_LEN];
5343 int i;
5344 int lowerCase;
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) {
5353 *commaPos = '\0';
5354 commaPos++;
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) {
5363 *commaPos2 = '\0';
5364 commaPos2++;
5365 if (isNaturalNumber(commaPos2, ISCSI_MAX_TPGT_VALUE) ==
5366 B_TRUE) {
5367 *tpgt = atoi(commaPos2);
5368 *tpgtSpecified = B_TRUE;
5369 } else {
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);
5380 case PARSE_ADDR_OK:
5381 break;
5382 default:
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;
5393 } else {
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);
5407 /*ARGSUSED*/
5408 static void
5409 listCHAPName(IMA_OID oid)
5411 IMA_INITIATOR_AUTHPARMS authParams;
5412 IMA_STATUS status;
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);
5419 } else {
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);
5437 } else {
5438 (void) fprintf(stdout, "%s", "-");
5440 } else {
5441 (void) fprintf(stdout, "%s", "-");
5445 static boolean_t
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"
5458 " iscsi(7D)."));
5459 return (B_FALSE);
5462 if (enabled == 0) {
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"
5468 " iscsi(7D)."));
5469 return (B_FALSE);
5472 return (B_TRUE);
5476 * Prints out see manual page.
5477 * Called out through atexit(3C) so is always last thing displayed.
5479 void
5480 seeMan(void)
5482 static int sent = 0;
5484 if (sent)
5485 return;
5487 (void) fprintf(stdout, "%s %s(8)\n",
5488 gettext("For more information, please see"), cmdName);
5490 sent = 1;
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];
5517 int ret;
5518 int funcRet = 0;
5519 void *subcommandArgs = NULL;
5521 if (geteuid() != 0) {
5522 (void) fprintf(stderr, "%s\n", gettext("permission denied"));
5523 return (1);
5526 if (checkServiceStatus() == B_FALSE) {
5527 return (1);
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);
5544 if (ret == -1) {
5545 perror(cmdName);
5546 ret = 1;
5549 if (funcRet != 0) {
5550 (void) fprintf(stderr, "%s: %s\n",
5551 cmdName, gettext("Unable to complete operation"));
5552 ret = 1;
5554 return (ret);
5557 static int
5558 setTunableParameters(IMA_OID oid, char *optarg)
5560 char keyp[MAXOPTARGLEN];
5561 char valp[MAXOPTARGLEN];
5562 int key;
5563 IMA_STATUS status;
5564 IMA_UINT uintValue;
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));
5572 } else {
5573 (void) fprintf(stderr, "%s: %s\n", cmdName,
5574 gettext("unknown error"));
5576 return (1);
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;
5588 return (1);
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;
5597 return (1);
5599 switch (key) {
5600 case RECV_LOGIN_RSP_TIMEOUT:
5601 case CONN_LOGIN_MAX:
5602 case POLLING_LOGIN_DELAY:
5603 errno = 0;
5604 uintValue = strtoul(valp, &endptr, 0);
5605 if (*endptr != '\0' || errno != 0) {
5606 (void) fprintf(stderr, "%s: %s - %s\n",
5607 cmdName,
5608 gettext("invalid option argument"),
5609 optarg);
5610 if (nameValueString) {
5611 free(nameValueString);
5612 nameValueString = NULL;
5614 return (1);
5616 if (uintValue > 3600) {
5617 (void) fprintf(stderr, "%s: %s\n",
5618 cmdName,
5619 gettext("value must be between 0 and 3600"));
5620 if (nameValueString) {
5621 free(nameValueString);
5622 nameValueString = NULL;
5624 return (1);
5627 if (chkConnLoginMaxPollingLoginDelay(oid, key, uintValue) > 0) {
5628 if (nameValueString) {
5629 free(nameValueString);
5630 nameValueString = NULL;
5632 return (1);
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);
5647 break;
5648 default:
5649 (void) fprintf(stderr, "%s: %s: %s\n", cmdName,
5650 gettext("Unsupported key"), keyp);
5651 if (nameValueString) {
5652 free(nameValueString);
5653 nameValueString = NULL;
5655 return (1);
5657 if (!IMA_SUCCESS(status)) {
5658 printLibError(status);
5659 if (nameValueString) {
5660 free(nameValueString);
5661 nameValueString = NULL;
5663 return (1);
5666 if (nameValueString) {
5667 free(nameValueString);
5668 nameValueString = NULL;
5670 return (0);
5674 * Print tunable parameters information
5676 static int
5677 printTunableParameters(IMA_OID oid)
5679 ISCSI_TUNABLE_PARAM tunableObj;
5680 char value[MAXOPTARGLEN] = "\0";
5681 IMA_STATUS status;
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);
5690 return (1);
5692 if (value[0] == '\0') {
5693 value[0] = '-';
5694 value[1] = '\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);
5701 value[0] = '\0';
5702 tunableObj.tunable_objectType = ISCSI_CONN_DEFAULT_LOGIN_MAX;
5703 status = SUN_IMA_GetTunableProperties(oid, &tunableObj);
5704 if (!IMA_SUCCESS(status)) {
5705 printLibError(status);
5706 return (1);
5708 if (value[0] == '\0') {
5709 value[0] = '-';
5710 value[1] = '\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);
5717 value[0] = '\0';
5718 tunableObj.tunable_objectType = ISCSI_LOGIN_POLLING_DELAY;
5719 status = SUN_IMA_GetTunableProperties(oid, &tunableObj);
5720 if (!IMA_SUCCESS(status)) {
5721 printLibError(status);
5722 return (1);
5724 if (value[0] == '\0') {
5725 value[0] = '-';
5726 value[1] = '\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);
5732 return (0);
5736 * This is helper function to check conn_login_max and polling_login_delay.
5738 static int
5739 chkConnLoginMaxPollingLoginDelay(IMA_OID oid, int key, int uintValue)
5741 char valuep[MAXOPTARGLEN];
5742 IMA_STATUS status;
5743 IMA_UINT getValue;
5744 ISCSI_TUNABLE_PARAM getObj;
5745 char *endptr;
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;
5751 } else {
5752 return (0);
5754 valuep[0] = '\0';
5755 getObj.tunable_objectValue = valuep;
5756 status = SUN_IMA_GetTunableProperties(oid, &getObj);
5757 if (!IMA_SUCCESS(status)) {
5758 printLibError(status);
5759 return (1);
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);
5766 } else {
5767 (void) strlcpy(valuep,
5768 ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX,
5769 strlen(ISCSI_DEFAULT_CONN_DEFAULT_LOGIN_MAX) +1);
5773 errno = 0;
5774 getValue = strtoul(valuep, &endptr, 0);
5775 if (*endptr != '\0' || errno != 0) {
5776 (void) fprintf(stderr, "%s: %s - %s\n",
5777 cmdName,
5778 gettext("cannot convert tunable string"),
5779 valuep);
5780 return (1);
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"),
5786 getValue);
5787 return (1);
5789 } else {
5790 if (uintValue > getValue) {
5791 (void) fprintf(stderr, "%s: %s %ld\n",
5792 cmdName, gettext("value must smaller than"),
5793 getValue);
5794 return (1);
5797 return (0);