1/*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30/*
31 | $Id: iscsi.h 743 2009-08-08 10:54:53Z danny $
32 */
33#define	TRUE	1
34#define FALSE	0
35#ifndef _KERNEL
36typedef int boolean_t;
37#endif
38
39#include <cam/cam.h>
40
41#define ISCSIDEV	"iscsi"
42#define ISCSI_MAX_TARGETS	64
43/*
44 | iSCSI commands
45 */
46
47/*
48 | Initiator Opcodes:
49 */
50#define ISCSI_NOP_OUT		0x00
51#define ISCSI_SCSI_CMD		0x01
52#define ISCSI_TASK_CMD		0x02
53#define ISCSI_LOGIN_CMD		0x03
54#define ISCSI_TEXT_CMD		0x04
55#define ISCSI_WRITE_DATA	0x05
56#define ISCSI_LOGOUT_CMD	0x06
57#define ISCSI_SNACK		0x10
58/*
59 | Target Opcodes:
60 */
61#define ISCSI_NOP_IN		0x20
62#define ISCSI_SCSI_RSP		0x21
63#define ISCSI_TASK_RSP		0x22
64#define ISCSI_LOGIN_RSP		0x23
65#define ISCSI_TEXT_RSP		0x24
66#define ISCSI_READ_DATA		0x25
67#define ISCSI_LOGOUT_RSP	0x26
68#define ISCSI_R2T		0x31
69#define ISCSI_ASYNC		0x32
70#define ISCSI_REJECT		0x3f
71/*
72 | PDU stuff
73 */
74/*
75 | BHS Basic Header Segment
76 */
77typedef struct bhs {
78     // the order is network byte order!
79     u_char	opcode:6;
80     u_char	I:1;
81     u_char	_:1;
82     u_char	__:7;
83     u_char	F:1;			// Final bit
84     u_char	___[2];
85
86     u_int	AHSLength:8;		// in 4byte words
87     u_int	DSLength:24;		// in bytes
88
89     u_int	LUN[2];			// or Opcode-specific fields
90     u_int	itt;
91     u_int	OpcodeSpecificFields[7];
92#define	CmdSN		OpcodeSpecificFields[1]
93#define	ExpStSN		OpcodeSpecificFields[2]
94#define MaxCmdSN	OpcodeSpecificFields[3]
95} bhs_t;
96
97typedef struct ahs {
98     u_int	len:16;
99     u_int	type:8;
100     u_int	spec:8;
101     char	data[0];
102} ahs_t;
103
104typedef struct {
105     // Sequence Numbers
106     // (computers were invented to count, right?)
107     int	cmd;
108     int	expcmd;
109     int	maxcmd;
110} req_sn_t;
111
112typedef struct {
113     // Sequence Numbers
114     // (computers were invented to count, right?)
115     int	stat;
116     int	expcmd;
117     int	maxcmd;
118} rsp_sn_t;
119
120typedef struct scsi_req {
121     u_char	opcode:6; // 0x01
122     u_char	I:1;
123     u_char	_:1;
124
125     u_char	attr:3;
126     u_char	_0:2;
127     u_char	W:1;
128     u_char	R:1;
129     u_char	F:1;
130#define		iSCSI_TASK_UNTAGGED	0
131#define		iSCSI_TASK_SIMPLE	1
132#define		iSCSI_TASK_ORDER	2
133#define		iSCSI_TASK_HOFQ		3
134#define		iSCSI_TASK_ACA		4
135     char	_1[2];
136     int	len;
137     int	lun[2];
138     int	itt;
139     int	edtlen;		// expectect data transfere length
140     int	cmdSN;
141     int	extStatSN;
142     int	cdb[4];
143} scsi_req_t;
144
145typedef struct scsi_rsp {
146     char	opcode;	// 0x21
147     u_char	flag;
148     u_char	response;
149     u_char	status;
150
151     int	len;
152     int	_[2];
153     int	itt;
154     int	stag;
155     rsp_sn_t	sn;
156     int	expdatasn;
157     int	bdrcnt;	// bidirectional residual count
158     int	rcnt;	// residual count
159} scsi_rsp_t;
160
161typedef struct nop_out {
162     // the order is network byte order!
163     u_char	opcode:6;
164     u_char	I:1;
165     u_char	_:1;
166     u_char	__:7;
167     u_char	F:1;			// Final bit
168     u_char	___[2];
169
170     u_int	len;
171     u_int	lun[2];
172     u_int	itt;
173     u_int	ttt;
174     req_sn_t	sn;
175     u_int	mbz[3];
176} nop_out_t;
177
178typedef struct nop_in {
179     // the order is network byte order!
180     u_char	opcode:6;
181     u_char	I:1;
182     u_char	_:1;
183     u_char	__:7;
184     u_char	F:1;			// Final bit
185     u_char	___[2];
186
187     u_int	len;
188     u_int	lun[2];
189     u_int	itt;
190     u_int	ttt;
191     rsp_sn_t	sn;
192     u_int	____[2];
193
194} nop_in_t;
195
196typedef struct r2t {
197     u_char	opcode:6;
198     u_char	I:1;
199     u_char	_:1;
200     u_char	__:7;
201     u_char	F:1;			// Final bit
202     u_char	___[2];
203
204     u_int	len;
205     u_int	lun[2];
206     u_int	itt;
207     u_int	ttt;
208     rsp_sn_t	sn;
209     u_int	r2tSN;
210     u_int	bo;
211     u_int	ddtl;
212} r2t_t;
213
214typedef struct data_out {
215     u_char	opcode:6;
216     u_char	I:1;
217     u_char	_:1;
218     u_char	__:7;
219     u_char	F:1;			// Final bit
220     u_char	___[2];
221
222     u_int	len;
223     u_int	lun[2];
224     u_int	itt;
225     u_int	ttt;
226     rsp_sn_t	sn;
227     u_int	dsn;	// data seq. number
228     u_int	bo;
229     u_int	____;
230} data_out_t;
231
232typedef struct data_in {
233     u_char	opcode:6;
234     u_char	I:1;
235     u_char	_:1;
236
237     u_char	S:1;
238     u_char	U:1;
239     u_char	O:1;
240     u_char	__:3;
241     u_char	A:1;
242     u_char	F:1;			// Final bit
243     u_char	___[1];
244     u_char	status;
245
246     u_int	len;
247     u_int	lun[2];
248     u_int	itt;
249     u_int	ttt;
250     rsp_sn_t	sn;
251     u_int	dataSN;
252     u_int	bo;
253     u_int	____;
254} data_in_t;
255
256typedef struct reject {
257     u_char	opcode:6;
258     u_char	_:2;
259     u_char	F:1;
260     u_char	__:7;
261     u_char	reason;
262     u_char	___;
263
264     u_int	len;
265     u_int	____[2];
266     u_int	tt[2];	// must be -1
267     rsp_sn_t	sn;
268     u_int	dataSN;	// or R2TSN or reserved
269     u_int	_____[2];
270} reject_t;
271
272typedef struct async {
273     u_char	opcode:6;
274     u_char	_:2;
275     u_char	F:1;
276     u_char	__:7;
277     u_char	___[2];
278
279     u_int	len;
280     u_int	lun[2];
281     u_int	itt;	// must be -1
282     u_int	____;
283     rsp_sn_t	sn;
284
285     u_char	asyncEvent;
286     u_char	asyncVCode;
287     u_char	param1[2];
288     u_char	param2[2];
289     u_char	param3[2];
290
291     u_int	_____;
292
293} async_t;
294
295typedef struct login_req {
296     char	cmd;	// 0x03
297
298     u_char	NSG:2;
299     u_char	CSG:2;
300     u_char	_:2;
301     u_char	C:1;
302     u_char	T:1;
303
304     char	v_max;
305     char	v_min;
306
307     int	len;	// remapped via standard bhs
308     char	isid[6];
309     short	tsih;
310     int	itt;	// Initiator Task Tag;
311
312     int	CID:16;
313     int	rsv:16;
314
315     int	cmdSN;
316     int	expStatSN;
317     int	unused[4];
318} login_req_t;
319
320typedef struct login_rsp {
321     char	cmd;	// 0x23
322     u_char	NSG:2;
323     u_char	CSG:2;
324     u_char	_1:2;
325     u_char	C:1;
326     u_char	T:1;
327
328     char	v_max;
329     char	v_act;
330
331     int	len;	// remapped via standard bhs
332     char	isid[6];
333     short	tsih;
334     int	itt;	// Initiator Task Tag;
335     int	_2;
336     rsp_sn_t	sn;
337     int	status:16;
338     int	_3:16;
339     int	_4[2];
340} login_rsp_t;
341
342typedef struct text_req {
343     char	cmd;	// 0x04
344
345     u_char	_1:6;
346     u_char	C:1;	// Continuation
347     u_char	F:1;	// Final
348     char	_2[2];
349
350     int	len;
351     int	itt;		// Initiator Task Tag
352     int	LUN[2];
353     int	ttt;		// Target Transfer Tag
354     int	cmdSN;
355     int	expStatSN;
356     int	unused[4];
357} text_req_t;
358
359typedef struct logout_req {
360     char	cmd;	// 0x06
361     u_char	reason;	// 0 - close session
362     			// 1 - close connection
363     			// 2 - remove the connection for recovery
364     char	_2[2];
365
366     int	len;
367     int	_r[2];
368     int	itt;	// Initiator Task Tag;
369
370     u_int	CID:16;
371     u_int	rsv:16;
372
373     int	cmdSN;
374     int	expStatSN;
375     int	unused[4];
376} logout_req_t;
377
378typedef struct logout_rsp {
379     char	cmd;	// 0x26
380     char	cbits;
381     char	_1[2];
382     int	len;
383     int	_2[2];
384     int	itt;
385     int	_3;
386     rsp_sn_t	sn;
387     short	time2wait;
388     short	time2retain;
389     int	_4;
390} logout_rsp_t;
391
392union ipdu_u {
393     bhs_t	bhs;
394     scsi_req_t	scsi_req;
395     scsi_rsp_t	scsi_rsp;
396     nop_out_t	nop_out;
397     nop_in_t	nop_in;
398     r2t_t	r2t;
399     data_out_t	data_out;
400     data_in_t	data_in;
401     reject_t	reject;
402     async_t	async;
403};
404
405/*
406 | Sequence Numbers
407 */
408typedef struct {
409     u_int	itt;
410     u_int      cmd;
411     u_int      expCmd;
412     u_int      maxCmd;
413     u_int      stat;
414     u_int      expStat;
415     u_int      data;
416} sn_t;
417
418/*
419 | in-core version of a Protocol Data Unit
420 */
421typedef struct {
422     union ipdu_u	ipdu;
423     u_int		hdr_dig;	// header digest
424
425     ahs_t		*ahs_addr;
426     u_int		ahs_len;
427     u_int		ahs_size;	// the allocated size
428
429     u_char		*ds_addr;
430     u_int		ds_len;
431     u_int		ds_size;	// the allocated size
432     u_int		ds_dig;		// data digest
433} pdu_t;
434
435typedef struct opvals {
436     int	port;
437     int	tags;
438     int	maxluns;
439     int	sockbufsize;
440
441     int	maxConnections;
442     int	maxRecvDataSegmentLength;
443     int	maxXmitDataSegmentLength; // pseudo ...
444     int	maxBurstLength;
445     int	firstBurstLength;
446     int	defaultTime2Wait;
447     int	defaultTime2Retain;
448     int	maxOutstandingR2T;
449     int	errorRecoveryLevel;
450     int	targetPortalGroupTag;
451
452     boolean_t	initialR2T;
453     boolean_t	immediateData;
454     boolean_t	dataPDUInOrder;
455     boolean_t	dataSequenceInOrder;
456     char	*headerDigest;
457     char	*dataDigest;
458     char	*sessionType;
459     char	*sendTargets;
460     char	*targetAddress;
461     char	*targetAlias;
462     char	*targetName;
463     char	*initiatorName;
464     char	*initiatorAlias;
465     char	*authMethod;
466     char	*chapSecret;
467     char	*chapIName;
468     char	*chapDigest;
469     char	*tgtChapName;
470     char	*tgtChapSecret;
471     int	tgtChallengeLen;
472     u_char	tgtChapID;
473     char	*tgtChapDigest;
474     char	*iqn;
475     char	*pidfile;
476} isc_opt_t;
477
478/*
479 | ioctl
480 */
481#define ISCSISETSES	_IOR('i', 1, int)
482#define ISCSISETSOC	_IOW('i', 2, int)
483#define ISCSISETOPT	_IOW('i', 5, isc_opt_t)
484#define ISCSIGETOPT	_IOR('i', 6, isc_opt_t)
485
486#define ISCSISEND	_IOW('i', 10, pdu_t)
487#define ISCSIRECV	_IOWR('i', 11, pdu_t)
488
489#define ISCSIPING	_IO('i', 20)
490#define ISCSISIGNAL	_IOW('i', 21, int *)
491
492#define ISCSISTART	_IO('i', 30)
493#define ISCSIRESTART	_IO('i', 31)
494#define ISCSISTOP	_IO('i', 32)
495
496typedef struct iscsi_cam {
497     path_id_t		path_id;
498     target_id_t	target_id;
499     int		target_nluns;
500} iscsi_cam_t;
501
502#define ISCSIGETCAM	_IOR('i', 33, iscsi_cam_t)
503