1 /*
2  * IMPORTANT:  READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
3  * By downloading, copying, installing or using the software you agree
4  * to this license.  If you do not agree to this license, do not
5  * download, install, copy or use the software.
6  *
7  * Intel License Agreement
8  *
9  * Copyright (c) 2000, Intel Corporation
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  *
16  * -Redistributions of source code must retain the above copyright
17  *  notice, this list of conditions and the following disclaimer.
18  *
19  * -Redistributions in binary form must reproduce the above copyright
20  *  notice, this list of conditions and the following disclaimer in the
21  *  documentation and/or other materials provided with the
22  *  distribution.
23  *
24  * -The name of Intel Corporation may not be used to endorse or
25  *  promote products derived from this software without specific prior
26  *  written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL INTEL
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
35  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
37  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
38  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  */
41 #ifndef ISCSI_H
42 #define ISCSI_H
43 
44 #include "iscsiutil.h"
45 
46 /*
47  * iSCSI Version 18
48  */
49 
50 #define ISCSI_VENDOR	"NetBSD"
51 #define ISCSI_PRODUCT	"NetBSD iSCSI"
52 #define ISCSI_VERSION	0
53 
54 /*
55  * Parameters
56  */
57 
58 #define ISCSI_IMMEDIATE_DATA_DFLT            1
59 #define ISCSI_INITIAL_R2T_DFLT               1
60 #define ISCSI_USE_PHASE_COLLAPSED_READ_DFLT  0
61 #define ISCSI_HEADER_LEN                     48
62 #define ISCSI_PORT                           3260	/* Default port */
63 #define ISCSI_OPCODE(HEADER)                 (HEADER[0] & 0x3f)
64 
65 #define ISCSI_FIRST_BURST                    (ISCSI_FIRST_BURST_DFLT)
66 #define ISCSI_DATA_PDU_LENGTH                (ISCSI_DATA_PDU_LENGTH_DFLT)
67 
68 /*
69  * Opcodes
70  */
71 enum {
72 	ISCSI_NOP_OUT       = 0x00,
73 	ISCSI_SCSI_CMD      = 0x01,
74 	ISCSI_TASK_CMD      = 0x02,
75 	ISCSI_LOGIN_CMD     = 0x03,
76 	ISCSI_TEXT_CMD      = 0x04,
77 	ISCSI_WRITE_DATA    = 0x05,
78 	ISCSI_LOGOUT_CMD    = 0x06,
79 	ISCSI_SNACK         = 0x10,	/* not implemented */
80 	ISCSI_NOP_IN        = 0x20,
81 	ISCSI_SCSI_RSP      = 0x21,
82 	ISCSI_TASK_RSP      = 0x22,
83 	ISCSI_LOGIN_RSP     = 0x23,
84 	ISCSI_TEXT_RSP      = 0x24,
85 	ISCSI_READ_DATA     = 0x25,
86 	ISCSI_LOGOUT_RSP    = 0x26,
87 	ISCSI_R2T           = 0x31,
88 	ISCSI_ASYNC         = 0x32,
89 	ISCSI_REJECT        = 0x3f
90 };
91 
92 enum {
93 	ISCSI_AHS_EXTENDED_CDB	= 0x01,
94 	ISCSI_AHS_BIDI_READ	= 0x02
95 };
96 
97 /*
98  * Login Phase
99  */
100 enum {
101 	ISCSI_LOGIN_STATUS_SUCCESS          = 0,
102 	ISCSI_LOGIN_STATUS_REDIRECTION      = 1,
103 	ISCSI_LOGIN_STATUS_INITIATOR_ERROR  = 2,
104 	ISCSI_LOGIN_STATUS_TARGET_ERROR     = 3,
105 
106 	ISCSI_LOGIN_STAGE_SECURITY          = 0,
107 	ISCSI_LOGIN_STAGE_NEGOTIATE         = 1,
108 	ISCSI_LOGIN_STAGE_FULL_FEATURE      = 3
109 };
110 
111 /* detailed return codes for login phase */
112 enum {
113 	ISCSI_LOGIN_DETAIL_SUCCESS = 0x0,
114 	ISCSI_LOGIN_DETAIL_INIT_AUTH_FAILURE = 0x01,
115 	ISCSI_LOGIN_DETAIL_VERSION_NOT_SUPPORTED = 0x05,
116 	ISCSI_LOGIN_DETAIL_NOT_LOGGED_IN = 0x0b
117 };
118 
119 
120 /*
121  * Logout Phase
122  */
123 enum {
124 	ISCSI_LOGOUT_CLOSE_SESSION      = 0,
125 	ISCSI_LOGOUT_CLOSE_CONNECTION   = 1,
126 	ISCSI_LOGOUT_CLOSE_RECOVERY     = 2,
127 
128 	ISCSI_LOGOUT_STATUS_SUCCESS     = 0,
129 	ISCSI_LOGOUT_STATUS_NO_CID      = 1,
130 	ISCSI_LOGOUT_STATUS_NO_RECOVERY = 2,
131 	ISCSI_LOGOUT_STATUS_FAILURE     = 3
132 };
133 
134 
135 /*
136  * Task Command
137  */
138 enum {
139 	ISCSI_TASK_CMD_ABORT_TASK           = 1,
140 	ISCSI_TASK_CMD_ABORT_TASK_SET       = 2,
141 	ISCSI_TASK_CMD_CLEAR_ACA            = 3,
142 	ISCSI_TASK_CMD_CLEAR_TASK_SET       = 4,
143 	ISCSI_TASK_CMD_LOGICAL_UNIT_RESET   = 5,
144 	ISCSI_TASK_CMD_TARGET_WARM_RESET    = 6,
145 	ISCSI_TASK_CMD_TARGET_COLD_RESET    = 7,
146 	ISCSI_TASK_CMD_TARGET_REASSIGN      = 8
147 };
148 
149 typedef struct iscsi_task_cmd_t {
150 	int32_t         immediate;
151 	uint8_t         function;
152 	uint64_t        lun;
153 	uint32_t        tag;
154 	uint32_t        ref_tag;
155 	uint32_t        CmdSN;
156 	uint32_t        ExpStatSN;
157 	uint32_t        RefCmdSN;
158 	uint32_t        ExpDataSN;
159 }               iscsi_task_cmd_t;
160 
161 int             iscsi_task_cmd_encap(uint8_t *header, iscsi_task_cmd_t * cmd);
162 int             iscsi_task_cmd_decap(uint8_t *header, iscsi_task_cmd_t * cmd);
163 
164 
165 /*
166  * Task Response
167  */
168 enum {
169 	ISCSI_TASK_RSP_FUNCTION_COMPLETE  = 0,
170 	ISCSI_TASK_RSP_NO_SUCH_TASK       = 1,
171 	ISCSI_TASK_RSP_NO_SUCH_LUN        = 2,
172 	ISCSI_TASK_RSP_STILL_ALLEGIANT    = 3,
173 	ISCSI_TASK_RSP_NO_FAILOVER        = 4,
174 	ISCSI_TASK_RSP_NO_SUPPORT	  = 5,
175 	ISCSI_TASK_RSP_AUTHORIZED_FAILED  = 6,
176 
177 	ISCSI_TASK_RSP_REJECTED           = 255,
178 
179 	ISCSI_TASK_QUAL_FUNCTION_EXECUTED = 0,
180 	ISCSI_TASK_QUAL_NOT_AUTHORIZED    = 1
181 };
182 
183 typedef struct iscsi_task_rsp_t {
184 	uint8_t         response;
185 	uint32_t        length;
186 	uint32_t        tag;
187 	uint32_t        StatSN;
188 	uint32_t        ExpCmdSN;
189 	uint32_t        MaxCmdSN;
190 }               iscsi_task_rsp_t;
191 
192 int             iscsi_task_rsp_encap(uint8_t *header, iscsi_task_rsp_t * rsp);
193 int             iscsi_task_rsp_decap(uint8_t *header, iscsi_task_rsp_t * rsp);
194 
195 
196 /*
197  * NOP-Out
198  */
199 
200 
201 typedef struct iscsi_nop_out_args_t {
202 	int32_t         immediate;
203 	uint32_t        length;
204 	uint64_t        lun;
205 	uint32_t        tag;
206 	uint32_t        transfer_tag;
207 	uint32_t        CmdSN;
208 	uint32_t        ExpStatSN;
209 	const uint8_t   *data;
210 }               iscsi_nop_out_args_t;
211 
212 int             iscsi_nop_out_encap(uint8_t *header, iscsi_nop_out_args_t * cmd);
213 int             iscsi_nop_out_decap(uint8_t *header, iscsi_nop_out_args_t * cmd);
214 
215 
216 /*
217  * NOP-In
218  */
219 
220 
221 typedef struct iscsi_nop_in_args_t {
222 	uint32_t        length;
223 	uint64_t        lun;
224 	uint32_t        tag;
225 	uint32_t        transfer_tag;
226 	uint32_t        StatSN;
227 	uint32_t        ExpCmdSN;
228 	uint32_t        MaxCmdSN;
229 }               iscsi_nop_in_args_t;
230 
231 int             iscsi_nop_in_encap(uint8_t *header, iscsi_nop_in_args_t * cmd);
232 int             iscsi_nop_in_decap(uint8_t *header, iscsi_nop_in_args_t * cmd);
233 
234 
235 /*
236  * Text Command
237  */
238 
239 
240 typedef struct iscsi_text_cmd_args_t {
241 	int32_t         immediate;
242 	int32_t         final;
243 	int32_t         cont;
244 	uint32_t        length;
245 	uint64_t        lun;
246 	uint32_t        tag;
247 	uint32_t        transfer_tag;
248 	uint32_t        CmdSN;
249 	uint32_t        ExpStatSN;
250 	char           *text;
251 }               iscsi_text_cmd_args_t;
252 
253 int             iscsi_text_cmd_encap(uint8_t *header, iscsi_text_cmd_args_t * cmd);
254 int             iscsi_text_cmd_decap(uint8_t *header, iscsi_text_cmd_args_t * cmd);
255 
256 
257 /*
258  * Text Response
259  */
260 
261 
262 typedef struct iscsi_text_rsp_args_t {
263 	int32_t         final;
264 	int32_t         cont;
265 	uint32_t        length;
266 	uint64_t        lun;
267 	uint32_t        tag;
268 	uint32_t        transfer_tag;
269 	uint32_t        StatSN;
270 	uint32_t        ExpCmdSN;
271 	uint32_t        MaxCmdSN;
272 }               iscsi_text_rsp_args_t;
273 
274 int             iscsi_text_rsp_encap(uint8_t *header, iscsi_text_rsp_args_t * rsp);
275 int             iscsi_text_rsp_decap(uint8_t *header, iscsi_text_rsp_args_t * rsp);
276 
277 
278 /*
279  * Login Command
280  */
281 
282 
283 typedef struct iscsi_login_cmd_args_t {
284 	int32_t         transit;
285 	int32_t         cont;
286 	uint8_t         csg;
287 	uint8_t         nsg;
288 	int8_t          version_max;
289 	int8_t          version_min;
290 	uint8_t         AHSlength;
291 	uint32_t        length;
292 	uint64_t	isid;
293 	uint16_t        tsih;
294 	uint32_t        tag;
295 	uint16_t        cid;
296 	uint32_t        CmdSN;
297 	uint32_t        ExpStatSN;
298 	char           *text;
299 }               iscsi_login_cmd_args_t;
300 
301 int             iscsi_login_cmd_encap(uint8_t *header, iscsi_login_cmd_args_t * cmd);
302 int             iscsi_login_cmd_decap(uint8_t *header, iscsi_login_cmd_args_t * cmd);
303 
304 
305 /*
306  * Login Response
307  */
308 
309 
310 typedef struct iscsi_login_rsp_args_t {
311 	int32_t         transit;
312 	int32_t         cont;
313 	uint8_t         csg;
314 	uint8_t         nsg;
315 	int8_t          version_max;
316 	int8_t          version_active;
317 	uint8_t         AHSlength;
318 	uint32_t        length;
319 	uint64_t	isid;
320 	uint16_t        tsih;
321 	uint32_t        tag;
322 	uint32_t        StatSN;
323 	uint32_t        ExpCmdSN;
324 	uint32_t        MaxCmdSN;
325 	uint8_t         status_class;
326 	uint8_t         status_detail;
327 }               iscsi_login_rsp_args_t;
328 
329 int             iscsi_login_rsp_encap(uint8_t *header, iscsi_login_rsp_args_t * rsp);
330 int             iscsi_login_rsp_decap(uint8_t *header, iscsi_login_rsp_args_t * rsp);
331 
332 
333 /*
334  * Logout Command
335  */
336 
337 
338 typedef struct iscsi_logout_cmd_args_t {
339 	int32_t         immediate;
340 	uint8_t         reason;
341 	uint32_t        tag;
342 	uint16_t        cid;
343 	uint32_t        CmdSN;
344 	uint32_t        ExpStatSN;
345 }               iscsi_logout_cmd_args_t;
346 
347 int             iscsi_logout_cmd_encap(uint8_t *header, iscsi_logout_cmd_args_t * cmd);
348 int             iscsi_logout_cmd_decap(uint8_t *header, iscsi_logout_cmd_args_t * cmd);
349 
350 
351 /*
352  * Logout Response
353  */
354 
355 
356 typedef struct iscsi_logout_rsp_args_t {
357 	uint8_t         response;
358 	uint32_t        length;
359 	uint32_t        tag;
360 	uint32_t        StatSN;
361 	uint32_t        ExpCmdSN;
362 	uint32_t        MaxCmdSN;
363 	uint16_t        Time2Wait;
364 	uint16_t        Time2Retain;
365 }               iscsi_logout_rsp_args_t;
366 
367 int             iscsi_logout_rsp_encap(uint8_t *header, iscsi_logout_rsp_args_t * rsp);
368 int             iscsi_logout_rsp_decap(uint8_t *header, iscsi_logout_rsp_args_t * rsp);
369 
370 
371 /*
372  * SCSI Command
373  */
374 
375 
376 typedef struct iscsi_scsi_cmd_args_t {
377 	int32_t         immediate;
378 	int32_t         final;
379 	int32_t         input;
380 	int32_t         output;
381 	uint8_t         attr;
382 	uint32_t        length;
383 	uint64_t        lun;
384 	uint32_t        tag;
385 	uint32_t        trans_len;
386 	uint32_t        bidi_trans_len;
387 	uint32_t        CmdSN;
388 	uint32_t        ExpStatSN;
389 	uint8_t  	*cdb;
390 	uint8_t  	*ext_cdb;
391 	uint8_t  	*ahs;
392 	uint8_t         ahs_len;
393 	uint8_t  	*send_data;
394 	uint8_t		*send_buffer;	/* malloc'ed buffer for READ */
395 	int32_t         send_sg_len;
396 	uint8_t  	*recv_data;
397 	int32_t         recv_sg_len;
398 	uint8_t         status;
399 	uint32_t        bytes_sent;
400 	uint32_t        bytes_recv;
401 }               iscsi_scsi_cmd_args_t;
402 
403 int             iscsi_scsi_cmd_encap(uint8_t *header, iscsi_scsi_cmd_args_t * cmd);
404 int             iscsi_scsi_cmd_decap(uint8_t *header, iscsi_scsi_cmd_args_t * cmd);
405 
406 
407 /*
408  * SCSI Response
409  */
410 
411 
412 typedef struct iscsi_scsi_rsp_args_t {
413 	int32_t         bidi_overflow;
414 	int32_t         bidi_underflow;
415 	int32_t         overflow;
416 	int32_t         underflow;
417 
418 
419 	uint8_t         response;
420 	uint8_t         status;
421 	uint32_t        ahs_len;
422 	uint32_t        length;
423 	uint32_t        tag;
424 	uint32_t        StatSN;
425 	uint32_t        ExpCmdSN;
426 	uint32_t        MaxCmdSN;
427 	uint32_t        ExpDataSN;
428 	uint32_t        bidi_res_cnt;
429 	uint32_t        basic_res_cnt;
430 }               iscsi_scsi_rsp_t;
431 
432 int             iscsi_scsi_rsp_encap(uint8_t *header, iscsi_scsi_rsp_t * rsp);
433 int             iscsi_scsi_rsp_decap(uint8_t *header, iscsi_scsi_rsp_t * rsp);
434 
435 
436 /*
437  * Ready To Transfer (R2T)
438  */
439 
440 
441 typedef struct iscsi_r2t_args_t {
442 	uint32_t        AHSlength;
443 	uint64_t        lun;
444 	uint32_t        tag;
445 	uint32_t        transfer_tag;
446 	uint32_t        StatSN;
447 	uint32_t        ExpCmdSN;
448 	uint32_t        MaxCmdSN;
449 	uint32_t        R2TSN;
450 	uint32_t        offset;
451 	uint32_t        length;
452 }               iscsi_r2t_t;
453 
454 int             iscsi_r2t_encap(uint8_t *header, iscsi_r2t_t * cmd);
455 int             iscsi_r2t_decap(uint8_t *header, iscsi_r2t_t * cmd);
456 
457 
458 /*
459  * SCSI Write Data
460  */
461 
462 
463 typedef struct iscsi_write_data_args_t {
464 	int32_t         final;
465 	uint32_t        length;
466 	uint64_t        lun;
467 	uint32_t        tag;
468 	uint32_t        transfer_tag;
469 	uint32_t        ExpStatSN;
470 	uint32_t        DataSN;
471 	uint32_t        offset;
472 }               iscsi_write_data_t;
473 
474 int             iscsi_write_data_encap(uint8_t *header, iscsi_write_data_t * cmd);
475 int             iscsi_write_data_decap(uint8_t *header, iscsi_write_data_t * cmd);
476 
477 
478 /*
479  * SCSI Read Data
480  */
481 
482 
483 typedef struct iscsi_read_data_args_t {
484 	int32_t         final;
485 	int32_t         ack;
486 	int32_t         overflow;
487 	int32_t         underflow;
488 	int32_t         S_bit;
489 	uint8_t         status;
490 	uint32_t        length;
491 	uint64_t        lun;
492 	uint32_t        task_tag;
493 	uint32_t        transfer_tag;
494 	uint32_t        StatSN;
495 	uint32_t        ExpCmdSN;
496 	uint32_t        MaxCmdSN;
497 	uint32_t        DataSN;
498 	uint32_t        offset;
499 	uint32_t        res_count;
500 }               iscsi_read_data_t;
501 
502 int             iscsi_read_data_encap(uint8_t *header, iscsi_read_data_t * cmd);
503 int             iscsi_read_data_decap(uint8_t *header, iscsi_read_data_t * cmd);
504 
505 
506 /*
507  * Reject
508  */
509 
510 typedef struct iscsi_reject_args_t {
511 	uint8_t         reason;
512 	uint32_t        length;
513 	uint32_t        StatSN;
514 	uint32_t        ExpCmdSN;
515 	uint32_t        MaxCmdSN;
516 	uint32_t        DataSN;
517 	char           *header;
518 
519 }               iscsi_reject_t;
520 
521 int             iscsi_reject_encap(uint8_t *header, iscsi_reject_t * cmd);
522 int             iscsi_reject_decap(uint8_t *header, iscsi_reject_t * cmd);
523 
524 /*
525  * Async Message
526  */
527 
528 typedef struct iscsi_async_msg_args_t {
529 	uint8_t         AHSlength;
530 	uint64_t        lun;
531 	uint32_t        StatSN;
532 	uint32_t        ExpCmdSN;
533 	uint32_t        MaxCmdSN;
534 	uint32_t        length;
535 	uint8_t         AsyncEvent;
536 	uint8_t         AsyncVCode;
537 }               iscsi_async_msg_t;
538 
539 int             iscsi_amsg_decap(uint8_t *header, iscsi_async_msg_t * msg);
540 
541 #ifndef SOL_TCP
542 #define SOL_TCP IPPROTO_TCP
543 #endif
544 
545 #endif				/* ISCSI_H */
546