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 1994 of file iscsi.c.

1994 {
1995 RP_SERVERNAME = 0,
1997 RP_PORT,
1998 RP_LUN,
2001};
@ NUM_RP_COMPONENTS
Definition iscsi.c:2000
@ RP_SERVERNAME
Definition iscsi.c:1995
@ RP_PORT
Definition iscsi.c:1997
@ RP_PROTOCOL
Definition iscsi.c:1996
@ RP_TARGETNAME
Definition iscsi.c:1999
@ RP_LUN
Definition iscsi.c:1998

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 1468 of file iscsi.c.

1468 {
1469
1470 assert ( iscsi->tx_state == ISCSI_TX_IDLE );
1471
1472 /* Initialise TX BHS */
1473 memset ( &iscsi->tx_bhs, 0, sizeof ( iscsi->tx_bhs ) );
1474
1475 /* Flag TX engine to start transmitting */
1476 iscsi->tx_state = ISCSI_TX_BHS;
1477
1478 /* Start transmission process */
1479 iscsi_tx_resume ( iscsi );
1480}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:61
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:1456
@ 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 800 of file iscsi.c.

800 {
802 int len;
803
804 switch ( iscsi->status & ISCSI_LOGIN_CSG_MASK ) {
806 DBGC ( iscsi, "iSCSI %p entering security negotiation\n",
807 iscsi );
808 break;
810 DBGC ( iscsi, "iSCSI %p entering operational negotiation\n",
811 iscsi );
812 break;
813 default:
814 assert ( 0 );
815 }
816
817 /* Construct BHS and initiate transmission */
818 iscsi_start_tx ( iscsi );
821 request->flags = ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) |
823 /* version_max and version_min left as zero */
825 ISCSI_SET_LENGTHS ( request->lengths, 0, len );
826 request->isid_iana_en = htonl ( ISCSI_ISID_IANA |
828 request->isid_iana_qual = htons ( iscsi->isid_iana_qual );
829 /* tsih left as zero */
830 request->itt = htonl ( iscsi->itt );
831 /* cid left as zero */
832 request->cmdsn = htonl ( iscsi->cmdsn );
833 request->expstatsn = htonl ( iscsi->statsn + 1 );
834}
#define NULL
NULL pointer (VOID *).
Definition Base.h:321
ring len
Length.
Definition dwmac.h:226
#define DBGC(...)
Definition compiler.h:530
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:721
static void iscsi_start_tx(struct iscsi_session *iscsi)
Start up a new TX PDU.
Definition iscsi.c:1468
#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 540 of file iscsi.c.

541 {
542 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
543 unsigned long offset;
544 unsigned long remaining;
545 unsigned long len;
546
547 /* We always send 512-byte Data-Out PDUs; this removes the
548 * need to worry about the target's MaxRecvDataSegmentLength.
549 */
550 offset = datasn * 512;
551 remaining = iscsi->transfer_len - offset;
552 len = remaining;
553 if ( len > 512 )
554 len = 512;
555
556 /* Construct BHS and initiate transmission */
557 iscsi_start_tx ( iscsi );
558 data_out->opcode = ISCSI_OPCODE_DATA_OUT;
559 if ( len == remaining )
560 data_out->flags = ( ISCSI_FLAG_FINAL );
561 ISCSI_SET_LENGTHS ( data_out->lengths, 0, len );
562 data_out->lun = iscsi->command->lun;
563 data_out->itt = htonl ( iscsi->itt );
564 data_out->ttt = htonl ( iscsi->ttt );
565 data_out->expstatsn = htonl ( iscsi->statsn + 1 );
566 data_out->datasn = htonl ( datasn );
567 data_out->offset = htonl ( iscsi->transfer_offset + offset );
568 DBGC ( iscsi, "iSCSI %p start data out DataSN %#x len %#lx\n",
569 iscsi, datasn, len );
570}
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:252
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:578
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:677
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:407
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:800
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.len &&
381 iscsi->command->data_out.len ) );
382
383 /* Construct BHS and initiate transmission */
384 iscsi_start_tx ( iscsi );
386 command->flags = ( ISCSI_FLAG_FINAL |
388 if ( iscsi->command->data_in.len )
390 if ( iscsi->command->data_out.len )
392 /* lengths left as zero */
393 memcpy ( &command->lun, &iscsi->command->lun,
394 sizeof ( command->lun ) );
395 command->itt = htonl ( iscsi->itt );
396 command->exp_len = htonl ( iscsi->command->data_in.len |
397 iscsi->command->data_out.len );
398 command->cmdsn = htonl ( iscsi->cmdsn );
399 command->expstatsn = htonl ( iscsi->statsn + 1 );
400 memcpy ( &command->cdb, &iscsi->command->cdb, sizeof ( command->cdb ));
401 DBGC2 ( iscsi, "iSCSI %p start " SCSI_CDB_FORMAT " %s %#zx\n",
402 iscsi, SCSI_CDB_DATA ( command->cdb ),
403 ( iscsi->command->data_in.len ? "in" : "out" ),
404 ( iscsi->command->data_in.len +
405 iscsi->command->data_out.len ) );
406}
#define DBGC2(...)
Definition compiler.h:547
#define SCSI_CDB_DATA(cdb)
printf() parameters for dumping a scsi_cdb
Definition scsi.h:224
#define SCSI_CDB_FORMAT
printf() format for dumping a scsi_cdb
Definition scsi.h:220
#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
struct xfer_buffer data_in
Data-in buffer.
Definition scsi.h:258
union scsi_cdb cdb
CDB for this command.
Definition scsi.h:254
struct xfer_buffer data_out
Data-out buffer.
Definition scsi.h:256
size_t len
Size of data.
Definition xferbuf.h:25
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_out, 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, xfer_buffer::len, 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 /* Sanity check */
428 if ( ! iscsi->command )
429 return -EPROTO;
430
431 /* Buffer up the PDU data */
432 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
433 DBGC ( iscsi, "iSCSI %p could not buffer SCSI response: %s\n",
434 iscsi, strerror ( rc ) );
435 return rc;
436 }
437 if ( remaining )
438 return 0;
439
440 /* Parse SCSI response and discard buffer */
441 memset ( &rsp, 0, sizeof ( rsp ) );
442 rsp.status = response->status;
443 residual_count = ntohl ( response->residual_count );
444 if ( response->flags & ISCSI_DATA_FLAG_OVERFLOW ) {
445 rsp.overrun = residual_count;
446 } else if ( response->flags & ISCSI_DATA_FLAG_UNDERFLOW ) {
447 rsp.overrun = -(residual_count);
448 }
449 data_len = ISCSI_DATA_LEN ( response->lengths );
450 if ( data_len >= 2 ) {
451 scsi_parse_sense ( ( iscsi->rx_buffer + 2 ), ( data_len - 2 ),
452 &rsp.sense );
453 }
455
456 /* Check for errors */
457 if ( response->response != ISCSI_RESPONSE_COMMAND_COMPLETE )
458 return -EIO;
459
460 /* Mark as completed */
461 iscsi_scsi_done ( iscsi, 0, &rsp );
462 return 0;
463}
#define EPROTO
Protocol error.
Definition errno.h:668
#define EIO
Input/output error.
Definition errno.h:477
#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:313
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 iscsi_session::command, data, data_len, DBGC, EIO, EPROTO, 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 474 of file iscsi.c.

