1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2005-2010 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/* 31 | $Id: misc.c,v 2.1 2006/11/12 08:06:51 danny Exp $ 32 */ 33 34#include <sys/cdefs.h> 35__FBSDID("$FreeBSD: stable/11/sbin/iscontrol/misc.c 330449 2018-03-05 07:26:05Z eadler $"); 36 37#include <sys/param.h> 38#include <sys/types.h> 39#include <sys/socket.h> 40#include <sys/sysctl.h> 41 42#include <netinet/in.h> 43#include <netinet/tcp.h> 44#include <arpa/inet.h> 45#include <stdlib.h> 46#include <stdio.h> 47#include <string.h> 48 49#include <dev/iscsi_initiator/iscsi.h> 50#include "iscontrol.h" 51 52static inline char 53c2b(unsigned char c) 54{ 55 switch(c) { 56 case '0' ... '9': 57 return c - '0'; 58 case 'a' ... 'f': 59 return c - 'a' + 10; 60 case 'A' ... 'F': 61 return c - 'A' + 10; 62 } 63 return 0; 64} 65 66static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 67 "abcdefghijklmnopqrstuvwxyz" 68 "0123456789+/"; 69 70static __inline unsigned char 71c64tobin(unsigned char c64) 72{ 73 int i; 74 for(i = 0; i < 64; i++) 75 if(base64[i] == c64) 76 break; 77 return i; 78} 79/* 80 | according to rfc3720, the binary string 81 | cannot be larger than 1024 - but i can't find it :-) XXX 82 | not enforced yet. 83 */ 84int 85str2bin(char *str, char **rsp) 86{ 87 char *src, *dst, *tmp; 88 int i, len = 0; 89 90 src = str; 91 tmp = NULL; 92 if(strncasecmp("0x", src, 2) == 0) { 93 src += 2; 94 len = strlen(src); 95 96 if((tmp = malloc((len+1)/2)) == NULL) { 97 // XXX: print some error? 98 return 0; 99 } 100 dst = tmp; 101 if(len & 1) 102 *dst++ = c2b(*src++); 103 while(*src) { 104 *dst = c2b(*src++) << 4; 105 *dst++ |= c2b(*src++); 106 } 107 len = dst - tmp; 108 } else 109 if(strncasecmp("0b", src , 2) == 0) { 110 // base64 111 unsigned char b6; 112 113 src += 2; 114 len = strlen(src) / 4 * 3; 115 if((tmp = malloc(len)) == NULL) { 116 // XXX: print some error? 117 return 0; 118 } 119 dst = tmp; 120 i = 0; 121 while(*src && ((b6 = c64tobin(*src++)) != 64)) { 122 switch(i % 4) { 123 case 0: 124 *dst = b6 << 2; 125 break; 126 case 1: 127 *dst++ |= b6 >> 4; 128 *dst = b6 << 4; 129 break; 130 case 2: 131 *dst++ |= b6 >> 2; 132 *dst = b6 << 6; 133 break; 134 case 3: 135 *dst++ |= b6; 136 break; 137 } 138 i++; 139 } 140 len = dst - tmp; 141 } 142 else { 143 /* 144 | assume it to be an ascii string, so just copy it 145 */ 146 len = strlen(str); 147 if((tmp = malloc(len)) == NULL) 148 return 0; 149 dst = tmp; 150 src = str; 151 while(*src) 152 *dst++ = *src++; 153 } 154 155 *rsp = tmp; 156 return len; 157} 158 159char * 160bin2str(char *encoding, unsigned char *md, int blen) 161{ 162 int len; 163 char *dst, *ds; 164 unsigned char *cp; 165 166 if(strncasecmp(encoding, "0x", 2) == 0) { 167 char ofmt[5]; 168 169 len = blen * 2; 170 dst = malloc(len + 3); 171 strcpy(dst, encoding); 172 ds = dst + 2; 173 cp = md; 174 sprintf(ofmt, "%%02%c", encoding[1]); 175 while(blen-- > 0) { 176 sprintf(ds, ofmt, *cp++); 177 ds += 2; 178 } 179 *ds = 0; 180 return dst; 181 } 182 if(strncasecmp(encoding, "0b", 2) == 0) { 183 int i, b6; 184 185 len = (blen + 2) * 4 / 3; 186 dst = malloc(len + 3); 187 strcpy(dst, encoding); 188 ds = dst + 2; 189 cp = md; 190 b6 = 0; // to keep compiler happy. 191 for(i = 0; i < blen; i++) { 192 switch(i % 3) { 193 case 0: 194 *ds++ = base64[*cp >> 2]; 195 b6 = (*cp & 0x3) << 4; 196 break; 197 case 1: 198 b6 += (*cp >> 4); 199 *ds++ = base64[b6]; 200 b6 = (*cp & 0xf) << 2; 201 break; 202 case 2: 203 b6 += (*cp >> 6); 204 *ds++ = base64[b6]; 205 *ds++ = base64[*cp & 0x3f]; 206 } 207 cp++; 208 } 209 switch(blen % 3) { 210 case 0: 211 break; 212 case 1: 213 *ds++ = base64[b6]; 214 *ds++ = '='; 215 *ds++ = '='; 216 break; 217 case 2: 218 *ds++ = base64[b6]; 219 *ds++ = '='; 220 break; 221 } 222 223 *ds = 0; 224 return dst; 225 } 226 227 return NULL; 228} 229