summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorelie <elie>2015-09-19 13:46:22 +0000
committerelie <elie>2015-09-19 13:46:22 +0000
commitb257c84d44e1be5b114cc8a812ca0ab5773e57b2 (patch)
tree21ce8b7d7efdfc959b4fa336802b9fcbb0707203
parent851e80ae0e04a05c40755d2f5a95d3571f71d64b (diff)
downloadpysnmp-b257c84d44e1be5b114cc8a812ca0ab5773e57b2.tar.gz
- Constraints assignment shortcut added to some base rfc1902 types (Integer,
Integer32, OctetString, Bits). That formally constitutes ASN.1 sub-typing. - Base SNMP types documented
-rw-r--r--CHANGES.txt2
-rw-r--r--docs/source/docs/snmp-data-types.rst75
-rw-r--r--pysnmp/proto/rfc1902.py463
3 files changed, 503 insertions, 37 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 69211b4..e50a2a6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -64,6 +64,8 @@ Revision 4.3.0, work in progress
SnmpEngine what makes them reusable with many SnmpEngine class instances.
- Oneliner GETBULK Command Generator now strips possible excessive OIDs
off the bottom of returned var-binds table.
+- Constraints assignment shortcut added to some base rfc1902 types (Integer,
+ Integer32, OctetString, Bits). That formally constitutes ASN.1 sub-typing.
- Built-in debugging is now based on Python logging module.
- Example on a single Transport Dispatcher use with multiple SnmpEngine's
in oneliner AsyncCommandGenerator & AsyncNotificationOriginator based
diff --git a/docs/source/docs/snmp-data-types.rst b/docs/source/docs/snmp-data-types.rst
index 63d2f1a..caa14a3 100644
--- a/docs/source/docs/snmp-data-types.rst
+++ b/docs/source/docs/snmp-data-types.rst
@@ -5,12 +5,81 @@ SNMP data types
SNMP represents real-world objects it serves along with their
states in form of values. Those values each belong to one
of SNMP types (:RFC:`1902#section-2`) which, in turn, are based
-on *ASN.1* data description language. PySNMP types are derived
-from `Python ASN.1 types <http://pyasn1.sf.net>`_ implementation.
+on `ASN.1 <https://en.wikipedia.org/wiki/Abstract_Syntax_Notation_One>`_
+data description language. PySNMP types are derived from
+`Python ASN.1 types <http://pyasn1.sf.net>`_ implementation.
.. toctree::
:maxdepth: 2
-.. autoclass:: pysnmp.proto.rfc1902.Integer(initializer)
+.. _integer32:
+
+Integer32 type
+--------------
+
.. autoclass:: pysnmp.proto.rfc1902.Integer32(initializer)
+ :members:
+
+.. _integer:
+
+Integer type
+------------
+
+.. autoclass:: pysnmp.proto.rfc1902.Integer(initializer)
+ :members:
+
+.. _octetstring:
+
+OctetString type
+----------------
+
+.. autoclass:: pysnmp.proto.rfc1902.OctetString(strValue=None, hexValue=None)
+ :members:
+
+.. _ipaddress:
+
+IpAddress type
+----------------
+
+.. autoclass:: pysnmp.proto.rfc1902.IpAddress(strValue=None, hexValue=None)
+
+ObjectIdentifier type
+---------------------
+
+.. autoclass:: pysnmp.proto.rfc1902.ObjectIdentifier(initializer)
+
+Counter32 type
+--------------
+
+.. autoclass:: pysnmp.proto.rfc1902.Counter32(initializer)
+
+Gauge32 type
+------------
+
+.. autoclass:: pysnmp.proto.rfc1902.Gauge32(initializer)
+
+Unsigned32 type
+---------------
+
+.. autoclass:: pysnmp.proto.rfc1902.Unsigned32(initializer)
+
+TimeTicks type
+--------------
+
+.. autoclass:: pysnmp.proto.rfc1902.TimeTicks(initializer)
+
+Opaque type
+-----------
+
+.. autoclass:: pysnmp.proto.rfc1902.Opaque(initializer)
+
+Counter64 type
+--------------
+
+.. autoclass:: pysnmp.proto.rfc1902.Counter64(initializer)
+
+Bits type
+---------
+.. autoclass:: pysnmp.proto.rfc1902.Bits(initializer)
+ :members:
diff --git a/pysnmp/proto/rfc1902.py b/pysnmp/proto/rfc1902.py
index 4e0f41d..b284140 100644
--- a/pysnmp/proto/rfc1902.py
+++ b/pysnmp/proto/rfc1902.py
@@ -1,13 +1,77 @@
from pyasn1.type import univ, tag, constraint, namedtype, namedval
from pysnmp.proto import rfc1155, error
-class Integer(univ.Integer):
+class Integer32(univ.Integer):
+ """Creates an instance of SNMP Integer32 class.
+
+ :py:class:`~pysnmp.proto.rfc1902.Integer32` type represents
+ integer-valued information between -2147483648 to 2147483647
+ inclusive (:RFC:`1902#section-7.1.1`). This type is indistinguishable
+ from the :py:class:`~pysnmp.proto.rfc1902.Integer` type.
+ The :py:class:`~pysnmp.proto.rfc1902.Integer32` type may be sub-typed
+ to be more constrained than the base
+ :py:class:`~pysnmp.proto.rfc1902.Integer32` type.
+
+ Parameters
+ ----------
+ initializer : int
+ Python integer in range between -2147483648 to 2147483647 inclusive
+ or :py:class:`~pysnmp.proto.rfc1902.Integer32`.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> Integer32(1234)
+ Integer32(1234)
+ >>> Integer32(1) > 2
+ True
+ >>> Integer32(1) + 1
+ Integer32(2)
+ >>> int(Integer32(321))
+ 321
+ >>> SmallInteger = Integer32.withRange(1,3)
+ >>> SmallInteger(1)
+ Integer32(1)
+ >>> DiscreetInteger = Integer32.withValues(4, 8, 1)
+ >>> DiscreetInteger(4)
+ Integer32(4)
+ >>>
+
+ """
+ subtypeSpec = univ.Integer.subtypeSpec+constraint.ValueRangeConstraint(
+ -2147483648, 2147483647
+ )
+
+ @classmethod
+ def withValues(cls, *values):
+ """Creates a subclass with discreet values constraint.
+ """
+ class X(cls):
+ subtypeSpec = cls.subtypeSpec + constraint.SingleValueConstraint(*values)
+ X.__name__ = cls.__name__
+ return X
+
+ @classmethod
+ def withRange(cls, minimum, maximum):
+ """Creates a subclass with value range constraint.
+ """
+ class X(cls):
+ subtypeSpec = cls.subtypeSpec + constraint.ValueRangeConstraint(minimum, maximum)
+ X.__name__ = cls.__name__
+ return X
+
+class Integer(Integer32):
"""Creates an instance of SNMP INTEGER class.
- The :py:class:`~pysnmp.proto.rfc1902.Integer` type used to represent
+ The :py:class:`~pysnmp.proto.rfc1902.Integer` type represents
integer-valued information as named-number enumerations
- (:RFC:`1902#section-7.1.1`). This type is indistinguishable from the
- :py:class:`~pysnmp.proto.rfc1902.Integer32` type.
+ (:RFC:`1902#section-7.1.1`). This type inherits and is indistinguishable
+ from :py:class:`~pysnmp.proto.rfc1902.Integer32` class.
The :py:class:`~pysnmp.proto.rfc1902.Integer` type may be sub-typed
to be more constrained than the base
:py:class:`~pysnmp.proto.rfc1902.Integer` type.
@@ -15,14 +79,15 @@ class Integer(univ.Integer):
Parameters
----------
initializer : int
- Python integer in range between -2147483648 to 2147483647 inclusive.
+ Python integer in range between -2147483648 to 2147483647 inclusive
+ or :py:class:`~pysnmp.proto.rfc1902.Integer` class instance.
In case of named-numbered enumerations, initialization is also
possible by enumerated literal.
Raises
------
PyAsn1Error :
- On bad initilizer.
+ On constraint violation or bad initializer.
Examples
--------
@@ -33,54 +98,69 @@ class Integer(univ.Integer):
True
>>> Integer(1) + 1
Integer(2)
+ >>> int(Integer(321))
+ 321
+ >>> SomeState = Integer.withNamedValues(enable=1, disable=0)
+ >>> SomeState(1)
+ Integer('enable')
+ >>> int(SomeState('disable'))
+ 0
>>>
"""
- subtypeSpec = univ.Integer.subtypeSpec+constraint.ValueRangeConstraint(
- -2147483648, 2147483647
- )
+ @classmethod
+ def withNamedValues(cls, **values):
+ """Creates a subclass with discreet named values constraint.
+ """
+ class X(cls):
+ namedValues = cls.namedValues + namedval.NamedValues(*values.items())
+ subtypeSpec = cls.subtypeSpec + constraint.SingleValueConstraint(*values.values())
+ X.__name__ = cls.__name__
+ return X
-class Integer32(univ.Integer):
- """Creates an instance of SNMP Integer32 class.
+class OctetString(univ.OctetString):
+ """Creates an instance of SNMP OCTET STRING class.
- :py:class:`~pysnmp.proto.rfc1902.Integer32` type represents
- integer-valued information between -2147483648 to 2147483647
- inclusive (:RFC:`1902#section-7.1.1`). This type is indistinguishable
- from the :py:class:`~pysnmp.proto.rfc1902.Integer` type.
- The :py:class:`~pysnmp.proto.rfc1902.Integer32` type may be sub-typed
- to be more constrained than the base
- :py:class:`~pysnmp.proto.rfc1902.Integer32` type.
+ The :py:class:`~pysnmp.proto.rfc1902.OctetString` type represents
+ arbitrary binary or text data (:RFC:`1902#section-7.1.2`).
+ It may be sub-typed to be constrained in size.
Parameters
----------
- initializer : int
- Python integer in range between -2147483648 to 2147483647 inclusive.
+ strValue : str
+ Python string or :py:class:`~pysnmp.proto.rfc1902.OctetString`
+ class instance.
+
+ Other parameters
+ ----------------
+ hexValue : str
+ Python string representing octets in a hexadecimal notation
+ (e.g. DEADBEEF).
Raises
------
PyAsn1Error :
- On bad initilizer.
+ On constraint violation or bad initializer.
Examples
--------
>>> from pysnmp.proto.rfc1902 import *
- >>> Integer32(1234)
- Integer32(1234)
- >>> Integer32(1) > 2
- True
- >>> Integer32(1) + 1
- Integer32(2)
+ >>> OctetString('some apples')
+ OctetString('some apples')
+ >>> OctetString('some apples') + ' and oranges'
+ OctetString('some apples and oranges')
+ >>> str(OctetString('some apples'))
+ 'some apples'
+ >>> SomeString = OctetString.withSize(3, 12)
+ >>> str(SomeString(hexValue='deadbeef'))
+ '\xde\xad\xbe\xef'
>>>
"""
- subtypeSpec = univ.Integer.subtypeSpec+constraint.ValueRangeConstraint(
- -2147483648, 2147483647
- )
-
-class OctetString(univ.OctetString):
- subtypeSpec = univ.Integer.subtypeSpec+constraint.ValueSizeConstraint(
+ subtypeSpec = univ.OctetString.subtypeSpec+constraint.ValueSizeConstraint(
0, 65535
)
+
# rfc1902 uses a notion of "fixed length string" what might mean
# having zero-range size constraint applied. The following is
# supposed to be used for setting and querying this property.
@@ -109,9 +189,79 @@ class OctetString(univ.OctetString):
self, value, implicitTag, explicitTag, subtypeSpec
).setFixedLength(self.getFixedLength())
-ObjectIdentifier = univ.ObjectIdentifier
+ @classmethod
+ def withSize(cls, minimum, maximum):
+ """Creates a subclass with value size constraint.
+ """
+ class X(cls):
+ subtypeSpec = cls.subtypeSpec + constraint.ValueSizeConstraint(minimum, maximum)
+ X.__name__ = cls.__name__
+ return X
+
+class ObjectIdentifier(univ.ObjectIdentifier):
+ """Creates an instance of SNMP OBJECT IDENTIFIER class.
+
+ The :py:class:`~pysnmp.proto.rfc1902.ObjectIdentifier` type represents
+ administratively assigned names (:RFC:`1902#section-7.1.3`).
+ Supports sequence protocol where elements are integer sub-identifiers.
+
+ Parameters
+ ----------
+ initializer: tuple, str
+ Python tuple of up to 128 integers in range between 0 to 4294967295
+ inclusive or Python string containing OID in "dotted" form or
+ :py:class:`~pysnmp.proto.rfc1902.ObjectIdentifier`.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> ObjectIdentifier((1, 3, 6))
+ ObjectIdentifier('1.3.6')
+ >>> ObjectIdentifier('1.3.6')
+ ObjectIdentifier('1.3.6')
+ >>> tuple(ObjectIdentifier('1.3.6'))
+ (1, 3, 6)
+ >>> str(ObjectIdentifier('1.3.6'))
+ '1.3.6'
+ >>>
+
+ """
class IpAddress(OctetString):
+ """Creates an instance of SNMP IpAddress class.
+
+ The :py:class:`~pysnmp.proto.rfc1902.IpAddress` class represents
+ a 32-bit internet address as an OCTET STRING of length 4, in network
+ byte-order (:RFC:`1902#section-7.1.5`).
+
+ Parameters
+ ----------
+ strValue : str
+ The same as :py:class:`~pysnmp.proto.rfc1902.OctetString`,
+ additionally IPv4 address in dotted notation ('127.0.0.1').
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> IpAddress('127.0.0.1')
+ IpAddress(hexValue='7f000001')
+ >>> str(IpAddress(hexValue='7f000001'))
+ '\x7f\x00\x00\x01'
+ >>> IpAddress('\x7f\x00\x00\x01')
+ IpAddress(hexValue='7f000001')
+ >>>
+
+ """
tagSet = OctetString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x00)
)
@@ -140,6 +290,36 @@ class IpAddress(OctetString):
return ''
class Counter32(univ.Integer):
+ """Creates an instance of SNMP Counter32 class.
+
+ :py:class:`~pysnmp.proto.rfc1902.Counter32` type represents
+ a non-negative integer which monotonically increases until it
+ reaches a maximum value of 4294967295, when it wraps around and
+ starts increasing again from zero (:RFC:`1902#section-7.1.6`).
+
+ Parameters
+ ----------
+ initializer : int
+ Python integer in range between 0 to 4294967295 inclusive
+ or any :py:class:`~pysnmp.proto.rfc1902.Integer`-based class.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> Counter32(1234)
+ Counter32(1234)
+ >>> Counter32(1) + 1
+ Counter32(2)
+ >>> int(Counter32(321))
+ 321
+ >>>
+
+ """
tagSet = univ.Integer.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x01)
)
@@ -148,6 +328,36 @@ class Counter32(univ.Integer):
)
class Gauge32(univ.Integer):
+ """Creates an instance of SNMP Gauge32 class.
+
+ :py:class:`~pysnmp.proto.rfc1902.Gauge32` type represents
+ a non-negative integer, which may increase or decrease, but shall
+ never exceed a maximum value. The maximum value can not be greater
+ than 4294967295 (:RFC:`1902#section-7.1.7`).
+
+ Parameters
+ ----------
+ initializer : int
+ Python integer in range between 0 to 4294967295 inclusive
+ or any :py:class:`~pysnmp.proto.rfc1902.Integer`-based class.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> Gauge32(1234)
+ Gauge32(1234)
+ >>> Gauge32(1) + 1
+ Gauge32(2)
+ >>> int(Gauge32(321))
+ 321
+ >>>
+
+ """
tagSet = univ.Integer.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x02)
)
@@ -156,6 +366,35 @@ class Gauge32(univ.Integer):
)
class Unsigned32(univ.Integer):
+ """Creates an instance of SNMP Unsigned32 class.
+
+ :py:class:`~pysnmp.proto.rfc1902.Unsigned32` type represents
+ integer-valued information between 0 and 4294967295
+ (:RFC:`1902#section-7.1.11`).
+
+ Parameters
+ ----------
+ initializer : int
+ Python integer in range between 0 to 4294967295 inclusive
+ or any :py:class:`~pysnmp.proto.rfc1902.Integer`-based class.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> Unsigned32(1234)
+ Unsigned32(1234)
+ >>> Unsigned32(1) + 1
+ Unsigned32(2)
+ >>> int(Unsigned32(321))
+ 321
+ >>>
+
+ """
tagSet = univ.Integer.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x02)
)
@@ -164,6 +403,35 @@ class Unsigned32(univ.Integer):
)
class TimeTicks(univ.Integer):
+ """Creates an instance of SNMP TimeTicks class.
+
+ :py:class:`~pysnmp.proto.rfc1902.TimeTicks` type represents
+ a non-negative integer which represents the time, modulo 4294967296,
+ in hundredths of a second between two epochs (:RFC:`1902#section-7.1.8`).
+
+ Parameters
+ ----------
+ initializer : int
+ Python integer in range between 0 to 4294967295 inclusive
+ or any :py:class:`~pysnmp.proto.rfc1902.Integer`-based class.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> TimeTicks(1234)
+ TimeTicks(1234)
+ >>> TimeTicks(1) + 1
+ TimeTicks(2)
+ >>> int(TimeTicks(321))
+ 321
+ >>>
+
+ """
tagSet = univ.Integer.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x03)
)
@@ -172,11 +440,80 @@ class TimeTicks(univ.Integer):
)
class Opaque(univ.OctetString):
+ """Creates an instance of SNMP Opaque class.
+
+ The :py:class:`~pysnmp.proto.rfc1902.Opaque` type supports the
+ capability to pass arbitrary ASN.1 syntax. A value is encoded
+ using the ASN.1 BER into a string of octets. This, in turn, is
+ encoded as an OCTET STRING, in effect "double-wrapping" the original
+ ASN.1 value (:RFC:`1902#section-7.1.9`).
+
+ Parameters
+ ----------
+ strValue : str
+ Python string or :py:class:`~pysnmp.proto.rfc1902.OctetString`-based
+ class instance.
+
+ Other parameters
+ ----------------
+ hexValue : str
+ Python string representing octets in a hexadecimal notation
+ (e.g. DEADBEEF).
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> Opaque('some apples')
+ Opaque('some apples')
+ >>> Opaque('some apples') + ' and oranges'
+ Opaque('some apples and oranges')
+ >>> str(Opaque('some apples'))
+ 'some apples'
+ >>> str(Opaque(hexValue='deadbeef'))
+ '\xde\xad\xbe\xef'
+ >>>
+
+ """
tagSet = univ.OctetString.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x04)
)
class Counter64(univ.Integer):
+ """Creates an instance of SNMP Counter64 class.
+
+ :py:class:`~pysnmp.proto.rfc1902.Counter64` type represents
+ a non-negative integer which monotonically increases until it reaches
+ a maximum value of 18446744073709551615, when it wraps around and starts
+ increasing again from zero (:RFC:`1902#section-7.1.10`).
+
+ Parameters
+ ----------
+ initializer : int
+ Python integer in range between 0 to 4294967295 inclusive
+ or any :py:class:`~pysnmp.proto.rfc1902.Integer`-based class.
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> Counter64(1234)
+ Counter64(1234)
+ >>> Counter64(1) + 1
+ Counter64(2)
+ >>> int(Counter64(321))
+ 321
+ >>>
+
+ """
tagSet = univ.Integer.tagSet.tagImplicitly(
tag.Tag(tag.tagClassApplication, tag.tagFormatSimple, 0x06)
)
@@ -185,6 +522,54 @@ class Counter64(univ.Integer):
)
class Bits(OctetString):
+ """Creates an instance of SNMP BITS class.
+
+ The :py:class:`~pysnmp.proto.rfc1902.Bits` type represents
+ an enumeration of named bits. This collection is assigned non-negative,
+ contiguous values, starting at zero. Only those named-bits so enumerated
+ may be present in a value (:RFC:`1902#section-7.1.4`).
+
+ The bits are named and identified by their position in the octet string.
+ Position zero is the high order (or left-most) bit in the first octet of
+ the string. Position 7 is the low order (or right-most) bit of the first
+ octet of the string. Position 8 is the high order bit in the second octet
+ of the string, and so on
+ (`BITS Pseudotype <https://tools.ietf.org/html/draft-perkins-bits-00>`_).
+
+ Parameters
+ ----------
+ strValue : str, tuple
+ Sequence of bit names or a Python string (as a raw data) or
+ :py:class:`~pysnmp.proto.rfc1902.OctetString` class instance.
+
+ Other parameters
+ ----------------
+ hexValue : str
+ Python string representing octets in a hexadecimal notation
+ (e.g. DEADBEEF).
+
+ Raises
+ ------
+ PyAsn1Error :
+ On constraint violation or bad initializer.
+
+ Examples
+ --------
+ >>> from pysnmp.proto.rfc1902 import *
+ >>> SomeBits = Bits.withNamedBits(apple=0, orange=1, peach=2)
+ >>> SomeBits(('apple', 'orange')).prettyPrint()
+ 'apple, orange'
+ >>> SomeBits(('apple', 'orange'))
+ Bits(hexValue='c0')
+ >>> SomeBits('\x80')
+ Bits(hexValue='80')
+ >>> SomeBits(hexValue='80')
+ Bits(hexValue='80')
+ >>> SomeBits(hexValue='80').prettyPrint()
+ 'apple'
+ >>>
+
+ """
namedValues = namedval.NamedValues()
def __init__(self, value=None, tagSet=None, subtypeSpec=None,
encoding=None, binValue=None, hexValue=None,
@@ -268,6 +653,16 @@ class Bits(OctetString):
return self.__class__(value, tagSet, subtypeSpec,
namedValues=namedValues)
+ @classmethod
+ def withNamedBits(cls, **values):
+ """Creates a subclass with discreet named bits constraint.
+ """
+ class X(cls):
+ namedValues = cls.namedValues + namedval.NamedValues(*values.items())
+ X.__name__ = cls.__name__
+ return X
+
+
class ObjectName(univ.ObjectIdentifier): pass
class SimpleSyntax(rfc1155.TypeCoercionHackMixIn, univ.Choice):