476 {
477 struct iscsi_bhs_data_in *data_in = &iscsi->rx_bhs.data_in;
478 unsigned long offset;
479 int rc;
480
481 /* Sanity check */
482 if ( ! iscsi->command )
483 return -EPROTO;
484
485 /* Copy data to data-in buffer */
486 offset = ntohl ( data_in->offset ) + iscsi->rx_offset;
487 if ( ( rc = xferbuf_write ( &iscsi->command->data_in, offset,
488 data, len ) ) != 0 )
489 return rc;
490
491 /* Wait for whole SCSI response to arrive */
492 if ( remaining )
493 return 0;
494
495 /* Mark as completed if status is present */
496 if ( data_in->flags & ISCSI_DATA_FLAG_STATUS ) {
497 assert ( ( offset + len ) == iscsi->command->data_in.len );
498 assert ( data_in->flags & ISCSI_FLAG_FINAL );
499 /* iSCSI cannot return an error status via a data-in */
500 iscsi_scsi_done ( iscsi, 0, NULL );
501 }
502
503 return 0;
504}
#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
int xferbuf_write(struct xfer_buffer *xferbuf, size_t offset, const void *data, size_t len)
Write to data transfer buffer.
Definition xferbuf.c:133

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

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 515 of file iscsi.c.

517 {
518 struct iscsi_bhs_r2t *r2t = &iscsi->rx_bhs.r2t;
519
520 /* Sanity check */
521 if ( ! iscsi->command )
522 return -EPROTO;
523
524 /* Record transfer parameters and trigger first data-out */
525 iscsi->ttt = ntohl ( r2t->ttt );
526 iscsi->transfer_offset = ntohl ( r2t->offset );
527 iscsi->transfer_len = ntohl ( r2t->len );
528 iscsi_start_data_out ( iscsi, 0 );
529
530 return 0;
531}
static void iscsi_start_data_out(struct iscsi_session *iscsi, unsigned int datasn)
Build iSCSI data-out BHS.
Definition iscsi.c:540
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, iscsi_session::command, data, EPROTO, 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 578 of file iscsi.c.

578 {
579 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
580
581 /* If we haven't reached the end of the sequence, start
582 * sending the next data-out PDU.
583 */
584 if ( ! ( data_out->flags & ISCSI_FLAG_FINAL ) )
585 iscsi_start_data_out ( iscsi, ntohl ( data_out->datasn ) + 1 );
586}

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 594 of file iscsi.c.

594 {
595 struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
596 struct io_buffer *iobuf;
597 unsigned long offset;
598 size_t len;
599 size_t pad_len;
600 int rc;
601
602 /* Calculate offset and lengths */
603 offset = ntohl ( data_out->offset );
604 len = ISCSI_DATA_LEN ( data_out->lengths );
605 pad_len = ISCSI_DATA_PAD_LEN ( data_out->lengths );
606
607 /* Allocate I/O buffer */
608 iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
609 if ( ! iobuf ) {
610 rc = -ENOMEM;
611 goto err_alloc;
612 }
613
614 /* Copy data to I/O buffer */
615 assert ( iscsi->command != NULL );
616 if ( ( rc = xferbuf_read ( &iscsi->command->data_out, offset,
617 iob_put ( iobuf, len ), len ) ) != 0 ) {
618 goto err_read;
619 }
620 memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
621
622 /* Deliver I/O buffer */
623 if ( ( rc = xfer_deliver_iob ( &iscsi->socket,
624 iob_disown ( iobuf ) ) ) != 0 ) {
625 goto err_deliver;
626 }
627
628 return 0;
629
630 err_deliver:
631 err_read:
632 free_iob ( iobuf );
633 err_alloc:
634 return rc;
635}
void free_iob(struct io_buffer *iobuf)
Free I/O buffer.
Definition iobuf.c:153
#define iob_put(iobuf, len)
Definition iobuf.h:185
#define iob_disown(iobuf)
Disown an I/O buffer.
Definition iobuf.h:277
#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:98
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
int xferbuf_read(struct xfer_buffer *xferbuf, size_t offset, void *data, size_t len)
Read from data transfer buffer.
Definition xferbuf.c:166

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

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 646 of file iscsi.c.

648 {
649 struct iscsi_nop_in *nop_in = &iscsi->rx_bhs.nop_in;
650
651 DBGC2 ( iscsi, "iSCSI %p received NOP-In\n", iscsi );
652
653 /* We don't currently have the ability to respond to NOP-Ins
654 * sent as ping requests, but we can happily accept NOP-Ins
655 * sent merely to update CmdSN.
656 */
657 if ( nop_in->ttt == htonl ( ISCSI_TAG_RESERVED ) )
658 return 0;
659
660 /* Ignore any other NOP-Ins. The target may eventually
661 * disconnect us for failing to respond, but this minimises
662 * unnecessary connection closures.
663 */
664 DBGC ( iscsi, "iSCSI %p received unsupported NOP-In with TTT %08x\n",
665 iscsi, ntohl ( nop_in->ttt ) );
666 return 0;
667}
#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 721 of file iscsi.c.

722 {
723 unsigned int used = 0;
724 const char *auth_method;
725
726 if ( iscsi->status & ISCSI_STATUS_STRINGS_SECURITY ) {
727 /* Default to allowing no authentication */
728 auth_method = "None";
729 /* If we have a credential to supply, permit CHAP */
730 if ( iscsi->initiator_username )
731 auth_method = "CHAP,None";
732 /* If we have a credential to check, force CHAP */
733 if ( iscsi->target_username )
734 auth_method = "CHAP";
735 used += ssnprintf ( data + used, len - used,
736 "InitiatorName=%s%c"
737 "TargetName=%s%c"
738 "SessionType=Normal%c"
739 "AuthMethod=%s%c",
740 iscsi->initiator_iqn, 0,
741 iscsi->target_iqn, 0, 0,
742 auth_method, 0 );
743 }
744
746 used += ssnprintf ( data + used, len - used, "CHAP_A=5%c", 0 );
747 }
748
749 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_RESPONSE ) ) {
750 char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
751 assert ( iscsi->initiator_username != NULL );
752 base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
753 buf, sizeof ( buf ) );
754 used += ssnprintf ( data + used, len - used,
755 "CHAP_N=%s%cCHAP_R=0x%s%c",
756 iscsi->initiator_username, 0, buf, 0 );
757 }
758
759 if ( ( iscsi->status & ISCSI_STATUS_STRINGS_CHAP_CHALLENGE ) ) {
760 size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
761 char buf[ base16_encoded_len ( challenge_len ) + 1 ];
762 base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
763 buf, sizeof ( buf ) );
764 used += ssnprintf ( data + used, len - used,
765 "CHAP_I=%d%cCHAP_C=0x%s%c",
766 iscsi->chap_challenge[0], 0, buf, 0 );
767 }
768
770 used += ssnprintf ( data + used, len - used,
771 "HeaderDigest=None%c"
772 "DataDigest=None%c"
773 "MaxConnections=1%c"
774 "InitialR2T=Yes%c"
775 "ImmediateData=No%c"
776 "MaxRecvDataSegmentLength=%d%c"
777 "MaxBurstLength=%d%c"
778 "FirstBurstLength=%d%c"
779 "DefaultTime2Wait=0%c"
780 "DefaultTime2Retain=0%c"
781 "MaxOutstandingR2T=1%c"
782 "DataPDUInOrder=Yes%c"
783 "DataSequenceInOrder=Yes%c"
784 "ErrorRecoveryLevel=0%c",
785 0, 0, 0, 0, 0,
789 0, 0, 0, 0, 0, 0 );
790 }
791
792 return used;
793}
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 snprintf() that accepts a signed buffer size.
Definition vsprintf.c:441

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 842 of file iscsi.c.

