1171568Sscottl/*- 2234233Sjpaetzel * Copyright (c) 2005-2011 Daniel Braniss <danny@cs.huji.ac.il> 3171568Sscottl * All rights reserved. 4171568Sscottl * 5171568Sscottl * Redistribution and use in source and binary forms, with or without 6171568Sscottl * modification, are permitted provided that the following conditions 7171568Sscottl * are met: 8171568Sscottl * 1. Redistributions of source code must retain the above copyright 9171568Sscottl * notice, this list of conditions and the following disclaimer. 10171568Sscottl * 2. Redistributions in binary form must reproduce the above copyright 11171568Sscottl * notice, this list of conditions and the following disclaimer in the 12171568Sscottl * documentation and/or other materials provided with the distribution. 13171568Sscottl * 14171568Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171568Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171568Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171568Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171568Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171568Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171568Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171568Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171568Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171568Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171568Sscottl * SUCH DAMAGE. 25171568Sscottl * 26171568Sscottl */ 27171568Sscottl/* 28171568Sscottl | iSCSI 29211095Sdes | $Id: isc_subr.c 560 2009-05-07 07:37:49Z danny $ 30171568Sscottl */ 31171568Sscottl 32171568Sscottl#include <sys/cdefs.h> 33171568Sscottl__FBSDID("$FreeBSD$"); 34171568Sscottl 35171568Sscottl#include "opt_iscsi_initiator.h" 36171568Sscottl 37171568Sscottl#include <sys/param.h> 38171568Sscottl#include <sys/kernel.h> 39171568Sscottl#include <sys/conf.h> 40171568Sscottl#include <sys/systm.h> 41171568Sscottl#include <sys/malloc.h> 42171568Sscottl#include <sys/ctype.h> 43171568Sscottl#include <sys/errno.h> 44171568Sscottl#include <sys/sysctl.h> 45171568Sscottl#include <sys/file.h> 46171568Sscottl#include <sys/uio.h> 47171568Sscottl#include <sys/socketvar.h> 48171568Sscottl#include <sys/socket.h> 49171568Sscottl#include <sys/protosw.h> 50171568Sscottl#include <sys/proc.h> 51171568Sscottl#include <sys/ioccom.h> 52171568Sscottl#include <sys/queue.h> 53171568Sscottl#include <sys/kthread.h> 54171568Sscottl#include <sys/syslog.h> 55171568Sscottl#include <sys/mbuf.h> 56171568Sscottl#include <sys/libkern.h> 57171568Sscottl 58254657Strasz#include <dev/iscsi_initiator/iscsi.h> 59254657Strasz#include <dev/iscsi_initiator/iscsivar.h> 60171568Sscottl 61227293Sedstatic MALLOC_DEFINE(M_ISC, "iSC", "iSCSI driver options"); 62211095Sdes 63171568Sscottlstatic char * 64171568Sscottli_strdupin(char *s, size_t maxlen) 65171568Sscottl{ 66171568Sscottl size_t len; 67171568Sscottl char *p, *q; 68171568Sscottl 69211095Sdes p = malloc(maxlen, M_ISC, M_WAITOK); 70171568Sscottl if(copyinstr(s, p, maxlen, &len)) { 71211095Sdes free(p, M_ISC); 72171568Sscottl return NULL; 73171568Sscottl } 74211095Sdes q = malloc(len, M_ISC, M_WAITOK); 75171568Sscottl bcopy(p, q, len); 76211095Sdes free(p, M_ISC); 77171568Sscottl 78171568Sscottl return q; 79171568Sscottl} 80234233Sjpaetzel#if __FreeBSD_version < 800000 81234233Sjpaetzel/*****************************************************************/ 82234233Sjpaetzel/* */ 83234233Sjpaetzel/* CRC LOOKUP TABLE */ 84234233Sjpaetzel/* ================ */ 85234233Sjpaetzel/* The following CRC lookup table was generated automagically */ 86234233Sjpaetzel/* by the Rocksoft^tm Model CRC Algorithm Table Generation */ 87234233Sjpaetzel/* Program V1.0 using the following model parameters: */ 88234233Sjpaetzel/* */ 89234233Sjpaetzel/* Width : 4 bytes. */ 90234233Sjpaetzel/* Poly : 0x1EDC6F41L */ 91234233Sjpaetzel/* Reverse : TRUE. */ 92234233Sjpaetzel/* */ 93234233Sjpaetzel/* For more information on the Rocksoft^tm Model CRC Algorithm, */ 94234233Sjpaetzel/* see the document titled "A Painless Guide to CRC Error */ 95234233Sjpaetzel/* Detection Algorithms" by Ross Williams */ 96234233Sjpaetzel/* (ross@guest.adelaide.edu.au.). This document is likely to be */ 97234233Sjpaetzel/* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". */ 98234233Sjpaetzel/* */ 99234233Sjpaetzel/*****************************************************************/ 100171568Sscottl 101234233Sjpaetzelstatic uint32_t crc32Table[256] = { 102234233Sjpaetzel 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 103234233Sjpaetzel 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 104234233Sjpaetzel 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 105234233Sjpaetzel 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 106234233Sjpaetzel 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 107234233Sjpaetzel 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 108234233Sjpaetzel 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 109234233Sjpaetzel 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 110234233Sjpaetzel 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 111234233Sjpaetzel 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 112234233Sjpaetzel 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 113234233Sjpaetzel 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 114234233Sjpaetzel 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 115234233Sjpaetzel 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, 116234233Sjpaetzel 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 117234233Sjpaetzel 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 118234233Sjpaetzel 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 119234233Sjpaetzel 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, 120234233Sjpaetzel 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 121234233Sjpaetzel 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 122234233Sjpaetzel 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 123234233Sjpaetzel 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 124234233Sjpaetzel 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 125234233Sjpaetzel 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 126234233Sjpaetzel 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 127234233Sjpaetzel 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 128234233Sjpaetzel 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 129234233Sjpaetzel 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 130234233Sjpaetzel 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 131234233Sjpaetzel 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, 132234233Sjpaetzel 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 133234233Sjpaetzel 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 134234233Sjpaetzel 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 135234233Sjpaetzel 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, 136234233Sjpaetzel 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 137234233Sjpaetzel 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 138234233Sjpaetzel 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 139234233Sjpaetzel 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 140234233Sjpaetzel 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 141234233Sjpaetzel 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 142234233Sjpaetzel 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 143234233Sjpaetzel 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 144234233Sjpaetzel 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 145234233Sjpaetzel 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 146234233Sjpaetzel 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 147234233Sjpaetzel 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 148234233Sjpaetzel 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 149234233Sjpaetzel 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 150234233Sjpaetzel 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 151234233Sjpaetzel 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, 152234233Sjpaetzel 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 153234233Sjpaetzel 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 154234233Sjpaetzel 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 155234233Sjpaetzel 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, 156234233Sjpaetzel 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 157234233Sjpaetzel 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 158234233Sjpaetzel 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 159234233Sjpaetzel 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 160234233Sjpaetzel 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 161234233Sjpaetzel 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 162234233Sjpaetzel 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 163234233Sjpaetzel 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 164234233Sjpaetzel 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 165234233Sjpaetzel 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L 166234233Sjpaetzel}; 167234233Sjpaetzel 168234233Sjpaetzelstatic __inline int 169234233Sjpaetzelcalculate_crc32c(uint32_t crc, const void *buf, size_t size) 170234233Sjpaetzel{ 171234233Sjpaetzel const uint8_t *p = buf; 172234233Sjpaetzel 173234233Sjpaetzel while (size--) 174234233Sjpaetzel crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8); 175234233Sjpaetzel return crc; 176234233Sjpaetzel} 177234233Sjpaetzel#endif 178234233Sjpaetzel 179171568Sscottlstatic uint32_t 180171568Sscottli_crc32c(const void *buf, size_t size, uint32_t crc) 181171568Sscottl{ 182171568Sscottl crc = crc ^ 0xffffffff; 183188605Srrs crc = calculate_crc32c(crc, buf, size); 184171568Sscottl crc = crc ^ 0xffffffff; 185171568Sscottl return crc; 186171568Sscottl} 187171568Sscottl 188171568Sscottl/* 189171568Sscottl | XXX: not finished coding 190171568Sscottl */ 191171568Sscottlint 192171568Sscottli_setopt(isc_session_t *sp, isc_opt_t *opt) 193171568Sscottl{ 194171568Sscottl if(opt->maxRecvDataSegmentLength > 0) { 195171568Sscottl sp->opt.maxRecvDataSegmentLength = opt->maxRecvDataSegmentLength; 196171568Sscottl sdebug(2, "maxRecvDataSegmentLength=%d", sp->opt.maxRecvDataSegmentLength); 197171568Sscottl } 198171568Sscottl if(opt->maxXmitDataSegmentLength > 0) { 199171568Sscottl // danny's RFC 200171568Sscottl sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength; 201211095Sdes sdebug(2, "opt.maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength); 202171568Sscottl } 203171568Sscottl if(opt->maxBurstLength != 0) { 204171568Sscottl sp->opt.maxBurstLength = opt->maxBurstLength; 205211095Sdes sdebug(2, "opt.maxBurstLength=%d", sp->opt.maxBurstLength); 206171568Sscottl } 207171568Sscottl 208171568Sscottl if(opt->targetAddress != NULL) { 209171568Sscottl if(sp->opt.targetAddress != NULL) 210211095Sdes free(sp->opt.targetAddress, M_ISC); 211171568Sscottl sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128); 212211095Sdes sdebug(2, "opt.targetAddress='%s'", sp->opt.targetAddress); 213171568Sscottl } 214171568Sscottl if(opt->targetName != NULL) { 215171568Sscottl if(sp->opt.targetName != NULL) 216211095Sdes free(sp->opt.targetName, M_ISC); 217171568Sscottl sp->opt.targetName = i_strdupin(opt->targetName, 128); 218211095Sdes sdebug(2, "opt.targetName='%s'", sp->opt.targetName); 219171568Sscottl } 220171568Sscottl if(opt->initiatorName != NULL) { 221171568Sscottl if(sp->opt.initiatorName != NULL) 222211095Sdes free(sp->opt.initiatorName, M_ISC); 223171568Sscottl sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128); 224211095Sdes sdebug(2, "opt.initiatorName='%s'", sp->opt.initiatorName); 225171568Sscottl } 226171568Sscottl 227171568Sscottl if(opt->maxluns > 0) { 228171568Sscottl if(opt->maxluns > ISCSI_MAX_LUNS) 229171568Sscottl sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ... 230171568Sscottl sp->opt.maxluns = opt->maxluns; 231211095Sdes sdebug(2, "opt.maxluns=%d", sp->opt.maxluns); 232171568Sscottl } 233171568Sscottl 234171568Sscottl if(opt->headerDigest != NULL) { 235171568Sscottl sdebug(2, "opt.headerDigest='%s'", opt->headerDigest); 236171568Sscottl if(strcmp(opt->headerDigest, "CRC32C") == 0) { 237171568Sscottl sp->hdrDigest = (digest_t *)i_crc32c; 238211095Sdes sdebug(2, "opt.headerDigest set"); 239171568Sscottl } 240171568Sscottl } 241171568Sscottl if(opt->dataDigest != NULL) { 242211095Sdes sdebug(2, "opt.dataDigest='%s'", opt->headerDigest); 243171568Sscottl if(strcmp(opt->dataDigest, "CRC32C") == 0) { 244171568Sscottl sp->dataDigest = (digest_t *)i_crc32c; 245211095Sdes sdebug(2, "opt.dataDigest set"); 246171568Sscottl } 247171568Sscottl } 248171568Sscottl 249171568Sscottl return 0; 250171568Sscottl} 251171568Sscottl 252171568Sscottlvoid 253171568Sscottli_freeopt(isc_opt_t *opt) 254171568Sscottl{ 255211095Sdes debug_called(8); 256211095Sdes 257171568Sscottl if(opt->targetAddress != NULL) { 258211095Sdes free(opt->targetAddress, M_ISC); 259171568Sscottl opt->targetAddress = NULL; 260171568Sscottl } 261171568Sscottl if(opt->targetName != NULL) { 262211095Sdes free(opt->targetName, M_ISC); 263171568Sscottl opt->targetName = NULL; 264171568Sscottl } 265171568Sscottl if(opt->initiatorName != NULL) { 266211095Sdes free(opt->initiatorName, M_ISC); 267171568Sscottl opt->initiatorName = NULL; 268171568Sscottl } 269171568Sscottl} 270