11558Srgrimes/*- 298542Smckusick * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il> 398542Smckusick * All rights reserved. 498542Smckusick * 598542Smckusick * Redistribution and use in source and binary forms, with or without 698542Smckusick * modification, are permitted provided that the following conditions 798542Smckusick * are met: 898542Smckusick * 1. Redistributions of source code must retain the above copyright 9110884Smckusick * notice, this list of conditions and the following disclaimer. 1098542Smckusick * 2. Redistributions in binary form must reproduce the above copyright 111558Srgrimes * notice, this list of conditions and the following disclaimer in the 121558Srgrimes * documentation and/or other materials provided with the distribution. 131558Srgrimes * 141558Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 151558Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 161558Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 171558Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 181558Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 191558Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 201558Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 211558Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 221558Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 231558Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 241558Srgrimes * SUCH DAMAGE. 251558Srgrimes * 261558Srgrimes */ 271558Srgrimes 281558Srgrimes/* 291558Srgrimes | $Id: misc.c,v 2.1 2006/11/12 08:06:51 danny Exp $ 301558Srgrimes */ 311558Srgrimes 321558Srgrimes#include <sys/cdefs.h> 331558Srgrimes__FBSDID("$FreeBSD: releng/10.2/sbin/iscontrol/misc.c 254657 2013-08-22 14:02:34Z trasz $"); 341558Srgrimes 351558Srgrimes#include <sys/param.h> 361558Srgrimes#include <sys/types.h> 371558Srgrimes#include <sys/socket.h> 381558Srgrimes#include <sys/sysctl.h> 391558Srgrimes 401558Srgrimes#include <netinet/in.h> 411558Srgrimes#include <netinet/tcp.h> 421558Srgrimes#include <arpa/inet.h> 431558Srgrimes#include <stdlib.h> 4436998Scharnier#include <stdio.h> 451558Srgrimes#include <string.h> 461558Srgrimes 471558Srgrimes#include <dev/iscsi_initiator/iscsi.h> 481558Srgrimes#include "iscontrol.h" 491558Srgrimes 5036998Scharnierstatic inline char 5123673Speterc2b(unsigned char c) 5236998Scharnier{ 5336998Scharnier switch(c) { 5450476Speter case '0' ... '9': 551558Srgrimes return c - '0'; 561558Srgrimes case 'a' ... 'f': 571558Srgrimes return c - 'a' + 10; 581558Srgrimes case 'A' ... 'F': 5996478Sphk return c - 'A' + 10; 601558Srgrimes } 6198542Smckusick return 0; 621558Srgrimes} 631558Srgrimes 6423673Speterstatic char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 65105741Sjmallett "abcdefghijklmnopqrstuvwxyz" 661558Srgrimes "0123456789+/"; 671558Srgrimes 6899826Sjmallettstatic __inline unsigned char 69109525Sjmallettc64tobin(unsigned char c64) 701558Srgrimes{ 711558Srgrimes int i; 7223673Speter for(i = 0; i < 64; i++) 731558Srgrimes if(base64[i] == c64) 7499826Sjmallett break; 75109510Sjmallett return i; 761558Srgrimes} 7799826Sjmallett/* 781558Srgrimes | according to rfc3720, the binary string 7992839Simp | cannot be larger than 1024 - but i can't find it :-) XXX 80109519Sjmallett | not enforced yet. 81109525Sjmallett */ 8292839Simpint 83109525Sjmallettstr2bin(char *str, char **rsp) 8492839Simp{ 851558Srgrimes char *src, *dst, *tmp; 861558Srgrimes int i, len = 0; 8792839Simp 881558Srgrimes src = str; 89109525Sjmallett tmp = NULL; 90109525Sjmallett if(strncasecmp("0x", src, 2) == 0) { 911558Srgrimes src += 2; 92109525Sjmallett len = strlen(src); 93109507Sjmallett 94109525Sjmallett if((tmp = malloc((len+1)/2)) == NULL) { 95109525Sjmallett // XXX: print some error? 96109525Sjmallett return 0; 97109525Sjmallett } 98109525Sjmallett dst = tmp; 99109525Sjmallett if(len & 1) 100109525Sjmallett *dst++ = c2b(*src++); 101109525Sjmallett while(*src) { 102109525Sjmallett *dst = c2b(*src++) << 4; 103109525Sjmallett *dst++ |= c2b(*src++); 1041558Srgrimes } 1051558Srgrimes len = dst - tmp; 1061558Srgrimes } else 1071558Srgrimes if(strncasecmp("0b", src , 2) == 0) { 1081558Srgrimes // base64 1091558Srgrimes unsigned char b6; 110109525Sjmallett 111109525Sjmallett src += 2; 112109525Sjmallett len = strlen(src) / 4 * 3; 113109525Sjmallett if((tmp = malloc(len)) == NULL) { 114109525Sjmallett // XXX: print some error? 115109525Sjmallett return 0; 116109525Sjmallett } 117109525Sjmallett dst = tmp; 118109525Sjmallett i = 0; 119109525Sjmallett while(*src && ((b6 = c64tobin(*src++)) != 64)) { 120109525Sjmallett switch(i % 4) { 121109525Sjmallett case 0: 1221558Srgrimes *dst = b6 << 2; 1231558Srgrimes break; 1241558Srgrimes case 1: 1251558Srgrimes *dst++ |= b6 >> 4; 12692839Simp *dst = b6 << 4; 1271558Srgrimes break; 128109532Sjmallett case 2: 12998542Smckusick *dst++ |= b6 >> 2; 130109767Snjl *dst = b6 << 6; 13199827Sjmallett break; 1321558Srgrimes case 3: 133101688Sjmallett *dst++ |= b6; 134101688Sjmallett break; 13598542Smckusick } 136109532Sjmallett i++; 13798542Smckusick } 138109532Sjmallett len = dst - tmp; 139122670Sjohan } 140122670Sjohan else { 141122670Sjohan /* 142122670Sjohan | assume it to be an ascii string, so just copy it 143101688Sjmallett */ 144101688Sjmallett len = strlen(str); 14598542Smckusick if((tmp = malloc(len)) == NULL) 146109532Sjmallett return 0; 14798542Smckusick dst = tmp; 148109532Sjmallett src = str; 14998542Smckusick while(*src) 150122670Sjohan *dst++ = *src++; 151122670Sjohan } 152101688Sjmallett 153101688Sjmallett *rsp = tmp; 154109532Sjmallett return len; 15598542Smckusick} 1561558Srgrimes 1571558Srgrimeschar * 1581558Srgrimesbin2str(char *encoding, unsigned char *md, int blen) 1591558Srgrimes{ 1601558Srgrimes int len; 1611558Srgrimes char *dst, *ds; 16298542Smckusick unsigned char *cp; 1631558Srgrimes 16498542Smckusick if(strncasecmp(encoding, "0x", 2) == 0) { 165101688Sjmallett char ofmt[5]; 166101688Sjmallett 16798542Smckusick len = blen * 2; 16898542Smckusick dst = malloc(len + 3); 16998542Smckusick strcpy(dst, encoding); 170122670Sjohan ds = dst + 2; 171122670Sjohan cp = md; 172122670Sjohan sprintf(ofmt, "%%02%c", encoding[1]); 173122670Sjohan while(blen-- > 0) { 174122670Sjohan sprintf(ds, ofmt, *cp++); 17598542Smckusick ds += 2; 17698542Smckusick } 177122670Sjohan *ds = 0; 178122670Sjohan return dst; 179122670Sjohan } 180109532Sjmallett if(strncasecmp(encoding, "0b", 2) == 0) { 181109532Sjmallett int i, b6; 182109532Sjmallett 183101688Sjmallett len = (blen + 2) * 4 / 3; 184101688Sjmallett dst = malloc(len + 3); 18598542Smckusick strcpy(dst, encoding); 18698542Smckusick ds = dst + 2; 18798542Smckusick cp = md; 18898542Smckusick b6 = 0; // to keep compiler happy. 18998542Smckusick for(i = 0; i < blen; i++) { 19098542Smckusick switch(i % 3) { 19198542Smckusick case 0: 19298542Smckusick *ds++ = base64[*cp >> 2]; 193122670Sjohan b6 = (*cp & 0x3) << 4; 19498542Smckusick break; 195122670Sjohan case 1: 19698542Smckusick b6 += (*cp >> 4); 19798542Smckusick *ds++ = base64[b6]; 19898542Smckusick b6 = (*cp & 0xf) << 2; 19998542Smckusick break; 20098542Smckusick case 2: 20198542Smckusick b6 += (*cp >> 6); 20298542Smckusick *ds++ = base64[b6]; 20398542Smckusick *ds++ = base64[*cp & 0x3f]; 20498542Smckusick } 20598542Smckusick cp++; 206101688Sjmallett } 207101688Sjmallett switch(blen % 3) { 208109532Sjmallett case 0: 20998542Smckusick break; 2101558Srgrimes case 1: 2111558Srgrimes *ds++ = base64[b6]; 2122154Sdg *ds++ = '='; 2132154Sdg *ds++ = '='; 21448875Smpp break; 215109767Snjl case 2: 216109767Snjl *ds++ = base64[b6]; 217109767Snjl *ds++ = '='; 218109767Snjl break; 219109767Snjl } 22048875Smpp 221109767Snjl *ds = 0; 222109767Snjl return dst; 223109767Snjl } 224109767Snjl 225109767Snjl return NULL; 226109767Snjl} 227109767Snjl