842 {
843
844 /* Clear any "strings to send" flags */
846
847 /* Free any dynamically allocated storage used for login */
848 chap_finish ( &iscsi->chap );
849}
#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 859 of file iscsi.c.

859 {
861 struct io_buffer *iobuf;
862 size_t len;
863 size_t pad_len;
864
865 len = ISCSI_DATA_LEN ( request->lengths );
866 pad_len = ISCSI_DATA_PAD_LEN ( request->lengths );
867 iobuf = xfer_alloc_iob ( &iscsi->socket, ( len + pad_len ) );
868 if ( ! iobuf )
869 return -ENOMEM;
870 iob_put ( iobuf, len );
871 iscsi_build_login_request_strings ( iscsi, iobuf->data, len );
872 memset ( iob_put ( iobuf, pad_len ), 0, pad_len );
873
874 return xfer_deliver_iob ( &iscsi->socket, iobuf );
875}
void * data
Start of data.
Definition iobuf.h:113

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(), 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 885 of file iscsi.c.

886 {
887
888 /* Check for initial '0x' or '0b' and decode as appropriate */
889 if ( *(encoded++) == '0' ) {
890 switch ( tolower ( *(encoded++) ) ) {
891 case 'x' :
892 return base16_decode ( encoded, raw, len );
893 case 'b' :
894 return base64_decode ( encoded, raw, len );
895 }
896 }
897
899}
__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 908 of file iscsi.c.

909 {
910 char *separator;
911
912 DBGC ( iscsi, "iSCSI %p will redirect to %s\n", iscsi, value );
913
914 /* Replace target address */
915 free ( iscsi->target_address );
916 iscsi->target_address = strdup ( value );
917 if ( ! iscsi->target_address )
918 return -ENOMEM;
919
920 /* Replace target port */
921 iscsi->target_port = htons ( ISCSI_PORT );
922 separator = strchr ( iscsi->target_address, ':' );
923 if ( separator ) {
924 *separator = '\0';
925 iscsi->target_port = strtoul ( ( separator + 1 ), NULL, 0 );
926 }
927
928 return 0;
929}
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:516
char * strchr(const char *src, int character)
Find character within a string.
Definition string.c:288
char * strdup(const char *src)
Duplicate string.
Definition string.c:425

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 938 of file iscsi.c.

939 {
940
941 /* If server requests CHAP, send the CHAP_A string */
942 if ( strcmp ( value, "CHAP" ) == 0 ) {
943 DBGC ( iscsi, "iSCSI %p initiating CHAP authentication\n",
944 iscsi );
947 }
948
949 return 0;
950}
#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 959 of file iscsi.c.

960 {
961 unsigned long max_burst_len;
962 char *end;
963
964 /* Update maximum burst length */
965 max_burst_len = strtoul ( value, &end, 0 );
966 if ( *end ) {
967 DBGC ( iscsi, "iSCSI %p invalid MaxBurstLength \"%s\"\n",
968 iscsi, value );
969 return -EINVAL_MAXBURSTLENGTH;
970 }
971 if ( max_burst_len < iscsi->max_burst_len )
972 iscsi->max_burst_len = max_burst_len;
973
974 return 0;
975}
#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 984 of file iscsi.c.

985 {
986
987 /* We only ever offer "5" (i.e. MD5) as an algorithm, so if
988 * the server responds with anything else it is a protocol
989 * violation.
990 */
991 if ( strcmp ( value, "5" ) != 0 ) {
992 DBGC ( iscsi, "iSCSI %p got invalid CHAP algorithm \"%s\"\n",
993 iscsi, value );
995 }
996
997 return 0;
998}
#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 1007 of file iscsi.c.

1008 {
1009 unsigned int identifier;
1010 char *endp;
1011 int rc;
1012
1013 /* The CHAP identifier is an integer value */
1014 identifier = strtoul ( value, &endp, 0 );
1015 if ( *endp != '\0' ) {
1016 DBGC ( iscsi, "iSCSI %p saw invalid CHAP identifier \"%s\"\n",
1017 iscsi, value );
1019 }
1020
1021 /* Prepare for CHAP with MD5 */
1022 chap_finish ( &iscsi->chap );
1023 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1024 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1025 iscsi, strerror ( rc ) );
1026 return rc;
1027 }
1028
1029 /* Identifier and secret are the first two components of the
1030 * challenge.
1031 */
1032 chap_set_identifier ( &iscsi->chap, identifier );
1033 if ( iscsi->initiator_password ) {
1034 chap_update ( &iscsi->chap, iscsi->initiator_password,
1035 strlen ( iscsi->initiator_password ) );
1036 }
1037
1038 return 0;
1039}
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
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 1048 of file iscsi.c.

1049 {
1050 uint8_t *buf;
1051 unsigned int i;
1052 int len;
1053 int rc;
1054
1055 /* Allocate decoding buffer */
1056 len = strlen ( value ); /* Decoding never expands data */
1057 buf = malloc ( len );
1058 if ( ! buf ) {
1059 rc = -ENOMEM;
1060 goto err_alloc;
1061 }
1062
1063 /* Process challenge */
1065 if ( len < 0 ) {
1066 rc = len;
1067 DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1068 iscsi, value, strerror ( rc ) );
1069 goto err_decode;
1070 }
1071 chap_update ( &iscsi->chap, buf, len );
1072
1073 /* Build CHAP response */
1074 DBGC ( iscsi, "iSCSI %p sending CHAP response\n", iscsi );
1075 chap_respond ( &iscsi->chap );
1077
1078 /* Send CHAP challenge, if applicable */
1079 if ( iscsi->target_username ) {
1081 /* Generate CHAP challenge data */
1082 for ( i = 0 ; i < sizeof ( iscsi->chap_challenge ) ; i++ ) {
1083 iscsi->chap_challenge[i] = random();
1084 }
1085 }
1086
1087 /* Success */
1088 rc = 0;
1089
1090 err_decode:
1091 free ( buf );
1092 err_alloc:
1093 return rc;
1094}
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:885

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 1103 of file iscsi.c.

