1 /*- 2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28 /* 29 | $Id: misc.c,v 2.1 2006/11/12 08:06:51 danny Exp $ 30 */ 31 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/socket.h> 35 #include <sys/sysctl.h> 36 37 #include <netinet/in.h> 38 #include <netinet/tcp.h> 39 #include <arpa/inet.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <string.h> 43 44 #include "misc.h" 45 46 static inline char 47 c2b(unsigned char c) 48 { 49 switch(c) { 50 case '0' ... '9': 51 return c - '0'; 52 case 'a' ... 'f': 53 return c - 'a' + 10; 54 case 'A' ... 'F': 55 return c - 'A' + 10; 56 } 57 return 0; 58 } 59 60 static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 61 "abcdefghijklmnopqrstuvwxyz" 62 "0123456789+/"; 63 64 static __inline unsigned char 65 c64tobin(unsigned char c64) 66 { 67 int i; 68 for(i = 0; i < 64; i++) 69 if(base64[i] == c64) 70 break; 71 return i; 72 } 73 /* 74 | according to rfc3720, the binary string 75 | cannot be larger than 1024 - but i can't find it :-) XXX 76 | not enforced yet. 77 */ 78 int 79 str2bin(char *str, char **rsp) 80 { 81 char *src, *dst, *tmp; 82 int i, len = 0; 83 84 src = str; 85 tmp = NULL; 86 if(strncasecmp("0x", src, 2) == 0) { 87 src += 2; 88 len = strlen(src); 89 90 if((tmp = malloc((len+1)/2)) == NULL) { 91 // XXX: print some error? 92 return 0; 93 } 94 dst = tmp; 95 if(len & 1) 96 *dst++ = c2b(*src++); 97 while(*src) { 98 *dst = c2b(*src++) << 4; 99 *dst++ |= c2b(*src++); 100 } 101 len = dst - tmp; 102 } else 103 if(strncasecmp("0b", src , 2) == 0) { 104 // base64 105 unsigned char b6; 106 107 src += 2; 108 len = strlen(src) / 4 * 3; 109 if((tmp = malloc(len)) == NULL) { 110 // XXX: print some error? 111 return 0; 112 } 113 dst = tmp; 114 i = 0; 115 while(*src && ((b6 = c64tobin(*src++)) != 64)) { 116 switch(i % 4) { 117 case 0: 118 *dst = b6 << 2; 119 break; 120 case 1: 121 *dst++ |= b6 >> 4; 122 *dst = b6 << 4; 123 break; 124 case 2: 125 *dst++ |= b6 >> 2; 126 *dst = b6 << 6; 127 break; 128 case 3: 129 *dst++ |= b6; 130 break; 131 } 132 i++; 133 } 134 len = dst - tmp; 135 } 136 else { 137 /* 138 | assume it to be an ascii string, so just copy it 139 */ 140 len = strlen(str); 141 if((tmp = malloc(len)) == NULL) 142 return 0; 143 dst = tmp; 144 src = str; 145 while(*src) 146 *dst++ = *src++; 147 } 148 149 *rsp = tmp; 150 return len; 151 } 152 153 char * 154 bin2str(char *encoding, unsigned char *md, int blen) 155 { 156 int len; 157 char *dst, *ds; 158 unsigned char *cp; 159 160 if(strncasecmp(encoding, "0x", 2) == 0) { 161 char ofmt[5]; 162 163 len = blen * 2; 164 dst = malloc(len + 3); 165 strcpy(dst, encoding); 166 ds = dst + 2; 167 cp = md; 168 sprintf(ofmt, "%%02%c", encoding[1]); 169 while(blen-- > 0) { 170 sprintf(ds, ofmt, *cp++); 171 ds += 2; 172 } 173 *ds = 0; 174 return dst; 175 } 176 if(strncasecmp(encoding, "0b", 2) == 0) { 177 int i, b6; 178 179 len = (blen + 2) * 4 / 3; 180 dst = malloc(len + 3); 181 strcpy(dst, encoding); 182 ds = dst + 2; 183 cp = md; 184 b6 = 0; // to keep compiler happy. 185 for(i = 0; i < blen; i++) { 186 switch(i % 3) { 187 case 0: 188 *ds++ = base64[*cp >> 2]; 189 b6 = (*cp & 0x3) << 4; 190 break; 191 case 1: 192 b6 += (*cp >> 4); 193 *ds++ = base64[b6]; 194 b6 = (*cp & 0xf) << 2; 195 break; 196 case 2: 197 b6 += (*cp >> 6); 198 *ds++ = base64[b6]; 199 *ds++ = base64[*cp & 0x3f]; 200 } 201 cp++; 202 } 203 switch(blen % 3) { 204 case 0: 205 break; 206 case 1: 207 *ds++ = base64[b6]; 208 *ds++ = '='; 209 *ds++ = '='; 210 break; 211 case 2: 212 *ds++ = base64[b6]; 213 *ds++ = '='; 214 break; 215 } 216 217 *ds = 0; 218 return dst; 219 } 220 221 return NULL; 222 } 223