SNMP 2.0.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);
575 unsigned int length = _length;
576 for (uint8_t index = 0; index < _size; ++index) {
577 stream.write(length >> ((_size - index - 1) << 3));
578 }
579 } else {
580 stream.write(_length);
581 }
582 }
583
589 void decode(Stream &stream) {
590 _length = stream.read();
591 if (_length & 0x80) {
592 _size = _length & 0x7F;
593 _length = 0;
594 for (uint8_t index = 0; index < _size; ++index) {
595 _length <<= 8;
596 _length += stream.read();
597 }
598 _size++;
599 } else {
600 _size = 1;
601 }
602 }
603#else
615 uint8_t* encode(uint8_t *buffer) {
616 uint8_t *pointer = buffer;
617 if (_length > 0x7F) {
618 *pointer = 0x80 | _size;
619 pointer += _size;
620 unsigned int value = _length;
621 for (uint8_t index = 0; index < _size; ++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 }
648 return pointer;
649 }
650#endif
651
664 operator unsigned int() const {
665 return _length;
666 }
667
681 Length& operator=(const unsigned int length) {
682 setLength(length);
683 return *this;
684 }
685
699 Length& operator+=(const unsigned int length) {
700 setLength(_length + length);
701 return *this;
702 }
703
717 Length& operator-=(const unsigned int length) {
718 setLength(_length - length);
719 return *this;
720 }
721
736 return *this;
737 }
738
752 Length length = *this;
753 operator++();
754 return length;
755 }
756
757private:
759 unsigned int _length;
760
768 void setLength(unsigned int length) {
769 _size = 1;
770 _length = length;
771 if (length > 0x7F) {
772 do {
773 length >>= 8;
774 _size++;
775 } while (length);
776 }
777 }
778};
779
792class BER: public Base {
793public:
799 BER(const unsigned int type) :
800 Base() {
801 _type = Type(type);
802 _length = Length(0);
803 }
804
808 virtual ~BER() {
809 }
810
811#if SNMP_STREAM
819 virtual void encode(Stream &stream) {
820 _type.encode(stream);
821 _length.encode(stream);
822 }
823
833 template<typename T>
834 void encodeNumeric(T value, Stream &stream) {
835 BER::encode(stream);
836 for (uint8_t index = 0; index < _length; ++index) {
837 stream.write(value >> ((_length - index - 1) << 3));
838 }
839 }
840
849 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
850 if ((flag & Flag::Typed) == Flag::None) {
851 _type.decode(stream);
852 }
853 _length.decode(stream);
854 }
855
866 template<typename T>
867 void decodeNumeric(T *value, Stream &stream, const uint8_t flag = Flag::None) {
868 BER::decode(stream, flag);
869 if (T() - 1 < 0) {
870 *value = stream.peek() & 0x80 ? 0xFFFFFFFF : 0;
871 } else {
872 *value = 0;
873 }
874 for (uint8_t index = 0; index < _length; ++index) {
875 *value <<= 8;
876 *value |= static_cast<uint8_t>(stream.read());
877 }
878 }
879#else
888 virtual uint8_t* encode(uint8_t *buffer) {
889 uint8_t *pointer = _type.encode(buffer);
890 pointer = _length.encode(pointer);
891 return pointer;
892 }
893
904 template<typename T>
905 uint8_t* encodeNumeric(T value, uint8_t *buffer) {
906 uint8_t *pointer = BER::encode(buffer);
907 for (uint8_t index = 0; index < _length; ++index) {
908 *pointer++ = value >> ((_length - index - 1) << 3);
909 }
910 return pointer;
911 }
912
921 virtual uint8_t* decode(uint8_t *buffer) {
922 uint8_t *pointer = _type.decode(buffer);
923 pointer = _length.decode(pointer);
924 return pointer;
925 }
926
938 template<typename T>
939 uint8_t* decodeNumeric(T *value, uint8_t *buffer, const uint8_t flag =
940 Flag::None) {
941 uint8_t *pointer = BER::decode(buffer);
942 if (T() - 1 < 0) {
943 *value = *pointer & 0x80 ? 0xFFFFFFFF : 0;
944 } else {
945 *value = 0;
946 }
947 for (unsigned int index = 0; index < _length; ++index) {
948 *value <<= 8;
949 *value |= static_cast<uint8_t>(*pointer++);
950 }
951 return pointer;
952 }
953#endif
954
961 template<typename T>
962 void setNegative(T value) {
963 unsigned int length = sizeof(T);
964 for (; length > 1; --length) {
965 uint16_t word = value >> ((length - 2) << 3);
966 if ((word & 0xFF80) != 0xFF80) {
967 break;
968 }
969 }
970 _length = length;
971 }
972
979 template<typename T>
980 void setPositive(T value) {
981 unsigned int length = 0;
982 uint8_t carry = 0;
983 do {
984 carry = value & 0x80;
985 value >>= 8;
986 length++;
987 } while (value | carry);
988 _length = length;
989 }
990
996 const unsigned int getType() const {
997 return _type;
998 }
999
1005 const unsigned int getLength() const {
1006 return _length;
1007 }
1008
1021 virtual const unsigned int getSize(const bool refresh = false) {
1023 return _size;
1024 }
1025
1026protected:
1031
1038 BER* create(const Type &type);
1039};
1040
1056class BooleanBER: public BER {
1057public:
1063 BooleanBER(const bool value) :
1064 BER(Type::Boolean) {
1065 _length = LENGTH;
1066 _value = value;
1067 }
1068
1069#if SNMP_STREAM
1078 virtual void encode(Stream &stream) {
1079 BER::encode(stream);
1080 stream.write(_value ? 0xFF : 0x00);
1081 }
1082
1092 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1093 BER::decode(stream, flag);
1094 _value = stream.read();
1095 }
1096#else
1106 virtual uint8_t* encode(uint8_t *buffer) {
1107 uint8_t *pointer = BER::encode(buffer);
1108 *pointer = _value ? 0xFF : 0x00;
1109 return buffer + SIZE;
1110 }
1111
1121 virtual uint8_t* decode(uint8_t *buffer) {
1122 uint8_t *pointer = BER::decode(buffer);
1123 _value = *pointer++;
1124 return buffer + SIZE;
1125 }
1126#endif
1127
1133 const bool getValue() const {
1134 return _value;
1135 }
1136
1144 void setValue(const bool value) {
1145 _value = value;
1146 }
1147
1148private:
1150 static constexpr uint8_t LENGTH = 1;
1152 static constexpr uint8_t SIZE = 3;
1155};
1156
1178class IntegerBER: public BER {
1179public:
1185 IntegerBER(const int32_t value) :
1186 BER(Type::Integer) {
1187 setValue(value);
1188 }
1189
1190#if SNMP_STREAM
1199 virtual void encode(Stream &stream) {
1201 }
1202
1212 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1213 BER::decodeNumeric<int32_t>(&_value, stream, flag);
1214 }
1215
1216#else
1226 virtual uint8_t* encode(uint8_t *buffer) {
1227 return BER::encodeNumeric<int32_t>(_value, buffer);
1228 }
1229
1239 virtual uint8_t* decode(uint8_t *buffer) {
1240 return BER::decodeNumeric<int32_t>(&_value, buffer);
1241 }
1242#endif
1243
1249 const int32_t getValue() const {
1250 return _value;
1251 }
1252
1260 void setValue(const int32_t value) {
1261 _value = value;
1262 if (_value < 0) {
1263 BER::setNegative(value);
1264 } else {
1265 BER::setPositive(value);
1266 }
1267 }
1268
1269private:
1271 int32_t _value;
1272};
1273
1288class OctetStringBER: public BER {
1289public:
1300 OctetStringBER(const char *value) :
1301 OctetStringBER(value, strlen(value)) {
1302 }
1303
1315 OctetStringBER(const char *value, const uint32_t length);
1316
1323 free(_value);
1324 }
1325
1326#if SNMP_STREAM
1335 virtual void encode(Stream &stream) {
1336 BER::encode(stream);
1337 stream.write(_value, _length);
1338 }
1339
1349 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1350 BER::decode(stream, flag);
1351 allocate();
1352 stream.readBytes(_value, _length);
1353 }
1354#else
1364 virtual uint8_t* encode(uint8_t *buffer) {
1365 uint8_t *pointer = BER::encode(buffer);
1366 memcpy(pointer, _value, _length);
1367 return pointer + _length;
1368 }
1369
1379 virtual uint8_t* decode(uint8_t *buffer) {
1380 uint8_t *pointer = BER::decode(buffer);
1381 setValue(reinterpret_cast<const char*>(pointer), _length);
1382 return pointer + _length;
1383 }
1384#endif
1385
1391 const char* getValue() const {
1392 return _value;
1393 }
1394
1403 void setValue(const char *value, const unsigned int length) {
1404 _length = length;
1405 allocate();
1406 memcpy(_value, value, length);
1407 }
1408
1415 const bool getBit(const unsigned int index) const {
1416 const unsigned int byte = index / 8;
1417 const uint8_t bit = index % 8;
1418 return _value[byte] & (0x80 >> bit);
1419 }
1420
1421protected:
1423 char *_value;
1424
1430 OctetStringBER(const uint8_t type = Type::OctetString) :
1431 BER(type) {
1432 _value = nullptr;
1433 }
1434
1438 void allocate() {
1439 free(_value);
1440 _value = static_cast<char*>(malloc(_length + 1));
1441 _value[_length] = 0;
1442 }
1443};
1444
1460class NullBER: public BER {
1461public:
1467 NullBER(const uint8_t type = Type::Null) :
1468 BER(type) {
1469 }
1470};
1471
1488public:
1499 ObjectIdentifierBER(const char *value) :
1500 BER(Type::ObjectIdentifier) {
1501 setValue(value);
1502 }
1503
1504#if SNMP_STREAM
1513 virtual void encode(Stream &stream) {
1514 unsigned int index = 0;
1515 uint32_t subidentifier = 0;
1516 BER::encode(stream);
1517 char *token = const_cast<char*>(_value.c_str());
1518 while (token != NULL) {
1519 switch (index) {
1520 case 0:
1521 subidentifier = atoi(token);
1522 break;
1523 case 1:
1524 subidentifier = subidentifier * 40 + atoi(++token);
1525 stream.write(subidentifier);
1526 _size++;
1527 break;
1528 ;
1529 default: {
1530 subidentifier = atol(++token);
1531 uint32_t value = subidentifier;
1532 uint32_t length = 0;
1533 do {
1534 value >>= 7;
1535 length++;
1536 } while (value);
1537 Base::encode7bits(subidentifier, stream, length);
1538 _size += length;
1539 }
1540 break;
1541 }
1542 token = strchr(token, '.');
1543 index++;
1544 }
1545 }
1546
1556 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1557 unsigned int index = 0;
1558 uint32_t subidentifier = 0;
1559 BER::decode(stream, flag);
1560 unsigned int length = _length;
1561 _size += length;
1562 while (length) {
1563 if (index++) {
1564 subidentifier = 0;
1565 uint8_t byte;
1566 do {
1567 length--;
1568 byte = stream.read();
1569 subidentifier <<= 7;
1570 subidentifier += byte & 0x7F;
1571 } while (byte & 0x80);
1572 _value += "." + String(subidentifier);
1573 } else {
1574 length--;
1575 subidentifier = stream.read();
1576 _value = String(subidentifier / 40) + "." + String(subidentifier % 40);
1577 }
1578 }
1579 }
1580#else
1590 virtual uint8_t* encode(uint8_t *buffer) {
1591 unsigned int index = 0;
1592 uint32_t subidentifier = 0;
1593 uint8_t *pointer = BER::encode(buffer);
1594 char *token = const_cast<char*>(_value.c_str());
1595 while (token != NULL) {
1596 switch (index) {
1597 case 0:
1598 subidentifier = atoi(token);
1599 break;
1600 case 1:
1601 subidentifier = subidentifier * 40 + atoi(++token);
1602 *pointer = subidentifier;
1603 break;
1604 ;
1605 default: {
1606 subidentifier = atol(++token);
1607 uint32_t value = subidentifier;
1608 uint32_t length = 0;
1609 do {
1610 value >>= 7;
1611 length++;
1612 } while (value);
1613 Base::encode7bits(subidentifier, pointer, length);
1614 pointer += length;
1615 }
1616 break;
1617 }
1618 token = strchr(token, '.');
1619 index++;
1620 }
1621 return ++pointer;
1622 }
1623
1633 virtual uint8_t* decode(uint8_t *buffer) {
1634 unsigned int index = 0;
1635 uint32_t subidentifier = 0;
1636 uint8_t *pointer = BER::decode(buffer);
1637 uint8_t *end = pointer + _length;
1638 do {
1639 if (index++) {
1640 subidentifier = 0;
1641 do {
1642 subidentifier <<= 7;
1643 subidentifier += *pointer & 0x7F;
1644 } while (*pointer++ & 0x80);
1645 _value += "." + String(subidentifier);
1646 } else {
1647 subidentifier = *pointer++;
1648 _value = String(subidentifier / 40) + "."
1649 + String(subidentifier % 40);
1650 }
1651 } while (pointer < end);
1652 return pointer;
1653 }
1654#endif
1655
1661 const char* getValue() const {
1662 return _value.c_str();
1663 }
1664
1672 void setValue(const char *value) {
1673 _value = value;
1674 unsigned int index = 0;
1675 uint32_t subidentifier = 0;
1676 char *token = const_cast<char*>(_value.c_str());
1677 while (token != NULL) {
1678 switch (index) {
1679 case 0:
1680 subidentifier = atoi(token);
1681 break;
1682 case 1:
1683 subidentifier = subidentifier * 40 + atoi(++token);
1684 _length++;
1685 break;
1686 default: {
1687 subidentifier = atol(++token);
1688 do {
1689 subidentifier >>= 7;
1690 _length++;
1691 } while (subidentifier);
1692 }
1693 break;
1694 }
1695 token = strchr(token, '.');
1696 index++;
1697 }
1698 }
1699
1700private:
1702 String _value;
1703};
1704
1714template<const uint8_t U>
1715class ArrayBER: public BER {
1716public:
1722 ArrayBER(const uint8_t type) :
1723 BER(type) {
1724 }
1725
1732#if SNMP_VECTOR
1733 for (auto ber : _bers) {
1734 delete ber;
1735 }
1736 _bers.clear();
1737#else
1738 for (uint8_t index = 0; index < _count; ++index) {
1739 delete _bers[index];
1740 }
1741#endif
1742 }
1743
1744#if SNMP_STREAM
1753 virtual void encode(Stream &stream) {
1754 BER::encode(stream);
1755 for (uint8_t index = 0; index < _count; ++index) {
1756 _bers[index]->encode(stream);
1757 }
1758 }
1759
1776 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
1777 BER::decode(stream, flag);
1778 unsigned int length = _length;
1779 if (length) {
1780 Type type;
1781 _length = 0;
1782 do {
1783 type.decode(stream);
1784 BER *ber = create(type);
1785 if (ber) {
1786 ber->decode(stream, Flag::Typed);
1787 length -= ber->getSize();
1788 add(ber);
1789 }
1790 } while (length);
1791 }
1792 }
1793#else
1803 virtual uint8_t* encode(uint8_t *buffer) {
1804 uint8_t *pointer = BER::encode(buffer);
1805#if SNMP_VECTOR
1806 for (auto ber : _bers) {
1807 pointer = ber->encode(pointer);
1808 }
1809#else
1810 for (uint8_t index = 0; index < _count; ++index) {
1811 pointer = _bers[index]->encode(pointer);
1812 }
1813#endif
1814 return pointer;
1815 }
1816
1826 virtual uint8_t* decode(uint8_t *buffer) {
1827 uint8_t *pointer = BER::decode(buffer);
1828 if (_length) {
1829 uint8_t *end = pointer + _length;
1830 _length = 0;
1831 Type type;
1832 do {
1833 type.decode(pointer);
1834 BER *ber = create(type);
1835 if (ber) {
1836 pointer = ber->decode(pointer);
1837 add(ber);
1838 }
1839 } while (pointer < end);
1840 }
1841 return pointer;
1842 }
1843#endif
1844
1859 virtual const unsigned int getSize(const bool refresh = false) {
1860 if (refresh) {
1861 _length = 0;
1862 for (uint8_t index = 0; index < _count; ++index) {
1863 _length += _bers[index]->getSize(true);
1864 }
1865 }
1866 return BER::getSize();
1867 }
1868
1877 BER* operator [](const unsigned int index) {
1878 return _bers[index];
1879 }
1880
1886 const uint8_t count() const {
1887 return _count;
1888 }
1889
1890protected:
1899 BER* add(BER *ber) {
1900#if SNMP_VECTOR
1901 _bers.push_back(ber);
1902 _length += ber->getSize();
1903 _count++;
1904#else
1905 if (_count < U) {
1906 _bers[_count++] = ber;
1907 _length += ber->getSize();
1908 }
1909#endif
1910 return ber;
1911 }
1912
1918 void remove() {
1919#if SNMP_VECTOR
1920 if (_bers.size()) {
1921 _length -= _bers.back()->getSize();
1922 _bers.pop_back();
1923 --_count;
1924 }
1925#else
1926 if (_count) {
1927 _length -= _bers[--_count]->getSize();
1928 }
1929#endif
1930 }
1931
1932private:
1934 uint8_t _count = 0;
1935#if SNMP_VECTOR
1937 std::vector<BER*> _bers;
1938#else
1941#endif
1942
1943 friend class Message;
1944 friend class VarBind;
1945 friend class VarBindList;
1946};
1947
1952class SequenceBER: public ArrayBER<SNMP_CAPACITY> {
1953public:
1959 SequenceBER(const uint8_t type = Type::Sequence) :
1960 ArrayBER(type) {
1961 }
1962};
1963
1974class VarBind: public ArrayBER<2> {
1975public:
1982 VarBind(const char *oid, BER *value = nullptr) :
1983 ArrayBER(Type::Sequence) {
1984 add(new ObjectIdentifierBER(oid));
1985 if (value) {
1986 add(value);
1987 } else {
1988 add(new NullBER);
1989 }
1990 }
1991
1999 const char* getName() const {
2000 return static_cast<ObjectIdentifierBER*>(_bers[0])->getValue();
2001 }
2002
2010 BER* getValue() const {
2011 return _bers[1];
2012 }
2013};
2014
2023public:
2032 VarBind* operator [](const uint32_t index) {
2033 return static_cast<VarBind*>(_bers[index]);
2034 }
2035};
2036
2054public:
2062 IPAddressBER(IPAddress value) :
2063 OctetStringBER(Type::IPAddress) {
2064 _length = LENGTH;
2065 allocate();
2066 for (uint8_t index = 0; index < LENGTH; ++index) {
2067 _value[index] = value[index];
2068 }
2069 }
2070
2076 const uint8_t* getValue() {
2077 return reinterpret_cast<uint8_t*>(_value);
2078 }
2079
2080private:
2082 static constexpr uint8_t LENGTH = 4;
2083};
2084
2091template<class T>
2092class UIntegerBER: public BER {
2093protected:
2100 UIntegerBER(const T value, const uint8_t type) :
2101 BER(type) {
2102 setValue(value);
2103 }
2104
2105public:
2106#if SNMP_STREAM
2115 virtual void encode(Stream &stream) {
2117 }
2118
2128 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
2129 BER::decodeNumeric<T>(&_value, stream, flag);
2130 }
2131#else
2141 virtual uint8_t* encode(uint8_t *buffer) {
2142 return BER::encodeNumeric<T>(_value, buffer);
2143 }
2144
2154 virtual uint8_t* decode(uint8_t *buffer) {
2155 return BER::decodeNumeric<T>(&_value, buffer);
2156 }
2157#endif
2158
2164 const T getValue() const {
2165 return _value;
2166 }
2167
2175 void setValue(const T value) {
2176 _value = value;
2177 BER::setPositive<T>(value);
2178 }
2179
2180private:
2183};
2184
2200class Counter32BER: public UIntegerBER<uint32_t> {
2201public:
2207 Counter32BER(const uint32_t value) :
2208 UIntegerBER(value, Type::Counter32) {
2209 }
2210};
2211
2227class Counter64BER: public UIntegerBER<uint64_t> {
2228public:
2234 Counter64BER(const uint64_t value) :
2235 UIntegerBER(value, Type::Counter64) {
2236 }
2237};
2238
2254class Gauge32BER: public UIntegerBER<uint32_t> {
2255public:
2261 Gauge32BER(const uint32_t value) :
2262 UIntegerBER(value, Type::Gauge32) {
2263 }
2264};
2265
2283class TimeTicksBER: public UIntegerBER<uint32_t> {
2284public:
2290 TimeTicksBER(const uint32_t value) :
2291 UIntegerBER(value, Type::TimeTicks) {
2292 }
2293};
2294
2312class OpaqueBER: public BER {
2313public:
2320
2326 virtual ~OpaqueBER() {
2327 delete _ber;
2328 }
2329
2330#if SNMP_STREAM
2339 virtual void encode(Stream &stream) {
2340 BER::encode(stream);
2341 _ber->encode(stream);
2342 }
2343
2360 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
2361 BER::decode(stream, flag);
2362 uint32_t length = _length;
2363 if (length) {
2364 Type type;
2365 do {
2366 type.decode(stream);
2367 _ber = create(type);
2368 if (_ber) {
2369 _ber->decode(stream, Flag::Typed);
2370 length -= _ber->getSize();
2371 }
2372 } while (length);
2373 }
2374 }
2375#else
2385 virtual uint8_t* encode(uint8_t *buffer) {
2386 uint8_t *pointer = BER::encode(buffer);
2387 return _ber->encode(pointer);
2388 }
2389
2399 virtual uint8_t* decode(uint8_t *buffer) {
2400 uint8_t *pointer = BER::decode(buffer);
2401 uint8_t *end = pointer + _length;
2402 if (_length) {
2403 Type type;
2404 do {
2405 type.decode(pointer);
2406 _ber = create(type);
2407 if (_ber) {
2408 pointer = _ber->decode(pointer);
2409 }
2410 } while (pointer < end);
2411 }
2412 return pointer;
2413 }
2414#endif
2415
2430 virtual const unsigned int getSize(const bool refresh = false) {
2431 if (refresh) {
2432 _length = _ber->getSize(true);
2433 }
2434 return BER::getSize();
2435 }
2436
2443 return _ber;
2444 }
2445
2446private:
2449};
2450
2473class FloatBER: public BER {
2474public:
2481 FloatBER(const float value, const unsigned int type = Type::Float) :
2482 BER(type) {
2483 _length = LENGTH;
2484 setValue(value);
2485 }
2486
2487#if SNMP_STREAM
2496 virtual void encode(Stream &stream) {
2497 BER::encodeNumeric<uint32_t>(*(reinterpret_cast<uint32_t*>(&_value)), stream);
2498 }
2499
2509 virtual void decode(Stream &stream, const uint8_t flag = Flag::None) {
2510 BER::decodeNumeric<uint32_t>(reinterpret_cast<uint32_t*>(&_value), stream, flag);
2511 }
2512#else
2522 virtual uint8_t* encode(uint8_t *buffer) {
2524 *(reinterpret_cast<uint32_t*>(&_value)), buffer);
2525 }
2526
2536 virtual uint8_t* decode(uint8_t *buffer) {
2538 reinterpret_cast<uint32_t*>(&_value), buffer);
2539 }
2540#endif
2541
2547 const float getValue() const {
2548 return _value;
2549 }
2550
2556 void setValue(const float value) {
2557 _value = value;
2558 }
2559
2560protected:
2562 static constexpr uint8_t LENGTH = 4;
2564 float _value;
2565};
2566
2572public:
2577 NullBER(Type::NoSuchObject) {
2578 }
2579};
2580
2586public:
2591 NullBER(Type::NoSuchInstance) {
2592 }
2593};
2594
2600public:
2605 NullBER(Type::EndOfMIBView) {
2606 }
2607};
2608
2630public:
2636 OpaqueFloatBER(const float value) :
2637 FloatBER(value, Type::OpaqueFloat) {
2638 }
2639};
2640
2641} // namespace SNMP
2642
2643#endif /* BER_H_ */
Base class for BER array of BERs.
Definition BER.h:1715
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes ArrayBER from stream.
Definition BER.h:1776
void remove()
Removes the last BER in the array.
Definition BER.h:1918
BER * operator[](const unsigned int index)
Array subscript operator.
Definition BER.h:1877
const uint8_t count() const
Gets the count of BERs in the array.
Definition BER.h:1886
std::vector< BER * > _bers
Definition BER.h:1937
BER * add(BER *ber)
Adds a BER to the array.
Definition BER.h:1899
~ArrayBER()
ArrayBER destructor.
Definition BER.h:1731
uint8_t _count
Definition BER.h:1934
ArrayBER(const uint8_t type)
Creates an ArrayBER.
Definition BER.h:1722
virtual uint8_t * encode(uint8_t *buffer)
Encodes ArrayBER to memory buffer.
Definition BER.h:1803
virtual void encode(Stream &stream)
Encodes ArrayBER to stream.
Definition BER.h:1753
virtual uint8_t * decode(uint8_t *buffer)
Decodes ArrayBER from memory buffer.
Definition BER.h:1826
virtual const unsigned int getSize(const bool refresh=false)
Gets the size of the ArrayBER.
Definition BER.h:1859
BER object.
Definition BER.h:792
virtual void encode(Stream &stream)
Encodes BER type and length to stream.
Definition BER.h:819
virtual const unsigned int getSize(const bool refresh=false)
Gets the size of the BER.
Definition BER.h:1021
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes BER type and length from stream.
Definition BER.h:849
void decodeNumeric(T *value, Stream &stream, const uint8_t flag=Flag::None)
Decodes BER numeric value from stream.
Definition BER.h:867
const unsigned int getType() const
Gets the BER type.
Definition BER.h:996
uint8_t * encodeNumeric(T value, uint8_t *buffer)
Encodes BER numeric value to memory buffer.
Definition BER.h:905
void setNegative(T value)
Computes BER length of a negative integer.
Definition BER.h:962
uint8_t * decodeNumeric(T *value, uint8_t *buffer, const uint8_t flag=Flag::None)
Decodes BER numeric value from memory buffer.
Definition BER.h:939
Type _type
Definition BER.h:1030
virtual uint8_t * encode(uint8_t *buffer)
Encodes BER type and length to memory buffer.
Definition BER.h:888
virtual ~BER()
BER destructor.
Definition BER.h:808
BER * create(const Type &type)
Creates a BER of given type.
virtual uint8_t * decode(uint8_t *buffer)
Decodes BER type and length from memory buffer.
Definition BER.h:921
Length _length
Definition BER.h:1028
BER(const unsigned int type)
Creates a BER object.
Definition BER.h:799
const unsigned int getLength() const
Gets the BER length.
Definition BER.h:1005
void setPositive(T value)
Computes BER length of a positive integer.
Definition BER.h:980
void encodeNumeric(T value, Stream &stream)
Encodes BER numeric value to stream.
Definition BER.h:834
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
BER object to handle boolean.
Definition BER.h:1056
BooleanBER(const bool value)
Creates a BooleanBER object.
Definition BER.h:1063
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes BooleanBER from stream.
Definition BER.h:1092
virtual void encode(Stream &stream)
Encodes BooleanBER to stream.
Definition BER.h:1078
virtual uint8_t * decode(uint8_t *buffer)
Decodes BooleanBER from memory buffer.
Definition BER.h:1121
virtual uint8_t * encode(uint8_t *buffer)
Encodes BooleanBER to memory buffer.
Definition BER.h:1106
static constexpr uint8_t SIZE
Definition BER.h:1152
void setValue(const bool value)
Sets the BooleanBER value.
Definition BER.h:1144
const bool getValue() const
Gets the BooleanBER value.
Definition BER.h:1133
static constexpr uint8_t LENGTH
Definition BER.h:1150
BER object to handle 32-bit counter.
Definition BER.h:2200
Counter32BER(const uint32_t value)
Creates a Counter32BER object.
Definition BER.h:2207
BER object to handle 64-bit counter.
Definition BER.h:2227
Counter64BER(const uint64_t value)
Creates a Counter64BER object.
Definition BER.h:2234
BER object to handle endOfMIBView exception.
Definition BER.h:2599
EndOfMIBViewBER()
Creates a EndOfMIBViewBER object.
Definition BER.h:2604
Helper class for internal flag.
Definition BER.h:202
@ None
Definition BER.h:208
@ Typed
Definition BER.h:209
BER object to handle float.
Definition BER.h:2473
const float getValue() const
Gets the FloatBER value.
Definition BER.h:2547
FloatBER(const float value, const unsigned int type=Type::Float)
Creates a FloatBER object.
Definition BER.h:2481
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes FloatBER from stream.
Definition BER.h:2509
virtual void encode(Stream &stream)
Encodes FloatBER to stream.
Definition BER.h:2496
static constexpr uint8_t LENGTH
Definition BER.h:2562
float _value
Definition BER.h:2564
void setValue(const float value)
Sets the FloatBER value.
Definition BER.h:2556
virtual uint8_t * decode(uint8_t *buffer)
Decodes FloatBER from memory buffer.
Definition BER.h:2536
virtual uint8_t * encode(uint8_t *buffer)
Encodes FloatBER to memory buffer.
Definition BER.h:2522
BER object to handle 32-bit gauge.
Definition BER.h:2254
Gauge32BER(const uint32_t value)
Creates a Gauge32BER object.
Definition BER.h:2261
BER object to handle IP address.
Definition BER.h:2053
IPAddressBER(IPAddress value)
Creates an IPAddressBER object.
Definition BER.h:2062
const uint8_t * getValue()
Gets the IPAddressBER value.
Definition BER.h:2076
static constexpr uint8_t LENGTH
Definition BER.h:2082
BER object to handle integer.
Definition BER.h:1178
const int32_t getValue() const
Gets the IntegerBER value.
Definition BER.h:1249
int32_t _value
Definition BER.h:1271
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes IntegerBER from stream.
Definition BER.h:1212
virtual void encode(Stream &stream)
Encodes IntegerBER to stream.
Definition BER.h:1199
virtual uint8_t * decode(uint8_t *buffer)
Decodes IntegerBER from memory buffer.
Definition BER.h:1239
IntegerBER(const int32_t value)
Creates an IntegerBER object.
Definition BER.h:1185
virtual uint8_t * encode(uint8_t *buffer)
Encodes IntegerBER to memory buffer.
Definition BER.h:1226
void setValue(const int32_t value)
Sets the IntegerBER value.
Definition BER.h:1260
Length of a BER object.
Definition BER.h:549
Length & operator+=(const unsigned int length)
Addition operator.
Definition BER.h:699
void setLength(unsigned int length)
Sets length from integer.
Definition BER.h:768
Length & operator-=(const unsigned int length)
Subtraction operator.
Definition BER.h:717
uint8_t * encode(uint8_t *buffer)
Encodes BER length to memory buffer.
Definition BER.h:615
void decode(Stream &stream)
Decodes BER length from stream.
Definition BER.h:589
unsigned int _length
Definition BER.h:759
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:681
Length & operator++()
Prefix increment operator.
Definition BER.h:734
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
SNMP message object.
BER object to handle noSuchInstance exception.
Definition BER.h:2585
NoSuchInstanceBER()
Creates a NoSuchInstanceBER object.
Definition BER.h:2590
BER object to handle noSuchObject exception.
Definition BER.h:2571
NoSuchObjectBER()
Creates a NoSuchObjectBER object.
Definition BER.h:2576
BER object to handle null.
Definition BER.h:1460
NullBER(const uint8_t type=Type::Null)
Creates a NullBER object.
Definition BER.h:1467
BER object to handle OID.
Definition BER.h:1487
virtual uint8_t * encode(uint8_t *buffer)
Encodes ObjectIdentifierBER to memory buffer.
Definition BER.h:1590
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes ObjectIdentifierBER from stream.
Definition BER.h:1556
void setValue(const char *value)
Set the ObjectIdentifierBER value.
Definition BER.h:1672
const char * getValue() const
Gets the ObjectIdentifierBER value.
Definition BER.h:1661
virtual void encode(Stream &stream)
Encodes ObjectIdentifierBER to stream.
Definition BER.h:1513
virtual uint8_t * decode(uint8_t *buffer)
Decodes ObjectIdentifierBER from memory buffer.
Definition BER.h:1633
ObjectIdentifierBER(const char *value)
Creates an ObjectIdentifierBER object.
Definition BER.h:1499
BER object to handle octet string.
Definition BER.h:1288
OctetStringBER(const char *value)
Creates an OctetStringBER object.
Definition BER.h:1300
virtual uint8_t * decode(uint8_t *buffer)
Decodes OctetStringBER from memory buffer.
Definition BER.h:1379
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes OctetStringBER from stream.
Definition BER.h:1349
OctetStringBER(const uint8_t type=Type::OctetString)
Creates an empty OctetStringBER object.
Definition BER.h:1430
OctetStringBER(const char *value, const uint32_t length)
Creates an OctetStringBER object.
virtual uint8_t * encode(uint8_t *buffer)
Encodes OctetStringBER to memory buffer.
Definition BER.h:1364
const char * getValue() const
Gets the OctetStringBER value.
Definition BER.h:1391
const bool getBit(const unsigned int index) const
Gets bit at a given index in the OctetStringBER value.
Definition BER.h:1415
void allocate()
Allocates the char array.
Definition BER.h:1438
void setValue(const char *value, const unsigned int length)
Sets the OctetStringBER value.
Definition BER.h:1403
virtual ~OctetStringBER()
OctetStringBER destructor.
Definition BER.h:1322
virtual void encode(Stream &stream)
Encodes OctetStringBER to stream.
Definition BER.h:1335
BER object to handle embedded BER object.
Definition BER.h:2312
virtual uint8_t * decode(uint8_t *buffer)
Decodes OpaqueBER from memory buffer.
Definition BER.h:2399
virtual const unsigned int getSize(const bool refresh=false)
Gets the size of the OpaqueBER.
Definition BER.h:2430
OpaqueBER(BER *ber)
Creates an OpaqueBER.
BER * _ber
Definition BER.h:2448
BER * getBER()
Gets the embedded BER.
Definition BER.h:2442
virtual ~OpaqueBER()
OpaqueBER destructor.
Definition BER.h:2326
virtual void encode(Stream &stream)
Encodes OpaqueBER to stream.
Definition BER.h:2339
virtual uint8_t * encode(uint8_t *buffer)
Encodes OpaqueBER to memory buffer.
Definition BER.h:2385
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes OpaqueBER from stream.
Definition BER.h:2360
BER object to handle float.
Definition BER.h:2629
OpaqueFloatBER(const float value)
Creates an OpaqueFloatBER object.
Definition BER.h:2636
BER object to handle sequence of BER objects.
Definition BER.h:1952
SequenceBER(const uint8_t type=Type::Sequence)
Creates a SequenceBER.
Definition BER.h:1959
BER object to handle time.
Definition BER.h:2283
TimeTicksBER(const uint32_t value)
Creates a TimeTicksBER object.
Definition BER.h:2290
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
@ 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
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
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
Base class for unsigned integer BER.
Definition BER.h:2092
virtual uint8_t * decode(uint8_t *buffer)
Decodes UIntegerBER from memory buffer.
Definition BER.h:2154
void setValue(const T value)
Sets the UIntegerBER value.
Definition BER.h:2175
const T getValue() const
Gets the UIntegerBER value.
Definition BER.h:2164
virtual void decode(Stream &stream, const uint8_t flag=Flag::None)
Decodes UIntegerBER from stream.
Definition BER.h:2128
virtual uint8_t * encode(uint8_t *buffer)
Encodes UIntegerBER to memory buffer.
Definition BER.h:2141
UIntegerBER(const T value, const uint8_t type)
Creates an UIntegerBER.
Definition BER.h:2100
virtual void encode(Stream &stream)
Encodes UIntegerBER to stream.
Definition BER.h:2115
BER object to handle variable binding.
Definition BER.h:1974
BER * getValue() const
Gets variable binding value.
Definition BER.h:2010
VarBind(const char *oid, BER *value=nullptr)
Creates a VarBind.
Definition BER.h:1982
const char * getName() const
Gets variable binding name.
Definition BER.h:1999
BER object to handle a list of variable bindings.
Definition BER.h:2022
VarBind * operator[](const uint32_t index)
Array subscript operator.
Definition BER.h:2032
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
Helper struct to handle SNMP error.
Definition BER.h:72
@ 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
uint8_t _index
Definition BER.h:114
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
Helper struct to handle trap PDU.
Definition BER.h:123
IPAddress _agentAddr
Definition BER.h:155
uint32_t _timeStamp
Definition BER.h:161
Trap()
Initializes to default values.
Definition BER.h:145
@ 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
uint8_t _genericTrap
Definition BER.h:157
const char * _enterprise
Definition BER.h:153
uint8_t _specificTrap
Definition BER.h:159
Helper struct to handle SNMP versions.
Definition BER.h:51