5 char hexDigit( char c ) {
21 std::string toHex( const char* buf, int len ) {
22 char* c = ( char* ) malloc( len * 2 );
25 return "<malloc fail>";
28 std::shared_ptr<char> mem = std::shared_ptr<char>( c, free );
30 for( int i = 0; i < len; i++ ) {
31 c[i * 2] = hexDigit( ( buf[i] >> 4 ) & 0xF );
32 c[i * 2 + 1] = hexDigit( buf[i] & 0xF );
35 return std::string( mem.get(), len * 2 );
38 SlipBIO::SlipBIO( std::shared_ptr<OpensslBIO> target ) {
39 this->target = target;
41 this->buffer = std::vector<char>( 4096 );
42 this->decodeTarget = 0;
49 SlipBIO::~SlipBIO() {}
51 int SlipBIO::write( const char* buf, int num ) {
54 for( int i = 0; i < num; i++ ) {
55 if( ( buf[i] == ( char )0xc0 ) || ( buf[i] == ( char )0xDB ) ) {
60 int totalLen = num + badOnes + 2;
61 char* targetPtr = ( char* ) malloc( totalLen );
67 std::shared_ptr<char> t = std::shared_ptr<char>( targetPtr, free );
69 targetPtr[j++] = ( char )0xC0;
71 for( int i = 0; i < num; i++ ) {
72 if( buf[i] == ( char )0xc0 ) {
73 targetPtr[j++] = ( char )0xDB;
74 targetPtr[j++] = ( char )0xDC;
75 } else if( buf[i] == ( char )0xDB ) {
76 targetPtr[j++] = ( char )0xDB;
77 targetPtr[j++] = ( char )0xDD;
79 targetPtr[j++] = buf[i];
83 targetPtr[j++] = ( char )0xC0;
85 if( target->write( targetPtr, j ) != j ) {
86 throw "Error, target write failed";
89 std::cout << toHex( targetPtr, j ) << std::endl;
93 int SlipBIO::read( char* buf, int size ) {
94 if( ( unsigned int ) size < buffer.capacity() ) {
98 // while we have no data to decode or unmasking does not yield a full package
99 while( decodePos >= rawPos || !unmask() ) {
101 // we have no data, read more
102 if( buffer.size() - rawPos < 64 ) {
103 // not enough space... package is too big
108 int len = target->read( buffer.data() + rawPos, buffer.capacity() - rawPos );
119 // a package finished, return it
120 std::copy( buffer.data(), buffer.data() + decodeTarget, buf );
121 // move the buffer contents back
123 int len = decodeTarget;
129 long SlipBIO::ctrl( int cmod, long arg1, void* arg2 ) {
137 const char* SlipBIO::getName() {
141 bool SlipBIO::unmask() {
142 unsigned int j = decodeTarget;
144 for( unsigned int i = decodePos; i < rawPos; i++ ) {
145 if( buffer[i] == ( char ) 0xDB ) {
150 buffer[decodeTarget] = buffer[i - 1];
151 decodePos = decodeTarget;
152 rawPos = decodePos + 1;
153 return 0;// no packet
154 } else if( buffer[i] == ( char )0xdc ) {
155 buffer[j++] = ( char ) 0xc0;
156 } else if( buffer[i] == ( char )0xdd ) {
157 buffer[j++] = ( char ) 0xdb;
164 } else if( buffer[i] == ( char ) 0xc0 ) {
168 // copy rest to bufferfer i to len
176 buffer[j++] = buffer[i];