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