1104 {
1105
1106 /* The target username isn't actually involved at any point in
1107 * the authentication process; it merely serves to identify
1108 * which password the target is using to generate the CHAP
1109 * response. We unnecessarily verify that the username is as
1110 * expected, in order to provide mildly helpful diagnostics if
1111 * the target is supplying the wrong username/password
1112 * combination.
1113 */
1114 if ( iscsi->target_username &&
1115 ( strcmp ( iscsi->target_username, value ) != 0 ) ) {
1116 DBGC ( iscsi, "iSCSI %p target username \"%s\" incorrect "
1117 "(wanted \"%s\")\n",
1118 iscsi, value, iscsi->target_username );
1120 }
1121
1122 return 0;
1123}
#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 1132 of file iscsi.c.

1133 {
1134 uint8_t *buf;
1135 int len;
1136 int rc;
1137
1138 /* Generate CHAP response for verification */
1139 chap_finish ( &iscsi->chap );
1140 if ( ( rc = chap_init ( &iscsi->chap, &md5_algorithm ) ) != 0 ) {
1141 DBGC ( iscsi, "iSCSI %p could not initialise CHAP: %s\n",
1142 iscsi, strerror ( rc ) );
1143 goto err_chap_init;
1144 }
1145 chap_set_identifier ( &iscsi->chap, iscsi->chap_challenge[0] );
1146 if ( iscsi->target_password ) {
1147 chap_update ( &iscsi->chap, iscsi->target_password,
1148 strlen ( iscsi->target_password ) );
1149 }
1150 chap_update ( &iscsi->chap, &iscsi->chap_challenge[1],
1151 ( sizeof ( iscsi->chap_challenge ) - 1 ) );
1152 chap_respond ( &iscsi->chap );
1153
1154 /* Allocate decoding buffer */
1155 len = strlen ( value ); /* Decoding never expands data */
1156 buf = malloc ( len );
1157 if ( ! buf ) {
1158 rc = -ENOMEM;
1159 goto err_alloc;
1160 }
1161
1162 /* Process response */
1164 if ( len < 0 ) {
1165 rc = len;
1166 DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1167 iscsi, value, strerror ( rc ) );
1168 goto err_decode;
1169 }
1170
1171 /* Check CHAP response */
1172 if ( len != ( int ) iscsi->chap.response_len ) {
1173 DBGC ( iscsi, "iSCSI %p invalid CHAP response length\n",
1174 iscsi );
1176 goto err_response_len;
1177 }
1178 if ( memcmp ( buf, iscsi->chap.response, len ) != 0 ) {
1179 DBGC ( iscsi, "iSCSI %p incorrect CHAP response \"%s\"\n",
1180 iscsi, value );
1182 goto err_response;
1183 }
1184
1185 /* Mark session as authenticated */
1187
1188 err_response:
1189 err_response_len:
1190 err_decode:
1191 free ( buf );
1192 err_alloc:
1193 err_chap_init:
1194 return rc;
1195}
#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 1234 of file iscsi.c.

1235 {
1236 struct iscsi_string_type *type;
1237 const char *separator;
1238 const char *value;
1239 size_t key_len;
1240 int rc;
1241
1242 /* Find separator */
1243 separator = strchr ( string, '=' );
1244 if ( ! separator ) {
1245 DBGC ( iscsi, "iSCSI %p malformed string %s\n",
1246 iscsi, string );
1248 }
1249 key_len = ( separator - string );
1250 value = ( separator + 1 );
1251
1252 /* Check for rejections. Since we send only non-rejectable
1253 * values, any rejection is a fatal protocol error.
1254 */
1255 if ( strcmp ( value, "Reject" ) == 0 ) {
1256 DBGC ( iscsi, "iSCSI %p rejection: %s\n", iscsi, string );
1257 return -EPROTO_VALUE_REJECTED;
1258 }
1259
1260 /* Handle key/value pair */
1261 for ( type = iscsi_string_types ; type->key ; type++ ) {
1262 if ( strncmp ( string, type->key, key_len ) != 0 )
1263 continue;
1264 DBGC ( iscsi, "iSCSI %p handling %s\n", iscsi, string );
1265 if ( ( rc = type->handle ( iscsi, value ) ) != 0 ) {
1266 DBGC ( iscsi, "iSCSI %p could not handle %s: %s\n",
1267 iscsi, string, strerror ( rc ) );
1268 return rc;
1269 }
1270 return 0;
1271 }
1272 DBGC ( iscsi, "iSCSI %p ignoring %s\n", iscsi, string );
1273 return 0;
1274}
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:1215
#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:1198

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 1284 of file iscsi.c.

1285 {
1286 size_t string_len;
1287 int rc;
1288
1289 /* Handle each string in turn, taking care not to overrun the
1290 * data buffer in case of badly-terminated data.
1291 */
1292 while ( 1 ) {
1293 string_len = ( strnlen ( strings, len ) + 1 );
1294 if ( string_len > len )
1295 break;
1296 if ( ( rc = iscsi_handle_string ( iscsi, strings ) ) != 0 )
1297 return rc;
1298 strings += string_len;
1299 len -= string_len;
1300 }
1301 return 0;
1302}
static int iscsi_handle_string(struct iscsi_session *iscsi, const char *string)
Handle iSCSI string.
Definition iscsi.c:1234
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 1311 of file iscsi.c.

1312 {
1313 switch ( status_class ) {
1315 switch ( status_detail ) {
1322 return -ENODEV;
1323 default :
1325 }
1327 switch ( status_detail ) {
1329 return -EIO_TARGET_UNAVAILABLE;
1332 default:
1333 return -ENOTSUP_TARGET_STATUS;
1334 }
1335 default :
1336 return -EINVAL;
1337 }
1338}
#define EINVAL
Invalid argument.
Definition errno.h:472
#define ENODEV
No such device.
Definition errno.h:553
#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 1349 of file iscsi.c.

