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