Non-implied OIDs, when laid in index, should be prefixed with the length
of the OID, but the current code erroneously uses len(self.name), that
is, the length of the MibTableRow's name instead.
* Fix InetAddress-to-InetAddressIPv{4,6} index cast
Previously, the pretty value of the InetAddress instance was being used.
Since InetAddress does not know how to format the raw octets to
protocol-specific syntax (IPv4 or IPv6), the pretty value was something
like u'\x00\x00\x00\x00' instead of u'0.0.0.0', which in turn caused
parse error in the protocol-specific subclass.
Passing the raw value (4- or 16-byte octet string) itself works as the
protocol-specific subclasses know how to handle these.
This is to meet the basic clone() contract and unbreak round-trip index
conversions. Previously only IPAddress values were allowed as the clone
source.
That is, reverse the supertype-subtype direction in the type matching
call: Previously it was checking if the value was a supertype of OID,
whereas the correct check should be whether the value is a subtype of
OID. This had gone undetected so far because all values were of simple,
tagged types, and if a value is not an OID, their tag set differed, i.e.
neither is a subtype of the other.
Recent introduction of NetworkAddress revealed this bug: Being an
untagged Choice type, NetworkAddress's tag set is empty, and it counts
as a supertype of OID: resolveWithMib() then erroneously treated it as
an OID.
* 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.
Previously an exceptions raised by vbProcessor.unmakeVarBinds() fell
through, and asyncio base event loop caught and reported it on stderr,
while the original cmdgen's future went unfinished, causing the call to
hang forever. Match the synchronous version's behavior, which is to
raise the exception for the caller of the cmdgen to catch.
Commit 30167082cd fixed string index
rendering except for implied string types, which were left broken.
Close that gap by applying the same workaround.