3 #include "dangerous/snmp/types.hpp"
4 #include "dangerous/snmp/logger.hpp"
10 namespace dangerous {
namespace snmp {
namespace asn1 {
16 static unsigned int byteSize(
unsigned int length ) {
17 unsigned int size = 1;
27 if( length > 0xFFFFFFFF ) {
29 }
else if( length > 0xFFFFFF ) {
31 }
else if( length > 0xFFFF ) {
33 }
else if( length > 0xFF ) {
40 static unsigned int bytes(
unsigned int length,
char* buffer,
unsigned int bufferLength ) {
41 unsigned int size = byteSize( length );
43 logger.
out() <<
"length::bytes: length=" << length <<
": size=" << size << std::endl;
45 if( bufferLength < size ) {
50 *buffer = length & 0xFF;
52 logger.
out() <<
"length::bytes: length=" << length <<
": A -> " << (int)( *buffer ) << std::endl;
56 *buffer = 0x80 | ( size - 1 );
58 logger.
out() <<
"length::bytes: length=" << length <<
": B -> " << (int)( *buffer ) << std::endl;
62 for(
unsigned int i = 0; i < size - 1; i++ ) {
63 *buffer = ( length >> ( ( (size-1) - 1 - i ) * 8 ) ) & 0xFF;
65 logger.
out() <<
"length::bytes: length=" << length <<
": C -> " << (int)( *buffer ) << std::endl;
77 static const int TYPE = 0x30;
79 static unsigned int byteSize(
unsigned int contentLength ) {
80 unsigned int size = 1;
81 size += helper::length::byteSize( contentLength );
85 static unsigned int bytes(
unsigned int contentLength,
char* buffer,
unsigned int bufferSize ) {
86 unsigned int size = byteSize( contentLength );
87 if( bufferSize < size ) {
95 unsigned int increment = helper::length::bytes( contentLength, buffer, bufferSize );
97 bufferSize -= increment;
107 static const int UNIVERSAL = 0b00;
108 static const int APPLICATION = 0b01;
109 static const int CONTEXT_SPECIFIC = 0b10;
110 static const int PRIVATE = 0b11;
115 static const int PRIMITIVE = 0b0;
116 static const int CONSTRUCTED = 0b1;
127 unsigned int encodedSize(
const typename T::value_type& value ) {
128 unsigned int length = T::length( value );
130 unsigned int size = 0;
132 size += helper::length::byteSize( length );
147 template<
int classBits,
int contentBit,
int tag,
typename myType >
150 static const int TYPE = ( classBits << 6 ) | ( contentBit << 5 ) | ( tag & 0b11111 );
151 typedef myType value_type;
153 static unsigned int length(
const value_type& value ) {
169 bool isNegative = std::is_signed<myType>::value && ( ( value >> ( (
sizeof(myType) - 1 ) * 8 ) ) & 0x80 ) == 0x80;
171 logger.
out() <<
"Integer " << value <<
" is " << ( isNegative ?
"negative" :
"positive" ) << std::endl;
176 unsigned int size =
sizeof(myType);
177 for(
unsigned int i = 0; i <
sizeof(myType); i++ ) {
179 uint8_t byte = ( value >> ( (
sizeof(myType) - 1 - i ) * 8 ) ) & 0xFF;
181 logger.
out() <<
"Integer " << value <<
", byte [ " << i <<
" ] has a value of " << std::hex << (int)byte << std::dec <<
"." << std::endl;
184 if( ( ! isNegative && byte == 0x00 ) || ( isNegative && byte == 0xFF ) ) {
196 if( ! isNegative && ( byte & 0x80 ) == 0x80 ) {
205 logger.
out() <<
"Integer " << value <<
" has an encoded length of " << size <<
"." << std::endl;
211 static bool write(
const value_type& value,
char* buffer,
unsigned int bufferSize ) {
213 logger.
out() <<
"INTEGER<...>::write: Value is " << value <<
"." << std::endl;
219 bool isNegative = std::is_signed<myType>::value && ( ( value >> ( (
sizeof(myType) - 1 ) * 8 ) ) & 0x80 ) == 0x80;
221 logger.
out() <<
"INTEGER<...>::write: Sign is '" << ( isNegative ?
"-" :
"+" ) <<
"'." << std::endl;
224 for(
unsigned int i = 0; i <
sizeof(myType); i++ ) {
226 uint8_t byte = ( value >> ( (
sizeof(myType) - 1 - i ) * 8 ) ) & 0xFF;
228 if( ( ! isNegative && byte == 0x00 ) || ( isNegative && byte == 0xFF ) ) {
231 if( i + 1 ==
sizeof(myType) ) {
233 logger.
out() <<
"INTEGER<...>::write: Adding last [trivial] byte " << ((int)byte) <<
"." << std::endl;
235 *buffer = (char)byte;
251 if( ! isNegative && ( byte & 0x80 ) == 0x80 ) {
253 logger.
out() <<
"INTEGER<...>::write: Adding first byte 0x00." << std::endl;
260 for( ; i <
sizeof(myType); i++ ) {
262 uint8_t byte = ( value >> ( (
sizeof(myType) - 1 - i ) * 8 ) ) & 0xFF;
264 logger.
out() <<
"INTEGER<...>::write: Adding byte " << ((int)byte) <<
"." << std::endl;
267 *buffer = (char)byte;
278 static value_type read( value_type& value,
const char* buffer,
unsigned int bufferSize ) {
281 bool isNegative =
false;
282 for(
unsigned int i = 0; i < bufferSize; i++ ) {
283 uint8_t byte = buffer[ i ];
285 logger.
out() <<
"INTEGER: read: byte[ " << i <<
" ]: " << (int)byte << std::endl;
289 isNegative = std::is_signed<myType>::value && ( byte & 0x80 ) == 0x80;
298 value |= ( byte & 0xFF );
301 if( value != 0 && isNegative ) {
302 value -= 0x80 << ( ( bufferSize - 1 ) * 8 );
309 template<
int classBits,
int contentBit,
int tag >
312 static const int TYPE = ( classBits << 6 ) | ( contentBit << 5 ) | ( tag & 0b11111 );
313 typedef std::string value_type;
315 static unsigned int length(
const value_type& text ) {
316 return text.length();
319 static bool write(
const value_type& text,
char* buffer,
unsigned int bufferSize ) {
320 for(
unsigned int i = 0, iSize = text.length(); i < iSize; i++ ) {
329 static bool read( value_type& value,
const char* buffer,
unsigned int bufferSize ) {
331 logger.
out() <<
"Clearing value." << std::endl;
335 logger.
out() <<
"Resizing string to length=" << bufferSize <<
"." << std::endl;
337 value.resize( bufferSize );
339 for(
unsigned int i = 0; i < bufferSize; i++ ) {
340 uint8_t byte = buffer[ i ];
342 logger.
out() <<
"OCTET_STRING: read: byte[ " << i <<
" ]: " << (int)byte << std::endl;
355 template<
int classBits,
int contentBit,
int tag >
358 static const int TYPE = ( classBits << 6 ) | ( contentBit << 5 ) | ( tag & 0b11111 );
360 typedef uint8_t value_type;
362 static uint8_t throwaway;
364 static unsigned int length(
const value_type& value ) {
368 static bool write(
const value_type& value,
char* buffer,
unsigned int bufferSize ) {
377 static bool read( value_type& value,
const char* buffer,
unsigned int bufferSize ) {
382 template<
int classBits,
int contentBit,
int tag >
383 uint8_t NULL_TYPE<classBits,contentBit,tag>::throwaway = 0;
385 template<
int classBits,
int contentBit,
int tag >
388 static const int TYPE = ( classBits << 6 ) | ( contentBit << 5 ) | ( tag & 0b11111 );
393 static unsigned int length(
const value_type& oid ) {
394 unsigned int size = 0;
396 if( oid.
numbers.size() >= 1 ) {
399 for(
unsigned int i = 2, iSize = oid.
numbers.size(); i < iSize; i++ ) {
400 unsigned int number = oid.
numbers[ i ];
403 while( number > 0 ) {
415 if( oid.
numbers.size() == 0 ) {
432 unsigned int number1 = oid.
numbers[ 0 ];
434 unsigned int number2 = oid.
numbers[ 1 ];
436 if( number1 >= 40 ) {
438 logger.
out() <<
"OID component #1 (" << number1 <<
") is too large (must be between 0 and 39)." << std::endl;
442 if( number2 >= 40 ) {
444 logger.
out() <<
"OID component #2 (" << number2 <<
") is too large (must be between 0 and 39)." << std::endl;
450 *buffer = 40 * number1 + number2;
455 for(
unsigned int i = 2, iSize = oid.
numbers.size(); i < iSize; i++ ) {
456 unsigned int number = oid.
numbers[ i ];
460 while( number > 0 ) {
475 for(
int l = 0; l < length; l++ ) {
480 buffer[ length - 1 - l ] = ( ( l > 0 ) ? 0x80 : 0x00 ) | ( number & 0x7F );
486 bufferSize -= length;
492 static bool read(
value_type& oid,
const char* buffer,
unsigned int bufferSize ) {
493 if( bufferSize < 1 ) {
499 unsigned int number2 = (int)(
char)(*buffer) % 40;
500 unsigned int number1 = ( (int)(
char)(*buffer) - number2 ) / 40;
502 logger.
out() <<
"." << number1 <<
"." << number2 << std::endl;
504 oid.numbers.push_back( number1 );
505 oid.numbers.push_back( number2 );
510 while( bufferSize > 0 ) {
511 unsigned int number = 0;
512 while( *buffer & 0x80 ) {
514 number |= ( *buffer & 0x7F );
518 if( bufferSize == 0 ) {
523 number |= ( *buffer & 0x7F );
524 oid.numbers.push_back( number );
526 logger.
out() <<
" ." << number << std::endl;
bool system(System system)
This returns the logging status for the given system.
Definition: logger.hpp:47
This class allows for the encoding and decoding of null values.
Definition: asn1.hpp:356
std::ostream & out()
This returns the output stream for the Logger.
Definition: logger.hpp:77
std::vector< unsigned int > numbers
This is the vector that represents the integers that make up the OID.
Definition: numericoid.hpp:57
A NumericOid represents an "true" OID; that is, one identified by a series of integers (as opposed to...
Definition: numericoid.hpp:22
static bool write(const value_type &value, char *buffer, unsigned int bufferSize)
Definition: asn1.hpp:211
static unsigned int length(const value_type &value)
Definition: asn1.hpp:153
Logger logger
We will expose a global Logger instance.
Logging related to decoding messages.
Definition: logger.hpp:21
static bool read(value_type &value, const char *buffer, unsigned int bufferSize)
In terms of reading an ASN.1 NULL value goes, by the time that we've gotten to this function...
Definition: asn1.hpp:377
NumericOid value_type
This class operates on a NumericType.
Definition: asn1.hpp:391
static bool write(const value_type &oid, char *buffer, unsigned int bufferSize)
Definition: asn1.hpp:412