/*! Gets whether a portal has an active session. * @param target the target to test for an active session. * @param portal the portal to test for an active connection. * @return true if the is an active connection for the portal; false otherwise. */ Boolean iSCSIDaemonIsPortalActive(iSCSIDaemonHandle handle, iSCSITargetRef target, iSCSIPortalRef portal) { if(handle < 0 || !target || !portal) return false; CFDataRef targetData = iSCSITargetCreateData(target); CFDataRef portalData = iSCSIPortalCreateData(portal); iSCSIDMsgIsPortalActiveCmd cmd = iSCSIDMsgIsPortalActiveCmdInit; cmd.targetLength = (UInt32)CFDataGetLength(targetData); cmd.portalLength = (UInt32)CFDataGetLength(portalData); errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, targetData,portalData,NULL); CFRelease(targetData); CFRelease(portalData); if(error) return false; iSCSIDMsgIsPortalActiveRsp rsp; if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) return false; if(rsp.funcCode != kiSCSIDIsPortalActive) return false; return rsp.active; }
/*! Logs into a target using a specific portal or all portals in the database. * If an argument is supplied for portal, login occurs over the specified * portal. Otherwise, the daemon will attempt to login over all portals. * @param handle a handle to a daemon connection. * @param authorization an authorization for the right kiSCSIAuthModifyLogin * @param target specifies the target and connection parameters to use. * @param portal specifies the portal to use (use NULL for all portals). * @param statusCode iSCSI response code indicating operation status. * @return an error code indicating whether the operation was successful. */ errno_t iSCSIDaemonLogin(iSCSIDaemonHandle handle, AuthorizationRef authorization, iSCSITargetRef target, iSCSIPortalRef portal, enum iSCSILoginStatusCode * statusCode) { if(handle < 0 || !target || !authorization || !statusCode) return EINVAL; CFDataRef targetData = iSCSITargetCreateData(target); CFDataRef portalData = NULL; iSCSIDMsgLoginCmd cmd = iSCSIDMsgLoginCmdInit; cmd.authLength = kAuthorizationExternalFormLength; cmd.targetLength = (UInt32)CFDataGetLength(targetData); cmd.portalLength = 0; if(portal) { portalData = iSCSIPortalCreateData(portal); cmd.portalLength = (UInt32)CFDataGetLength(portalData); } AuthorizationExternalForm authExtForm; AuthorizationMakeExternalForm(authorization,&authExtForm); CFDataRef authData = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (UInt8*)&authExtForm.bytes, kAuthorizationExternalFormLength, kCFAllocatorDefault); errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, authData,targetData,portalData,NULL); if(portal) CFRelease(portalData); CFRelease(targetData); if(error) return error; iSCSIDMsgLoginRsp rsp; if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) return EIO; if(rsp.funcCode != kiSCSIDLogin) return EIO; // At this point we have a valid response, process it *statusCode = rsp.statusCode; return rsp.errorCode; }
/*! Retrieves a list of targets available from a give portal. * @param handle a handle to a daemon connection. * @param portal the iSCSI portal to look for targets. * @param authMethod the preferred authentication method. * @param statusCode iSCSI response code indicating operation status. * @return an error code indicating whether the operation was successful. */ errno_t iSCSIDaemonQueryTargetForAuthMethod(iSCSIDaemonHandle handle, iSCSIPortalRef portal, CFStringRef targetIQN, enum iSCSIAuthMethods * authMethod, enum iSCSILoginStatusCode * statusCode) { // Validate inputs if(handle < 0 || !portal || !targetIQN || !authMethod || !statusCode) return EINVAL; // Setup a target object with the target name iSCSIMutableTargetRef target = iSCSITargetCreateMutable(); iSCSITargetSetIQN(target,targetIQN); // Generate data to transmit (no longer need target object after this) CFDataRef targetData = iSCSITargetCreateData(target); iSCSITargetRelease(target); CFDataRef portalData = iSCSIPortalCreateData(portal); // Create command header to transmit iSCSIDMsgQueryTargetForAuthMethodCmd cmd = iSCSIDMsgQueryTargetForAuthMethodCmdInit; cmd.portalLength = (UInt32)CFDataGetLength(portalData); cmd.targetLength = (UInt32)CFDataGetLength(targetData); if(iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd,targetData,portalData,NULL)) { CFRelease(portalData); CFRelease(targetData); return EIO; } CFRelease(portalData); CFRelease(targetData); iSCSIDMsgQueryTargetForAuthMethodRsp rsp; if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) return EIO; *authMethod = rsp.authMethod; *statusCode = rsp.statusCode; return rsp.errorCode; }
/*! Logs out of the target or a specific portal, if specified. * @param handle a handle to a daemon connection. * @param target the target to logout. * @param portal the portal to logout. If one is not specified, * @param statusCode iSCSI response code indicating operation status. */ errno_t iSCSIDaemonLogout(iSCSIDaemonHandle handle, iSCSITargetRef target, iSCSIPortalRef portal, enum iSCSILogoutStatusCode * statusCode) { if(handle < 0 || !target || !statusCode) return EINVAL; CFDataRef targetData = iSCSITargetCreateData(target); CFDataRef portalData = NULL; iSCSIDMsgLogoutCmd cmd = iSCSIDMsgLogoutCmdInit; cmd.targetLength = (UInt32)CFDataGetLength(targetData); cmd.portalLength = 0; if(portal) { portalData = iSCSIPortalCreateData(portal); cmd.portalLength = (UInt32)CFDataGetLength(portalData); } errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, targetData,portalData,NULL); if(portal) CFRelease(portalData); CFRelease(targetData); if(error) return error; iSCSIDMsgLogoutRsp rsp; if(recv(handle,&rsp,sizeof(rsp),0) != sizeof(rsp)) return EIO; if(rsp.funcCode != kiSCSIDLogout) return EIO; // At this point we have a valid response, process it *statusCode = rsp.statusCode; return rsp.errorCode; }
/*! Creates a dictionary of connection parameters for the connection associated * with the specified target and portal, if one exists. * @param handle a handle to a daemon connection. * @param target the target associated with the the specified portal. * @param portal the portal to check for active connections to generate * a dictionary of connection parameters. * @return a dictionary of connection properties. */ CFDictionaryRef iSCSIDaemonCreateCFPropertiesForConnection(iSCSIDaemonHandle handle, iSCSITargetRef target, iSCSIPortalRef portal) { // Validate inputs if(handle < 0 || !target || !portal) return NULL; CFDictionaryRef properties = NULL; CFDataRef targetData = iSCSITargetCreateData(target); CFDataRef portalData = iSCSIPortalCreateData(portal); // Send command to daemon iSCSIDMsgCreateCFPropertiesForConnectionCmd cmd = iSCSIDMsgCreateCFPropertiesForConnectionCmdInit; cmd.targetLength = (UInt32)CFDataGetLength(targetData); cmd.portalLength = (UInt32)CFDataGetLength(portalData); errno_t error = iSCSIDaemonSendMsg(handle,(iSCSIDMsgGeneric *)&cmd, targetData,portalData,NULL); CFRelease(targetData); CFRelease(portalData); iSCSIDMsgCreateCFPropertiesForConnectionRsp rsp; if(!error) error = iSCSIDaemonRecvMsg(handle,(iSCSIDMsgGeneric*)&rsp,NULL); if(!error) { CFDataRef data = NULL; error = iSCSIDaemonRecvMsg(handle,0,&data,rsp.dataLength,NULL); if(!error && data) { CFPropertyListFormat format; properties = CFPropertyListCreateWithData(kCFAllocatorDefault,data,0,&format,NULL); CFRelease(data); } } return properties; }