iPXE
iscsi.c File Reference

iSCSI protocol More...

#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <assert.h>
#include <byteswap.h>
#include <ipxe/vsprintf.h>
#include <ipxe/socket.h>
#include <ipxe/iobuf.h>
#include <ipxe/uri.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/scsi.h>
#include <ipxe/process.h>
#include <ipxe/tcpip.h>
#include <ipxe/settings.h>
#include <ipxe/features.h>
#include <ipxe/base16.h>
#include <ipxe/base64.h>
#include <ipxe/ibft.h>
#include <ipxe/blockdev.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/iscsi.h>

Go to the source code of this file.

Data Structures

struct  iscsi_string_type
 An iSCSI text string that we want to handle. More...

Macros

#define EACCES_INCORRECT_TARGET_USERNAME    __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )
#define EINFO_EACCES_INCORRECT_TARGET_USERNAME    __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" )
#define EACCES_INCORRECT_TARGET_PASSWORD    __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )
#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD    __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" )
#define EINVAL_ROOT_PATH_TOO_SHORT    __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )
#define EINFO_EINVAL_ROOT_PATH_TOO_SHORT    __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" )
#define EINVAL_BAD_CREDENTIAL_MIX    __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )
#define EINFO_EINVAL_BAD_CREDENTIAL_MIX    __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" )
#define EINVAL_NO_ROOT_PATH    __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )
#define EINFO_EINVAL_NO_ROOT_PATH    __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" )
#define EINVAL_NO_TARGET_IQN    __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )
#define EINFO_EINVAL_NO_TARGET_IQN    __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )
#define EINVAL_NO_INITIATOR_IQN    __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )
#define EINFO_EINVAL_NO_INITIATOR_IQN    __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )
#define EINVAL_MAXBURSTLENGTH    __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )
#define EINFO_EINVAL_MAXBURSTLENGTH    __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" )
#define EIO_TARGET_UNAVAILABLE    __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )
#define EINFO_EIO_TARGET_UNAVAILABLE    __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" )
#define EIO_TARGET_NO_RESOURCES    __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )
#define EINFO_EIO_TARGET_NO_RESOURCES    __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" )
#define ENOTSUP_INITIATOR_STATUS    __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )
#define EINFO_ENOTSUP_INITIATOR_STATUS    __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" )
#define ENOTSUP_OPCODE    __einfo_error ( EINFO_ENOTSUP_OPCODE )
#define EINFO_ENOTSUP_OPCODE    __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" )
#define ENOTSUP_DISCOVERY    __einfo_error ( EINFO_ENOTSUP_DISCOVERY )
#define EINFO_ENOTSUP_DISCOVERY    __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" )
#define ENOTSUP_TARGET_STATUS    __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )
#define EINFO_ENOTSUP_TARGET_STATUS    __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" )
#define EPERM_INITIATOR_AUTHENTICATION    __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )
#define EINFO_EPERM_INITIATOR_AUTHENTICATION    __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" )
#define EPERM_INITIATOR_AUTHORISATION    __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )
#define EINFO_EPERM_INITIATOR_AUTHORISATION    __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" )
#define EPROTO_INVALID_CHAP_ALGORITHM    __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )
#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM    __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" )
#define EPROTO_INVALID_CHAP_IDENTIFIER    __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )
#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER    __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" )
#define EPROTO_INVALID_LARGE_BINARY    __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )
#define EINFO_EPROTO_INVALID_LARGE_BINARY    __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )
#define EPROTO_INVALID_CHAP_RESPONSE    __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )
#define EINFO_EPROTO_INVALID_CHAP_RESPONSE    __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )
#define EPROTO_INVALID_KEY_VALUE_PAIR    __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )
#define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR    __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" )
#define EPROTO_VALUE_REJECTED    __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )
#define EINFO_EPROTO_VALUE_REJECTED    __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" )

Enumerations

enum  iscsi_root_path_component {
  RP_SERVERNAME = 0 , RP_PROTOCOL , RP_PORT , RP_LUN ,
  RP_TARGETNAME , NUM_RP_COMPONENTS
}
 iSCSI root path components (as per RFC4173) More...

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 FILE_SECBOOT (PERMITTED)
 FEATURE (FEATURE_PROTOCOL, "iSCSI", DHCP_EB_FEATURE_ISCSI, 1)
static void iscsi_start_tx (struct iscsi_session *iscsi)
 Start up a new TX PDU.
static void iscsi_start_login (struct iscsi_session *iscsi)
 Build iSCSI login request BHS.
static void iscsi_start_data_out (struct iscsi_session *iscsi, unsigned int datasn)
 Build iSCSI data-out BHS.
static void iscsi_rx_buffered_data_done (struct iscsi_session *iscsi)
 Finish receiving PDU data into buffer.
static int iscsi_rx_buffered_data (struct iscsi_session *iscsi, const void *data, size_t len)
 Receive PDU data into buffer.
static void iscsi_free (struct refcnt *refcnt)
 Free iSCSI session.
static void iscsi_close (struct iscsi_session *iscsi, int rc)
 Shut down iSCSI interface.
static void iscsi_new_itt (struct iscsi_session *iscsi)
 Assign new iSCSI initiator task tag.
static int iscsi_open_connection (struct iscsi_session *iscsi)
 Open iSCSI transport-layer connection.
static void iscsi_close_connection (struct iscsi_session *iscsi, int rc)
 Close iSCSI transport-layer connection.
