1171568Sscottl/*- 2211095Sdes * Copyright (c) 2005-2010 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/* 29171568Sscottl | $Id: misc.c,v 2.1 2006/11/12 08:06:51 danny Exp $ 30171568Sscottl */ 31171568Sscottl 32171568Sscottl#include <sys/cdefs.h> 33171568Sscottl__FBSDID("$FreeBSD$"); 34171568Sscottl 35171568Sscottl#include <sys/param.h> 36171568Sscottl#include <sys/types.h> 37171568Sscottl#include <sys/socket.h> 38171568Sscottl#include <sys/sysctl.h> 39171568Sscottl 40171568Sscottl#include <netinet/in.h> 41171568Sscottl#include <netinet/tcp.h> 42171568Sscottl#include <arpa/inet.h> 43171568Sscottl#include <stdlib.h> 44171568Sscottl#include <stdio.h> 45171568Sscottl#include <string.h> 46171568Sscottl 47254657Strasz#include <dev/iscsi_initiator/iscsi.h> 48211095Sdes#include "iscontrol.h" 49211095Sdes 50171568Sscottlstatic inline char 51171568Sscottlc2b(unsigned char c) 52171568Sscottl{ 53171568Sscottl switch(c) { 54171568Sscottl case '0' ... '9': 55171568Sscottl return c - '0'; 56171568Sscottl case 'a' ... 'f': 57171568Sscottl return c - 'a' + 10; 58171568Sscottl case 'A' ... 'F': 59171568Sscottl return c - 'A' + 10; 60171568Sscottl } 61171568Sscottl return 0; 62171568Sscottl} 63171568Sscottl 64171568Sscottlstatic char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 65171568Sscottl "abcdefghijklmnopqrstuvwxyz" 66171568Sscottl "0123456789+/"; 67171568Sscottl 68171568Sscottlstatic __inline unsigned char 69171568Sscottlc64tobin(unsigned char c64) 70171568Sscottl{ 71171568Sscottl int i; 72171568Sscottl for(i = 0; i < 64; i++) 73171568Sscottl if(base64[i] == c64) 74171568Sscottl break; 75171568Sscottl return i; 76171568Sscottl} 77171568Sscottl/* 78171568Sscottl | according to rfc3720, the binary string 79171568Sscottl | cannot be larger than 1024 - but i can't find it :-) XXX 80171568Sscottl | not enforced yet. 81171568Sscottl */ 82171568Sscottlint 83171568Sscottlstr2bin(char *str, char **rsp) 84171568Sscottl{ 85171568Sscottl char *src, *dst, *tmp; 86171568Sscottl int i, len = 0; 87171568Sscottl 88171568Sscottl src = str; 89171568Sscottl tmp = NULL; 90171568Sscottl if(strncasecmp("0x", src, 2) == 0) { 91171568Sscottl src += 2; 92171568Sscottl len = strlen(src); 93171568Sscottl 94171568Sscottl if((tmp = malloc((len+1)/2)) == NULL) { 95171568Sscottl // XXX: print some error? 96171568Sscottl return 0; 97171568Sscottl } 98171568Sscottl dst = tmp; 99171568Sscottl if(len & 1) 100171568Sscottl *dst++ = c2b(*src++); 101171568Sscottl while(*src) { 102171568Sscottl *dst = c2b(*src++) << 4; 103171568Sscottl *dst++ |= c2b(*src++); 104171568Sscottl } 105171568Sscottl len = dst - tmp; 106171568Sscottl } else 107171568Sscottl if(strncasecmp("0b", src , 2) == 0) { 108171568Sscottl // base64 109171568Sscottl unsigned char b6; 110171568Sscottl 111171568Sscottl src += 2; 112171568Sscottl len = strlen(src) / 4 * 3; 113171568Sscottl if((tmp = malloc(len)) == NULL) { 114171568Sscottl // XXX: print some error? 115171568Sscottl return 0; 116171568Sscottl } 117171568Sscottl dst = tmp; 118171568Sscottl i = 0; 119171568Sscottl while(*src && ((b6 = c64tobin(*src++)) != 64)) { 120171568Sscottl switch(i % 4) { 121171568Sscottl case 0: 122171568Sscottl *dst = b6 << 2; 123171568Sscottl break; 124171568Sscottl case 1: 125171568Sscottl *dst++ |= b6 >> 4; 126171568Sscottl *dst = b6 << 4; 127171568Sscottl break; 128171568Sscottl case 2: 129171568Sscottl *dst++ |= b6 >> 2; 130171568Sscottl *dst = b6 << 6; 131171568Sscottl break; 132171568Sscottl case 3: 133171568Sscottl *dst++ |= b6; 134171568Sscottl break; 135171568Sscottl } 136171568Sscottl i++; 137171568Sscottl } 138171568Sscottl len = dst - tmp; 139171568Sscottl } 140171568Sscottl else { 141171568Sscottl /* 142171568Sscottl | assume it to be an ascii string, so just copy it 143171568Sscottl */ 144171568Sscottl len = strlen(str); 145171568Sscottl if((tmp = malloc(len)) == NULL) 146171568Sscottl return 0; 147171568Sscottl dst = tmp; 148171568Sscottl src = str; 149171568Sscottl while(*src) 150171568Sscottl *dst++ = *src++; 151171568Sscottl } 152171568Sscottl 153171568Sscottl *rsp = tmp; 154171568Sscottl return len; 155171568Sscottl} 156171568Sscottl 157171568Sscottlchar * 158171568Sscottlbin2str(char *encoding, unsigned char *md, int blen) 159171568Sscottl{ 160171568Sscottl int len; 161176033Spb char *dst, *ds; 162176033Spb unsigned char *cp; 163171568Sscottl 164171568Sscottl if(strncasecmp(encoding, "0x", 2) == 0) { 165171568Sscottl char ofmt[5]; 166171568Sscottl 167171568Sscottl len = blen * 2; 168171568Sscottl dst = malloc(len + 3); 169171568Sscottl strcpy(dst, encoding); 170171568Sscottl ds = dst + 2; 171176033Spb cp = md; 172171568Sscottl sprintf(ofmt, "%%02%c", encoding[1]); 173171568Sscottl while(blen-- > 0) { 174171568Sscottl sprintf(ds, ofmt, *cp++); 175171568Sscottl ds += 2; 176171568Sscottl } 177171568Sscottl *ds = 0; 178171568Sscottl return dst; 179171568Sscottl } 180171568Sscottl if(strncasecmp(encoding, "0b", 2) == 0) { 181171568Sscottl int i, b6; 182171568Sscottl 183171568Sscottl len = (blen + 2) * 4 / 3; 184171568Sscottl dst = malloc(len + 3); 185171568Sscottl strcpy(dst, encoding); 186171568Sscottl ds = dst + 2; 187176033Spb cp = md; 188176034Spb b6 = 0; // to keep compiler happy. 189171568Sscottl for(i = 0; i < blen; i++) { 190171568Sscottl switch(i % 3) { 191171568Sscottl case 0: 192171568Sscottl *ds++ = base64[*cp >> 2]; 193171568Sscottl b6 = (*cp & 0x3) << 4; 194171568Sscottl break; 195171568Sscottl case 1: 196171568Sscottl b6 += (*cp >> 4); 197171568Sscottl *ds++ = base64[b6]; 198171568Sscottl b6 = (*cp & 0xf) << 2; 199171568Sscottl break; 200171568Sscottl case 2: 201171568Sscottl b6 += (*cp >> 6); 202171568Sscottl *ds++ = base64[b6]; 203171568Sscottl *ds++ = base64[*cp & 0x3f]; 204171568Sscottl } 205171568Sscottl cp++; 206171568Sscottl } 207171568Sscottl switch(blen % 3) { 208171568Sscottl case 0: 209171568Sscottl break; 210171568Sscottl case 1: 211171568Sscottl *ds++ = base64[b6]; 212171568Sscottl *ds++ = '='; 213171568Sscottl *ds++ = '='; 214171568Sscottl break; 215171568Sscottl case 2: 216171568Sscottl *ds++ = base64[b6]; 217171568Sscottl *ds++ = '='; 218171568Sscottl break; 219171568Sscottl } 220171568Sscottl 221171568Sscottl *ds = 0; 222171568Sscottl return dst; 223171568Sscottl } 224171568Sscottl 225171568Sscottl return NULL; 226171568Sscottl} 227