1351 {
1352 struct iscsi_bhs_login_response *response
1353 = &iscsi->rx_bhs.login_response;
1354 int rc;
1355
1356 /* Buffer up the PDU data */
1357 if ( ( rc = iscsi_rx_buffered_data ( iscsi, data, len ) ) != 0 ) {
1358 DBGC ( iscsi, "iSCSI %p could not buffer login response: %s\n",
1359 iscsi, strerror ( rc ) );
1360 return rc;
1361 }
1362 if ( remaining )
1363 return 0;
1364
1365 /* Process string data and discard string buffer */
1366 if ( ( rc = iscsi_handle_strings ( iscsi, iscsi->rx_buffer,
1367 iscsi->rx_len ) ) != 0 )
1368 return rc;
1370
1371 /* Check for login redirection */
1372 if ( response->status_class == ISCSI_STATUS_REDIRECT ) {
1373 DBGC ( iscsi, "iSCSI %p redirecting to new server\n", iscsi );
1374 iscsi_close_connection ( iscsi, 0 );
1375 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1376 DBGC ( iscsi, "iSCSI %p could not redirect: %s\n ",
1377 iscsi, strerror ( rc ) );
1378 return rc;
1379 }
1380 return 0;
1381 }
1382
1383 /* Check for fatal errors */
1384 if ( response->status_class != 0 ) {
1385 DBGC ( iscsi, "iSCSI login failure: class %02x detail %02x\n",
1386 response->status_class, response->status_detail );
1387 rc = iscsi_status_to_rc ( response->status_class,
1388 response->status_detail );
1389 return rc;
1390 }
1391
1392 /* Handle login transitions */
1393 if ( response->flags & ISCSI_LOGIN_FLAG_TRANSITION ) {
1394 iscsi->status &= ~( ISCSI_STATUS_PHASE_MASK |
1396 switch ( response->flags & ISCSI_LOGIN_NSG_MASK ) {
1398 iscsi->status |=
1401 break;
1404 break;
1405 default:
1406 DBGC ( iscsi, "iSCSI %p got invalid response flags "
1407 "%02x\n", iscsi, response->flags );
1408 return -EIO;
1409 }
1410 }
1411
1412 /* Send next login request PDU if we haven't reached the full
1413 * feature phase yet.
1414 */
1415 if ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) !=
1417 iscsi_start_login ( iscsi );
1418 return 0;
1419 }
1420
1421 /* Check that target authentication was successful (if required) */
1422 if ( ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_REQUIRED ) &&
1423 ! ( iscsi->status & ISCSI_STATUS_AUTH_REVERSE_OK ) ) {
1424 DBGC ( iscsi, "iSCSI %p nefarious target tried to bypass "
1425 "authentication\n", iscsi );
1426 return -EPROTO;
1427 }
1428
1429 /* Notify SCSI layer of window change */
1430 DBGC ( iscsi, "iSCSI %p entering full feature phase\n", iscsi );
1431 xfer_window_changed ( &iscsi->control );
1432
1433 return 0;
1434}
static int iscsi_handle_strings(struct iscsi_session *iscsi, const char *strings, size_t len)
Handle iSCSI strings.
Definition iscsi.c:1284
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:1311
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 1447 of file iscsi.c.

1447 {
1448 process_del ( &iscsi->process );
1449}

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 1456 of file iscsi.c.

1456 {
1457 process_add ( &iscsi->process );
1458}
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 1488 of file iscsi.c.

1488 {
1489 return 0;
1490}

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 1498 of file iscsi.c.

1498 {
1499 return xfer_deliver_raw ( &iscsi->socket, &iscsi->tx_bhs,
1500 sizeof ( iscsi->tx_bhs ) );
1501}
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 1512 of file iscsi.c.

1512 {
1513 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1514
1515 switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1517 return iscsi_tx_data_out ( iscsi );
1519 return iscsi_tx_login_request ( iscsi );
1520 default:
1521 /* Nothing to send in other states */
1522 return 0;
1523 }
1524}
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:859
static int iscsi_tx_data_out(struct iscsi_session *iscsi)
Send iSCSI data-out data segment.
Definition iscsi.c:594
#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 1535 of file iscsi.c.

1535 {
1536 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1537
1538 /* Stop transmission process */
1539 iscsi_tx_pause ( iscsi );
1540
1541 switch ( common->opcode & ISCSI_OPCODE_MASK ) {
1543 iscsi_data_out_done ( iscsi );
1544 break;
1546 iscsi_login_request_done ( iscsi );
1547 break;
1548 default:
1549 /* No action */
1550 break;
1551 }
1552}
static void iscsi_tx_pause(struct iscsi_session *iscsi)
Pause TX engine.
Definition iscsi.c:1447
static void iscsi_login_request_done(struct iscsi_session *iscsi)
Complete iSCSI login request PDU transmission.
Definition iscsi.c:842
static void iscsi_data_out_done(struct iscsi_session *iscsi)
Complete iSCSI data-out PDU transmission.
Definition iscsi.c:578

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 1563 of file iscsi.c.

1563 {
1564 struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
1565 int ( * tx ) ( struct iscsi_session *iscsi );
1566 enum iscsi_tx_state next_state;
1567 size_t tx_len;
1568 int rc;
1569
1570 /* Select fragment to transmit */
1571 while ( 1 ) {
1572 switch ( iscsi->tx_state ) {
1573 case ISCSI_TX_BHS:
1574 tx = iscsi_tx_bhs;
1575 tx_len = sizeof ( iscsi->tx_bhs );
1576 next_state = ISCSI_TX_AHS;
1577 break;
1578 case ISCSI_TX_AHS:
1580 tx_len = 0;
1581 next_state = ISCSI_TX_DATA;
1582 break;
1583 case ISCSI_TX_DATA:
1584 tx = iscsi_tx_data;
1585 tx_len = ISCSI_DATA_LEN ( common->lengths );
1586 next_state = ISCSI_TX_IDLE;
1587 break;
1588 case ISCSI_TX_IDLE:
1589 /* Nothing to do; pause processing */
1590 iscsi_tx_pause ( iscsi );
1591 return;
1592 default:
1593 assert ( 0 );
1594 return;
1595 }
1596
1597 /* Check for window availability, if needed */
1598 if ( tx_len && ( xfer_window ( &iscsi->socket ) == 0 ) ) {
1599 /* Cannot transmit at this point; pause
1600 * processing and wait for window to reopen
1601 */
1602 iscsi_tx_pause ( iscsi );
1603 return;
1604 }
1605
1606 /* Transmit data */
1607 if ( ( rc = tx ( iscsi ) ) != 0 ) {
1608 DBGC ( iscsi, "iSCSI %p could not transmit: %s\n",
1609 iscsi, strerror ( rc ) );
1610 /* Transmission errors are fatal */
1611 iscsi_close ( iscsi, rc );
1612 return;
1613 }
1614
1615 /* Move to next state */
1616 iscsi->tx_state = next_state;
1617
1618 /* If we have moved to the idle state, mark
1619 * transmission as complete
1620 */
1621 if ( iscsi->tx_state == ISCSI_TX_IDLE )
1622 iscsi_tx_done ( iscsi );
1623 }
1624}
static int iscsi_tx_nothing(struct iscsi_session *iscsi __unused)
Transmit nothing.
Definition iscsi.c:1488
static int iscsi_tx_bhs(struct iscsi_session *iscsi)
Transmit basic header segment of an iSCSI PDU.
Definition iscsi.c:1498
static void iscsi_tx_done(struct iscsi_session *iscsi)
Complete iSCSI PDU transmission.
Definition iscsi.c:1535
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:1512
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 1642 of file iscsi.c.

1643 {
1644 memcpy ( &iscsi->rx_bhs.bytes[iscsi->rx_offset], data, len );
1645 if ( ( iscsi->rx_offset + len ) >= sizeof ( iscsi->rx_bhs ) ) {
1646 DBGC2 ( iscsi, "iSCSI %p received PDU opcode %#x len %#x\n",
1647 iscsi, iscsi->rx_bhs.common.opcode,
1648 ISCSI_DATA_LEN ( iscsi->rx_bhs.common.lengths ) );
1649 }
1650 return 0;
1651}
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 1664 of file iscsi.c.