static void iscsi_scsi_done (struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
 Mark iSCSI SCSI operation as complete.
static void iscsi_start_command (struct iscsi_session *iscsi)
 Build iSCSI SCSI command BHS.
static int iscsi_rx_scsi_response (struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
 Receive data segment of an iSCSI SCSI response PDU.
static int iscsi_rx_data_in (struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
 Receive data segment of an iSCSI data-in PDU.
static int iscsi_rx_r2t (struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
 Receive data segment of an iSCSI R2T PDU.
static void iscsi_data_out_done (struct iscsi_session *iscsi)
 Complete iSCSI data-out PDU transmission.
static int iscsi_tx_data_out (struct iscsi_session *iscsi)
 Send iSCSI data-out data segment.
static int iscsi_rx_nop_in (struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
 Receive data segment of an iSCSI NOP-In.
static int iscsi_build_login_request_strings (struct iscsi_session *iscsi, void *data, size_t len)
 Build iSCSI login request strings.
static void iscsi_login_request_done (struct iscsi_session *iscsi)
 Complete iSCSI login request PDU transmission.
static int iscsi_tx_login_request (struct iscsi_session *iscsi)
 Transmit data segment of an iSCSI login request PDU.
static int iscsi_large_binary_decode (const char *encoded, uint8_t *raw, size_t len)
 Decode large binary value.
static int iscsi_handle_targetaddress_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI TargetAddress text value.
static int iscsi_handle_authmethod_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI AuthMethod text value.
static int iscsi_handle_maxburstlength_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI MaxBurstLength text value.
static int iscsi_handle_chap_a_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_A text value.
static int iscsi_handle_chap_i_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_I text value.
static int iscsi_handle_chap_c_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_C text value.
static int iscsi_handle_chap_n_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_N text value.
static int iscsi_handle_chap_r_value (struct iscsi_session *iscsi, const char *value)
 Handle iSCSI CHAP_R text value.
static int iscsi_handle_string (struct iscsi_session *iscsi, const char *string)
 Handle iSCSI string.
static int iscsi_handle_strings (struct iscsi_session *iscsi, const char *strings, size_t len)
 Handle iSCSI strings.
static int iscsi_status_to_rc (unsigned int status_class, unsigned int status_detail)
 Convert iSCSI response status to return status code.
static int iscsi_rx_login_response (struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
 Receive data segment of an iSCSI login response PDU.
static void iscsi_tx_pause (struct iscsi_session *iscsi)
 Pause TX engine.
static void iscsi_tx_resume (struct iscsi_session *iscsi)
 Resume TX engine.
static int iscsi_tx_nothing (struct iscsi_session *iscsi __unused)
 Transmit nothing.
static int iscsi_tx_bhs (struct iscsi_session *iscsi)
 Transmit basic header segment of an iSCSI PDU.
static int iscsi_tx_data (struct iscsi_session *iscsi)
 Transmit data segment of an iSCSI PDU.
static void iscsi_tx_done (struct iscsi_session *iscsi)
 Complete iSCSI PDU transmission.
static void iscsi_tx_step (struct iscsi_session *iscsi)
 Transmit iSCSI PDU.
static int iscsi_rx_bhs (struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining __unused)
 Receive basic header segment of an iSCSI PDU.
static int iscsi_rx_discard (struct iscsi_session *iscsi __unused, const void *data __unused, size_t len __unused, size_t remaining __unused)
 Discard portion of an iSCSI PDU.
static int iscsi_rx_data (struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
 Receive data segment of an iSCSI PDU.
static int iscsi_socket_deliver (struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
 Receive new data.
static int iscsi_vredirect (struct iscsi_session *iscsi, int type, va_list args)
 Handle redirection event.
static size_t iscsi_scsi_window (struct iscsi_session *iscsi)
 Check iSCSI flow-control window.
static int iscsi_scsi_command (struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
 Issue iSCSI SCSI command.
static void iscsi_scsi_capacity (struct iscsi_session *iscsi, struct block_device_capacity *capacity)
 Update SCSI block device capacity.
static struct acpi_descriptoriscsi_describe (struct iscsi_session *iscsi)
 Get iSCSI ACPI descriptor.
static void iscsi_command_close (struct iscsi_session *iscsi, int rc)
 Close iSCSI command.
const struct setting initiator_iqn_setting __setting (SETTING_SANBOOT_EXTRA, initiator-iqn)
 iSCSI initiator IQN setting
const struct setting reverse_username_setting __setting (SETTING_AUTH_EXTRA, reverse-username)
 iSCSI reverse username setting
static int iscsi_parse_root_path (struct iscsi_session *iscsi, const char *root_path)
 Parse iSCSI root path.
static int iscsi_fetch_settings (struct iscsi_session *iscsi)
 Fetch iSCSI settings.
static int iscsi_check_auth (struct iscsi_session *iscsi)
 Check iSCSI authentication details.
static int iscsi_open (struct interface *parent, struct uri *uri)
 Open iSCSI URI.

Variables

static struct iscsi_string_type iscsi_string_types []
 iSCSI text strings that we want to handle
static struct process_descriptor iscsi_process_desc
 iSCSI TX process descriptor
static struct interface_operation iscsi_socket_operations []
 iSCSI socket interface operations
static struct interface_descriptor iscsi_socket_desc
 iSCSI socket interface descriptor
static struct interface_operation iscsi_control_op []
 iSCSI SCSI command-issuing interface operations
static struct interface_descriptor iscsi_control_desc
 iSCSI SCSI command-issuing interface descriptor
static struct interface_operation iscsi_data_op []
 iSCSI SCSI command interface operations
static struct interface_descriptor iscsi_data_desc
 iSCSI SCSI command interface descriptor
struct uri_opener iscsi_uri_opener __uri_opener
 iSCSI URI opener

Detailed Description

iSCSI protocol

Definition in file iscsi.c.

Macro Definition Documentation

◆ EACCES_INCORRECT_TARGET_USERNAME

#define EACCES_INCORRECT_TARGET_USERNAME    __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

Definition at line 62 of file iscsi.c.

62#define EACCES_INCORRECT_TARGET_USERNAME \
63 __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_USERNAME )

Referenced by iscsi_handle_chap_n_value().

◆ EINFO_EACCES_INCORRECT_TARGET_USERNAME

#define EINFO_EACCES_INCORRECT_TARGET_USERNAME    __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" )

Definition at line 64 of file iscsi.c.

64#define EINFO_EACCES_INCORRECT_TARGET_USERNAME \
65 __einfo_uniqify ( EINFO_EACCES, 0x01, "Incorrect target username" )

◆ EACCES_INCORRECT_TARGET_PASSWORD

#define EACCES_INCORRECT_TARGET_PASSWORD    __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

Definition at line 66 of file iscsi.c.

66#define EACCES_INCORRECT_TARGET_PASSWORD \
67 __einfo_error ( EINFO_EACCES_INCORRECT_TARGET_PASSWORD )

Referenced by iscsi_handle_chap_r_value().

◆ EINFO_EACCES_INCORRECT_TARGET_PASSWORD

#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD    __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" )

Definition at line 68 of file iscsi.c.

68#define EINFO_EACCES_INCORRECT_TARGET_PASSWORD \
69 __einfo_uniqify ( EINFO_EACCES, 0x02, "Incorrect target password" )

◆ EINVAL_ROOT_PATH_TOO_SHORT

#define EINVAL_ROOT_PATH_TOO_SHORT    __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )

Definition at line 70 of file iscsi.c.

70#define EINVAL_ROOT_PATH_TOO_SHORT \
71 __einfo_error ( EINFO_EINVAL_ROOT_PATH_TOO_SHORT )

Referenced by iscsi_parse_root_path().

◆ EINFO_EINVAL_ROOT_PATH_TOO_SHORT

#define EINFO_EINVAL_ROOT_PATH_TOO_SHORT    __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" )

Definition at line 72 of file iscsi.c.

72#define EINFO_EINVAL_ROOT_PATH_TOO_SHORT \
73 __einfo_uniqify ( EINFO_EINVAL, 0x01, "Root path too short" )

◆ EINVAL_BAD_CREDENTIAL_MIX

#define EINVAL_BAD_CREDENTIAL_MIX    __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

Definition at line 74 of file iscsi.c.

74#define EINVAL_BAD_CREDENTIAL_MIX \
75 __einfo_error ( EINFO_EINVAL_BAD_CREDENTIAL_MIX )

Referenced by iscsi_check_auth().

◆ EINFO_EINVAL_BAD_CREDENTIAL_MIX

#define EINFO_EINVAL_BAD_CREDENTIAL_MIX    __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" )

Definition at line 76 of file iscsi.c.

76#define EINFO_EINVAL_BAD_CREDENTIAL_MIX \
77 __einfo_uniqify ( EINFO_EINVAL, 0x02, "Bad credential mix" )

◆ EINVAL_NO_ROOT_PATH

#define EINVAL_NO_ROOT_PATH    __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

Definition at line 78 of file iscsi.c.

78#define EINVAL_NO_ROOT_PATH \
79 __einfo_error ( EINFO_EINVAL_NO_ROOT_PATH )

Referenced by iscsi_open().

◆ EINFO_EINVAL_NO_ROOT_PATH

#define EINFO_EINVAL_NO_ROOT_PATH    __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" )

Definition at line 80 of file iscsi.c.

80#define EINFO_EINVAL_NO_ROOT_PATH \
81 __einfo_uniqify ( EINFO_EINVAL, 0x03, "No root path" )

◆ EINVAL_NO_TARGET_IQN

#define EINVAL_NO_TARGET_IQN    __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

Definition at line 82 of file iscsi.c.

82#define EINVAL_NO_TARGET_IQN \
83 __einfo_error ( EINFO_EINVAL_NO_TARGET_IQN )

Referenced by iscsi_open().

◆ EINFO_EINVAL_NO_TARGET_IQN

#define EINFO_EINVAL_NO_TARGET_IQN    __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )

Definition at line 84 of file iscsi.c.

84#define EINFO_EINVAL_NO_TARGET_IQN \
85 __einfo_uniqify ( EINFO_EINVAL, 0x04, "No target IQN" )

◆ EINVAL_NO_INITIATOR_IQN

#define EINVAL_NO_INITIATOR_IQN    __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

Definition at line 86 of file iscsi.c.

86#define EINVAL_NO_INITIATOR_IQN \
87 __einfo_error ( EINFO_EINVAL_NO_INITIATOR_IQN )

Referenced by iscsi_fetch_settings().

◆ EINFO_EINVAL_NO_INITIATOR_IQN

#define EINFO_EINVAL_NO_INITIATOR_IQN    __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )

Definition at line 88 of file iscsi.c.

88#define EINFO_EINVAL_NO_INITIATOR_IQN \
89 __einfo_uniqify ( EINFO_EINVAL, 0x05, "No initiator IQN" )

◆ EINVAL_MAXBURSTLENGTH

#define EINVAL_MAXBURSTLENGTH    __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )

Definition at line 90 of file iscsi.c.

90#define EINVAL_MAXBURSTLENGTH \
91 __einfo_error ( EINFO_EINVAL_MAXBURSTLENGTH )

Referenced by iscsi_handle_maxburstlength_value().

◆ EINFO_EINVAL_MAXBURSTLENGTH

#define EINFO_EINVAL_MAXBURSTLENGTH    __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" )

Definition at line 92 of file iscsi.c.

92#define EINFO_EINVAL_MAXBURSTLENGTH \
93 __einfo_uniqify ( EINFO_EINVAL, 0x06, "Invalid MaxBurstLength" )

◆ EIO_TARGET_UNAVAILABLE

#define EIO_TARGET_UNAVAILABLE    __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

Definition at line 94 of file iscsi.c.

94#define EIO_TARGET_UNAVAILABLE \
95 __einfo_error ( EINFO_EIO_TARGET_UNAVAILABLE )

Referenced by iscsi_status_to_rc().

◆ EINFO_EIO_TARGET_UNAVAILABLE

#define EINFO_EIO_TARGET_UNAVAILABLE    __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" )

Definition at line 96 of file iscsi.c.

96#define EINFO_EIO_TARGET_UNAVAILABLE \
97 __einfo_uniqify ( EINFO_EIO, 0x01, "Target not currently operational" )

◆ EIO_TARGET_NO_RESOURCES

#define EIO_TARGET_NO_RESOURCES    __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

Definition at line 98 of file iscsi.c.

98#define EIO_TARGET_NO_RESOURCES \
99 __einfo_error ( EINFO_EIO_TARGET_NO_RESOURCES )

Referenced by iscsi_status_to_rc().

◆ EINFO_EIO_TARGET_NO_RESOURCES

#define EINFO_EIO_TARGET_NO_RESOURCES    __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" )

Definition at line 100 of file iscsi.c.

100#define EINFO_EIO_TARGET_NO_RESOURCES \
101 __einfo_uniqify ( EINFO_EIO, 0x02, "Target out of resources" )

◆ ENOTSUP_INITIATOR_STATUS

#define ENOTSUP_INITIATOR_STATUS    __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Definition at line 102 of file iscsi.c.

102#define ENOTSUP_INITIATOR_STATUS \
103 __einfo_error ( EINFO_ENOTSUP_INITIATOR_STATUS )

Referenced by iscsi_status_to_rc().

◆ EINFO_ENOTSUP_INITIATOR_STATUS

#define EINFO_ENOTSUP_INITIATOR_STATUS    __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" )

Definition at line 104 of file iscsi.c.

104#define EINFO_ENOTSUP_INITIATOR_STATUS \
105 __einfo_uniqify ( EINFO_ENOTSUP, 0x01, "Unsupported initiator status" )

◆ ENOTSUP_OPCODE

#define ENOTSUP_OPCODE    __einfo_error ( EINFO_ENOTSUP_OPCODE )

Definition at line 106 of file iscsi.c.

106#define ENOTSUP_OPCODE \
107 __einfo_error ( EINFO_ENOTSUP_OPCODE )

Referenced by iscsi_rx_data().

◆ EINFO_ENOTSUP_OPCODE

#define EINFO_ENOTSUP_OPCODE    __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" )

Definition at line 108 of file iscsi.c.

108#define EINFO_ENOTSUP_OPCODE \
109 __einfo_uniqify ( EINFO_ENOTSUP, 0x02, "Unsupported opcode" )

◆ ENOTSUP_DISCOVERY

#define ENOTSUP_DISCOVERY    __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Definition at line 110 of file iscsi.c.

110#define ENOTSUP_DISCOVERY \
111 __einfo_error ( EINFO_ENOTSUP_DISCOVERY )

Referenced by iscsi_open().

◆ EINFO_ENOTSUP_DISCOVERY

#define EINFO_ENOTSUP_DISCOVERY    __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" )

Definition at line 112 of file iscsi.c.

112#define EINFO_ENOTSUP_DISCOVERY \
113 __einfo_uniqify ( EINFO_ENOTSUP, 0x03, "Discovery not supported" )

◆ ENOTSUP_TARGET_STATUS

#define ENOTSUP_TARGET_STATUS    __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Definition at line 114 of file iscsi.c.

114#define ENOTSUP_TARGET_STATUS \
115 __einfo_error ( EINFO_ENOTSUP_TARGET_STATUS )

Referenced by iscsi_status_to_rc().

◆ EINFO_ENOTSUP_TARGET_STATUS

#define EINFO_ENOTSUP_TARGET_STATUS    __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" )

Definition at line 116 of file iscsi.c.

116#define EINFO_ENOTSUP_TARGET_STATUS \
117 __einfo_uniqify ( EINFO_ENOTSUP, 0x04, "Unsupported target status" )

◆ EPERM_INITIATOR_AUTHENTICATION

#define EPERM_INITIATOR_AUTHENTICATION    __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Definition at line 118 of file iscsi.c.

118#define EPERM_INITIATOR_AUTHENTICATION \
119 __einfo_error ( EINFO_EPERM_INITIATOR_AUTHENTICATION )

Referenced by iscsi_status_to_rc().

◆ EINFO_EPERM_INITIATOR_AUTHENTICATION

#define EINFO_EPERM_INITIATOR_AUTHENTICATION    __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" )

Definition at line 120 of file iscsi.c.

120#define EINFO_EPERM_INITIATOR_AUTHENTICATION \
121 __einfo_uniqify ( EINFO_EPERM, 0x01, "Initiator authentication failed" )

◆ EPERM_INITIATOR_AUTHORISATION

#define EPERM_INITIATOR_AUTHORISATION    __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Definition at line 122 of file iscsi.c.

122#define EPERM_INITIATOR_AUTHORISATION \
123 __einfo_error ( EINFO_EPERM_INITIATOR_AUTHORISATION )

Referenced by iscsi_status_to_rc().

◆ EINFO_EPERM_INITIATOR_AUTHORISATION

#define EINFO_EPERM_INITIATOR_AUTHORISATION    __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" )

Definition at line 124 of file iscsi.c.

124#define EINFO_EPERM_INITIATOR_AUTHORISATION \
125 __einfo_uniqify ( EINFO_EPERM, 0x02, "Initiator not authorised" )

◆ EPROTO_INVALID_CHAP_ALGORITHM

#define EPROTO_INVALID_CHAP_ALGORITHM    __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

Definition at line 126 of file iscsi.c.

126#define EPROTO_INVALID_CHAP_ALGORITHM \
127 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_ALGORITHM )

Referenced by iscsi_handle_chap_a_value().

◆ EINFO_EPROTO_INVALID_CHAP_ALGORITHM

#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM    __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" )

Definition at line 128 of file iscsi.c.

128#define EINFO_EPROTO_INVALID_CHAP_ALGORITHM \
129 __einfo_uniqify ( EINFO_EPROTO, 0x01, "Invalid CHAP algorithm" )

◆ EPROTO_INVALID_CHAP_IDENTIFIER

#define EPROTO_INVALID_CHAP_IDENTIFIER    __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

Definition at line 130 of file iscsi.c.

130#define EPROTO_INVALID_CHAP_IDENTIFIER \
131 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_IDENTIFIER )

Referenced by iscsi_handle_chap_i_value().

◆ EINFO_EPROTO_INVALID_CHAP_IDENTIFIER

#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER    __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" )

Definition at line 132 of file iscsi.c.

132#define EINFO_EPROTO_INVALID_CHAP_IDENTIFIER \
133 __einfo_uniqify ( EINFO_EPROTO, 0x02, "Invalid CHAP identifier" )

◆ EPROTO_INVALID_LARGE_BINARY

#define EPROTO_INVALID_LARGE_BINARY    __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

Definition at line 134 of file iscsi.c.

134#define EPROTO_INVALID_LARGE_BINARY \
135 __einfo_error ( EINFO_EPROTO_INVALID_LARGE_BINARY )

Referenced by iscsi_large_binary_decode().

◆ EINFO_EPROTO_INVALID_LARGE_BINARY

#define EINFO_EPROTO_INVALID_LARGE_BINARY    __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )

Definition at line 136 of file iscsi.c.

136#define EINFO_EPROTO_INVALID_LARGE_BINARY \
137 __einfo_uniqify ( EINFO_EPROTO, 0x03, "Invalid large binary value" )

◆ EPROTO_INVALID_CHAP_RESPONSE

#define EPROTO_INVALID_CHAP_RESPONSE    __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Definition at line 138 of file iscsi.c.

138#define EPROTO_INVALID_CHAP_RESPONSE \
139 __einfo_error ( EINFO_EPROTO_INVALID_CHAP_RESPONSE )

Referenced by iscsi_handle_chap_r_value().

◆ EINFO_EPROTO_INVALID_CHAP_RESPONSE

#define EINFO_EPROTO_INVALID_CHAP_RESPONSE    __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )

Definition at line 140 of file iscsi.c.

140#define EINFO_EPROTO_INVALID_CHAP_RESPONSE \
141 __einfo_uniqify ( EINFO_EPROTO, 0x04, "Invalid CHAP response" )

◆ EPROTO_INVALID_KEY_VALUE_PAIR

#define EPROTO_INVALID_KEY_VALUE_PAIR    __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )

Definition at line 142 of file iscsi.c.

142#define EPROTO_INVALID_KEY_VALUE_PAIR \
143 __einfo_error ( EINFO_EPROTO_INVALID_KEY_VALUE_PAIR )

Referenced by iscsi_handle_string().

◆ EINFO_EPROTO_INVALID_KEY_VALUE_PAIR

#define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR    __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" )

Definition at line 144 of file iscsi.c.

144#define EINFO_EPROTO_INVALID_KEY_VALUE_PAIR \
145 __einfo_uniqify ( EINFO_EPROTO, 0x05, "Invalid key/value pair" )

◆ EPROTO_VALUE_REJECTED

#define EPROTO_VALUE_REJECTED    __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Definition at line 146 of file iscsi.c.

146#define EPROTO_VALUE_REJECTED \
147 __einfo_error ( EINFO_EPROTO_VALUE_REJECTED )

Referenced by iscsi_handle_string().

◆ EINFO_EPROTO_VALUE_REJECTED

#define EINFO_EPROTO_VALUE_REJECTED    __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" )

Definition at line 148 of file iscsi.c.

148#define EINFO_EPROTO_VALUE_REJECTED \
149 __einfo_uniqify ( EINFO_EPROTO, 0x06, "Parameter rejected" )

Enumeration Type Documentation

◆ iscsi_root_path_component

iSCSI root path components (as per RFC4173)

Enumerator
RP_SERVERNAME 
RP_PROTOCOL 
RP_PORT 
RP_LUN 
RP_TARGETNAME 
NUM_RP_COMPONENTS 

Definition at line 1965 of file iscsi.c.

1965 {
1966 RP_SERVERNAME = 0,
1968 RP_PORT,
1969 RP_LUN,
1972};
@ NUM_RP_COMPONENTS
Definition iscsi.c:1971
@ RP_SERVERNAME
Definition iscsi.c:1966
@ RP_PORT
Definition iscsi.c:1968
@ RP_PROTOCOL
Definition iscsi.c:1967
@ RP_TARGETNAME
Definition iscsi.c:1970
@ RP_LUN
Definition iscsi.c:1969

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ FEATURE()

FEATURE ( FEATURE_PROTOCOL ,
"iSCSI" ,
DHCP_EB_FEATURE_ISCSI ,
1  )

◆ iscsi_start_tx()

void iscsi_start_tx ( struct iscsi_session * iscsi)
static

Start up a new TX PDU.

Parameters
iscsiiSCSI session

This initiates the process of sending a new PDU. Only one PDU may be in transit at any one time.

Definition at line 1439 of file iscsi.c.

1439 {
1440
1441 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1442
1443 /* Initialise TX BHS */
1444 memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1445
1446 /* Flag TX engine to start transmitting */
1447 iscsi->tx_state = ISCSI_TX_BHS;
1448
1449 /* Start transmission process */
1450 iscsi_tx_resume ( iscsi );
1451}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void * memset(void *dest, int character, size_t len) __nonnull
static void iscsi_tx_resume(struct iscsi_session *iscsi)
Resume TX engine.
Definition iscsi.c:1427
@ ISCSI_TX_BHS
Sending the basic header segment.
Definition iscsi.h:525
@ ISCSI_TX_IDLE
Nothing to send.
Definition iscsi.h:523
union iscsi_bhs tx_bhs
Basic header segment for current TX PDU.
Definition iscsi.h:641
enum iscsi_tx_state tx_state
State of the TX engine.
Definition iscsi.h:643

References assert, ISCSI_TX_BHS, ISCSI_TX_IDLE, iscsi_tx_resume(), memset(), iscsi_session::tx_bhs, and iscsi_session::tx_state.

Referenced by iscsi_start_command(), iscsi_start_data_out(), and iscsi_start_login().

◆ iscsi_start_login()

void iscsi_start_login ( struct iscsi_session * iscsi)
static

Build iSCSI login request BHS.

Parameters
iscsiiSCSI session

Definition at line 771 of file iscsi.c.

771 {
773 int len;
774
775 switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) {
777 DBGC ( iscsi, "iSCSI %p entering security negotiation\n",
778 iscsi );
779 break;
781 DBGC ( iscsi, "iSCSI %p entering operational negotiation\n",
782 iscsi );
783 break;
784 default:
785 assert ( 0 );
786 }
787
788 /* Construct BHS and initiate transmission */
789 iscsi_start_tx ( iscsi );
792 request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
794 /* version_max and version_min left as zero */
796 ISCSI_SET_LENGTHS ( request->lengths, 0, len );
797 request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
799 request->isid_iana_qual = htons ( iscsi->isid_iana_qual );
800 /* tsih left as zero */
801 request->itt = htonl ( iscsi->itt );
802 /* cid left as zero */
803 request->cmdsn = htonl ( iscsi->cmdsn );
804 request->expstatsn = htonl ( iscsi->statsn + 1 );
805}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
ring len
Length.
Definition dwmac.h:226
#define DBGC(...)
Definition compiler.h:505
u8 request[0]
List of IEs requested.
Definition ieee80211.h:2
#define htonl(value)
Definition byteswap.h:134
#define htons(value)
Definition byteswap.h:136
static int iscsi_build_login_request_strings(struct iscsi_session *iscsi, void *data, size_t len)
Build iSCSI login request strings.
Definition iscsi.c:692
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition iscsi.c:1439
#define ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION
Definition iscsi.h:185
#define ISCSI_FLAG_IMMEDIATE
Immediate delivery.
Definition iscsi.h:100
#define ISCSI_OPCODE_LOGIN_REQUEST
Login request opcode.
Definition iscsi.h:174
#define ISCSI_STATUS_PHASE_MASK
Mask for all iSCSI session phases.
Definition iscsi.h:685
#define ISCSI_LOGIN_FLAG_TRANSITION
Willingness to transition to next stage.
Definition iscsi.h:177
#define ISCSI_LOGIN_CSG_MASK
Definition iscsi.h:183
#define IANA_EN_FEN_SYSTEMS
Fen Systems Ltd.
Definition iscsi.h:202
#define ISCSI_ISID_IANA
ISID IANA format marker.
Definition iscsi.h:195
#define ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION
Definition iscsi.h:184
#define ISCSI_SET_LENGTHS(segment_lengths, ahs_len, data_len)
Set additional header and data segment lengths.
Definition iscsi.h:70
iSCSI login request basic header segment
Definition iscsi.h:142
uint32_t cmdsn
Command sequence number.
Definition iscsi.h:630
uint32_t itt
Initiator task tag.
Definition iscsi.h:604
uint16_t isid_iana_qual
Initiator session ID (IANA format) qualifier.
Definition iscsi.h:598
int status
Session status.
Definition iscsi.h:570
uint32_t statsn
Status sequence number.
Definition iscsi.h:638
struct iscsi_bhs_login_request login_request
Definition iscsi.h:509

References assert, iscsi_session::cmdsn, DBGC, htonl, htons, IANA_EN_FEN_SYSTEMS, iscsi_build_login_request_strings(), ISCSI_FLAG_IMMEDIATE, ISCSI_ISID_IANA, ISCSI_LOGIN_CSG_MASK, ISCSI_LOGIN_CSG_OPERATIONAL_NEGOTIATION, ISCSI_LOGIN_CSG_SECURITY_NEGOTIATION, ISCSI_LOGIN_FLAG_TRANSITION, ISCSI_OPCODE_LOGIN_REQUEST, ISCSI_SET_LENGTHS, iscsi_start_tx(), ISCSI_STATUS_PHASE_MASK, iscsi_session::isid_iana_qual, iscsi_session::itt, len, iscsi_bhs::login_request, NULL, request, iscsi_session::statsn, iscsi_session::status, and iscsi_session::tx_bhs.

Referenced by iscsi_open_connection(), and iscsi_rx_login_response().

◆ iscsi_start_data_out()

void iscsi_start_data_out ( struct iscsi_session * iscsi,
unsigned int datasn )
static

Build iSCSI data-out BHS.

Parameters
iscsiiSCSI session
datasnData sequence number within the transfer

Definition at line 528 of file iscsi.c.

529 {
530 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
531 unsigned long offset;
532 unsigned long remaining;
533 unsigned long len;
534
535 /* We always send 512-byte Data-Out PDUs; this removes the
536 * need to worry about the target's MaxRecvDataSegmentLength.
537 */
538 offset = datasn * 512;
539 remaining = iscsi->transfer_len - offset;
540 len = remaining;
541 if ( len > 512 )
542 len = 512;
543
544 /* Construct BHS and initiate transmission */
545 iscsi_start_tx ( iscsi );
546 data_out->opcode = ISCSI_OPCODE_DATA_OUT;
547 if ( len == remaining )
548 data_out->flags = ( ISCSI_FLAG_FINAL );
549 ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
550 data_out->lun = iscsi->command->lun;
551 data_out->itt = htonl ( iscsi->itt );
552 data_out->ttt = htonl ( iscsi->ttt );
553 data_out->expstatsn = htonl ( iscsi->statsn + 1 );
554 data_out->datasn = htonl ( datasn );
555 data_out->offset = htonl ( iscsi->transfer_offset + offset );
556 DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
557 iscsi, datasn, len );
558}
uint16_t offset
Offset to command line.
Definition bzimage.h:3
#define ISCSI_OPCODE_DATA_OUT
Data-out opcode.
Definition iscsi.h:435
#define ISCSI_FLAG_FINAL
Final PDU of a sequence.
Definition iscsi.h:103
iSCSI data-out basic header segment
Definition iscsi.h:405
uint8_t opcode
Opcode.
Definition iscsi.h:407
union iscsi_segment_lengths lengths
Segment lengths.
Definition iscsi.h:413
uint32_t datasn
Data sequence number.
Definition iscsi.h:427
struct scsi_lun lun
Logical Unit Number.
Definition iscsi.h:415
uint32_t itt
Initiator Task Tag.
Definition iscsi.h:417
uint32_t expstatsn
Expected status sequence number.
Definition iscsi.h:423
uint32_t ttt
Target Transfer Tag.
Definition iscsi.h:419
uint32_t offset
Buffer offset.
Definition iscsi.h:429
uint8_t flags
Flags.
Definition iscsi.h:409
uint32_t ttt
Target transfer tag.
Definition iscsi.h:610
uint32_t transfer_len
Transfer length.
Definition iscsi.h:622
uint32_t transfer_offset
Transfer offset.
Definition iscsi.h:616
struct scsi_cmd * command
Current SCSI command, if any.
Definition iscsi.h:659
struct scsi_lun lun
LUN.
Definition scsi.h:251
struct iscsi_bhs_data_out data_out
Definition iscsi.h:514

References iscsi_session::command, iscsi_bhs::data_out, iscsi_bhs_data_out::datasn, DBGC, iscsi_bhs_data_out::expstatsn, iscsi_bhs_data_out::flags, htonl, ISCSI_FLAG_FINAL, ISCSI_OPCODE_DATA_OUT, ISCSI_SET_LENGTHS, iscsi_start_tx(), iscsi_bhs_data_out::itt, iscsi_session::itt, len, iscsi_bhs_data_out::lengths, iscsi_bhs_data_out::lun, scsi_cmd::lun, iscsi_bhs_data_out::offset, offset, iscsi_bhs_data_out::opcode, iscsi_session::statsn, iscsi_session::transfer_len, iscsi_session::transfer_offset, iscsi_bhs_data_out::ttt, iscsi_session::ttt, and iscsi_session::tx_bhs.

Referenced by iscsi_data_out_done(), and iscsi_rx_r2t().

◆ iscsi_rx_buffered_data_done()

void iscsi_rx_buffered_data_done ( struct iscsi_session * iscsi)
static

Finish receiving PDU data into buffer.

Parameters
iscsiiSCSI session

Definition at line 161 of file iscsi.c.

161 {
162 free ( iscsi->rx_buffer );
163 iscsi->rx_buffer = NULL;
164}
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
void * rx_buffer
Buffer for received data (not always used)
Definition iscsi.h:656

References free, NULL, and iscsi_session::rx_buffer.

Referenced by iscsi_close_connection(), iscsi_free(), iscsi_rx_login_response(), and iscsi_rx_scsi_response().

◆ iscsi_rx_buffered_data()

int iscsi_rx_buffered_data ( struct iscsi_session * iscsi,
const void * data,
size_t len )
static

Receive PDU data into buffer.

Parameters
iscsiiSCSI session
dataData to receive
lenLength of data
Return values
rcReturn status code

This can be used when the RX PDU type handler wishes to buffer up all received data and process the PDU as a single unit. The caller is repsonsible for calling iscsi_rx_buffered_data_done() after processing the data.

Definition at line 179 of file iscsi.c.

180 {
181
182 /* Allocate buffer on first call */
183 if ( ! iscsi->rx_buffer ) {
184 iscsi->rx_buffer = malloc ( iscsi->rx_len );
185 if ( ! iscsi->rx_buffer )
186 return -ENOMEM;
187 }
188
189 /* Copy data to buffer */
190 assert ( ( iscsi->rx_offset + len ) <= iscsi->rx_len );
191 memcpy ( ( iscsi->rx_buffer + iscsi->rx_offset ), data, len );
192
193 return 0;
194}
uint8_t data[48]
Additional event data.
Definition ena.h:11
#define ENOMEM
Not enough space.
Definition errno.h:535
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
size_t rx_offset
Byte offset within the current RX state.
Definition iscsi.h:652
size_t rx_len
Length of the current RX state.
Definition iscsi.h:654

References assert, data, ENOMEM, len, malloc(), memcpy(), iscsi_session::rx_buffer, iscsi_session::rx_len, and iscsi_session::rx_offset.

Referenced by iscsi_rx_login_response(), and iscsi_rx_scsi_response().

◆ iscsi_free()

void iscsi_free ( struct refcnt * refcnt)
static

Free iSCSI session.

Parameters
refcntReference counter

Definition at line 201 of file iscsi.c.

201 {
202 struct iscsi_session *iscsi =
204
205 free ( iscsi->initiator_iqn );
206 free ( iscsi->target_address );
207 free ( iscsi->target_iqn );
208 free ( iscsi->initiator_username );
209 free ( iscsi->initiator_password );
210 free ( iscsi->target_username );
211 free ( iscsi->target_password );
212 chap_finish ( &iscsi->chap );
214 free ( iscsi->command );
215 free ( iscsi );
216}
void chap_finish(struct chap_response *chap)
Free resources used by a CHAP response.
Definition chap.c:123
static void iscsi_rx_buffered_data_done(struct iscsi_session *iscsi)
Finish receiving PDU data into buffer.
Definition iscsi.c:161
#define container_of(ptr, type, field)
Get containing structure.
Definition stddef.h:36
An iSCSI session.
Definition iscsi.h:545
char * target_iqn
Target IQN.
Definition iscsi.h:563
char * initiator_password
Initiator password (if any)
Definition iscsi.h:575
char * target_password
Target password (if any)
Definition iscsi.h:579
char * initiator_username
Initiator username (if any)
Definition iscsi.h:573
char * initiator_iqn
Initiator IQN.
Definition iscsi.h:557
char * target_username
Target username (if any)
Definition iscsi.h:577
struct chap_response chap
CHAP response (used for both initiator and target auth)
Definition iscsi.h:588
char * target_address
Target address.
Definition iscsi.h:559
A reference counter.
Definition refcnt.h:27

References iscsi_session::chap, chap_finish(), iscsi_session::command, container_of, free, iscsi_session::initiator_iqn, iscsi_session::initiator_password, iscsi_session::initiator_username, iscsi_rx_buffered_data_done(), iscsi_session::target_address, iscsi_session::target_iqn, iscsi_session::target_password, and iscsi_session::target_username.

Referenced by iscsi_open().

◆ iscsi_close()

void iscsi_close ( struct iscsi_session * iscsi,
int rc )
static

Shut down iSCSI interface.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 224 of file iscsi.c.

224 {
225
226 /* A TCP graceful close is still an error from our point of view */
227 if ( rc == 0 )
228 rc = -ECONNRESET;
229
230 DBGC ( iscsi, "iSCSI %p closed: %s\n", iscsi, strerror ( rc ) );
231
232 /* Stop transmission process */
233 process_del ( &iscsi->process );
234
235 /* Shut down interfaces */
236 intfs_shutdown ( rc, &iscsi->socket, &iscsi->control, &iscsi->data,
237 NULL );
238}
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
#define ECONNRESET
Connection reset.
Definition errno.h:364
void intfs_shutdown(int rc,...)
Shut down multiple object interfaces.
Definition interface.c:327
void process_del(struct process *process)
Remove process from process list.
Definition process.c:80
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
struct interface control
SCSI command-issuing interface.
Definition iscsi.h:550
struct interface data
SCSI command interface.
Definition iscsi.h:552
struct process process
TX process.
Definition iscsi.h:645
struct interface socket
Transport-layer socket.
Definition iscsi.h:554

References iscsi_session::control, iscsi_session::data, DBGC, ECONNRESET, intfs_shutdown(), NULL, iscsi_session::process, process_del(), rc, iscsi_session::socket, and strerror().

Referenced by iscsi_command_close(), iscsi_open(), iscsi_socket_deliver(), iscsi_tx_step(), and iscsi_vredirect().

◆ iscsi_new_itt()

void iscsi_new_itt ( struct iscsi_session * iscsi)
static

Assign new iSCSI initiator task tag.

Parameters
iscsiiSCSI session

Definition at line 245 of file iscsi.c.

245 {
246 static uint16_t itt_idx;
247
248 iscsi->itt = ( ISCSI_TAG_MAGIC | (++itt_idx) );
249}
unsigned short uint16_t
Definition stdint.h:11
#define ISCSI_TAG_MAGIC
iSCSI tag magic marker
Definition iscsi.h:106

References ISCSI_TAG_MAGIC, and iscsi_session::itt.

Referenced by iscsi_open_connection(), and iscsi_scsi_command().

◆ iscsi_open_connection()

int iscsi_open_connection ( struct iscsi_session * iscsi)
static

Open iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 257 of file iscsi.c.

257 {
258 struct sockaddr_tcpip target;
259 int rc;
260
261 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
262 assert ( iscsi->rx_state == ISCSI_RX_BHS );
263 assert ( iscsi->rx_offset == 0 );
264
265 /* Open socket */
266 memset ( &target, 0, sizeof ( target ) );
267 target.st_port = htons ( iscsi->target_port );
268 if ( ( rc = xfer_open_named_socket ( &iscsi->socket, SOCK_STREAM,
269 ( struct sockaddr * ) &target,
270 iscsi->target_address,
271 NULL ) ) != 0 ) {
272 DBGC ( iscsi, "iSCSI %p could not open socket: %s\n",
273 iscsi, strerror ( rc ) );
274 return rc;
275 }
276
277 /* Enter security negotiation phase */
280 if ( iscsi->target_username )
282
283 /* Assign new ISID */
284 iscsi->isid_iana_qual = ( random() & 0xffff );
285
286 /* Assign fresh initiator task tag */
287 iscsi_new_itt ( iscsi );
288
289 /* Set default operational parameters */
291
292 /* Initiate login */
293 iscsi_start_login ( iscsi );
294
295 return 0;
296}
#define SOCK_STREAM
Definition socket.h:25
static void iscsi_start_login(struct iscsi_session *iscsi)
Build iSCSI login request BHS.
Definition iscsi.c:771
static void iscsi_new_itt(struct iscsi_session *iscsi)
Assign new iSCSI initiator task tag.
Definition iscsi.c:245
#define ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE
iSCSI session is currently in the security negotiation phase
Definition iscsi.h:670
#define ISCSI_STATUS_AUTH_REVERSE_REQUIRED
Initiator requires target (reverse) authentication.
Definition iscsi.h:709
#define ISCSI_MAX_BURST_LEN
Default iSCSI maximum burst length.
Definition iscsi.h:30
@ ISCSI_RX_BHS
Receiving the basic header segment.
Definition iscsi.h:535
#define ISCSI_STATUS_STRINGS_SECURITY
iSCSI session needs to send the initial security negotiation strings
Definition iscsi.h:688
long int random(void)
Generate a pseudo-random number between 0 and 2147483647L or 2147483562?
Definition random.c:32
int xfer_open_named_socket(struct interface *xfer, int semantics, struct sockaddr *peer, const char *name, struct sockaddr *local)
Open named socket.
Definition resolv.c:403
enum iscsi_rx_state rx_state
State of the RX engine.
Definition iscsi.h:650
size_t max_burst_len
Maximum burst length.
Definition iscsi.h:591
unsigned int target_port
Target port.
Definition iscsi.h:561
TCP/IP socket address.
Definition tcpip.h:76
Generalized socket address structure.
Definition socket.h:97

References assert, DBGC, htons, ISCSI_MAX_BURST_LEN, iscsi_new_itt(), ISCSI_RX_BHS, iscsi_start_login(), ISCSI_STATUS_AUTH_REVERSE_REQUIRED, ISCSI_STATUS_SECURITY_NEGOTIATION_PHASE, ISCSI_STATUS_STRINGS_SECURITY, ISCSI_TX_IDLE, iscsi_session::isid_iana_qual, iscsi_session::max_burst_len, memset(), NULL, random(), rc, iscsi_session::rx_offset, iscsi_session::rx_state, SOCK_STREAM, iscsi_session::socket, sockaddr_tcpip::st_port, iscsi_session::status, strerror(), iscsi_session::target_address, iscsi_session::target_port, iscsi_session::target_username, iscsi_session::tx_state, and xfer_open_named_socket().

Referenced by iscsi_open(), and iscsi_rx_login_response().

◆ iscsi_close_connection()

void iscsi_close_connection ( struct iscsi_session * iscsi,
int rc )
static

Close iSCSI transport-layer connection.

Parameters
iscsiiSCSI session
rcReason for close

Closes the transport-layer connection and resets the session state ready to attempt a fresh login.

Definition at line 307 of file iscsi.c.

307 {
308
309 /* Close all data transfer interfaces */
310 intf_restart ( &iscsi->socket, rc );
311
312 /* Clear connection status */
313 iscsi->status = 0;
314
315 /* Reset TX and RX state machines */
316 iscsi->tx_state = ISCSI_TX_IDLE;
317 iscsi->rx_state = ISCSI_RX_BHS;
318 iscsi->rx_offset = 0;
319
320 /* Free any temporary dynamically allocated memory */
321 chap_finish ( &iscsi->chap );
323}
void intf_restart(struct interface *intf, int rc)
Shut down and restart an object interface.
Definition interface.c:344

References iscsi_session::chap, chap_finish(), intf_restart(), ISCSI_RX_BHS, iscsi_rx_buffered_data_done(), ISCSI_TX_IDLE, rc, iscsi_session::rx_offset, iscsi_session::rx_state, iscsi_session::socket, iscsi_session::status, and iscsi_session::tx_state.

Referenced by iscsi_rx_login_response().

◆ iscsi_scsi_done()

void iscsi_scsi_done ( struct iscsi_session * iscsi,
int rc,
struct scsi_rsp * rsp )
static

Mark iSCSI SCSI operation as complete.

Parameters
iscsiiSCSI session
rcReturn status code
rspSCSI response, if any

Note that iscsi_scsi_done() will not close the connection, and must therefore be called only when the internal state machines are in an appropriate state, otherwise bad things may happen on the next call to iscsi_scsi_command(). The general rule is to call iscsi_scsi_done() only at the end of receiving a PDU; at this point the TX and RX engines should both be idle.

Definition at line 339 of file iscsi.c.

340 {
341 uint32_t itt = iscsi->itt;
342
343 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
344
345 /* Clear command */
346 free ( iscsi->command );
347 iscsi->command = NULL;
348
349 /* Send SCSI response, if any */
350 if ( rsp )
351 scsi_response ( &iscsi->data, rsp );
352
353 /* Close SCSI command, if this is still the same command. (It
354 * is possible that the command interface has already been
355 * closed as a result of the SCSI response we sent.)
356 */
357 if ( iscsi->itt == itt )
358 intf_restart ( &iscsi->data, rc );
359}
unsigned int uint32_t
Definition stdint.h:12
uint64_t rsp
Definition librm.h:18
void scsi_response(struct interface *intf, struct scsi_rsp *response)
Report SCSI response.
Definition scsi.c:207

References assert, iscsi_session::command, iscsi_session::data, free, intf_restart(), ISCSI_TX_IDLE, iscsi_session::itt, NULL, rc, rsp, scsi_response(), and iscsi_session::tx_state.

Referenced by iscsi_rx_data_in(), and iscsi_rx_scsi_response().

◆ iscsi_start_command()

void iscsi_start_command ( struct iscsi_session * iscsi)
static

Build iSCSI SCSI command BHS.

Parameters
iscsiiSCSI session

We don't currently support bidirectional commands (i.e. with both Data-In and Data-Out segments); these would require providing code to generate an AHS, and there doesn't seem to be any need for it at the moment.

Definition at line 377 of file iscsi.c.

377 {
379
380 assert ( ! ( iscsi->command->data_in && iscsi->command->data_out ) );
381
382 /* Construct BHS and initiate transmission */
383 iscsi_start_tx ( iscsi );
385 command->flags = ( ISCSI_FLAG_FINAL |
387 if ( iscsi->command->data_in )
389 if ( iscsi->command->data_out )
391 /* lengths left as zero */
392 memcpy ( &command->lun, &iscsi->command->lun,
393 sizeof ( command->lun ) );
394 command->itt = htonl ( iscsi->itt );
395 command->exp_len = htonl ( iscsi->command->data_in_len |
396 iscsi->command->data_out_len );
397 command->cmdsn = htonl ( iscsi->cmdsn );
398 command->expstatsn = htonl ( iscsi->statsn + 1 );
399 memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
400 DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
401 iscsi, SCSI_CDB_DATA ( command->cdb ),
402 ( iscsi->command->data_in ? "in" : "out" ),
403 ( iscsi->command->data_in ?
404 iscsi->command->data_in_len :
405 iscsi->command->data_out_len ) );
406}
#define DBGC2(...)
Definition compiler.h:522
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:223
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:219
#define ISCSI_COMMAND_ATTR_SIMPLE
Definition iscsi.h:296
#define ISCSI_COMMAND_FLAG_READ
Command will read data.
Definition iscsi.h:289
#define ISCSI_COMMAND_FLAG_WRITE
Command will write data.
Definition iscsi.h:292
#define ISCSI_OPCODE_SCSI_COMMAND
SCSI command opcode.
Definition iscsi.h:286
A command-line command.
Definition command.h:10
iSCSI SCSI command basic header segment
Definition iscsi.h:262
size_t data_out_len
Data-out buffer length.
Definition scsi.h:260
size_t data_in_len
Data-in buffer length.
Definition scsi.h:267
void * data_out
Data-out buffer (may be NULL)
Definition scsi.h:255
void * data_in
Data-in buffer (may be NULL)
Definition scsi.h:262
union scsi_cdb cdb
CDB for this command.
Definition scsi.h:253
struct iscsi_bhs_scsi_command scsi_command
Definition iscsi.h:511

References assert, scsi_cmd::cdb, iscsi_session::cmdsn, iscsi_session::command, scsi_cmd::data_in, scsi_cmd::data_in_len, scsi_cmd::data_out, scsi_cmd::data_out_len, DBGC2, htonl, ISCSI_COMMAND_ATTR_SIMPLE, ISCSI_COMMAND_FLAG_READ, ISCSI_COMMAND_FLAG_WRITE, ISCSI_FLAG_FINAL, ISCSI_OPCODE_SCSI_COMMAND, iscsi_start_tx(), iscsi_session::itt, scsi_cmd::lun, memcpy(), SCSI_CDB_DATA, SCSI_CDB_FORMAT, iscsi_bhs::scsi_command, iscsi_session::statsn, and iscsi_session::tx_bhs.

Referenced by iscsi_scsi_command().

◆ iscsi_rx_scsi_response()

int iscsi_rx_scsi_response ( struct iscsi_session * iscsi,
const void * data,
size_t len,
size_t remaining )
static

Receive data segment of an iSCSI SCSI response PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 417 of file iscsi.c.

419 {
421 = &iscsi->rx_bhs.scsi_response;
422 struct scsi_rsp rsp;
423 uint32_t residual_count;
424 size_t data_len;
425 int rc;
426
427 /* Buffer up the PDU data */
428 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
429 DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n",
430 iscsi, strerror ( rc ) );
431 return rc;
432 }
433 if ( remaining )
434 return 0;
435
436 /* Parse SCSI response and discard buffer */
437 memset ( &rsp, 0, sizeof ( rsp ) );
438 rsp.status = response->status;
439 residual_count = ntohl ( response->residual_count );
440 if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) {
441 rsp.overrun = residual_count;
442 } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) {
443 rsp.overrun = -(residual_count);
444 }
445 data_len = ISCSI_DATA_LEN ( response->lengths );
446 if ( data_len ) {
447 scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ),
448 &rsp.sense );
449 }
451
452 /* Check for errors */
453 if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
454 return -EIO;
455
456 /* Mark as completed */
457 iscsi_scsi_done ( iscsi, 0, &rsp );
458 return 0;
459}
#define EIO
Input/output error.
Definition errno.h:434
#define ntohl(value)
Definition byteswap.h:135
static void iscsi_scsi_done(struct iscsi_session *iscsi, int rc, struct scsi_rsp *rsp)
Mark iSCSI SCSI operation as complete.
Definition iscsi.c:339
static int iscsi_rx_buffered_data(struct iscsi_session *iscsi, const void *data, size_t len)
Receive PDU data into buffer.
Definition iscsi.c:179
#define ISCSI_RESPONSE_COMMAND_COMPLETE
SCSI command completed at target.
Definition iscsi.h:340
#define ISCSI_DATA_LEN(segment_lengths)
The length of the data segment, in bytes, excluding any padding.
Definition iscsi.h:62
#define ISCSI_DATA_FLAG_OVERFLOW
Data overflow occurred.
Definition iscsi.h:393
#define ISCSI_DATA_FLAG_UNDERFLOW
Data underflow occurred.
Definition iscsi.h:396
void scsi_parse_sense(const void *data, size_t len, struct scsi_sns_descriptor *sense)
Parse SCSI sense data.
Definition scsi.c:147
iSCSI SCSI response basic header segment
Definition iscsi.h:305
uint8_t status
SCSI status code.
Definition iscsi.h:313
uint32_t residual_count
Residual count.
Definition iscsi.h:333
uint8_t response
Response code.
Definition iscsi.h:311
uint8_t flags
Flags.
Definition iscsi.h:309
union iscsi_segment_lengths lengths
Segment lengths.
Definition iscsi.h:315
union iscsi_bhs rx_bhs
Basic header segment for current RX PDU.
Definition iscsi.h:648
A SCSI response information unit.
Definition scsi.h:322
uint32_t data_len
Microcode data size (or 0 to indicate 2000 bytes)
Definition ucode.h:15
struct iscsi_bhs_scsi_response scsi_response
Definition iscsi.h:512

