xref: /freebsd-12.1/sbin/iscontrol/misc.c (revision 1de7b4b8)
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