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