References data, data_len, DBGC, EIO, iscsi_bhs_scsi_response::flags, ISCSI_DATA_FLAG_OVERFLOW, ISCSI_DATA_FLAG_UNDERFLOW, ISCSI_DATA_LEN, ISCSI_RESPONSE_COMMAND_COMPLETE, iscsi_rx_buffered_data(), iscsi_rx_buffered_data_done(), iscsi_scsi_done(), len, iscsi_bhs_scsi_response::lengths, memset(), ntohl, rc, iscsi_bhs_scsi_response::residual_count, iscsi_bhs_scsi_response::response, rsp, iscsi_session::rx_bhs, iscsi_session::rx_buffer, scsi_parse_sense(), iscsi_bhs::scsi_response, iscsi_bhs_scsi_response::status, and strerror().

Referenced by iscsi_rx_data().

◆ iscsi_rx_data_in()

int iscsi_rx_data_in ( struct iscsi_session * iscsi,
const void * data,
size_t len,
size_t remaining )
static

Receive data segment of an iSCSI data-in PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 470 of file iscsi.c.

472 {
473 struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
474 unsigned long offset;
475
476 /* Copy data to data-in buffer */
477 offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
478 assert ( iscsi->command != NULL );
479 assert ( iscsi->command->data_in );
480 assert ( ( offset + len ) <= iscsi->command->data_in_len );
481 memcpy ( ( iscsi->command->data_in + offset ), data, len );
482
483 /* Wait for whole SCSI response to arrive */
484 if ( remaining )
485 return 0;
486
487 /* Mark as completed if status is present */
488 if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
489 assert ( ( offset + len ) == iscsi->command->data_in_len );
490 assert ( data_in->flags & ISCSI_FLAG_FINAL );
491 /* iSCSI cannot return an error status via a data-in */
492 iscsi_scsi_done ( iscsi, 0, NULL );
493 }
494
495 return 0;
496}
#define ISCSI_DATA_FLAG_STATUS
SCSI status code and overflow/underflow flags are valid.
Definition iscsi.h:399
iSCSI data-in basic header segment
Definition iscsi.h:355
uint32_t offset
Buffer offset.
Definition iscsi.h:381
uint8_t flags
Flags.
Definition iscsi.h:359
struct iscsi_bhs_data_in data_in
Definition iscsi.h:513

