1171568Sscottl/*- 2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3330449Seadler * 4211095Sdes * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il> 5171568Sscottl * All rights reserved. 6171568Sscottl * 7171568Sscottl * Redistribution and use in source and binary forms, with or without 8171568Sscottl * modification, are permitted provided that the following conditions 9171568Sscottl * are met: 10171568Sscottl * 1. Redistributions of source code must retain the above copyright 11171568Sscottl * notice, this list of conditions and the following disclaimer. 12171568Sscottl * 2. Redistributions in binary form must reproduce the above copyright 13171568Sscottl * notice, this list of conditions and the following disclaimer in the 14171568Sscottl * documentation and/or other materials provided with the distribution. 15171568Sscottl * 16171568Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17171568Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18171568Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19171568Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20171568Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21171568Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22171568Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23171568Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24171568Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25171568Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26171568Sscottl * SUCH DAMAGE. 27171568Sscottl * 28171568Sscottl */ 29171568Sscottl 30171568Sscottl/* 31171568Sscottl | $Id: misc.c,v 2.1 2006/11/12 08:06:51 danny Exp $ 32171568Sscottl */ 33171568Sscottl 34171568Sscottl#include <sys/cdefs.h> 35171568Sscottl__FBSDID("$FreeBSD: stable/11/sbin/iscontrol/misc.c 330449 2018-03-05 07:26:05Z eadler $"); 36171568Sscottl 37171568Sscottl#include <sys/param.h> 38171568Sscottl#include <sys/types.h> 39171568Sscottl#include <sys/socket.h> 40171568Sscottl#include <sys/sysctl.h> 41171568Sscottl 42171568Sscottl#include <netinet/in.h> 43171568Sscottl#include <netinet/tcp.h> 44171568Sscottl#include <arpa/inet.h> 45171568Sscottl#include <stdlib.h> 46171568Sscottl#include <stdio.h> 47171568Sscottl#include <string.h> 48171568Sscottl 49254657Strasz#include <dev/iscsi_initiator/iscsi.h> 50211095Sdes#include "iscontrol.h" 51211095Sdes 52171568Sscottlstatic inline char 53171568Sscottlc2b(unsigned char c) 54171568Sscottl{ 55171568Sscottl switch(c) { 56171568Sscottl case '0' ... '9': 57171568Sscottl return c - '0'; 58171568Sscottl case 'a' ... 'f': 59171568Sscottl return c - 'a' + 10; 60171568Sscottl case 'A' ... 'F': 61171568Sscottl return c - 'A' + 10; 62171568Sscottl } 63171568Sscottl return 0; 64171568Sscottl} 65171568Sscottl 66171568Sscottlstatic char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 67171568Sscottl "abcdefghijklmnopqrstuvwxyz" 68171568Sscottl "0123456789+/"; 69171568Sscottl 70171568Sscottlstatic __inline unsigned char 71171568Sscottlc64tobin(unsigned char c64) 72171568Sscottl{ 73171568Sscottl int i; 74171568Sscottl for(i = 0; i < 64; i++) 75171568Sscottl if(base64[i] == c64) 76171568Sscottl break; 77171568Sscottl return i; 78171568Sscottl} 79171568Sscottl/* 80171568Sscottl | according to rfc3720, the binary string 81171568Sscottl | cannot be larger than 1024 - but i can't find it :-) XXX 82171568Sscottl | not enforced yet. 83171568Sscottl */ 84171568Sscottlint 85171568Sscottlstr2bin(char *str, char **rsp) 86171568Sscottl{ 87171568Sscottl char *src, *dst, *tmp; 88171568Sscottl int i, len = 0; 89171568Sscottl 90171568Sscottl src = str; 91171568Sscottl tmp = NULL; 92171568Sscottl if(strncasecmp("0x", src, 2) == 0) { 93171568Sscottl src += 2; 94171568Sscottl len = strlen(src); 95171568Sscottl 96171568Sscottl if((tmp = malloc((len+1)/2)) == NULL) { 97171568Sscottl // XXX: print some error? 98171568Sscottl return 0; 99171568Sscottl } 100171568Sscottl dst = tmp; 101171568Sscottl if(len & 1) 102171568Sscottl *dst++ = c2b(*src++); 103171568Sscottl while(*src) { 104171568Sscottl *dst = c2b(*src++) << 4; 105171568Sscottl *dst++ |= c2b(*src++); 106171568Sscottl } 107171568Sscottl len = dst - tmp; 108171568Sscottl } else 109171568Sscottl if(strncasecmp("0b", src , 2) == 0) { 110171568Sscottl // base64 111171568Sscottl unsigned char b6; 112171568Sscottl 113171568Sscottl src += 2; 114171568Sscottl len = strlen(src) / 4 * 3; 115171568Sscottl if((tmp = malloc(len)) == NULL) { 116171568Sscottl // XXX: print some error? 117171568Sscottl return 0; 118171568Sscottl } 119171568Sscottl dst = tmp; 120171568Sscottl i = 0; 121171568Sscottl while(*src && ((b6 = c64tobin(*src++)) != 64)) { 122171568Sscottl switch(i % 4) { 123171568Sscottl case 0: 124171568Sscottl *dst = b6 << 2; 125171568Sscottl break; 126171568Sscottl case 1: 127171568Sscottl *dst++ |= b6 >> 4; 128171568Sscottl *dst = b6 << 4; 129171568Sscottl break; 130171568Sscottl case 2: 131171568Sscottl *dst++ |= b6 >> 2; 132171568Sscottl *dst = b6 << 6; 133171568Sscottl break; 134171568Sscottl case 3: 135171568Sscottl *dst++ |= b6; 136171568Sscottl break; 137171568Sscottl } 138171568Sscottl i++; 139171568Sscottl } 140171568Sscottl len = dst - tmp; 141171568Sscottl } 142171568Sscottl else { 143171568Sscottl /* 144171568Sscottl | assume it to be an ascii string, so just copy it 145171568Sscottl */ 146171568Sscottl len = strlen(str); 147171568Sscottl if((tmp = malloc(len)) == NULL) 148171568Sscottl return 0; 149171568Sscottl dst = tmp; 150171568Sscottl src = str; 151171568Sscottl while(*src) 152171568Sscottl *dst++ = *src++; 153171568Sscottl } 154171568Sscottl 155171568Sscottl *rsp = tmp; 156171568Sscottl return len; 157171568Sscottl} 158171568Sscottl 159171568Sscottlchar * 160171568Sscottlbin2str(char *encoding, unsigned char *md, int blen) 161171568Sscottl{ 162171568Sscottl int len; 163176033Spb char *dst, *ds; 164176033Spb unsigned char *cp; 165171568Sscottl 166171568Sscottl if(strncasecmp(encoding, "0x", 2) == 0) { 167171568Sscottl char ofmt[5]; 168171568Sscottl 169171568Sscottl len = blen * 2; 170171568Sscottl dst = malloc(len + 3); 171171568Sscottl strcpy(dst, encoding); 172171568Sscottl ds = dst + 2; 173176033Spb cp = md; 174171568Sscottl sprintf(ofmt, "%%02%c", encoding[1]); 175171568Sscottl while(blen-- > 0) { 176171568Sscottl sprintf(ds, ofmt, *cp++); 177171568Sscottl ds += 2; 178171568Sscottl } 179171568Sscottl *ds = 0; 180171568Sscottl return dst; 181171568Sscottl } 182171568Sscottl if(strncasecmp(encoding, "0b", 2) == 0) { 183171568Sscottl int i, b6; 184171568Sscottl 185171568Sscottl len = (blen + 2) * 4 / 3; 186171568Sscottl dst = malloc(len + 3); 187171568Sscottl strcpy(dst, encoding); 188171568Sscottl ds = dst + 2; 189176033Spb cp = md; 190176034Spb b6 = 0; // to keep compiler happy. 191171568Sscottl for(i = 0; i < blen; i++) { 192171568Sscottl switch(i % 3) { 193171568Sscottl case 0: 194171568Sscottl *ds++ = base64[*cp >> 2]; 195171568Sscottl b6 = (*cp & 0x3) << 4; 196171568Sscottl break; 197171568Sscottl case 1: 198171568Sscottl b6 += (*cp >> 4); 199171568Sscottl *ds++ = base64[b6]; 200171568Sscottl b6 = (*cp & 0xf) << 2; 201171568Sscottl break; 202171568Sscottl case 2: 203171568Sscottl b6 += (*cp >> 6); 204171568Sscottl *ds++ = base64[b6]; 205171568Sscottl *ds++ = base64[*cp & 0x3f]; 206171568Sscottl } 207171568Sscottl cp++; 208171568Sscottl } 209171568Sscottl switch(blen % 3) { 210171568Sscottl case 0: 211171568Sscottl break; 212171568Sscottl case 1: 213171568Sscottl *ds++ = base64[b6]; 214171568Sscottl *ds++ = '='; 215171568Sscottl *ds++ = '='; 216171568Sscottl break; 217171568Sscottl case 2: 218171568Sscottl *ds++ = base64[b6]; 219171568Sscottl *ds++ = '='; 220171568Sscottl break; 221171568Sscottl } 222171568Sscottl 223171568Sscottl *ds = 0; 224171568Sscottl return dst; 225171568Sscottl } 226171568Sscottl 227171568Sscottl return NULL; 228171568Sscottl} 229