1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <arpa/inet.h> 27 #include <sys/socket.h> 28 #include <sys/types.h> 29 #include <stdarg.h> 30 #include <stdlib.h> 31 #include <string.h> 32 #include <strings.h> 33 #include <unistd.h> 34 #include <syslog.h> 35 #include <errno.h> 36 #include <wchar.h> 37 #include <widec.h> 38 #include <libsysevent.h> 39 #include <sys/nvpair.h> 40 #include <fcntl.h> 41 #include <stdio.h> 42 #include <time.h> 43 #include <libdevinfo.h> 44 #include <sys/scsi/adapters/iscsi_if.h> 45 #include <sys/scsi/adapters/iscsi_protocol.h> 46 #include <ima.h> 47 48 #define LIBRARY_PROPERTY_IMPLEMENTATION_VERSION L"1.0.0" 49 #define LIBRARY_PROPERTY_VENDOR L"Sun Microsystems, Inc." 50 #define OS_DEVICE_NAME "/devices/iscsi" 51 #define LIBRARY_FILE_NAME L"libsun_ima.so" 52 53 #define OS_DEVICE_NAME_LEN 256 54 #define INQUIRY_CMD 0x12 55 #define GETCAPACITY_CMD 0x25 56 #define INQUIRY_CMDLEN 6 57 #define INQUIRY_REPLY_LEN 96 58 #define USCSI_TIMEOUT_IN_SEC 10 59 #define MAX_AUTHMETHODS 10 60 #define NUM_SUPPORTED_AUTH_METHODS 2 61 #define SUN_IMA_MAX_DIGEST_ALGORITHMS 2 /* NONE and CRC 32 */ 62 #define SUN_IMA_IP_ADDRESS_LEN 256 63 #define SUN_IMA_IP_PORT_LEN 64 64 #define SUN_IMA_MAX_RADIUS_SECRET_LEN 128 65 66 /* Forward declaration */ 67 #define BOOL_PARAM 1 68 #define MIN_MAX_PARAM 2 69 70 /* OK */ 71 #define DISC_ADDR_OK 0 72 /* Incorrect IP address */ 73 #define DISC_ADDR_INTEGRITY_ERROR 1 74 /* Error converting text IP address to numeric binary form */ 75 #define DISC_ADDR_IP_CONV_ERROR 2 76 77 /* Currently not defined in IMA_TARGET_DISCOVERY_METHOD enum */ 78 #define IMA_TARGET_DISCOVERY_METHOD_UNKNOWN 0 79 80 static IMA_OID lhbaObjectId; 81 static IMA_UINT32 pluginOwnerId; 82 static sysevent_handle_t *shp; 83 84 85 86 /* 87 * Custom struct to allow tgpt to be specified. 88 */ 89 typedef struct _SUN_IMA_DISC_ADDRESS_KEY 90 { 91 IMA_NODE_NAME name; 92 IMA_ADDRESS_KEY address; 93 IMA_UINT16 tpgt; 94 } SUN_IMA_DISC_ADDRESS_KEY; 95 96 /* 97 * Custom struct to allow tgpt to be specified. 98 */ 99 typedef struct _SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES 100 { 101 IMA_UINT keyCount; 102 SUN_IMA_DISC_ADDRESS_KEY keys[1]; 103 } SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES; 104 105 /* 106 * Custom struct to allow tgpt to be specified. 107 */ 108 typedef struct _SUN_IMA_DISC_ADDR_PROP_LIST 109 { 110 IMA_UINT discAddrCount; 111 IMA_DISCOVERY_ADDRESS_PROPERTIES props[1]; 112 } SUN_IMA_DISC_ADDR_PROP_LIST; 113 114 115 static IMA_OBJECT_VISIBILITY_FN pObjectVisibilityCallback = NULL; 116 static IMA_OBJECT_PROPERTY_FN pObjectPropertyCallback = NULL; 117 118 static IMA_STATUS getISCSINodeParameter(int paramType, IMA_OID *oid, 119 void *pProps, uint32_t paramIndex); 120 static IMA_STATUS setISCSINodeParameter(int paramType, IMA_OID *oid, 121 void *pProps, uint32_t paramIndex); 122 static IMA_STATUS setAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount, 123 const IMA_AUTHMETHOD *pMethodList); 124 static IMA_STATUS getAuthMethods(IMA_OID oid, IMA_UINT *pMethodCount, 125 IMA_AUTHMETHOD *pMethodList); 126 127 static int prepare_discovery_entry(IMA_TARGET_ADDRESS discoveryAddress, 128 entry_t *entry); 129 static IMA_STATUS configure_discovery_method(IMA_BOOL enable, 130 iSCSIDiscoveryMethod_t method); 131 static IMA_STATUS get_target_oid_list(uint32_t targetListType, 132 IMA_OID_LIST **ppList); 133 static IMA_STATUS get_target_lun_oid_list(IMA_OID * targetOid, 134 iscsi_lun_list_t **ppLunList); 135 static int get_lun_devlink(di_devlink_t link, void *osDeviceName); 136 static IMA_STATUS getDiscoveryAddressPropertiesList( 137 SUN_IMA_DISC_ADDR_PROP_LIST **ppList 138 ); 139 static IMA_STATUS sendTargets(IMA_TARGET_ADDRESS address, 140 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList 141 ); 142 143 static IMA_STATUS getSupportedAuthMethods(IMA_OID lhbaOid, 144 IMA_BOOL getSettableMethods, IMA_UINT *pMethodCount, 145 IMA_AUTHMETHOD *pMethodList); 146 static IMA_STATUS getLuProperties(IMA_OID luId, IMA_LU_PROPERTIES *pProps); 147 static IMA_STATUS getTargetProperties(IMA_OID targetId, 148 IMA_TARGET_PROPERTIES *pProps); 149 150 void InitLibrary(); 151 152 static void libSwprintf(wchar_t *wcs, const wchar_t *lpszFormat, ...) 153 { 154 va_list args; 155 va_start(args, lpszFormat); 156 (void) vswprintf(wcs, OS_DEVICE_NAME_LEN - 1, lpszFormat, args); 157 va_end(args); 158 } 159 160 static void 161 sysevent_handler(sysevent_t *ev) 162 { 163 IMA_OID tmpOid; 164 IMA_BOOL becomingVisible = IMA_FALSE; 165 IMA_UINT i; 166 167 const char *visibility_subclasses[] = { 168 ESC_ISCSI_STATIC_START, 169 ESC_ISCSI_STATIC_END, 170 ESC_ISCSI_SEND_TARGETS_START, 171 ESC_ISCSI_SEND_TARGETS_END, 172 ESC_ISCSI_SLP_START, 173 ESC_ISCSI_SLP_END, 174 ESC_ISCSI_ISNS_START, 175 ESC_ISCSI_ISNS_END, 176 NULL 177 }; 178 179 tmpOid.ownerId = pluginOwnerId; 180 tmpOid.objectType = IMA_OBJECT_TYPE_TARGET; 181 tmpOid.objectSequenceNumber = 0; 182 183 /* Make sure our event class matches what we are looking for */ 184 if (strncmp(EC_ISCSI, sysevent_get_class_name(ev), 185 strlen(EC_ISCSI)) != 0) { 186 return; 187 } 188 189 190 /* Check for object property changes */ 191 if ((strncmp(ESC_ISCSI_PROP_CHANGE, 192 sysevent_get_subclass_name(ev), 193 strlen(ESC_ISCSI_PROP_CHANGE)) == 0)) { 194 if (pObjectPropertyCallback != NULL) 195 pObjectPropertyCallback(tmpOid); 196 } else { 197 i = 0; 198 while (visibility_subclasses[i] != NULL) { 199 if ((strncmp(visibility_subclasses[i], 200 sysevent_get_subclass_name(ev), 201 strlen(visibility_subclasses[i])) == 0) && 202 pObjectVisibilityCallback != NULL) { 203 becomingVisible = IMA_TRUE; 204 pObjectVisibilityCallback(becomingVisible, 205 tmpOid); 206 } 207 i++; 208 } 209 } 210 } 211 212 IMA_STATUS init_sysevents() { 213 const char *subclass_list[] = { 214 ESC_ISCSI_STATIC_START, 215 ESC_ISCSI_STATIC_END, 216 ESC_ISCSI_SEND_TARGETS_START, 217 ESC_ISCSI_SEND_TARGETS_END, 218 ESC_ISCSI_SLP_START, 219 ESC_ISCSI_SLP_END, 220 ESC_ISCSI_ISNS_START, 221 ESC_ISCSI_ISNS_END, 222 ESC_ISCSI_PROP_CHANGE, 223 }; 224 225 /* Bind event handler and create subscriber handle */ 226 shp = sysevent_bind_handle(sysevent_handler); 227 if (shp == NULL) { 228 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 229 } 230 231 if (sysevent_subscribe_event(shp, EC_ISCSI, subclass_list, 9) != 0) { 232 sysevent_unbind_handle(shp); 233 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 234 } 235 return (IMA_STATUS_SUCCESS); 236 } 237 238 IMA_STATUS Initialize(IMA_UINT32 pluginOid) { 239 pluginOwnerId = pluginOid; 240 return (init_sysevents()); 241 } 242 243 void Terminate() { 244 if (shp != NULL) { 245 sysevent_unsubscribe_event(shp, EC_ISCSI); 246 } 247 248 } 249 250 void InitLibrary() { 251 } 252 253 static void GetBuildTime(IMA_DATETIME* pdatetime) 254 { 255 (void) memset(pdatetime, 0, sizeof (IMA_DATETIME)); 256 } 257 258 /*ARGSUSED*/ 259 IMA_API IMA_STATUS IMA_GetNodeProperties( 260 IMA_OID nodeOid, 261 IMA_NODE_PROPERTIES *pProps 262 ) 263 { 264 int fd; 265 iscsi_param_get_t pg; 266 267 pProps->runningInInitiatorMode = IMA_TRUE; 268 pProps->runningInTargetMode = IMA_FALSE; 269 pProps->nameAndAliasSettable = IMA_FALSE; 270 271 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 272 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 273 ISCSI_DRIVER_DEVCTL, errno); 274 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 275 } 276 277 (void) memset(&pg, 0, sizeof (iscsi_param_get_t)); 278 pg.g_vers = ISCSI_INTERFACE_VERSION; 279 pg.g_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME; 280 281 if (ioctl(fd, ISCSI_PARAM_GET, &pg) == -1) { 282 pProps->nameValid = IMA_FALSE; 283 } else { 284 if (strlen((char *)pg.g_value.v_name) > 0) { 285 (void) mbstowcs(pProps->name, 286 (char *)pg.g_value.v_name, 287 IMA_NODE_NAME_LEN); 288 pProps->nameValid = IMA_TRUE; 289 } else { 290 pProps->nameValid = IMA_FALSE; 291 } 292 } 293 294 (void) memset(&pg, 0, sizeof (iscsi_param_get_t)); 295 pg.g_vers = ISCSI_INTERFACE_VERSION; 296 pg.g_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS; 297 (void) memset(pProps->alias, 0, 298 sizeof (IMA_WCHAR) * IMA_NODE_ALIAS_LEN); 299 if (ioctl(fd, ISCSI_PARAM_GET, &pg) == -1) { 300 pProps->aliasValid = IMA_FALSE; 301 } else { 302 if (strlen((char *)pg.g_value.v_name) > 0) { 303 (void) mbstowcs(pProps->alias, 304 (char *)pg.g_value.v_name, 305 IMA_NODE_ALIAS_LEN); 306 pProps->aliasValid = IMA_TRUE; 307 } 308 } 309 310 (void) close(fd); 311 return (IMA_STATUS_SUCCESS); 312 } 313 314 IMA_API IMA_STATUS IMA_SetNodeName( 315 IMA_OID nodeOid, 316 const IMA_NODE_NAME newName 317 ) 318 { 319 int fd; 320 iscsi_param_set_t ps; 321 322 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 323 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 324 ISCSI_DRIVER_DEVCTL, errno); 325 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 326 } 327 328 (void) memset(&ps, 0, sizeof (iscsi_param_set_t)); 329 ps.s_oid = nodeOid.objectSequenceNumber; 330 ps.s_vers = ISCSI_INTERFACE_VERSION; 331 ps.s_param = ISCSI_LOGIN_PARAM_INITIATOR_NAME; 332 (void) wcstombs((char *)ps.s_value.v_name, newName, ISCSI_MAX_NAME_LEN); 333 if (ioctl(fd, ISCSI_INIT_NODE_NAME_SET, &ps)) { 334 syslog(LOG_USER|LOG_DEBUG, 335 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno); 336 (void) close(fd); 337 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 338 } 339 340 (void) close(fd); 341 return (IMA_STATUS_SUCCESS); 342 } 343 344 IMA_API IMA_STATUS IMA_SetNodeAlias( 345 IMA_OID nodeOid, 346 const IMA_NODE_ALIAS newAlias 347 ) 348 { 349 int fd; 350 iscsi_param_set_t ps; 351 352 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 353 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 354 ISCSI_DRIVER_DEVCTL, errno); 355 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 356 } 357 358 (void) memset(&ps, 0, sizeof (iscsi_param_set_t)); 359 ps.s_oid = nodeOid.objectSequenceNumber; 360 ps.s_vers = ISCSI_INTERFACE_VERSION; 361 ps.s_param = ISCSI_LOGIN_PARAM_INITIATOR_ALIAS; 362 363 /* newAlias = NULL specifies that the alias should be deleted. */ 364 if (newAlias != NULL) 365 (void) wcstombs((char *)ps.s_value.v_name, newAlias, 366 ISCSI_MAX_NAME_LEN); 367 else 368 (void) wcstombs((char *)ps.s_value.v_name, 369 L"", ISCSI_MAX_NAME_LEN); 370 371 if (ioctl(fd, ISCSI_PARAM_SET, &ps)) { 372 syslog(LOG_USER|LOG_DEBUG, 373 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno); 374 (void) close(fd); 375 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 376 } 377 378 (void) close(fd); 379 return (IMA_STATUS_SUCCESS); 380 } 381 382 383 IMA_API IMA_STATUS IMA_GetLhbaOidList( 384 IMA_OID_LIST **ppList 385 ) 386 { 387 /* Always return the same object ID for the lhba */ 388 lhbaObjectId.objectType = IMA_OBJECT_TYPE_LHBA; 389 lhbaObjectId.ownerId = pluginOwnerId; 390 lhbaObjectId.objectSequenceNumber = ISCSI_INITIATOR_OID; 391 392 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST)); 393 if (*ppList == NULL) { 394 return (IMA_ERROR_INSUFFICIENT_MEMORY); 395 } 396 397 (*ppList)->oidCount = 1; 398 (void) memcpy(&(*ppList)->oids[0], 399 &lhbaObjectId, sizeof (lhbaObjectId)); 400 return (IMA_STATUS_SUCCESS); 401 } 402 403 404 /* 405 * Get the discovery properties of the LHBA 406 */ 407 /*ARGSUSED*/ 408 IMA_API IMA_STATUS IMA_GetDiscoveryProperties( 409 IMA_OID oid, 410 IMA_DISCOVERY_PROPERTIES *pProps 411 ) 412 { 413 int fd; 414 iSCSIDiscoveryProperties_t discoveryProps; 415 416 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 417 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 418 ISCSI_DRIVER_DEVCTL, errno); 419 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 420 } 421 422 (void) memset(&discoveryProps, 0, sizeof (discoveryProps)); 423 discoveryProps.vers = ISCSI_INTERFACE_VERSION; 424 425 if (ioctl(fd, ISCSI_DISCOVERY_PROPS, &discoveryProps) != 0) { 426 syslog(LOG_USER|LOG_DEBUG, 427 "ISCSI_DISCOVERY_PROPS ioctl failed, errno: %d", errno); 428 (void) close(fd); 429 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 430 } 431 432 pProps->iSnsDiscoverySettable = discoveryProps.iSNSDiscoverySettable; 433 pProps->iSnsDiscoveryEnabled = discoveryProps.iSNSDiscoveryEnabled; 434 /* 435 * Set the iSNS discovery method - The IMA specification indicates 436 * this field is valid only if iSNS discovery is enabled. 437 */ 438 if (pProps->iSnsDiscoveryEnabled == IMA_TRUE) { 439 switch (discoveryProps.iSNSDiscoveryMethod) { 440 case iSNSDiscoveryMethodStatic: 441 pProps->iSnsDiscoveryMethod = 442 IMA_ISNS_DISCOVERY_METHOD_STATIC; 443 break; 444 case iSNSDiscoveryMethodDHCP: 445 pProps->iSnsDiscoveryMethod = 446 IMA_ISNS_DISCOVERY_METHOD_DHCP; 447 break; 448 case iSNSDiscoveryMethodSLP: 449 pProps->iSnsDiscoveryMethod = 450 IMA_ISNS_DISCOVERY_METHOD_SLP; 451 break; 452 default: 453 (void) close(fd); 454 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 455 } 456 } 457 (void) memcpy(pProps->iSnsHost.id.hostname, 458 discoveryProps.iSNSDomainName, 459 sizeof (pProps->iSnsHost.id.hostname)); 460 pProps->slpDiscoverySettable = discoveryProps.SLPDiscoverySettable; 461 pProps->slpDiscoveryEnabled = discoveryProps.SLPDiscoveryEnabled; 462 pProps->staticDiscoverySettable = 463 discoveryProps.StaticDiscoverySettable; 464 pProps->staticDiscoveryEnabled = discoveryProps.StaticDiscoveryEnabled; 465 pProps->sendTargetsDiscoverySettable = 466 discoveryProps.SendTargetsDiscoverySettable; 467 pProps->sendTargetsDiscoveryEnabled = 468 discoveryProps.SendTargetsDiscoveryEnabled; 469 470 (void) close(fd); 471 return (IMA_STATUS_SUCCESS); 472 } 473 474 IMA_API IMA_STATUS IMA_FreeMemory( 475 void *pMemory 476 ) 477 { 478 if (pMemory != NULL) 479 free(pMemory); 480 return (IMA_STATUS_SUCCESS); 481 } 482 483 IMA_API IMA_STATUS IMA_GetNonSharedNodeOidList( 484 IMA_OID_LIST **ppList 485 ) 486 { 487 if (ppList == NULL) 488 return (IMA_ERROR_INVALID_PARAMETER); 489 490 *ppList = (IMA_OID_LIST*) calloc(1, sizeof (IMA_OID_LIST)); 491 if (*ppList == NULL) { 492 return (IMA_ERROR_INSUFFICIENT_MEMORY); 493 } 494 (*ppList)->oidCount = 0; 495 496 return (IMA_STATUS_SUCCESS); 497 } 498 499 IMA_API IMA_STATUS IMA_GetFirstBurstLengthProperties( 500 IMA_OID Oid, 501 IMA_MIN_MAX_VALUE *pProps 502 ) 503 { 504 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 505 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH)); 506 } 507 508 IMA_API IMA_STATUS IMA_GetMaxBurstLengthProperties( 509 IMA_OID Oid, 510 IMA_MIN_MAX_VALUE *pProps 511 ) 512 { 513 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 514 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH)); 515 } 516 517 IMA_API IMA_STATUS IMA_GetMaxRecvDataSegmentLengthProperties( 518 IMA_OID Oid, 519 IMA_MIN_MAX_VALUE *pProps 520 ) 521 { 522 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 523 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH)); 524 } 525 526 /*ARGSUSED*/ 527 IMA_API IMA_STATUS IMA_PluginIOCtl( 528 IMA_OID pluginOid, 529 IMA_UINT command, 530 const void *pInputBuffer, 531 IMA_UINT inputBufferLength, 532 void *pOutputBuffer, 533 IMA_UINT *pOutputBufferLength 534 ) 535 { 536 return (IMA_ERROR_NOT_SUPPORTED); 537 } 538 539 IMA_API IMA_STATUS IMA_SetFirstBurstLength( 540 IMA_OID lhbaId, 541 IMA_UINT firstBurstLength 542 ) 543 { 544 IMA_MIN_MAX_VALUE mv; 545 546 mv.currentValue = firstBurstLength; 547 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 548 ISCSI_LOGIN_PARAM_FIRST_BURST_LENGTH)); 549 } 550 551 IMA_API IMA_STATUS IMA_SetMaxBurstLength( 552 IMA_OID lhbaId, 553 IMA_UINT maxBurstLength 554 ) 555 { 556 IMA_MIN_MAX_VALUE mv; 557 558 mv.currentValue = maxBurstLength; 559 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 560 ISCSI_LOGIN_PARAM_MAX_BURST_LENGTH)); 561 } 562 563 IMA_API IMA_STATUS IMA_SetMaxRecvDataSegmentLength( 564 IMA_OID lhbaId, 565 IMA_UINT maxRecvDataSegmentLength 566 ) 567 { 568 IMA_MIN_MAX_VALUE mv; 569 570 mv.currentValue = maxRecvDataSegmentLength; 571 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 572 ISCSI_LOGIN_PARAM_MAX_RECV_DATA_SEGMENT_LENGTH)); 573 } 574 575 IMA_API IMA_STATUS IMA_GetMaxConnectionsProperties( 576 IMA_OID Oid, 577 IMA_MIN_MAX_VALUE *pProps 578 ) 579 { 580 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 581 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS)); 582 } 583 584 IMA_API IMA_STATUS IMA_SetMaxConnections( 585 IMA_OID lhbaId, 586 IMA_UINT maxConnections 587 ) 588 { 589 IMA_MIN_MAX_VALUE mv; 590 591 mv.currentValue = maxConnections; 592 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 593 ISCSI_LOGIN_PARAM_MAX_CONNECTIONS)); 594 } 595 596 IMA_API IMA_STATUS IMA_GetDefaultTime2RetainProperties( 597 IMA_OID lhbaId, 598 IMA_MIN_MAX_VALUE *pProps 599 ) 600 { 601 return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps, 602 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN)); 603 } 604 605 IMA_API IMA_STATUS IMA_SetDefaultTime2Retain( 606 IMA_OID lhbaId, 607 IMA_UINT defaultTime2Retain 608 ) 609 { 610 IMA_MIN_MAX_VALUE mv; 611 612 mv.currentValue = defaultTime2Retain; 613 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 614 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_RETAIN)); 615 } 616 617 IMA_API IMA_STATUS IMA_GetDefaultTime2WaitProperties( 618 IMA_OID lhbaId, 619 IMA_MIN_MAX_VALUE *pProps 620 ) 621 { 622 return (getISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, pProps, 623 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT)); 624 } 625 626 IMA_API IMA_STATUS IMA_SetDefaultTime2Wait( 627 IMA_OID lhbaId, 628 IMA_UINT defaultTime2Wait 629 ) 630 { 631 IMA_MIN_MAX_VALUE mv; 632 633 mv.currentValue = defaultTime2Wait; 634 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 635 ISCSI_LOGIN_PARAM_DEFAULT_TIME_2_WAIT)); 636 } 637 638 IMA_API IMA_STATUS IMA_GetMaxOutstandingR2TProperties( 639 IMA_OID Oid, 640 IMA_MIN_MAX_VALUE *pProps 641 ) 642 { 643 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 644 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T)); 645 } 646 647 IMA_API IMA_STATUS IMA_SetMaxOutstandingR2T( 648 IMA_OID lhbaId, 649 IMA_UINT maxOutstandingR2T 650 ) 651 { 652 IMA_MIN_MAX_VALUE mv; 653 654 mv.currentValue = maxOutstandingR2T; 655 return (setISCSINodeParameter(MIN_MAX_PARAM, &lhbaId, &mv, 656 ISCSI_LOGIN_PARAM_OUTSTANDING_R2T)); 657 } 658 659 660 IMA_API IMA_STATUS IMA_GetErrorRecoveryLevelProperties( 661 IMA_OID Oid, 662 IMA_MIN_MAX_VALUE *pProps 663 ) 664 { 665 return (getISCSINodeParameter(MIN_MAX_PARAM, &Oid, pProps, 666 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL)); 667 } 668 669 IMA_API IMA_STATUS IMA_SetErrorRecoveryLevel( 670 IMA_OID Oid, 671 IMA_UINT errorRecoveryLevel 672 ) 673 { 674 IMA_MIN_MAX_VALUE mv; 675 676 mv.currentValue = errorRecoveryLevel; 677 return (setISCSINodeParameter(MIN_MAX_PARAM, &Oid, &mv, 678 ISCSI_LOGIN_PARAM_ERROR_RECOVERY_LEVEL)); 679 } 680 681 IMA_API IMA_STATUS IMA_GetInitialR2TProperties( 682 IMA_OID Oid, 683 IMA_BOOL_VALUE *pProps 684 ) 685 { 686 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 687 ISCSI_LOGIN_PARAM_INITIAL_R2T)); 688 } 689 690 IMA_API IMA_STATUS IMA_SetInitialR2T( 691 IMA_OID Oid, 692 IMA_BOOL initialR2T 693 ) 694 { 695 IMA_BOOL_VALUE bv; 696 697 bv.currentValue = initialR2T; 698 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 699 ISCSI_LOGIN_PARAM_INITIAL_R2T)); 700 } 701 702 703 IMA_API IMA_STATUS IMA_GetImmediateDataProperties( 704 IMA_OID Oid, 705 IMA_BOOL_VALUE *pProps 706 ) 707 { 708 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 709 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA)); 710 } 711 712 IMA_API IMA_STATUS IMA_SetImmediateData( 713 IMA_OID Oid, 714 IMA_BOOL immediateData 715 ) 716 { 717 IMA_BOOL_VALUE bv; 718 719 bv.currentValue = immediateData; 720 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 721 ISCSI_LOGIN_PARAM_IMMEDIATE_DATA)); 722 } 723 724 IMA_API IMA_STATUS IMA_GetDataPduInOrderProperties( 725 IMA_OID Oid, 726 IMA_BOOL_VALUE *pProps 727 ) 728 { 729 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 730 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER)); 731 } 732 733 IMA_API IMA_STATUS IMA_SetDataPduInOrder( 734 IMA_OID Oid, 735 IMA_BOOL dataPduInOrder 736 ) 737 { 738 IMA_BOOL_VALUE bv; 739 740 bv.currentValue = dataPduInOrder; 741 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 742 ISCSI_LOGIN_PARAM_DATA_PDU_IN_ORDER)); 743 } 744 745 IMA_API IMA_STATUS IMA_GetDataSequenceInOrderProperties( 746 IMA_OID Oid, 747 IMA_BOOL_VALUE *pProps 748 ) 749 { 750 return (getISCSINodeParameter(BOOL_PARAM, &Oid, pProps, 751 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER)); 752 } 753 754 IMA_API IMA_STATUS IMA_SetDataSequenceInOrder( 755 IMA_OID Oid, 756 IMA_BOOL dataSequenceInOrder 757 ) 758 { 759 IMA_BOOL_VALUE bv; 760 761 bv.currentValue = dataSequenceInOrder; 762 return (setISCSINodeParameter(BOOL_PARAM, &Oid, &bv, 763 ISCSI_LOGIN_PARAM_DATA_SEQUENCE_IN_ORDER)); 764 } 765 766 767 /*ARGSUSED*/ 768 IMA_API IMA_STATUS IMA_SetStatisticsCollection( 769 IMA_OID Oid, 770 IMA_BOOL enableStatisticsCollection 771 ) 772 { 773 return (IMA_ERROR_NOT_SUPPORTED); 774 } 775 776 777 /*ARGSUSED*/ 778 IMA_API IMA_STATUS IMA_GetDiscoveryAddressOidList( 779 IMA_OID Oid, 780 IMA_OID_LIST **ppList 781 ) 782 { 783 int fd, i, addr_list_size; 784 iscsi_addr_list_t *idlp, al_info; 785 786 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 787 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 788 ISCSI_DRIVER_DEVCTL, errno); 789 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 790 } 791 792 (void) memset(&al_info, 0, sizeof (al_info)); 793 al_info.al_vers = ISCSI_INTERFACE_VERSION; 794 al_info.al_in_cnt = 0; 795 796 /* 797 * Issue ioctl to obtain the number of targets. 798 */ 799 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 800 syslog(LOG_USER|LOG_DEBUG, 801 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 802 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 803 (void) close(fd); 804 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 805 } 806 807 addr_list_size = sizeof (iscsi_addr_list_t); 808 if (al_info.al_out_cnt > 1) { 809 addr_list_size += (sizeof (iscsi_addr_list_t) * 810 al_info.al_out_cnt - 1); 811 } 812 813 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size); 814 if (idlp == NULL) { 815 (void) close(fd); 816 return (IMA_ERROR_INSUFFICIENT_MEMORY); 817 } 818 819 idlp->al_vers = ISCSI_INTERFACE_VERSION; 820 idlp->al_in_cnt = al_info.al_out_cnt; 821 /* Issue the same ioctl again to obtain the OIDs. */ 822 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) { 823 syslog(LOG_USER|LOG_DEBUG, 824 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 825 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 826 free(idlp); 827 (void) close(fd); 828 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 829 } 830 831 *ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) + 832 idlp->al_out_cnt * sizeof (IMA_OID)); 833 if (*ppList == NULL) { 834 free(idlp); 835 (void) close(fd); 836 return (IMA_ERROR_INSUFFICIENT_MEMORY); 837 } 838 (*ppList)->oidCount = idlp->al_out_cnt; 839 840 for (i = 0; i < idlp->al_out_cnt; i++) { 841 (*ppList)->oids[i].objectType = 842 IMA_OBJECT_TYPE_DISCOVERY_ADDRESS; 843 (*ppList)->oids[i].ownerId = pluginOwnerId; 844 (*ppList)->oids[i].objectSequenceNumber = 845 idlp->al_addrs[i].a_oid; 846 } 847 848 free(idlp); 849 (void) close(fd); 850 851 return (IMA_STATUS_SUCCESS); 852 } 853 854 855 /* ARGSUSED */ 856 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetOidList( 857 IMA_OID Oid, 858 IMA_OID_LIST **ppList 859 ) 860 { 861 if (Oid.objectType == IMA_OBJECT_TYPE_PNP) { 862 return (IMA_ERROR_OBJECT_NOT_FOUND); 863 } 864 865 return (get_target_oid_list(ISCSI_STATIC_TGT_OID_LIST, ppList)); 866 } 867 868 /* ARGSUSED */ 869 IMA_API IMA_STATUS IMA_GetTargetOidList( 870 IMA_OID Oid, 871 IMA_OID_LIST **ppList 872 ) 873 { 874 return (get_target_oid_list(ISCSI_TGT_PARAM_OID_LIST, ppList)); 875 } 876 877 /*ARGSUSED*/ 878 IMA_API IMA_STATUS IMA_SetIsnsDiscovery( 879 IMA_OID phbaId, 880 IMA_BOOL enableIsnsDiscovery, 881 IMA_ISNS_DISCOVERY_METHOD discoveryMethod, 882 const IMA_HOST_ID *iSnsHost 883 ) 884 { 885 /* XXX need to set discovery Method and domaineName */ 886 return (configure_discovery_method(enableIsnsDiscovery, 887 iSCSIDiscoveryMethodISNS)); 888 } 889 890 891 /* ARGSUSED */ 892 IMA_API IMA_STATUS IMA_SetSlpDiscovery( 893 IMA_OID phbaId, 894 IMA_BOOL enableSlpDiscovery 895 ) 896 { 897 return (configure_discovery_method(enableSlpDiscovery, 898 iSCSIDiscoveryMethodSLP)); 899 } 900 901 902 /* ARGSUSED */ 903 IMA_API IMA_STATUS IMA_SetStaticDiscovery( 904 IMA_OID phbaId, 905 IMA_BOOL enableStaticDiscovery 906 ) 907 { 908 return (configure_discovery_method(enableStaticDiscovery, 909 iSCSIDiscoveryMethodStatic)); 910 } 911 912 /* ARGSUSED */ 913 IMA_API IMA_STATUS IMA_SetSendTargetsDiscovery( 914 IMA_OID phbaId, 915 IMA_BOOL enableSendTargetsDiscovery 916 ) 917 { 918 return (configure_discovery_method(enableSendTargetsDiscovery, 919 iSCSIDiscoveryMethodSendTargets)); 920 } 921 922 /*ARGSUSED*/ 923 IMA_API IMA_STATUS IMA_RemoveDiscoveryAddress( 924 IMA_OID discoveryAddressOid 925 ) 926 { 927 int status, fd, i, addr_list_size; 928 iscsi_addr_list_t *idlp, al_info; 929 iscsi_addr_t *matched_addr = NULL; 930 entry_t entry; 931 932 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 933 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 934 ISCSI_DRIVER_DEVCTL, errno); 935 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 936 } 937 938 (void) memset(&al_info, 0, sizeof (al_info)); 939 al_info.al_vers = ISCSI_INTERFACE_VERSION; 940 al_info.al_in_cnt = 0; 941 942 /* 943 * Issue ioctl to obtain the number of discovery address. 944 */ 945 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 946 syslog(LOG_USER|LOG_DEBUG, 947 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 948 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 949 (void) close(fd); 950 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 951 } 952 953 if (al_info.al_out_cnt == 0) { 954 return (IMA_ERROR_OBJECT_NOT_FOUND); 955 } 956 957 addr_list_size = sizeof (iscsi_addr_list_t); 958 if (al_info.al_out_cnt > 1) { 959 addr_list_size += (sizeof (iscsi_addr_list_t) * 960 al_info.al_out_cnt - 1); 961 } 962 963 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size); 964 if (idlp == NULL) { 965 (void) close(fd); 966 return (IMA_ERROR_INSUFFICIENT_MEMORY); 967 } 968 969 idlp->al_vers = ISCSI_INTERFACE_VERSION; 970 idlp->al_in_cnt = al_info.al_out_cnt; 971 972 /* Issue the same ioctl again to obtain the OIDs. */ 973 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) { 974 syslog(LOG_USER|LOG_DEBUG, 975 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 976 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 977 free(idlp); 978 (void) close(fd); 979 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 980 } 981 982 for (i = 0; i < idlp->al_out_cnt; i++) { 983 if (discoveryAddressOid.objectSequenceNumber != 984 idlp->al_addrs[i].a_oid) 985 continue; 986 matched_addr = &(idlp->al_addrs[i]); 987 } 988 989 if (matched_addr == NULL) { 990 return (IMA_ERROR_OBJECT_NOT_FOUND); 991 } 992 993 994 (void) memset(&entry, 0, sizeof (entry_t)); 995 entry.e_vers = ISCSI_INTERFACE_VERSION; 996 entry.e_oid = discoveryAddressOid.objectSequenceNumber; 997 if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) { 998 bcopy(&matched_addr->a_addr.i_addr.in4, 999 &entry.e_u.u_in4, sizeof (entry.e_u.u_in4)); 1000 entry.e_insize = sizeof (struct in_addr); 1001 } else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) { 1002 bcopy(&matched_addr->a_addr.i_addr.in6, 1003 &entry.e_u.u_in6, sizeof (entry.e_u.u_in6)); 1004 entry.e_insize = sizeof (struct in6_addr); 1005 } else { 1006 /* Should not happen */ 1007 syslog(LOG_USER|LOG_DEBUG, 1008 "ISCSI_STATIC_GET returned bad address"); 1009 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1010 } 1011 1012 entry.e_port = matched_addr->a_port; 1013 entry.e_tpgt = 0; 1014 entry.e_oid = discoveryAddressOid.objectSequenceNumber; 1015 1016 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_CLEAR, &entry)) { 1017 status = errno; 1018 (void) close(fd); 1019 syslog(LOG_USER|LOG_DEBUG, 1020 "ISCSI_DISCOVERY_ADDR_CLEAR ioctl failed, errno: %d", 1021 errno); 1022 if (status == EBUSY) { 1023 return (IMA_ERROR_LU_IN_USE); 1024 } else { 1025 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1026 } 1027 } 1028 1029 free(idlp); 1030 (void) close(fd); 1031 return (IMA_STATUS_SUCCESS); 1032 } 1033 1034 1035 /*ARGSUSED*/ 1036 IMA_API IMA_STATUS IMA_AddDiscoveryAddress( 1037 IMA_OID oid, 1038 const IMA_TARGET_ADDRESS discoveryAddress, 1039 IMA_OID *pDiscoveryAddressOid 1040 ) 1041 { 1042 entry_t entry; 1043 int fd; 1044 1045 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1046 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1047 ISCSI_DRIVER_DEVCTL, errno); 1048 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1049 } 1050 1051 if (prepare_discovery_entry(discoveryAddress, &entry) != 1052 DISC_ADDR_OK) { 1053 (void) close(fd); 1054 return (IMA_ERROR_INVALID_PARAMETER); 1055 } 1056 1057 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_SET, &entry)) { 1058 syslog(LOG_USER|LOG_DEBUG, 1059 "ISCSI_DISCOVERY_ADDR_SET ioctl failed, errno: %d", 1060 errno); 1061 (void) close(fd); 1062 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1063 } 1064 1065 pDiscoveryAddressOid->ownerId = pluginOwnerId; 1066 pDiscoveryAddressOid->objectType = IMA_OBJECT_TYPE_DISCOVERY_ADDRESS; 1067 pDiscoveryAddressOid->objectSequenceNumber = entry.e_oid; 1068 1069 (void) close(fd); 1070 return (IMA_STATUS_SUCCESS); 1071 } 1072 1073 IMA_API IMA_STATUS IMA_GetStaticDiscoveryTargetProperties( 1074 IMA_OID staticTargetOid, 1075 IMA_STATIC_DISCOVERY_TARGET_PROPERTIES *pProps 1076 ) 1077 { 1078 char static_target_addr_str[SUN_IMA_IP_ADDRESS_LEN]; 1079 char static_target_addr_port_str[SUN_IMA_IP_ADDRESS_LEN]; 1080 int af, fd, status; 1081 iscsi_static_property_t prop; 1082 /* LINTED */ 1083 IMA_HOST_ID *host; 1084 1085 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1086 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1087 ISCSI_DRIVER_DEVCTL, errno); 1088 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1089 } 1090 1091 (void) memset(&prop, 0, sizeof (iscsi_static_property_t)); 1092 prop.p_vers = ISCSI_INTERFACE_VERSION; 1093 prop.p_oid = (uint32_t)staticTargetOid.objectSequenceNumber; 1094 if (ioctl(fd, ISCSI_STATIC_GET, &prop) != 0) { 1095 status = errno; 1096 (void) close(fd); 1097 syslog(LOG_USER|LOG_DEBUG, 1098 "ISCSI_STATIC_GET ioctl failed, errno: %d", status); 1099 if (status == ENOENT) { 1100 return (IMA_ERROR_OBJECT_NOT_FOUND); 1101 1102 } else { 1103 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1104 } 1105 } 1106 (void) close(fd); 1107 1108 (void) mbstowcs(pProps->staticTarget.targetName, (char *)prop.p_name, 1109 sizeof (pProps->staticTarget.targetName)/sizeof (IMA_WCHAR)); 1110 1111 if (prop.p_addr_list.al_addrs[0].a_addr.i_insize == 1112 sizeof (struct in_addr)) { 1113 /* IPv4 */ 1114 af = AF_INET; 1115 } else if (prop.p_addr_list.al_addrs[0].a_addr.i_insize == 1116 sizeof (struct in6_addr)) { 1117 /* IPv6 */ 1118 af = AF_INET6; 1119 } else { 1120 /* Should not happen */ 1121 syslog(LOG_USER|LOG_DEBUG, 1122 "ISCSI_STATIC_GET returned bad address"); 1123 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1124 } 1125 1126 if (inet_ntop(af, &prop.p_addr_list.al_addrs[0].a_addr.i_addr, 1127 static_target_addr_str, sizeof (static_target_addr_str)) == NULL) { 1128 /* Should not happen */ 1129 syslog(LOG_USER|LOG_DEBUG, 1130 "ISCSI_STATIC_GET returned address that cannot " 1131 "be inet_ntop"); 1132 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1133 } else { 1134 if (af == AF_INET) { 1135 (void) snprintf(static_target_addr_port_str, 1136 SUN_IMA_IP_ADDRESS_LEN, 1137 "%s:%ld", 1138 static_target_addr_str, 1139 prop.p_addr_list.al_addrs[0].a_port); 1140 } else { 1141 (void) snprintf(static_target_addr_port_str, 1142 SUN_IMA_IP_ADDRESS_LEN, 1143 "[%s]:%ld", 1144 static_target_addr_str, 1145 prop.p_addr_list.al_addrs[0].a_port); 1146 } 1147 host = &pProps->staticTarget.targetAddress.hostnameIpAddress; 1148 (void) mbstowcs(pProps->staticTarget. 1149 targetAddress.hostnameIpAddress. 1150 id.hostname, static_target_addr_port_str, 1151 sizeof (host->id.hostname) / sizeof (IMA_WCHAR)); 1152 } 1153 1154 return (IMA_STATUS_SUCCESS); 1155 } 1156 1157 /*ARGSUSED*/ 1158 IMA_API IMA_STATUS IMA_GetDiscoveryAddressProperties( 1159 IMA_OID discoveryAddressOid, 1160 IMA_DISCOVERY_ADDRESS_PROPERTIES *pProps 1161 ) 1162 { 1163 int fd; 1164 int i; 1165 int addr_list_size; 1166 iscsi_addr_list_t *idlp, al_info; 1167 iscsi_addr_t *matched_addr = NULL; 1168 /* LINTED */ 1169 IMA_TARGET_ADDRESS *addr; 1170 1171 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1172 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1173 ISCSI_DRIVER_DEVCTL, errno); 1174 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1175 } 1176 1177 (void) memset(&al_info, 0, sizeof (al_info)); 1178 al_info.al_vers = ISCSI_INTERFACE_VERSION; 1179 al_info.al_in_cnt = 0; 1180 1181 /* 1182 * Issue ioctl to obtain the number of discovery addresses. 1183 */ 1184 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 1185 (void) close(fd); 1186 syslog(LOG_USER|LOG_DEBUG, 1187 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl %d failed, errno: %d", 1188 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 1189 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1190 } 1191 1192 if (al_info.al_out_cnt == 0) { 1193 return (IMA_ERROR_OBJECT_NOT_FOUND); 1194 } 1195 1196 addr_list_size = sizeof (iscsi_addr_list_t); 1197 if (al_info.al_out_cnt > 1) { 1198 addr_list_size += (sizeof (iscsi_addr_list_t) * 1199 al_info.al_out_cnt - 1); 1200 } 1201 1202 idlp = (iscsi_addr_list_t *)calloc(1, addr_list_size); 1203 if (idlp == NULL) { 1204 (void) close(fd); 1205 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1206 } 1207 1208 idlp->al_vers = ISCSI_INTERFACE_VERSION; 1209 idlp->al_in_cnt = al_info.al_out_cnt; 1210 1211 /* Issue the same ioctl again to obtain the OIDs. */ 1212 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, idlp) != 0) { 1213 free(idlp); 1214 (void) close(fd); 1215 syslog(LOG_USER|LOG_DEBUG, 1216 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 1217 ISCSI_DISCOVERY_ADDR_LIST_GET, errno); 1218 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1219 } 1220 1221 for (i = 0; i < idlp->al_out_cnt; i++) { 1222 if (discoveryAddressOid.objectSequenceNumber != 1223 idlp->al_addrs[i].a_oid) 1224 continue; 1225 matched_addr = &(idlp->al_addrs[i]); 1226 } 1227 1228 if (matched_addr == NULL) { 1229 return (IMA_ERROR_OBJECT_NOT_FOUND); 1230 } 1231 1232 if (matched_addr->a_addr.i_insize == sizeof (struct in_addr)) { 1233 pProps->discoveryAddress.hostnameIpAddress.id. 1234 ipAddress.ipv4Address = IMA_TRUE; 1235 } else if (matched_addr->a_addr.i_insize == sizeof (struct in6_addr)) { 1236 pProps->discoveryAddress.hostnameIpAddress.id. 1237 ipAddress.ipv4Address = IMA_FALSE; 1238 } else { 1239 /* Should not happen */ 1240 syslog(LOG_USER|LOG_DEBUG, 1241 "ISCSI_STATIC_GET returned bad address"); 1242 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1243 } 1244 1245 addr = &pProps->discoveryAddress; 1246 bcopy(&(matched_addr->a_addr.i_addr), pProps->discoveryAddress. 1247 hostnameIpAddress.id.ipAddress.ipAddress, 1248 sizeof (addr->hostnameIpAddress.id.ipAddress.ipAddress)); 1249 1250 pProps->discoveryAddress.portNumber = matched_addr->a_port; 1251 1252 pProps->associatedLhbaOid.objectType = IMA_OBJECT_TYPE_LHBA; 1253 pProps->associatedLhbaOid.ownerId = pluginOwnerId; 1254 pProps->associatedLhbaOid.objectSequenceNumber = ISCSI_INITIATOR_OID; 1255 1256 free(idlp); 1257 (void) close(fd); 1258 1259 return (IMA_STATUS_SUCCESS); 1260 } 1261 1262 IMA_API IMA_STATUS IMA_RemoveStaticDiscoveryTarget( 1263 IMA_OID staticTargetOid 1264 ) 1265 { 1266 entry_t entry; 1267 int status, fd; 1268 1269 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1270 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1271 ISCSI_DRIVER_DEVCTL, errno); 1272 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1273 } 1274 1275 (void) memset(&entry, 0, sizeof (entry_t)); 1276 entry.e_vers = ISCSI_INTERFACE_VERSION; 1277 entry.e_oid = (uint32_t)staticTargetOid.objectSequenceNumber; 1278 1279 if (ioctl(fd, ISCSI_STATIC_CLEAR, &entry)) { 1280 status = errno; 1281 (void) close(fd); 1282 syslog(LOG_USER|LOG_DEBUG, 1283 "ISCSI_STATIC_CLEAR ioctl failed, errno: %d", errno); 1284 if (status == EBUSY) { 1285 return (IMA_ERROR_LU_IN_USE); 1286 } else { 1287 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1288 } 1289 } 1290 1291 (void) close(fd); 1292 return (IMA_STATUS_SUCCESS); 1293 } 1294 1295 /*ARGSUSED*/ 1296 IMA_API IMA_STATUS IMA_AddStaticDiscoveryTarget( 1297 IMA_OID lhbaOid, 1298 const IMA_STATIC_DISCOVERY_TARGET staticConfig, 1299 IMA_OID *pTargetOid 1300 ) 1301 { 1302 char tmp_target_str[SUN_IMA_IP_ADDRESS_LEN]; 1303 char target_addr_str[SUN_IMA_IP_ADDRESS_LEN]; 1304 char target_port_str[SUN_IMA_IP_PORT_LEN]; 1305 iscsi_target_entry_t target; 1306 int fd; 1307 int target_in_addr_size; 1308 int target_port; 1309 union { 1310 struct in_addr u_in4; 1311 struct in6_addr u_in6; 1312 } target_in; 1313 1314 /* 1315 * staticConfig.address may come in with port number at its trailer. 1316 * Parse it to separate the IP address and port number. 1317 * Also translate the hostname to IP address if needed. 1318 */ 1319 (void) wcstombs(tmp_target_str, 1320 staticConfig.targetAddress.hostnameIpAddress. 1321 id.hostname, sizeof (tmp_target_str)); 1322 1323 if (tmp_target_str[0] == '[') { 1324 /* IPv6 address */ 1325 char *closeBracketPos; 1326 closeBracketPos = strchr(tmp_target_str, ']'); 1327 if (!closeBracketPos) { 1328 return (IMA_ERROR_INVALID_PARAMETER); 1329 } 1330 1331 *closeBracketPos = NULL; 1332 (void) strlcpy(target_addr_str, &tmp_target_str[1], 1333 sizeof (target_addr_str)); 1334 1335 if (inet_pton(AF_INET6, target_addr_str, 1336 &target_in.u_in6) != 1) { 1337 return (IMA_ERROR_INVALID_PARAMETER); 1338 } 1339 target_in_addr_size = sizeof (struct in6_addr); 1340 1341 /* Extract the port number */ 1342 closeBracketPos++; 1343 if (*closeBracketPos == ':') { 1344 closeBracketPos++; 1345 1346 if (*closeBracketPos != NULL) { 1347 (void) strlcpy(target_port_str, closeBracketPos, 1348 sizeof (target_port_str)); 1349 target_port = atoi(target_port_str); 1350 } else { 1351 target_port = ISCSI_LISTEN_PORT; 1352 } 1353 } else { 1354 /* No port number specified; use default port */ 1355 target_port = ISCSI_LISTEN_PORT; 1356 } 1357 } else { 1358 /* IPv4 address */ 1359 char *colonPos; 1360 colonPos = strchr(tmp_target_str, ':'); 1361 if (!colonPos) { 1362 /* No port number specified; use default port */ 1363 target_port = ISCSI_LISTEN_PORT; 1364 (void) strlcpy(target_addr_str, tmp_target_str, 1365 sizeof (target_addr_str)); 1366 } else { 1367 *colonPos = NULL; 1368 (void) strlcpy(target_addr_str, tmp_target_str, 1369 sizeof (target_addr_str)); 1370 /* Extract the port number */ 1371 colonPos++; 1372 if (*colonPos != NULL) { 1373 (void) strlcpy(target_port_str, colonPos, 1374 sizeof (target_port_str)); 1375 target_port = atoi(target_port_str); 1376 } else { 1377 target_port = ISCSI_LISTEN_PORT; 1378 } 1379 } 1380 1381 if (inet_pton(AF_INET, target_addr_str, 1382 &target_in.u_in4) != 1) { 1383 return (IMA_ERROR_INVALID_PARAMETER); 1384 } 1385 1386 target_in_addr_size = sizeof (struct in_addr); 1387 } 1388 1389 1390 (void) memset(&target, 0, sizeof (iscsi_target_entry_t)); 1391 target.te_entry.e_vers = ISCSI_INTERFACE_VERSION; 1392 target.te_entry.e_oid = ISCSI_OID_NOTSET; 1393 target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT; 1394 1395 (void) wcstombs((char *)target.te_name, staticConfig.targetName, 1396 ISCSI_MAX_NAME_LEN); 1397 1398 target.te_entry.e_insize = target_in_addr_size; 1399 if (target.te_entry.e_insize == sizeof (struct in_addr)) { 1400 target.te_entry.e_u.u_in4.s_addr = target_in.u_in4.s_addr; 1401 } else if (target.te_entry.e_insize == sizeof (struct in6_addr)) { 1402 bcopy(target_in.u_in6.s6_addr, 1403 target.te_entry.e_u.u_in6.s6_addr, 1404 sizeof (struct in6_addr)); 1405 } else { 1406 /* Should not happen */ 1407 syslog(LOG_USER|LOG_DEBUG, 1408 "ISCSI_STATIC_GET returned bad address"); 1409 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1410 } 1411 1412 target.te_entry.e_port = target_port; 1413 1414 /* No target portal group specified. Default to -1. */ 1415 target.te_entry.e_tpgt = ISCSI_DEFAULT_TPGT; 1416 1417 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1418 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1419 ISCSI_DRIVER_DEVCTL, errno); 1420 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1421 } 1422 1423 if (ioctl(fd, ISCSI_STATIC_SET, &target)) { 1424 /* 1425 * Encountered problem setting the IP address and port for 1426 * the target just added. 1427 */ 1428 (void) close(fd); 1429 syslog(LOG_USER|LOG_DEBUG, 1430 "ISCSI_STATIC_SET ioctl failed, errno: %d", errno); 1431 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1432 } 1433 1434 pTargetOid->objectType = IMA_OBJECT_TYPE_TARGET; 1435 pTargetOid->ownerId = pluginOwnerId; 1436 pTargetOid->objectSequenceNumber = target.te_entry.e_oid; 1437 1438 (void) close(fd); 1439 return (IMA_STATUS_SUCCESS); 1440 } 1441 1442 IMA_API IMA_STATUS IMA_GetTargetProperties( 1443 IMA_OID targetId, 1444 IMA_TARGET_PROPERTIES *pProps 1445 ) 1446 { 1447 return (getTargetProperties(targetId, pProps)); 1448 } 1449 1450 static IMA_STATUS getTargetProperties( 1451 IMA_OID targetId, 1452 IMA_TARGET_PROPERTIES *pProps 1453 ) 1454 { 1455 int fd; 1456 iscsi_property_t prop; 1457 1458 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1459 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1460 ISCSI_DRIVER_DEVCTL, errno); 1461 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1462 } 1463 1464 (void) memset(&prop, 0, sizeof (iscsi_property_t)); 1465 prop.p_vers = ISCSI_INTERFACE_VERSION; 1466 prop.p_oid = (uint32_t)targetId.objectSequenceNumber; 1467 1468 if (ioctl(fd, ISCSI_TARGET_PROPS_GET, &prop) != 0) { 1469 (void) close(fd); 1470 syslog(LOG_USER|LOG_DEBUG, 1471 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno); 1472 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1473 } 1474 1475 (void) mbstowcs(pProps->name, (char *)prop.p_name, IMA_NODE_NAME_LEN); 1476 (void) memset(pProps->alias, 0, 1477 sizeof (IMA_WCHAR) * IMA_NODE_ALIAS_LEN); 1478 if (prop.p_alias_len > 0) { 1479 (void) mbstowcs(pProps->alias, (char *)prop.p_alias, 1480 IMA_NODE_ALIAS_LEN); 1481 } 1482 1483 /* Initialize the discovery method to unknown method. */ 1484 pProps->discoveryMethodFlags = IMA_TARGET_DISCOVERY_METHOD_UNKNOWN; 1485 if (!((prop.p_discovery & iSCSIDiscoveryMethodStatic) ^ 1486 iSCSIDiscoveryMethodStatic)) { 1487 pProps->discoveryMethodFlags |= 1488 IMA_TARGET_DISCOVERY_METHOD_STATIC; 1489 } 1490 1491 if (!((prop.p_discovery & iSCSIDiscoveryMethodSLP) ^ 1492 iSCSIDiscoveryMethodSLP)) { 1493 pProps->discoveryMethodFlags |= IMA_TARGET_DISCOVERY_METHOD_SLP; 1494 } 1495 1496 if (!((prop.p_discovery & iSCSIDiscoveryMethodISNS) ^ 1497 iSCSIDiscoveryMethodISNS)) { 1498 pProps->discoveryMethodFlags |= iSCSIDiscoveryMethodISNS; 1499 } 1500 1501 if (!((prop.p_discovery & iSCSIDiscoveryMethodSendTargets) ^ 1502 iSCSIDiscoveryMethodSendTargets)) { 1503 pProps->discoveryMethodFlags |= iSCSIDiscoveryMethodSendTargets; 1504 } 1505 1506 (void) close(fd); 1507 return (IMA_STATUS_SUCCESS); 1508 } 1509 1510 /*ARGSUSED*/ 1511 IMA_API IMA_STATUS IMA_GetTargetErrorStatistics( 1512 IMA_OID targetId, 1513 IMA_TARGET_ERROR_STATISTICS *pStats 1514 ) 1515 { 1516 return (IMA_ERROR_NOT_SUPPORTED); 1517 } 1518 1519 IMA_API IMA_STATUS IMA_GetLuOidList( 1520 IMA_OID oid, 1521 IMA_OID_LIST **ppList 1522 ) 1523 { 1524 IMA_STATUS status; 1525 int i; 1526 iscsi_lun_list_t *pLunList; 1527 1528 if (oid.objectType == IMA_OBJECT_TYPE_LHBA) { 1529 status = get_target_lun_oid_list(NULL, &pLunList); 1530 } else { 1531 status = get_target_lun_oid_list(&oid, &pLunList); 1532 } 1533 1534 if (!IMA_SUCCESS(status)) { 1535 return (status); 1536 } 1537 1538 *ppList = (IMA_OID_LIST *) calloc(1, (sizeof (IMA_OID_LIST) + 1539 (pLunList->ll_out_cnt * sizeof (IMA_OID)))); 1540 if (*ppList == NULL) { 1541 return (IMA_ERROR_INSUFFICIENT_MEMORY); 1542 } 1543 (*ppList)->oidCount = pLunList->ll_out_cnt; 1544 for (i = 0; i < pLunList->ll_out_cnt; i++) { 1545 (*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_LU; 1546 (*ppList)->oids[i].ownerId = pluginOwnerId; 1547 (*ppList)->oids[i].objectSequenceNumber = 1548 pLunList->ll_luns[i].l_oid; 1549 } 1550 1551 free(pLunList); 1552 return (IMA_STATUS_SUCCESS); 1553 } 1554 1555 IMA_API IMA_STATUS IMA_GetLuOid( 1556 IMA_OID targetId, 1557 IMA_UINT64 lun, 1558 IMA_OID *pluId 1559 ) 1560 { 1561 IMA_STATUS status; 1562 int i; 1563 iscsi_lun_list_t *pLunList; 1564 1565 status = get_target_lun_oid_list(&targetId, &pLunList); 1566 if (!IMA_SUCCESS(status)) { 1567 return (status); 1568 } 1569 1570 for (i = 0; i < pLunList->ll_out_cnt; i++) { 1571 if (pLunList->ll_luns[i].l_num == lun) { 1572 pluId->objectType = IMA_OBJECT_TYPE_LU; 1573 pluId->ownerId = pluginOwnerId; 1574 pluId->objectSequenceNumber = 1575 pLunList->ll_luns[i].l_oid; 1576 free(pLunList); 1577 return (IMA_STATUS_SUCCESS); 1578 } 1579 } 1580 1581 free(pLunList); 1582 return (IMA_ERROR_OBJECT_NOT_FOUND); 1583 } 1584 1585 IMA_API IMA_STATUS IMA_GetLuProperties( 1586 IMA_OID luId, 1587 IMA_LU_PROPERTIES *pProps 1588 ) 1589 { 1590 return (getLuProperties(luId, pProps)); 1591 } 1592 1593 static IMA_STATUS getLuProperties( 1594 IMA_OID luId, 1595 IMA_LU_PROPERTIES *pProps 1596 ) 1597 { 1598 IMA_STATUS status; 1599 iscsi_lun_list_t *pLunList; 1600 int j; 1601 IMA_BOOL lunMatch = IMA_FALSE; 1602 int fd; 1603 iscsi_lun_props_t lun; 1604 di_devlink_handle_t hdl; 1605 1606 if (luId.objectType != IMA_OBJECT_TYPE_LU) { 1607 return (IMA_ERROR_INCORRECT_OBJECT_TYPE); 1608 } 1609 1610 /* 1611 * get list of lun oids for all targets 1612 */ 1613 status = get_target_lun_oid_list(NULL, &pLunList); 1614 if (!IMA_SUCCESS(status)) { 1615 return (status); 1616 } 1617 for (j = 0; j < pLunList->ll_out_cnt; j++) { 1618 /* 1619 * for each lun, check if match is found 1620 */ 1621 if (pLunList->ll_luns[j].l_oid == luId.objectSequenceNumber) { 1622 /* 1623 * match found, break out of lun loop 1624 */ 1625 lunMatch = IMA_TRUE; 1626 break; 1627 } 1628 } 1629 1630 if (lunMatch == IMA_TRUE) { 1631 (void) memset(&lun, 0, sizeof (iscsi_lun_props_t)); 1632 lun.lp_vers = ISCSI_INTERFACE_VERSION; 1633 lun.lp_tgt_oid = pLunList->ll_luns[j].l_tgt_oid; 1634 lun.lp_oid = pLunList->ll_luns[j].l_oid; 1635 } 1636 1637 free(pLunList); 1638 1639 if (lunMatch == IMA_FALSE) { 1640 return (IMA_ERROR_OBJECT_NOT_FOUND); 1641 } 1642 1643 /* 1644 * get lun properties 1645 */ 1646 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1647 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1648 ISCSI_DRIVER_DEVCTL, errno); 1649 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1650 } 1651 1652 if (ioctl(fd, ISCSI_LUN_PROPS_GET, &lun)) { 1653 syslog(LOG_USER|LOG_DEBUG, 1654 "ISCSI_LUN_PROPS_GET ioctl failed, errno: %d", errno); 1655 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1656 } 1657 (void) close(fd); 1658 1659 /* 1660 * set property values 1661 */ 1662 pProps->associatedTargetOid.objectType = IMA_OBJECT_TYPE_TARGET; 1663 pProps->associatedTargetOid.ownerId = pluginOwnerId; 1664 pProps->associatedTargetOid.objectSequenceNumber = lun.lp_tgt_oid; 1665 pProps->targetLun = (IMA_UINT64)lun.lp_num; 1666 pProps->exposedToOs = IMA_TRUE; 1667 (void) memset(&pProps->timeExposedToOs, 0, 1668 sizeof (pProps->timeExposedToOs)); 1669 1670 if (lun.lp_status == LunValid) { 1671 1672 /* add minor device delimiter */ 1673 (void) strcat(lun.lp_pathname, ":"); 1674 1675 if ((strstr(lun.lp_pathname, "sd@") != NULL) || 1676 (strstr(lun.lp_pathname, "ssd@") != NULL) || 1677 (strstr(lun.lp_pathname, "disk@") != NULL)) { 1678 /* 1679 * modify returned pathname to obtain the 2nd slice 1680 * of the raw disk 1681 */ 1682 (void) strcat(lun.lp_pathname, "c,raw"); 1683 } 1684 1685 /* 1686 * Pathname returned by driver is the physical device path. 1687 * This name needs to be converted to the OS device name. 1688 */ 1689 if (hdl = di_devlink_init(lun.lp_pathname, DI_MAKE_LINK)) { 1690 pProps->osDeviceName[0] = L'\0'; 1691 (void) di_devlink_walk(hdl, NULL, lun.lp_pathname, 1692 DI_PRIMARY_LINK, (void *)pProps->osDeviceName, 1693 get_lun_devlink); 1694 if (pProps->osDeviceName[0] != L'\0') { 1695 /* OS device name synchronously made */ 1696 pProps->osDeviceNameValid = IMA_TRUE; 1697 } else { 1698 pProps->osDeviceNameValid = IMA_FALSE; 1699 } 1700 1701 (void) di_devlink_fini(&hdl); 1702 } else { 1703 pProps->osDeviceNameValid = IMA_FALSE; 1704 } 1705 1706 } else { 1707 pProps->osDeviceNameValid = IMA_FALSE; 1708 } 1709 1710 pProps->osParallelIdsValid = IMA_FALSE; 1711 1712 return (IMA_STATUS_SUCCESS); 1713 } 1714 1715 /*ARGSUSED*/ 1716 IMA_API IMA_STATUS IMA_GetStatisticsProperties( 1717 IMA_OID oid, 1718 IMA_STATISTICS_PROPERTIES *pProps 1719 ) 1720 { 1721 return (IMA_ERROR_NOT_SUPPORTED); 1722 } 1723 1724 /*ARGSUSED*/ 1725 IMA_API IMA_STATUS IMA_GetDeviceStatistics( 1726 IMA_OID luId, 1727 IMA_DEVICE_STATISTICS *pStats 1728 ) 1729 { 1730 return (IMA_ERROR_NOT_SUPPORTED); 1731 } 1732 1733 /*ARGSUSED*/ 1734 IMA_API IMA_STATUS IMA_LuInquiry( 1735 IMA_OID deviceId, 1736 IMA_BOOL evpd, 1737 IMA_BOOL cmddt, 1738 IMA_BYTE pageCode, 1739 IMA_BYTE *pOutputBuffer, 1740 IMA_UINT *pOutputBufferLength, 1741 IMA_BYTE *pSenseBuffer, 1742 IMA_UINT *pSenseBufferLength 1743 ) 1744 { 1745 IMA_LU_PROPERTIES luProps; 1746 IMA_STATUS status; 1747 1748 char cmdblk [ INQUIRY_CMDLEN ] = 1749 { INQUIRY_CMD, /* command */ 1750 0, /* lun/reserved */ 1751 0, /* page code */ 1752 0, /* reserved */ 1753 INQUIRY_REPLY_LEN, /* allocation length */ 1754 0 }; /* reserved/flag/link */ 1755 1756 1757 int fd; 1758 iscsi_uscsi_t uscsi; 1759 1760 cmdblk[2] = pageCode; 1761 1762 (void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t)); 1763 uscsi.iu_vers = ISCSI_INTERFACE_VERSION; 1764 1765 /* iu_oid is a session oid in the driver */ 1766 if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) { 1767 uscsi.iu_oid = deviceId.objectSequenceNumber; 1768 uscsi.iu_lun = 0; 1769 } else { 1770 /* 1771 * Get LU properties and associated session oid 1772 * for this lun(deviceId) and put in uscsi.iu_oid 1773 */ 1774 status = getLuProperties(deviceId, &luProps); 1775 if (status != IMA_STATUS_SUCCESS) { 1776 return (status); 1777 } 1778 uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid. 1779 objectSequenceNumber; 1780 uscsi.iu_lun = luProps.targetLun; 1781 } 1782 1783 uscsi.iu_ucmd.uscsi_flags = USCSI_READ; 1784 uscsi.iu_ucmd.uscsi_timeout = USCSI_TIMEOUT_IN_SEC; 1785 uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer; 1786 uscsi.iu_ucmd.uscsi_buflen = *pOutputBufferLength; 1787 uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer; 1788 uscsi.iu_ucmd.uscsi_rqlen = *pSenseBufferLength; 1789 uscsi.iu_ucmd.uscsi_cdb = &cmdblk[0]; 1790 uscsi.iu_ucmd.uscsi_cdblen = INQUIRY_CMDLEN; 1791 1792 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1793 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1794 ISCSI_DRIVER_DEVCTL, errno); 1795 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1796 } 1797 1798 if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) { 1799 (void) close(fd); 1800 syslog(LOG_USER|LOG_DEBUG, 1801 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno); 1802 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1803 } 1804 1805 return (IMA_STATUS_SUCCESS); 1806 } 1807 1808 /*ARGSUSED*/ 1809 IMA_API IMA_STATUS IMA_LuReadCapacity( 1810 IMA_OID deviceId, 1811 IMA_UINT cdbLength, 1812 IMA_BYTE *pOutputBuffer, 1813 IMA_UINT *pOutputBufferLength, 1814 1815 IMA_BYTE *pSenseBuffer, 1816 IMA_UINT *pSenseBufferLength 1817 ) 1818 { 1819 IMA_LU_PROPERTIES luProps; 1820 IMA_STATUS status; 1821 int fd; 1822 iscsi_uscsi_t uscsi; 1823 1824 char cmdblk [ INQUIRY_CMDLEN ] = 1825 { GETCAPACITY_CMD, /* command */ 1826 0, /* lun/reserved */ 1827 0, /* page code */ 1828 0, /* reserved */ 1829 INQUIRY_REPLY_LEN, /* allocation length */ 1830 0 }; /* reserved/flag/link */ 1831 1832 1833 1834 (void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t)); 1835 uscsi.iu_vers = ISCSI_INTERFACE_VERSION; 1836 1837 /* iu_oid is a session oid in the driver */ 1838 if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) { 1839 uscsi.iu_oid = deviceId.objectSequenceNumber; 1840 uscsi.iu_lun = 0; 1841 } else { 1842 /* 1843 * Get LU properties and associated session oid 1844 * for this lun(deviceId) and put in uscsi.iu_oid 1845 */ 1846 status = getLuProperties(deviceId, &luProps); 1847 if (status != IMA_STATUS_SUCCESS) { 1848 return (status); 1849 } 1850 uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid. 1851 objectSequenceNumber; 1852 uscsi.iu_lun = luProps.targetLun; 1853 } 1854 1855 uscsi.iu_ucmd.uscsi_flags = USCSI_READ; 1856 uscsi.iu_ucmd.uscsi_timeout = 10; 1857 uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer; 1858 uscsi.iu_ucmd.uscsi_buflen = *pOutputBufferLength; 1859 uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer; 1860 uscsi.iu_ucmd.uscsi_rqlen = *pSenseBufferLength; 1861 uscsi.iu_ucmd.uscsi_cdb = &cmdblk[0]; 1862 uscsi.iu_ucmd.uscsi_cdblen = INQUIRY_CMDLEN; 1863 1864 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1865 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1866 ISCSI_DRIVER_DEVCTL, errno); 1867 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1868 } 1869 1870 if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) { 1871 (void) close(fd); 1872 syslog(LOG_USER|LOG_DEBUG, 1873 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno); 1874 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1875 } 1876 1877 return (IMA_STATUS_SUCCESS); 1878 } 1879 1880 /*ARGSUSED*/ 1881 IMA_API IMA_STATUS IMA_LuReportLuns( 1882 IMA_OID deviceId, 1883 IMA_BOOL sendToWellKnownLun, 1884 IMA_BYTE selectReport, 1885 1886 IMA_BYTE *pOutputBuffer, 1887 IMA_UINT *pOutputBufferLength, 1888 1889 IMA_BYTE *pSenseBuffer, 1890 IMA_UINT *pSenseBufferLength 1891 ) 1892 { 1893 IMA_LU_PROPERTIES luProps; 1894 IMA_STATUS status; 1895 int fd; 1896 iscsi_uscsi_t uscsi; 1897 1898 char cmdblk [ INQUIRY_CMDLEN ] = 1899 { INQUIRY_CMD, /* command */ 1900 0, /* lun/reserved */ 1901 0, /* page code */ 1902 0, /* reserved */ 1903 INQUIRY_REPLY_LEN, /* allocation length */ 1904 0 }; /* reserved/flag/link */ 1905 1906 (void) memset(&uscsi, 0, sizeof (iscsi_uscsi_t)); 1907 uscsi.iu_vers = ISCSI_INTERFACE_VERSION; 1908 1909 /* iu_oid is a session oid in the driver */ 1910 if (deviceId.objectType == IMA_OBJECT_TYPE_TARGET) { 1911 uscsi.iu_oid = deviceId.objectSequenceNumber; 1912 uscsi.iu_lun = 0; 1913 } else { 1914 /* 1915 * Get LU properties and associated session oid 1916 * for this lun(deviceId) and put in uscsi.iu_oid 1917 */ 1918 status = getLuProperties(deviceId, &luProps); 1919 if (status != IMA_STATUS_SUCCESS) { 1920 return (status); 1921 } 1922 uscsi.iu_oid = (uint32_t)luProps.associatedTargetOid. 1923 objectSequenceNumber; 1924 uscsi.iu_lun = luProps.targetLun; 1925 } 1926 1927 uscsi.iu_ucmd.uscsi_flags = USCSI_READ; 1928 uscsi.iu_ucmd.uscsi_timeout = 10; 1929 uscsi.iu_ucmd.uscsi_bufaddr = (char *)pOutputBuffer; 1930 uscsi.iu_ucmd.uscsi_buflen = *pOutputBufferLength; 1931 uscsi.iu_ucmd.uscsi_rqbuf = (char *)pSenseBuffer; 1932 uscsi.iu_ucmd.uscsi_rqlen = *pSenseBufferLength; 1933 uscsi.iu_ucmd.uscsi_cdb = &cmdblk[0]; 1934 uscsi.iu_ucmd.uscsi_cdblen = INQUIRY_CMDLEN; 1935 1936 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 1937 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 1938 ISCSI_DRIVER_DEVCTL, errno); 1939 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1940 } 1941 1942 if (ioctl(fd, ISCSI_USCSI, &uscsi) != 0) { 1943 (void) close(fd); 1944 syslog(LOG_USER|LOG_DEBUG, 1945 "ISCSI_TARGET_PROPS_GET ioctl failed, errno: %d", errno); 1946 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 1947 } 1948 1949 return (IMA_STATUS_SUCCESS); 1950 } 1951 1952 /*ARGSUSED*/ 1953 IMA_API IMA_STATUS IMA_ExposeLu( 1954 IMA_OID luId 1955 ) 1956 { 1957 return (IMA_ERROR_NOT_SUPPORTED); 1958 } 1959 1960 /*ARGSUSED*/ 1961 IMA_API IMA_STATUS IMA_UnexposeLu( 1962 IMA_OID luId 1963 ) 1964 { 1965 return (IMA_ERROR_NOT_SUPPORTED); 1966 } 1967 1968 IMA_API IMA_STATUS IMA_GetAddressKeys( 1969 IMA_OID targetOid, 1970 IMA_ADDRESS_KEYS **ppKeys 1971 ) 1972 { 1973 IMA_STATUS status; 1974 IMA_TARGET_PROPERTIES targetProps; 1975 SUN_IMA_DISC_ADDR_PROP_LIST *discAddressList; 1976 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *pList; 1977 int i, j, addressKeyCount = 0; 1978 int addressKeyIdx = 0; 1979 1980 status = getTargetProperties(targetOid, &targetProps); 1981 if (status != IMA_STATUS_SUCCESS) { 1982 return (status); 1983 } 1984 1985 status = getDiscoveryAddressPropertiesList(&discAddressList); 1986 if (status != IMA_STATUS_SUCCESS) { 1987 return (status); 1988 } 1989 1990 /* Get the number of addresses to allocate */ 1991 for (i = 0; i < discAddressList->discAddrCount; i++) { 1992 (void) sendTargets(discAddressList->props[i].discoveryAddress, 1993 &pList); 1994 for (j = 0; j < pList->keyCount; j++) { 1995 if (wcsncmp(pList->keys[j].name, targetProps.name, 1996 wslen(pList->keys[j].name)) == 0) { 1997 addressKeyCount++; 1998 } 1999 } 2000 (void) IMA_FreeMemory(pList); 2001 } 2002 2003 *ppKeys = (IMA_ADDRESS_KEYS *)calloc(1, sizeof (IMA_ADDRESS_KEYS) + 2004 addressKeyCount * sizeof (IMA_ADDRESS_KEY)); 2005 if (*ppKeys == NULL) { 2006 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2007 } 2008 (*ppKeys)->addressKeyCount = addressKeyCount; 2009 addressKeyIdx = 0; 2010 2011 for (i = 0; i < discAddressList->discAddrCount; i++) { 2012 (void) sendTargets(discAddressList->props[i].discoveryAddress, 2013 &pList); 2014 for (j = 0; j < pList->keyCount; j++) { 2015 if (wcsncmp(pList->keys[j].name, targetProps.name, 2016 wslen(pList->keys[j].name)) != 0) { 2017 continue; 2018 } 2019 2020 bcopy(&(pList->keys[j].address.ipAddress), 2021 &((*ppKeys)->addressKeys[addressKeyIdx]. 2022 ipAddress), sizeof (IMA_IP_ADDRESS)); 2023 2024 (*ppKeys)->addressKeys[addressKeyIdx++].portNumber = 2025 pList->keys[j].address.portNumber; 2026 2027 } 2028 (void) IMA_FreeMemory(pList); 2029 } 2030 return (IMA_STATUS_SUCCESS); 2031 } 2032 2033 IMA_BOOL isAuthMethodValid(IMA_OID oid, IMA_AUTHMETHOD method) { 2034 IMA_STATUS status; 2035 IMA_AUTHMETHOD supportedList[MAX_AUTHMETHODS]; 2036 IMA_UINT i, supportedCount; 2037 IMA_BOOL supported; 2038 status = getSupportedAuthMethods(oid, IMA_FALSE, &supportedCount, 2039 supportedList); 2040 if (status != IMA_STATUS_SUCCESS) 2041 return (IMA_FALSE); 2042 2043 supported = IMA_FALSE; 2044 for (i = 0; i < supportedCount; i++) { 2045 if (method == supportedList[i]) { 2046 supported = IMA_TRUE; 2047 } 2048 } 2049 2050 return (supported); 2051 } 2052 2053 IMA_BOOL isAuthMethodListValid(IMA_OID oid, const IMA_AUTHMETHOD *pMethodList, 2054 IMA_UINT methodCount) { 2055 IMA_UINT i, j; 2056 2057 if (pMethodList == NULL) { 2058 return (IMA_FALSE); 2059 } 2060 /* Check list for duplicates */ 2061 for (i = 0; i < methodCount; i++) { 2062 for (j = i + 1; j < methodCount; j++) { 2063 if (pMethodList[i] == pMethodList[j]) { 2064 return (IMA_FALSE); 2065 } 2066 } 2067 2068 if (isAuthMethodValid(oid, pMethodList[i]) == IMA_FALSE) { 2069 return (IMA_FALSE); 2070 } 2071 } 2072 return (IMA_TRUE); 2073 } 2074 2075 IMA_API IMA_STATUS IMA_GetSupportedAuthMethods( 2076 IMA_OID lhbaOid, 2077 IMA_BOOL getSettableMethods, 2078 IMA_UINT *pMethodCount, 2079 IMA_AUTHMETHOD *pMethodList 2080 ) 2081 { 2082 return (getSupportedAuthMethods(lhbaOid, getSettableMethods, 2083 pMethodCount, pMethodList)); 2084 } 2085 2086 2087 /*ARGSUSED*/ 2088 static IMA_STATUS getSupportedAuthMethods( 2089 IMA_OID lhbaOid, 2090 IMA_BOOL getSettableMethods, 2091 IMA_UINT *pMethodCount, 2092 IMA_AUTHMETHOD *pMethodList 2093 ) 2094 { 2095 if (pMethodList == NULL) { 2096 *pMethodCount = 0; 2097 return (IMA_STATUS_SUCCESS); 2098 } 2099 2100 *pMethodCount = NUM_SUPPORTED_AUTH_METHODS; 2101 if (*pMethodCount > 1) { 2102 pMethodList[0] = IMA_AUTHMETHOD_NONE; 2103 pMethodList[1] = IMA_AUTHMETHOD_CHAP; 2104 } 2105 2106 return (IMA_STATUS_SUCCESS); 2107 } 2108 2109 IMA_API IMA_STATUS IMA_GetInUseInitiatorAuthMethods( 2110 IMA_OID lhbaOid, 2111 IMA_UINT *pMethodCount, 2112 IMA_AUTHMETHOD *pMethodList 2113 ) 2114 { 2115 return (getAuthMethods(lhbaOid, pMethodCount, pMethodList)); 2116 } 2117 2118 /*ARGSUSED*/ 2119 IMA_API IMA_STATUS IMA_GetInitiatorAuthParms( 2120 IMA_OID lhbaOid, 2121 IMA_AUTHMETHOD method, 2122 IMA_INITIATOR_AUTHPARMS *pParms 2123 ) 2124 { 2125 int fd; 2126 iscsi_chap_props_t chap_p; 2127 2128 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2129 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2130 ISCSI_DRIVER_DEVCTL, errno); 2131 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2132 } 2133 2134 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t)); 2135 chap_p.c_vers = ISCSI_INTERFACE_VERSION; 2136 chap_p.c_oid = (uint32_t)lhbaOid.objectSequenceNumber; 2137 2138 if (method == IMA_AUTHMETHOD_CHAP) { 2139 if (ioctl(fd, ISCSI_CHAP_GET, &chap_p) != 0) { 2140 syslog(LOG_USER|LOG_DEBUG, 2141 "ISCSI_CHAP_GET ioctl failed, errno: %d", errno); 2142 (void) close(fd); 2143 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2144 } 2145 } else { 2146 return (IMA_ERROR_INVALID_PARAMETER); 2147 } 2148 2149 (void) memcpy(pParms->chapParms.name, chap_p.c_user, 2150 chap_p.c_user_len); 2151 pParms->chapParms.nameLength = chap_p.c_user_len; 2152 (void) memcpy(pParms->chapParms.challengeSecret, chap_p.c_secret, 2153 chap_p.c_secret_len); 2154 pParms->chapParms.challengeSecretLength = chap_p.c_secret_len; 2155 2156 return (IMA_STATUS_SUCCESS); 2157 } 2158 2159 IMA_API IMA_STATUS IMA_SetInitiatorAuthMethods( 2160 IMA_OID lhbaOid, 2161 IMA_UINT methodCount, 2162 const IMA_AUTHMETHOD *pMethodList 2163 ) 2164 { 2165 if (isAuthMethodListValid(lhbaOid, pMethodList, 2166 methodCount) == IMA_FALSE) 2167 return (IMA_ERROR_INVALID_PARAMETER); 2168 return (setAuthMethods(lhbaOid, &methodCount, pMethodList)); 2169 } 2170 2171 /* 2172 * This function only sets CHAP params since we only support CHAP for now. 2173 */ 2174 IMA_API IMA_STATUS IMA_SetInitiatorAuthParms( 2175 IMA_OID lhbaOid, 2176 IMA_AUTHMETHOD method, 2177 const IMA_INITIATOR_AUTHPARMS *pParms 2178 ) 2179 { 2180 int fd; 2181 iscsi_chap_props_t chap_p; 2182 2183 if (method != IMA_AUTHMETHOD_CHAP) 2184 return (IMA_ERROR_INVALID_PARAMETER); 2185 2186 if (isAuthMethodValid(lhbaOid, method) == IMA_FALSE) { 2187 return (IMA_ERROR_INVALID_PARAMETER); 2188 } 2189 2190 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2191 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2192 ISCSI_DRIVER_DEVCTL, errno); 2193 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2194 } 2195 2196 (void) memset(&chap_p, 0, sizeof (iscsi_chap_props_t)); 2197 chap_p.c_vers = ISCSI_INTERFACE_VERSION; 2198 chap_p.c_oid = (uint32_t)lhbaOid.objectSequenceNumber; 2199 2200 chap_p.c_user_len = pParms->chapParms.nameLength; 2201 (void) memcpy(chap_p.c_user, pParms->chapParms.name, chap_p.c_user_len); 2202 2203 chap_p.c_secret_len = pParms->chapParms.challengeSecretLength; 2204 (void) memcpy(chap_p.c_secret, pParms->chapParms.challengeSecret, 2205 chap_p.c_secret_len); 2206 2207 if (method == IMA_AUTHMETHOD_CHAP) { 2208 if (ioctl(fd, ISCSI_CHAP_SET, &chap_p) != 0) { 2209 (void) close(fd); 2210 syslog(LOG_USER|LOG_DEBUG, 2211 "ISCSI_CHAP_SET ioctl failed, errno: %d", errno); 2212 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2213 } 2214 } 2215 2216 return (IMA_STATUS_SUCCESS); 2217 } 2218 2219 /* A helper function to obtain iSCSI node parameters. */ 2220 static IMA_STATUS 2221 getISCSINodeParameter( 2222 int paramType, 2223 IMA_OID *oid, 2224 void *pProps, 2225 uint32_t paramIndex 2226 ) 2227 { 2228 int fd; 2229 iscsi_param_get_t pg; 2230 2231 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2232 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2233 ISCSI_DRIVER_DEVCTL, errno); 2234 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2235 } 2236 2237 (void) memset(&pg, 0, sizeof (iscsi_param_get_t)); 2238 pg.g_vers = ISCSI_INTERFACE_VERSION; 2239 pg.g_oid = (uint32_t)oid->objectSequenceNumber; 2240 pg.g_param = paramIndex; 2241 pg.g_param_type = ISCSI_SESS_PARAM; 2242 2243 if (ioctl(fd, ISCSI_PARAM_GET, &pg) != 0) { 2244 syslog(LOG_USER|LOG_DEBUG, 2245 "ISCSI_PARAM_GET ioctl failed, errno: %d", errno); 2246 (void) close(fd); 2247 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2248 } 2249 2250 switch (paramType) { 2251 IMA_BOOL_VALUE *bp; 2252 IMA_MIN_MAX_VALUE *mp; 2253 2254 case MIN_MAX_PARAM: 2255 mp = (IMA_MIN_MAX_VALUE *)pProps; 2256 2257 mp->currentValueValid = 2258 (pg.g_value.v_valid == B_TRUE) ? 2259 IMA_TRUE : IMA_FALSE; 2260 mp->currentValue = pg.g_value.v_integer.i_current; 2261 mp->defaultValue = pg.g_value.v_integer.i_default; 2262 mp->minimumValue = pg.g_value.v_integer.i_min; 2263 mp->maximumValue = pg.g_value.v_integer.i_max; 2264 mp->incrementValue = pg.g_value.v_integer.i_incr; 2265 break; 2266 2267 case BOOL_PARAM: 2268 bp = (IMA_BOOL_VALUE *)pProps; 2269 bp->currentValueValid = 2270 (pg.g_value.v_valid == B_TRUE) ? 2271 IMA_TRUE : IMA_FALSE; 2272 bp->currentValue = pg.g_value.v_bool.b_current; 2273 bp->defaultValue = pg.g_value.v_bool.b_default; 2274 break; 2275 2276 default: 2277 break; 2278 } 2279 2280 (void) close(fd); 2281 return (IMA_STATUS_SUCCESS); 2282 } 2283 2284 /* A helper function to set iSCSI node parameters. */ 2285 static IMA_STATUS 2286 setISCSINodeParameter( 2287 int paramType, 2288 IMA_OID *oid, 2289 void *pProp, 2290 uint32_t paramIndex 2291 ) 2292 { 2293 int fd; 2294 iscsi_param_set_t ps; 2295 2296 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2297 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2298 ISCSI_DRIVER_DEVCTL, errno); 2299 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2300 } 2301 2302 (void) memset(&ps, 0, sizeof (iscsi_param_set_t)); 2303 ps.s_vers = ISCSI_INTERFACE_VERSION; 2304 ps.s_oid = (uint32_t)oid->objectSequenceNumber; 2305 ps.s_param = paramIndex; 2306 2307 switch (paramType) { 2308 IMA_BOOL_VALUE *bp; 2309 IMA_MIN_MAX_VALUE *mp; 2310 2311 case MIN_MAX_PARAM: 2312 mp = (IMA_MIN_MAX_VALUE *)pProp; 2313 ps.s_value.v_integer = mp->currentValue; 2314 break; 2315 case BOOL_PARAM: 2316 bp = (IMA_BOOL_VALUE *)pProp; 2317 ps.s_value.v_bool = 2318 (bp->currentValue == IMA_TRUE) ? 2319 B_TRUE : B_FALSE; 2320 break; 2321 2322 default: 2323 break; 2324 } 2325 2326 if (ioctl(fd, ISCSI_PARAM_SET, &ps)) { 2327 int tmpErrno = errno; 2328 syslog(LOG_USER|LOG_DEBUG, 2329 "ISCSI_PARAM_SET ioctl failed, errno: %d", errno); 2330 (void) close(fd); 2331 switch (tmpErrno) { 2332 case ENOTSUP : 2333 return (IMA_ERROR_NOT_SUPPORTED); 2334 default : 2335 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2336 } 2337 } 2338 2339 (void) close(fd); 2340 return (IMA_STATUS_SUCCESS); 2341 } 2342 2343 static int 2344 prepare_discovery_entry( 2345 IMA_TARGET_ADDRESS discoveryAddress, 2346 entry_t *entry 2347 ) 2348 { 2349 (void) memset(entry, 0, sizeof (entry_t)); 2350 entry->e_vers = ISCSI_INTERFACE_VERSION; 2351 entry->e_oid = ISCSI_OID_NOTSET; 2352 2353 if (discoveryAddress.hostnameIpAddress.id.ipAddress.ipv4Address == 2354 IMA_FALSE) { 2355 bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress, 2356 entry->e_u.u_in6.s6_addr, 2357 sizeof (entry->e_u.u_in6.s6_addr)); 2358 entry->e_insize = sizeof (struct in6_addr); 2359 } else { 2360 bcopy(discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress, 2361 &entry->e_u.u_in4.s_addr, 2362 sizeof (entry->e_u.u_in4.s_addr)); 2363 entry->e_insize = sizeof (struct in_addr); 2364 } 2365 2366 entry->e_port = discoveryAddress.portNumber; 2367 entry->e_tpgt = 0; 2368 return (DISC_ADDR_OK); 2369 } 2370 2371 static IMA_STATUS configure_discovery_method( 2372 IMA_BOOL enable, 2373 iSCSIDiscoveryMethod_t method 2374 ) 2375 { 2376 int fd, status; 2377 2378 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2379 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2380 ISCSI_DRIVER_DEVCTL, errno); 2381 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2382 } 2383 2384 if (enable == IMA_FALSE) { 2385 if (ioctl(fd, ISCSI_DISCOVERY_CLEAR, &method)) { 2386 status = errno; 2387 (void) close(fd); 2388 syslog(LOG_USER|LOG_DEBUG, 2389 "ISCSI_DISCOVERY_CLEAR ioctl failed, errno: %d", 2390 status); 2391 if (status == EBUSY) { 2392 return (IMA_ERROR_LU_IN_USE); 2393 } else { 2394 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2395 } 2396 } 2397 2398 (void) close(fd); 2399 return (IMA_STATUS_SUCCESS); 2400 } else { 2401 /* Set the discovery method */ 2402 if (ioctl(fd, ISCSI_DISCOVERY_SET, &method)) { 2403 (void) close(fd); 2404 syslog(LOG_USER|LOG_DEBUG, 2405 "ISCSI_DISCOVERY_SET ioctl failed, errno: %d", 2406 errno); 2407 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2408 } 2409 2410 (void) close(fd); 2411 return (IMA_STATUS_SUCCESS); 2412 } 2413 } 2414 2415 static IMA_STATUS get_target_oid_list( 2416 uint32_t targetListType, 2417 IMA_OID_LIST **ppList) 2418 { 2419 int fd; 2420 int i; 2421 int target_list_size; 2422 iscsi_target_list_t *idlp, tl_info; 2423 2424 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2425 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2426 ISCSI_DRIVER_DEVCTL, errno); 2427 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2428 } 2429 2430 (void) memset(&tl_info, 0, sizeof (tl_info)); 2431 tl_info.tl_vers = ISCSI_INTERFACE_VERSION; 2432 tl_info.tl_in_cnt = 0; 2433 tl_info.tl_tgt_list_type = targetListType; 2434 2435 /* 2436 * Issue ioctl to obtain the number of targets. 2437 */ 2438 if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, &tl_info) != 0) { 2439 (void) close(fd); 2440 syslog(LOG_USER|LOG_DEBUG, 2441 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 2442 targetListType, errno); 2443 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2444 } 2445 2446 target_list_size = sizeof (iscsi_target_list_t); 2447 if (tl_info.tl_out_cnt > 1) { 2448 target_list_size += (sizeof (uint32_t) * 2449 tl_info.tl_out_cnt - 1); 2450 } 2451 2452 idlp = (iscsi_target_list_t *)calloc(1, target_list_size); 2453 if (idlp == NULL) { 2454 (void) close(fd); 2455 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2456 } 2457 2458 idlp->tl_vers = ISCSI_INTERFACE_VERSION; 2459 idlp->tl_in_cnt = tl_info.tl_out_cnt; 2460 idlp->tl_tgt_list_type = targetListType; 2461 2462 /* Issue the same ioctl again to obtain the OIDs. */ 2463 if (ioctl(fd, ISCSI_TARGET_OID_LIST_GET, idlp) != 0) { 2464 free(idlp); 2465 (void) close(fd); 2466 syslog(LOG_USER|LOG_DEBUG, 2467 "ISCSI_TARGET_OID_LIST_GET ioctl %d failed, errno: %d", 2468 targetListType, errno); 2469 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2470 } 2471 2472 *ppList = (IMA_OID_LIST *)calloc(1, sizeof (IMA_OID_LIST) + 2473 idlp->tl_out_cnt * sizeof (IMA_OID)); 2474 if (*ppList == NULL) { 2475 free(idlp); 2476 (void) close(fd); 2477 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2478 } 2479 (*ppList)->oidCount = idlp->tl_out_cnt; 2480 2481 for (i = 0; i < idlp->tl_out_cnt; i++) { 2482 2483 if (targetListType == ISCSI_STATIC_TGT_OID_LIST) 2484 (*ppList)->oids[i].objectType = 2485 IMA_OBJECT_TYPE_STATIC_DISCOVERY_TARGET; 2486 else 2487 (*ppList)->oids[i].objectType = IMA_OBJECT_TYPE_TARGET; 2488 2489 (*ppList)->oids[i].ownerId = pluginOwnerId; 2490 (*ppList)->oids[i].objectSequenceNumber = idlp->tl_oid_list[i]; 2491 } 2492 2493 free(idlp); 2494 (void) close(fd); 2495 return (IMA_STATUS_SUCCESS); 2496 } 2497 2498 static IMA_STATUS get_target_lun_oid_list( 2499 IMA_OID * targetOid, 2500 iscsi_lun_list_t **ppLunList) 2501 { 2502 int fd; 2503 iscsi_lun_list_t *illp, ll_info; 2504 int lun_list_size; 2505 2506 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2507 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2508 ISCSI_DRIVER_DEVCTL, errno); 2509 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2510 } 2511 2512 (void) memset(&ll_info, 0, sizeof (ll_info)); 2513 ll_info.ll_vers = ISCSI_INTERFACE_VERSION; 2514 if (targetOid == NULL) { 2515 /* get lun oid list for all targets */ 2516 ll_info.ll_all_tgts = B_TRUE; 2517 } else { 2518 /* get lun oid list for single target */ 2519 ll_info.ll_all_tgts = B_FALSE; 2520 ll_info.ll_tgt_oid = (uint32_t)targetOid->objectSequenceNumber; 2521 } 2522 ll_info.ll_in_cnt = 0; 2523 2524 /* 2525 * Issue ioctl to obtain the number of target LUNs. 2526 */ 2527 if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, &ll_info) != 0) { 2528 (void) close(fd); 2529 syslog(LOG_USER|LOG_DEBUG, 2530 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno); 2531 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2532 } 2533 2534 lun_list_size = sizeof (iscsi_lun_list_t); 2535 if (ll_info.ll_out_cnt > 1) { 2536 lun_list_size += (sizeof (iscsi_if_lun_t) * 2537 (ll_info.ll_out_cnt - 1)); 2538 } 2539 2540 illp = (iscsi_lun_list_t *)calloc(1, lun_list_size); 2541 if (illp == NULL) { 2542 (void) close(fd); 2543 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2544 } 2545 illp->ll_vers = ISCSI_INTERFACE_VERSION; 2546 illp->ll_all_tgts = ll_info.ll_all_tgts; 2547 illp->ll_tgt_oid = ll_info.ll_tgt_oid; 2548 illp->ll_in_cnt = ll_info.ll_out_cnt; 2549 2550 /* Issue the same ioctl again to get the target LUN list */ 2551 if (ioctl(fd, ISCSI_LUN_OID_LIST_GET, illp) != 0) { 2552 free(illp); 2553 (void) close(fd); 2554 syslog(LOG_USER|LOG_DEBUG, 2555 "ISCSI_LUN_LIST_GET ioctl failed, errno: %d", errno); 2556 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2557 } 2558 2559 *ppLunList = illp; 2560 2561 (void) close(fd); 2562 return (IMA_STATUS_SUCCESS); 2563 } 2564 2565 2566 /* A helper function to set authentication method. */ 2567 static IMA_STATUS 2568 setAuthMethods( 2569 IMA_OID oid, 2570 IMA_UINT *pMethodCount, 2571 const IMA_AUTHMETHOD *pMethodList 2572 ) 2573 { 2574 int fd; 2575 int i; 2576 iscsi_auth_props_t auth; 2577 2578 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2579 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2580 ISCSI_DRIVER_DEVCTL, errno); 2581 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2582 } 2583 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t)); 2584 auth.a_vers = ISCSI_INTERFACE_VERSION; 2585 auth.a_oid = (uint32_t)oid.objectSequenceNumber; 2586 /* First do a get because other data fields may exist */ 2587 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) { 2588 /* EMPTY */ 2589 /* It is fine if there is no other data fields. */ 2590 } 2591 auth.a_auth_method = authMethodNone; 2592 2593 for (i = 0; i < *pMethodCount; i++) { 2594 switch (pMethodList[i]) { 2595 case IMA_AUTHMETHOD_CHAP: 2596 auth.a_auth_method |= authMethodCHAP; 2597 break; 2598 default: 2599 break; 2600 } 2601 } 2602 2603 if (ioctl(fd, ISCSI_AUTH_SET, &auth) != 0) { 2604 syslog(LOG_USER|LOG_DEBUG, 2605 "ISCSI_AUTH_SET failed, errno: %d", errno); 2606 (void) close(fd); 2607 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2608 } 2609 2610 (void) close(fd); 2611 return (IMA_STATUS_SUCCESS); 2612 } 2613 2614 /* A helper function to get authentication method. */ 2615 static IMA_STATUS 2616 getAuthMethods( 2617 IMA_OID oid, 2618 IMA_UINT *pMethodCount, 2619 IMA_AUTHMETHOD *pMethodList 2620 ) 2621 { 2622 int fd, i; 2623 iscsi_auth_props_t auth; 2624 2625 if (pMethodList == NULL) { 2626 *pMethodCount = 0; 2627 return (IMA_STATUS_SUCCESS); 2628 } 2629 2630 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2631 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2632 ISCSI_DRIVER_DEVCTL, errno); 2633 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2634 } 2635 2636 (void) memset(&auth, 0, sizeof (iscsi_auth_props_t)); 2637 auth.a_vers = ISCSI_INTERFACE_VERSION; 2638 auth.a_oid = (uint32_t)oid.objectSequenceNumber; 2639 2640 if (ioctl(fd, ISCSI_AUTH_GET, &auth) != 0) { 2641 syslog(LOG_USER|LOG_DEBUG, 2642 "ISCSI_AUTH_GET failed, errno: %d", errno); 2643 (void) close(fd); 2644 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2645 } 2646 2647 i = 0; 2648 if (auth.a_auth_method == IMA_AUTHMETHOD_NONE) { 2649 pMethodList[i++] = IMA_AUTHMETHOD_NONE; 2650 } else if (auth.a_auth_method & authMethodCHAP) { 2651 pMethodList[i++] = IMA_AUTHMETHOD_CHAP; 2652 } 2653 *pMethodCount = i; 2654 2655 (void) close(fd); 2656 return (IMA_STATUS_SUCCESS); 2657 } 2658 2659 IMA_API IMA_STATUS IMA_GetPhbaOidList( 2660 IMA_OID_LIST **ppList 2661 ) 2662 { 2663 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST)); 2664 if (*ppList == NULL) { 2665 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2666 } 2667 (*ppList)->oidCount = 0; 2668 return (IMA_STATUS_SUCCESS); 2669 } 2670 2671 /* ARGSUSED */ 2672 IMA_API IMA_STATUS IMA_GetPhbaProperties( 2673 IMA_OID phbaOid, 2674 IMA_PHBA_PROPERTIES *pProps 2675 ) 2676 { 2677 return (IMA_ERROR_OBJECT_NOT_FOUND); 2678 } 2679 2680 /* ARGSUSED */ 2681 IMA_API IMA_STATUS IMA_GetPhbaStatus( 2682 IMA_OID phbaOid, 2683 IMA_PHBA_STATUS *pStatus 2684 ) 2685 { 2686 return (IMA_ERROR_OBJECT_NOT_FOUND); 2687 } 2688 2689 /* ARGSUSED */ 2690 IMA_API IMA_STATUS IMA_GetPhbaDownloadProperties( 2691 IMA_OID phbaOid, 2692 IMA_PHBA_DOWNLOAD_PROPERTIES *pProps 2693 ) 2694 { 2695 return (IMA_ERROR_OBJECT_NOT_FOUND); 2696 } 2697 2698 /* ARGSUSED */ 2699 IMA_API IMA_STATUS IMA_IsPhbaDownloadFile( 2700 IMA_OID phbaOid, 2701 const IMA_WCHAR *pFileName, 2702 IMA_PHBA_DOWNLOAD_IMAGE_PROPERTIES *pProps 2703 ) 2704 { 2705 return (IMA_ERROR_OBJECT_NOT_FOUND); 2706 } 2707 2708 /* ARGSUSED */ 2709 IMA_API IMA_STATUS IMA_PhbaDownload( 2710 IMA_OID phbaOid, 2711 IMA_PHBA_DOWNLOAD_IMAGE_TYPE imageType, 2712 const IMA_WCHAR *pFileName 2713 ) 2714 { 2715 return (IMA_ERROR_OBJECT_NOT_FOUND); 2716 } 2717 2718 IMA_API IMA_STATUS IMA_GetPnpOidList( 2719 IMA_OID pnpOid, 2720 IMA_OID_LIST **ppList 2721 ) 2722 { 2723 /* 2724 * Always return the same object ID for the pnp as the spec 2725 * states that this function will always return a list of at least 2726 * one element 2727 */ 2728 pnpOid.objectType = IMA_OBJECT_TYPE_PNP; 2729 pnpOid.ownerId = pluginOwnerId; 2730 pnpOid.objectSequenceNumber = ISCSI_INITIATOR_OID; 2731 2732 *ppList = (IMA_OID_LIST*)calloc(1, sizeof (IMA_OID_LIST) + 2733 (1* sizeof (IMA_OID))); 2734 2735 if (*ppList == NULL) { 2736 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2737 } 2738 2739 (*ppList)->oidCount = 1; 2740 (void) memcpy(&(*ppList)->oids[0], &pnpOid, sizeof (pnpOid)); 2741 return (IMA_STATUS_SUCCESS); 2742 } 2743 2744 /* ARGSUSED */ 2745 IMA_API IMA_STATUS IMA_GetPnpProperties( 2746 IMA_OID pnpOid, 2747 IMA_PNP_PROPERTIES *pProps 2748 ) 2749 { 2750 return (IMA_ERROR_OBJECT_NOT_FOUND); 2751 } 2752 2753 /* ARGSUSED */ 2754 IMA_API IMA_STATUS IMA_GetPnpStatistics( 2755 IMA_OID pnpOid, 2756 IMA_PNP_STATISTICS *pStats 2757 ) 2758 { 2759 return (IMA_ERROR_OBJECT_NOT_FOUND); 2760 } 2761 2762 /* ARGSUSED */ 2763 IMA_API IMA_STATUS IMA_GetIpProperties( 2764 IMA_OID oid, 2765 IMA_IP_PROPERTIES *pProps 2766 ) 2767 { 2768 return (IMA_ERROR_OBJECT_NOT_FOUND); 2769 } 2770 2771 /* ARGSUSED */ 2772 IMA_API IMA_STATUS IMA_SetDefaultGateway( 2773 IMA_OID oid, 2774 IMA_IP_ADDRESS defaultGateway 2775 ) 2776 { 2777 return (IMA_ERROR_OBJECT_NOT_FOUND); 2778 } 2779 2780 /* ARGSUSED */ 2781 IMA_API IMA_STATUS IMA_SetDnsServerAddress( 2782 IMA_OID oid, 2783 const IMA_IP_ADDRESS *pPrimaryDnsServerAddress, 2784 const IMA_IP_ADDRESS *pAlternateDnsServerAddress 2785 ) 2786 { 2787 return (IMA_ERROR_OBJECT_NOT_FOUND); 2788 } 2789 2790 /* ARGSUSED */ 2791 IMA_API IMA_STATUS IMA_SetSubnetMask( 2792 IMA_OID oid, 2793 IMA_IP_ADDRESS subnetMask 2794 ) 2795 { 2796 return (IMA_ERROR_OBJECT_NOT_FOUND); 2797 } 2798 2799 /* ARGSUSED */ 2800 IMA_API IMA_STATUS IMA_SetIpConfigMethod( 2801 IMA_OID oid, 2802 IMA_BOOL enableDhcpIpConfiguration 2803 ) 2804 { 2805 return (IMA_ERROR_OBJECT_NOT_FOUND); 2806 } 2807 2808 IMA_API IMA_STATUS IMA_RegisterForObjectPropertyChanges( 2809 IMA_OBJECT_PROPERTY_FN pClientFn 2810 ) 2811 { 2812 pObjectPropertyCallback = pClientFn; 2813 return (IMA_STATUS_SUCCESS); 2814 } 2815 2816 /* ARGSUSED */ 2817 IMA_API IMA_STATUS IMA_DeregisterForObjectPropertyChanges( 2818 IMA_OBJECT_PROPERTY_FN pClientFn 2819 ) 2820 { 2821 return (IMA_STATUS_SUCCESS); 2822 } 2823 2824 IMA_API IMA_STATUS IMA_RegisterForObjectVisibilityChanges( 2825 IMA_OBJECT_VISIBILITY_FN pClientFn 2826 ) 2827 { 2828 pObjectVisibilityCallback = pClientFn; 2829 return (IMA_STATUS_SUCCESS); 2830 } 2831 2832 /* ARGSUSED */ 2833 IMA_API IMA_STATUS IMA_DeregisterForObjectVisibilityChanges( 2834 IMA_OBJECT_VISIBILITY_FN pClientFn 2835 ) 2836 { 2837 return (IMA_STATUS_SUCCESS); 2838 } 2839 2840 /* ARGSUSED */ 2841 IMA_API IMA_STATUS IMA_GetNetworkPortStatus( 2842 IMA_OID portOid, 2843 IMA_NETWORK_PORT_STATUS *pStaus 2844 ) 2845 { 2846 return (IMA_ERROR_OBJECT_NOT_FOUND); 2847 } 2848 2849 /* ARGSUSED */ 2850 IMA_API IMA_STATUS IMA_GetNetworkPortalOidList( 2851 IMA_OID pnpOid, 2852 IMA_OID_LIST **ppList 2853 ) 2854 { 2855 return (IMA_ERROR_OBJECT_NOT_FOUND); 2856 } 2857 2858 /* ARGSUSED */ 2859 IMA_API IMA_STATUS IMA_GetNetworkPortalProperties( 2860 IMA_OID networkPortalOid, 2861 IMA_NETWORK_PORTAL_PROPERTIES *pProps 2862 ) 2863 { 2864 return (IMA_ERROR_OBJECT_NOT_FOUND); 2865 } 2866 2867 /* ARGSUSED */ 2868 IMA_API IMA_STATUS IMA_SetNetworkPortalIpAddress( 2869 IMA_OID networkPortalOid, 2870 const IMA_IP_ADDRESS NewIpAddress 2871 ) 2872 { 2873 return (IMA_ERROR_OBJECT_NOT_FOUND); 2874 } 2875 2876 /* ARGSUSED */ 2877 IMA_API IMA_STATUS IMA_RemoveStaleData( 2878 IMA_OID lhbaOid 2879 ) 2880 { 2881 return (IMA_ERROR_NOT_SUPPORTED); 2882 } 2883 2884 /* ARGSUSED */ 2885 IMA_API IMA_STATUS IMA_GetIpsecProperties( 2886 IMA_OID oid, 2887 IMA_IPSEC_PROPERTIES *pProps 2888 ) 2889 { 2890 pProps->ipsecSupported = IMA_TRUE; 2891 pProps->implementedInHardware = IMA_FALSE; 2892 pProps->implementedInSoftware = IMA_TRUE; 2893 2894 return (IMA_STATUS_SUCCESS); 2895 } 2896 2897 /* ARGSUSED */ 2898 IMA_API IMA_STATUS IMA_GetLhbaProperties( 2899 IMA_OID lhbaOid, 2900 IMA_LHBA_PROPERTIES *pProps 2901 ) 2902 { 2903 2904 if (pProps == NULL) { 2905 return (IMA_ERROR_INVALID_PARAMETER); 2906 } 2907 2908 if (lhbaObjectId.objectSequenceNumber != ISCSI_INITIATOR_OID) { 2909 return (IMA_ERROR_OBJECT_NOT_FOUND); 2910 } 2911 2912 (void) memset(pProps, 0, sizeof (IMA_LHBA_PROPERTIES)); 2913 (void) mbstowcs(pProps->osDeviceName, OS_DEVICE_NAME, 2914 OS_DEVICE_NAME_LEN); 2915 pProps->luExposingSupported = IMA_FALSE; 2916 pProps->isDestroyable = IMA_FALSE; 2917 pProps->staleDataRemovable = IMA_FALSE; 2918 pProps->staleDataSize = 0; 2919 pProps->initiatorAuthMethodsSettable = IMA_TRUE; 2920 pProps->targetAuthMethodsSettable = IMA_FALSE; 2921 2922 return (IMA_STATUS_SUCCESS); 2923 } 2924 2925 IMA_API IMA_STATUS IMA_GetLnpOidList( 2926 IMA_OID_LIST **ppList 2927 ) 2928 { 2929 *ppList = (IMA_OID_LIST *) calloc(1, (sizeof (IMA_OID_LIST))); 2930 if (*ppList == NULL) { 2931 return (IMA_ERROR_INSUFFICIENT_MEMORY); 2932 } 2933 (*ppList)->oidCount = 0; 2934 2935 return (IMA_STATUS_SUCCESS); 2936 } 2937 2938 /* ARGSUSED */ 2939 IMA_API IMA_STATUS IMA_GetLnpProperties( 2940 IMA_OID lnpOid, 2941 IMA_LNP_PROPERTIES *pProps 2942 ) 2943 { 2944 return (IMA_ERROR_OBJECT_NOT_FOUND); 2945 } 2946 2947 #define IMA_DISK_DEVICE_NAME_PREFIX "/dev/rdsk/" 2948 #define IMA_TAPE_DEVICE_NAME_PREFIX "/dev/rmt/" 2949 static int 2950 get_lun_devlink(di_devlink_t link, void *osDeviceName) 2951 { 2952 if ((strncmp(IMA_DISK_DEVICE_NAME_PREFIX, di_devlink_path(link), 2953 strlen(IMA_DISK_DEVICE_NAME_PREFIX)) == 0) || 2954 (strncmp(IMA_TAPE_DEVICE_NAME_PREFIX, di_devlink_path(link), 2955 strlen(IMA_TAPE_DEVICE_NAME_PREFIX)) == 0)) { 2956 (void) mbstowcs((wchar_t *)osDeviceName, di_devlink_path(link), 2957 MAXPATHLEN); 2958 return (DI_WALK_TERMINATE); 2959 } 2960 2961 return (DI_WALK_CONTINUE); 2962 } 2963 2964 /* ARGSUSED */ 2965 IMA_API IMA_STATUS IMA_GetPluginProperties( 2966 IMA_OID pluginOid, 2967 IMA_PLUGIN_PROPERTIES *pProps 2968 ) 2969 { 2970 pProps->supportedImaVersion = 1; 2971 libSwprintf(pProps->vendor, L"%ls", LIBRARY_PROPERTY_VENDOR); 2972 libSwprintf(pProps->implementationVersion, L"%ls", 2973 LIBRARY_PROPERTY_IMPLEMENTATION_VERSION); 2974 libSwprintf(pProps->fileName, L"%ls", LIBRARY_FILE_NAME); 2975 GetBuildTime(&(pProps->buildTime)); 2976 pProps->lhbasCanBeCreatedAndDestroyed = IMA_FALSE; 2977 return (IMA_STATUS_SUCCESS); 2978 } 2979 2980 IMA_STATUS getDiscoveryAddressPropertiesList( 2981 SUN_IMA_DISC_ADDR_PROP_LIST **ppList 2982 ) 2983 { 2984 int fd; 2985 int i; 2986 int discovery_addr_list_size; 2987 iscsi_addr_list_t *ialp, al_info; 2988 2989 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 2990 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 2991 ISCSI_DRIVER_DEVCTL, errno); 2992 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 2993 } 2994 2995 (void) memset(&al_info, 0, sizeof (al_info)); 2996 al_info.al_vers = ISCSI_INTERFACE_VERSION; 2997 al_info.al_in_cnt = 0; 2998 2999 /* 3000 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl to obtain the number of 3001 * discovery addresses. 3002 */ 3003 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, &al_info) != 0) { 3004 (void) close(fd); 3005 syslog(LOG_USER|LOG_DEBUG, 3006 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d", 3007 errno); 3008 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3009 } 3010 3011 discovery_addr_list_size = sizeof (iscsi_addr_list_t); 3012 if (al_info.al_out_cnt > 1) { 3013 discovery_addr_list_size += (sizeof (iscsi_addr_t) * 3014 al_info.al_out_cnt - 1); 3015 } 3016 3017 ialp = (iscsi_addr_list_t *)calloc(1, discovery_addr_list_size); 3018 if (ialp == NULL) { 3019 (void) close(fd); 3020 return (IMA_ERROR_INSUFFICIENT_MEMORY); 3021 } 3022 ialp->al_vers = ISCSI_INTERFACE_VERSION; 3023 ialp->al_in_cnt = al_info.al_out_cnt; 3024 3025 /* 3026 * Issue ISCSI_DISCOVERY_ADDR_LIST_GET ioctl again to obtain the 3027 * discovery addresses. 3028 */ 3029 if (ioctl(fd, ISCSI_DISCOVERY_ADDR_LIST_GET, ialp) != 0) { 3030 free(ialp); 3031 (void) close(fd); 3032 syslog(LOG_USER|LOG_DEBUG, 3033 "ISCSI_DISCOVERY_ADDR_LIST_GET ioctl failed, errno: %d", 3034 errno); 3035 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3036 } 3037 3038 *ppList = (SUN_IMA_DISC_ADDR_PROP_LIST *) 3039 calloc(1, sizeof (SUN_IMA_DISC_ADDR_PROP_LIST) + 3040 ialp->al_out_cnt * sizeof (IMA_DISCOVERY_ADDRESS_PROPERTIES)); 3041 3042 if (*ppList == NULL) { 3043 free(ialp); 3044 (void) close(fd); 3045 return (IMA_ERROR_INSUFFICIENT_MEMORY); 3046 } 3047 (*ppList)->discAddrCount = ialp->al_out_cnt; 3048 3049 for (i = 0; i < ialp->al_out_cnt; i++) { 3050 if (ialp->al_addrs[i].a_addr.i_insize == 3051 sizeof (struct in_addr)) { 3052 (*ppList)->props[i].discoveryAddress.hostnameIpAddress. 3053 id.ipAddress.ipv4Address = IMA_TRUE; 3054 } else if (ialp->al_addrs[i].a_addr.i_insize == 3055 sizeof (struct in6_addr)) { 3056 (*ppList)->props[i].discoveryAddress. 3057 hostnameIpAddress.id.ipAddress.ipv4Address = IMA_FALSE; 3058 } else { 3059 /* Should not happen */ 3060 syslog(LOG_USER|LOG_DEBUG, 3061 "ISCSI_STATIC_GET returned bad address"); 3062 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3063 } 3064 3065 bcopy(&ialp->al_addrs[i].a_addr.i_addr, (*ppList)->props[i]. 3066 discoveryAddress.hostnameIpAddress.id.ipAddress.ipAddress, 3067 sizeof ((*ppList)->props[i].discoveryAddress. 3068 hostnameIpAddress.id.ipAddress.ipAddress)); 3069 3070 (*ppList)->props[i].discoveryAddress.portNumber = 3071 ialp->al_addrs[i].a_port; 3072 } 3073 3074 free(ialp); 3075 (void) close(fd); 3076 return (IMA_STATUS_SUCCESS); 3077 } 3078 3079 3080 /* ARGSUSED */ 3081 IMA_STATUS sendTargets( 3082 IMA_TARGET_ADDRESS address, 3083 SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES **ppList 3084 ) 3085 { 3086 char *colonPos; 3087 char discAddrStr[SUN_IMA_IP_ADDRESS_LEN]; 3088 int fd; 3089 int ctr; 3090 int stl_sz; 3091 iscsi_sendtgts_list_t *stl_hdr = NULL; 3092 IMA_BOOL retry = IMA_TRUE; 3093 3094 #define SENDTGTS_DEFAULT_NUM_TARGETS 10 3095 3096 stl_sz = sizeof (*stl_hdr) + ((SENDTGTS_DEFAULT_NUM_TARGETS - 1) * 3097 sizeof (iscsi_sendtgts_entry_t)); 3098 stl_hdr = (iscsi_sendtgts_list_t *)calloc(1, stl_sz); 3099 if (stl_hdr == NULL) { 3100 return (IMA_ERROR_INSUFFICIENT_MEMORY); 3101 } 3102 stl_hdr->stl_entry.e_vers = ISCSI_INTERFACE_VERSION; 3103 stl_hdr->stl_in_cnt = SENDTGTS_DEFAULT_NUM_TARGETS; 3104 3105 colonPos = strchr(discAddrStr, ':'); 3106 if (colonPos == NULL) { 3107 /* IPv4 */ 3108 stl_hdr->stl_entry.e_insize = sizeof (struct in_addr); 3109 } else { 3110 /* IPv6 */ 3111 stl_hdr->stl_entry.e_insize = sizeof (struct in6_addr); 3112 } 3113 3114 3115 bcopy(address.hostnameIpAddress.id.ipAddress.ipAddress, 3116 &stl_hdr->stl_entry.e_u, 3117 sizeof (address.hostnameIpAddress.id.ipAddress.ipAddress)); 3118 stl_hdr->stl_entry.e_port = address.portNumber; 3119 3120 if ((fd = open(ISCSI_DRIVER_DEVCTL, O_RDONLY)) == -1) { 3121 syslog(LOG_USER|LOG_DEBUG, "Cannot open %s (%d)", 3122 ISCSI_DRIVER_DEVCTL, errno); 3123 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3124 } 3125 3126 retry_sendtgts: 3127 /* 3128 * Issue ioctl to obtain the SendTargets list 3129 */ 3130 if (ioctl(fd, ISCSI_SENDTGTS_GET, stl_hdr) != 0) { 3131 syslog(LOG_USER|LOG_DEBUG, 3132 "ISCSI_SENDTGTS_GET ioctl failed, errno: %d", errno); 3133 (void) close(fd); 3134 free(stl_hdr); 3135 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3136 } 3137 3138 /* check if all targets received */ 3139 if (stl_hdr->stl_in_cnt < stl_hdr->stl_out_cnt) { 3140 if (retry == IMA_TRUE) { 3141 stl_sz = sizeof (*stl_hdr) + 3142 ((stl_hdr->stl_out_cnt - 1) * 3143 sizeof (iscsi_sendtgts_entry_t)); 3144 stl_hdr = (iscsi_sendtgts_list_t *) 3145 realloc(stl_hdr, stl_sz); 3146 if (stl_hdr == NULL) { 3147 (void) close(fd); 3148 return (IMA_ERROR_INSUFFICIENT_MEMORY); 3149 } 3150 stl_hdr->stl_in_cnt = stl_hdr->stl_out_cnt; 3151 retry = IMA_FALSE; 3152 goto retry_sendtgts; 3153 } else { 3154 /* 3155 * don't retry after 2 attempts. The target list 3156 * shouldn't continue to growing. Justs continue 3157 * on and display what was found. 3158 */ 3159 syslog(LOG_USER|LOG_DEBUG, 3160 "ISCSI_SENDTGTS_GET overflow: " 3161 "failed to obtain all targets"); 3162 stl_hdr->stl_out_cnt = stl_hdr->stl_in_cnt; 3163 } 3164 } 3165 3166 (void) close(fd); 3167 3168 /* allocate for caller return buffer */ 3169 *ppList = (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES *)calloc(1, 3170 sizeof (SUN_IMA_DISC_ADDRESS_KEY_PROPERTIES) + 3171 stl_hdr->stl_out_cnt * sizeof (SUN_IMA_DISC_ADDRESS_KEY)); 3172 if (*ppList == NULL) { 3173 free(stl_hdr); 3174 return (IMA_ERROR_INSUFFICIENT_MEMORY); 3175 } 3176 3177 (*ppList)->keyCount = stl_hdr->stl_out_cnt; 3178 3179 for (ctr = 0; ctr < stl_hdr->stl_out_cnt; ctr++) { 3180 (void) mbstowcs((*ppList)->keys[ctr].name, 3181 (char *)stl_hdr->stl_list[ctr].ste_name, 3182 IMA_NODE_NAME_LEN); 3183 3184 (*ppList)->keys[ctr].tpgt = stl_hdr->stl_list[ctr].ste_tpgt; 3185 3186 (*ppList)->keys[ctr].address.portNumber = 3187 stl_hdr->stl_list[ctr].ste_ipaddr.a_port; 3188 3189 if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize == 3190 sizeof (struct in_addr)) { 3191 (*ppList)->keys[ctr].address.ipAddress.ipv4Address = 3192 IMA_TRUE; 3193 } else if (stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize == 3194 sizeof (struct in6_addr)) { 3195 (*ppList)->keys[ctr].address.ipAddress.ipv4Address = 3196 IMA_FALSE; 3197 } else { 3198 free(stl_hdr); 3199 syslog(LOG_USER|LOG_DEBUG, 3200 "ISCSI_STATIC_GET returned bad address"); 3201 return (IMA_ERROR_UNEXPECTED_OS_ERROR); 3202 } 3203 3204 3205 (void) memcpy(&(*ppList)->keys[ctr].address.ipAddress.ipAddress, 3206 &(stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_addr), 3207 stl_hdr->stl_list[ctr].ste_ipaddr.a_addr.i_insize); 3208 } 3209 free(stl_hdr); 3210 3211 return (IMA_STATUS_SUCCESS); 3212 } 3213