1666 {
1667 /* Do nothing */
1668 return 0;
1669}

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 1683 of file iscsi.c.

1684 {
1685 struct iscsi_bhs_common_response *response
1686 = &iscsi->rx_bhs.common_response;
1687
1688 /* Update cmdsn and statsn */
1689 iscsi->cmdsn = ntohl ( response->expcmdsn );
1690 iscsi->statsn = ntohl ( response->statsn );
1691
1692 switch ( response->opcode & ISCSI_OPCODE_MASK ) {
1694 return iscsi_rx_login_response ( iscsi, data, len, remaining );
1696 return iscsi_rx_scsi_response ( iscsi, data, len, remaining );
1698 return iscsi_rx_data_in ( iscsi, data, len, remaining );
1699 case ISCSI_OPCODE_R2T:
1700 return iscsi_rx_r2t ( iscsi, data, len, remaining );
1702 return iscsi_rx_nop_in ( iscsi, data, len, remaining );
1703 default:
1704 if ( remaining )
1705 return 0;
1706 DBGC ( iscsi, "iSCSI %p unknown opcode %02x\n", iscsi,
1707 response->opcode );
1708 return -ENOTSUP_OPCODE;
1709 }
1710}
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:474
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:1349
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:515
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:646
#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 1727 of file iscsi.c.

1729 {
1730 struct iscsi_bhs_common *common = &iscsi->rx_bhs.common;
1731 int ( * rx ) ( struct iscsi_session *iscsi, const void *data,
1732 size_t len, size_t remaining );
1733 enum iscsi_rx_state next_state;
1734 size_t frag_len;
1735 size_t remaining;
1736 int rc;
1737
1738 while ( 1 ) {
1739 switch ( iscsi->rx_state ) {
1740 case ISCSI_RX_BHS:
1741 rx = iscsi_rx_bhs;
1742 iscsi->rx_len = sizeof ( iscsi->rx_bhs );
1743 next_state = ISCSI_RX_AHS;
1744 break;
1745 case ISCSI_RX_AHS:
1747 iscsi->rx_len = 4 * ISCSI_AHS_LEN ( common->lengths );
1748 next_state = ISCSI_RX_DATA;
1749 break;
1750 case ISCSI_RX_DATA:
1751 rx = iscsi_rx_data;
1752 iscsi->rx_len = ISCSI_DATA_LEN ( common->lengths );
1753 next_state = ISCSI_RX_DATA_PADDING;
1754 break;
1757 iscsi->rx_len = ISCSI_DATA_PAD_LEN ( common->lengths );
1758 next_state = ISCSI_RX_BHS;
1759 break;
1760 default:
1761 assert ( 0 );
1762 rc = -EINVAL;
1763 goto done;
1764 }
1765
1766 frag_len = iscsi->rx_len - iscsi->rx_offset;
1767 if ( frag_len > iob_len ( iobuf ) )
1768 frag_len = iob_len ( iobuf );
1769 remaining = iscsi->rx_len - iscsi->rx_offset - frag_len;
1770 if ( ( rc = rx ( iscsi, iobuf->data, frag_len,
1771 remaining ) ) != 0 ) {
1772 DBGC ( iscsi, "iSCSI %p could not process received "
1773 "data: %s\n", iscsi, strerror ( rc ) );
1774 goto done;
1775 }
1776
1777 iscsi->rx_offset += frag_len;
1778 iob_pull ( iobuf, frag_len );
1779
1780 /* If all the data for this state has not yet been
1781 * received, stay in this state for now.
1782 */
1783 if ( iscsi->rx_offset != iscsi->rx_len ) {
1784 rc = 0;
1785 goto done;
1786 }
1787
1788 iscsi->rx_state = next_state;
1789 iscsi->rx_offset = 0;
1790 }
1791
1792 done:
1793 /* Free I/O buffer */
1794 free_iob ( iobuf );
1795
1796 /* Destroy session on error */
1797 if ( rc != 0 )
1798 iscsi_close ( iscsi, rc );
1799
1800 return rc;
1801}
struct bofm_section_header done
Definition bofm_test.c:46
static size_t iob_len(struct io_buffer *iobuf)
Calculate length of data in an I/O buffer.
Definition iobuf.h:220
#define iob_pull(iobuf, len)
Definition iobuf.h:167
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:1683
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:1664
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:1642
#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 1811 of file iscsi.c.

1812 {
1813 va_list tmp;
1814 struct sockaddr *peer;
1815 int rc;
1816
1817 /* Intercept redirects to a LOCATION_SOCKET and record the IP
1818 * address for the iBFT. This is a bit of a hack, but avoids
1819 * inventing an ioctl()-style call to retrieve the socket
1820 * address from a data-xfer interface.
1821 */
1822 if ( type == LOCATION_SOCKET ) {
1823 va_copy ( tmp, args );
1824 ( void ) va_arg ( tmp, int ); /* Discard "semantics" */
1825 peer = va_arg ( tmp, struct sockaddr * );
1826 memcpy ( &iscsi->target_sockaddr, peer,
1827 sizeof ( iscsi->target_sockaddr ) );
1828 va_end ( tmp );
1829 }
1830
1831 /* Redirect to new location */
1832 if ( ( rc = xfer_vreopen ( &iscsi->socket, type, args ) ) != 0 )
1833 goto err;
1834
1835 return 0;
1836
1837 err:
1838 iscsi_close ( iscsi, rc );
1839 return rc;
1840}
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:234
@ 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 1867 of file iscsi.c.

