1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #ifndef _ISCSI_PROTOCOL_H
27 #define	_ISCSI_PROTOCOL_H
28 
29 #pragma ident	"%Z%%M%	%I%	%E% SMI"
30 
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34 
35 /*
36  * iSCSI connection daemon
37  * Copyright (C) 2001 Cisco Systems, Inc.
38  * All rights reserved.
39  *
40  * This file sets up definitions of messages and constants used by the
41  * iSCSI protocol.
42  *
43  */
44 
45 #include <sys/types.h>
46 #include <sys/isa_defs.h>
47 
48 #define	ISCSI_MAX_NAME_LEN	224
49 
50 /* prototypes for iscsi_crc.c */
51 uint32_t iscsi_crc32c(void *address, unsigned long length);
52 uint32_t iscsi_crc32c_continued(void *address, unsigned long length,
53     uint32_t crc);
54 
55 /* iSCSI listen port for incoming connections */
56 #define	ISCSI_LISTEN_PORT 3260
57 
58 /* assumes a pointer to a 3-byte array */
59 #define	ntoh24(p) (((p)[0] << 16) | ((p)[1] << 8) | ((p)[2]))
60 
61 /* assumes a pointer to a 3 byte array, and an integer value */
62 #define	hton24(p, v) {\
63 	p[0] = (((v) >> 16) & 0xFF); \
64 	p[1] = (((v) >> 8) & 0xFF); \
65 	p[2] = ((v) & 0xFF); \
66 }
67 
68 
69 /* for Login min, max, active version fields */
70 #define	ISCSI_MIN_VERSION	0x00
71 #define	ISCSI_DRAFT8_VERSION    0x02
72 #define	ISCSI_DRAFT20_VERSION   0x00
73 #define	ISCSI_MAX_VERSION	0x02
74 
75 /* Min. and Max. length of a PDU we can support */
76 #define	ISCSI_MIN_PDU_LENGTH	(8 << 9)	/* 4KB */
77 #define	ISCSI_MAX_PDU_LENGTH	(0xffffffff)	/* Huge */
78 
79 /* Padding word length */
80 #define	ISCSI_PAD_WORD_LEN		4
81 
82 /* Max. number of Key=Value pairs in a text message */
83 #define	ISCSI_MAX_KEY_VALUE_PAIRS	8192
84 
85 /* text separtor between key value pairs exhanged in login */
86 #define	ISCSI_TEXT_SEPARATOR	'='
87 
88 /* Sun's initiator session ID */
89 #define	ISCSI_SUN_ISID_0	0x40	/* ISID - EN format */
90 #define	ISCSI_SUN_ISID_1	0x00	/* Sec B */
91 #define	ISCSI_SUN_ISID_2	0x00	/* Sec B */
92 #define	ISCSI_SUN_ISID_3	0x2A	/* Sec C - 42 = Sun's EN */
93 
94 /* Reserved value for initiator/target task tag */
95 #define	ISCSI_RSVD_TASK_TAG	0xffffffff
96 
97 /* maximum length for text keys/values */
98 #define	KEY_MAXLEN 64
99 #define	VALUE_MAXLEN 255
100 #define	TARGET_NAME_MAXLEN    VALUE_MAXLEN
101 
102 #define	ISCSI_DEFAULT_MAX_RECV_DATA_SEGMENT_LENGTH 8192
103 
104 /* most PDU types have a final bit */
105 #define	ISCSI_FLAG_FINAL		0x80
106 
107 /*
108  * Strings used during SendTargets requests
109  */
110 #define	ISCSI_TEXT_SEPARATOR	'='
111 #define	TARGETNAME "TargetName="
112 #define	TARGETADDRESS "TargetAddress="
113 
114 /* iSCSI Template Message Header */
115 typedef struct _iscsi_hdr {
116 	uint8_t opcode;
117 	uint8_t flags;	/* Final bit */
118 	uint8_t rsvd2[2];
119 	uint8_t hlength;	/* AHSs total length */
120 	uint8_t dlength[3];	/* Data length */
121 	uint8_t lun[8];
122 	uint32_t itt;	/* Initiator Task Tag */
123 	uint8_t		rsvd3[8];
124 	uint32_t	expstatsn;
125 	uint8_t		other[16];
126 } iscsi_hdr_t;
127 
128 typedef struct _iscsi_rsp_hdr {
129 	uint8_t		opcode;
130 	uint8_t		flags;
131 	uint8_t		rsvd1[3];
132 	uint8_t		dlength[3];
133 	uint8_t		rsvd2[8];
134 	uint32_t	itt;
135 	uint8_t		rsvd3[4];
136 	uint32_t	statsn;
137 	uint32_t	expcmdsn;
138 	uint32_t	maxcmdsn;
139 	uint8_t		rsvd4[12];
140 } iscsi_rsp_hdr_t;
141 
142 /* Opcode encoding bits */
143 #define	ISCSI_OP_RETRY			0x80
144 #define	ISCSI_OP_IMMEDIATE		0x40
145 #define	ISCSI_OPCODE_MASK		0x3F
146 
147 /* Client to Server Message Opcode values */
148 #define	ISCSI_OP_NOOP_OUT		0x00
149 #define	ISCSI_OP_SCSI_CMD		0x01
150 #define	ISCSI_OP_SCSI_TASK_MGT_MSG	0x02
151 #define	ISCSI_OP_LOGIN_CMD		0x03
152 #define	ISCSI_OP_TEXT_CMD		0x04
153 #define	ISCSI_OP_SCSI_DATA		0x05
154 #define	ISCSI_OP_LOGOUT_CMD		0x06
155 #define	ISCSI_OP_SNACK_CMD		0x10
156 
157 /* Server to Client Message Opcode values */
158 #define	ISCSI_OP_NOOP_IN		0x20
159 #define	ISCSI_OP_SCSI_RSP		0x21
160 #define	ISCSI_OP_SCSI_TASK_MGT_RSP	0x22
161 #define	ISCSI_OP_LOGIN_RSP		0x23
162 #define	ISCSI_OP_TEXT_RSP		0x24
163 #define	ISCSI_OP_SCSI_DATA_RSP		0x25
164 #define	ISCSI_OP_LOGOUT_RSP		0x26
165 #define	ISCSI_OP_RTT_RSP		0x31
166 #define	ISCSI_OP_ASYNC_EVENT		0x32
167 #define	ISCSI_OP_REJECT_MSG		0x3f
168 
169 
170 /* SCSI Command Header */
171 typedef struct _iscsi_scsi_cmd_hdr {
172 	uint8_t opcode;
173 	uint8_t flags;
174 	uint8_t rsvd[2];
175 	uint8_t hlength;
176 	uint8_t dlength[3];
177 	uint8_t lun[8];
178 	uint32_t itt;	/* Initiator Task Tag */
179 	uint32_t data_length;
180 	uint32_t cmdsn;
181 	uint32_t expstatsn;
182 	uint8_t scb[16];	/* SCSI Command Block */
183 	/*
184 	 * Additional Data (Command Dependent)
185 	 */
186 } iscsi_scsi_cmd_hdr_t;
187 
188 /* Command PDU flags */
189 #define	ISCSI_FLAG_CMD_READ		0x40
190 #define	ISCSI_FLAG_CMD_WRITE		0x20
191 #define	ISCSI_FLAG_CMD_ATTR_MASK	0x07	/* 3 bits */
192 
193 /* SCSI Command Attribute values */
194 #define	ISCSI_ATTR_UNTAGGED		0
195 #define	ISCSI_ATTR_SIMPLE		1
196 #define	ISCSI_ATTR_ORDERED		2
197 #define	ISCSI_ATTR_HEAD_OF_QUEUE	3
198 #define	ISCSI_ATTR_ACA			4
199 
200 
201 /* SCSI Response Header */
202 typedef struct _iscsi_scsi_rsp_hdr {
203 	uint8_t opcode;
204 	uint8_t flags;
205 	uint8_t response;
206 	uint8_t cmd_status;
207 	uint8_t hlength;
208 	uint8_t dlength[3];
209 	uint8_t rsvd[8];
210 	uint32_t itt;	/* Initiator Task Tag */
211 	uint32_t rsvd1;
212 	uint32_t statsn;
213 	uint32_t expcmdsn;
214 	uint32_t maxcmdsn;
215 	uint32_t expdatasn;
216 	uint32_t bi_residual_count;
217 	uint32_t residual_count;
218 	/*
219 	 * Response or Sense Data (optional)
220 	 */
221 } iscsi_scsi_rsp_hdr_t;
222 
223 /* 10.2.2.3 - Extended CDB Additional Header Segment */
224 
225 typedef struct _iscsi_addl_hdr {
226 	iscsi_scsi_cmd_hdr_t ahs_isch;
227 	uint8_t ahs_hlen_hi;
228 	uint8_t ahs_hlen_lo;
229 	uint8_t ahs_key;
230 	uint8_t ahs_resv;
231 	uint8_t ahs_extscb[4];
232 } iscsi_addl_hdr_t;
233 
234 /* Command Response PDU flags */
235 #define	ISCSI_FLAG_CMD_BIDI_OVERFLOW	0x10
236 #define	ISCSI_FLAG_CMD_BIDI_UNDERFLOW	0x08
237 #define	ISCSI_FLAG_CMD_OVERFLOW		0x04
238 #define	ISCSI_FLAG_CMD_UNDERFLOW	0x02
239 
240 /* iSCSI Status values. Valid if Rsp Selector bit is not set */
241 #define	ISCSI_STATUS_CMD_COMPLETED	0
242 #define	ISCSI_STATUS_TARGET_FAILURE	1
243 #define	ISCSI_STATUS_SUBSYS_FAILURE	2
244 
245 
246 /* Asynchronous Event Header */
247 typedef struct _iscsi_async_evt_hdr {
248 	uint8_t opcode;
249 	uint8_t flags;
250 	uint8_t rsvd2[2];
251 	uint8_t rsvd3;
252 	uint8_t dlength[3];
253 	uint8_t lun[8];
254 	uint8_t rsvd4[8];
255 	uint32_t statsn;
256 	uint32_t expcmdsn;
257 	uint32_t maxcmdsn;
258 	uint8_t async_event;
259 	uint8_t async_vcode;
260 	uint16_t param1;
261 	uint16_t param2;
262 	uint16_t param3;
263 	uint8_t rsvd5[4];
264 } iscsi_async_evt_hdr_t;
265 
266 /* iSCSI Event Indicator values */
267 #define	ISCSI_ASYNC_EVENT_SCSI_EVENT			0
268 #define	ISCSI_ASYNC_EVENT_REQUEST_LOGOUT		1
269 #define	ISCSI_ASYNC_EVENT_DROPPING_CONNECTION		2
270 #define	ISCSI_ASYNC_EVENT_DROPPING_ALL_CONNECTIONS	3
271 #define	ISCSI_ASYNC_EVENT_PARAM_NEGOTIATION		4
272 #define	ISCSI_ASYNC_EVENT_VENDOR_SPECIFIC		255
273 
274 
275 /* NOP-Out Message */
276 typedef struct _iscsi_nop_out_hdr {
277 	uint8_t opcode;
278 	uint8_t flags;
279 	uint16_t rsvd2;
280 	uint8_t rsvd3;
281 	uint8_t dlength[3];
282 	uint8_t lun[8];
283 	uint32_t itt;	/* Initiator Task Tag */
284 	uint32_t ttt;	/* Target Transfer Tag */
285 	uint32_t cmdsn;
286 	uint32_t expstatsn;
287 	uint8_t rsvd4[16];
288 } iscsi_nop_out_hdr_t;
289 
290 
291 /* NOP-In Message */
292 typedef struct _iscsi_nop_in_hdr {
293 	uint8_t opcode;
294 	uint8_t flags;
295 	uint16_t rsvd2;
296 	uint8_t rsvd3;
297 	uint8_t dlength[3];
298 	uint8_t lun[8];
299 	uint32_t itt;	/* Initiator Task Tag */
300 	uint32_t ttt;	/* Target Transfer Tag */
301 	uint32_t statsn;
302 	uint32_t expcmdsn;
303 	uint32_t maxcmdsn;
304 	uint8_t rsvd4[12];
305 } iscsi_nop_in_hdr_t;
306 
307 /* SCSI Task Management Message Header */
308 typedef struct _iscsi_scsi_task_mgt_hdr {
309 	uint8_t opcode;
310 	uint8_t function;
311 	uint8_t rsvd1[2];
312 	uint8_t hlength;
313 	uint8_t dlength[3];
314 	uint8_t lun[8];
315 	uint32_t itt;	/* Initiator Task Tag */
316 	uint32_t rtt;	/* Reference Task Tag */
317 	uint32_t cmdsn;
318 	uint32_t expstatsn;
319 	uint32_t refcmdsn;
320 	uint32_t expdatasn;
321 	uint8_t rsvd2[8];
322 } iscsi_scsi_task_mgt_hdr_t;
323 
324 #define	ISCSI_FLAG_TASK_MGMT_FUNCTION_MASK  0x7F
325 
326 /* Function values */
327 #define	ISCSI_TM_FUNC_ABORT_TASK		1
328 #define	ISCSI_TM_FUNC_ABORT_TASK_SET		2
329 #define	ISCSI_TM_FUNC_CLEAR_ACA			3
330 #define	ISCSI_TM_FUNC_CLEAR_TASK_SET		4
331 #define	ISCSI_TM_FUNC_LOGICAL_UNIT_RESET	5
332 #define	ISCSI_TM_FUNC_TARGET_WARM_RESET		6
333 #define	ISCSI_TM_FUNC_TARGET_COLD_RESET		7
334 #define	ISCSI_TM_FUNC_TASK_REASSIGN		8
335 
336 
337 /* SCSI Task Management Response Header */
338 typedef struct _iscsi_scsi_task_mgt_rsp_hdr {
339 	uint8_t opcode;
340 	uint8_t flags;
341 	uint8_t response;	/* see Response values below */
342 	uint8_t qualifier;
343 	uint8_t hlength;
344 	uint8_t dlength[3];
345 	uint8_t rsvd2[8];
346 	uint32_t itt;	/* Initiator Task Tag */
347 	uint32_t rtt;	/* Reference Task Tag */
348 	uint32_t statsn;
349 	uint32_t expcmdsn;
350 	uint32_t maxcmdsn;
351 	uint8_t rsvd3[12];
352 } iscsi_scsi_task_mgt_rsp_hdr_t;
353 
354 
355 /* Response values */
356 #define	SCSI_TCP_TM_RESP_COMPLETE	0x00
357 #define	SCSI_TCP_TM_RESP_NO_TASK	0x01
358 #define	SCSI_TCP_TM_RESP_NO_LUN		0x02
359 #define	SCSI_TCP_TM_RESP_TASK_ALLEGIANT	0x03
360 #define	SCSI_TCP_TM_RESP_NO_FAILOVER	0x04
361 #define	SCSI_TCP_TM_RESP_IN_PRGRESS	0x05
362 #define	SCSI_TCP_TM_RESP_REJECTED	0xff
363 
364 /* Ready To Transfer Header */
365 typedef struct _iscsi_rtt_hdr {
366 	uint8_t opcode;
367 	uint8_t flags;
368 	uint8_t rsvd2[2];
369 	uint8_t rsvd3[12];
370 	uint32_t itt;	/* Initiator Task Tag */
371 	uint32_t ttt;	/* Target Transfer Tag */
372 	uint32_t statsn;
373 	uint32_t expcmdsn;
374 	uint32_t maxcmdsn;
375 	uint32_t rttsn;
376 	uint32_t data_offset;
377 	uint32_t data_length;
378 } iscsi_rtt_hdr_t;
379 
380 
381 /* SCSI Data Hdr */
382 typedef struct _iscsi_data_hdr {
383 	uint8_t opcode;
384 	uint8_t flags;
385 	uint8_t rsvd2[2];
386 	uint8_t rsvd3;
387 	uint8_t dlength[3];
388 	uint8_t lun[8];
389 	uint32_t itt;
390 	uint32_t ttt;
391 	uint32_t rsvd4;
392 	uint32_t expstatsn;
393 	uint32_t rsvd5;
394 	uint32_t datasn;
395 	uint32_t offset;
396 	uint32_t rsvd6;
397 	/*
398 	 * Payload
399 	 */
400 } iscsi_data_hdr_t;
401 
402 /* SCSI Data Response Hdr */
403 typedef struct _iscsi_data_rsp_hdr {
404 	uint8_t opcode;
405 	uint8_t flags;
406 	uint8_t rsvd2;
407 	uint8_t cmd_status;
408 	uint8_t hlength;
409 	uint8_t dlength[3];
410 	uint8_t lun[8];
411 	uint32_t itt;
412 	uint32_t ttt;
413 	uint32_t statsn;
414 	uint32_t expcmdsn;
415 	uint32_t maxcmdsn;
416 	uint32_t datasn;
417 	uint32_t offset;
418 	uint32_t residual_count;
419 } iscsi_data_rsp_hdr_t;
420 
421 /* Data Response PDU flags */
422 #define	ISCSI_FLAG_DATA_ACK		0x40
423 #define	ISCSI_FLAG_DATA_OVERFLOW	0x04
424 #define	ISCSI_FLAG_DATA_UNDERFLOW	0x02
425 #define	ISCSI_FLAG_DATA_STATUS		0x01
426 
427 
428 /* Text Header */
429 typedef struct _iscsi_text_hdr {
430 	uint8_t opcode;
431 	uint8_t flags;
432 	uint8_t rsvd2[2];
433 	uint8_t hlength;
434 	uint8_t dlength[3];
435 	uint8_t rsvd4[8];
436 	uint32_t itt;
437 	uint32_t ttt;
438 	uint32_t cmdsn;
439 	uint32_t expstatsn;
440 	uint8_t rsvd5[16];
441 	/*
442 	 * Text - key=value pairs
443 	 */
444 } iscsi_text_hdr_t;
445 
446 #define	ISCSI_FLAG_TEXT_CONTINUE	0x40
447 
448 /* Text Response Header */
449 typedef struct _iscsi_text_rsp_hdr {
450 	uint8_t opcode;
451 	uint8_t flags;
452 	uint8_t rsvd2[2];
453 	uint8_t hlength;
454 	uint8_t dlength[3];
455 	uint8_t rsvd4[8];
456 	uint32_t itt;
457 	uint32_t ttt;
458 	uint32_t statsn;
459 	uint32_t expcmdsn;
460 	uint32_t maxcmdsn;
461 	uint8_t rsvd5[12];
462 	/*
463 	 * Text Response - key:value pairs
464 	 */
465 } iscsi_text_rsp_hdr_t;
466 
467 /* Login Header */
468 typedef struct _iscsi_login_hdr {
469 	uint8_t opcode;
470 	uint8_t flags;
471 	uint8_t max_version;	/* Max. version supported */
472 	uint8_t min_version;	/* Min. version supported */
473 	uint8_t hlength;
474 	uint8_t dlength[3];
475 	uint8_t isid[6];	/* Initiator Session ID */
476 	uint16_t tsid;	/* Target Session ID */
477 	uint32_t itt;	/* Initiator Task Tag */
478 	uint16_t cid;
479 	uint16_t rsvd3;
480 	uint32_t cmdsn;
481 	uint32_t expstatsn;
482 	uint8_t rsvd5[16];
483 } iscsi_login_hdr_t;
484 
485 /* Login PDU flags */
486 #define	ISCSI_FLAG_LOGIN_TRANSIT		0x80
487 #define	ISCSI_FLAG_LOGIN_CONTINUE		0x40
488 #define	ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK	0x0C	/* 2 bits */
489 #define	ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK	0x03	/* 2 bits */
490 
491 #define	ISCSI_LOGIN_CURRENT_STAGE(flags) \
492 	((flags & ISCSI_FLAG_LOGIN_CURRENT_STAGE_MASK) >> 2)
493 #define	ISCSI_LOGIN_NEXT_STAGE(flags) \
494 	(flags & ISCSI_FLAG_LOGIN_NEXT_STAGE_MASK)
495 
496 
497 /* Login Response Header */
498 typedef struct _iscsi_login_rsp_hdr {
499 	uint8_t opcode;
500 	uint8_t flags;
501 	uint8_t max_version;	/* Max. version supported */
502 	uint8_t active_version;	/* Active version */
503 	uint8_t hlength;
504 	uint8_t dlength[3];
505 	uint8_t isid[6];	/* Initiator Session ID */
506 	uint16_t tsid;	/* Target Session ID */
507 	uint32_t itt;	/* Initiator Task Tag */
508 	uint32_t rsvd3;
509 	uint32_t statsn;
510 	uint32_t expcmdsn;
511 	uint32_t maxcmdsn;
512 	uint8_t status_class;	/* see Login RSP ststus classes below */
513 	uint8_t status_detail;	/* see Login RSP Status details below */
514 	uint8_t rsvd4[10];
515 } iscsi_login_rsp_hdr_t;
516 
517 /* Login stage (phase) codes for CSG, NSG */
518 #define	ISCSI_SECURITY_NEGOTIATION_STAGE	0
519 #define	ISCSI_OP_PARMS_NEGOTIATION_STAGE	1
520 #define	ISCSI_FULL_FEATURE_PHASE		3
521 
522 /* Login Status response classes */
523 #define	ISCSI_STATUS_CLASS_SUCCESS		0x00
524 #define	ISCSI_STATUS_CLASS_REDIRECT		0x01
525 #define	ISCSI_STATUS_CLASS_INITIATOR_ERR	0x02
526 #define	ISCSI_STATUS_CLASS_TARGET_ERR		0x03
527 
528 /* Login Status response detail codes */
529 /* Class-0 (Success) */
530 #define	ISCSI_LOGIN_STATUS_ACCEPT		0x00
531 
532 /* Class-1 (Redirection) */
533 #define	ISCSI_LOGIN_STATUS_TGT_MOVED_TEMP	0x01
534 #define	ISCSI_LOGIN_STATUS_TGT_MOVED_PERM	0x02
535 
536 /* Class-2 (Initiator Error) */
537 #define	ISCSI_LOGIN_STATUS_INIT_ERR		0x00
538 #define	ISCSI_LOGIN_STATUS_AUTH_FAILED		0x01
539 #define	ISCSI_LOGIN_STATUS_TGT_FORBIDDEN	0x02
540 #define	ISCSI_LOGIN_STATUS_TGT_NOT_FOUND	0x03
541 #define	ISCSI_LOGIN_STATUS_TGT_REMOVED		0x04
542 #define	ISCSI_LOGIN_STATUS_NO_VERSION		0x05
543 #define	ISCSI_LOGIN_STATUS_ISID_ERROR		0x06
544 #define	ISCSI_LOGIN_STATUS_MISSING_FIELDS	0x07
545 #define	ISCSI_LOGIN_STATUS_CONN_ADD_FAILED	0x08
546 #define	ISCSI_LOGIN_STATUS_NO_SESSION_TYPE	0x09
547 #define	ISCSI_LOGIN_STATUS_NO_SESSION		0x0a
548 #define	ISCSI_LOGIN_STATUS_INVALID_REQUEST	0x0b
549 
550 /* Class-3 (Target Error) */
551 #define	ISCSI_LOGIN_STATUS_TARGET_ERROR		0x00
552 #define	ISCSI_LOGIN_STATUS_SVC_UNAVAILABLE	0x01
553 #define	ISCSI_LOGIN_STATUS_NO_RESOURCES		0x02
554 
555 /* Logout Header */
556 typedef struct _iscsi_logout_hdr {
557 	uint8_t opcode;
558 	uint8_t flags;
559 	uint8_t rsvd1[2];
560 	uint8_t hlength;
561 	uint8_t dlength[3];
562 	uint8_t rsvd2[8];
563 	uint32_t itt;	/* Initiator Task Tag */
564 	uint16_t cid;
565 	uint8_t rsvd3[2];
566 	uint32_t cmdsn;
567 	uint32_t expstatsn;
568 	uint8_t rsvd4[16];
569 } iscsi_logout_hdr_t;
570 
571 /* Logout PDU flags */
572 #define	ISCSI_FLAG_LOGOUT_REASON_MASK		0x7F
573 
574 /* logout reason_code values */
575 
576 #define	ISCSI_LOGOUT_REASON_CLOSE_SESSION	0
577 #define	ISCSI_LOGOUT_REASON_CLOSE_CONNECTION	1
578 #define	ISCSI_LOGOUT_REASON_RECOVERY		2
579 #define	ISCSI_LOGOUT_REASON_AEN_REQUEST		3
580 
581 /* Logout Response Header */
582 typedef struct _iscsi_logout_rsp_hdr {
583 	uint8_t opcode;
584 	uint8_t flags;
585 	uint8_t response;	/* see Logout response values below */
586 	uint8_t rsvd2;
587 	uint8_t hlength;
588 	uint8_t dlength[3];
589 	uint8_t rsvd3[8];
590 	uint32_t itt;	/* Initiator Task Tag */
591 	uint32_t rsvd4;
592 	uint32_t statsn;
593 	uint32_t expcmdsn;
594 	uint32_t maxcmdsn;
595 	uint32_t rsvd5;
596 	uint16_t t2wait;
597 	uint16_t t2retain;
598 	uint32_t rsvd6;
599 } iscsi_logout_rsp_hdr_t;
600 
601 /* logout response status values */
602 
603 #define	ISCSI_LOGOUT_SUCCESS		  0
604 #define	ISCSI_LOGOUT_CID_NOT_FOUND	  1
605 #define	ISCSI_LOGOUT_RECOVERY_UNSUPPORTED 2
606 #define	ISCSI_LOGOUT_CLEANUP_FAILED	  3
607 
608 
609 /* SNACK Header */
610 typedef struct _iscsi_snack_hdr {
611 	uint8_t opcode;
612 	uint8_t flags;
613 	uint8_t rsvd2[14];
614 	uint32_t itt;
615 	uint32_t begrun;
616 	uint32_t runlength;
617 	uint32_t expstatsn;
618 	uint32_t rsvd3;
619 	uint32_t expdatasn;
620 	uint8_t rsvd6[8];
621 } iscsi_snack_hdr_t;
622 
623 /* SNACK PDU flags */
624 #define	ISCSI_FLAG_SNACK_TYPE_MASK	0x0F	/* 4 bits */
625 
626 /* Reject Message Header */
627 typedef struct _iscsi_reject_rsp_hdr {
628 	uint8_t opcode;
629 	uint8_t flags;
630 	uint8_t reason;
631 	uint8_t rsvd2;
632 	uint8_t rsvd3;
633 	uint8_t dlength[3];
634 	uint8_t rsvd4[16];
635 	uint32_t statsn;
636 	uint32_t expcmdsn;
637 	uint32_t maxcmdsn;
638 	uint32_t datasn;
639 	uint8_t rsvd5[8];
640 	/*
641 	 * Text - Rejected hdr
642 	 */
643 } iscsi_reject_rsp_hdr_t;
644 
645 /* Reason for Reject */
646 #define	ISCSI_REJECT_CMD_BEFORE_LOGIN		1
647 #define	ISCSI_REJECT_DATA_DIGEST_ERROR		2
648 #define	ISCSI_REJECT_SNACK_REJECT		3
649 #define	ISCSI_REJECT_PROTOCOL_ERROR		4
650 #define	ISCSI_REJECT_CMD_NOT_SUPPORTED		5
651 #define	ISCSI_REJECT_IMM_CMD_REJECT		6
652 #define	ISCSI_REJECT_TASK_IN_PROGRESS		7
653 #define	ISCSI_REJECT_INVALID_DATA_ACK		8
654 #define	ISCSI_REJECT_INVALID_PDU_FIELD		9
655 #define	ISCSI_REJECT_LONG_OPERATION_REJECT	10
656 #define	ISCSI_REJECT_NEGOTIATION_RESET		11
657 #define	ISCSI_REJECT_WAITING_FOR_LOGOUT		12
658 
659 /* Defaults as defined by the iSCSI specification */
660 #define	ISCSI_DEFAULT_IMMEDIATE_DATA		TRUE
661 #define	ISCSI_DEFAULT_INITIALR2T		TRUE
662 #define	ISCSI_DEFAULT_FIRST_BURST_LENGTH	(64 * 1024) /* 64kbytes */
663 #define	ISCSI_DEFAULT_MAX_BURST_LENGTH		(256 * 1024) /* 256kbytes */
664 #define	ISCSI_DEFAULT_DATA_PDU_IN_ORDER		TRUE
665 #define	ISCSI_DEFAULT_DATA_SEQUENCE_IN_ORDER	TRUE
666 #define	ISCSI_DEFAULT_TIME_TO_WAIT		2 /* 2 seconds */
667 #define	ISCSI_DEFAULT_TIME_TO_RETAIN		20 /* 20 seconds */
668 #define	ISCSI_DEFAULT_HEADER_DIGEST		ISCSI_DIGEST_NONE
669 #define	ISCSI_DEFAULT_DATA_DIGEST		ISCSI_DIGEST_NONE
670 #define	ISCSI_DEFAULT_MAX_RECV_SEG_LEN		(64 * 1024)
671 #define	ISCSI_DEFAULT_MAX_XMIT_SEG_LEN		(8 * 1024)
672 #define	ISCSI_DEFAULT_MAX_CONNECTIONS		1
673 #define	ISCSI_DEFAULT_MAX_OUT_R2T		1
674 #define	ISCSI_DEFAULT_ERROR_RECOVERY_LEVEL	0
675 #define	ISCSI_DEFAULT_IFMARKER			FALSE
676 #define	ISCSI_DEFAULT_OFMARKER			FALSE
677 
678 /*
679  * Maximum values from the iSCSI specification
680  */
681 #define	ISCSI_MAX_HEADER_DIGEST			3
682 #define	ISCSI_MAX_DATA_DIGEST			3
683 #define	ISCSI_MAX_TIME2RETAIN			3600
684 #define	ISCSI_MAX_TIME2WAIT			3600
685 #define	ISCSI_MAX_ERROR_RECOVERY_LEVEL		2
686 #define	ISCSI_MAX_FIRST_BURST_LENGTH		0xffffff
687 #define	ISCSI_MAX_BURST_LENGTH			0xffffff
688 #define	ISCSI_MAX_CONNECTIONS			65535
689 #define	ISCSI_MAX_OUTSTANDING_R2T		65535
690 #define	ISCSI_MAX_RECV_DATA_SEGMENT_LENGTH	0xffffff
691 #define	ISCSI_MAX_TPGT_VALUE			65535 /* 16 bit numeric */
692 
693 /*
694  * iqn and eui name prefixes and related defines
695  */
696 #define	ISCSI_IQN_NAME_PREFIX			"iqn"
697 #define	ISCSI_EUI_NAME_PREFIX			"eui"
698 #define	ISCSI_EUI_NAME_LEN			20 /* eui. plus 16 octets */
699 
700 #ifdef __cplusplus
701 }
702 #endif
703 
704 #endif /* _ISCSI_PROTOCOL_H */
705