1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2005-2010 Daniel Braniss <[email protected]>
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$");
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
52 static inline char
c2b(unsigned char c)53 c2b(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
66 static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
67 "abcdefghijklmnopqrstuvwxyz"
68 "0123456789+/";
69
70 static __inline unsigned char
c64tobin(unsigned char c64)71 c64tobin(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 */
84 int
str2bin(char * str,char ** rsp)85 str2bin(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
159 char *
bin2str(char * encoding,unsigned char * md,int blen)160 bin2str(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