1867 {
1868
1869 if ( ( ( iscsi->status & ISCSI_STATUS_PHASE_MASK ) ==
1871 ( iscsi->command == NULL ) ) {
1872 /* We cannot handle concurrent commands */
1873 return 1;
1874 } else {
1875 return 0;
1876 }
1877}

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 1887 of file iscsi.c.

1889 {
1890
1891 /* This iSCSI implementation cannot handle multiple concurrent
1892 * commands or commands arriving before login is complete.
1893 */
1894 if ( iscsi_scsi_window ( iscsi ) == 0 ) {
1895 DBGC ( iscsi, "iSCSI %p cannot handle concurrent commands\n",
1896 iscsi );
1897 return -EOPNOTSUPP;
1898 }
1899
1900 /* Store command */
1901 iscsi->command = malloc ( sizeof ( *command ) );
1902 if ( ! iscsi->command )
1903 return -ENOMEM;
1904 memcpy ( iscsi->command, command, sizeof ( *command ) );
1905
1906 /* Assign new ITT */
1907 iscsi_new_itt ( iscsi );
1908
1909 /* Start sending command */
1910 iscsi_start_command ( iscsi );
1911
1912 /* Attach to parent interface and return */
1913 intf_plug_plug ( &iscsi->data, parent );
1914 return iscsi->itt;
1915}
#define EOPNOTSUPP
Operation not supported on socket.
Definition errno.h:648
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:1867
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 1923 of file iscsi.c.

1924 {
1925 unsigned int max_count;
1926
1927 /* Limit maximum number of blocks per transfer to fit MaxBurstLength */
1928 if ( capacity->blksize ) {
1929 max_count = ( iscsi->max_burst_len / capacity->blksize );
1930 if ( max_count < capacity->max_count )
1931 capacity->max_count = max_count;
1932 }
1933}
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 1941 of file iscsi.c.

1941 {
1942
1943 return &iscsi->desc;
1944}
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 1966 of file iscsi.c.

1966 {
1967
1968 /* Restart interface */
1969 intf_restart ( &iscsi->data, rc );
1970
1971 /* Treat unsolicited command closures mid-command as fatal,
1972 * because we have no code to handle partially-completed PDUs.
1973 */
1974 if ( iscsi->command != NULL )
1975 iscsi_close ( iscsi, ( ( rc == 0 ) ? -ECANCELED : rc ) );
1976}
#define ECANCELED
Operation canceled.
Definition errno.h:387

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 2037 of file iscsi.c.

2038 {
2039 char *rp_copy;
2040 char *rp_comp[NUM_RP_COMPONENTS];
2041 char *rp;
2042 int skip = 0;
2043 int i = 0;
2044 int rc;
2045
2046 /* Create modifiable copy of root path */
2047 rp_copy = strdup ( root_path );
2048 if ( ! rp_copy ) {
2049 rc = -ENOMEM;
2050 goto err_strdup;
2051 }
2052 rp = rp_copy;
2053
2054 /* Split root path into component parts */
2055 while ( 1 ) {
2056 rp_comp[i++] = rp;
2057 if ( i == NUM_RP_COMPONENTS )
2058 break;
2059 for ( ; ( ( *rp != ':' ) || skip ) ; rp++ ) {
2060 if ( ! *rp ) {
2061 DBGC ( iscsi, "iSCSI %p root path \"%s\" "
2062 "too short\n", iscsi, root_path );
2064 goto err_split;
2065 } else if ( *rp == '[' ) {
2066 skip = 1;
2067 } else if ( *rp == ']' ) {
2068 skip = 0;
2069 }
2070 }
2071 *(rp++) = '\0';
2072 }
2073
2074 /* Use root path components to configure iSCSI session */
2075 iscsi->target_address = strdup ( rp_comp[RP_SERVERNAME] );
2076 if ( ! iscsi->target_address ) {
2077 rc = -ENOMEM;
2078 goto err_servername;
2079 }
2080 iscsi->target_port = strtoul ( rp_comp[RP_PORT], NULL, 10 );
2081 if ( ! iscsi->target_port )
2082 iscsi->target_port = ISCSI_PORT;
2083 if ( ( rc = scsi_parse_lun ( rp_comp[RP_LUN], &iscsi->lun ) ) != 0 ) {
2084 DBGC ( iscsi, "iSCSI %p invalid LUN \"%s\"\n",
2085 iscsi, rp_comp[RP_LUN] );
2086 goto err_lun;
2087 }
2088 iscsi->target_iqn = strdup ( rp_comp[RP_TARGETNAME] );
2089 if ( ! iscsi->target_iqn ) {
2090 rc = -ENOMEM;
2091 goto err_targetname;
2092 }
2093
2094 err_targetname:
2095 err_lun:
2096 err_servername:
2097 err_split:
2098 free ( rp_copy );
2099 err_strdup:
2100 return rc;
2101}
#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 2109 of file iscsi.c.

2109 {
2110 char *hostname;
2111 union uuid uuid;
2112 int len;
2113
2114 /* Fetch relevant settings. Don't worry about freeing on
2115 * error, since iscsi_free() will take care of that anyway.
2116 */
2117 fetch_string_setting_copy ( NULL, &username_setting,
2118 &iscsi->initiator_username );
2119 fetch_string_setting_copy ( NULL, &password_setting,
2120 &iscsi->initiator_password );
2121 fetch_string_setting_copy ( NULL, &reverse_username_setting,
2122 &iscsi->target_username );
2123 fetch_string_setting_copy ( NULL, &reverse_password_setting,
2124 &iscsi->target_password );
2125
2126 /* Use explicit initiator IQN if provided */
2127 fetch_string_setting_copy ( NULL, &initiator_iqn_setting,
2128 &iscsi->initiator_iqn );
2129 if ( iscsi->initiator_iqn )
2130 return 0;
2131
2132 /* Otherwise, try to construct an initiator IQN from the hostname */
2133 fetch_string_setting_copy ( NULL, &hostname_setting, &hostname );
2134 if ( hostname ) {
2135 len = asprintf ( &iscsi->initiator_iqn,
2136 ISCSI_DEFAULT_IQN_PREFIX ":%s", hostname );
2137 free ( hostname );
2138 if ( len < 0 ) {
2139 DBGC ( iscsi, "iSCSI %p could not allocate initiator "
2140 "IQN\n", iscsi );
2141 return -ENOMEM;
2142 }
2143 assert ( iscsi->initiator_iqn );
2144 return 0;
2145 }
2146
2147 /* Otherwise, try to construct an initiator IQN from the UUID */
2148 if ( ( len = fetch_uuid_setting ( NULL, &uuid_setting, &uuid ) ) < 0 ) {
2149 DBGC ( iscsi, "iSCSI %p has no suitable initiator IQN\n",
2150 iscsi );
2152 }
2153 if ( ( len = asprintf ( &iscsi->initiator_iqn,
2155 uuid_ntoa ( &uuid ) ) ) < 0 ) {
2156 DBGC ( iscsi, "iSCSI %p could not allocate initiator IQN\n",
2157 iscsi );
2158 return -ENOMEM;
2159 }
2160 assert ( iscsi->initiator_iqn );
2161
2162 return 0;
2163}
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:1095
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 2172 of file iscsi.c.

2172 {
2173
2174 /* Check for invalid authentication combinations */
2175 if ( ( /* Initiator username without password (or vice-versa) */
2176 ( !! iscsi->initiator_username ) ^
2177 ( !! iscsi->initiator_password ) ) ||
2178 ( /* Target username without password (or vice-versa) */
2179 ( !! iscsi->target_username ) ^
2180 ( !! iscsi->target_password ) ) ||
2181 ( /* Target (reverse) without initiator (forward) */
2182 ( iscsi->target_username &&
2183 ( ! iscsi->initiator_username ) ) ) ) {
2184 DBGC ( iscsi, "iSCSI %p invalid credentials: initiator "
2185 "%sname,%spw, target %sname,%spw\n", iscsi,
2186 ( iscsi->initiator_username ? "" : "no " ),
2187 ( iscsi->initiator_password ? "" : "no " ),
2188 ( iscsi->target_username ? "" : "no " ),
2189 ( iscsi->target_password ? "" : "no " ) );
2191 }
2192
2193 return 0;
2194}
#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 2203 of file iscsi.c.

2203 {
2204 struct iscsi_session *iscsi;
2205 int rc;
2206
2207 /* Sanity check */
2208 if ( ! uri->opaque ) {
2210 goto err_sanity_uri;
2211 }
2212
2213 /* Allocate and initialise structure */
2214 iscsi = zalloc ( sizeof ( *iscsi ) );
2215 if ( ! iscsi ) {
2216 rc = -ENOMEM;
2217 goto err_zalloc;
2218 }
2219 ref_init ( &iscsi->refcnt, iscsi_free );
2220 intf_init ( &iscsi->control, &iscsi_control_desc, &iscsi->refcnt );
2221 intf_init ( &iscsi->data, &iscsi_data_desc, &iscsi->refcnt );
2222 intf_init ( &iscsi->socket, &iscsi_socket_desc, &iscsi->refcnt );
2224 &iscsi->refcnt );
2225 acpi_init ( &iscsi->desc, &ibft_model, &iscsi->refcnt );
2226
2227 /* Parse root path */
2228 if ( ( rc = iscsi_parse_root_path ( iscsi, uri->opaque ) ) != 0 )
2229 goto err_parse_root_path;
2230 /* Set fields not specified by root path */
2231 if ( ( rc = iscsi_fetch_settings ( iscsi ) ) != 0 )
2232 goto err_fetch_settings;
2233 /* Validate authentication */
2234 if ( ( rc = iscsi_check_auth ( iscsi ) ) != 0 )
2235 goto err_check_auth;
2236
2237 /* Sanity checks */
2238 if ( ! iscsi->target_address ) {
2239 DBGC ( iscsi, "iSCSI %p does not yet support discovery\n",
2240 iscsi );
2242 goto err_sanity_address;
2243 }
2244 if ( ! iscsi->target_iqn ) {
2245 DBGC ( iscsi, "iSCSI %p no target address supplied in %s\n",
2246 iscsi, uri->opaque );
2248 goto err_sanity_iqn;
2249 }
2250 DBGC ( iscsi, "iSCSI %p initiator %s\n",iscsi, iscsi->initiator_iqn );
2251 DBGC ( iscsi, "iSCSI %p target %s %s\n",
2252 iscsi, iscsi->target_address, iscsi->target_iqn );
2253
2254 /* Open socket */
2255 if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
2256 goto err_open_connection;
2257
2258 /* Attach SCSI device to parent interface */
2259 if ( ( rc = scsi_open ( parent, &iscsi->control,
2260 &iscsi->lun ) ) != 0 ) {
2261 DBGC ( iscsi, "iSCSI %p could not create SCSI device: %s\n",
2262 iscsi, strerror ( rc ) );
2263 goto err_scsi_open;
2264 }
2265
2266 /* Mortalise self, and return */
2267 ref_put ( &iscsi->refcnt );
2268 return 0;
2269
2270 err_scsi_open:
2271 err_open_connection:
2272 err_sanity_iqn:
2273 err_sanity_address:
2274 err_check_auth:
2275 err_fetch_settings:
2276 err_parse_root_path:
2277 iscsi_close ( iscsi, rc );
2278 ref_put ( &iscsi->refcnt );
2279 err_zalloc:
2280 err_sanity_uri:
2281 return rc;
2282}
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:2172
#define EINVAL_NO_TARGET_IQN
Definition iscsi.c:82
static struct interface_descriptor iscsi_socket_desc
iSCSI socket interface descriptor
Definition iscsi.c:1852
static struct interface_descriptor iscsi_control_desc
iSCSI SCSI command-issuing interface descriptor
Definition iscsi.c:1957
static int iscsi_parse_root_path(struct iscsi_session *iscsi, const char *root_path)
Parse iSCSI root path.
Definition iscsi.c:2037
#define ENOTSUP_DISCOVERY
Definition iscsi.c:110
static int iscsi_fetch_settings(struct iscsi_session *iscsi)
Fetch iSCSI settings.
Definition iscsi.c:2109
#define EINVAL_NO_ROOT_PATH
Definition iscsi.c:78
static struct process_descriptor iscsi_process_desc
iSCSI TX process descriptor
Definition iscsi.c:1627
static struct interface_descriptor iscsi_data_desc
iSCSI SCSI command interface descriptor
Definition iscsi.c:1984
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:718
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:987
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:984
static int iscsi_handle_maxburstlength_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI MaxBurstLength text value.
Definition iscsi.c:959
static int iscsi_handle_chap_c_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_C text value.
Definition iscsi.c:1048
static int iscsi_handle_chap_i_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_I text value.
Definition iscsi.c:1007
static int iscsi_handle_authmethod_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI AuthMethod text value.
Definition iscsi.c:938
static int iscsi_handle_chap_r_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_R text value.
Definition iscsi.c:1132
static int iscsi_handle_chap_n_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI CHAP_N text value.
Definition iscsi.c:1103
static int iscsi_handle_targetaddress_value(struct iscsi_session *iscsi, const char *value)
Handle iSCSI TargetAddress text value.
Definition iscsi.c:908