References assert, iscsi_session::command, data, iscsi_bhs::data_in, scsi_cmd::data_in, scsi_cmd::data_in_len, iscsi_bhs_data_in::flags, ISCSI_DATA_FLAG_STATUS, ISCSI_FLAG_FINAL, iscsi_scsi_done(), len, memcpy(), ntohl, NULL, iscsi_bhs_data_in::offset, offset, iscsi_session::rx_bhs, and iscsi_session::rx_offset.

Referenced by iscsi_rx_data().

◆ iscsi_rx_r2t()

int iscsi_rx_r2t ( struct iscsi_session * iscsi,
const void *data __unused,
size_t len __unused,
size_t remaining __unused )
static

Receive data segment of an iSCSI R2T PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 507 of file iscsi.c.

509 {
510 struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
511
512 /* Record transfer parameters and trigger first data-out */
513 iscsi->ttt = ntohl ( r2t->ttt );
514 iscsi->transfer_offset = ntohl ( r2t->offset );
515 iscsi->transfer_len = ntohl ( r2t->len );
516 iscsi_start_data_out ( iscsi, 0 );
517
518 return 0;
519}
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition iscsi.c:528
iSCSI request to transfer basic header segment
Definition iscsi.h:441
uint32_t ttt
Target Transfer Tag.
Definition iscsi.h:455
uint32_t len
Desired data transfer length.
Definition iscsi.h:467
uint32_t offset
Buffer offset.
Definition iscsi.h:465
struct iscsi_bhs_r2t r2t
Definition iscsi.h:515

References __unused, data, iscsi_start_data_out(), iscsi_bhs_r2t::len, len, ntohl, iscsi_bhs_r2t::offset, iscsi_bhs::r2t, iscsi_session::rx_bhs, iscsi_session::transfer_len, iscsi_session::transfer_offset, iscsi_bhs_r2t::ttt, and iscsi_session::ttt.

Referenced by iscsi_rx_data().

◆ iscsi_data_out_done()

void iscsi_data_out_done ( struct iscsi_session * iscsi)
static

Complete iSCSI data-out PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 566 of file iscsi.c.

566 {
567 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
568
569 /* If we haven't reached the end of the sequence, start
570 * sending the next data-out PDU.
571 */
572 if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
573 iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
574}

References iscsi_bhs::data_out, iscsi_bhs_data_out::datasn, iscsi_bhs_data_out::flags, ISCSI_FLAG_FINAL, iscsi_start_data_out(), ntohl, and iscsi_session::tx_bhs.

Referenced by iscsi_tx_done().

◆ iscsi_tx_data_out()

int iscsi_tx_data_out ( struct iscsi_session * iscsi)
static

Send iSCSI data-out data segment.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 582 of file iscsi.c.

582 {
583 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
584 struct io_buffer *iobuf;
585 unsigned long offset;
586 size_t len;
587 size_t pad_len;
588
589 offset = ntohl ( data_out->offset );
590 len = ISCSI_DATA_LEN ( data_out->lengths );
591 pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
592
593 assert ( iscsi->command != NULL );
594 assert ( iscsi->command->data_out );
595 assert ( ( offset + len ) <= iscsi->command->data_out_len );
596
597 iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
598 if ( ! iobuf )
599 return -ENOMEM;
600
601 memcpy ( iob_put ( iobuf, len ),
602 ( iscsi->command->data_out + offset ), len );
603 memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
604
605 return xfer_deliver_iob ( &iscsi->socket, iobuf );
606}
long pad_len
Definition bigint.h:31
#define iob_put(iobuf, len)
Definition iobuf.h:125
#define ISCSI_DATA_PAD_LEN(segment_lengths)
The padding of the data segment, in bytes.
Definition iscsi.h:66
A persistent I/O buffer.
Definition iobuf.h:38
struct io_buffer * xfer_alloc_iob(struct interface *intf, size_t len)
Allocate I/O buffer.
Definition xfer.c:159
int xfer_deliver_iob(struct interface *intf, struct io_buffer *iobuf)
Deliver datagram as I/O buffer without metadata.
Definition xfer.c:256

References assert, iscsi_session::command, iscsi_bhs::data_out, scsi_cmd::data_out, scsi_cmd::data_out_len, ENOMEM, iob_put, ISCSI_DATA_LEN, ISCSI_DATA_PAD_LEN, len, iscsi_bhs_data_out::lengths, memcpy(), memset(), ntohl, NULL, iscsi_bhs_data_out::offset, offset, pad_len, iscsi_session::socket, iscsi_session::tx_bhs, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by iscsi_tx_data().

◆ iscsi_rx_nop_in()

int iscsi_rx_nop_in ( struct iscsi_session * iscsi,
const void *data __unused,
size_t len __unused,
size_t remaining __unused )
static

Receive data segment of an iSCSI NOP-In.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 617 of file iscsi.c.

619 {
620 struct iscsi_nop_in *nop_in = &iscsi->rx_bhs.nop_in;
621
622 DBGC2 ( iscsi, "iSCSI %p received NOP-In\n", iscsi );
623
624 /* We don't currently have the ability to respond to NOP-Ins
625 * sent as ping requests, but we can happily accept NOP-Ins
626 * sent merely to update CmdSN.
627 */
628 if ( nop_in->ttt == htonl ( ISCSI_TAG_RESERVED ) )
629 return 0;
630
631 /* Ignore any other NOP-Ins. The target may eventually
632 * disconnect us for failing to respond, but this minimises
633 * unnecessary connection closures.
634 */
635 DBGC ( iscsi, "iSCSI %p received unsupported NOP-In with TTT %08x\n",
636 iscsi, ntohl ( nop_in->ttt ) );
637 return 0;
638}
#define ISCSI_TAG_RESERVED
iSCSI reserved tag value
Definition iscsi.h:109
iSCSI NOP-In basic header segment
Definition iscsi.h:477
uint32_t ttt
Target Transfer Tag.
Definition iscsi.h:489
struct iscsi_nop_in nop_in
Definition iscsi.h:516

References __unused, data, DBGC, DBGC2, htonl, ISCSI_TAG_RESERVED, len, iscsi_bhs::nop_in, ntohl, iscsi_session::rx_bhs, and iscsi_nop_in::ttt.

Referenced by iscsi_rx_data().

◆ iscsi_build_login_request_strings()

int iscsi_build_login_request_strings ( struct iscsi_session * iscsi,
void * data,
size_t len )
static

Build iSCSI login request strings.

Parameters
iscsiiSCSI session

These are the initial set of strings sent in the first login request PDU. We want the following settings:

HeaderDigest=None
DataDigest=None
MaxConnections=1 (irrelevant; we make only one connection anyway) [4]
InitialR2T=Yes [1]
ImmediateData=No (irrelevant; we never send immediate data) [4]
MaxRecvDataSegmentLength=8192 (default; we don't care) [3]
MaxBurstLength=262144 (default; we don't care) [3]
FirstBurstLength=65536 (irrelevant due to other settings) [5]
DefaultTime2Wait=0 [2]
DefaultTime2Retain=0 [2]
MaxOutstandingR2T=1
DataPDUInOrder=Yes
DataSequenceInOrder=Yes
ErrorRecoveryLevel=0

[1] InitialR2T has an OR resolution function, so the target may force us to use it. We therefore simplify our logic by always using it.

[2] These ensure that we can safely start a new task once we have reconnected after a failure, without having to manually tidy up after the old one.

[3] We are quite happy to use the RFC-defined default values for these parameters, but some targets (notably OpenSolaris) incorrectly assume a default value of zero, so we explicitly specify the default values.

[4] We are quite happy to use the RFC-defined default values for these parameters, but some targets (notably a QNAP TS-639Pro) fail unless they are supplied, so we explicitly specify the default values.

[5] FirstBurstLength is defined to be irrelevant since we already force InitialR2T=Yes and ImmediateData=No, but some targets (notably LIO as of kernel 4.11) fail unless it is specified, so we explicitly specify the default value.

Definition at line 692 of file iscsi.c.

693 {
694 unsigned int used = 0;
695 const char *auth_method;
696
697 if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
698 /* Default to allowing no authentication */
699 auth_method = "None";
700 /* If we have a credential to supply, permit CHAP */
701 if ( iscsi->initiator_username )
702 auth_method = "CHAP,None";
703 /* If we have a credential to check, force CHAP */
704 if ( iscsi->target_username )
705 auth_method = "CHAP";
706 used += ssnprintf ( data + used, len - used,
707 "InitiatorName=%s%c"
708 "TargetName=%s%c"
709 "SessionType=Normal%c"
710 "AuthMethod=%s%c",
711 iscsi->initiator_iqn, 0,
712 iscsi->target_iqn, 0, 0,
713 auth_method, 0 );
714 }
715
717 used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
718 }
719
720 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
721 char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
722 assert ( iscsi->initiator_username != NULL );
723 base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
724 buf, sizeof ( buf ) );
725 used += ssnprintf ( data + used, len - used,
726 "CHAP_N=%s%cCHAP_R=0x%s%c",
727 iscsi->initiator_username, 0, buf, 0 );
728 }
729
730 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
731 size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
732 char buf[ base16_encoded_len ( challenge_len ) + 1 ];
733 base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
734 buf, sizeof ( buf ) );
735 used += ssnprintf ( data + used, len - used,
736 "CHAP_I=%d%cCHAP_C=0x%s%c",
737 iscsi->chap_challenge[0], 0, buf, 0 );
738 }
739
741 used += ssnprintf ( data + used, len - used,
742 "HeaderDigest=None%c"
743 "DataDigest=None%c"
744 "MaxConnections=1%c"
745 "InitialR2T=Yes%c"
746 "ImmediateData=No%c"
747 "MaxRecvDataSegmentLength=%d%c"
748 "MaxBurstLength=%d%c"
749 "FirstBurstLength=%d%c"
750 "DefaultTime2Wait=0%c"
751 "DefaultTime2Retain=0%c"
752 "MaxOutstandingR2T=1%c"
753 "DataPDUInOrder=Yes%c"
754 "DataSequenceInOrder=Yes%c"
755 "ErrorRecoveryLevel=0%c",
756 0, 0, 0, 0, 0,
760 0, 0, 0, 0, 0, 0 );
761 }
762
763 return used;
764}
static size_t base16_encoded_len(size_t raw_len)
Calculate length of base16-encoded data.
Definition base16.h:25
#define ISCSI_STATUS_STRINGS_OPERATIONAL
iSCSI session needs to send the operational negotiation strings
Definition iscsi.h:700
#define ISCSI_FIRST_BURST_LEN
Default iSCSI first burst length.
Definition iscsi.h:27
#define ISCSI_STATUS_STRINGS_CHAP_ALGORITHM
iSCSI session needs to send the CHAP_A string
Definition iscsi.h:691
#define ISCSI_STATUS_STRINGS_CHAP_CHALLENGE
iSCSI session needs to send the mutual CHAP challenge
Definition iscsi.h:697
#define ISCSI_STATUS_STRINGS_CHAP_RESPONSE
iSCSI session needs to send the CHAP response
Definition iscsi.h:694
#define ISCSI_MAX_RECV_DATA_SEG_LEN
Default iSCSI maximum receive data segment length.
Definition iscsi.h:33
uint8_t * response
CHAP response.
Definition chap.h:25
size_t response_len
Length of CHAP response.
Definition chap.h:27
unsigned char chap_challenge[17]
CHAP challenge (for target auth only)
Definition iscsi.h:586
int ssnprintf(char *buf, ssize_t ssize, const char *fmt,...)
Version of vsnprintf() that accepts a signed buffer size.
Definition vsprintf.c:421

