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