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