009ea47eb2
Reviewed by: ken (parts) Approved by: re (delphij) Sponsored by: FreeBSD Foundation
440 lines
13 KiB
C
440 lines
13 KiB
C
/*-
|
|
* Copyright (c) 2012 The FreeBSD Foundation
|
|
* All rights reserved.
|
|
*
|
|
* This software was developed by Edward Tomasz Napierala under sponsorship
|
|
* from the FreeBSD Foundation.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
#ifndef ISCSI_PROTO_H
|
|
#define ISCSI_PROTO_H
|
|
|
|
#ifndef CTASSERT
|
|
#define CTASSERT(x) _CTASSERT(x, __LINE__)
|
|
#define _CTASSERT(x, y) __CTASSERT(x, y)
|
|
#define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1]
|
|
#endif
|
|
|
|
#define ISCSI_BHS_SIZE 48
|
|
#define ISCSI_HEADER_DIGEST_SIZE 4
|
|
#define ISCSI_DATA_DIGEST_SIZE 4
|
|
|
|
#define ISCSI_BHS_OPCODE_IMMEDIATE 0x40
|
|
|
|
#define ISCSI_BHS_OPCODE_NOP_OUT 0x00
|
|
#define ISCSI_BHS_OPCODE_SCSI_COMMAND 0x01
|
|
#define ISCSI_BHS_OPCODE_TASK_REQUEST 0x02
|
|
#define ISCSI_BHS_OPCODE_LOGIN_REQUEST 0x03
|
|
#define ISCSI_BHS_OPCODE_TEXT_REQUEST 0x04
|
|
#define ISCSI_BHS_OPCODE_SCSI_DATA_OUT 0x05
|
|
#define ISCSI_BHS_OPCODE_LOGOUT_REQUEST 0x06
|
|
|
|
#define ISCSI_BHS_OPCODE_NOP_IN 0x20
|
|
#define ISCSI_BHS_OPCODE_SCSI_RESPONSE 0x21
|
|
#define ISCSI_BHS_OPCODE_TASK_RESPONSE 0x22
|
|
#define ISCSI_BHS_OPCODE_LOGIN_RESPONSE 0x23
|
|
#define ISCSI_BHS_OPCODE_TEXT_RESPONSE 0x24
|
|
#define ISCSI_BHS_OPCODE_SCSI_DATA_IN 0x25
|
|
#define ISCSI_BHS_OPCODE_LOGOUT_RESPONSE 0x26
|
|
#define ISCSI_BHS_OPCODE_R2T 0x31
|
|
#define ISCSI_BHS_OPCODE_ASYNC_MESSAGE 0x32
|
|
#define ISCSI_BHS_OPCODE_REJECT 0x3f
|
|
|
|
struct iscsi_bhs {
|
|
uint8_t bhs_opcode;
|
|
uint8_t bhs_opcode_specific1[3];
|
|
uint8_t bhs_total_ahs_len;
|
|
uint8_t bhs_data_segment_len[3];
|
|
uint64_t bhs_lun;
|
|
uint8_t bhs_inititator_task_tag[4];
|
|
uint8_t bhs_opcode_specific4[28];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSSC_FLAGS_F 0x80
|
|
#define BHSSC_FLAGS_R 0x40
|
|
#define BHSSC_FLAGS_W 0x20
|
|
#define BHSSC_FLAGS_ATTR 0x07
|
|
|
|
#define BHSSC_FLAGS_ATTR_UNTAGGED 0
|
|
#define BHSSC_FLAGS_ATTR_SIMPLE 1
|
|
#define BHSSC_FLAGS_ATTR_ORDERED 2
|
|
#define BHSSC_FLAGS_ATTR_HOQ 3
|
|
#define BHSSC_FLAGS_ATTR_ACA 4
|
|
|
|
struct iscsi_bhs_scsi_command {
|
|
uint8_t bhssc_opcode;
|
|
uint8_t bhssc_flags;
|
|
uint8_t bhssc_reserved[2];
|
|
uint8_t bhssc_total_ahs_len;
|
|
uint8_t bhssc_data_segment_len[3];
|
|
uint64_t bhssc_lun;
|
|
uint32_t bhssc_initiator_task_tag;
|
|
uint32_t bhssc_expected_data_transfer_length;
|
|
uint32_t bhssc_cmdsn;
|
|
uint32_t bhssc_expstatsn;
|
|
uint8_t bhssc_cdb[16];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSSR_FLAGS_RESIDUAL_UNDERFLOW 0x02
|
|
#define BHSSR_FLAGS_RESIDUAL_OVERFLOW 0x04
|
|
|
|
#define BHSSR_RESPONSE_COMMAND_COMPLETED 0x00
|
|
|
|
struct iscsi_bhs_scsi_response {
|
|
uint8_t bhssr_opcode;
|
|
uint8_t bhssr_flags;
|
|
uint8_t bhssr_response;
|
|
uint8_t bhssr_status;
|
|
uint8_t bhssr_total_ahs_len;
|
|
uint8_t bhssr_data_segment_len[3];
|
|
uint64_t bhssr_reserved;
|
|
uint32_t bhssr_initiator_task_tag;
|
|
uint32_t bhssr_snack_tag;
|
|
uint32_t bhssr_statsn;
|
|
uint32_t bhssr_expcmdsn;
|
|
uint32_t bhssr_maxcmdsn;
|
|
uint32_t bhssr_expdatasn;
|
|
uint32_t bhssr_bidirectional_read_residual_count;
|
|
uint32_t bhssr_residual_count;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSTMR_FUNCTION_ABORT_TASK 1
|
|
#define BHSTMR_FUNCTION_ABORT_TASK_SET 2
|
|
#define BHSTMR_FUNCTION_CLEAR_ACA 3
|
|
#define BHSTMR_FUNCTION_CLEAR_TASK_SET 4
|
|
#define BHSTMR_FUNCTION_LOGICAL_UNIT_RESET 5
|
|
#define BHSTMR_FUNCTION_TARGET_WARM_RESET 6
|
|
#define BHSTMR_FUNCTION_TARGET_COLD_RESET 7
|
|
#define BHSTMR_FUNCTION_TASK_REASSIGN 8
|
|
|
|
struct iscsi_bhs_task_management_request {
|
|
uint8_t bhstmr_opcode;
|
|
uint8_t bhstmr_function;
|
|
uint8_t bhstmr_reserved[2];
|
|
uint8_t bhstmr_total_ahs_len;
|
|
uint8_t bhstmr_data_segment_len[3];
|
|
uint64_t bhstmr_lun;
|
|
uint32_t bhstmr_initiator_task_tag;
|
|
uint32_t bhstmr_referenced_task_tag;
|
|
uint32_t bhstmr_cmdsn;
|
|
uint32_t bhstmr_expstatsn;
|
|
uint32_t bhstmr_refcmdsn;
|
|
uint32_t bhstmr_expdatasn;
|
|
uint64_t bhstmr_reserved2;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0
|
|
#define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5
|
|
|
|
struct iscsi_bhs_task_management_response {
|
|
uint8_t bhstmr_opcode;
|
|
uint8_t bhstmr_flags;
|
|
uint8_t bhstmr_response;
|
|
uint8_t bhstmr_reserved;
|
|
uint8_t bhstmr_total_ahs_len;
|
|
uint8_t bhstmr_data_segment_len[3];
|
|
uint64_t bhstmr_reserved2;
|
|
uint32_t bhstmr_initiator_task_tag;
|
|
uint32_t bhstmr_reserved3;
|
|
uint32_t bhstmr_statsn;
|
|
uint32_t bhstmr_expcmdsn;
|
|
uint32_t bhstmr_maxcmdsn;
|
|
uint8_t bhstmr_reserved4[12];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSLR_FLAGS_TRANSIT 0x80
|
|
#define BHSLR_FLAGS_CONTINUE 0x40
|
|
|
|
#define BHSLR_STAGE_SECURITY_NEGOTIATION 0
|
|
#define BHSLR_STAGE_OPERATIONAL_NEGOTIATION 1
|
|
#define BHSLR_STAGE_FULL_FEATURE_PHASE 3 /* Yes, 3. */
|
|
|
|
struct iscsi_bhs_login_request {
|
|
uint8_t bhslr_opcode;
|
|
uint8_t bhslr_flags;
|
|
uint8_t bhslr_version_max;
|
|
uint8_t bhslr_version_min;
|
|
uint8_t bhslr_total_ahs_len;
|
|
uint8_t bhslr_data_segment_len[3];
|
|
uint8_t bhslr_isid[6];
|
|
uint16_t bhslr_tsih;
|
|
uint32_t bhslr_initiator_task_tag;
|
|
uint16_t bhslr_cid;
|
|
uint16_t bhslr_reserved;
|
|
uint32_t bhslr_cmdsn;
|
|
uint32_t bhslr_expstatsn;
|
|
uint8_t bhslr_reserved2[16];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE);
|
|
|
|
struct iscsi_bhs_login_response {
|
|
uint8_t bhslr_opcode;
|
|
uint8_t bhslr_flags;
|
|
uint8_t bhslr_version_max;
|
|
uint8_t bhslr_version_active;
|
|
uint8_t bhslr_total_ahs_len;
|
|
uint8_t bhslr_data_segment_len[3];
|
|
uint8_t bhslr_isid[6];
|
|
uint16_t bhslr_tsih;
|
|
uint32_t bhslr_initiator_task_tag;
|
|
uint32_t bhslr_reserved;
|
|
uint32_t bhslr_statsn;
|
|
uint32_t bhslr_expcmdsn;
|
|
uint32_t bhslr_maxcmdsn;
|
|
uint8_t bhslr_status_class;
|
|
uint8_t bhslr_status_detail;
|
|
uint16_t bhslr_reserved2;
|
|
uint8_t bhslr_reserved3[8];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSTR_FLAGS_FINAL 0x80
|
|
#define BHSTR_FLAGS_CONTINUE 0x40
|
|
|
|
struct iscsi_bhs_text_request {
|
|
uint8_t bhstr_opcode;
|
|
uint8_t bhstr_flags;
|
|
uint16_t bhstr_reserved;
|
|
uint8_t bhstr_total_ahs_len;
|
|
uint8_t bhstr_data_segment_len[3];
|
|
uint64_t bhstr_lun;
|
|
uint32_t bhstr_initiator_task_tag;
|
|
uint32_t bhstr_target_transfer_tag;
|
|
uint32_t bhstr_cmdsn;
|
|
uint32_t bhstr_expstatsn;
|
|
uint8_t bhstr_reserved2[16];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE);
|
|
|
|
struct iscsi_bhs_text_response {
|
|
uint8_t bhstr_opcode;
|
|
uint8_t bhstr_flags;
|
|
uint16_t bhstr_reserved;
|
|
uint8_t bhstr_total_ahs_len;
|
|
uint8_t bhstr_data_segment_len[3];
|
|
uint64_t bhstr_lun;
|
|
uint32_t bhstr_initiator_task_tag;
|
|
uint32_t bhstr_target_transfer_tag;
|
|
uint32_t bhstr_statsn;
|
|
uint32_t bhstr_expcmdsn;
|
|
uint32_t bhstr_maxcmdsn;
|
|
uint8_t bhstr_reserved2[12];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSDO_FLAGS_F 0x80
|
|
|
|
struct iscsi_bhs_data_out {
|
|
uint8_t bhsdo_opcode;
|
|
uint8_t bhsdo_flags;
|
|
uint8_t bhsdo_reserved[2];
|
|
uint8_t bhsdo_total_ahs_len;
|
|
uint8_t bhsdo_data_segment_len[3];
|
|
uint64_t bhsdo_lun;
|
|
uint32_t bhsdo_initiator_task_tag;
|
|
uint32_t bhsdo_target_transfer_tag;
|
|
uint32_t bhsdo_reserved2;
|
|
uint32_t bhsdo_expstatsn;
|
|
uint32_t bhsdo_reserved3;
|
|
uint32_t bhsdo_datasn;
|
|
uint32_t bhsdo_buffer_offset;
|
|
uint32_t bhsdo_reserved4;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSDI_FLAGS_F 0x80
|
|
#define BHSDI_FLAGS_A 0x40
|
|
#define BHSDI_FLAGS_O 0x04
|
|
#define BHSDI_FLAGS_U 0x02
|
|
#define BHSDI_FLAGS_S 0x01
|
|
|
|
struct iscsi_bhs_data_in {
|
|
uint8_t bhsdi_opcode;
|
|
uint8_t bhsdi_flags;
|
|
uint8_t bhsdi_reserved;
|
|
uint8_t bhsdi_status;
|
|
uint8_t bhsdi_total_ahs_len;
|
|
uint8_t bhsdi_data_segment_len[3];
|
|
uint64_t bhsdi_lun;
|
|
uint32_t bhsdi_initiator_task_tag;
|
|
uint32_t bhsdi_target_transfer_tag;
|
|
uint32_t bhsdi_statsn;
|
|
uint32_t bhsdi_expcmdsn;
|
|
uint32_t bhsdi_maxcmdsn;
|
|
uint32_t bhsdi_datasn;
|
|
uint32_t bhsdi_buffer_offset;
|
|
uint32_t bhsdi_residual_count;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE);
|
|
|
|
struct iscsi_bhs_r2t {
|
|
uint8_t bhsr2t_opcode;
|
|
uint8_t bhsr2t_flags;
|
|
uint16_t bhsr2t_reserved;
|
|
uint8_t bhsr2t_total_ahs_len;
|
|
uint8_t bhsr2t_data_segment_len[3];
|
|
uint64_t bhsr2t_lun;
|
|
uint32_t bhsr2t_initiator_task_tag;
|
|
uint32_t bhsr2t_target_transfer_tag;
|
|
uint32_t bhsr2t_statsn;
|
|
uint32_t bhsr2t_expcmdsn;
|
|
uint32_t bhsr2t_maxcmdsn;
|
|
uint32_t bhsr2t_r2tsn;
|
|
uint32_t bhsr2t_buffer_offset;
|
|
uint32_t bhsr2t_desired_data_transfer_length;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE);
|
|
|
|
struct iscsi_bhs_nop_out {
|
|
uint8_t bhsno_opcode;
|
|
uint8_t bhsno_flags;
|
|
uint16_t bhsno_reserved;
|
|
uint8_t bhsno_total_ahs_len;
|
|
uint8_t bhsno_data_segment_len[3];
|
|
uint64_t bhsno_lun;
|
|
uint32_t bhsno_initiator_task_tag;
|
|
uint32_t bhsno_target_transfer_tag;
|
|
uint32_t bhsno_cmdsn;
|
|
uint32_t bhsno_expstatsn;
|
|
uint8_t bhsno_reserved2[16];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE);
|
|
|
|
struct iscsi_bhs_nop_in {
|
|
uint8_t bhsni_opcode;
|
|
uint8_t bhsni_flags;
|
|
uint16_t bhsni_reserved;
|
|
uint8_t bhsni_total_ahs_len;
|
|
uint8_t bhsni_data_segment_len[3];
|
|
uint64_t bhsni_lun;
|
|
uint32_t bhsni_initiator_task_tag;
|
|
uint32_t bhsni_target_transfer_tag;
|
|
uint32_t bhsni_statsn;
|
|
uint32_t bhsni_expcmdsn;
|
|
uint32_t bhsni_maxcmdsn;
|
|
uint8_t bhsno_reserved2[12];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSLR_REASON_CLOSE_SESSION 0
|
|
#define BHSLR_REASON_CLOSE_CONNECTION 1
|
|
#define BHSLR_REASON_REMOVE_FOR_RECOVERY 2
|
|
|
|
struct iscsi_bhs_logout_request {
|
|
uint8_t bhslr_opcode;
|
|
uint8_t bhslr_reason;
|
|
uint16_t bhslr_reserved;
|
|
uint8_t bhslr_total_ahs_len;
|
|
uint8_t bhslr_data_segment_len[3];
|
|
uint64_t bhslr_reserved2;
|
|
uint32_t bhslr_initiator_task_tag;
|
|
uint16_t bhslr_cid;
|
|
uint16_t bhslr_reserved3;
|
|
uint32_t bhslr_cmdsn;
|
|
uint32_t bhslr_expstatsn;
|
|
uint8_t bhslr_reserved4[16];
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSLR_RESPONSE_CLOSED_SUCCESSFULLY 0
|
|
#define BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED 2
|
|
|
|
struct iscsi_bhs_logout_response {
|
|
uint8_t bhslr_opcode;
|
|
uint8_t bhslr_flags;
|
|
uint8_t bhslr_response;
|
|
uint8_t bhslr_reserved;
|
|
uint8_t bhslr_total_ahs_len;
|
|
uint8_t bhslr_data_segment_len[3];
|
|
uint64_t bhslr_reserved2;
|
|
uint32_t bhslr_initiator_task_tag;
|
|
uint32_t bhslr_reserved3;
|
|
uint32_t bhslr_statsn;
|
|
uint32_t bhslr_expcmdsn;
|
|
uint32_t bhslr_maxcmdsn;
|
|
uint32_t bhslr_reserved4;
|
|
uint16_t bhslr_time2wait;
|
|
uint16_t bhslr_time2retain;
|
|
uint32_t bhslr_reserved5;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSAM_EVENT_TARGET_REQUESTS_LOGOUT 1
|
|
#define BHSAM_EVENT_TARGET_TERMINATES_CONNECTION 2
|
|
#define BHSAM_EVENT_TARGET_TERMINATES_SESSION 3
|
|
|
|
struct iscsi_bhs_asynchronous_message {
|
|
uint8_t bhsam_opcode;
|
|
uint8_t bhsam_flags;
|
|
uint16_t bhsam_reserved;
|
|
uint8_t bhsam_total_ahs_len;
|
|
uint8_t bhsam_data_segment_len[3];
|
|
uint64_t bhsam_lun;
|
|
uint32_t bhsam_0xffffffff;
|
|
uint32_t bhsam_reserved2;
|
|
uint32_t bhsam_statsn;
|
|
uint32_t bhsam_expcmdsn;
|
|
uint32_t bhsam_maxcmdsn;
|
|
uint8_t bhsam_async_event;
|
|
uint8_t bhsam_async_vcode;
|
|
uint16_t bhsam_parameter1;
|
|
uint16_t bhsam_parameter2;
|
|
uint16_t bhsam_parameter3;
|
|
uint32_t bhsam_reserved3;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE);
|
|
|
|
#define BHSSR_REASON_DATA_DIGEST_ERROR 0x02
|
|
#define BHSSR_PROTOCOL_ERROR 0x04
|
|
#define BHSSR_COMMAND_NOT_SUPPORTED 0x05
|
|
#define BHSSR_INVALID_PDU_FIELD 0x09
|
|
|
|
struct iscsi_bhs_reject {
|
|
uint8_t bhsr_opcode;
|
|
uint8_t bhsr_flags;
|
|
uint8_t bhsr_reason;
|
|
uint8_t bhsr_reserved;
|
|
uint8_t bhsr_total_ahs_len;
|
|
uint8_t bhsr_data_segment_len[3];
|
|
uint64_t bhsr_reserved2;
|
|
uint32_t bhsr_0xffffffff;
|
|
uint32_t bhsr_reserved3;
|
|
uint32_t bhsr_statsn;
|
|
uint32_t bhsr_expcmdsn;
|
|
uint32_t bhsr_maxcmdsn;
|
|
uint32_t bhsr_datasn_r2tsn;
|
|
uint32_t bhsr_reserved4;
|
|
uint32_t bhsr_reserved5;
|
|
};
|
|
CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE);
|
|
|
|
#endif /* !ISCSI_PROTO_H */
|