SNMP 2.1.0
Loading...
Searching...
No Matches
BER.h
Go to the documentation of this file.
1#ifndef BER_H_
2#define BER_H_
3
4#include <Arduino.h>
5#include <IPAddress.h>
6
7#ifdef __has_include
8#if __has_include("SNMPcfg.h")
9#include "SNMPcfg.h"
10#else
15#define SNMP_STREAM 1
16
21#define SNMP_VECTOR 0
22
27#define SNMP_CAPACITY 6
28#endif
29#endif
30
31#if SNMP_STREAM
32#include <Stream.h>
33#endif
34
35#if SNMP_VECTOR
36#include <vector>
37#endif
38
43namespace SNMP {
44
51struct Version {
55 enum : uint8_t {
58 };
59};
60
116
123struct Trap {
127 enum : uint8_t {
135 };
136
146 _enterprise = nullptr;
148 _specificTrap = 0;
149 _timeStamp = 0;
150 }
151
153 const char *_enterprise;
155 IPAddress _agentAddr;
161 uint32_t _timeStamp;
162};
163
170struct Class {
174 enum : uint8_t {
175 Universal = 0x00,
176 Application = 0x40,
177 Context = 0x80,
178 Private = 0xC0,
179 };
180};
181
188struct Form {
192 enum : uint8_t {
193 Primitive = 0x00,
194 Constructed = 0x20,
195 };
196};
197
202class Flag {
203public:
207 enum : uint8_t {
208 None = 0,
209 Typed = (1 << 0),
210 };
211};
212
219class Base {
220public:
221#if SNMP_STREAM
235 static void encode7bits(uint32_t value, Stream &stream, const uint8_t size) {
236 for (uint8_t index = 0; index < size; ++index) {
237 stream.write((value >> (7 * (size - index - 1)) & 0x7F) | ((size - index - 1) ? 0x80 : 0x00));
238 }
239 }
240#else
254 void encode7bits(uint32_t value, uint8_t *buffer, const uint8_t size) {
255 buffer += size;
256 for (uint8_t index = 0; index < size; ++index) {
257 *buffer-- = (value & 0x7F) | (index ? 0x80 : 0x00);
258 value >>= 7;
259 }
260 }
261#endif
262
263protected:
265 unsigned int _size = 0;
266
267 friend class BER;
268};
269
282class Type: public Base {
283public:
287 enum : uint16_t {
288 // Universal
296 // Application
304 // Context
308 // Version 1
314 // Version 2C
318 // Version 3
320 // Opaque type
321 OpaqueFloat = 0x9F78
322 };
323
329 Type(const unsigned int type = 0) :
330 Base() {
331 setType(type);
332 }
333
342 Type(const uint8_t flag, const unsigned int tag) :
343 Base() {
344 setFlagTag(flag, tag);
345 }
346
347#if SNMP_STREAM
358 void encode(Stream &stream) {
359 if (_size == 1) {
360 stream.write(_class | _form | _tag);
361 } else {
362 stream.write(_class | _form | 0x1F);
363 Base::encode7bits(_tag, stream, _size - 1);
364 }
365 }
366
372 void decode(Stream &stream) {
373 _size = 1;
374 _type = stream.read();
375 _class = _type & 0xC0;
376 _form = _type & 0x20;
377 _tag = _type & 0x1F;
378 if (_tag == 0x1F) {
379 _tag = 0;
380 do {
381 _size++;
382 _type <<= 8;
383 _type |= stream.read();
384 _tag <<= 7;
385 _tag |= _type & 0x7F;
386 } while (_type & 0x80);
387 }
388 }
389#else
401 uint8_t* encode(uint8_t *buffer) {
402 if (_size == 1) {
403 *buffer = _class | _form | _tag;
404 } else {
405 *buffer = _class | _form | 0x1F;
406 Base::encode7bits(_tag, buffer, _size - 1);
407 }
408 return buffer + _size;
409 }
410
417 uint8_t* decode(uint8_t *buffer) {
418 _type = *buffer++;
419 _class = _type & 0xC0;
420 _form = _type & 0x20;
421 _tag = _type & 0x1F;
422 if ((_tag & 0x1F) == 0x1F) {
423 _tag = 0;
424 do {
425 _type <<= 8;
426 _type |= *buffer++;
427 _tag <<= 7;
428 _tag |= _type & 0x7F;
429 } while (_type & 0x80);
430 }
431 return buffer;
432 }
433#endif
434
442 operator unsigned int() const {
443 return _type;
444 }
445
451 const uint8_t getClass() const {
452 return _class;
453 }
454
460 const uint8_t getForm() const {
461 return _form;
462 }
463
469 const unsigned int getTag() const {
470 return _tag;
471 }
472
473private:
475 uint8_t _class;
477 uint8_t _form;
479 unsigned int _tag;
481 unsigned int _type;
482
490 void setType(unsigned int type) {
491 _size = 1;
492 _type = type;
493 while (type >>= 8) {
494 ++_size;
495 }
496 type = _type;
497 if (_size == 1) {
498 _tag = type & 0x1F;
499 } else {
500 _tag = 0;
501 for (uint8_t index = 0; index < _size - 1; ++index) {
502 _tag <<= 7;
503 _tag |= type & 0x7F;
504 type >>= 8;
505 }
506 }
507 _class = type & 0xC0;
508 _form = type & 0x20;
509 }
510
521 void setFlagTag(uint8_t flag, unsigned int tag) {
522 _size = 1;
523 _class = flag & 0xC0;
524 _form = flag & 0x20;
525 _tag = tag;
526 if (tag < 0x1F) {
527 _type = _class | _form | _tag;
528 } else {
529 _type = _class | _form | 0x1F;
530 do {
531 ++_size;
532 } while (tag >>= 7);
533 tag = _tag;
534 for (int32_t index = _size - 2; index > -1; --index) {
535 _type <<= 8;
536 _type |= tag >> (index << 3) & 0x7F;
537 _type |= index ? 0x80 : 0x00;
538 }
539 }
540 }
541};
542
549class Length: public Base {
550public:
556 Length(unsigned int length = 0) :
557 Base() {
558 setLength(length);
559 }
560
561#if SNMP_STREAM
572 void encode(Stream &stream) {
573 if (_length > 0x7F) {
574 stream.write(0x80 | _size - 1);
575 unsigned int length = _length;
576 for (uint8_t index = 0; index < _size - 1; ++index) {
577 stream.write(length >> ((_size - index - 2) << 3));
578
579 }
580 } else {
581 stream.write(_length);
582 }
583 }
584
590 void decode(Stream &stream) {
591 _length = stream.read();
592 if (_length & 0x80) {
593 _size = _length & 0x7F;
594 _length = 0;
595 for (uint8_t index = 0; index < _size; ++index) {
596 _length <<= 8;
597 _length += stream.read();
598 }
599 _size++;
600 }
601 }
602#else
614 uint8_t* encode(uint8_t *buffer) {
615 uint8_t *pointer = buffer;
616 if (_length > 0x7F) {
617 *pointer = 0x80 | _size - 1;
618 pointer += _size - 1;
619
620 unsigned int value = _length;
621 for (uint8_t index = 0; index < _size - 1; ++index) {
622 *pointer-- = value;
623 value >>= 8;
624 }
625 } else {
626 *pointer++ = _length;
627 }
628 return buffer + _size;
629 }
630
637 uint8_t* decode(uint8_t *buffer) {
638 uint8_t *pointer = buffer;
639 _length = *pointer++;
640 if (_length & 0x80) {
641 _size = _length & 0x7F;
642 _length = 0;
643 for (uint8_t index = 0; index < _size; ++index) {
644 _length <<= 8;
645 _length += *pointer++;
646 }
647 _size++;
648 }
649 return pointer;
650 }
651#endif
652
665 operator unsigned int() const {
666 return _length;
667 }
668
682 Length& operator=(const unsigned int length) {
683 setLength(length);
684 return *this;
685 }
686
700 Length& operator+=(const unsigned int length) {
701 setLength(_length + length);
702 return *this;
703 }
704
718 Length& operator-=(const unsigned int length) {
719 setLength(_length - length);
720 return *this;
721 }
722
737 return *this;
738 }
739
753 Length length = *this;
754 operator++();
755 return length;
756 }
757
758private:
760 unsigned int _length;
761
769 void setLength(unsigned int length) {
770 _size = 1;
771 _length = length;
772 if (length > 0x7F) {
773 do {
774 length >>= 8;
775 _size++;
776 } while (length);
777 }
778 }
779};
780
793class BER: public Base {
794public:
800 BER(const unsigned int type) :
801 Base() {
802 _type = Type(type);
803 _length = Length(0);
804 }
805
809 virtual ~BER() {
810 }
811
812#if SNMP_STREAM
820 virtual void encode(Stream &stream) {
821 _type.encode(stream);
822 _length.encode(stream);
823 }
824
834 template<typename T>
835 void encodeNumeric(T value, Stream &stream) {
836 BER::encode(stream);
837 for (uint8_t index = 0; index < _length; ++index) {
838 stream.write(value >> ((_length - index - 1) << 3));
839 }
840 }
841
850 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
851 if ((flag & Flag::Typed) == Flag::None) {
852 _type.decode(stream);
853 }
854 _length.decode(stream);
855 }
856
867 template<typename T>
868 void decodeNumeric(T *value, Stream &stream, const uint8_t flag = Flag::None) {
869 BER::decode(stream, flag);
870 if (T() - 1 < 0) {
871 *value = stream.peek() & 0x80 ? 0xFFFFFFFF : 0;
872 } else {
873 *value = 0;
874 }
875 for (uint8_t index = 0; index < _length; ++index) {
876 *value <<= 8;
877 *value |= static_cast<uint8_t>(stream.read());
878 }
879 }
880#else
889 virtual uint8_t* encode(uint8_t *buffer) {
890 uint8_t *pointer = _type.encode(buffer);
891 pointer = _length.encode(pointer);
892 return pointer;
893 }
894
905 template<typename T>
906 uint8_t* encodeNumeric(T value, uint8_t *buffer) {
907 uint8_t *pointer = BER::encode(buffer);
908 for (uint8_t index = 0; index < _length; ++index) {
909 *pointer++ = value >> ((_length - index - 1) << 3);
910 }
911 return pointer;
912 }
913
922 virtual uint8_t* decode(uint8_t *buffer) {
923 uint8_t *pointer = _type.decode(buffer);
924 pointer = _length.decode(pointer);
925 return pointer;
926 }
927
939 template<typename T>
940 uint8_t* decodeNumeric(T *value, uint8_t *buffer, const uint8_t flag =
941 Flag::None) {
942 uint8_t *pointer = BER::decode(buffer);
943 if (T() - 1 < 0) {
944 *value = *pointer & 0x80 ? 0xFFFFFFFF : 0;
945 } else {
946 *value = 0;
947 }
948 for (unsigned int index = 0; index < _length; ++index) {
949 *value <<= 8;
950 *value |= static_cast<uint8_t>(*pointer++);
951 }
952 return pointer;
953 }
954#endif
955
962 template<typename T>
963 void setNegative(T value) {
964 unsigned int length = sizeof(T);
965 for (; length > 1; --length) {
966 uint16_t word = value >> ((length - 2) << 3);
967 if ((word & 0xFF80) != 0xFF80) {
968 break;
969 }
970 }
971 _length = length;
972 }
973
980 template<typename T>
981 void setPositive(T value) {
982 unsigned int length = 0;
983 uint8_t carry = 0;
984 do {
985 carry = value & 0x80;
986 value >>= 8;
987 length++;
988 } while (value | carry);
989 _length = length;
990 }
991
997 const unsigned int getType() const {
998 return _type;
999 }
1000
1006 const unsigned int getLength() const {
1007 return _length;
1008 }
1009
1022 virtual const unsigned int getSize(const bool refresh = false) {
1023 _size = _type._size + _length._size + _length;
1024 return _size;
1025 }
1026
1027protected:
1032
1039 BER* create(const Type &type);
1040};
1041
1057class BooleanBER: public BER {
1058public:
1064 BooleanBER(const bool value) :
1065 BER(Type::Boolean) {
1066 _length = LENGTH;
1067 _value = value;
1068 }
1069
1070#if SNMP_STREAM
1079 virtual void encode(Stream &stream) {
1080 BER::encode(stream);
1081 stream.write(_value ? 0xFF : 0x00);
1082 }
1083
1093 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1094 BER::decode(stream, flag);
1095 _value = stream.read();
1096 }
1097#else
1107 virtual uint8_t* encode(uint8_t *buffer) {
1108 uint8_t *pointer = BER::encode(buffer);
1109 *pointer = _value ? 0xFF : 0x00;
1110 return buffer + SIZE;
1111 }
1112
1122 virtual uint8_t* decode(uint8_t *buffer) {
1123 uint8_t *pointer = BER::decode(buffer);
1124 _value = *pointer++;
1125 return buffer + SIZE;
1126 }
1127#endif
1128
1134 const bool getValue() const {
1135 return _value;
1136 }
1137
1145 void setValue(const bool value) {
1146 _value = value;
1147 }
1148
1149private:
1151 static constexpr uint8_t LENGTH = 1;
1153 static constexpr uint8_t SIZE = 3;
1156};
1157
1179class IntegerBER: public BER {
1180public:
1186 IntegerBER(const int32_t value) :
1187 BER(Type::Integer) {
1188 setValue(value);
1189 }
1190
1191#if SNMP_STREAM
1200 virtual void encode(Stream &stream) {
1202 }
1203
1213 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1214 BER::decodeNumeric<int32_t>(&_value, stream, flag);
1215 }
1216
1217#else
1227 virtual uint8_t* encode(uint8_t *buffer) {
1228 return BER::encodeNumeric<int32_t>(_value, buffer);
1229 }
1230
1240 virtual uint8_t* decode(uint8_t *buffer) {
1241 return BER::decodeNumeric<int32_t>(&_value, buffer);
1242 }
1243#endif
1244
1250 const int32_t getValue() const {
1251 return _value;
1252 }
1253
1261 void setValue(const int32_t value) {
1262 _value = value;
1263 if (_value < 0) {
1264 BER::setNegative(value);
1265 } else {
1266 BER::setPositive(value);
1267 }
1268 }
1269
1270private:
1272 int32_t _value;
1273};
1274
1289class OctetStringBER: public BER {
1290public:
1301 OctetStringBER(const char *value) :
1302 OctetStringBER(value, strlen(value)) {
1303 }
1304
1316 OctetStringBER(const char *value, const uint32_t length);
1317
1324 free(_value);
1325 }
1326
1327#if SNMP_STREAM
1336 virtual void encode(Stream &stream) {
1337 BER::encode(stream);
1338 stream.write(_value, _length);
1339 }
1340
1350 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1351 BER::decode(stream, flag);
1352 allocate();
1353 stream.readBytes(_value, _length);
1354 }
1355#else
1365 virtual uint8_t* encode(uint8_t *buffer) {
1366 uint8_t *pointer = BER::encode(buffer);
1367 memcpy(pointer, _value, _length);
1368 return pointer + _length;
1369 }
1370
1380 virtual uint8_t* decode(uint8_t *buffer) {
1381 uint8_t *pointer = BER::decode(buffer);
1382 setValue(reinterpret_cast<const char*>(pointer), _length);
1383 return pointer + _length;
1384 }
1385#endif
1386
1392 const char* getValue() const {
1393 return _value;
1394 }
1395
1404 void setValue(const char *value, const unsigned int length) {
1405 _length = length;
1406 allocate();
1407 memcpy(_value, value, length);
1408 }
1409
1416 const bool getBit(const unsigned int index) const {
1417 const unsigned int byte = index / 8;
1418 const uint8_t bit = index % 8;
1419 return _value[byte] & (0x80 >> bit);
1420 }
1421
1422protected:
1424 char *_value;
1425
1431 OctetStringBER(const uint8_t type = Type::OctetString) :
1432 BER(type) {
1433 _value = nullptr;
1434 }
1435
1439 void allocate() {
1440 free(_value);
1441 _value = static_cast<char*>(malloc(_length + 1));
1442 _value[_length] = 0;
1443 }
1444};
1445
1461class NullBER: public BER {
1462public:
1468 NullBER(const uint8_t type = Type::Null) :
1469 BER(type) {
1470 }
1471};
1472
1489public:
1500 ObjectIdentifierBER(const char *value) :
1501 BER(Type::ObjectIdentifier) {
1502 setValue(value);
1503 }
1504
1505#if SNMP_STREAM
1514 virtual void encode(Stream &stream) {
1515 unsigned int index = 0;
1516 uint32_t subidentifier = 0;
1517 BER::encode(stream);
1518 char *token = const_cast<char*>(_value.c_str());
1519 while (token != NULL) {
1520 switch (index) {
1521 case 0:
1522 subidentifier = atoi(token);
1523 break;
1524 case 1:
1525 subidentifier = subidentifier * 40 + atoi(++token);
1526 stream.write(subidentifier);
1527 _size++;
1528 break;
1529 ;
1530 default: {
1531 subidentifier = atol(++token);
1532 uint32_t value = subidentifier;
1533 uint32_t length = 0;
1534 do {
1535 value >>= 7;
1536 length++;
1537 } while (value);
1538 Base::encode7bits(subidentifier, stream, length);
1539 _size += length;
1540 }
1541 break;
1542 }
1543 token = strchr(token, '.');
1544 index++;
1545 }
1546 }
1547
1557 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1558 unsigned int index = 0;
1559 uint32_t subidentifier = 0;
1560 BER::decode(stream, flag);
1561 unsigned int length = _length;
1562 _size += length;
1563 while (length) {
1564 if (index++) {
1565 subidentifier = 0;
1566 uint8_t byte;
1567 do {
1568 length--;
1569 byte = stream.read();
1570 subidentifier <<= 7;
1571 subidentifier += byte & 0x7F;
1572 } while (byte & 0x80);
1573 _value += "." + String(subidentifier);
1574 } else {
1575 length--;
1576 subidentifier = stream.read();
1577 _value = String(subidentifier / 40) + "." + String(subidentifier % 40);
1578 }
1579 }
1580 }
1581#else
1591 virtual uint8_t* encode(uint8_t *buffer) {
1592 unsigned int index = 0;
1593 uint32_t subidentifier = 0;
1594 uint8_t *pointer = BER::encode(buffer);
1595 char *token = const_cast<char*>(_value.c_str());
1596 while (token != NULL) {
1597 switch (index) {
1598 case 0:
1599 subidentifier = atoi(token);
1600 break;
1601 case 1:
1602 subidentifier = subidentifier * 40 + atoi(++token);
1603 *pointer = subidentifier;
1604 break;
1605 ;
1606 default: {
1607 subidentifier = atol(++token);
1608 uint32_t value = subidentifier;
1609 uint32_t length = 0;
1610 do {
1611 value >>= 7;
1612 length++;
1613 } while (value);
1614 Base::encode7bits(subidentifier, pointer, length);
1615 pointer += length;
1616 }
1617 break;
1618 }
1619 token = strchr(token, '.');
1620 index++;
1621 }
1622 return ++pointer;
1623 }
1624
1634 virtual uint8_t* decode(uint8_t *buffer) {
1635 unsigned int index = 0;
1636 uint32_t subidentifier = 0;
1637 uint8_t *pointer = BER::decode(buffer);
1638 uint8_t *end = pointer + _length;
1639 do {
1640 if (index++) {
1641 subidentifier = 0;
1642 do {
1643 subidentifier <<= 7;
1644 subidentifier += *pointer & 0x7F;
1645 } while (*pointer++ & 0x80);
1646 _value += "." + String(subidentifier);
1647 } else {
1648 subidentifier = *pointer++;
1649 _value = String(subidentifier / 40) + "."
1650 + String(subidentifier % 40);
1651 }
1652 } while (pointer < end);
1653 return pointer;
1654 }
1655#endif
1656
1662 const char* getValue() const {
1663 return _value.c_str();
1664 }
1665
1673 void setValue(const char *value) {
1674 _value = value;
1675 unsigned int index = 0;
1676 uint32_t subidentifier = 0;
1677 char *token = const_cast<char*>(_value.c_str());
1678 while (token != NULL) {
1679 switch (index) {
1680 case 0:
1681 subidentifier = atoi(token);
1682 break;
1683 case 1:
1684 subidentifier = subidentifier * 40 + atoi(++token);
1685 _length++;
1686 break;
1687 default: {
1688 subidentifier = atol(++token);
1689 do {
1690 subidentifier >>= 7;
1691 _length++;
1692 } while (subidentifier);
1693 }
1694 break;
1695 }
1696 token = strchr(token, '.');
1697 index++;
1698 }
1699 }
1700
1701private:
1703 String _value;
1704};
1705
1715template<const uint8_t U>
1716class ArrayBER: public BER {
1717public:
1723 ArrayBER(const uint8_t type) :
1724 BER(type) {
1725 }
1726
1733#if SNMP_VECTOR
1734 for (auto ber : _bers) {
1735 delete ber;
1736 }
1737 _bers.clear();
1738#else
1739 for (uint8_t index = 0; index < _count; ++index) {
1740 delete _bers[index];
1741 }
1742#endif
1743 }
1744
1745#if SNMP_STREAM
1754 virtual void encode(Stream &stream) {
1755 BER::encode(stream);
1756 for (uint8_t index = 0; index < _count; ++index) {
1757 _bers[index]->encode(stream);
1758 }
1759 }
1760
1777 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1778 BER::decode(stream, flag);
1779 unsigned int length = _length;
1780 if (length) {
1781 Type type;
1782 _length = 0;
1783 do {
1784 type.decode(stream);
1785 BER *ber = create(type);
1786 if (ber) {
1787 ber->decode(stream, Flag::Typed);
1788 length -= ber->getSize();
1789 add(ber);
1790 }
1791 } while (length);
1792 }
1793 }
1794#else
1804 virtual uint8_t* encode(uint8_t *buffer) {
1805 uint8_t *pointer = BER::encode(buffer);
1806#if SNMP_VECTOR
1807 for (auto ber : _bers) {
1808 pointer = ber->encode(pointer);
1809 }
1810#else
1811 for (uint8_t index = 0; index < _count; ++index) {
1812 pointer = _bers[index]->encode(pointer);
1813 }
1814#endif
1815 return pointer;
1816 }
1817
1827 virtual uint8_t* decode(uint8_t *buffer) {
1828 uint8_t *pointer = BER::decode(buffer);
1829 if (_length) {
1830 uint8_t *end = pointer + _length;
1831 _length = 0;
1832 Type type;
1833 do {
1834 type.decode(pointer);
1835 BER *ber = create(type);
1836 if (ber) {
1837 pointer = ber->decode(pointer);
1838 add(ber);
1839 }
1840 } while (pointer < end);
1841 }
1842 return pointer;
1843 }
1844#endif
1845
1860 virtual const unsigned int getSize(const bool refresh = false) {
1861 if (refresh) {
1862 _length = 0;
1863 for (uint8_t index = 0; index < _count; ++index) {
1864 _length += _bers[index]->getSize(true);
1865 }
1866 }
1867 return BER::getSize();
1868 }
1869
1878 BER* operator [](const unsigned int index) {
1879 return _bers[index];
1880 }
1881
1887 const uint8_t count() const {
1888 return _count;
1889 }
1890
1891protected:
1900 BER* add(BER *ber) {
1901#if SNMP_VECTOR
1902 _bers.push_back(ber);
1903 _length += ber->getSize();
1904 _count++;
1905#else
1906 if (_count < U) {
1907 _bers[_count++] = ber;
1908 _length += ber->getSize();
1909 }
1910#endif
1911 return ber;
1912 }
1913
1919 void remove() {
1920#if SNMP_VECTOR
1921 if (_bers.size()) {
1922 _length -= _bers.back()->getSize();
1923 _bers.pop_back();
1924 --_count;
1925 }
1926#else
1927 if (_count) {
1928 _length -= _bers[--_count]->getSize();
1929 }
1930#endif
1931 }
1932
1933private:
1935 uint8_t _count = 0;
1936#if SNMP_VECTOR
1938 std::vector<BER*> _bers;
1939#else
1942#endif
1943
1944 friend class Message;
1945 friend class VarBind;
1946 friend class VarBindList;
1947};
1948
1953class SequenceBER: public ArrayBER<SNMP_CAPACITY> {
1954public:
1960 SequenceBER(const uint8_t type = Type::Sequence) :
1961 ArrayBER(type) {
1962 }
1963};
1964
1975class VarBind: public ArrayBER<2> {
1976public:
1983 VarBind(const char *oid, BER *value = nullptr) :
1984 ArrayBER(Type::Sequence) {
1985 add(new ObjectIdentifierBER(oid));
1986 if (value) {
1987 add(value);
1988 } else {
1989 add(new NullBER);
1990 }
1991 }
1992
2000 const char* getName() const {
2001 return static_cast<ObjectIdentifierBER*>(_bers[0])->getValue();
2002 }
2003
2011 BER* getValue() const {
2012 return _bers[1];
2013 }
2014};
2015
2024public:
2033 VarBind* operator [](const uint32_t index) {
2034 return static_cast<VarBind*>(_bers[index]);
2035 }
2036};
2037
2055public:
2063 IPAddressBER(IPAddress value) :
2064 OctetStringBER(Type::IPAddress) {
2065 _length = LENGTH;
2066 allocate();
2067 for (uint8_t index = 0; index < LENGTH; ++index) {
2068 _value[index] = value[index];
2069 }
2070 }
2071
2077 const uint8_t* getValue() {
2078 return reinterpret_cast<uint8_t*>(_value);
2079 }
2080
2081private:
2083 static constexpr uint8_t LENGTH = 4;
2084};
2085
2092template<class T>
2093class UIntegerBER: public BER {
2094protected:
2101 UIntegerBER(const T value, const uint8_t type) :
2102 BER(type) {
2103 setValue(value);
2104 }
2105
2106public:
2107#if SNMP_STREAM
2116 virtual void encode(Stream &stream) {
2118 }
2119
2129 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
2130 BER::decodeNumeric<T>(&_value, stream, flag);
2131 }
2132#else
2142 virtual uint8_t* encode(uint8_t *buffer) {
2143 return BER::encodeNumeric<T>(_value, buffer);
2144 }
2145
2155 virtual uint8_t* decode(uint8_t *buffer) {
2156 return BER::decodeNumeric<T>(&_value, buffer);
2157 }
2158#endif
2159
2165 const T getValue() const {
2166 return _value;
2167 }
2168
2176 void setValue(const T value) {
2177 _value = value;
2178 BER::setPositive<T>(value);
2179 }
2180
2181private:
2184};
2185
2201class Counter32BER: public UIntegerBER<uint32_t> {
2202public:
2208 Counter32BER(const uint32_t value) :
2209 UIntegerBER(value, Type::Counter32) {
2210 }
2211};
2212
2228class Counter64BER: public UIntegerBER<uint64_t> {
2229public:
2235 Counter64BER(const uint64_t value) :
2236 UIntegerBER(value, Type::Counter64) {
2237 }
2238};
2239
2255class Gauge32BER: public UIntegerBER<uint32_t> {
2256public:
2262 Gauge32BER(const uint32_t value) :
2263 UIntegerBER(value, Type::Gauge32) {
2264 }
2265};
2266
2284class TimeTicksBER: public UIntegerBER<uint32_t> {
2285public:
2291 TimeTicksBER(const uint32_t value) :
2292 UIntegerBER(value, Type::TimeTicks) {
2293 }
2294};
2295
2312
2313class OpaqueBER: public BER {
2314public:
2320 OpaqueBER(BER *ber);
2321
2327 virtual ~OpaqueBER() {
2328 delete _ber;
2329 }
2330
2331#if SNMP_STREAM
2340 virtual void encode(Stream &stream) {
2341 BER::encode(stream);
2342 _ber->encode(stream);
2343 }
2344
2361 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
2362 BER::decode(stream, flag);
2363 uint32_t length = _length;
2364 if (length) {
2365 Type type;
2366 do {
2367 type.decode(stream);
2368 _ber = create(type);
2369 if (_ber) {
2370 _ber->decode(stream, Flag::Typed);
2371 length -= _ber->getSize();
2372 }
2373 } while (length);
2374 }
2375 }
2376#else
2386 virtual uint8_t* encode(uint8_t *buffer) {
2387 uint8_t *pointer = BER::encode(buffer);
2388 return _ber->encode(pointer);
2389 }
2390
2400 virtual uint8_t* decode(uint8_t *buffer) {
2401 uint8_t *pointer = BER::decode(buffer);
2402 uint8_t *end = pointer + _length;
2403 if (_length) {
2404 Type type;
2405 do {
2406 type.decode(pointer);
2407 _ber = create(type);
2408 if (_ber) {
2409 pointer = _ber->decode(pointer);
2410 }
2411 } while (pointer < end);
2412 }
2413 return pointer;
2414 }
2415#endif
2416
2431 virtual const unsigned int getSize(const bool refresh = false) {
2432 if (refresh) {
2433 _length = _ber->getSize(true);
2434 }
2435 return BER::getSize();
2436 }
2437
2444 return _ber;
2445 }
2446
2447private:
2450};
2451
2474class FloatBER: public BER {
2475public:
2482 FloatBER(const float value, const unsigned int type = Type::Float) :
2483 BER(type) {
2484 _length = LENGTH;
2485 setValue(value);
2486 }
2487
2488#if SNMP_STREAM
2497 virtual void encode(Stream &stream) {
2498 BER::encodeNumeric<uint32_t>(*(reinterpret_cast<uint32_t*>(&_value)), stream);
2499 }
2500
2510 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
2511 BER::decodeNumeric<uint32_t>(reinterpret_cast<uint32_t*>(&_value), stream, flag);
2512 }
2513#else
2523 virtual uint8_t* encode(uint8_t *buffer) {
2525 *(reinterpret_cast<uint32_t*>(&_value)), buffer);
2526 }
2527
2537 virtual uint8_t* decode(uint8_t *buffer) {
2539 reinterpret_cast<uint32_t*>(&_value), buffer);
2540 }
2541#endif
2542
2548 const float getValue() const {
2549 return _value;
2550 }
2551
2557 void setValue(const float value) {
2558 _value = value;
2559 }
2560
2561protected:
2563 static constexpr uint8_t LENGTH = 4;
2565 float _value;
2566};
2567
2573public:
2578 NullBER(Type::NoSuchObject) {
2579 }
2580};
2581
2587public:
2592 NullBER(Type::NoSuchInstance) {
2593 }
2594};
2595
2601public:
2606 NullBER(Type::EndOfMIBView) {
2607 }
2608};
2609
2631public:
2637 OpaqueFloatBER(const float value) :
2638 FloatBER(value, Type::OpaqueFloat) {
2639 }
2640};
2641
2642} // namespace SNMP
2643
2644#endif /* BER_H_ */
2645
2646//Added by Sloeber
2647#pragma once
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes ArrayBER from stream.
Definition BER.h:1777
void remove()
Removes the last BER in the array.
Definition BER.h:1919
BER * operator[](const unsigned int index)
Array subscript operator.
Definition BER.h:1878
const uint8_t count() const
Gets the count of BERs in the array.
Definition BER.h:1887
std::vector< BER * > _bers
Definition BER.h:1938
BER * add(BER *ber)
Adds a BER to the array.
Definition BER.h:1900
friend class VarBindList
Definition BER.h:1946
friend class Message
Definition BER.h:1944
~ArrayBER()
ArrayBER destructor.
Definition BER.h:1732
uint8_t _count
Definition BER.h:1935
ArrayBER(const uint8_t type)
Creates an ArrayBER.
Definition BER.h:1723
virtual uint8_t * encode(uint8_t *buffer)
Encodes ArrayBER to memory buffer.
Definition BER.h:1804
virtual void encode(Stream &stream)
Encodes ArrayBER to stream.
Definition BER.h:1754
friend class VarBind
Definition BER.h:1945
virtual uint8_t * decode(uint8_t *buffer)
Decodes ArrayBER from memory buffer.
Definition BER.h:1827
virtual const unsigned int getSize(const bool refresh=false)
Gets the size of the ArrayBER.
Definition BER.h:1860
BER object.
Definition BER.h:793
virtual void encode(Stream &stream)
Encodes BER type and length to stream.
Definition BER.h:820
virtual const unsigned int getSize(const bool refresh=false)
Gets the size of the BER.
Definition BER.h:1022
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes BER type and length from stream.
Definition BER.h:850
void decodeNumeric(T *value, Stream &stream, const uint8_t flag=Flag::None)
Decodes BER numeric value from stream.
Definition BER.h:868
const unsigned int getType() const
Gets the BER type.
Definition BER.h:997
uint8_t * encodeNumeric(T value, uint8_t *buffer)
Encodes BER numeric value to memory buffer.
Definition BER.h:906
void setNegative(T value)
Computes BER length of a negative integer.
Definition BER.h:963
uint8_t * decodeNumeric(T *value, uint8_t *buffer, const uint8_t flag=Flag::None)
Decodes BER numeric value from memory buffer.
Definition BER.h:940
Type _type
Definition BER.h:1031
virtual uint8_t * encode(uint8_t *buffer)
Encodes BER type and length to memory buffer.
Definition BER.h:889
virtual ~BER()
BER destructor.
Definition BER.h:809
BER * create(const Type &type)
Creates a BER of given type.
Definition BER.cpp:15
virtual uint8_t * decode(uint8_t *buffer)
Decodes BER type and length from memory buffer.
Definition BER.h:922
Length _length
Definition BER.h:1029
BER(const unsigned int type)
Creates a BER object.
Definition BER.h:800
const unsigned int getLength() const
Gets the BER length.
Definition BER.h:1006
void setPositive(T value)
Computes BER length of a positive integer.
Definition BER.h:981
void encodeNumeric(T value, Stream &stream)
Encodes BER numeric value to stream.
Definition BER.h:835
Base class for BER, Length and Type.
Definition BER.h:219
unsigned int _size
Definition BER.h:265
static void encode7bits(uint32_t value, Stream &stream, const uint8_t size)
Encodes integer value to stream.
Definition BER.h:235
void encode7bits(uint32_t value, uint8_t *buffer, const uint8_t size)
Encodes integer value to memory buffer.
Definition BER.h:254
friend class BER
Definition BER.h:267
BooleanBER(const bool value)
Creates a BooleanBER object.
Definition BER.h:1064
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes BooleanBER from stream.
Definition BER.h:1093
virtual void encode(Stream &stream)
Encodes BooleanBER to stream.
Definition BER.h:1079
virtual uint8_t * decode(uint8_t *buffer)
Decodes BooleanBER from memory buffer.
Definition BER.h:1122
virtual uint8_t * encode(uint8_t *buffer)
Encodes BooleanBER to memory buffer.
Definition BER.h:1107
static constexpr uint8_t SIZE
Definition BER.h:1153
void setValue(const bool value)
Sets the BooleanBER value.
Definition BER.h:1145
const bool getValue() const
Gets the BooleanBER value.
Definition BER.h:1134
static constexpr uint8_t LENGTH
Definition BER.h:1151
Counter32BER(const uint32_t value)
Creates a Counter32BER object.
Definition BER.h:2208
Counter64BER(const uint64_t value)
Creates a Counter64BER object.
Definition BER.h:2235
EndOfMIBViewBER()
Creates a EndOfMIBViewBER object.
Definition BER.h:2605
Helper class for internal flag.
Definition BER.h:202
@ None
Definition BER.h:208
@ Typed
Definition BER.h:209
const float getValue() const
Gets the FloatBER value.
Definition BER.h:2548
FloatBER(const float value, const unsigned int type=Type::Float)
Creates a FloatBER object.
Definition BER.h:2482
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes FloatBER from stream.
Definition BER.h:2510
virtual void encode(Stream &stream)
Encodes FloatBER to stream.
Definition BER.h:2497
static constexpr uint8_t LENGTH
Definition BER.h:2563
float _value
Definition BER.h:2565
void setValue(const float value)
Sets the FloatBER value.
Definition BER.h:2557
virtual uint8_t * decode(uint8_t *buffer)
Decodes FloatBER from memory buffer.
Definition BER.h:2537
virtual uint8_t * encode(uint8_t *buffer)
Encodes FloatBER to memory buffer.
Definition BER.h:2523
Gauge32BER(const uint32_t value)
Creates a Gauge32BER object.
Definition BER.h:2262
IPAddressBER(IPAddress value)
Creates an IPAddressBER object.
Definition BER.h:2063
const uint8_t * getValue()
Gets the IPAddressBER value.
Definition BER.h:2077
static constexpr uint8_t LENGTH
Definition BER.h:2083
const int32_t getValue() const
Gets the IntegerBER value.
Definition BER.h:1250
int32_t _value
Definition BER.h:1272
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes IntegerBER from stream.
Definition BER.h:1213
virtual void encode(Stream &stream)
Encodes IntegerBER to stream.
Definition BER.h:1200
virtual uint8_t * decode(uint8_t *buffer)
Decodes IntegerBER from memory buffer.
Definition BER.h:1240
IntegerBER(const int32_t value)
Creates an IntegerBER object.
Definition BER.h:1186
virtual uint8_t * encode(uint8_t *buffer)
Encodes IntegerBER to memory buffer.
Definition BER.h:1227
void setValue(const int32_t value)
Sets the IntegerBER value.
Definition BER.h:1261
Length of a BER object.
Definition BER.h:549
Length & operator+=(const unsigned int length)
Addition operator.
Definition BER.h:700
void setLength(unsigned int length)
Sets length from integer.
Definition BER.h:769
Length & operator-=(const unsigned int length)
Subtraction operator.
Definition BER.h:718
uint8_t * encode(uint8_t *buffer)
Encodes BER length to memory buffer.
Definition BER.h:614
void decode(Stream &stream)
Decodes BER length from stream.
Definition BER.h:590
unsigned int _length
Definition BER.h:760
uint8_t * decode(uint8_t *buffer)
Decodes BER length from memory buffer.
Definition BER.h:637
Length & operator=(const unsigned int length)
Unsigned int assignment operator.
Definition BER.h:682
Length & operator++()
Prefix increment operator.
Definition BER.h:735
Length(unsigned int length=0)
Creates a BER length from a length value.
Definition BER.h:556
void encode(Stream &stream)
Encodes BER length to stream.
Definition BER.h:572
NoSuchInstanceBER()
Creates a NoSuchInstanceBER object.
Definition BER.h:2591
NoSuchObjectBER()
Creates a NoSuchObjectBER object.
Definition BER.h:2577
BER object to handle null.
Definition BER.h:1461
NullBER(const uint8_t type=Type::Null)
Creates a NullBER object.
Definition BER.h:1468
BER object to handle OID.
Definition BER.h:1488
virtual uint8_t * encode(uint8_t *buffer)
Encodes ObjectIdentifierBER to memory buffer.
Definition BER.h:1591
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes ObjectIdentifierBER from stream.
Definition BER.h:1557
void setValue(const char *value)
Set the ObjectIdentifierBER value.
Definition BER.h:1673
const char * getValue() const
Gets the ObjectIdentifierBER value.
Definition BER.h:1662
virtual void encode(Stream &stream)
Encodes ObjectIdentifierBER to stream.
Definition BER.h:1514
virtual uint8_t * decode(uint8_t *buffer)
Decodes ObjectIdentifierBER from memory buffer.
Definition BER.h:1634
ObjectIdentifierBER(const char *value)
Creates an ObjectIdentifierBER object.
Definition BER.h:1500
OctetStringBER(const char *value)
Creates an OctetStringBER object.
Definition BER.h:1301
virtual uint8_t * decode(uint8_t *buffer)
Decodes OctetStringBER from memory buffer.
Definition BER.h:1380
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes OctetStringBER from stream.
Definition BER.h:1350
OctetStringBER(const uint8_t type=Type::OctetString)
Creates an empty OctetStringBER object.
Definition BER.h:1431
virtual uint8_t * encode(uint8_t *buffer)
Encodes OctetStringBER to memory buffer.
Definition BER.h:1365
const char * getValue() const
Gets the OctetStringBER value.
Definition BER.h:1392
const bool getBit(const unsigned int index) const
Gets bit at a given index in the OctetStringBER value.
Definition BER.h:1416
void allocate()
Allocates the char array.
Definition BER.h:1439
void setValue(const char *value, const unsigned int length)
Sets the OctetStringBER value.
Definition BER.h:1404
virtual ~OctetStringBER()
OctetStringBER destructor.
Definition BER.h:1323
virtual void encode(Stream &stream)
Encodes OctetStringBER to stream.
Definition BER.h:1336
virtual uint8_t * decode(uint8_t *buffer)
Decodes OpaqueBER from memory buffer.
Definition BER.h:2400
virtual const unsigned int getSize(const bool refresh=false)
Gets the size of the OpaqueBER.
Definition BER.h:2431
OpaqueBER(BER *ber)
Creates an OpaqueBER.
Definition BER.cpp:82
BER * _ber
Definition BER.h:2449
BER * getBER()
Gets the embedded BER.
Definition BER.h:2443
virtual ~OpaqueBER()
OpaqueBER destructor.
Definition BER.h:2327
virtual void encode(Stream &stream)
Encodes OpaqueBER to stream.
Definition BER.h:2340
virtual uint8_t * encode(uint8_t *buffer)
Encodes OpaqueBER to memory buffer.
Definition BER.h:2386
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes OpaqueBER from stream.
Definition BER.h:2361
OpaqueFloatBER(const float value)
Creates an OpaqueFloatBER object.
Definition BER.h:2637
SequenceBER(const uint8_t type=Type::Sequence)
Creates a SequenceBER.
Definition BER.h:1960
TimeTicksBER(const uint32_t value)
Creates a TimeTicksBER object.
Definition BER.h:2291
Type of a BER object.
Definition BER.h:282
void setType(unsigned int type)
Sets BER type from type value.
Definition BER.h:490
Type(const uint8_t flag, const unsigned int tag)
Creates a BER type from a composite type value.
Definition BER.h:342
const uint8_t getClass() const
Gets class from BER type.
Definition BER.h:451
void decode(Stream &stream)
Decodes BER type from stream.
Definition BER.h:372
uint8_t * encode(uint8_t *buffer)
Encodes BER type to memory buffer.
Definition BER.h:401
unsigned int _tag
Definition BER.h:479
uint8_t * decode(uint8_t *buffer)
Decodes BER type from memory buffer.
Definition BER.h:417
unsigned int _type
Definition BER.h:481
Type(const unsigned int type=0)
Creates a BER type from a type value.
Definition BER.h:329
@ Trap
Definition BER.h:313
@ NoSuchObject
Definition BER.h:305
@ BitString
Definition BER.h:291
@ OpaqueFloat
Definition BER.h:321
@ GetNextRequest
Definition BER.h:310
@ Gauge32
Definition BER.h:299
@ EndOfMIBView
Definition BER.h:307
@ Boolean
Definition BER.h:289
@ Sequence
Definition BER.h:295
@ GetResponse
Definition BER.h:311
@ NoSuchInstance
Definition BER.h:306
@ TimeTicks
Definition BER.h:300
@ Integer
Definition BER.h:290
@ InformRequest
Definition BER.h:316
@ SNMPv2Trap
Definition BER.h:317
@ Counter64
Definition BER.h:302
@ ObjectIdentifier
Definition BER.h:294
@ Counter32
Definition BER.h:298
@ GetRequest
Definition BER.h:309
@ GetBulkRequest
Definition BER.h:315
@ Float
Definition BER.h:303
@ Report
Definition BER.h:319
@ SetRequest
Definition BER.h:312
@ IPAddress
Definition BER.h:297
@ Null
Definition BER.h:293
@ Opaque
Definition BER.h:301
@ OctetString
Definition BER.h:292
void encode(Stream &stream)
Encodes BER type to stream.
Definition BER.h:358
uint8_t _form
Definition BER.h:477
uint8_t _class
Definition BER.h:475
const unsigned int getTag() const
Gets tag from BER type.
Definition BER.h:469
const uint8_t getForm() const
Gets form from BER type.
Definition BER.h:460
void setFlagTag(uint8_t flag, unsigned int tag)
Creates a BER type from a composite type value.
Definition BER.h:521
virtual uint8_t * decode(uint8_t *buffer)
Decodes UIntegerBER from memory buffer.
Definition BER.h:2155
void setValue(const T value)
Sets the UIntegerBER value.
Definition BER.h:2176
const T getValue() const
Gets the UIntegerBER value.
Definition BER.h:2165
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes UIntegerBER from stream.
Definition BER.h:2129
virtual uint8_t * encode(uint8_t *buffer)
Encodes UIntegerBER to memory buffer.
Definition BER.h:2142
UIntegerBER(const T value, const uint8_t type)
Creates an UIntegerBER.
Definition BER.h:2101
virtual void encode(Stream &stream)
Encodes UIntegerBER to stream.
Definition BER.h:2116
BER object to handle variable binding.
Definition BER.h:1975
BER * getValue() const
Gets variable binding value.
Definition BER.h:2011
VarBind(const char *oid, BER *value=nullptr)
Creates a VarBind.
Definition BER.h:1983
const char * getName() const
Gets variable binding name.
Definition BER.h:2000
BER object to handle a list of variable bindings.
Definition BER.h:2023
VarBind * operator[](const uint32_t index)
Array subscript operator.
Definition BER.h:2033
SNMP library namespace.
Helper struct to handle class of BER type.
Definition BER.h:170
@ Private
Definition BER.h:178
@ Application
Definition BER.h:176
@ Universal
Definition BER.h:175
@ Context
Definition BER.h:177
uint8_t _index
Definition BER.h:114
@ InconsistentName
Definition BER.h:97
@ InconsistentValue
Definition BER.h:91
@ WrongEncoding
Definition BER.h:88
@ AuthorizationError
Definition BER.h:95
@ WrongValue
Definition BER.h:89
@ CommitFailed
Definition BER.h:93
@ WrongType
Definition BER.h:86
@ WrongLength
Definition BER.h:87
@ NotWritable
Definition BER.h:96
@ NoAccess
Definition BER.h:85
@ TooBig
Definition BER.h:79
@ BadValue
Definition BER.h:81
@ GenErr
Definition BER.h:83
@ ReadOnly
Definition BER.h:82
@ UndoFailed
Definition BER.h:94
@ NoError
Definition BER.h:78
@ NoCreation
Definition BER.h:90
@ ResourceUnavailable
Definition BER.h:92
@ NoSuchName
Definition BER.h:80
Error()
Initializes to default values.
Definition BER.h:106
uint8_t _status
Definition BER.h:112
Helper struct to handle form of BER type.
Definition BER.h:188
@ Primitive
Definition BER.h:193
@ Constructed
Definition BER.h:194
IPAddress _agentAddr
Definition BER.h:155
uint32_t _timeStamp
Definition BER.h:161
Trap()
Initializes to default values.
Definition BER.h:145
uint8_t _genericTrap
Definition BER.h:157
uint32_t _specificTrap
Definition BER.h:159
const char * _enterprise
Definition BER.h:153
@ EGPNeighborLoss
Definition BER.h:133
@ WarmStart
Definition BER.h:129
@ EnterpriseSpecific
Definition BER.h:134
@ AuthenticationFailure
Definition BER.h:132
@ LinkUp
Definition BER.h:131
@ ColdStart
Definition BER.h:128
@ LinkDown
Definition BER.h:130
Helper struct to handle SNMP versions.
Definition BER.h:51