References assert, base16_encoded_len(), iscsi_session::chap, iscsi_session::chap_challenge, data, iscsi_session::initiator_iqn, iscsi_session::initiator_username, ISCSI_FIRST_BURST_LEN, ISCSI_MAX_BURST_LEN, ISCSI_MAX_RECV_DATA_SEG_LEN, ISCSI_STATUS_STRINGS_CHAP_ALGORITHM, ISCSI_STATUS_STRINGS_CHAP_CHALLENGE, ISCSI_STATUS_STRINGS_CHAP_RESPONSE, ISCSI_STATUS_STRINGS_OPERATIONAL, ISCSI_STATUS_STRINGS_SECURITY, len, NULL, chap_response::response, chap_response::response_len, ssnprintf(), iscsi_session::status, iscsi_session::target_iqn, and iscsi_session::target_username.

Referenced by iscsi_start_login(), and iscsi_tx_login_request().

◆ iscsi_login_request_done()

void iscsi_login_request_done ( struct iscsi_session * iscsi)
static

Complete iSCSI login request PDU transmission.

Parameters
iscsiiSCSI session

Definition at line 813 of file iscsi.c.

813 {
814
815 /* Clear any "strings to send" flags */
817
818 /* Free any dynamically allocated storage used for login */
819 chap_finish ( &iscsi->chap );
820}
#define ISCSI_STATUS_STRINGS_MASK
Mask for all iSCSI "needs to send" flags.
Definition iscsi.h:703

References iscsi_session::chap, chap_finish(), ISCSI_STATUS_STRINGS_MASK, and iscsi_session::status.

Referenced by iscsi_tx_done().

◆ iscsi_tx_login_request()

int iscsi_tx_login_request ( struct iscsi_session * iscsi)
static

Transmit data segment of an iSCSI login request PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

For login requests, the data segment consists of the login strings.

Definition at line 830 of file iscsi.c.

830 {
832 struct io_buffer *iobuf;
833 size_t len;
834 size_t pad_len;
835
836 len = ISCSI_DATA_LEN ( request->lengths );
837 pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
838 iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
839 if ( ! iobuf )
840 return -ENOMEM;
841 iob_put ( iobuf, len );
842 iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
843 memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
844
845 return xfer_deliver_iob ( &iscsi->socket, iobuf );
846}
void * data
Start of data.
Definition iobuf.h:53

References io_buffer::data, ENOMEM, iob_put, iscsi_build_login_request_strings(), ISCSI_DATA_LEN, ISCSI_DATA_PAD_LEN, len, iscsi_bhs::login_request, memset(), pad_len, request, iscsi_session::socket, iscsi_session::tx_bhs, xfer_alloc_iob(), and xfer_deliver_iob().

Referenced by iscsi_tx_data().

◆ iscsi_large_binary_decode()

int iscsi_large_binary_decode ( const char * encoded,
uint8_t * raw,
size_t len )
static

Decode large binary value.

Parameters
encodedEncoded large binary value
rawRaw data
lenLength of data buffer
Return values
lenLength of raw data, or negative error

Definition at line 856 of file iscsi.c.

857 {
858
859 /* Check for initial '0x' or '0b' and decode as appropriate */
860 if ( *(encoded++) == '0' ) {
861 switch ( tolower ( *(encoded++) ) ) {
862 case 'x' :
863 return base16_decode ( encoded, raw, len );
864 case 'b' :
865 return base64_decode ( encoded, raw, len );
866 }
867 }
868
870}
__be32 raw[7]
Definition CIB_PRM.h:0
int base64_decode(const char *encoded, void *data, size_t len)
Base64-decode string.
Definition base64.c:92
static int tolower(int character)
Convert character to lower case.
Definition ctype.h:109
#define EPROTO_INVALID_LARGE_BINARY
Definition iscsi.c:134

References base64_decode(), EPROTO_INVALID_LARGE_BINARY, len, raw, and tolower().

Referenced by iscsi_handle_chap_c_value(), and iscsi_handle_chap_r_value().

◆ iscsi_handle_targetaddress_value()

int iscsi_handle_targetaddress_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI TargetAddress text value.

Parameters
iscsiiSCSI session
valueTargetAddress value
Return values
rcReturn status code

Definition at line 879 of file iscsi.c.

880 {
881 char *separator;
882
883 DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
884
885 /* Replace target address */
886 free ( iscsi->target_address );
887 iscsi->target_address = strdup ( value );
888 if ( ! iscsi->target_address )
889 return -ENOMEM;
890
891 /* Replace target port */
892 iscsi->target_port = htons ( ISCSI_PORT );
893 separator = strchr ( iscsi->target_address, ':' );
894 if ( separator ) {
895 *separator = '\0';
896 iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
897 }
898
899 return 0;
900}
pseudo_bit_t value[0x00020]
Definition arbel.h:2
#define ISCSI_PORT
Default iSCSI port.
Definition iscsi.h:24
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition string.c:485
char * strchr(const char *src, int character)
Find character within a string.
Definition string.c:272
char * strdup(const char *src)
Duplicate string.
Definition string.c:394

References DBGC, ENOMEM, free, htons, ISCSI_PORT, NULL, strchr(), strdup(), strtoul(), iscsi_session::target_address, iscsi_session::target_port, and value.

◆ iscsi_handle_authmethod_value()

int iscsi_handle_authmethod_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI AuthMethod text value.

Parameters
iscsiiSCSI session
valueAuthMethod value
Return values
rcReturn status code

Definition at line 909 of file iscsi.c.

910 {
911
912 /* If server requests CHAP, send the CHAP_A string */
913 if ( strcmp ( value, "CHAP" ) == 0 ) {
914 DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
915 iscsi );
918 }
919
920 return 0;
921}
#define ISCSI_STATUS_AUTH_FORWARD_REQUIRED
Target has requested forward (initiator) authentication.
Definition iscsi.h:706
int strcmp(const char *first, const char *second)
Compare strings.
Definition string.c:174

References DBGC, ISCSI_STATUS_AUTH_FORWARD_REQUIRED, ISCSI_STATUS_STRINGS_CHAP_ALGORITHM, iscsi_session::status, strcmp(), and value.

◆ iscsi_handle_maxburstlength_value()

int iscsi_handle_maxburstlength_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI MaxBurstLength text value.

Parameters
iscsiiSCSI session
valueMaxBurstLength value
Return values
rcReturn status code

Definition at line 930 of file iscsi.c.

931 {
932 unsigned long max_burst_len;
933 char *end;
934
935 /* Update maximum burst length */
936 max_burst_len = strtoul ( value, &end, 0 );
937 if ( *end ) {
938 DBGC ( iscsi, "iSCSI %p invalid MaxBurstLength \"%s\"\n",
939 iscsi, value );
940 return -EINVAL_MAXBURSTLENGTH;
941 }
942 if ( max_burst_len < iscsi->max_burst_len )
943 iscsi->max_burst_len = max_burst_len;
944
945 return 0;
946}
#define EINVAL_MAXBURSTLENGTH
Definition iscsi.c:90
uint32_t end
Ending offset.
Definition netvsc.h:7

References DBGC, EINVAL_MAXBURSTLENGTH, end, iscsi_session::max_burst_len, strtoul(), and value.

◆ iscsi_handle_chap_a_value()

int iscsi_handle_chap_a_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI CHAP_A text value.

Parameters
iscsiiSCSI session
valueCHAP_A value
Return values
rcReturn status code

Definition at line 955 of file iscsi.c.

956 {
957
958 /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
959 * the server responds with anything else it is a protocol
960 * violation.
961 */
962 if ( strcmp ( value, "5" ) != 0 ) {
963 DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
964 iscsi, value );
966 }
967
968 return 0;
969}
#define EPROTO_INVALID_CHAP_ALGORITHM
Definition iscsi.c:126

References DBGC, EPROTO_INVALID_CHAP_ALGORITHM, strcmp(), and value.

◆ iscsi_handle_chap_i_value()

int iscsi_handle_chap_i_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI CHAP_I text value.

Parameters
iscsiiSCSI session
valueCHAP_I value
Return values
rcReturn status code

Definition at line 978 of file iscsi.c.

979 {
980 unsigned int identifier;
981 char *endp;
982 int rc;
983
984 /* The CHAP identifier is an integer value */
985 identifier = strtoul ( value, &endp, 0 );
986 if ( *endp != '\0' ) {
987 DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
988 iscsi, value );
990 }
991
992 /* Prepare for CHAP with MD5 */
993 chap_finish ( &iscsi->chap );
994 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
995 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
996 iscsi, strerror ( rc ) );
997 return rc;
998 }
999
1000 /* Identifier and secret are the first two components of the
1001 * challenge.
1002 */
1003 chap_set_identifier ( &iscsi->chap, identifier );
1004 if ( iscsi->initiator_password ) {
1005 chap_update ( &iscsi->chap, iscsi->initiator_password,
1006 strlen ( iscsi->initiator_password ) );
1007 }
1008
1009 return 0;
1010}
void chap_update(struct chap_response *chap, const void *data, size_t len)
Add data to the CHAP challenge.
Definition chap.c:86
int chap_init(struct chap_response *chap, struct digest_algorithm *digest)
Initialise CHAP challenge/response.
Definition chap.c:52
static void chap_set_identifier(struct chap_response *chap, unsigned int identifier)
Add identifier data to the CHAP challenge.
Definition chap.h:47
#define EPROTO_INVALID_CHAP_IDENTIFIER
Definition iscsi.c:130
struct digest_algorithm md5_algorithm
MD5 algorithm.
Definition md5.c:287
size_t strlen(const char *src)
Get length of string.
Definition string.c:244

References iscsi_session::chap, chap_finish(), chap_init(), chap_set_identifier(), chap_update(), DBGC, EPROTO_INVALID_CHAP_IDENTIFIER, iscsi_session::initiator_password, md5_algorithm, rc, strerror(), strlen(), strtoul(), and value.

◆ iscsi_handle_chap_c_value()

int iscsi_handle_chap_c_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI CHAP_C text value.

Parameters
iscsiiSCSI session
valueCHAP_C value
Return values
rcReturn status code

Definition at line 1019 of file iscsi.c.

1020 {
1021 uint8_t *buf;
1022 unsigned int i;
1023 int len;
1024 int rc;
1025
1026 /* Allocate decoding buffer */
1027 len = strlen ( value ); /* Decoding never expands data */
1028 buf = malloc ( len );
1029 if ( ! buf ) {
1030 rc = -ENOMEM;
1031 goto err_alloc;
1032 }
1033
1034 /* Process challenge */
1036 if ( len < 0 ) {
1037 rc = len;
1038 DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1039 iscsi, value, strerror ( rc ) );
1040 goto err_decode;
1041 }
1042 chap_update ( &iscsi->chap, buf, len );
1043
1044 /* Build CHAP response */
1045 DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1046 chap_respond ( &iscsi->chap );
1048
1049 /* Send CHAP challenge, if applicable */
1050 if ( iscsi->target_username ) {
1052 /* Generate CHAP challenge data */
1053 for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1054 iscsi->chap_challenge[i] = random();
1055 }
1056 }
1057
1058 /* Success */
1059 rc = 0;
1060
1061 err_decode:
1062 free ( buf );
1063 err_alloc:
1064 return rc;
1065}
unsigned char uint8_t
Definition stdint.h:10
void chap_respond(struct chap_response *chap)
Respond to the CHAP challenge.
Definition chap.c:105
static int iscsi_large_binary_decode(const char *encoded, uint8_t *raw, size_t len)
Decode large binary value.
Definition iscsi.c:856

References iscsi_session::chap, iscsi_session::chap_challenge, chap_respond(), chap_update(), DBGC, ENOMEM, free, iscsi_large_binary_decode(), ISCSI_STATUS_STRINGS_CHAP_CHALLENGE, ISCSI_STATUS_STRINGS_CHAP_RESPONSE, len, malloc(), random(), rc, iscsi_session::status, strerror(), strlen(), iscsi_session::target_username, and value.

◆ iscsi_handle_chap_n_value()

int iscsi_handle_chap_n_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI CHAP_N text value.

Parameters
iscsiiSCSI session
valueCHAP_N value
Return values
rcReturn status code

Definition at line 1074 of file iscsi.c.

1075 {
1076
1077 /* The target username isn't actually involved at any point in
1078 * the authentication process; it merely serves to identify
1079 * which password the target is using to generate the CHAP
1080 * response. We unnecessarily verify that the username is as
1081 * expected, in order to provide mildly helpful diagnostics if
1082 * the target is supplying the wrong username/password
1083 * combination.
1084 */
1085 if ( iscsi->target_username &&
1086 ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1087 DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1088 "(wanted \"%s\")\n",
1089 iscsi, value, iscsi->target_username );
1091 }
1092
1093 return 0;
1094}
#define EACCES_INCORRECT_TARGET_USERNAME
Definition iscsi.c:62

References DBGC, EACCES_INCORRECT_TARGET_USERNAME, strcmp(), iscsi_session::target_username, and value.

◆ iscsi_handle_chap_r_value()

int iscsi_handle_chap_r_value ( struct iscsi_session * iscsi,
const char * value )
static

Handle iSCSI CHAP_R text value.

Parameters
iscsiiSCSI session
valueCHAP_R value
Return values
rcReturn status code

Definition at line 1103 of file iscsi.c.

1104 {
1105 uint8_t *buf;
1106 int len;
1107 int rc;
1108
1109 /* Generate CHAP response for verification */
1110 chap_finish ( &iscsi->chap );
1111 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1112 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1113 iscsi, strerror ( rc ) );
1114 goto err_chap_init;
1115 }
1116 chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1117 if ( iscsi->target_password ) {
1118 chap_update ( &iscsi->chap, iscsi->target_password,
1119 strlen ( iscsi->target_password ) );
1120 }
1121 chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1122 ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1123 chap_respond ( &iscsi->chap );
1124
1125 /* Allocate decoding buffer */
1126 len = strlen ( value ); /* Decoding never expands data */
1127 buf = malloc ( len );
1128 if ( ! buf ) {
1129 rc = -ENOMEM;
1130 goto err_alloc;
1131 }
1132
1133 /* Process response */
1135 if ( len < 0 ) {
1136 rc = len;
1137 DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1138 iscsi, value, strerror ( rc ) );
1139 goto err_decode;
1140 }
1141
1142 /* Check CHAP response */
1143 if ( len != ( int ) iscsi->chap.response_len ) {
1144 DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1145 iscsi );
1147 goto err_response_len;
1148 }
1149 if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1150 DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1151 iscsi, value );
1153 goto err_response;
1154 }
1155
1156 /* Mark session as authenticated */
1158
1159 err_response:
1160 err_response_len:
1161 err_decode:
1162 free ( buf );
1163 err_alloc:
1164 err_chap_init:
1165 return rc;
1166}
#define EACCES_INCORRECT_TARGET_PASSWORD
Definition iscsi.c:66
#define EPROTO_INVALID_CHAP_RESPONSE
Definition iscsi.c:138
#define ISCSI_STATUS_AUTH_REVERSE_OK
Target authenticated itself correctly.
Definition iscsi.h:712
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition string.c:115

References iscsi_session::chap, iscsi_session::chap_challenge, chap_finish(), chap_init(), chap_respond(), chap_set_identifier(), chap_update(), DBGC, EACCES_INCORRECT_TARGET_PASSWORD, ENOMEM, EPROTO_INVALID_CHAP_RESPONSE, free, iscsi_large_binary_decode(), ISCSI_STATUS_AUTH_REVERSE_OK, len, malloc(), md5_algorithm, memcmp(), rc, chap_response::response, chap_response::response_len, iscsi_session::status, strerror(), strlen(), iscsi_session::target_password, and value.

◆ iscsi_handle_string()

int iscsi_handle_string ( struct iscsi_session * iscsi,
const char * string )
static

Handle iSCSI string.

Parameters
iscsiiSCSI session
stringiSCSI string (in "key=value" format)
Return values
rcReturn status code

Definition at line 1205 of file iscsi.c.

1206 {
1207 struct iscsi_string_type *type;
1208 const char *separator;
1209 const char *value;
1210 size_t key_len;
1211 int rc;
1212
1213 /* Find separator */
1214 separator = strchr ( string, '=' );
1215 if ( ! separator ) {
1216 DBGC ( iscsi, "iSCSI %p malformed string %s\n",
1217 iscsi, string );
1219 }
1220 key_len = ( separator - string );
1221 value = ( separator + 1 );
1222
1223 /* Check for rejections. Since we send only non-rejectable
1224 * values, any rejection is a fatal protocol error.
1225 */
1226 if ( strcmp ( value, "Reject" ) == 0 ) {
1227 DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string );
1228 return -EPROTO_VALUE_REJECTED;
1229 }
1230
1231 /* Handle key/value pair */
1232 for ( type = iscsi_string_types ; type->key ; type++ ) {
1233 if ( strncmp ( string, type->key, key_len ) != 0 )
1234 continue;
1235 DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
1236 if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) {
1237 DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
1238 iscsi, string, strerror ( rc ) );
1239 return rc;
1240 }
1241 return 0;
1242 }
1243 DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
1244 return 0;
1245}
uint32_t type
Operating system type.
Definition ena.h:1
#define EPROTO_VALUE_REJECTED
Definition iscsi.c:146
static struct iscsi_string_type iscsi_string_types[]
iSCSI text strings that we want to handle
Definition iscsi.c:1186
#define EPROTO_INVALID_KEY_VALUE_PAIR
Definition iscsi.c:142
uint32_t string
Definition multiboot.h:2
int strncmp(const char *first, const char *second, size_t max)
Compare strings.
Definition string.c:187
An iSCSI text string that we want to handle.
Definition iscsi.c:1169

