2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2005-2011 Daniel Braniss <danny@cs.huji.ac.il>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
31 | $Id: isc_subr.c 560 2009-05-07 07:37:49Z danny $
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
37 #include "opt_iscsi_initiator.h"
39 #include <sys/param.h>
40 #include <sys/kernel.h>
42 #include <sys/gsb_crc32.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/ctype.h>
46 #include <sys/errno.h>
47 #include <sys/sysctl.h>
50 #include <sys/socketvar.h>
51 #include <sys/socket.h>
52 #include <sys/protosw.h>
54 #include <sys/ioccom.h>
55 #include <sys/queue.h>
56 #include <sys/kthread.h>
57 #include <sys/syslog.h>
59 #include <sys/libkern.h>
62 #include <dev/iscsi_initiator/iscsi.h>
63 #include <dev/iscsi_initiator/iscsivar.h>
65 static MALLOC_DEFINE(M_ISC, "iSC", "iSCSI driver options");
68 i_strdupin(char *s, size_t maxlen)
73 p = malloc(maxlen, M_ISC, M_WAITOK);
74 if(copyinstr(s, p, maxlen, &len)) {
78 q = malloc(len, M_ISC, M_WAITOK);
84 #if __FreeBSD_version < 800000
85 /*****************************************************************/
87 /* CRC LOOKUP TABLE */
88 /* ================ */
89 /* The following CRC lookup table was generated automagically */
90 /* by the Rocksoft^tm Model CRC Algorithm Table Generation */
91 /* Program V1.0 using the following model parameters: */
93 /* Width : 4 bytes. */
94 /* Poly : 0x1EDC6F41L */
97 /* For more information on the Rocksoft^tm Model CRC Algorithm, */
98 /* see the document titled "A Painless Guide to CRC Error */
99 /* Detection Algorithms" by Ross Williams */
100 /* (ross@guest.adelaide.edu.au.). This document is likely to be */
101 /* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */
103 /*****************************************************************/
105 static uint32_t crc32Table[256] = {
106 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
107 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
108 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
109 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
110 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
111 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
112 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
113 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
114 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
115 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
116 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
117 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
118 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
119 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
120 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
121 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
122 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
123 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
124 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
125 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
126 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
127 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
128 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
129 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
130 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
131 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
132 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
133 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
134 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
135 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
136 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
137 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
138 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
139 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
140 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
141 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
142 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
143 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
144 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
145 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
146 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
147 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
148 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
149 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
150 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
151 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
152 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
153 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
154 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
155 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
156 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
157 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
158 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
159 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
160 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
161 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
162 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
163 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
164 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
165 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
166 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
167 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
168 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
169 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
173 calculate_crc32c(uint32_t crc, const void *buf, size_t size)
175 const uint8_t *p = buf;
178 crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
184 i_crc32c(const void *buf, size_t size, uint32_t crc)
186 crc = crc ^ 0xffffffff;
187 crc = calculate_crc32c(crc, buf, size);
188 crc = crc ^ 0xffffffff;
193 | XXX: not finished coding
196 i_setopt(isc_session_t *sp, isc_opt_t *opt)
198 if(opt->maxRecvDataSegmentLength > 0) {
199 sp->opt.maxRecvDataSegmentLength = opt->maxRecvDataSegmentLength;
200 sdebug(2, "maxRecvDataSegmentLength=%d", sp->opt.maxRecvDataSegmentLength);
202 if(opt->maxXmitDataSegmentLength > 0) {
204 sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength;
205 sdebug(2, "opt.maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength);
207 if(opt->maxBurstLength != 0) {
208 sp->opt.maxBurstLength = opt->maxBurstLength;
209 sdebug(2, "opt.maxBurstLength=%d", sp->opt.maxBurstLength);
212 if(opt->targetAddress != NULL) {
213 if(sp->opt.targetAddress != NULL)
214 free(sp->opt.targetAddress, M_ISC);
215 sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128);
216 sdebug(2, "opt.targetAddress='%s'", sp->opt.targetAddress);
218 if(opt->targetName != NULL) {
219 if(sp->opt.targetName != NULL)
220 free(sp->opt.targetName, M_ISC);
221 sp->opt.targetName = i_strdupin(opt->targetName, 128);
222 sdebug(2, "opt.targetName='%s'", sp->opt.targetName);
224 if(opt->initiatorName != NULL) {
225 if(sp->opt.initiatorName != NULL)
226 free(sp->opt.initiatorName, M_ISC);
227 sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128);
228 sdebug(2, "opt.initiatorName='%s'", sp->opt.initiatorName);
231 if(opt->maxluns > 0) {
232 if(opt->maxluns > ISCSI_MAX_LUNS)
233 sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ...
234 sp->opt.maxluns = opt->maxluns;
235 sdebug(2, "opt.maxluns=%d", sp->opt.maxluns);
238 if(opt->headerDigest != NULL) {
239 sdebug(2, "opt.headerDigest='%s'", opt->headerDigest);
240 if(strcmp(opt->headerDigest, "CRC32C") == 0) {
241 sp->hdrDigest = (digest_t *)i_crc32c;
242 sdebug(2, "opt.headerDigest set");
245 if(opt->dataDigest != NULL) {
246 sdebug(2, "opt.dataDigest='%s'", opt->headerDigest);
247 if(strcmp(opt->dataDigest, "CRC32C") == 0) {
248 sp->dataDigest = (digest_t *)i_crc32c;
249 sdebug(2, "opt.dataDigest set");
257 i_freeopt(isc_opt_t *opt)
261 if(opt->targetAddress != NULL) {
262 free(opt->targetAddress, M_ISC);
263 opt->targetAddress = NULL;
265 if(opt->targetName != NULL) {
266 free(opt->targetName, M_ISC);
267 opt->targetName = NULL;
269 if(opt->initiatorName != NULL) {
270 free(opt->initiatorName, M_ISC);
271 opt->initiatorName = NULL;