Annotation of embedaddon/istgt/src/istgt_crc32c.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2008-2010 Daisuke Aoyama <aoyama@peach.ne.jp>.
! 3: * All rights reserved.
! 4: *
! 5: * Redistribution and use in source and binary forms, with or without
! 6: * modification, are permitted provided that the following conditions
! 7: * are met:
! 8: * 1. Redistributions of source code must retain the above copyright
! 9: * notice, this list of conditions and the following disclaimer.
! 10: * 2. Redistributions in binary form must reproduce the above copyright
! 11: * notice, this list of conditions and the following disclaimer in the
! 12: * documentation and/or other materials provided with the distribution.
! 13: *
! 14: * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
! 15: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 16: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 17: * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
! 18: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 19: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 20: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 21: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 22: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 23: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 24: * SUCH DAMAGE.
! 25: *
! 26: */
! 27:
! 28: #ifdef HAVE_CONFIG_H
! 29: #include "config.h"
! 30: #endif
! 31:
! 32: #include <inttypes.h>
! 33: #include <stdint.h>
! 34:
! 35: #include <ctype.h>
! 36: #include <stdio.h>
! 37: #include <string.h>
! 38: #include <sys/uio.h>
! 39:
! 40: #include "istgt_iscsi.h"
! 41: #include "istgt_crc32c.h"
! 42:
! 43: /* defined in RFC3720(12.1) */
! 44: static uint32_t istgt_crc32c_initial = ISTGT_CRC32C_INITIAL;
! 45: static uint32_t istgt_crc32c_xor = ISTGT_CRC32C_XOR;
! 46: static uint32_t istgt_crc32c_polynomial = ISTGT_CRC32C_POLYNOMIAL;
! 47: #ifdef ISTGT_USE_CRC32C_TABLE
! 48: static uint32_t istgt_crc32c_table[256];
! 49: static int istgt_crc32c_initialized = 0;
! 50: #endif /* ISTGT_USE_CRC32C_TABLE */
! 51:
! 52: static uint32_t
! 53: istgt_reflect(uint32_t val, int bits)
! 54: {
! 55: int i;
! 56: uint32_t r;
! 57:
! 58: if (bits < 1 || bits > 32)
! 59: return 0;
! 60: r = 0;
! 61: for (i = 0; i < bits; i++) {
! 62: r |= ((val >> ((bits - 1) - i)) & 1) << i;
! 63: }
! 64: return r;
! 65: }
! 66:
! 67: #ifdef ISTGT_USE_CRC32C_TABLE
! 68: void
! 69: istgt_init_crc32c_table(void)
! 70: {
! 71: int i, j;
! 72: uint32_t val;
! 73: uint32_t reflect_polynomial;
! 74:
! 75: reflect_polynomial = istgt_reflect(istgt_crc32c_polynomial, 32);
! 76: for (i = 0; i < 256; i++) {
! 77: val = i;
! 78: for (j = 0; j < 8; j++) {
! 79: if (val & 1) {
! 80: val = (val >> 1) ^ reflect_polynomial;
! 81: } else {
! 82: val = (val >> 1);
! 83: }
! 84: }
! 85: istgt_crc32c_table[i] = val;
! 86: }
! 87: istgt_crc32c_initialized = 1;
! 88: }
! 89: #endif /* ISTGT_USE_CRC32C_TABLE */
! 90:
! 91: uint32_t
! 92: istgt_update_crc32c(const uint8_t *buf, size_t len, uint32_t crc)
! 93: {
! 94: size_t s;
! 95: #ifndef ISTGT_USE_CRC32C_TABLE
! 96: int i;
! 97: uint32_t val;
! 98: uint32_t reflect_polynomial;
! 99: #endif /* ISTGT_USE_CRC32C_TABLE */
! 100:
! 101: #ifdef ISTGT_USE_CRC32C_TABLE
! 102: #if 0
! 103: /* initialize by main() */
! 104: if (!istgt_crc32c_initialized) {
! 105: istgt_init_crc32c_table();
! 106: }
! 107: #endif
! 108: #else
! 109: reflect_polynomial = istgt_reflect(istgt_crc32c_polynomial, 32);
! 110: #endif /* ISTGT_USE_CRC32C_TABLE */
! 111:
! 112: for (s = 0; s < len; s++) {
! 113: #ifdef ISTGT_USE_CRC32C_TABLE
! 114: crc = (crc >> 8) ^ istgt_crc32c_table[(crc ^ buf[s]) & 0xff];
! 115: #else
! 116: val = buf[s];
! 117: for (i = 0; i < 8; i++) {
! 118: if ((crc ^ val) & 1) {
! 119: crc = (crc >> 1) ^ reflect_polynomial;
! 120: } else {
! 121: crc = (crc >> 1);
! 122: }
! 123: val = val >> 1;
! 124: }
! 125: #endif /* ISTGT_USE_CRC32C_TABLE */
! 126: }
! 127: return crc;
! 128: }
! 129:
! 130: uint32_t
! 131: istgt_fixup_crc32c(size_t total, uint32_t crc)
! 132: {
! 133: uint8_t padding[ISCSI_ALIGNMENT];
! 134: size_t pad_length;
! 135: size_t rest;
! 136:
! 137: if (total == 0)
! 138: return crc;
! 139: #if 0
! 140: /* alignment must be power of 2 */
! 141: rest = total & ~(ISCSI_ALIGNMENT - 1);
! 142: #endif
! 143: rest = total % ISCSI_ALIGNMENT;
! 144: if (rest != 0) {
! 145: pad_length = ISCSI_ALIGNMENT;
! 146: pad_length -= rest;
! 147: if (pad_length > 0 && pad_length < sizeof padding){
! 148: memset(padding, 0, sizeof padding);
! 149: crc = istgt_update_crc32c(padding, pad_length, crc);
! 150: }
! 151: }
! 152: return crc;
! 153: }
! 154:
! 155: uint32_t
! 156: istgt_crc32c(const uint8_t *buf, size_t len)
! 157: {
! 158: uint32_t crc32c;
! 159:
! 160: crc32c = istgt_crc32c_initial;
! 161: crc32c = istgt_update_crc32c(buf, len, crc32c);
! 162: if ((len % ISCSI_ALIGNMENT) != 0) {
! 163: crc32c = istgt_fixup_crc32c(len, crc32c);
! 164: }
! 165: crc32c = crc32c ^ istgt_crc32c_xor;
! 166: return crc32c;
! 167: }
! 168:
! 169: uint32_t
! 170: istgt_iovec_crc32c(const struct iovec *iovp, int iovc, uint32_t offset, uint32_t len)
! 171: {
! 172: const uint8_t *p;
! 173: uint32_t total;
! 174: uint32_t pos;
! 175: uint32_t n;
! 176: uint32_t crc32c;
! 177: int i;
! 178:
! 179: pos = 0;
! 180: total = 0;
! 181: crc32c = istgt_crc32c_initial;
! 182: for (i = 0; i < iovc; i++) {
! 183: if (len == 0)
! 184: break;
! 185: if (pos + iovp[i].iov_len > offset) {
! 186: p = (const uint8_t *) iovp[i].iov_base + (offset - pos);
! 187: if (iovp[i].iov_len > len) {
! 188: n = len;
! 189: len = 0;
! 190: } else {
! 191: n = iovp[i].iov_len;
! 192: len -= n;
! 193: }
! 194: crc32c = istgt_update_crc32c(p, n, crc32c);
! 195: offset += n;
! 196: total += n;
! 197: }
! 198: pos += iovp[i].iov_len;
! 199: }
! 200: #if 0
! 201: printf("update %d bytes\n", total);
! 202: #endif
! 203: crc32c = istgt_fixup_crc32c(total, crc32c);
! 204: crc32c = crc32c ^ istgt_crc32c_xor;
! 205: return crc32c;
! 206: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>