1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012 The FreeBSD Foundation 5 * 6 * This software was developed by Edward Tomasz Napierala under sponsorship 7 * from the FreeBSD Foundation. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31 #ifndef ISCSI_PROTO_H 32 #define ISCSI_PROTO_H 33 34 #ifndef CTASSERT 35 #define CTASSERT(x) _CTASSERT(x, __LINE__) 36 #define _CTASSERT(x, y) __CTASSERT(x, y) 37 #define __CTASSERT(x, y) typedef char __assert_ ## y [(x) ? 1 : -1] 38 #endif 39 40 #define ISCSI_SNGT(x, y) ((int32_t)(x) - (int32_t)(y) > 0) 41 #define ISCSI_SNLT(x, y) ((int32_t)(x) - (int32_t)(y) < 0) 42 43 #define ISCSI_BHS_SIZE 48 44 #define ISCSI_HEADER_DIGEST_SIZE 4 45 #define ISCSI_DATA_DIGEST_SIZE 4 46 47 #define ISCSI_BHS_OPCODE_IMMEDIATE 0x40 48 49 #define ISCSI_BHS_OPCODE_NOP_OUT 0x00 50 #define ISCSI_BHS_OPCODE_SCSI_COMMAND 0x01 51 #define ISCSI_BHS_OPCODE_TASK_REQUEST 0x02 52 #define ISCSI_BHS_OPCODE_LOGIN_REQUEST 0x03 53 #define ISCSI_BHS_OPCODE_TEXT_REQUEST 0x04 54 #define ISCSI_BHS_OPCODE_SCSI_DATA_OUT 0x05 55 #define ISCSI_BHS_OPCODE_LOGOUT_REQUEST 0x06 56 57 #define ISCSI_BHS_OPCODE_NOP_IN 0x20 58 #define ISCSI_BHS_OPCODE_SCSI_RESPONSE 0x21 59 #define ISCSI_BHS_OPCODE_TASK_RESPONSE 0x22 60 #define ISCSI_BHS_OPCODE_LOGIN_RESPONSE 0x23 61 #define ISCSI_BHS_OPCODE_TEXT_RESPONSE 0x24 62 #define ISCSI_BHS_OPCODE_SCSI_DATA_IN 0x25 63 #define ISCSI_BHS_OPCODE_LOGOUT_RESPONSE 0x26 64 #define ISCSI_BHS_OPCODE_R2T 0x31 65 #define ISCSI_BHS_OPCODE_ASYNC_MESSAGE 0x32 66 #define ISCSI_BHS_OPCODE_REJECT 0x3f 67 68 struct iscsi_bhs { 69 uint8_t bhs_opcode; 70 uint8_t bhs_opcode_specific1[3]; 71 uint8_t bhs_total_ahs_len; 72 uint8_t bhs_data_segment_len[3]; 73 uint64_t bhs_lun; 74 uint8_t bhs_inititator_task_tag[4]; 75 uint8_t bhs_opcode_specific4[28]; 76 }; 77 CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE); 78 79 #define BHSSC_FLAGS_F 0x80 80 #define BHSSC_FLAGS_R 0x40 81 #define BHSSC_FLAGS_W 0x20 82 #define BHSSC_FLAGS_ATTR 0x07 83 84 #define BHSSC_FLAGS_ATTR_UNTAGGED 0 85 #define BHSSC_FLAGS_ATTR_SIMPLE 1 86 #define BHSSC_FLAGS_ATTR_ORDERED 2 87 #define BHSSC_FLAGS_ATTR_HOQ 3 88 #define BHSSC_FLAGS_ATTR_ACA 4 89 90 #define BHSSC_PRI_MASK 0xf0 91 #define BHSSC_PRI_SHIFT 4 92 93 struct iscsi_bhs_scsi_command { 94 uint8_t bhssc_opcode; 95 uint8_t bhssc_flags; 96 uint8_t bhssc_pri; 97 uint8_t bhssc_reserved; 98 uint8_t bhssc_total_ahs_len; 99 uint8_t bhssc_data_segment_len[3]; 100 uint64_t bhssc_lun; 101 uint32_t bhssc_initiator_task_tag; 102 uint32_t bhssc_expected_data_transfer_length; 103 uint32_t bhssc_cmdsn; 104 uint32_t bhssc_expstatsn; 105 uint8_t bhssc_cdb[16]; 106 }; 107 CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE); 108 109 #define BHSSR_FLAGS_RESIDUAL_UNDERFLOW 0x02 110 #define BHSSR_FLAGS_RESIDUAL_OVERFLOW 0x04 111 112 #define BHSSR_RESPONSE_COMMAND_COMPLETED 0x00 113 114 struct iscsi_bhs_scsi_response { 115 uint8_t bhssr_opcode; 116 uint8_t bhssr_flags; 117 uint8_t bhssr_response; 118 uint8_t bhssr_status; 119 uint8_t bhssr_total_ahs_len; 120 uint8_t bhssr_data_segment_len[3]; 121 uint16_t bhssr_status_qualifier; 122 uint16_t bhssr_reserved; 123 uint32_t bhssr_reserved2; 124 uint32_t bhssr_initiator_task_tag; 125 uint32_t bhssr_snack_tag; 126 uint32_t bhssr_statsn; 127 uint32_t bhssr_expcmdsn; 128 uint32_t bhssr_maxcmdsn; 129 uint32_t bhssr_expdatasn; 130 uint32_t bhssr_bidirectional_read_residual_count; 131 uint32_t bhssr_residual_count; 132 }; 133 CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE); 134 135 #define BHSTMR_FUNCTION_ABORT_TASK 1 136 #define BHSTMR_FUNCTION_ABORT_TASK_SET 2 137 #define BHSTMR_FUNCTION_CLEAR_ACA 3 138 #define BHSTMR_FUNCTION_CLEAR_TASK_SET 4 139 #define BHSTMR_FUNCTION_LOGICAL_UNIT_RESET 5 140 #define BHSTMR_FUNCTION_TARGET_WARM_RESET 6 141 #define BHSTMR_FUNCTION_TARGET_COLD_RESET 7 142 #define BHSTMR_FUNCTION_TASK_REASSIGN 8 143 #define BHSTMR_FUNCTION_QUERY_TASK 9 144 #define BHSTMR_FUNCTION_QUERY_TASK_SET 10 145 #define BHSTMR_FUNCTION_I_T_NEXUS_RESET 11 146 #define BHSTMR_FUNCTION_QUERY_ASYNC_EVENT 12 147 148 struct iscsi_bhs_task_management_request { 149 uint8_t bhstmr_opcode; 150 uint8_t bhstmr_function; 151 uint8_t bhstmr_reserved[2]; 152 uint8_t bhstmr_total_ahs_len; 153 uint8_t bhstmr_data_segment_len[3]; 154 uint64_t bhstmr_lun; 155 uint32_t bhstmr_initiator_task_tag; 156 uint32_t bhstmr_referenced_task_tag; 157 uint32_t bhstmr_cmdsn; 158 uint32_t bhstmr_expstatsn; 159 uint32_t bhstmr_refcmdsn; 160 uint32_t bhstmr_expdatasn; 161 uint64_t bhstmr_reserved2; 162 }; 163 CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE); 164 165 #define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0 166 #define BHSTMR_RESPONSE_TASK_DOES_NOT_EXIST 1 167 #define BHSTMR_RESPONSE_LUN_DOES_NOT_EXIST 2 168 #define BHSTMR_RESPONSE_TASK_STILL_ALLEGIANT 3 169 #define BHSTMR_RESPONSE_TASK_ALL_REASS_NOT_SUPP 4 170 #define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5 171 #define BHSTMR_RESPONSE_FUNCTION_AUTH_FAIL 6 172 #define BHSTMR_RESPONSE_FUNCTION_SUCCEEDED 7 173 #define BHSTMR_RESPONSE_FUNCTION_REJECTED 255 174 175 struct iscsi_bhs_task_management_response { 176 uint8_t bhstmr_opcode; 177 uint8_t bhstmr_flags; 178 uint8_t bhstmr_response; 179 uint8_t bhstmr_reserved; 180 uint8_t bhstmr_total_ahs_len; 181 uint8_t bhstmr_data_segment_len[3]; 182 uint8_t bhstmr_additional_reponse_information[3]; 183 uint8_t bhstmr_reserved2[5]; 184 uint32_t bhstmr_initiator_task_tag; 185 uint32_t bhstmr_reserved3; 186 uint32_t bhstmr_statsn; 187 uint32_t bhstmr_expcmdsn; 188 uint32_t bhstmr_maxcmdsn; 189 uint8_t bhstmr_reserved4[12]; 190 }; 191 CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE); 192 193 #define BHSLR_FLAGS_TRANSIT 0x80 194 #define BHSLR_FLAGS_CONTINUE 0x40 195 196 #define BHSLR_STAGE_SECURITY_NEGOTIATION 0 197 #define BHSLR_STAGE_OPERATIONAL_NEGOTIATION 1 198 #define BHSLR_STAGE_FULL_FEATURE_PHASE 3 /* Yes, 3. */ 199 200 struct iscsi_bhs_login_request { 201 uint8_t bhslr_opcode; 202 uint8_t bhslr_flags; 203 uint8_t bhslr_version_max; 204 uint8_t bhslr_version_min; 205 uint8_t bhslr_total_ahs_len; 206 uint8_t bhslr_data_segment_len[3]; 207 uint8_t bhslr_isid[6]; 208 uint16_t bhslr_tsih; 209 uint32_t bhslr_initiator_task_tag; 210 uint16_t bhslr_cid; 211 uint16_t bhslr_reserved; 212 uint32_t bhslr_cmdsn; 213 uint32_t bhslr_expstatsn; 214 uint8_t bhslr_reserved2[16]; 215 }; 216 CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE); 217 218 struct iscsi_bhs_login_response { 219 uint8_t bhslr_opcode; 220 uint8_t bhslr_flags; 221 uint8_t bhslr_version_max; 222 uint8_t bhslr_version_active; 223 uint8_t bhslr_total_ahs_len; 224 uint8_t bhslr_data_segment_len[3]; 225 uint8_t bhslr_isid[6]; 226 uint16_t bhslr_tsih; 227 uint32_t bhslr_initiator_task_tag; 228 uint32_t bhslr_reserved; 229 uint32_t bhslr_statsn; 230 uint32_t bhslr_expcmdsn; 231 uint32_t bhslr_maxcmdsn; 232 uint8_t bhslr_status_class; 233 uint8_t bhslr_status_detail; 234 uint16_t bhslr_reserved2; 235 uint8_t bhslr_reserved3[8]; 236 }; 237 CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE); 238 239 #define BHSTR_FLAGS_FINAL 0x80 240 #define BHSTR_FLAGS_CONTINUE 0x40 241 242 struct iscsi_bhs_text_request { 243 uint8_t bhstr_opcode; 244 uint8_t bhstr_flags; 245 uint16_t bhstr_reserved; 246 uint8_t bhstr_total_ahs_len; 247 uint8_t bhstr_data_segment_len[3]; 248 uint64_t bhstr_lun; 249 uint32_t bhstr_initiator_task_tag; 250 uint32_t bhstr_target_transfer_tag; 251 uint32_t bhstr_cmdsn; 252 uint32_t bhstr_expstatsn; 253 uint8_t bhstr_reserved2[16]; 254 }; 255 CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE); 256 257 struct iscsi_bhs_text_response { 258 uint8_t bhstr_opcode; 259 uint8_t bhstr_flags; 260 uint16_t bhstr_reserved; 261 uint8_t bhstr_total_ahs_len; 262 uint8_t bhstr_data_segment_len[3]; 263 uint64_t bhstr_lun; 264 uint32_t bhstr_initiator_task_tag; 265 uint32_t bhstr_target_transfer_tag; 266 uint32_t bhstr_statsn; 267 uint32_t bhstr_expcmdsn; 268 uint32_t bhstr_maxcmdsn; 269 uint8_t bhstr_reserved2[12]; 270 }; 271 CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE); 272 273 #define BHSDO_FLAGS_F 0x80 274 275 struct iscsi_bhs_data_out { 276 uint8_t bhsdo_opcode; 277 uint8_t bhsdo_flags; 278 uint8_t bhsdo_reserved[2]; 279 uint8_t bhsdo_total_ahs_len; 280 uint8_t bhsdo_data_segment_len[3]; 281 uint64_t bhsdo_lun; 282 uint32_t bhsdo_initiator_task_tag; 283 uint32_t bhsdo_target_transfer_tag; 284 uint32_t bhsdo_reserved2; 285 uint32_t bhsdo_expstatsn; 286 uint32_t bhsdo_reserved3; 287 uint32_t bhsdo_datasn; 288 uint32_t bhsdo_buffer_offset; 289 uint32_t bhsdo_reserved4; 290 }; 291 CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE); 292 293 #define BHSDI_FLAGS_F 0x80 294 #define BHSDI_FLAGS_A 0x40 295 #define BHSDI_FLAGS_O 0x04 296 #define BHSDI_FLAGS_U 0x02 297 #define BHSDI_FLAGS_S 0x01 298 299 struct iscsi_bhs_data_in { 300 uint8_t bhsdi_opcode; 301 uint8_t bhsdi_flags; 302 uint8_t bhsdi_reserved; 303 uint8_t bhsdi_status; 304 uint8_t bhsdi_total_ahs_len; 305 uint8_t bhsdi_data_segment_len[3]; 306 uint64_t bhsdi_lun; 307 uint32_t bhsdi_initiator_task_tag; 308 uint32_t bhsdi_target_transfer_tag; 309 uint32_t bhsdi_statsn; 310 uint32_t bhsdi_expcmdsn; 311 uint32_t bhsdi_maxcmdsn; 312 uint32_t bhsdi_datasn; 313 uint32_t bhsdi_buffer_offset; 314 uint32_t bhsdi_residual_count; 315 }; 316 CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE); 317 318 struct iscsi_bhs_r2t { 319 uint8_t bhsr2t_opcode; 320 uint8_t bhsr2t_flags; 321 uint16_t bhsr2t_reserved; 322 uint8_t bhsr2t_total_ahs_len; 323 uint8_t bhsr2t_data_segment_len[3]; 324 uint64_t bhsr2t_lun; 325 uint32_t bhsr2t_initiator_task_tag; 326 uint32_t bhsr2t_target_transfer_tag; 327 uint32_t bhsr2t_statsn; 328 uint32_t bhsr2t_expcmdsn; 329 uint32_t bhsr2t_maxcmdsn; 330 uint32_t bhsr2t_r2tsn; 331 uint32_t bhsr2t_buffer_offset; 332 uint32_t bhsr2t_desired_data_transfer_length; 333 }; 334 CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE); 335 336 struct iscsi_bhs_nop_out { 337 uint8_t bhsno_opcode; 338 uint8_t bhsno_flags; 339 uint16_t bhsno_reserved; 340 uint8_t bhsno_total_ahs_len; 341 uint8_t bhsno_data_segment_len[3]; 342 uint64_t bhsno_lun; 343 uint32_t bhsno_initiator_task_tag; 344 uint32_t bhsno_target_transfer_tag; 345 uint32_t bhsno_cmdsn; 346 uint32_t bhsno_expstatsn; 347 uint8_t bhsno_reserved2[16]; 348 }; 349 CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE); 350 351 struct iscsi_bhs_nop_in { 352 uint8_t bhsni_opcode; 353 uint8_t bhsni_flags; 354 uint16_t bhsni_reserved; 355 uint8_t bhsni_total_ahs_len; 356 uint8_t bhsni_data_segment_len[3]; 357 uint64_t bhsni_lun; 358 uint32_t bhsni_initiator_task_tag; 359 uint32_t bhsni_target_transfer_tag; 360 uint32_t bhsni_statsn; 361 uint32_t bhsni_expcmdsn; 362 uint32_t bhsni_maxcmdsn; 363 uint8_t bhsno_reserved2[12]; 364 }; 365 CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE); 366 367 #define BHSLR_REASON_CLOSE_SESSION 0 368 #define BHSLR_REASON_CLOSE_CONNECTION 1 369 #define BHSLR_REASON_REMOVE_FOR_RECOVERY 2 370 371 struct iscsi_bhs_logout_request { 372 uint8_t bhslr_opcode; 373 uint8_t bhslr_reason; 374 uint16_t bhslr_reserved; 375 uint8_t bhslr_total_ahs_len; 376 uint8_t bhslr_data_segment_len[3]; 377 uint64_t bhslr_reserved2; 378 uint32_t bhslr_initiator_task_tag; 379 uint16_t bhslr_cid; 380 uint16_t bhslr_reserved3; 381 uint32_t bhslr_cmdsn; 382 uint32_t bhslr_expstatsn; 383 uint8_t bhslr_reserved4[16]; 384 }; 385 CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE); 386 387 #define BHSLR_RESPONSE_CLOSED_SUCCESSFULLY 0 388 #define BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED 2 389 390 struct iscsi_bhs_logout_response { 391 uint8_t bhslr_opcode; 392 uint8_t bhslr_flags; 393 uint8_t bhslr_response; 394 uint8_t bhslr_reserved; 395 uint8_t bhslr_total_ahs_len; 396 uint8_t bhslr_data_segment_len[3]; 397 uint64_t bhslr_reserved2; 398 uint32_t bhslr_initiator_task_tag; 399 uint32_t bhslr_reserved3; 400 uint32_t bhslr_statsn; 401 uint32_t bhslr_expcmdsn; 402 uint32_t bhslr_maxcmdsn; 403 uint32_t bhslr_reserved4; 404 uint16_t bhslr_time2wait; 405 uint16_t bhslr_time2retain; 406 uint32_t bhslr_reserved5; 407 }; 408 CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE); 409 410 #define BHSAM_EVENT_TARGET_REQUESTS_LOGOUT 1 411 #define BHSAM_EVENT_TARGET_TERMINATES_CONNECTION 2 412 #define BHSAM_EVENT_TARGET_TERMINATES_SESSION 3 413 414 struct iscsi_bhs_asynchronous_message { 415 uint8_t bhsam_opcode; 416 uint8_t bhsam_flags; 417 uint16_t bhsam_reserved; 418 uint8_t bhsam_total_ahs_len; 419 uint8_t bhsam_data_segment_len[3]; 420 uint64_t bhsam_lun; 421 uint32_t bhsam_0xffffffff; 422 uint32_t bhsam_reserved2; 423 uint32_t bhsam_statsn; 424 uint32_t bhsam_expcmdsn; 425 uint32_t bhsam_maxcmdsn; 426 uint8_t bhsam_async_event; 427 uint8_t bhsam_async_vcode; 428 uint16_t bhsam_parameter1; 429 uint16_t bhsam_parameter2; 430 uint16_t bhsam_parameter3; 431 uint32_t bhsam_reserved3; 432 }; 433 CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE); 434 435 #define BHSSR_REASON_DATA_DIGEST_ERROR 0x02 436 #define BHSSR_PROTOCOL_ERROR 0x04 437 #define BHSSR_COMMAND_NOT_SUPPORTED 0x05 438 #define BHSSR_INVALID_PDU_FIELD 0x09 439 440 struct iscsi_bhs_reject { 441 uint8_t bhsr_opcode; 442 uint8_t bhsr_flags; 443 uint8_t bhsr_reason; 444 uint8_t bhsr_reserved; 445 uint8_t bhsr_total_ahs_len; 446 uint8_t bhsr_data_segment_len[3]; 447 uint64_t bhsr_reserved2; 448 uint32_t bhsr_0xffffffff; 449 uint32_t bhsr_reserved3; 450 uint32_t bhsr_statsn; 451 uint32_t bhsr_expcmdsn; 452 uint32_t bhsr_maxcmdsn; 453 uint32_t bhsr_datasn_r2tsn; 454 uint32_t bhsr_reserved4; 455 uint32_t bhsr_reserved5; 456 }; 457 CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE); 458 459 #endif /* !ISCSI_PROTO_H */ 460