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