iSCSI text strings that we want to handle

Definition at line 1215 of file iscsi.c.

1215 {
1216 { "TargetAddress", iscsi_handle_targetaddress_value },
1217 { "MaxBurstLength", iscsi_handle_maxburstlength_value },
1218 { "AuthMethod", iscsi_handle_authmethod_value },
1219 { "CHAP_A", iscsi_handle_chap_a_value },
1220 { "CHAP_I", iscsi_handle_chap_i_value },
1221 { "CHAP_C", iscsi_handle_chap_c_value },
1222 { "CHAP_N", iscsi_handle_chap_n_value },
1223 { "CHAP_R", iscsi_handle_chap_r_value },
1224 { NULL, NULL }
1225};

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:1563
#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 1627 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:1727
static int iscsi_vredirect(struct iscsi_session *iscsi, int type, va_list args)
Handle redirection event.
Definition iscsi.c:1811
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 1843 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:1843

iSCSI socket interface descriptor

Definition at line 1852 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:949
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path(struct iscsi_session *iscsi)
Construct EFI device path for iSCSI device.
Definition efi_path.c:535
#define EFI_INTF_OP
Definition efi.h:381
static void iscsi_scsi_capacity(struct iscsi_session *iscsi, struct block_device_capacity *capacity)
Update SCSI block device capacity.
Definition iscsi.c:1923
static int iscsi_scsi_command(struct iscsi_session *iscsi, struct interface *parent, struct scsi_cmd *command)
Issue iSCSI SCSI command.
Definition iscsi.c:1887
static struct acpi_descriptor * iscsi_describe(struct iscsi_session *iscsi)
Get iSCSI ACPI descriptor.
Definition iscsi.c:1941
A SCSI command.
Definition scsi.c:263

iSCSI SCSI command-issuing interface operations

Definition at line 1947 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:1947
uint32_t control
Control.
Definition myson.h:3

iSCSI SCSI command-issuing interface descriptor

Definition at line 1957 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:1966

iSCSI SCSI command interface operations

Definition at line 1979 of file iscsi.c.

1979 {
1981};

◆ 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:1979

iSCSI SCSI command interface descriptor

Definition at line 1984 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:2203

iSCSI URI opener

Definition at line 2285 of file iscsi.c.

2285 {
2286 .scheme = "iscsi",
2287 .open = iscsi_open,
2288};