References DBGC, EPROTO_INVALID_KEY_VALUE_PAIR, EPROTO_VALUE_REJECTED, iscsi_string_types, rc, strchr(), strcmp(), strerror(), string, strncmp(), type, and value.

Referenced by iscsi_handle_strings().

◆ iscsi_handle_strings()

int iscsi_handle_strings ( struct iscsi_session * iscsi,
const char * strings,
size_t len )
static

Handle iSCSI strings.

Parameters
iscsiiSCSI session
stringiSCSI string buffer
lenLength of string buffer
Return values
rcReturn status code

Definition at line 1255 of file iscsi.c.

1256 {
1257 size_t string_len;
1258 int rc;
1259
1260 /* Handle each string in turn, taking care not to overrun the
1261 * data buffer in case of badly-terminated data.
1262 */
1263 while ( 1 ) {
1264 string_len = ( strnlen ( strings, len ) + 1 );
1265 if ( string_len > len )
1266 break;
1267 if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1268 return rc;
1269 strings += string_len;
1270 len -= string_len;
1271 }
1272 return 0;
1273}
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
Definition iscsi.c:1205
size_t strnlen(const char *src, size_t max)
Get length of string.
Definition string.c:256

References iscsi_handle_string(), len, rc, and strnlen().

Referenced by iscsi_rx_login_response().

◆ iscsi_status_to_rc()

int iscsi_status_to_rc ( unsigned int status_class,
unsigned int status_detail )
static

Convert iSCSI response status to return status code.

Parameters
status_classiSCSI status class
status_detailiSCSI status detail
Return values
rcReturn status code

Definition at line 1282 of file iscsi.c.

1283 {
1284 switch ( status_class ) {
1286 switch ( status_detail ) {
1293 return -ENODEV;
1294 default :
1296 }
1298 switch ( status_detail ) {
1300 return -EIO_TARGET_UNAVAILABLE;
1303 default:
1304 return -ENOTSUP_TARGET_STATUS;
1305 }
1306 default :
1307 return -EINVAL;
1308 }
1309}
#define EINVAL
Invalid argument.
Definition errno.h:429
#define ENODEV
No such device.
Definition errno.h:510
#define ENOTSUP_TARGET_STATUS
Definition iscsi.c:114
#define EPERM_INITIATOR_AUTHORISATION
Definition iscsi.c:122
#define EIO_TARGET_NO_RESOURCES
Definition iscsi.c:98
#define ENOTSUP_INITIATOR_STATUS
Definition iscsi.c:102
#define EPERM_INITIATOR_AUTHENTICATION
Definition iscsi.c:118
#define EIO_TARGET_UNAVAILABLE
Definition iscsi.c:94
#define ISCSI_STATUS_TARGET_ERROR
Definition iscsi.h:254
#define ISCSI_STATUS_INITIATOR_ERROR
Definition iscsi.h:249
#define ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE
Definition iscsi.h:255
#define ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND
Definition iscsi.h:252
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION
Definition iscsi.h:250
#define ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES
Definition iscsi.h:256
#define ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION
Definition iscsi.h:251
#define ISCSI_STATUS_INITIATOR_ERROR_REMOVED
Definition iscsi.h:253

References EINVAL, EIO_TARGET_NO_RESOURCES, EIO_TARGET_UNAVAILABLE, ENODEV, ENOTSUP_INITIATOR_STATUS, ENOTSUP_TARGET_STATUS, EPERM_INITIATOR_AUTHENTICATION, EPERM_INITIATOR_AUTHORISATION, ISCSI_STATUS_INITIATOR_ERROR, ISCSI_STATUS_INITIATOR_ERROR_AUTHENTICATION, ISCSI_STATUS_INITIATOR_ERROR_AUTHORISATION, ISCSI_STATUS_INITIATOR_ERROR_NOT_FOUND, ISCSI_STATUS_INITIATOR_ERROR_REMOVED, ISCSI_STATUS_TARGET_ERROR, ISCSI_STATUS_TARGET_ERROR_NO_RESOURCES, and ISCSI_STATUS_TARGET_ERROR_UNAVAILABLE.

Referenced by iscsi_rx_login_response().

◆ iscsi_rx_login_response()

int iscsi_rx_login_response ( struct iscsi_session * iscsi,
const void * data,
size_t len,
size_t remaining )
static

Receive data segment of an iSCSI login response PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Definition at line 1320 of file iscsi.c.

1322 {
1323 struct iscsi_bhs_login_response *response
1324 = &iscsi->rx_bhs.login_response;
1325 int rc;
1326
1327 /* Buffer up the PDU data */
1328 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1329 DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1330 iscsi, strerror ( rc ) );
1331 return rc;
1332 }
1333 if ( remaining )
1334 return 0;
1335
1336 /* Process string data and discard string buffer */
1337 if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1338 iscsi->rx_len ) ) != 0 )
1339 return rc;
1341
1342 /* Check for login redirection */
1343 if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1344 DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1345 iscsi_close_connection ( iscsi, 0 );
1346 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1347 DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1348 iscsi, strerror ( rc ) );
1349 return rc;
1350 }
1351 return 0;
1352 }
1353
1354 /* Check for fatal errors */
1355 if ( response->status_class != 0 ) {
1356 DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1357 response->status_class, response->status_detail );
1358 rc = iscsi_status_to_rc ( response->status_class,
1359 response->status_detail );
1360 return rc;
1361 }
1362
1363 /* Handle login transitions */
1364 if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1365 iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1367 switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1369 iscsi->status |=
1372 break;
1375 break;
1376 default:
1377 DBGC ( iscsi, "iSCSI %p got invalid response flags "
1378 "%02x\n", iscsi, response->flags );
1379 return -EIO;
1380 }
1381 }
1382
1383 /* Send next login request PDU if we haven't reached the full
1384 * feature phase yet.
1385 */
1386 if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1388 iscsi_start_login ( iscsi );
1389 return 0;
1390 }
1391
1392 /* Check that target authentication was successful (if required) */
1393 if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1394 ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1395 DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1396 "authentication\n", iscsi );
1397 return -EPROTO;
1398 }
1399
1400 /* Notify SCSI layer of window change */
1401 DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi );
1402 xfer_window_changed ( &iscsi->control );
1403
1404 return 0;
1405}
#define EPROTO
Protocol error.
Definition errno.h:625
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
Definition iscsi.c:1255
static int iscsi_status_to_rc(unsigned int status_class, unsigned int status_detail)
Convert iSCSI response status to return status code.
Definition iscsi.c:1282
static int iscsi_open_connection(struct iscsi_session *iscsi)
Open iSCSI transport-layer connection.
Definition iscsi.c:257
static void iscsi_close_connection(struct iscsi_session *iscsi, int rc)
Close iSCSI transport-layer connection.
Definition iscsi.c:307
#define ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE
iSCSI session is currently in the operational parameter negotiation phase
Definition iscsi.h:677
#define ISCSI_STATUS_FULL_FEATURE_PHASE
iSCSI session is currently in the full feature phase
Definition iscsi.h:682
#define ISCSI_LOGIN_NSG_MASK
Definition iscsi.h:189
#define ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE
Definition iscsi.h:192
#define ISCSI_STATUS_REDIRECT
Definition iscsi.h:248
#define ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION
Definition iscsi.h:191
iSCSI login response basic header segment
Definition iscsi.h:208
uint8_t status_detail
Status detail.
Definition iscsi.h:238
uint8_t status_class
Status class.
Definition iscsi.h:236
uint8_t flags
Flags.
Definition iscsi.h:212
struct iscsi_bhs_login_response login_response
Definition iscsi.h:510
void xfer_window_changed(struct interface *intf)
Report change of flow control window.
Definition xfer.c:147

References iscsi_session::control, data, DBGC, EIO, EPROTO, iscsi_bhs_login_response::flags, iscsi_close_connection(), iscsi_handle_strings(), ISCSI_LOGIN_FLAG_TRANSITION, ISCSI_LOGIN_NSG_FULL_FEATURE_PHASE, ISCSI_LOGIN_NSG_MASK, ISCSI_LOGIN_NSG_OPERATIONAL_NEGOTIATION, iscsi_open_connection(), iscsi_rx_buffered_data(), iscsi_rx_buffered_data_done(), iscsi_start_login(), ISCSI_STATUS_AUTH_REVERSE_OK, ISCSI_STATUS_AUTH_REVERSE_REQUIRED, ISCSI_STATUS_FULL_FEATURE_PHASE, ISCSI_STATUS_OPERATIONAL_NEGOTIATION_PHASE, ISCSI_STATUS_PHASE_MASK, ISCSI_STATUS_REDIRECT, ISCSI_STATUS_STRINGS_MASK, ISCSI_STATUS_STRINGS_OPERATIONAL, iscsi_status_to_rc(), len, iscsi_bhs::login_response, rc, iscsi_session::rx_bhs, iscsi_session::rx_buffer, iscsi_session::rx_len, iscsi_session::status, iscsi_bhs_login_response::status_class, iscsi_bhs_login_response::status_detail, strerror(), and xfer_window_changed().

Referenced by iscsi_rx_data().

◆ iscsi_tx_pause()

void iscsi_tx_pause ( struct iscsi_session * iscsi)
static

Pause TX engine.

Parameters
iscsiiSCSI session

Definition at line 1418 of file iscsi.c.

1418 {
1419 process_del ( &iscsi->process );
1420}

References iscsi_session::process, and process_del().

Referenced by iscsi_tx_done(), and iscsi_tx_step().

◆ iscsi_tx_resume()

void iscsi_tx_resume ( struct iscsi_session * iscsi)
static

Resume TX engine.

Parameters
iscsiiSCSI session

Definition at line 1427 of file iscsi.c.

1427 {
1428 process_add ( &iscsi->process );
1429}
void process_add(struct process *process)
Add process to process list.
Definition process.c:60

References iscsi_session::process, and process_add().

Referenced by iscsi_start_tx().

◆ iscsi_tx_nothing()

int iscsi_tx_nothing ( struct iscsi_session *iscsi __unused)
static

Transmit nothing.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1459 of file iscsi.c.

1459 {
1460 return 0;
1461}

References __unused.

Referenced by iscsi_tx_step().

◆ iscsi_tx_bhs()

int iscsi_tx_bhs ( struct iscsi_session * iscsi)
static

Transmit basic header segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 1469 of file iscsi.c.

1469 {
1470 return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs,
1471 sizeof ( iscsi->tx_bhs ) );
1472}
int xfer_deliver_raw(struct interface *intf, const void *data, size_t len)
Deliver datagram as raw data without metadata.
Definition xfer.c:289

References iscsi_session::socket, iscsi_session::tx_bhs, and xfer_deliver_raw().

Referenced by iscsi_tx_step().

◆ iscsi_tx_data()

int iscsi_tx_data ( struct iscsi_session * iscsi)
static

Transmit data segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Handle transmission of part of a PDU data segment. iscsi::tx_bhs will be valid when this is called.

Definition at line 1483 of file iscsi.c.

1483 {
1484 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1485
1486 switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1488 return iscsi_tx_data_out ( iscsi );
1490 return iscsi_tx_login_request ( iscsi );
1491 default:
1492 /* Nothing to send in other states */
1493 return 0;
1494 }
1495}
struct ib_cm_common common
Definition ib_mad.h:0
static int iscsi_tx_login_request(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI login request PDU.
Definition iscsi.c:830
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
Definition iscsi.c:582
#define ISCSI_OPCODE_MASK
Opcode mask.
Definition iscsi.h:97
iSCSI basic header segment common fields
Definition iscsi.h:79
struct iscsi_bhs_common common
Definition iscsi.h:507

References common, iscsi_bhs::common, ISCSI_OPCODE_DATA_OUT, ISCSI_OPCODE_LOGIN_REQUEST, ISCSI_OPCODE_MASK, iscsi_tx_data_out(), iscsi_tx_login_request(), and iscsi_session::tx_bhs.

Referenced by iscsi_tx_step().

◆ iscsi_tx_done()

void iscsi_tx_done ( struct iscsi_session * iscsi)
static

Complete iSCSI PDU transmission.

Parameters
iscsiiSCSI session

Called when a PDU has been completely transmitted and the TX state machine is about to enter the idle state. iscsi::tx_bhs will be valid for the just-completed PDU when this is called.

Definition at line 1506 of file iscsi.c.

1506 {
1507 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1508
1509 /* Stop transmission process */
1510 iscsi_tx_pause ( iscsi );
1511
1512 switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1514 iscsi_data_out_done ( iscsi );
1515 break;
1517 iscsi_login_request_done ( iscsi );
1518 break;
1519 default:
1520 /* No action */
1521 break;
1522 }
1523}
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition iscsi.c:1418
static void iscsi_login_request_done(struct iscsi_session *iscsi)
Complete iSCSI login request PDU transmission.
Definition iscsi.c:813
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
Definition iscsi.c:566

References common, iscsi_bhs::common, iscsi_data_out_done(), iscsi_login_request_done(), ISCSI_OPCODE_DATA_OUT, ISCSI_OPCODE_LOGIN_REQUEST, ISCSI_OPCODE_MASK, iscsi_tx_pause(), and iscsi_session::tx_bhs.

Referenced by iscsi_tx_step().

◆ iscsi_tx_step()

void iscsi_tx_step ( struct iscsi_session * iscsi)
static

Transmit iSCSI PDU.

Parameters
iscsiiSCSI session
bufTemporary data buffer
lenLength of temporary data buffer

Constructs data to be sent for the current TX state

Definition at line 1534 of file iscsi.c.

1534 {
1535 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1536 int ( * tx ) ( struct iscsi_session *iscsi );
1537 enum iscsi_tx_state next_state;
1538 size_t tx_len;
1539 int rc;
1540
1541 /* Select fragment to transmit */
1542 while ( 1 ) {
1543 switch ( iscsi->tx_state ) {
1544 case ISCSI_TX_BHS:
1545 tx = iscsi_tx_bhs;
1546 tx_len = sizeof ( iscsi->tx_bhs );
1547 next_state = ISCSI_TX_AHS;
1548 break;
1549 case ISCSI_TX_AHS:
1551 tx_len = 0;
1552 next_state = ISCSI_TX_DATA;
1553 break;
1554 case ISCSI_TX_DATA:
1555 tx = iscsi_tx_data;
1556 tx_len = ISCSI_DATA_LEN ( common->lengths );
1557 next_state = ISCSI_TX_IDLE;
1558 break;
1559 case ISCSI_TX_IDLE:
1560 /* Nothing to do; pause processing */
1561 iscsi_tx_pause ( iscsi );
1562 return;
1563 default:
1564 assert ( 0 );
1565 return;
1566 }
1567
1568 /* Check for window availability, if needed */
1569 if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1570 /* Cannot transmit at this point; pause
1571 * processing and wait for window to reopen
1572 */
1573 iscsi_tx_pause ( iscsi );
1574 return;
1575 }
1576
1577 /* Transmit data */
1578 if ( ( rc = tx ( iscsi ) ) != 0 ) {
1579 DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1580 iscsi, strerror ( rc ) );
1581 /* Transmission errors are fatal */
1582 iscsi_close ( iscsi, rc );
1583 return;
1584 }
1585
1586 /* Move to next state */
1587 iscsi->tx_state = next_state;
1588
1589 /* If we have moved to the idle state, mark
1590 * transmission as complete
1591 */
1592 if ( iscsi->tx_state == ISCSI_TX_IDLE )
1593 iscsi_tx_done ( iscsi );
1594 }
1595}
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
Definition iscsi.c:1459
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
Definition iscsi.c:1469
static void iscsi_tx_done(struct iscsi_session *iscsi)
Complete iSCSI PDU transmission.
Definition iscsi.c:1506
static void iscsi_close(struct iscsi_session *iscsi, int rc)
Shut down iSCSI interface.
Definition iscsi.c:224
static int iscsi_tx_data(struct iscsi_session *iscsi)
Transmit data segment of an iSCSI PDU.
Definition iscsi.c:1483
iscsi_tx_state
State of an iSCSI TX engine.
Definition iscsi.h:521
@ ISCSI_TX_AHS
Sending the additional header segment.
Definition iscsi.h:527
@ ISCSI_TX_DATA
Sending the data segment.
Definition iscsi.h:529
u8 tx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets to the AP.
Definition wpa.h:4
size_t xfer_window(struct interface *intf)
Check flow control window.
Definition xfer.c:117

References assert, common, iscsi_bhs::common, DBGC, iscsi_close(), ISCSI_DATA_LEN, ISCSI_TX_AHS, ISCSI_TX_BHS, iscsi_tx_bhs(), ISCSI_TX_DATA, iscsi_tx_data(), iscsi_tx_done(), ISCSI_TX_IDLE, iscsi_tx_nothing(), iscsi_tx_pause(), rc, iscsi_session::socket, strerror(), tx, iscsi_session::tx_bhs, iscsi_session::tx_state, and xfer_window().

◆ iscsi_rx_bhs()

int iscsi_rx_bhs ( struct iscsi_session * iscsi,
const void * data,
size_t len,
size_t remaining __unused )
static

Receive basic header segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

This fills in iscsi::rx_bhs with the data from the BHS portion of the received PDU.

Definition at line 1613 of file iscsi.c.

