2 * Copyright (c) 2012 The FreeBSD Foundation
5 * This software was developed by Edward Tomasz Napierala under sponsorship
6 * from the FreeBSD Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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.
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
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]
41 #define ISCSI_BHS_SIZE 48
42 #define ISCSI_HEADER_DIGEST_SIZE 4
43 #define ISCSI_DATA_DIGEST_SIZE 4
45 #define ISCSI_BHS_OPCODE_IMMEDIATE 0x40
47 #define ISCSI_BHS_OPCODE_NOP_OUT 0x00
48 #define ISCSI_BHS_OPCODE_SCSI_COMMAND 0x01
49 #define ISCSI_BHS_OPCODE_TASK_REQUEST 0x02
50 #define ISCSI_BHS_OPCODE_LOGIN_REQUEST 0x03
51 #define ISCSI_BHS_OPCODE_TEXT_REQUEST 0x04
52 #define ISCSI_BHS_OPCODE_SCSI_DATA_OUT 0x05
53 #define ISCSI_BHS_OPCODE_LOGOUT_REQUEST 0x06
55 #define ISCSI_BHS_OPCODE_NOP_IN 0x20
56 #define ISCSI_BHS_OPCODE_SCSI_RESPONSE 0x21
57 #define ISCSI_BHS_OPCODE_TASK_RESPONSE 0x22
58 #define ISCSI_BHS_OPCODE_LOGIN_RESPONSE 0x23
59 #define ISCSI_BHS_OPCODE_TEXT_RESPONSE 0x24
60 #define ISCSI_BHS_OPCODE_SCSI_DATA_IN 0x25
61 #define ISCSI_BHS_OPCODE_LOGOUT_RESPONSE 0x26
62 #define ISCSI_BHS_OPCODE_R2T 0x31
63 #define ISCSI_BHS_OPCODE_ASYNC_MESSAGE 0x32
64 #define ISCSI_BHS_OPCODE_REJECT 0x3f
68 uint8_t bhs_opcode_specific1[3];
69 uint8_t bhs_total_ahs_len;
70 uint8_t bhs_data_segment_len[3];
72 uint8_t bhs_inititator_task_tag[4];
73 uint8_t bhs_opcode_specific4[28];
75 CTASSERT(sizeof(struct iscsi_bhs) == ISCSI_BHS_SIZE);
77 #define BHSSC_FLAGS_F 0x80
78 #define BHSSC_FLAGS_R 0x40
79 #define BHSSC_FLAGS_W 0x20
80 #define BHSSC_FLAGS_ATTR 0x07
82 #define BHSSC_FLAGS_ATTR_UNTAGGED 0
83 #define BHSSC_FLAGS_ATTR_SIMPLE 1
84 #define BHSSC_FLAGS_ATTR_ORDERED 2
85 #define BHSSC_FLAGS_ATTR_HOQ 3
86 #define BHSSC_FLAGS_ATTR_ACA 4
88 struct iscsi_bhs_scsi_command {
91 uint8_t bhssc_reserved[2];
92 uint8_t bhssc_total_ahs_len;
93 uint8_t bhssc_data_segment_len[3];
95 uint32_t bhssc_initiator_task_tag;
96 uint32_t bhssc_expected_data_transfer_length;
98 uint32_t bhssc_expstatsn;
99 uint8_t bhssc_cdb[16];
101 CTASSERT(sizeof(struct iscsi_bhs_scsi_command) == ISCSI_BHS_SIZE);
103 #define BHSSR_FLAGS_RESIDUAL_UNDERFLOW 0x02
104 #define BHSSR_FLAGS_RESIDUAL_OVERFLOW 0x04
106 #define BHSSR_RESPONSE_COMMAND_COMPLETED 0x00
108 struct iscsi_bhs_scsi_response {
109 uint8_t bhssr_opcode;
111 uint8_t bhssr_response;
112 uint8_t bhssr_status;
113 uint8_t bhssr_total_ahs_len;
114 uint8_t bhssr_data_segment_len[3];
115 uint64_t bhssr_reserved;
116 uint32_t bhssr_initiator_task_tag;
117 uint32_t bhssr_snack_tag;
118 uint32_t bhssr_statsn;
119 uint32_t bhssr_expcmdsn;
120 uint32_t bhssr_maxcmdsn;
121 uint32_t bhssr_expdatasn;
122 uint32_t bhssr_bidirectional_read_residual_count;
123 uint32_t bhssr_residual_count;
125 CTASSERT(sizeof(struct iscsi_bhs_scsi_response) == ISCSI_BHS_SIZE);
127 #define BHSTMR_FUNCTION_ABORT_TASK 1
128 #define BHSTMR_FUNCTION_ABORT_TASK_SET 2
129 #define BHSTMR_FUNCTION_CLEAR_ACA 3
130 #define BHSTMR_FUNCTION_CLEAR_TASK_SET 4
131 #define BHSTMR_FUNCTION_LOGICAL_UNIT_RESET 5
132 #define BHSTMR_FUNCTION_TARGET_WARM_RESET 6
133 #define BHSTMR_FUNCTION_TARGET_COLD_RESET 7
134 #define BHSTMR_FUNCTION_TASK_REASSIGN 8
136 struct iscsi_bhs_task_management_request {
137 uint8_t bhstmr_opcode;
138 uint8_t bhstmr_function;
139 uint8_t bhstmr_reserved[2];
140 uint8_t bhstmr_total_ahs_len;
141 uint8_t bhstmr_data_segment_len[3];
143 uint32_t bhstmr_initiator_task_tag;
144 uint32_t bhstmr_referenced_task_tag;
145 uint32_t bhstmr_cmdsn;
146 uint32_t bhstmr_expstatsn;
147 uint32_t bhstmr_refcmdsn;
148 uint32_t bhstmr_expdatasn;
149 uint64_t bhstmr_reserved2;
151 CTASSERT(sizeof(struct iscsi_bhs_task_management_request) == ISCSI_BHS_SIZE);
153 #define BHSTMR_RESPONSE_FUNCTION_COMPLETE 0
154 #define BHSTMR_RESPONSE_FUNCTION_NOT_SUPPORTED 5
156 struct iscsi_bhs_task_management_response {
157 uint8_t bhstmr_opcode;
158 uint8_t bhstmr_flags;
159 uint8_t bhstmr_response;
160 uint8_t bhstmr_reserved;
161 uint8_t bhstmr_total_ahs_len;
162 uint8_t bhstmr_data_segment_len[3];
163 uint64_t bhstmr_reserved2;
164 uint32_t bhstmr_initiator_task_tag;
165 uint32_t bhstmr_reserved3;
166 uint32_t bhstmr_statsn;
167 uint32_t bhstmr_expcmdsn;
168 uint32_t bhstmr_maxcmdsn;
169 uint8_t bhstmr_reserved4[12];
171 CTASSERT(sizeof(struct iscsi_bhs_task_management_response) == ISCSI_BHS_SIZE);
173 #define BHSLR_FLAGS_TRANSIT 0x80
174 #define BHSLR_FLAGS_CONTINUE 0x40
176 #define BHSLR_STAGE_SECURITY_NEGOTIATION 0
177 #define BHSLR_STAGE_OPERATIONAL_NEGOTIATION 1
178 #define BHSLR_STAGE_FULL_FEATURE_PHASE 3 /* Yes, 3. */
180 struct iscsi_bhs_login_request {
181 uint8_t bhslr_opcode;
183 uint8_t bhslr_version_max;
184 uint8_t bhslr_version_min;
185 uint8_t bhslr_total_ahs_len;
186 uint8_t bhslr_data_segment_len[3];
187 uint8_t bhslr_isid[6];
189 uint32_t bhslr_initiator_task_tag;
191 uint16_t bhslr_reserved;
192 uint32_t bhslr_cmdsn;
193 uint32_t bhslr_expstatsn;
194 uint8_t bhslr_reserved2[16];
196 CTASSERT(sizeof(struct iscsi_bhs_login_request) == ISCSI_BHS_SIZE);
198 struct iscsi_bhs_login_response {
199 uint8_t bhslr_opcode;
201 uint8_t bhslr_version_max;
202 uint8_t bhslr_version_active;
203 uint8_t bhslr_total_ahs_len;
204 uint8_t bhslr_data_segment_len[3];
205 uint8_t bhslr_isid[6];
207 uint32_t bhslr_initiator_task_tag;
208 uint32_t bhslr_reserved;
209 uint32_t bhslr_statsn;
210 uint32_t bhslr_expcmdsn;
211 uint32_t bhslr_maxcmdsn;
212 uint8_t bhslr_status_class;
213 uint8_t bhslr_status_detail;
214 uint16_t bhslr_reserved2;
215 uint8_t bhslr_reserved3[8];
217 CTASSERT(sizeof(struct iscsi_bhs_login_response) == ISCSI_BHS_SIZE);
219 #define BHSTR_FLAGS_FINAL 0x80
220 #define BHSTR_FLAGS_CONTINUE 0x40
222 struct iscsi_bhs_text_request {
223 uint8_t bhstr_opcode;
225 uint16_t bhstr_reserved;
226 uint8_t bhstr_total_ahs_len;
227 uint8_t bhstr_data_segment_len[3];
229 uint32_t bhstr_initiator_task_tag;
230 uint32_t bhstr_target_transfer_tag;
231 uint32_t bhstr_cmdsn;
232 uint32_t bhstr_expstatsn;
233 uint8_t bhstr_reserved2[16];
235 CTASSERT(sizeof(struct iscsi_bhs_text_request) == ISCSI_BHS_SIZE);
237 struct iscsi_bhs_text_response {
238 uint8_t bhstr_opcode;
240 uint16_t bhstr_reserved;
241 uint8_t bhstr_total_ahs_len;
242 uint8_t bhstr_data_segment_len[3];
244 uint32_t bhstr_initiator_task_tag;
245 uint32_t bhstr_target_transfer_tag;
246 uint32_t bhstr_statsn;
247 uint32_t bhstr_expcmdsn;
248 uint32_t bhstr_maxcmdsn;
249 uint8_t bhstr_reserved2[12];
251 CTASSERT(sizeof(struct iscsi_bhs_text_response) == ISCSI_BHS_SIZE);
253 #define BHSDO_FLAGS_F 0x80
255 struct iscsi_bhs_data_out {
256 uint8_t bhsdo_opcode;
258 uint8_t bhsdo_reserved[2];
259 uint8_t bhsdo_total_ahs_len;
260 uint8_t bhsdo_data_segment_len[3];
262 uint32_t bhsdo_initiator_task_tag;
263 uint32_t bhsdo_target_transfer_tag;
264 uint32_t bhsdo_reserved2;
265 uint32_t bhsdo_expstatsn;
266 uint32_t bhsdo_reserved3;
267 uint32_t bhsdo_datasn;
268 uint32_t bhsdo_buffer_offset;
269 uint32_t bhsdo_reserved4;
271 CTASSERT(sizeof(struct iscsi_bhs_data_out) == ISCSI_BHS_SIZE);
273 #define BHSDI_FLAGS_F 0x80
274 #define BHSDI_FLAGS_A 0x40
275 #define BHSDI_FLAGS_O 0x04
276 #define BHSDI_FLAGS_U 0x02
277 #define BHSDI_FLAGS_S 0x01
279 struct iscsi_bhs_data_in {
280 uint8_t bhsdi_opcode;
282 uint8_t bhsdi_reserved;
283 uint8_t bhsdi_status;
284 uint8_t bhsdi_total_ahs_len;
285 uint8_t bhsdi_data_segment_len[3];
287 uint32_t bhsdi_initiator_task_tag;
288 uint32_t bhsdi_target_transfer_tag;
289 uint32_t bhsdi_statsn;
290 uint32_t bhsdi_expcmdsn;
291 uint32_t bhsdi_maxcmdsn;
292 uint32_t bhsdi_datasn;
293 uint32_t bhsdi_buffer_offset;
294 uint32_t bhsdi_residual_count;
296 CTASSERT(sizeof(struct iscsi_bhs_data_in) == ISCSI_BHS_SIZE);
298 struct iscsi_bhs_r2t {
299 uint8_t bhsr2t_opcode;
300 uint8_t bhsr2t_flags;
301 uint16_t bhsr2t_reserved;
302 uint8_t bhsr2t_total_ahs_len;
303 uint8_t bhsr2t_data_segment_len[3];
305 uint32_t bhsr2t_initiator_task_tag;
306 uint32_t bhsr2t_target_transfer_tag;
307 uint32_t bhsr2t_statsn;
308 uint32_t bhsr2t_expcmdsn;
309 uint32_t bhsr2t_maxcmdsn;
310 uint32_t bhsr2t_r2tsn;
311 uint32_t bhsr2t_buffer_offset;
312 uint32_t bhsr2t_desired_data_transfer_length;
314 CTASSERT(sizeof(struct iscsi_bhs_r2t) == ISCSI_BHS_SIZE);
316 struct iscsi_bhs_nop_out {
317 uint8_t bhsno_opcode;
319 uint16_t bhsno_reserved;
320 uint8_t bhsno_total_ahs_len;
321 uint8_t bhsno_data_segment_len[3];
323 uint32_t bhsno_initiator_task_tag;
324 uint32_t bhsno_target_transfer_tag;
325 uint32_t bhsno_cmdsn;
326 uint32_t bhsno_expstatsn;
327 uint8_t bhsno_reserved2[16];
329 CTASSERT(sizeof(struct iscsi_bhs_nop_out) == ISCSI_BHS_SIZE);
331 struct iscsi_bhs_nop_in {
332 uint8_t bhsni_opcode;
334 uint16_t bhsni_reserved;
335 uint8_t bhsni_total_ahs_len;
336 uint8_t bhsni_data_segment_len[3];
338 uint32_t bhsni_initiator_task_tag;
339 uint32_t bhsni_target_transfer_tag;
340 uint32_t bhsni_statsn;
341 uint32_t bhsni_expcmdsn;
342 uint32_t bhsni_maxcmdsn;
343 uint8_t bhsno_reserved2[12];
345 CTASSERT(sizeof(struct iscsi_bhs_nop_in) == ISCSI_BHS_SIZE);
347 #define BHSLR_REASON_CLOSE_SESSION 0
348 #define BHSLR_REASON_CLOSE_CONNECTION 1
349 #define BHSLR_REASON_REMOVE_FOR_RECOVERY 2
351 struct iscsi_bhs_logout_request {
352 uint8_t bhslr_opcode;
353 uint8_t bhslr_reason;
354 uint16_t bhslr_reserved;
355 uint8_t bhslr_total_ahs_len;
356 uint8_t bhslr_data_segment_len[3];
357 uint64_t bhslr_reserved2;
358 uint32_t bhslr_initiator_task_tag;
360 uint16_t bhslr_reserved3;
361 uint32_t bhslr_cmdsn;
362 uint32_t bhslr_expstatsn;
363 uint8_t bhslr_reserved4[16];
365 CTASSERT(sizeof(struct iscsi_bhs_logout_request) == ISCSI_BHS_SIZE);
367 #define BHSLR_RESPONSE_CLOSED_SUCCESSFULLY 0
368 #define BHSLR_RESPONSE_RECOVERY_NOT_SUPPORTED 2
370 struct iscsi_bhs_logout_response {
371 uint8_t bhslr_opcode;
373 uint8_t bhslr_response;
374 uint8_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 uint32_t bhslr_reserved3;
380 uint32_t bhslr_statsn;
381 uint32_t bhslr_expcmdsn;
382 uint32_t bhslr_maxcmdsn;
383 uint32_t bhslr_reserved4;
384 uint16_t bhslr_time2wait;
385 uint16_t bhslr_time2retain;
386 uint32_t bhslr_reserved5;
388 CTASSERT(sizeof(struct iscsi_bhs_logout_response) == ISCSI_BHS_SIZE);
390 #define BHSAM_EVENT_TARGET_REQUESTS_LOGOUT 1
391 #define BHSAM_EVENT_TARGET_TERMINATES_CONNECTION 2
392 #define BHSAM_EVENT_TARGET_TERMINATES_SESSION 3
394 struct iscsi_bhs_asynchronous_message {
395 uint8_t bhsam_opcode;
397 uint16_t bhsam_reserved;
398 uint8_t bhsam_total_ahs_len;
399 uint8_t bhsam_data_segment_len[3];
401 uint32_t bhsam_0xffffffff;
402 uint32_t bhsam_reserved2;
403 uint32_t bhsam_statsn;
404 uint32_t bhsam_expcmdsn;
405 uint32_t bhsam_maxcmdsn;
406 uint8_t bhsam_async_event;
407 uint8_t bhsam_async_vcode;
408 uint16_t bhsam_parameter1;
409 uint16_t bhsam_parameter2;
410 uint16_t bhsam_parameter3;
411 uint32_t bhsam_reserved3;
413 CTASSERT(sizeof(struct iscsi_bhs_asynchronous_message) == ISCSI_BHS_SIZE);
415 #define BHSSR_REASON_DATA_DIGEST_ERROR 0x02
416 #define BHSSR_PROTOCOL_ERROR 0x04
417 #define BHSSR_COMMAND_NOT_SUPPORTED 0x05
418 #define BHSSR_INVALID_PDU_FIELD 0x09
420 struct iscsi_bhs_reject {
424 uint8_t bhsr_reserved;
425 uint8_t bhsr_total_ahs_len;
426 uint8_t bhsr_data_segment_len[3];
427 uint64_t bhsr_reserved2;
428 uint32_t bhsr_0xffffffff;
429 uint32_t bhsr_reserved3;
430 uint32_t bhsr_statsn;
431 uint32_t bhsr_expcmdsn;
432 uint32_t bhsr_maxcmdsn;
433 uint32_t bhsr_datasn_r2tsn;
434 uint32_t bhsr_reserved4;
435 uint32_t bhsr_reserved5;
437 CTASSERT(sizeof(struct iscsi_bhs_reject) == ISCSI_BHS_SIZE);
439 #endif /* !ISCSI_PROTO_H */