mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
262 lines
7.0 KiB
262 lines
7.0 KiB
/*
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com
|
|
* Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com
|
|
*
|
|
* The initial version of this code was written by Dragos Vingarzan
|
|
* (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the
|
|
* Fruanhofer Institute. It was and still is maintained in a separate
|
|
* branch of the original SER. We are therefore migrating it to
|
|
* Kamailio/SR and look forward to maintaining it from here on out.
|
|
* 2011/2012 Smile Communications, Pty. Ltd.
|
|
* ported/maintained/improved by
|
|
* Jason Penton (jason(dot)penton(at)smilecoms.com and
|
|
* Richard Good (richard(dot)good(at)smilecoms.com) as part of an
|
|
* effort to add full IMS support to Kamailio/SR using a new and
|
|
* improved architecture
|
|
*
|
|
* NB: Alot of this code was originally part of OpenIMSCore,
|
|
* FhG Fokus.
|
|
* Copyright (C) 2004-2006 FhG Fokus
|
|
* Thanks for great work! This is an effort to
|
|
* break apart the various CSCF functions into logically separate
|
|
* components. We hope this will drive wider use. We also feel
|
|
* that in this way the architecture is more complete and thereby easier
|
|
* to manage in the Kamailio/SR environment
|
|
*
|
|
* This file is part of Kamailio, a free SIP server.
|
|
*
|
|
* Kamailio is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version
|
|
*
|
|
* Kamailio is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
*
|
|
* Serving-CSCF - Conversion between base16, base64 and base256
|
|
*
|
|
* \author Dragos Vingarzan vingarzan -at- fokus dot fraunhofer dot de
|
|
*
|
|
*/
|
|
|
|
/** base16 char constants */
|
|
char *hexchars="0123456789abcdef";
|
|
/**
|
|
* Converts a binary encoded value to its base16 representation.
|
|
* @param from - buffer containing the input data
|
|
* @param len - the size of from
|
|
* @param to - the output buffer !!! must have at least len*2 allocated memory
|
|
* @returns the written length
|
|
*/
|
|
int bin_to_base16(char *from,int len, char *to)
|
|
{
|
|
int i,j;
|
|
for(i=0,j=0;i<len;i++,j+=2){
|
|
to[j] = hexchars[(((unsigned char)from[i]) >>4 )&0x0F];
|
|
to[j+1] = hexchars[(((unsigned char)from[i]))&0x0F];
|
|
}
|
|
return 2*len;
|
|
}
|
|
|
|
/** from base16 char to int */
|
|
#define HEX_DIGIT(x) \
|
|
((x>='0'&&x<='9')?x-'0':((x>='a'&&x<='f')?x-'a'+10:((x>='A'&&x<='F')?x-'A'+10:0)))
|
|
/**
|
|
* Converts a hex encoded value to its binary value
|
|
* @param from - buffer containing the input data
|
|
* @param len - the size of from
|
|
* @param to - the output buffer !!! must have at least len/2 allocated memory
|
|
* @returns the written length
|
|
*/
|
|
int base16_to_bin(char *from,int len, char *to)
|
|
{
|
|
int i,j;
|
|
for(i=0,j=0;j<len;i++,j+=2){
|
|
to[i] = (unsigned char) ( HEX_DIGIT(from[j])<<4 | HEX_DIGIT(from[j+1]));
|
|
}
|
|
return i;
|
|
}
|
|
|
|
/**
|
|
* Convert on character from base64 encoding to integer.
|
|
*"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
* @param x - characted to convert
|
|
* @returns the int value or -1 if terminal character ('=')
|
|
*/
|
|
static inline int base64_val(char x)\
|
|
{
|
|
switch(x){
|
|
case '=': return -1;
|
|
case 'A': return 0;
|
|
case 'B': return 1;
|
|
case 'C': return 2;
|
|
case 'D': return 3;
|
|
case 'E': return 4;
|
|
case 'F': return 5;
|
|
case 'G': return 6;
|
|
case 'H': return 7;
|
|
case 'I': return 8;
|
|
case 'J': return 9;
|
|
case 'K': return 10;
|
|
case 'L': return 11;
|
|
case 'M': return 12;
|
|
case 'N': return 13;
|
|
case 'O': return 14;
|
|
case 'P': return 15;
|
|
case 'Q': return 16;
|
|
case 'R': return 17;
|
|
case 'S': return 18;
|
|
case 'T': return 19;
|
|
case 'U': return 20;
|
|
case 'V': return 21;
|
|
case 'W': return 22;
|
|
case 'X': return 23;
|
|
case 'Y': return 24;
|
|
case 'Z': return 25;
|
|
case 'a': return 26;
|
|
case 'b': return 27;
|
|
case 'c': return 28;
|
|
case 'd': return 29;
|
|
case 'e': return 30;
|
|
case 'f': return 31;
|
|
case 'g': return 32;
|
|
case 'h': return 33;
|
|
case 'i': return 34;
|
|
case 'j': return 35;
|
|
case 'k': return 36;
|
|
case 'l': return 37;
|
|
case 'm': return 38;
|
|
case 'n': return 39;
|
|
case 'o': return 40;
|
|
case 'p': return 41;
|
|
case 'q': return 42;
|
|
case 'r': return 43;
|
|
case 's': return 44;
|
|
case 't': return 45;
|
|
case 'u': return 46;
|
|
case 'v': return 47;
|
|
case 'w': return 48;
|
|
case 'x': return 49;
|
|
case 'y': return 50;
|
|
case 'z': return 51;
|
|
case '0': return 52;
|
|
case '1': return 53;
|
|
case '2': return 54;
|
|
case '3': return 55;
|
|
case '4': return 56;
|
|
case '5': return 57;
|
|
case '6': return 58;
|
|
case '7': return 59;
|
|
case '8': return 60;
|
|
case '9': return 61;
|
|
case '+': return 62;
|
|
case '/': return 63;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Convert a string encoded in base64 to binary value.
|
|
* @param from - buffer containing the input data
|
|
* @param from_len - the size of from
|
|
* @param to - the output buffer !!! must have at least len*2 allocated memory
|
|
* @returns the written length
|
|
*/
|
|
int base64_to_bin(char *from,int from_len, char *to)
|
|
{
|
|
int i,j,x1,x2,x3,x4;
|
|
|
|
for(i=0,j=0;i<from_len;i+=4){
|
|
x1=base64_val(from[i]);
|
|
x2=base64_val(from[i+1]);
|
|
x3=base64_val(from[i+2]);
|
|
x4=base64_val(from[i+3]);
|
|
to[j++]=(x1<<2) | ((x2 & 0x30)>>4);
|
|
if (x3==-1) break;
|
|
to[j++]=((x2 & 0x0F)<<4) | ((x3 & 0x3C)>>2);
|
|
if (x4==-1) break;
|
|
to[j++]=((x3 & 0x03)<<6) | (x4 & 0x3F);
|
|
}
|
|
return j;
|
|
}
|
|
|
|
/** base64 characters constant */
|
|
char base64[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
/**
|
|
* Convert a binary string to base64 encoding.
|
|
* @param src - the source buffer
|
|
* @param src_len - length of the source buffer
|
|
* @param ptr - the destination buffer - must be allocated to at least src_len/3*4+4
|
|
* @returns the length of the resulted buffer
|
|
*/
|
|
int bin_to_base64(char *src,int src_len,char* ptr)
|
|
{
|
|
int i,k;
|
|
int triplets,rest;
|
|
char *s;
|
|
s=ptr;
|
|
|
|
triplets = src_len/3;
|
|
rest = src_len%3;
|
|
for(i=0;i<triplets*3;i+=3){
|
|
k = (((unsigned char) src[i])&0xFC)>>2;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
k = (((unsigned char) src[i])&0x03)<<4;
|
|
k |=(((unsigned char) src[i+1])&0xF0)>>4;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
k = (((unsigned char) src[i+1])&0x0F)<<2;
|
|
k |=(((unsigned char) src[i+2])&0xC0)>>6;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
k = (((unsigned char) src[i+2])&0x3F);
|
|
*ptr=base64[k];ptr++;
|
|
}
|
|
i=triplets*3;
|
|
switch(rest){
|
|
case 0:
|
|
break;
|
|
case 1:
|
|
k = (((unsigned char) src[i])&0xFC)>>2;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
k = (((unsigned char) src[i])&0x03)<<4;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
*ptr='=';ptr++;
|
|
|
|
*ptr='=';ptr++;
|
|
break;
|
|
case 2:
|
|
k = (((unsigned char) src[i])&0xFC)>>2;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
k = (((unsigned char) src[i])&0x03)<<4;
|
|
k |=(((unsigned char) src[i+1])&0xF0)>>4;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
k = (((unsigned char) src[i+1])&0x0F)<<2;
|
|
*ptr=base64[k];ptr++;
|
|
|
|
*ptr='=';ptr++;
|
|
break;
|
|
}
|
|
|
|
return ptr-s;
|
|
}
|
|
|