1614 {
1615 memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1616 if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1617 DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1618 iscsi, iscsi->rx_bhs.common.opcode,
1619 ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1620 }
1621 return 0;
1622}
uint8_t opcode
Opcode.
Definition iscsi.h:81
union iscsi_segment_lengths lengths
Segment lengths.
Definition iscsi.h:87
unsigned char bytes[sizeof(struct iscsi_bhs_common)]
Definition iscsi.h:517

References __unused, iscsi_bhs::bytes, iscsi_bhs::common, data, DBGC2, ISCSI_DATA_LEN, len, iscsi_bhs_common::lengths, memcpy(), iscsi_bhs_common::opcode, iscsi_session::rx_bhs, and iscsi_session::rx_offset.

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_discard()

int iscsi_rx_discard ( struct iscsi_session *iscsi __unused,
const void *data __unused,
size_t len __unused,
size_t remaining __unused )
static

Discard portion of an iSCSI PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

This discards data from a portion of a received PDU.

Definition at line 1635 of file iscsi.c.

1637 {
1638 /* Do nothing */
1639 return 0;
1640}

References __unused, data, and len.

Referenced by iscsi_socket_deliver().

◆ iscsi_rx_data()

int iscsi_rx_data ( struct iscsi_session * iscsi,
const void * data,
size_t len,
size_t remaining )
static

Receive data segment of an iSCSI PDU.

Parameters
iscsiiSCSI session
dataReceived data
lenLength of received data
remainingData remaining after this data
Return values
rcReturn status code

Handle processing of part of a PDU data segment. iscsi::rx_bhs will be valid when this is called.

Definition at line 1654 of file iscsi.c.

1655 {
1656 struct iscsi_bhs_common_response *response
1657 = &iscsi->rx_bhs.common_response;
1658
1659 /* Update cmdsn and statsn */
1660 iscsi->cmdsn = ntohl ( response->expcmdsn );
1661 iscsi->statsn = ntohl ( response->statsn );
1662
1663 switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1665 return iscsi_rx_login_response ( iscsi, data, len, remaining );
1667 return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1669 return iscsi_rx_data_in ( iscsi, data, len, remaining );
1670 case ISCSI_OPCODE_R2T:
1671 return iscsi_rx_r2t ( iscsi, data, len, remaining );
1673 return iscsi_rx_nop_in ( iscsi, data, len, remaining );
1674 default:
1675 if ( remaining )
1676 return 0;
1677 DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1678 response->opcode );
1679 return -ENOTSUP_OPCODE;
1680 }
1681}
static int iscsi_rx_scsi_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI SCSI response PDU.
Definition iscsi.c:417
static int iscsi_rx_data_in(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI data-in PDU.
Definition iscsi.c:470
static int iscsi_rx_login_response(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI login response PDU.
Definition iscsi.c:1320
static int iscsi_rx_r2t(struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
Receive data segment of an iSCSI R2T PDU.
Definition iscsi.c:507
static int iscsi_rx_nop_in(struct iscsi_session *iscsi, const void *data __unused, size_t len __unused, size_t remaining __unused)
Receive data segment of an iSCSI NOP-In.
Definition iscsi.c:617
#define ENOTSUP_OPCODE
Definition iscsi.c:106
#define ISCSI_OPCODE_LOGIN_RESPONSE
Login response opcode.
Definition iscsi.h:244
#define ISCSI_OPCODE_DATA_IN
Data-in opcode.
Definition iscsi.h:387
#define ISCSI_OPCODE_R2T
R2T opcode.
Definition iscsi.h:471
#define ISCSI_OPCODE_NOP_IN
NOP-In opcode.
Definition iscsi.h:501
#define ISCSI_OPCODE_SCSI_RESPONSE
SCSI response opcode.
Definition iscsi.h:337
iSCSI basic header segment common request fields
Definition iscsi.h:115
uint32_t expcmdsn
Expected command sequence number.
Definition iscsi.h:133
uint8_t opcode
Opcode.
Definition iscsi.h:117
uint32_t statsn
Status sequence number.
Definition iscsi.h:131
struct iscsi_bhs_common_response common_response
Definition iscsi.h:508

References iscsi_session::cmdsn, iscsi_bhs::common_response, data, DBGC, ENOTSUP_OPCODE, iscsi_bhs_common_response::expcmdsn, ISCSI_OPCODE_DATA_IN, ISCSI_OPCODE_LOGIN_RESPONSE, ISCSI_OPCODE_MASK, ISCSI_OPCODE_NOP_IN, ISCSI_OPCODE_R2T, ISCSI_OPCODE_SCSI_RESPONSE, iscsi_rx_data_in(), iscsi_rx_login_response(), iscsi_rx_nop_in(), iscsi_rx_r2t(), iscsi_rx_scsi_response(), len, ntohl, iscsi_bhs_common_response::opcode, iscsi_session::rx_bhs, iscsi_bhs_common_response::statsn, and iscsi_session::statsn.

Referenced by iscsi_socket_deliver().

◆ iscsi_socket_deliver()

int iscsi_socket_deliver ( struct iscsi_session * iscsi,
struct io_buffer * iobuf,
struct xfer_metadata *meta __unused )
static

Receive new data.

Parameters
iscsiiSCSI session
iobufI/O buffer
metaData transfer metadata
Return values
rcReturn status code

This handles received PDUs. The receive strategy is to fill in iscsi::rx_bhs with the contents of the BHS portion of the PDU, throw away any AHS portion, and then process each part of the data portion as it arrives. The data processing routine therefore always has a full copy of the BHS available, even for portions of the data in different packets to the BHS.

Definition at line 1698 of file iscsi.c.

1700 {
1701 struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1702 int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1703 size_t len, size_t remaining );
1704 enum iscsi_rx_state next_state;
1705 size_t frag_len;
1706 size_t remaining;
1707 int rc;
1708
1709 while ( 1 ) {
1710 switch ( iscsi->rx_state ) {
1711 case ISCSI_RX_BHS:
1712 rx = iscsi_rx_bhs;
1713 iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1714 next_state = ISCSI_RX_AHS;
1715 break;
1716 case ISCSI_RX_AHS:
1718 iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1719 next_state = ISCSI_RX_DATA;
1720 break;
1721 case ISCSI_RX_DATA:
1722 rx = iscsi_rx_data;
1723 iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1724 next_state = ISCSI_RX_DATA_PADDING;
1725 break;
1728 iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1729 next_state = ISCSI_RX_BHS;
1730 break;
1731 default:
1732 assert ( 0 );
1733 rc = -EINVAL;
1734 goto done;
1735 }
1736
1737 frag_len = iscsi->rx_len - iscsi->rx_offset;
1738 if ( frag_len > iob_len ( iobuf ) )
1739 frag_len = iob_len ( iobuf );
1740 remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1741 if ( ( rc = rx ( iscsi, iobuf->data, frag_len,
1742 remaining ) ) != 0 ) {
1743 DBGC ( iscsi, "iSCSI %p could not process received "
1744 "data: %s\n", iscsi, strerror ( rc ) );
1745 goto done;
1746 }
1747
1748 iscsi->rx_offset += frag_len;
1749 iob_pull ( iobuf, frag_len );
1750
1751 /* If all the data for this state has not yet been
1752 * received, stay in this state for now.
1753 */
1754 if ( iscsi->rx_offset != iscsi->rx_len ) {
1755 rc = 0;
1756 goto done;
1757 }
1758
1759 iscsi->rx_state = next_state;
1760 iscsi->rx_offset = 0;
1761 }
1762
1763 done:
1764 /* Free I/O buffer */
1765 free_iob ( iobuf );
1766
1767 /* Destroy session on error */
1768 if ( rc != 0 )
1769 iscsi_close ( iscsi, rc );
1770
1771 return rc;
1772}
struct bofm_section_header done
Definition bofm_test.c:46
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:160
#define iob_pull(iobuf, len)
Definition iobuf.h:107
static int iscsi_rx_data(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining)
Receive data segment of an iSCSI PDU.
Definition iscsi.c:1654
static int iscsi_rx_discard(struct iscsi_session *iscsi __unused, const void *data __unused, size_t len __unused, size_t remaining __unused)
Discard portion of an iSCSI PDU.
Definition iscsi.c:1635
static int iscsi_rx_bhs(struct iscsi_session *iscsi, const void *data, size_t len, size_t remaining __unused)
Receive basic header segment of an iSCSI PDU.
Definition iscsi.c:1613
#define ISCSI_AHS_LEN(segment_lengths)
The length of the additional header segment, in dwords.
Definition iscsi.h:58
iscsi_rx_state
State of an iSCSI RX engine.
Definition iscsi.h:533
@ ISCSI_RX_AHS
Receiving the additional header segment.
Definition iscsi.h:537
@ ISCSI_RX_DATA
Receiving the data segment.
Definition iscsi.h:539
@ ISCSI_RX_DATA_PADDING
Receiving the data segment padding.
Definition iscsi.h:541
u8 rx[WPA_TKIP_MIC_KEY_LEN]
MIC key for packets from the AP.
Definition wpa.h:1

References __unused, assert, common, iscsi_bhs::common, data, io_buffer::data, DBGC, done, EINVAL, free_iob(), iob_len(), iob_pull, ISCSI_AHS_LEN, iscsi_close(), ISCSI_DATA_LEN, ISCSI_DATA_PAD_LEN, ISCSI_RX_AHS, ISCSI_RX_BHS, iscsi_rx_bhs(), ISCSI_RX_DATA, iscsi_rx_data(), ISCSI_RX_DATA_PADDING, iscsi_rx_discard(), len, meta, rc, rx, iscsi_session::rx_bhs, iscsi_session::rx_len, iscsi_session::rx_offset, iscsi_session::rx_state, and strerror().

◆ iscsi_vredirect()

int iscsi_vredirect ( struct iscsi_session * iscsi,
int type,
va_list args )
static

Handle redirection event.

Parameters
iscsiiSCSI session
typeLocation type
argsRemaining arguments depend upon location type
Return values
rcReturn status code

Definition at line 1782 of file iscsi.c.

1783 {
1784 va_list tmp;
1785 struct sockaddr *peer;
1786 int rc;
1787
1788 /* Intercept redirects to a LOCATION_SOCKET and record the IP
1789 * address for the iBFT. This is a bit of a hack, but avoids
1790 * inventing an ioctl()-style call to retrieve the socket
1791 * address from a data-xfer interface.
1792 */
1793 if ( type == LOCATION_SOCKET ) {
1794 va_copy ( tmp, args );
1795 ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1796 peer = va_arg ( tmp, struct sockaddr * );
1797 memcpy ( &iscsi->target_sockaddr, peer,
1798 sizeof ( iscsi->target_sockaddr ) );
1799 va_end ( tmp );
1800 }
1801
1802 /* Redirect to new location */
1803 if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 )
1804 goto err;
1805
1806 return 0;
1807
1808 err:
1809 iscsi_close ( iscsi, rc );
1810 return rc;
1811}
unsigned long tmp
Definition linux_pci.h:65
struct mschapv2_challenge peer
Peer challenge.
Definition mschapv2.h:1
int xfer_vreopen(struct interface *intf, int type, va_list args)
Reopen location.
Definition open.c:225
@ LOCATION_SOCKET
Location is a socket.
Definition open.h:44
#define va_copy(dest, src)
Definition stdarg.h:11
#define va_arg(ap, type)
Definition stdarg.h:9
#define va_end(ap)
Definition stdarg.h:10
__builtin_va_list va_list
Definition stdarg.h:7
struct sockaddr target_sockaddr
Target socket address (for boot firmware table)
Definition iscsi.h:662

References iscsi_close(), LOCATION_SOCKET, memcpy(), peer, rc, iscsi_session::socket, iscsi_session::target_sockaddr, tmp, type, va_arg, va_copy, va_end, and xfer_vreopen().

◆ iscsi_scsi_window()

size_t iscsi_scsi_window ( struct iscsi_session * iscsi)
static

Check iSCSI flow-control window.

Parameters
iscsiiSCSI session
Return values
lenLength of window

Definition at line 1838 of file iscsi.c.

1838 {
1839
1840 if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) ==
1842 ( iscsi->command == NULL ) ) {
1843 /* We cannot handle concurrent commands */
1844 return 1;
1845 } else {
1846 return 0;
1847 }
1848}

References iscsi_session::command, ISCSI_STATUS_FULL_FEATURE_PHASE, ISCSI_STATUS_PHASE_MASK, NULL, and iscsi_session::status.

Referenced by iscsi_scsi_command().

◆ iscsi_scsi_command()

int iscsi_scsi_command ( struct iscsi_session * iscsi,
struct interface * parent,
struct scsi_cmd * command )
static

Issue iSCSI SCSI command.

Parameters
iscsiiSCSI session
parentParent interface
commandSCSI command
Return values
tagCommand tag, or negative error

Definition at line 1858 of file iscsi.c.

1860 {
1861
1862 /* This iSCSI implementation cannot handle multiple concurrent
1863 * commands or commands arriving before login is complete.
1864 */
1865 if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1866 DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1867 iscsi );
1868 return -EOPNOTSUPP;
1869 }
1870
1871 /* Store command */
1872 iscsi->command = malloc ( sizeof ( *command ) );
1873 if ( ! iscsi->command )
1874 return -ENOMEM;
1875 memcpy ( iscsi->command, command, sizeof ( *command ) );
1876
1877 /* Assign new ITT */
1878 iscsi_new_itt ( iscsi );
1879
1880 /* Start sending command */
1881 iscsi_start_command ( iscsi );
1882
1883 /* Attach to parent interface and return */
1884 intf_plug_plug ( &iscsi->data, parent );
1885 return iscsi->itt;
1886}
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:605
void intf_plug_plug(struct interface *a, struct interface *b)
Plug two object interfaces together.
Definition interface.c:108
static size_t iscsi_scsi_window(struct iscsi_session *iscsi)
Check iSCSI flow-control window.
Definition iscsi.c:1838
static void iscsi_start_command(struct iscsi_session *iscsi)
Build iSCSI SCSI command BHS.
Definition iscsi.c:377

References iscsi_session::command, iscsi_session::data, DBGC, ENOMEM, EOPNOTSUPP, intf_plug_plug(), iscsi_new_itt(), iscsi_scsi_window(), iscsi_start_command(), iscsi_session::itt, malloc(), and memcpy().

◆ iscsi_scsi_capacity()

void iscsi_scsi_capacity ( struct iscsi_session * iscsi,
struct block_device_capacity * capacity )
static

Update SCSI block device capacity.

Parameters
iscsiiSCSI session
capacityBlock device capacity

Definition at line 1894 of file iscsi.c.

1895 {
1896 unsigned int max_count;
1897
1898 /* Limit maximum number of blocks per transfer to fit MaxBurstLength */
1899 if ( capacity->blksize ) {
1900 max_count = ( iscsi->max_burst_len / capacity->blksize );
1901 if ( max_count < capacity->max_count )
1902 capacity->max_count = max_count;
1903 }
1904}
unsigned int max_count
Maximum number of blocks per single transfer.
Definition blockdev.h:24
size_t blksize
Block size.
Definition blockdev.h:22

References block_device_capacity::blksize, iscsi_session::max_burst_len, and block_device_capacity::max_count.

◆ iscsi_describe()

struct acpi_descriptor * iscsi_describe ( struct iscsi_session * iscsi)
static

Get iSCSI ACPI descriptor.

Parameters
iscsiiSCSI session
Return values
descACPI descriptor

Definition at line 1912 of file iscsi.c.

1912 {
1913
1914 return &iscsi->desc;
1915}
struct acpi_descriptor desc
ACPI descriptor.
Definition iscsi.h:666

References iscsi_session::desc.

◆ iscsi_command_close()

void iscsi_command_close ( struct iscsi_session * iscsi,
int rc )
static

Close iSCSI command.

Parameters
iscsiiSCSI session
rcReason for close

Definition at line 1937 of file iscsi.c.

1937 {
1938
1939 /* Restart interface */
1940 intf_restart ( &iscsi->data, rc );
1941
1942 /* Treat unsolicited command closures mid-command as fatal,
1943 * because we have no code to handle partially-completed PDUs.
1944 */
1945 if ( iscsi->command != NULL )
1946 iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1947}
#define ECANCELED
Operation canceled.
Definition errno.h:344

References iscsi_session::command, iscsi_session::data, ECANCELED, intf_restart(), iscsi_close(), NULL, and rc.

◆ __setting() [1/2]

const struct setting initiator_iqn_setting __setting ( SETTING_SANBOOT_EXTRA ,
initiator- iqn )

iSCSI initiator IQN setting

References __setting, DHCP_ISCSI_INITIATOR_IQN, and SETTING_SANBOOT_EXTRA.

◆ __setting() [2/2]

const struct setting reverse_password_setting __setting ( SETTING_AUTH_EXTRA ,
reverse- username )
Initial value:
= {
.name = "reverse-password",
.description = "Reverse password",
.type = &setting_type_string,
}
#define DHCP_EB_REVERSE_PASSWORD
Reverse password.
Definition dhcp.h:515

iSCSI reverse username setting

iSCSI reverse password setting

References __setting, DHCP_EB_REVERSE_USERNAME, SETTING_AUTH_EXTRA, and username.

◆ iscsi_parse_root_path()

int iscsi_parse_root_path ( struct iscsi_session * iscsi,
const char * root_path )
static

Parse iSCSI root path.

Parameters
iscsiiSCSI session
root_pathiSCSI root path (as per RFC4173)
Return values
rcReturn status code

Definition at line 2008 of file iscsi.c.

