Sync usage with man page.
[netbsd-mini2440.git] / external / bsd / iscsi / dist / src / lib / protocol.c
blob3822af14a4049d226c6e315e5848ab12e2c6d696
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.
7 * Intel License Agreement
9 * Copyright (c) 2000, Intel Corporation
10 * All rights reserved.
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
16 * -Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
41 #include "config.h"
43 #ifdef HAVE_STDLIB_H
44 #include <stdlib.h>
45 #endif
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
49 #endif
51 #ifdef HAVE_SYS_UIO_H
52 #include <sys/uio.h>
53 #endif
55 #ifdef HAVE_STRING_H
56 #include <string.h>
57 #endif
59 #ifdef HAVE_INTTYPES_H
60 #include <inttypes.h>
61 #endif
63 #include "iscsiprotocol.h"
64 #include "iscsiutil.h"
68 * Task Command
71 int
72 iscsi_task_cmd_encap(uint8_t *header, iscsi_task_cmd_t * cmd)
74 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
75 iscsi_trace(TRACE_ISCSI_ARGS, "Function: %u\n", cmd->function);
76 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
77 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
78 iscsi_trace(TRACE_ISCSI_ARGS, "Ref Tag: %#x\n", cmd->ref_tag);
79 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
80 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
81 iscsi_trace(TRACE_ISCSI_ARGS, "RefCmdSN: %u\n", cmd->RefCmdSN);
82 iscsi_trace(TRACE_ISCSI_ARGS, "ExpDataSN: %u\n", cmd->ExpDataSN);
84 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
86 header[0] |= ISCSI_TASK_CMD; /* Opcode */
87 if (cmd->immediate) {
88 header[0] |= 0x40; /* Immediate bit */
90 header[1] = cmd->function & 0x80; /* Function */
91 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
92 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
93 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->ref_tag); /* Reference Tag */
94 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->CmdSN); /* CmdSN */
95 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
96 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(cmd->RefCmdSN); /* RefCmdSN */
97 *((uint32_t *) (void *) (header + 36)) = ISCSI_HTONL(cmd->ExpDataSN); /* ExpDataSN */
99 return 0;
102 int
103 iscsi_task_cmd_decap(uint8_t *header, iscsi_task_cmd_t * cmd)
105 const char *errmsg;
106 uint8_t zeros[16];
108 if (ISCSI_OPCODE(header) != ISCSI_TASK_CMD) {
109 iscsi_err(__FILE__, __LINE__, "Opcode");
110 return 1;
112 cmd->immediate = ((header[0] & 0x40) == 0x40);
113 cmd->function = header[1] & 0x80;
114 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8)));
115 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16)));
116 cmd->ref_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20)));
117 cmd->CmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24)));
118 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28)));
119 cmd->RefCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32)));
120 cmd->ExpDataSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 36)));
122 errmsg = NULL;
123 (void) memset(zeros, 0x0, sizeof(zeros));
124 if ((header[1] & 0x80) != 0x80) {
125 errmsg = "Byte 1 bit 0";
126 } else if (header[2] != 0) {
127 errmsg = "Byte 2";
128 } else if (header[3] != 0) {
129 errmsg = "Byte 3";
130 } else if (memcmp(header + 4, zeros, 4) != 0) {
131 errmsg = "Bytes 4-7";
132 } else if (memcmp(header + 40, zeros, 8) != 0) {
133 errmsg = "Bytes 40-47";
135 if (errmsg) {
136 iscsi_err(__FILE__, __LINE__, errmsg);
137 NO_CLEANUP;
138 return 1;
141 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
142 iscsi_trace(TRACE_ISCSI_ARGS, "Function: %u\n", cmd->function);
143 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
144 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
145 iscsi_trace(TRACE_ISCSI_ARGS, "Ref Tag: %#x\n", cmd->ref_tag);
146 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
147 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
148 iscsi_trace(TRACE_ISCSI_ARGS, "RefCmdSN: %u\n", cmd->RefCmdSN);
149 iscsi_trace(TRACE_ISCSI_ARGS, "ExpDataSN: %u\n", cmd->ExpDataSN);
150 return 0;
154 * Task Response
157 int
158 iscsi_task_rsp_encap(uint8_t *header, iscsi_task_rsp_t * rsp)
160 uint32_t length;
162 iscsi_trace(TRACE_ISCSI_ARGS, "Response: %u\n", rsp->response);
163 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", rsp->length);
164 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", rsp->tag);
165 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
166 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
167 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
169 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
171 header[0] |= ISCSI_TASK_RSP; /* Opcode */
172 header[1] |= 0x80; /* Byte 1 bit 0 */
173 header[2] = rsp->response; /* Response */
174 length = (rsp->length & 0x00ffffff); /* Length */
175 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length);
176 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(rsp->tag);
177 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(rsp->StatSN);
178 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(rsp->ExpCmdSN);
179 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(rsp->MaxCmdSN);
180 return 0;
183 int
184 iscsi_task_rsp_decap(uint8_t *header, iscsi_task_rsp_t * rsp)
186 const char *errmsg;
187 uint8_t zeros[16];
189 if (ISCSI_OPCODE(header) != ISCSI_TASK_RSP) {
190 iscsi_err(__FILE__, __LINE__, "Opcode");
191 return 1;
193 rsp->response = header[2];
194 rsp->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16)));
195 rsp->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24)));
196 rsp->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28)));
197 rsp->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32)));
198 errmsg = NULL;
199 (void) memset(zeros, 0x0, sizeof(zeros));
200 if ((header[0] & 0x00) != 0x00) {
201 errmsg = "Byte 0 bits 0-1";
202 } else if ((header[1] & 0x80) != 0x80) {
203 errmsg = "Byte 1 bit 0";
204 } else if (header[3] != 0) {
205 errmsg = "Byte 3";
206 } else if (memcmp(header + 4, zeros, 12) != 0) {
207 errmsg = "Bytes 4-15";
208 } else if (memcmp(header + 20, zeros, 4) != 0) {
209 errmsg = "Bytes 20-23";
210 } else if (memcmp(header + 36, zeros, 12) != 0) {
211 errmsg = "Bytes 36-47";
213 if (errmsg) {
214 iscsi_err(__FILE__, __LINE__, errmsg);
215 NO_CLEANUP;
216 return 1;
218 iscsi_trace(TRACE_ISCSI_ARGS, "Response: %u\n", rsp->response);
219 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", rsp->tag);
220 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
221 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
222 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
223 return 0;
227 * NOP-Out
230 int
231 iscsi_nop_out_encap(uint8_t *header, iscsi_nop_out_args_t * cmd)
234 uint32_t length;
236 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
237 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
238 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
239 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
240 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
241 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
242 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
244 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
246 header[0] = ISCSI_NOP_OUT; /* Opcode */
247 if (cmd->immediate) {
248 header[0] |= 0x40; /* Immediate bit */
250 header[1] |= 0x80; /* Byte 1 bit 0 and Reserved */
251 length = (cmd->length & 0x00ffffff); /* Length */
252 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length); /* Length */
253 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
254 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
255 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->transfer_tag); /* Target Transfer Tag */
256 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->CmdSN); /* CmdSN */
257 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
259 return 0;
262 int
263 iscsi_nop_out_decap(uint8_t *header, iscsi_nop_out_args_t * cmd)
265 const char *errmsg;
266 uint8_t zeros[16];
268 if (ISCSI_OPCODE(header) != ISCSI_NOP_OUT) {
269 iscsi_err(__FILE__, __LINE__, "Opcode");
270 return 1;
272 cmd->immediate = ((header[0] & 0x40) == 0x40); /* Immediate bit */
273 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
274 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
275 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
276 cmd->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Target Tranfer Tag */
277 cmd->CmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* CmdSN */
278 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpStatSN */
280 errmsg = NULL;
281 (void) memset(zeros, 0x0, sizeof(zeros));
282 if (header[1] != 0x80) {
283 errmsg = "Byte 1";
284 } else if (memcmp(header + 2, zeros, 3) != 0) {
285 errmsg = "Bytes 2-4";
286 } else if (memcmp(header + 32, zeros, 16) != 0) {
287 errmsg = "Bytes 32-47";
289 if (errmsg) {
290 iscsi_err(__FILE__, __LINE__, errmsg);
291 NO_CLEANUP;
292 return 1;
294 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
295 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
296 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
297 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
298 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
299 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
300 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
301 return 0;
305 * NOP-In
308 int
309 iscsi_nop_in_encap(uint8_t *header, iscsi_nop_in_args_t * cmd)
311 uint32_t length;
313 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
314 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
315 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
316 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
317 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
318 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
319 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
321 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
323 header[0] = 0x00 | ISCSI_NOP_IN; /* Opcode */
324 header[1] |= 0x80; /* Reserved */
325 length = (cmd->length & 0x00ffffff); /* Length */
326 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length); /* Length */
327 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
328 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
329 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->transfer_tag); /* Target Transfer Tag */
330 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->StatSN); /* StatSN */
331 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpCmdSN); /* ExpCmdSN */
332 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(cmd->MaxCmdSN); /* MaxCmdSN */
334 return 0;
337 int
338 iscsi_nop_in_decap(uint8_t *header, iscsi_nop_in_args_t * cmd)
340 const char *errmsg;
341 uint8_t zeros[16];
343 if (ISCSI_OPCODE(header) != ISCSI_NOP_IN) {
344 iscsi_err(__FILE__, __LINE__, "Opcode");
345 return 1;
347 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
348 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
349 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
350 cmd->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Target Transfer Tag */
351 cmd->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
352 cmd->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
353 cmd->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
355 errmsg = NULL;
356 (void) memset(zeros, 0x0, sizeof(zeros));
357 if ((header[0] & 0xc0) != 0x00) {
358 errmsg = "Byte 0, bits 0-1";
359 } else if (header[1] != 0x80) {
360 errmsg = "Byte 1";
361 } else if (memcmp(header + 2, zeros, 3) != 0) {
362 errmsg = "Bytes 2-4";
363 } else if (memcmp(header + 36, zeros, 12) != 0) {
364 errmsg = "Bytes 36-47";
366 if (errmsg) {
367 iscsi_err(__FILE__, __LINE__, errmsg);
368 NO_CLEANUP;
369 return 1;
371 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
372 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
373 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
374 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
375 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
376 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
377 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
378 return 0;
382 * Text Command
385 int
386 iscsi_text_cmd_encap(uint8_t *header, iscsi_text_cmd_args_t * cmd)
388 uint32_t length;
390 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
391 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", cmd->final);
392 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", cmd->cont);
393 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
394 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
395 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
396 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
397 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
398 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
400 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
402 header[0] |= ISCSI_TEXT_CMD; /* Opcode */
403 if (cmd->immediate) {
404 header[0] |= 0x40; /* Immediate bit */
406 if (cmd->final) {
407 header[1] |= 0x80; /* Final bit */
409 if (cmd->cont) {
410 header[1] |= 0x40; /* Continue bit */
412 length = (cmd->length & 0x00ffffff); /* Length */
413 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length); /* Length */
414 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
415 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
416 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->transfer_tag); /* Transfer Tag */
417 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->CmdSN); /* CmdSN */
418 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
420 return 0;
423 int
424 iscsi_text_cmd_decap(uint8_t *header, iscsi_text_cmd_args_t * cmd)
426 const char *errmsg;
427 uint8_t zeros[16];
429 if (ISCSI_OPCODE(header) != ISCSI_TEXT_CMD) {
430 iscsi_err(__FILE__, __LINE__, "Opcode");
431 return 1;
433 cmd->immediate = ((header[0] & 0x40) == 0x40); /* Immediate bit */
434 cmd->final = ((header[1] & 0x80) == 0x80); /* Final bit */
435 cmd->cont = ((header[1] & 0x40) == 0x40); /* Continue bit */
436 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
437 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
438 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
439 cmd->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Transfer Tag */
440 cmd->CmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* CmdSN */
441 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpStatSN */
443 errmsg = NULL;
444 (void) memset(zeros, 0x0, sizeof(zeros));
445 if ((header[1] & 0x00) != 0x00) {
446 errmsg = "Byte 1, bits 2-7";
447 } else if (memcmp(header + 2, zeros, 3) != 0) {
448 errmsg = "Bytes 2-4";
449 } else if (memcmp(header + 8, zeros, 8) != 0) {
450 errmsg = "Bytes 8-15";
451 } else if (memcmp(header + 32, zeros, 16) != 0) {
452 errmsg = "Bytes 32-47";
454 if (errmsg) {
455 iscsi_err(__FILE__, __LINE__, errmsg);
456 NO_CLEANUP;
457 return 1;
459 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
460 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", cmd->final);
461 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", cmd->cont);
462 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
463 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
464 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
465 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
466 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
467 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
469 return 0;
473 * Text Response
476 int
477 iscsi_text_rsp_encap(uint8_t *header, iscsi_text_rsp_args_t * rsp)
479 uint32_t length;
481 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", rsp->final);
482 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", rsp->cont);
483 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", rsp->length);
484 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", rsp->lun);
485 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", rsp->tag);
486 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", rsp->transfer_tag);
487 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
488 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
489 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
491 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
492 header[0] |= 0x00 | ISCSI_TEXT_RSP; /* Opcode */
493 if (rsp->final) {
494 header[1] |= 0x80; /* Final bit */
496 if (rsp->cont) {
497 header[1] |= 0x40; /* Continue */
499 length = (rsp->length & 0x00ffffff); /* Length */
500 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length); /* Length */
501 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(rsp->lun); /* LUN */
502 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(rsp->tag); /* Tag */
503 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(rsp->transfer_tag); /* Transfer Tag */
504 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(rsp->StatSN); /* StatSN */
505 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(rsp->ExpCmdSN); /* ExpCmdSN */
506 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(rsp->MaxCmdSN); /* MaxCmdSN */
508 return 0;
511 int
512 iscsi_text_rsp_decap(uint8_t *header, iscsi_text_rsp_args_t * rsp)
514 const char *errmsg;
515 uint8_t zeros[16];
517 if (ISCSI_OPCODE(header) != ISCSI_TEXT_RSP) {
518 iscsi_err(__FILE__, __LINE__, "Opcode");
519 return 1;
521 rsp->final = ((header[1] & 0x80) == 0x80); /* Final bit */
522 rsp->cont = ((header[1] & 0x40) == 0x40); /* Continue bit */
523 rsp->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
524 rsp->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
525 rsp->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
526 rsp->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Transfer Tag */
527 rsp->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
528 rsp->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
529 rsp->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
531 errmsg = NULL;
532 (void) memset(zeros, 0x0, sizeof(zeros));
533 if ((header[1] & 0x3f) != 0x00) {
534 errmsg = "Byte 1, bits 2-7";
535 } else if (memcmp(header + 2, zeros, 3) != 0) {
536 errmsg = "Bytes 2-4";
537 } else if (memcmp(header + 8, zeros, 8) != 0) {
538 errmsg = "Bytes 8-15";
539 } else if (memcmp(header + 36, zeros, 12) != 0) {
540 errmsg = "Bytes 36-47";
542 if (errmsg) {
543 iscsi_err(__FILE__, __LINE__, errmsg);
544 NO_CLEANUP;
545 return 1;
547 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", rsp->final);
548 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", rsp->cont);
549 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", rsp->length);
550 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", rsp->lun);
551 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", rsp->tag);
552 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", rsp->transfer_tag);
553 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
554 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
555 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
557 return 0;
561 * Login Command
564 int
565 iscsi_login_cmd_encap(uint8_t *header, iscsi_login_cmd_args_t * cmd)
567 uint32_t length;
569 iscsi_trace(TRACE_ISCSI_ARGS, "Transit: %d\n", cmd->transit);
570 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", cmd->cont);
571 iscsi_trace(TRACE_ISCSI_ARGS, "CSG: %u\n", cmd->csg);
572 iscsi_trace(TRACE_ISCSI_ARGS, "NSG: %u\n", cmd->nsg);
573 iscsi_trace(TRACE_ISCSI_ARGS, "Version_min: %u\n", cmd->version_min);
574 iscsi_trace(TRACE_ISCSI_ARGS, "Version_max: %u\n", cmd->version_max);
575 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", cmd->AHSlength);
576 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
577 iscsi_trace(TRACE_ISCSI_ARGS, "ISID: %" PRIu64 "\n", cmd->isid);
578 iscsi_trace(TRACE_ISCSI_ARGS, "TSIH: %hu\n", cmd->tsih);
579 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
580 iscsi_trace(TRACE_ISCSI_ARGS, "CID: %hu\n", cmd->cid);
581 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
582 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
584 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
586 header[0] |= 0x40 | ISCSI_LOGIN_CMD; /* Opcode */
587 if (cmd->transit) {
588 header[1] |= 0x80; /* Transit */
590 if (cmd->cont) {
591 header[1] |= 0x40; /* Continue */
593 header[1] |= ((cmd->csg) << 2) & 0x0c; /* CSG */
594 header[1] |= (cmd->nsg) & 0x03; /* NSG */
595 header[2] = cmd->version_max; /* Version-Max */
596 header[3] = cmd->version_min; /* Version-Min */
597 header[4] = cmd->AHSlength; /* TotalAHSLength */
598 length = (cmd->length & 0x00ffffff); /* Length */
599 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length); /* Length */
600 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->isid); /* ISID */
601 *((uint16_t *) (void *) (header + 14)) = ISCSI_HTONS(cmd->tsih); /* TSIH */
602 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Task Tag */
603 *((uint16_t *) (void *) (header + 20)) = ISCSI_HTONS(cmd->cid); /* CID */
604 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->CmdSN); /* CmdSN */
605 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
607 return 0;
610 int
611 iscsi_login_cmd_decap(uint8_t *header, iscsi_login_cmd_args_t * cmd)
613 const char *errmsg;
614 uint8_t zeros[16];
616 if (ISCSI_OPCODE(header) != ISCSI_LOGIN_CMD) {
617 iscsi_err(__FILE__, __LINE__, "Opcode");
618 return 1;
620 cmd->transit = (header[1] & 0x80) ? 1 : 0; /* Transit */
621 cmd->cont = (header[1] & 0x40) ? 1 : 0; /* Continue */
622 cmd->csg = (header[1] & 0x0cU) >> 2; /* CSG */
623 cmd->nsg = header[1] & 0x03; /* NSG */
624 cmd->version_max = header[2]; /* Version-Max */
625 cmd->version_min = header[3]; /* Version-Min */
626 cmd->AHSlength = header[4]; /* TotalAHSLength */
627 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
628 cmd->isid = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* ISID */
629 cmd->tsih = ISCSI_NTOHS(*((uint16_t *) (void *) (header + 14))); /* TSIH */
630 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Task Tag */
631 cmd->cid = ISCSI_NTOHS(*((uint16_t *) (void *) (header + 20))); /* CID */
632 cmd->CmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* CmdSN */
633 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpStatSN */
635 iscsi_trace(TRACE_ISCSI_ARGS, "Transit: %d\n", cmd->transit);
636 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", cmd->cont);
637 iscsi_trace(TRACE_ISCSI_ARGS, "CSG: %u\n", cmd->csg);
638 iscsi_trace(TRACE_ISCSI_ARGS, "NSG: %u\n", cmd->nsg);
639 iscsi_trace(TRACE_ISCSI_ARGS, "Version_min: %u\n", cmd->version_min);
640 iscsi_trace(TRACE_ISCSI_ARGS, "Version_max: %u\n", cmd->version_max);
641 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", cmd->AHSlength);
642 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
643 iscsi_trace(TRACE_ISCSI_ARGS, "ISID: %" PRIu64 "\n", cmd->isid);
644 iscsi_trace(TRACE_ISCSI_ARGS, "TSIH: %hu\n", cmd->tsih);
645 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
646 iscsi_trace(TRACE_ISCSI_ARGS, "CID: %hu\n", cmd->cid);
647 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
648 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
650 errmsg = NULL;
651 (void) memset(zeros, 0x0, sizeof(zeros));
652 if (((header[1] & 0x30U) >> 4U) != 0x0) {
653 errmsg = "Byte 1, bits 2-3";
654 } else if (memcmp(header + 22, zeros, 2) != 0) {
655 errmsg = "Bytes 22-23";
656 } else if (memcmp(header + 32, zeros, 16) != 0) {
657 errmsg = "Bytes 32-47";
659 if (errmsg) {
660 iscsi_err(__FILE__, __LINE__, errmsg);
661 NO_CLEANUP;
662 return 1;
664 if (cmd->transit) {
665 if (cmd->nsg <= cmd->csg) {
666 return -1;
668 if ((cmd->nsg != 0) && (cmd->nsg != 1) && (cmd->nsg != 3)) {
669 return -1;
672 return 0;
676 * Login Response
679 int
680 iscsi_login_rsp_encap(uint8_t *header, iscsi_login_rsp_args_t * rsp)
683 iscsi_trace(TRACE_ISCSI_ARGS, "Transit: %d\n", rsp->transit);
684 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", rsp->cont);
685 iscsi_trace(TRACE_ISCSI_ARGS, "CSG: %u\n", rsp->csg);
686 iscsi_trace(TRACE_ISCSI_ARGS, "NSG: %u\n", rsp->nsg);
687 iscsi_trace(TRACE_ISCSI_ARGS, "Version_max: %u\n", rsp->version_max);
688 iscsi_trace(TRACE_ISCSI_ARGS, "Version_active: %u\n", rsp->version_active);
689 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", rsp->AHSlength);
690 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", rsp->length);
691 iscsi_trace(TRACE_ISCSI_ARGS, "ISID: %" PRIu64 "\n", rsp->isid);
692 iscsi_trace(TRACE_ISCSI_ARGS, "TSIH: %u\n", rsp->tsih);
693 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", rsp->tag);
694 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
695 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
696 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
697 iscsi_trace(TRACE_ISCSI_ARGS, "Status-Class: %u\n", rsp->status_class);
698 iscsi_trace(TRACE_ISCSI_ARGS, "Status-Detail: %u\n", rsp->status_detail);
700 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
702 header[0] |= 0x00 | ISCSI_LOGIN_RSP; /* Opcode */
703 if (rsp->transit) {
704 header[1] |= 0x80; /* Transit */
706 if (rsp->cont) {
707 header[1] |= 0x40; /* Continue */
709 header[1] |= ((rsp->csg) << 2) & 0x0c; /* CSG */
710 if (rsp->transit) {
711 header[1] |= (rsp->nsg) & 0x03; /* NSG */
713 header[2] = rsp->version_max; /* Version-max */
714 header[3] = rsp->version_active; /* Version-active */
715 header[4] = rsp->AHSlength; /* TotalAHSLength */
716 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(rsp->length); /* Length */
717 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(rsp->isid); /* ISID */
718 *((uint16_t *) (void *) (header + 14)) = ISCSI_HTONS(rsp->tsih); /* TSIH */
719 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(rsp->tag); /* Tag */
720 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(rsp->StatSN); /* StatRn */
721 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(rsp->ExpCmdSN); /* ExpCmdSN */
722 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(rsp->MaxCmdSN); /* MaxCmdSN */
723 header[36] = rsp->status_class; /* Status-Class */
724 header[37] = rsp->status_detail; /* Status-Detail */
726 return 0;
729 int
730 iscsi_login_rsp_decap(uint8_t *header, iscsi_login_rsp_args_t * rsp)
732 const char *errmsg;
733 uint8_t zeros[8];
735 if (ISCSI_OPCODE(header) != ISCSI_LOGIN_RSP) {
736 iscsi_err(__FILE__, __LINE__, "Opcode");
737 return 1;
739 rsp->transit = (header[1] & 0x80U) >> 7; /* Transit */
740 rsp->cont = (header[1] & 0x40U) >> 6; /* Continue */
741 rsp->csg = (header[1] & 0x0cU) >> 2; /* CSG */
742 rsp->nsg = header[1] & 0x03; /* NSG */
743 rsp->version_max = header[2]; /* Version-max */
744 rsp->version_active = header[3]; /* Version-active */
745 rsp->AHSlength = header[4]; /* TotalAHSLength */
746 rsp->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
747 rsp->isid = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* ISID */
748 rsp->tsih = ISCSI_NTOHS(*((uint16_t *) (void *) (header + 14))); /* TSIH */
750 rsp->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
751 rsp->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
752 rsp->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
753 rsp->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
754 rsp->status_class = header[36]; /* Status-Class */
755 rsp->status_detail = header[37]; /* Status-Detail */
757 iscsi_trace(TRACE_ISCSI_ARGS, "Transit: %d\n", rsp->transit);
758 iscsi_trace(TRACE_ISCSI_ARGS, "Continue: %d\n", rsp->cont);
759 iscsi_trace(TRACE_ISCSI_ARGS, "CSG: %u\n", rsp->csg);
760 iscsi_trace(TRACE_ISCSI_ARGS, "NSG: %u\n", rsp->nsg);
762 iscsi_trace(TRACE_ISCSI_ARGS, "Version_max: %u\n", rsp->version_max);
763 iscsi_trace(TRACE_ISCSI_ARGS, "Version_active: %u\n", rsp->version_active);
764 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", rsp->AHSlength);
765 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", rsp->length);
766 iscsi_trace(TRACE_ISCSI_ARGS, "ISID: %" PRIu64 "\n", rsp->isid);
767 iscsi_trace(TRACE_ISCSI_ARGS, "TSIH: %u\n", rsp->tsih);
768 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", rsp->tag);
769 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
770 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
771 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
772 iscsi_trace(TRACE_ISCSI_ARGS, "Status-Class: %u\n", rsp->status_class);
773 iscsi_trace(TRACE_ISCSI_ARGS, "Status-Detail: %u\n", rsp->status_detail);
774 errmsg = NULL;
775 (void) memset(zeros, 0x0, sizeof(zeros));
776 if (((header[1] & 0x30U) >> 4U) != 0x0) {
777 errmsg = "Byte 1, bits 2-3";
778 } else if (memcmp(header + 20, zeros, 4) != 0) {
779 errmsg = "Bytes 20-23";
780 } else if (memcmp(header + 38, zeros, 2) != 0) {
781 errmsg = "Bytes 38-39";
782 } else if (memcmp(header + 40, zeros, 8) != 0) {
783 errmsg = "Bytes 40-47";
785 if (errmsg) {
786 iscsi_err(__FILE__, __LINE__, errmsg);
787 NO_CLEANUP;
788 return 1;
790 return 0;
794 * Logout Command
797 int
798 iscsi_logout_cmd_encap(uint8_t *header, iscsi_logout_cmd_args_t * cmd)
801 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
802 iscsi_trace(TRACE_ISCSI_ARGS, "Reason: %u\n", cmd->reason);
803 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
804 iscsi_trace(TRACE_ISCSI_ARGS, "CID: %hu\n", cmd->cid);
805 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
806 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
808 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
810 header[0] = ISCSI_LOGOUT_CMD; /* Opcode */
811 if (cmd->immediate) {
812 header[0] |= 0x40; /* Immediate */
814 header[1] = cmd->reason | 0x80; /* Reason */
815 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
816 *((uint16_t *) (void *) (header + 20)) = ISCSI_HTONS(cmd->cid); /* CID */
817 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->CmdSN); /* CmdSN */
818 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
820 return 0;
823 int
824 iscsi_logout_cmd_decap(uint8_t *header, iscsi_logout_cmd_args_t * cmd)
826 const char *errmsg;
827 uint8_t zeros[16];
829 if (ISCSI_OPCODE(header) != ISCSI_LOGOUT_CMD) {
830 iscsi_err(__FILE__, __LINE__, "Opcode");
831 return 1;
833 cmd->immediate = (header[0] & 0x40) ? 1 : 0; /* Immediate */
834 cmd->reason = header[1] & 0x7f; /* Reason */
835 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
836 cmd->cid = ISCSI_NTOHS(*((uint16_t *) (void *) (header + 20))); /* CID */
837 cmd->CmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* CmdSN */
838 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpStatSN */
840 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
841 iscsi_trace(TRACE_ISCSI_ARGS, "Reason: %u\n", cmd->reason);
842 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
844 iscsi_trace(TRACE_ISCSI_ARGS, "CID: %hu\n", cmd->cid);
845 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
846 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
847 errmsg = NULL;
848 (void) memset(zeros, 0x0, sizeof(zeros));
849 if ((unsigned)(header[0]) >> 0x7U != 0) {
850 errmsg = "Byte 0, bit 0";
851 } else if ((unsigned)(header[1]) >> 7U != 1) {
852 errmsg = "Byte 1, bit 0";
853 } else if (header[2] != 0) {
854 errmsg = "Byte 2";
855 } else if (header[3] != 0) {
856 errmsg = "Byte 3";
857 } else if (memcmp(header + 4, zeros, 12) != 0) {
858 errmsg = "Bytes 4-7";
859 } else if (memcmp(header + 22, zeros, 2) != 0) {
860 errmsg = "Bytes 22-23";
861 } else if (memcmp(header + 32, zeros, 16) != 0) {
862 errmsg = "Bytes 32-47";
864 if (errmsg) {
865 iscsi_err(__FILE__, __LINE__, errmsg);
866 NO_CLEANUP;
867 return 1;
869 return 0;
873 * Logout Response
876 int
877 iscsi_logout_rsp_encap(uint8_t *header, iscsi_logout_rsp_args_t * rsp)
880 iscsi_trace(TRACE_ISCSI_ARGS, "Response: %u\n", rsp->response);
881 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", rsp->length);
882 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", rsp->tag);
883 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
884 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
885 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
887 iscsi_trace(TRACE_ISCSI_ARGS, "Time2Wait: %hu\n", rsp->Time2Wait);
888 iscsi_trace(TRACE_ISCSI_ARGS, "Time2Retain: %hu\n", rsp->Time2Retain);
890 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
892 header[0] |= 0x00 | ISCSI_LOGOUT_RSP; /* Opcode */
893 header[1] |= 0x80; /* Reserved */
894 header[2] = rsp->response; /* Response */
895 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(rsp->length); /* Length */
896 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(rsp->tag); /* Tag */
897 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(rsp->StatSN); /* StatSN */
898 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(rsp->ExpCmdSN); /* ExpCmdSN */
899 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(rsp->MaxCmdSN); /* MaxCmdSN */
900 *((uint16_t *) (void *) (header + 40)) = ISCSI_HTONS(rsp->Time2Wait); /* Time2Wait */
901 *((uint16_t *) (void *) (header + 42)) = ISCSI_HTONS(rsp->Time2Retain); /* Time2Retain */
903 return 0;
906 int
907 iscsi_logout_rsp_decap(uint8_t *header, iscsi_logout_rsp_args_t * rsp)
909 const char *errmsg;
910 uint8_t zeros[16];
912 if (ISCSI_OPCODE(header) != ISCSI_LOGOUT_RSP) {
913 iscsi_err(__FILE__, __LINE__, "Opcode");
914 return 1;
916 rsp->response = header[2]; /* Response */
917 rsp->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
918 rsp->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
919 rsp->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
920 rsp->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
921 rsp->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
922 rsp->Time2Wait = ISCSI_NTOHS(*((uint32_t *) (void *) (header + 40))); /* Time2Wait */
923 rsp->Time2Retain = ISCSI_NTOHS(*((uint32_t *) (void *) (header + 42))); /* Time2Retain */
925 errmsg = NULL;
926 (void) memset(zeros, 0x0, sizeof(zeros));
927 if ((header[0] & 0x20) != 0x20) {
928 errmsg = "Byte 0, bits 0-1";
929 } else if ((header[1] & 0x80) != 0x80) {
930 errmsg = "Byte 1, bit 0";
931 } else if (header[3] != 0) {
932 errmsg = "Byte 3";
933 } else if (memcmp(header + 4, zeros, 12) != 0) {
934 errmsg = "Bytes 4-15";
935 } else if (memcmp(header + 20, zeros, 4) != 0) {
936 errmsg = "Bytes 20-23";
937 } else if (memcmp(header + 36, zeros, 4) != 0) {
938 errmsg = "Bytes 36-39";
939 } else if (memcmp(header + 44, zeros, 4) != 0) {
940 errmsg = "Bytes 44-47";
942 if (errmsg) {
943 iscsi_err(__FILE__, __LINE__, errmsg);
944 NO_CLEANUP;
945 return 1;
947 iscsi_trace(TRACE_ISCSI_ARGS, "Response: %u\n", rsp->response);
948 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", rsp->length);
949 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", rsp->tag);
950 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
951 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
952 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
953 iscsi_trace(TRACE_ISCSI_ARGS, "Time2Wait: %hu\n", rsp->Time2Wait);
954 iscsi_trace(TRACE_ISCSI_ARGS, "Time2Retain: %hu\n", rsp->Time2Retain);
956 return 0;
960 * SCSI Command
963 int
964 iscsi_scsi_cmd_encap(uint8_t *header, iscsi_scsi_cmd_args_t * cmd)
967 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
968 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", cmd->final);
969 iscsi_trace(TRACE_ISCSI_ARGS, "Input: %d\n", cmd->input);
970 iscsi_trace(TRACE_ISCSI_ARGS, "Output: %d\n", cmd->output);
971 iscsi_trace(TRACE_ISCSI_ARGS, "ATTR: %d\n", cmd->attr);
972 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", cmd->ahs_len);
973 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
974 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
975 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
976 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Length: %u\n", cmd->trans_len);
977 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
978 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
979 iscsi_trace(TRACE_ISCSI_ARGS, "CDB: %#x\n", cmd->cdb[0]);
981 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
983 header[0] |= ISCSI_SCSI_CMD; /* Opcode */
984 if (cmd->immediate) {
985 header[0] |= 0x40; /* Immediate */
987 if (cmd->final) {
988 header[1] |= 0x80; /* Final */
990 if (cmd->input) {
991 header[1] |= 0x40; /* Input bit */
993 if (cmd->output) {
994 header[1] |= 0x20; /* Output bit */
996 header[1] |= cmd->attr & 0x07; /* ATTR */
997 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(cmd->length); /* DataSegmentLength */
998 header[4] = cmd->ahs_len; /* TotalAHSLength */
999 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
1000 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Task Tag */
1001 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->trans_len); /* Expected Transfer
1002 * Length */
1003 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->CmdSN); /* CmdSN */
1004 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
1005 memcpy(header + 32, cmd->cdb, 16); /* CDB */
1007 return 0;
1010 int
1011 iscsi_scsi_cmd_decap(uint8_t *header, iscsi_scsi_cmd_args_t * cmd)
1013 const char *errmsg;
1015 if (ISCSI_OPCODE(header) != ISCSI_SCSI_CMD) {
1016 iscsi_err(__FILE__, __LINE__, "Opcode");
1017 return 1;
1019 cmd->immediate = (header[0] & 0x40) ? 1 : 0; /* Immediate */
1020 cmd->final = (header[1] & 0x80) ? 1 : 0; /* Final */
1021 cmd->input = (header[1] & 0x40) ? 1 : 0; /* Input */
1022 cmd->output = (header[1] & 0x20) ? 1 : 0; /* Output */
1023 cmd->attr = header[1] & 0x07; /* ATTR */
1024 cmd->ahs_len = header[4];
1025 header[4] = 0x00;
1026 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* DataSegmentLength */
1027 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
1028 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Task Tag */
1029 cmd->trans_len = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Expected Transfer
1030 * Length */
1031 cmd->CmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* CmdSN */
1032 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpStatSN */
1033 cmd->cdb = header + 32; /* CDB */
1035 errmsg = NULL;
1036 if ((header[1] & 0x18) != 0x0) {
1037 errmsg = "Byte 1, bits 3-4";
1038 } else if (header[2] != 0) {
1039 errmsg = "Byte 2";
1040 } else if (header[3] != 0) {
1041 errmsg = "Byte 3";
1043 if (errmsg) {
1044 iscsi_err(__FILE__, __LINE__, errmsg);
1045 NO_CLEANUP;
1046 return 1;
1048 iscsi_trace(TRACE_ISCSI_ARGS, "Immediate: %d\n", cmd->immediate);
1049 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", cmd->final);
1050 iscsi_trace(TRACE_ISCSI_ARGS, "Input: %d\n", cmd->input);
1051 iscsi_trace(TRACE_ISCSI_ARGS, "Output: %d\n", cmd->output);
1052 iscsi_trace(TRACE_ISCSI_ARGS, "ATTR: %d\n", cmd->attr);
1053 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", cmd->ahs_len);
1054 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
1055 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
1056 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
1057 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Length: %u\n", cmd->trans_len);
1058 iscsi_trace(TRACE_ISCSI_ARGS, "CmdSN: %u\n", cmd->CmdSN);
1059 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
1060 iscsi_trace(TRACE_ISCSI_ARGS, "CDB: %#x\n", cmd->cdb[0]);
1062 return 0;
1066 * SCSI Response
1069 int
1070 iscsi_scsi_rsp_encap(uint8_t *header, iscsi_scsi_rsp_t * rsp)
1073 iscsi_trace(TRACE_ISCSI_ARGS, "Bidi Overflow: %d\n", rsp->bidi_overflow);
1074 iscsi_trace(TRACE_ISCSI_ARGS, "Bidi Underflow: %d\n", rsp->bidi_underflow);
1075 iscsi_trace(TRACE_ISCSI_ARGS, "Overflow: %d\n", rsp->overflow);
1076 iscsi_trace(TRACE_ISCSI_ARGS, "Underflow: %d\n", rsp->underflow);
1077 iscsi_trace(TRACE_ISCSI_ARGS, "iSCSI Response: %u\n", rsp->response);
1078 iscsi_trace(TRACE_ISCSI_ARGS, "SCSI Status: %u\n", rsp->status);
1079 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", rsp->length);
1080 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", rsp->tag);
1081 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
1082 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
1083 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
1084 iscsi_trace(TRACE_ISCSI_ARGS, "ExpDataSN: %u\n", rsp->ExpDataSN);
1085 iscsi_trace(TRACE_ISCSI_ARGS, "Bidi Residual Count: %u\n", rsp->bidi_res_cnt);
1086 iscsi_trace(TRACE_ISCSI_ARGS, "Residual Count: %u\n", rsp->basic_res_cnt);
1088 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
1090 header[0] |= 0x00 | ISCSI_SCSI_RSP; /* Opcode */
1091 header[1] |= 0x80; /* Byte 1 bit 7 */
1092 if (rsp->bidi_overflow) {
1093 header[1] |= 0x10; /* Bidi overflow */
1095 if (rsp->bidi_underflow) {
1096 header[1] |= 0x08; /* Bidi underflow */
1098 if (rsp->overflow) {
1099 header[1] |= 0x04; /* Overflow */
1101 if (rsp->underflow) {
1102 header[1] |= 0x02; /* Underflow */
1104 header[2] = rsp->response; /* iSCSI Response */
1105 header[3] = rsp->status;/* SCSI Status */
1106 header[4] = rsp->ahs_len; /* TotalAHSLength */
1107 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(rsp->length); /* DataSegmentLength */
1108 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(rsp->tag); /* Task Tag */
1109 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(rsp->StatSN); /* StatSN */
1110 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(rsp->ExpCmdSN); /* ExpCmdSN */
1111 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(rsp->MaxCmdSN); /* MaxCmdSN */
1112 *((uint32_t *) (void *) (header + 36)) = ISCSI_HTONL(rsp->ExpDataSN); /* ExpDataSN */
1113 *((uint32_t *) (void *) (header + 40)) = ISCSI_HTONL(rsp->bidi_res_cnt); /* Bidi Residual Count */
1114 *((uint32_t *) (void *) (header + 44)) = ISCSI_HTONL(rsp->basic_res_cnt); /* Residual Count */
1116 return 0;
1119 int
1120 iscsi_scsi_rsp_decap(uint8_t *header, iscsi_scsi_rsp_t * rsp)
1122 const char *errmsg;
1124 if (ISCSI_OPCODE(header) != ISCSI_SCSI_RSP) {
1125 iscsi_err(__FILE__, __LINE__, "Opcode");
1126 return 1;
1128 rsp->bidi_overflow = (header[1] & 0x10) ? 1 : 0; /* Bidi overflow */
1129 rsp->bidi_underflow = (header[1] & 0x08) ? 1 : 0; /* Bidi underflow */
1130 rsp->overflow = (header[1] & 0x04) ? 1 : 0; /* Overflow */
1131 rsp->underflow = (header[1] & 0x02) ? 1 : 0; /* Underflow */
1133 rsp->response = header[2]; /* iSCSI Response */
1134 rsp->status = header[3];/* SCSI Status */
1135 rsp->ahs_len = header[4]; /* TotalAHSLength */
1136 rsp->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* DataSegmentLength */
1137 rsp->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Task Tag */
1138 rsp->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
1139 rsp->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
1140 rsp->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
1141 rsp->ExpDataSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 36))); /* ExpDataSN */
1142 rsp->bidi_res_cnt = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 40))); /* Bidi Residual Count */
1143 rsp->basic_res_cnt = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 44))); /* Residual Count */
1145 errmsg = NULL;
1146 if ((header[0] & 0xc0) != 0x0) {
1147 errmsg = "Byte 0, bits 0-1";
1148 } else if ((header[1] & 0x80) != 0x80) {
1149 errmsg = "Byte 1, bit 0";
1150 } else if (rsp->bidi_res_cnt != 0) {
1151 errmsg = "bidi_res_cnt";
1152 } else if (rsp->bidi_overflow != 0) {
1153 errmsg = "bidi_overflow";
1154 } else if (rsp->bidi_underflow != 0) {
1155 errmsg = "bidi_underflow";
1156 } else if (rsp->overflow != 0) {
1157 errmsg = "overflow";
1159 if (errmsg) {
1160 iscsi_err(__FILE__, __LINE__, errmsg);
1161 NO_CLEANUP;
1162 return 1;
1164 iscsi_trace(TRACE_ISCSI_ARGS, "Bidi Overflow: %d\n", rsp->bidi_overflow);
1165 iscsi_trace(TRACE_ISCSI_ARGS, "Bidi Underflow: %d\n", rsp->bidi_underflow);
1166 iscsi_trace(TRACE_ISCSI_ARGS, "Overflow: %d\n", rsp->overflow);
1167 iscsi_trace(TRACE_ISCSI_ARGS, "Underflow: %d\n", rsp->underflow);
1168 iscsi_trace(TRACE_ISCSI_ARGS, "iSCSI Response: %u\n", rsp->response);
1169 iscsi_trace(TRACE_ISCSI_ARGS, "SCSI Status: %u\n", rsp->status);
1170 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", rsp->length);
1171 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", rsp->tag);
1172 iscsi_trace(TRACE_ISCSI_ARGS, "Residual Count: %u\n", rsp->basic_res_cnt);
1173 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", rsp->StatSN);
1174 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", rsp->ExpCmdSN);
1175 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", rsp->MaxCmdSN);
1176 iscsi_trace(TRACE_ISCSI_ARGS, "ExpDataSN: %u\n", rsp->ExpDataSN);
1177 iscsi_trace(TRACE_ISCSI_ARGS, "Bidi Residual Count: %u\n", rsp->bidi_res_cnt);
1179 return 0;
1184 * Ready To Transfer
1187 int
1188 iscsi_r2t_encap(uint8_t *header, iscsi_r2t_t * cmd)
1190 uint32_t length;
1192 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", cmd->AHSlength);
1193 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
1194 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
1195 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
1196 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
1197 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
1198 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
1199 iscsi_trace(TRACE_ISCSI_ARGS, "R2TSN: %u\n", cmd->R2TSN);
1200 iscsi_trace(TRACE_ISCSI_ARGS, "Offset: %u\n", cmd->offset);
1201 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
1203 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
1205 header[0] |= 0x00 | ISCSI_R2T; /* Opcode */
1206 header[1] |= 0x80;
1207 length = (cmd->AHSlength & 0x00ffffff); /* AHSLength */
1208 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(length); /* AHSLength */
1209 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
1210 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
1211 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->transfer_tag); /* Transfer Tag */
1212 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->StatSN); /* StatSN */
1213 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpCmdSN); /* ExpCmdSN */
1214 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(cmd->MaxCmdSN); /* MaxCmdSN */
1215 *((uint32_t *) (void *) (header + 36)) = ISCSI_HTONL(cmd->R2TSN); /* R2TSN */
1216 *((uint32_t *) (void *) (header + 40)) = ISCSI_HTONL(cmd->offset); /* Buffer Offset */
1217 *((uint32_t *) (void *) (header + 44)) = ISCSI_HTONL(cmd->length); /* Transfer Length */
1219 return 0;
1222 int
1223 iscsi_r2t_decap(uint8_t *header, iscsi_r2t_t * cmd)
1225 const char *errmsg;
1226 uint8_t zeros[12];
1228 if (ISCSI_OPCODE(header) != ISCSI_R2T) {
1229 iscsi_err(__FILE__, __LINE__, "Opcode");
1230 return 1;
1232 cmd->AHSlength = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* TotalAHSLength */
1233 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
1234 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16)));
1235 cmd->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20)));
1236 cmd->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24)));
1237 cmd->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28)));
1238 cmd->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32)));
1239 cmd->R2TSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 36)));
1240 cmd->offset = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 40)));
1241 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 44)));
1243 errmsg = NULL;
1244 (void) memset(zeros, 0x0, sizeof(zeros));
1245 if ((header[1] & 0x7f) != 0x0) {
1246 errmsg = "Byte 1, bits 1-7";
1247 } else if (header[2] != 0) {
1248 errmsg = "Byte 2";
1249 } else if (header[3] != 0) {
1250 errmsg = "Byte 3";
1251 } else if (memcmp(header + 4, zeros, 12) != 0) {
1252 errmsg = "Bytes 4-15";
1254 if (errmsg) {
1255 iscsi_err(__FILE__, __LINE__, errmsg);
1256 NO_CLEANUP;
1257 return 1;
1259 iscsi_trace(TRACE_ISCSI_ARGS, "AHSLength: %u\n", cmd->AHSlength);
1260 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
1261 iscsi_trace(TRACE_ISCSI_ARGS, "Tag: %#x\n", cmd->tag);
1262 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
1263 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
1264 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
1265 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
1266 iscsi_trace(TRACE_ISCSI_ARGS, "R2TSN: %u\n", cmd->R2TSN);
1267 iscsi_trace(TRACE_ISCSI_ARGS, "Offset: %u\n", cmd->offset);
1268 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
1269 return 0;
1273 * SCSI Write Data
1276 int
1277 iscsi_write_data_encap(uint8_t *header, iscsi_write_data_t * cmd)
1280 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %u\n", cmd->final);
1281 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
1282 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
1283 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
1284 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
1285 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
1286 iscsi_trace(TRACE_ISCSI_ARGS, "DataSN: %u\n", cmd->DataSN);
1287 iscsi_trace(TRACE_ISCSI_ARGS, "Buffer Offset: %u\n", cmd->offset);
1289 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
1290 header[0] = 0x00 | ISCSI_WRITE_DATA; /* Opcode */
1291 if (cmd->final) {
1292 header[1] |= 0x80; /* Final */
1294 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(cmd->length); /* Length */
1295 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
1296 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->tag); /* Tag */
1297 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->transfer_tag); /* Transfer Tag */
1298 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpStatSN); /* ExpStatSN */
1299 *((uint32_t *) (void *) (header + 36)) = ISCSI_HTONL(cmd->DataSN); /* DataSN */
1300 *((uint32_t *) (void *) (header + 40)) = ISCSI_HTONL(cmd->offset); /* Buffer Offset */
1302 return 0;
1305 int
1306 iscsi_write_data_decap(uint8_t *header, iscsi_write_data_t * cmd)
1308 const char *errmsg;
1309 uint8_t zeros[16];
1311 if (ISCSI_OPCODE(header) != ISCSI_WRITE_DATA) {
1312 iscsi_err(__FILE__, __LINE__, "Opcode");
1313 return 1;
1315 cmd->final = (header[1] & 0x80) ? 1 : 0; /* Final */
1316 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
1317 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
1318 cmd->tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Tag */
1319 cmd->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Transfer Tag */
1320 cmd->ExpStatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpStatSN */
1321 cmd->DataSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 36))); /* DataSN */
1322 cmd->offset = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 40))); /* Buffer Offset */
1324 errmsg = NULL;
1325 (void) memset(zeros, 0x0, sizeof(zeros));
1326 if ((header[1] & 0x7f) != 0x0) {
1327 errmsg = "Byte 1, bits 1-7";
1328 } else if (header[2] != 0) {
1329 errmsg = "Byte 2";
1330 } else if (header[3] != 0) {
1331 errmsg = "Byte 3";
1332 } else if (header[4] != 0) {
1333 errmsg = "Byte 4";
1334 } else if (memcmp(header + 24, zeros, 4) != 0) {
1335 errmsg = "Bytes 24-27";
1336 } else if (memcmp(header + 32, zeros, 4) != 0) {
1337 errmsg = "Bytes 32-35";
1338 } else if (memcmp(header + 44, zeros, 4) != 0) {
1339 errmsg = "Bytes 44-47";
1341 if (errmsg) {
1342 iscsi_err(__FILE__, __LINE__, errmsg);
1343 NO_CLEANUP;
1344 return 1;
1346 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %u\n", cmd->final);
1347 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
1348 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
1349 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->tag);
1350 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
1351 iscsi_trace(TRACE_ISCSI_ARGS, "ExpStatSN: %u\n", cmd->ExpStatSN);
1352 iscsi_trace(TRACE_ISCSI_ARGS, "DataSN: %u\n", cmd->DataSN);
1353 iscsi_trace(TRACE_ISCSI_ARGS, "Buffer Offset: %u\n", cmd->offset);
1355 return 0;
1359 * SCSI Read Data
1362 int
1363 iscsi_read_data_encap(uint8_t *header, iscsi_read_data_t * cmd)
1366 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", cmd->final);
1367 iscsi_trace(TRACE_ISCSI_ARGS, "Acknowledge: %d\n", cmd->ack);
1368 iscsi_trace(TRACE_ISCSI_ARGS, "Overflow: %d\n", cmd->overflow);
1369 iscsi_trace(TRACE_ISCSI_ARGS, "Underflow: %d\n", cmd->underflow);
1370 iscsi_trace(TRACE_ISCSI_ARGS, "S_bit: %d\n", cmd->S_bit);
1371 iscsi_trace(TRACE_ISCSI_ARGS, "Status: %u\n", cmd->status);
1372 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
1373 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", cmd->lun);
1374 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->task_tag);
1375 iscsi_trace(TRACE_ISCSI_ARGS, "Transfer Tag: %#x\n", cmd->transfer_tag);
1376 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
1377 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
1378 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
1379 iscsi_trace(TRACE_ISCSI_ARGS, "DataSN: %u\n", cmd->DataSN);
1380 iscsi_trace(TRACE_ISCSI_ARGS, "Buffer Offset %u\n", cmd->offset);
1381 iscsi_trace(TRACE_ISCSI_ARGS, "Residual Count: %u\n", cmd->res_count);
1383 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
1385 header[0] = 0x00 | ISCSI_READ_DATA; /* Opcode */
1386 if (cmd->final) {
1387 header[1] |= 0x80; /* Final */
1389 if (cmd->ack) {
1390 header[1] |= 0x40; /* ACK */
1392 if (cmd->overflow) {
1393 header[1] |= 0x04; /* Overflow */
1395 if (cmd->underflow) {
1396 header[1] |= 0x02; /* Underflow */
1398 if (cmd->S_bit) {
1399 header[1] |= 0x01; /* S Bit */
1401 if (cmd->S_bit) {
1402 header[3] = cmd->status; /* Status */
1404 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(cmd->length); /* Length */
1405 *((uint64_t *) (void *) (header + 8)) = ISCSI_HTONLL6(cmd->lun); /* LUN */
1406 *((uint32_t *) (void *) (header + 16)) = ISCSI_HTONL(cmd->task_tag); /* Task Tag */
1407 *((uint32_t *) (void *) (header + 20)) = ISCSI_HTONL(cmd->transfer_tag); /* Transfer Tag */
1408 if (cmd->S_bit) {
1409 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->StatSN); /* StatSN */
1411 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpCmdSN); /* ExpCmdSN */
1412 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(cmd->MaxCmdSN); /* MaxCmdSN */
1413 *((uint32_t *) (void *) (header + 36)) = ISCSI_HTONL(cmd->DataSN); /* DataSN */
1414 *((uint32_t *) (void *) (header + 40)) = ISCSI_HTONL(cmd->offset); /* Buffer Offset */
1415 if (cmd->S_bit) {
1416 *((uint32_t *) (void *) (header + 44)) = ISCSI_HTONL(cmd->res_count); /* Residual Count */
1419 return 0;
1422 int
1423 iscsi_read_data_decap(uint8_t *header, iscsi_read_data_t * cmd)
1425 const char *errmsg;
1426 uint8_t zeros[16];
1428 if (ISCSI_OPCODE(header) != ISCSI_READ_DATA) {
1429 iscsi_err(__FILE__, __LINE__, "Opcode");
1430 return 1;
1432 cmd->final = (header[1] & 0x80) ? 1 : 0; /* Final */
1433 cmd->ack = (header[1] & 0x40) ? 1 : 0; /* Acknowledge */
1434 cmd->overflow = (header[1] & 0x04) ? 1 : 0; /* Overflow */
1435 cmd->underflow = (header[1] & 0x02) ? 1 : 0; /* Underflow */
1436 cmd->S_bit = (header[1] & 0x01) ? 1 : 0; /* S Bit */
1437 cmd->status = header[3];/* Status */
1438 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
1439 cmd->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
1440 cmd->task_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 16))); /* Task Tag */
1441 cmd->transfer_tag = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 20))); /* Transfer Tag */
1442 cmd->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
1443 cmd->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
1444 cmd->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
1445 cmd->DataSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 36))); /* DataSN */
1446 cmd->offset = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 40))); /* Buffer Offset */
1447 cmd->res_count = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 44))); /* Residual Count */
1448 errmsg = NULL;
1449 (void) memset(zeros, 0x0, sizeof(zeros));
1450 if ((header[0] & 0xc0) != 0x0) {
1451 errmsg = "Byte 0, bits 0-1";
1452 } else if ((header[1] & 0x38) != 0x0) {
1453 errmsg = "Byte 1, bits 2-4";
1454 } else if (header[2] != 0) {
1455 errmsg = "Byte 2";
1456 } else if (header[4] != 0) {
1457 errmsg = "Byte 4";
1458 } else if (memcmp(header + 8, zeros, 8) != 0) {
1459 errmsg = "Bytes 8-15";
1460 } else if (memcmp(header + 44, zeros, 4) != 0) {
1461 errmsg = "Bytes 44-47";
1463 if (errmsg) {
1464 iscsi_err(__FILE__, __LINE__, errmsg);
1465 NO_CLEANUP;
1466 return 1;
1468 iscsi_trace(TRACE_ISCSI_ARGS, "Final: %d\n", cmd->final);
1469 iscsi_trace(TRACE_ISCSI_ARGS, "Acknowledge: %d\n", cmd->ack);
1470 iscsi_trace(TRACE_ISCSI_ARGS, "Overflow: %d\n", cmd->overflow);
1471 iscsi_trace(TRACE_ISCSI_ARGS, "Underflow: %d\n", cmd->underflow);
1472 iscsi_trace(TRACE_ISCSI_ARGS, "S_bit: %d\n", cmd->S_bit);
1473 iscsi_trace(TRACE_ISCSI_ARGS, "Status: %u\n", cmd->status);
1474 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", cmd->length);
1475 iscsi_trace(TRACE_ISCSI_ARGS, "Task Tag: %#x\n", cmd->task_tag);
1476 iscsi_trace(TRACE_ISCSI_ARGS, "Residual Count: %u\n", cmd->res_count);
1477 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
1478 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
1479 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
1480 iscsi_trace(TRACE_ISCSI_ARGS, "DataSN: %u\n", cmd->DataSN);
1481 iscsi_trace(TRACE_ISCSI_ARGS, "Buffer Offset %u\n", cmd->offset);
1482 return 0;
1486 * Reject
1489 int
1490 iscsi_reject_encap(uint8_t *header, iscsi_reject_t * cmd)
1493 iscsi_trace(TRACE_ISCSI_ARGS, "Reason: %u\n", cmd->reason);
1494 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
1495 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
1496 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
1497 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
1498 iscsi_trace(TRACE_ISCSI_ARGS, "DataSN: %u\n", cmd->DataSN);
1500 (void) memset(header, 0x0, ISCSI_HEADER_LEN);
1502 header[0] |= 0x00 | ISCSI_REJECT; /* Opcode */
1503 header[1] |= 0x80;
1504 header[2] = cmd->reason;/* Reason */
1505 *((uint32_t *) (void *) (header + 4)) = ISCSI_HTONL(cmd->length); /* Length */
1506 *((uint32_t *) (void *) (header + 24)) = ISCSI_HTONL(cmd->StatSN); /* StatSN */
1507 *((uint32_t *) (void *) (header + 28)) = ISCSI_HTONL(cmd->ExpCmdSN); /* ExpCmdSN */
1508 *((uint32_t *) (void *) (header + 32)) = ISCSI_HTONL(cmd->MaxCmdSN); /* MaxCmdSN */
1509 *((uint32_t *) (void *) (header + 36)) = ISCSI_HTONL(cmd->DataSN); /* DataSN */
1511 return 0;
1514 int
1515 iscsi_reject_decap(uint8_t *header, iscsi_reject_t * cmd)
1517 const char *errmsg;
1518 uint8_t zeros[8];
1520 if (ISCSI_OPCODE(header) != ISCSI_REJECT) {
1521 iscsi_err(__FILE__, __LINE__, "Opcode");
1522 return 1;
1524 cmd->reason = header[2];/* Reason */
1525 cmd->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
1526 cmd->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
1527 cmd->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
1528 cmd->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
1529 cmd->DataSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 36))); /* DataSN */
1531 errmsg = NULL;
1532 (void) memset(zeros, 0x0, sizeof(zeros));
1533 if ((header[0] & 0xc0) != 0x0) {
1534 errmsg = "Byte 0, bits 0-1";
1535 } else if ((header[1] & 0x7f) != 0x0) {
1536 errmsg = "Byte 1, bits 0-7";
1537 } else if (header[3] != 0) {
1538 errmsg = "Byte 3";
1539 } else if (header[4] != 0) {
1540 errmsg = "Byte 4";
1541 } else if (memcmp(header + 8, zeros, 8) != 0) {
1542 errmsg = "Bytes 8-15";
1543 } else if (memcmp(header + 20, zeros, 4) != 0) {
1544 errmsg = "Bytes 20-23";
1545 } else if (memcmp(header + 40, zeros, 8) != 0) {
1546 errmsg = "Bytes 40-47";
1548 if (errmsg) {
1549 iscsi_err(__FILE__, __LINE__, errmsg);
1550 NO_CLEANUP;
1551 return 1;
1553 iscsi_trace(TRACE_ISCSI_ARGS, "Reason: %u\n", cmd->reason);
1554 iscsi_trace(TRACE_ISCSI_ARGS, "Length: %u\n", cmd->length);
1555 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", cmd->StatSN);
1556 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", cmd->ExpCmdSN);
1557 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", cmd->MaxCmdSN);
1558 iscsi_trace(TRACE_ISCSI_ARGS, "DataSN: %u\n", cmd->DataSN);
1559 return 0;
1562 int
1563 iscsi_amsg_decap(uint8_t *header, iscsi_async_msg_t * msg)
1566 if (ISCSI_OPCODE(header) != ISCSI_ASYNC) {
1567 iscsi_err(__FILE__, __LINE__, "Opcode");
1568 return 1;
1570 msg->AHSlength = header[4]; /* TotalAHSLength */
1571 msg->length = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 4))); /* Length */
1572 msg->lun = ISCSI_NTOHLL6(*((uint64_t *) (void *) (header + 8))); /* LUN */
1573 msg->StatSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 24))); /* StatSN */
1574 msg->ExpCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 28))); /* ExpCmdSN */
1575 msg->MaxCmdSN = ISCSI_NTOHL(*((uint32_t *) (void *) (header + 32))); /* MaxCmdSN */
1576 msg->AsyncEvent = header[36]; /* Async Event */
1577 msg->AsyncVCode = header[37]; /* Async Vendor Code */
1579 iscsi_trace(TRACE_ISCSI_ARGS, "TotalAHSLength: %u\n", msg->AHSlength);
1580 iscsi_trace(TRACE_ISCSI_ARGS, "DataSegmentLength: %u\n", msg->length);
1581 iscsi_trace(TRACE_ISCSI_ARGS, "LUN: %" PRIu64 "\n", msg->lun);
1582 iscsi_trace(TRACE_ISCSI_ARGS, "StatSN: %u\n", msg->StatSN);
1583 iscsi_trace(TRACE_ISCSI_ARGS, "ExpCmdSN: %u\n", msg->ExpCmdSN);
1584 iscsi_trace(TRACE_ISCSI_ARGS, "MaxCmdSN: %u\n", msg->MaxCmdSN);
1585 iscsi_trace(TRACE_ISCSI_ARGS, "AsyncEvent: %u\n", msg->AsyncEvent);
1586 iscsi_trace(TRACE_ISCSI_ARGS, "AsyncVCode: %u\n", msg->AsyncVCode);
1588 return 0;