misc.c revision 171568
150476Speter/*- 234925Sdufault * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il> 334925Sdufault * All rights reserved. 434925Sdufault * 534925Sdufault * Redistribution and use in source and binary forms, with or without 634925Sdufault * modification, are permitted provided that the following conditions 734925Sdufault * are met: 834925Sdufault * 1. Redistributions of source code must retain the above copyright 934925Sdufault * notice, this list of conditions and the following disclaimer. 1034925Sdufault * 2. Redistributions in binary form must reproduce the above copyright 1134925Sdufault * notice, this list of conditions and the following disclaimer in the 1234925Sdufault * documentation and/or other materials provided with the distribution. 1334925Sdufault * 1434925Sdufault * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1534925Sdufault * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1634925Sdufault * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1734925Sdufault * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1834925Sdufault * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1934925Sdufault * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2034925Sdufault * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2134925Sdufault * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2234925Sdufault * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2334925Sdufault * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2434925Sdufault * SUCH DAMAGE. 2534925Sdufault * 2669857Sru */ 2734925Sdufault 2879531Sru/* 2934925Sdufault | $Id: misc.c,v 2.1 2006/11/12 08:06:51 danny Exp $ 3034925Sdufault */ 3134925Sdufault 3234925Sdufault#include <sys/cdefs.h> 3359460Sphantom__FBSDID("$FreeBSD: head/sbin/iscontrol/misc.c 171568 2007-07-24 15:35:02Z scottl $"); 3459460Sphantom 3534925Sdufault#include <sys/param.h> 3684306Sru#include <sys/types.h> 3734925Sdufault#include <sys/socket.h> 3834925Sdufault#include <sys/sysctl.h> 3934925Sdufault 4034925Sdufault#include <netinet/in.h> 4134925Sdufault#include <netinet/tcp.h> 4234925Sdufault#include <arpa/inet.h> 4334925Sdufault#if __FreeBSD_version < 500000 44108028Sru#include <sys/time.h> 4534925Sdufault#endif 4634925Sdufault#include <stdlib.h> 4734925Sdufault#include <stdio.h> 4834925Sdufault#include <string.h> 4934925Sdufault 50108087Srustatic inline char 5134925Sdufaultc2b(unsigned char c) 5234925Sdufault{ 5334925Sdufault switch(c) { 5434925Sdufault case '0' ... '9': 5534925Sdufault return c - '0'; 5634925Sdufault case 'a' ... 'f': 5734925Sdufault return c - 'a' + 10; 5834925Sdufault case 'A' ... 'F': 5934925Sdufault return c - 'A' + 10; 6034925Sdufault } 6134925Sdufault return 0; 6234925Sdufault} 6334925Sdufault 64108028Srustatic char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 6534925Sdufault "abcdefghijklmnopqrstuvwxyz" 6634925Sdufault "0123456789+/"; 6734925Sdufault 6834925Sdufaultstatic __inline unsigned char 6934925Sdufaultc64tobin(unsigned char c64) 7034925Sdufault{ 7134925Sdufault int i; 7234925Sdufault for(i = 0; i < 64; i++) 7334925Sdufault if(base64[i] == c64) 7434925Sdufault break; 7534925Sdufault return i; 7634925Sdufault} 7734925Sdufault/* 7834925Sdufault | according to rfc3720, the binary string 7934925Sdufault | cannot be larger than 1024 - but i can't find it :-) XXX 80116023Scharnier | not enforced yet. 8134925Sdufault */ 8234925Sdufaultint 8334925Sdufaultstr2bin(char *str, char **rsp) 8434925Sdufault{ 8534925Sdufault char *src, *dst, *tmp; 8634925Sdufault int i, len = 0; 8734925Sdufault 8834925Sdufault src = str; 8934925Sdufault tmp = NULL; 9034925Sdufault if(strncasecmp("0x", src, 2) == 0) { 9134925Sdufault src += 2; 9234925Sdufault len = strlen(src); 9334925Sdufault 9434925Sdufault if((tmp = malloc((len+1)/2)) == NULL) { 95108087Sru // XXX: print some error? 9634925Sdufault return 0; 9734925Sdufault } 9834925Sdufault dst = tmp; 9934925Sdufault if(len & 1) 10034925Sdufault *dst++ = c2b(*src++); 10134925Sdufault while(*src) { 10234925Sdufault *dst = c2b(*src++) << 4; 10334925Sdufault *dst++ |= c2b(*src++); 10434925Sdufault } 10534925Sdufault len = dst - tmp; 106108028Sru } else 10734925Sdufault if(strncasecmp("0b", src , 2) == 0) { 10834925Sdufault // base64 10934925Sdufault unsigned char b6; 11034925Sdufault 11134925Sdufault src += 2; 11234925Sdufault len = strlen(src) / 4 * 3; 11334925Sdufault if((tmp = malloc(len)) == NULL) { 11434925Sdufault // XXX: print some error? 11534925Sdufault return 0; 11634925Sdufault } 11734925Sdufault dst = tmp; 11834925Sdufault i = 0; 119116023Scharnier while(*src && ((b6 = c64tobin(*src++)) != 64)) { 12034925Sdufault switch(i % 4) { 12134925Sdufault case 0: 12234925Sdufault *dst = b6 << 2; 12334925Sdufault break; 12434925Sdufault case 1: 125131504Sru *dst++ |= b6 >> 4; 126131504Sru *dst = b6 << 4; 12734925Sdufault break; 128108028Sru case 2: 12934925Sdufault *dst++ |= b6 >> 2; 13034925Sdufault *dst = b6 << 6; 13168854Sru break; 13282642Sru case 3: 13334925Sdufault *dst++ |= b6; 13434925Sdufault break; 13534925Sdufault } 13634925Sdufault i++; 13759954Sphantom } 13834925Sdufault len = dst - tmp; 13934925Sdufault } 14034925Sdufault else { 14134925Sdufault /* 142116023Scharnier | assume it to be an ascii string, so just copy it 14334925Sdufault */ 14434925Sdufault len = strlen(str); 14534925Sdufault if((tmp = malloc(len)) == NULL) 14634925Sdufault return 0; 14734925Sdufault dst = tmp; 14834925Sdufault src = str; 149108087Sru while(*src) 15034925Sdufault *dst++ = *src++; 15134925Sdufault } 15234925Sdufault 15334925Sdufault *rsp = tmp; 15479366Sru return len; 15534925Sdufault} 15634925Sdufault 15734925Sdufaultchar * 15838702Swoschbin2str(char *encoding, unsigned char *md, int blen) 15934925Sdufault{ 16034925Sdufault int len; 16134925Sdufault char *dst, *ds, *cp; 16279754Sdd 16334925Sdufault if(strncasecmp(encoding, "0x", 2) == 0) { 16434925Sdufault char ofmt[5]; 165108028Sru 16634925Sdufault len = blen * 2; 167 dst = malloc(len + 3); 168 strcpy(dst, encoding); 169 ds = dst + 2; 170 cp = (char *)md; 171 sprintf(ofmt, "%%02%c", encoding[1]); 172 while(blen-- > 0) { 173 sprintf(ds, ofmt, *cp++); 174 ds += 2; 175 } 176 *ds = 0; 177 return dst; 178 } 179 if(strncasecmp(encoding, "0b", 2) == 0) { 180 int i, b6; 181 182 len = (blen + 2) * 4 / 3; 183 dst = malloc(len + 3); 184 strcpy(dst, encoding); 185 ds = dst + 2; 186 cp = (char *)md; 187 b6 = 0; // to keep copiler happy. 188 for(i = 0; i < blen; i++) { 189 switch(i % 3) { 190 case 0: 191 *ds++ = base64[*cp >> 2]; 192 b6 = (*cp & 0x3) << 4; 193 break; 194 case 1: 195 b6 += (*cp >> 4); 196 *ds++ = base64[b6]; 197 b6 = (*cp & 0xf) << 2; 198 break; 199 case 2: 200 b6 += (*cp >> 6); 201 *ds++ = base64[b6]; 202 *ds++ = base64[*cp & 0x3f]; 203 } 204 cp++; 205 } 206 switch(blen % 3) { 207 case 0: 208 break; 209 case 1: 210 *ds++ = base64[b6]; 211 *ds++ = '='; 212 *ds++ = '='; 213 break; 214 case 2: 215 *ds++ = base64[b6]; 216 *ds++ = '='; 217 break; 218 } 219 220 *ds = 0; 221 return dst; 222 } 223 224 return NULL; 225} 226