7 char hexDigit( char c ) {
23 std::string toHex( const char* buf, int len ) {
24 char* c = ( char* ) malloc( len * 2 );
27 return "<malloc fail>";
30 std::shared_ptr<char> mem = std::shared_ptr<char>( c, free );
32 for( int i = 0; i < len; i++ ) {
33 c[i * 2] = hexDigit( ( buf[i] >> 4 ) & 0xF );
34 c[i * 2 + 1] = hexDigit( buf[i] & 0xF );
37 return std::string( mem.get(), len * 2 );
41 this->buffer = std::vector<char>( 4096 );
42 this->decodeTarget = 0;
47 void SlipBIO::setTarget( std::shared_ptr<OpensslBIO> target ) {
48 this->target = target;
51 SlipBIO::SlipBIO( std::shared_ptr<OpensslBIO> target ) {
52 this->target = target;
53 this->buffer = std::vector<char>( 4096 );
54 this->decodeTarget = 0;
61 SlipBIO::~SlipBIO() {}
63 int SlipBIO::write( const char* buf, int num ) {
66 for( int i = 0; i < num; i++ ) {
67 if( ( buf[i] == ( char )0xc0 ) || ( buf[i] == ( char )0xDB ) ) {
72 int totalLen = num + badOnes + 1; // 2
73 char* targetPtr = ( char* ) malloc( totalLen );
79 std::shared_ptr<char> t = std::shared_ptr<char>( targetPtr, free );
82 //targetPtr[j++] = (char)0xC0;
84 for( int i = 0; i < num; i++ ) {
85 if( buf[i] == ( char )0xc0 ) {
86 targetPtr[j++] = ( char )0xDB;
87 targetPtr[j++] = ( char )0xDC;
88 } else if( buf[i] == ( char )0xDB ) {
89 targetPtr[j++] = ( char )0xDB;
90 targetPtr[j++] = ( char )0xDD;
92 targetPtr[j++] = buf[i];
96 targetPtr[j++] = ( char )0xC0;
102 int dlen = target->write( targetPtr + sent, std::min( 1024, j - sent ) );
105 throw "Error, target write failed";
106 } else if( dlen == 0 ) {
121 int SlipBIO::read( char* buf, int size ) {
122 // while we have no data to decode or unmasking does not yield a full package
123 while( !packageLeft && ( decodePos >= rawPos || !unmask() ) ) {
125 // we have no data, read more
126 if( buffer.size() - rawPos < 64 ) {
127 // not enough space... package is too big
132 int len = target->read( buffer.data() + rawPos, buffer.capacity() - rawPos );
145 int len = std::min( decodeTarget, ( unsigned int ) size );
146 // a package finished, return it
147 std::copy( buffer.data(), buffer.data() + len, buf );
148 // move the buffer contents back
149 std::copy( buffer.data() + len, buffer.data() + decodeTarget, buffer.data() );
152 if( decodeTarget == 0 ) {
159 long SlipBIO::ctrl( int cmod, long arg1, void* arg2 ) {
163 std::cout << "SLIP crtl: " << cmod << std::endl;
164 return target->ctrl( cmod, arg1, arg2 );
167 const char* SlipBIO::getName() {
171 bool SlipBIO::unmask() {
172 unsigned int j = decodeTarget;
174 for( unsigned int i = decodePos; i < rawPos; i++ ) {
175 if( buffer[i] == ( char ) 0xDB ) {
180 buffer[decodeTarget] = buffer[i - 1];
181 decodePos = decodeTarget;
182 rawPos = decodePos + 1;
183 return 0;// no packet
184 } else if( buffer[i] == ( char )0xdc ) {
185 buffer[j++] = ( char ) 0xc0;
186 } else if( buffer[i] == ( char )0xdd ) {
187 buffer[j++] = ( char ) 0xdb;
194 } else if( buffer[i] == ( char ) 0xc0 ) {
198 // copy rest to bufferfer i to len
206 buffer[j++] = buffer[i];