summaryrefslogtreecommitdiff
path: root/pysnmp/proto
diff options
context:
space:
mode:
authorEugene M. Kim <astralblue@gmail.com>2017-10-09 04:10:49 -0700
committerIlya Etingof <etingof@gmail.com>2017-10-09 13:10:49 +0200
commit1d5af2afc0b79fd7ed5b7ea9e564932c9adfdaac (patch)
tree840a8ce658f8d1ae17234470f93b4f086262f48e /pysnmp/proto
parentc383f2de5bbdbbd64f880726d7f9a6a55855c82a (diff)
downloadpysnmp-git-1d5af2afc0b79fd7ed5b7ea9e564932c9adfdaac.tar.gz
Render NetworkAddress indices (#87)
* Add OID-index roundtrip methods to NetworkAddress This enables use of NetworkAddress as a table index. * Use NetworkAddress for RFC1213-MIB::atNetAddress Previously atNetAddress defined to be an IpAddress, whose table index mapping was different from that of NetworkAddress. This prevented proper use of RFC1213-MIB::atTable instances, because: - OID-to-symbol resolution was failing; - Symbol-to-OID mapping result was invalid. * Move clone() from Choice to NetworkAddress Previously it was implemented in pyasn1.type.univ.Choice in case there may be more Choice-based types—such as NetworkAddress—used as a table index. However, SMIv2 (RFC 2578) limits the SYNTAX of an OBJECT-TYPE to be only PyASN1 “simple” types, and NetworkAddress is the only known Choice-based type used as a table index in MIB-I, so there is little reason to clutter PyASN1 with the one-off logic in anticipation of something will probably never happen. Having NetworkAddress's own clone() method also allows use of string literals as the value, so the following invocations are all valid: na = NetworkAddress() na1234 = na.clone('1.2.3.4') na1234_2 = na1234.clone() na1234_3 = na.clone(na1234) na4321 = na.clone(IpAddress('4.3.2.1')) To elaborate on simple types, SMIv2 limits the object syntax to be: - a base type (or its refinement) - a textual convention (or its refinement); or - a BITS pseudo-type. All base types descend from ASN.1 integer, octet string, or OID, all of which are simple types. PySNMP defines SMIv2 BITS as a subclass of OctetString, which is again a simple type. Finally, a SMIv2 textual convention (RFC 2579) is simply a syntactic sugar applied on top of either a base type a BITS type, so it is a simple type.
Diffstat (limited to 'pysnmp/proto')
-rw-r--r--pysnmp/proto/rfc1155.py51
1 files changed, 51 insertions, 0 deletions
diff --git a/pysnmp/proto/rfc1155.py b/pysnmp/proto/rfc1155.py
index fb7e76ae..35f6110b 100644
--- a/pysnmp/proto/rfc1155.py
+++ b/pysnmp/proto/rfc1155.py
@@ -51,6 +51,57 @@ class NetworkAddress(univ.Choice):
namedtype.NamedType('internet', IpAddress())
)
+ def clone(self, value=univ.noValue, **kwargs):
+ """Clone this instance.
+
+ If *value* is specified, use its tag as the component type selector,
+ and itself as the component value.
+
+ :param value: (Optional) the component value.
+ :type value: :py:obj:`pyasn1.type.base.Asn1ItemBase`
+ :return: the cloned instance.
+ :rtype: :py:obj:`pysnmp.proto.rfc1155.NetworkAddress`
+ :raise: :py:obj:`pysnmp.smi.error.SmiError`:
+ if the type of *value* is not allowed for this Choice instance.
+ """
+ cloned = univ.Choice.clone(self, **kwargs)
+ if value is not univ.noValue:
+ # IpAddress is the only supported type, perhaps forever because
+ # this is SNMPv1.
+ if not isinstance(value, IpAddress):
+ value = IpAddress(value)
+ try:
+ tagSet = value.tagSet
+ except AttributeError:
+ raise PyAsn1Error('component value %r has no tag set' % (value,))
+ cloned.setComponentByType(tagSet, value)
+ return cloned
+
+ # RFC 1212, section 4.1.6:
+ #
+ # "(5) NetworkAddress-valued: `n+1' sub-identifiers, where `n'
+ # depends on the kind of address being encoded (the first
+ # sub-identifier indicates the kind of address, value 1
+ # indicates an IpAddress);"
+
+ def cloneFromName(self, value, impliedFlag, parentRow, parentIndices):
+ kind = value[0]
+ clone = self.clone()
+ if kind == 1:
+ clone['internet'] = tuple(value[1:5])
+ return clone, value[5:]
+ else:
+ raise SmiError('unknown NetworkAddress type %r' % (kind,))
+
+ def cloneAsName(self, impliedFlag, parentRow, parentIndices):
+ kind = self.getName()
+ component = self.getComponent()
+ if kind == 'internet':
+ return (1,) + tuple(component.asNumbers())
+ else:
+ raise SmiError('unknown NetworkAddress type %r' % (kind,))
+
+
class Gauge(univ.Integer):
tagSet = univ.Integer.tagSet.tagImplicitly(