2009 {
2010 char *rp_copy;
2011 char *rp_comp[NUM_RP_COMPONENTS];
2012 char *rp;
2013 int skip = 0;
2014 int i = 0;
2015 int rc;
2016
2017 /* Create modifiable copy of root path */
2018 rp_copy = strdup ( root_path );
2019 if ( ! rp_copy ) {
2020 rc = -ENOMEM;
2021 goto err_strdup;
2022 }
2023 rp = rp_copy;
2024
2025 /* Split root path into component parts */
2026 while ( 1 ) {
2027 rp_comp[i++] = rp;
2028 if ( i == NUM_RP_COMPONENTS )
2029 break;
2030 for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) {
2031 if ( ! *rp ) {
2032 DBGC ( iscsi, "iSCSI %p root path \"%s\" "
2033 "too short\n", iscsi, root_path );
2035 goto err_split;
2036 } else if ( *rp == '[' ) {
2037 skip = 1;
2038 } else if ( *rp == ']' ) {
2039 skip = 0;
2040 }
2041 }
2042 *(rp++) = '\0';
2043 }
2044
2045 /* Use root path components to configure iSCSI session */
2046 iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
2047 if ( ! iscsi->target_address ) {
2048 rc = -ENOMEM;
2049 goto err_servername;
2050 }
2051 iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
2052 if ( ! iscsi->target_port )
2053 iscsi->target_port = ISCSI_PORT;
2054 if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
2055 DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
2056 iscsi, rp_comp[RP_LUN] );
2057 goto err_lun;
2058 }
2059 iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
2060 if ( ! iscsi->target_iqn ) {
2061 rc = -ENOMEM;
2062 goto err_targetname;
2063 }
2064
2065 err_targetname:
2066 err_lun:
2067 err_servername:
2068 err_split:
2069 free ( rp_copy );
2070 err_strdup:
2071 return rc;
2072}
#define EINVAL_ROOT_PATH_TOO_SHORT
Definition iscsi.c:70
int scsi_parse_lun(const char *lun_string, struct scsi_lun *lun)
Parse SCSI LUN.
Definition scsi.c:118
struct scsi_lun lun
SCSI LUN (for boot firmware table)
Definition iscsi.h:664

References DBGC, EINVAL_ROOT_PATH_TOO_SHORT, ENOMEM, free, ISCSI_PORT, iscsi_session::lun, NULL, NUM_RP_COMPONENTS, rc, RP_LUN, RP_PORT, RP_SERVERNAME, RP_TARGETNAME, scsi_parse_lun(), strdup(), strtoul(), iscsi_session::target_address, iscsi_session::target_iqn, and iscsi_session::target_port.

Referenced by iscsi_open().

◆ iscsi_fetch_settings()

int iscsi_fetch_settings ( struct iscsi_session * iscsi)
static

Fetch iSCSI settings.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2080 of file iscsi.c.

2080 {
2081 char *hostname;
2082 union uuid uuid;
2083 int len;
2084
2085 /* Fetch relevant settings. Don't worry about freeing on
2086 * error, since iscsi_free() will take care of that anyway.
2087 */
2088 fetch_string_setting_copy ( NULL, &username_setting,
2089 &iscsi->initiator_username );
2090 fetch_string_setting_copy ( NULL, &password_setting,
2091 &iscsi->initiator_password );
2092 fetch_string_setting_copy ( NULL, &reverse_username_setting,
2093 &iscsi->target_username );
2094 fetch_string_setting_copy ( NULL, &reverse_password_setting,
2095 &iscsi->target_password );
2096
2097 /* Use explicit initiator IQN if provided */
2098 fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
2099 &iscsi->initiator_iqn );
2100 if ( iscsi->initiator_iqn )
2101 return 0;
2102
2103 /* Otherwise, try to construct an initiator IQN from the hostname */
2104 fetch_string_setting_copy ( NULL, &hostname_setting, &hostname );
2105 if ( hostname ) {
2106 len = asprintf ( &iscsi->initiator_iqn,
2107 ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
2108 free ( hostname );
2109 if ( len < 0 ) {
2110 DBGC ( iscsi, "iSCSI %p could not allocate initiator "
2111 "IQN\n", iscsi );
2112 return -ENOMEM;
2113 }
2114 assert ( iscsi->initiator_iqn );
2115 return 0;
2116 }
2117
2118 /* Otherwise, try to construct an initiator IQN from the UUID */
2119 if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
2120 DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
2121 iscsi );
2123 }
2124 if ( ( len = asprintf ( &iscsi->initiator_iqn,
2126 uuid_ntoa ( &uuid ) ) ) < 0 ) {
2127 DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
2128 iscsi );
2129 return -ENOMEM;
2130 }
2131 assert ( iscsi->initiator_iqn );
2132
2133 return 0;
2134}
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition asprintf.c:42
#define EINVAL_NO_INITIATOR_IQN
Definition iscsi.c:86
#define ISCSI_DEFAULT_IQN_PREFIX
Default initiator IQN prefix.
Definition iscsi.h:715
int fetch_string_setting_copy(struct settings *settings, const struct setting *setting, char **data)
Fetch value of string setting.
Definition settings.c:874
int fetch_uuid_setting(struct settings *settings, const struct setting *setting, union uuid *uuid)
Fetch value of UUID setting.
Definition settings.c:1085
A universally unique ID.
Definition uuid.h:16
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition uuid.c:46

References asprintf(), assert, DBGC, EINVAL_NO_INITIATOR_IQN, ENOMEM, fetch_string_setting_copy(), fetch_uuid_setting(), free, iscsi_session::initiator_iqn, iscsi_session::initiator_password, iscsi_session::initiator_username, ISCSI_DEFAULT_IQN_PREFIX, len, NULL, iscsi_session::target_password, iscsi_session::target_username, and uuid_ntoa().

Referenced by iscsi_open().

◆ iscsi_check_auth()

int iscsi_check_auth ( struct iscsi_session * iscsi)
static

Check iSCSI authentication details.

Parameters
iscsiiSCSI session
Return values
rcReturn status code

Definition at line 2143 of file iscsi.c.

2143 {
2144
2145 /* Check for invalid authentication combinations */
2146 if ( ( /* Initiator username without password (or vice-versa) */
2147 ( !! iscsi->initiator_username ) ^
2148 ( !! iscsi->initiator_password ) ) ||
2149 ( /* Target username without password (or vice-versa) */
2150 ( !! iscsi->target_username ) ^
2151 ( !! iscsi->target_password ) ) ||
2152 ( /* Target (reverse) without initiator (forward) */
2153 ( iscsi->target_username &&
2154 ( ! iscsi->initiator_username ) ) ) ) {
2155 DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
2156 "%sname,%spw, target %sname,%spw\n", iscsi,
2157 ( iscsi->initiator_username ? "" : "no " ),
2158 ( iscsi->initiator_password ? "" : "no " ),
2159 ( iscsi->target_username ? "" : "no " ),
2160 ( iscsi->target_password ? "" : "no " ) );
2162 }
2163
2164 return 0;
2165}
#define EINVAL_BAD_CREDENTIAL_MIX
Definition iscsi.c:74

References DBGC, EINVAL_BAD_CREDENTIAL_MIX, iscsi_session::initiator_password, iscsi_session::initiator_username, iscsi_session::target_password, and iscsi_session::target_username.

Referenced by iscsi_open().

◆ iscsi_open()

int iscsi_open ( struct interface * parent,
struct uri * uri )
static

Open iSCSI URI.

Parameters
parentParent interface
uriURI
Return values
rcReturn status code

Definition at line 2174 of file iscsi.c.

2174 {
2175 struct iscsi_session *iscsi;
2176 int rc;
2177
2178 /* Sanity check */
2179 if ( ! uri->opaque ) {
2181 goto err_sanity_uri;
2182 }
2183
2184 /* Allocate and initialise structure */
2185 iscsi = zalloc ( sizeof ( *iscsi ) );
2186 if ( ! iscsi ) {
2187 rc = -ENOMEM;
2188 goto err_zalloc;
2189 }
2190 ref_init ( &iscsi->refcnt, iscsi_free );
2191 intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2192 intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2193 intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2195 &iscsi->refcnt );
2196 acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2197
2198 /* Parse root path */
2199 if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2200 goto err_parse_root_path;
2201 /* Set fields not specified by root path */
2202 if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2203 goto err_fetch_settings;
2204 /* Validate authentication */
2205 if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2206 goto err_check_auth;
2207
2208 /* Sanity checks */
2209 if ( ! iscsi->target_address ) {
2210 DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2211 iscsi );
2213 goto err_sanity_address;
2214 }
2215 if ( ! iscsi->target_iqn ) {
2216 DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2217 iscsi, uri->opaque );
2219 goto err_sanity_iqn;
2220 }
2221 DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2222 DBGC ( iscsi, "iSCSI %p target %s %s\n",
2223 iscsi, iscsi->target_address, iscsi->target_iqn );
2224
2225 /* Open socket */
2226 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2227 goto err_open_connection;
2228
2229 /* Attach SCSI device to parent interface */
2230 if ( ( rc = scsi_open ( parent, &iscsi->control,
2231 &iscsi->lun ) ) != 0 ) {
2232 DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2233 iscsi, strerror ( rc ) );
2234 goto err_scsi_open;
2235 }
2236
2237 /* Mortalise self, and return */
2238 ref_put ( &iscsi->refcnt );
2239 return 0;
2240
2241 err_scsi_open:
2242 err_open_connection:
2243 err_sanity_iqn:
2244 err_sanity_address:
2245 err_check_auth:
2246 err_fetch_settings:
2247 err_parse_root_path:
2248 iscsi_close ( iscsi, rc );
2249 ref_put ( &iscsi->refcnt );
2250 err_zalloc:
2251 err_sanity_uri:
2252 return rc;
2253}
static void acpi_init(struct acpi_descriptor *desc, struct acpi_model *model, struct refcnt *refcnt)
Initialise ACPI descriptor.
Definition acpi.h:312
static void intf_init(struct interface *intf, struct interface_descriptor *desc, struct refcnt *refcnt)
Initialise an object interface.
Definition interface.h:204
static void iscsi_free(struct refcnt *refcnt)
Free iSCSI session.
Definition iscsi.c:201
static int iscsi_check_auth(struct iscsi_session *iscsi)
Check iSCSI authentication details.
Definition iscsi.c:2143
#define EINVAL_NO_TARGET_IQN
Definition iscsi.c:82
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition iscsi.c:1823
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition iscsi.c:1928
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
Definition iscsi.c:2008
#define ENOTSUP_DISCOVERY
Definition iscsi.c:110
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition iscsi.c:2080
#define EINVAL_NO_ROOT_PATH
Definition iscsi.c:78
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition iscsi.c:1598
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition iscsi.c:1955
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void process_init_stopped(struct process *process, struct process_descriptor *desc, struct refcnt *refcnt)
Initialise process without adding to process list.
Definition process.h:146
#define ref_put(refcnt)
Drop reference to object.
Definition refcnt.h:107
#define ref_init(refcnt, free)
Initialise a reference counter.
Definition refcnt.h:65
int scsi_open(struct interface *block, struct interface *scsi, struct scsi_lun *lun)
Open SCSI device.
Definition scsi.c:985
struct refcnt refcnt
Reference counter.
Definition iscsi.h:547
A Uniform Resource Identifier.
Definition uri.h:65
const char * opaque
Opaque part.
Definition uri.h:71

References acpi_init(), iscsi_session::control, iscsi_session::data, DBGC, iscsi_session::desc, EINVAL_NO_ROOT_PATH, EINVAL_NO_TARGET_IQN, ENOMEM, ENOTSUP_DISCOVERY, iscsi_session::initiator_iqn, intf_init(), iscsi_check_auth(), iscsi_close(), iscsi_control_desc, iscsi_data_desc, iscsi_fetch_settings(), iscsi_free(), iscsi_open_connection(), iscsi_parse_root_path(), iscsi_process_desc, iscsi_socket_desc, iscsi_session::lun, uri::opaque, iscsi_session::process, process_init_stopped(), rc, ref_init, ref_put, iscsi_session::refcnt, scsi_open(), iscsi_session::socket, strerror(), iscsi_session::target_address, iscsi_session::target_iqn, and zalloc().

Variable Documentation

◆ iscsi_string_types

struct iscsi_string_type iscsi_string_types[]
static
Initial value:
= {
{ "TargetAddress", iscsi_handle_targetaddress_value },
{ "MaxBurstLength", iscsi_handle_maxburstlength_value },
{ "AuthMethod", iscsi_handle_authmethod_value },
{ NULL, NULL }
}
static int iscsi_handle_chap_a_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_A text value.
Definition iscsi.c:955
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
Definition iscsi.c:930
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition iscsi.c:1019
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition iscsi.c:978
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition iscsi.c:909
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition iscsi.c:1103
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition iscsi.c:1074
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition iscsi.c:879

iSCSI text strings that we want to handle

Definition at line 1186 of file iscsi.c.

1186 {
1187 { "TargetAddress", iscsi_handle_targetaddress_value },
1188 { "MaxBurstLength", iscsi_handle_maxburstlength_value },
1189 { "AuthMethod", iscsi_handle_authmethod_value },
1190 { "CHAP_A", iscsi_handle_chap_a_value },
1191 { "CHAP_I", iscsi_handle_chap_i_value },
1192 { "CHAP_C", iscsi_handle_chap_c_value },
1193 { "CHAP_N", iscsi_handle_chap_n_value },
1194 { "CHAP_R", iscsi_handle_chap_r_value },
1195 { NULL, NULL }
1196};

Referenced by iscsi_handle_string().

◆ iscsi_process_desc

struct process_descriptor iscsi_process_desc
static
Initial value:
=
static void iscsi_tx_step(struct iscsi_session *iscsi)
Transmit iSCSI PDU.
Definition iscsi.c:1534
#define PROC_DESC(object_type, process, _step)
Define a process descriptor.
Definition process.h:83
A process.
Definition process.h:18

iSCSI TX process descriptor

Definition at line 1598 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_socket_operations

struct interface_operation iscsi_socket_operations[]
static
Initial value:
= {
}
void intf_close(struct interface *intf, int rc)
Close an object interface.
Definition interface.c:250
#define INTF_OP(op_type, object_type, op_func)
Define an object interface operation.
Definition interface.h:33
static int iscsi_socket_deliver(struct iscsi_session *iscsi, struct io_buffer *iobuf, struct xfer_metadata *meta __unused)
Receive new data.
Definition iscsi.c:1698
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
Definition iscsi.c:1782
int xfer_deliver(struct interface *intf, struct io_buffer *iobuf, struct xfer_metadata *meta)
Deliver datagram.
Definition xfer.c:195
int xfer_vredirect(struct interface *intf, int type, va_list args)
Send redirection event.
Definition xfer.c:63

iSCSI socket interface operations

Definition at line 1814 of file iscsi.c.

◆ iscsi_socket_desc

struct interface_descriptor iscsi_socket_desc
static
Initial value:
=
#define INTF_DESC(object_type, intf, operations)
Define an object interface descriptor.
Definition interface.h:81
static struct interface_operation iscsi_socket_operations[]
iSCSI socket interface operations
Definition iscsi.c:1814

iSCSI socket interface descriptor

Definition at line 1823 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_control_op

struct interface_operation iscsi_control_op[]
static
Initial value:
= {
}
struct acpi_descriptor * acpi_describe(struct interface *intf)
Get object's ACPI descriptor.
Definition acpi.c:321
void block_capacity(struct interface *intf, struct block_device_capacity *capacity)
Report block device capacity.
Definition blockdev.c:130
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition efi_path.c:920
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition efi_path.c:506
#define EFI_INTF_OP
Definition efi.h:374
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
Definition iscsi.c:1894
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition iscsi.c:1858
static struct acpi_descriptor * iscsi_describe(struct iscsi_session *iscsi)
Get iSCSI ACPI descriptor.
Definition iscsi.c:1912
A SCSI command.
Definition scsi.c:263

iSCSI SCSI command-issuing interface operations

Definition at line 1918 of file iscsi.c.

◆ iscsi_control_desc

struct interface_descriptor iscsi_control_desc
static
Initial value:
=
static struct interface_operation iscsi_control_op[]
iSCSI SCSI command-issuing interface operations
Definition iscsi.c:1918
uint32_t control
Control.
Definition myson.h:3

iSCSI SCSI command-issuing interface descriptor

Definition at line 1928 of file iscsi.c.

Referenced by iscsi_open().

◆ iscsi_data_op

struct interface_operation iscsi_data_op[]
static
Initial value:
= {
}
static void iscsi_command_close(struct iscsi_session *iscsi, int rc)
Close iSCSI command.
Definition iscsi.c:1937

iSCSI SCSI command interface operations

Definition at line 1950 of file iscsi.c.

1950 {
1952};

◆ iscsi_data_desc

struct interface_descriptor iscsi_data_desc
static
Initial value:
=
static struct interface_operation iscsi_data_op[]
iSCSI SCSI command interface operations
Definition iscsi.c:1950

iSCSI SCSI command interface descriptor

Definition at line 1955 of file iscsi.c.

Referenced by iscsi_open().

◆ __uri_opener

struct uri_opener iscsi_uri_opener __uri_opener
Initial value:
= {
.scheme = "iscsi",
.open = iscsi_open,
}
static int iscsi_open(struct interface *parent, struct uri *uri)
Open iSCSI URI.
Definition iscsi.c:2174

iSCSI URI opener

Definition at line 2256 of file iscsi.c.

2256 {
2257 .scheme = "iscsi",
2258 .open = iscsi_open,
2259};