Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jobs:
run: |
uv run mibdump --generate-mib-texts NET-SNMP-EXAMPLES-MIB
uv run mibdump --generate-mib-texts IF-MIB
uv run mibdump --generate-mib-texts TCP-MIB
uv run mibdump --generate-mib-texts LEXTUDIO-TEST-MIB
uv run mibdump --generate-mib-texts CISCO-ENHANCED-IPSEC-FLOW-MIB
uv run pytest --junitxml=junit/test-results-${{ matrix.python-version }}.xml --cov=com --cov-report=xml --cov-report=html
Expand Down
8 changes: 2 additions & 6 deletions pysnmp/smi/mibs/INET-ADDRESS-MIB.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,6 @@ class InetAddressIPv4(TextualConvention, OctetString):
subtypeSpec += ConstraintsUnion(
ValueSizeConstraint(4, 4),
)
fixed_length = 4

if mibBuilder.loadTexts:
description = "Represents an IPv4 network address: Octets Contents Encoding 1-4 IPv4 address network-byte order The corresponding InetAddressType value is ipv4(1). This textual convention SHOULD NOT be used directly in object definitions, as it restricts addresses to a specific format. However, if it is used, it MAY be used either on its own or in conjunction with InetAddressType, as a pair."
Expand All @@ -164,7 +163,6 @@ class InetAddressIPv6(TextualConvention, OctetString):
subtypeSpec += ConstraintsUnion(
ValueSizeConstraint(16, 16),
)
fixed_length = 16

if mibBuilder.loadTexts:
description = "Represents an IPv6 network address: Octets Contents Encoding 1-16 IPv6 address network-byte order The corresponding InetAddressType value is ipv6(2). This textual convention SHOULD NOT be used directly in object definitions, as it restricts addresses to a specific format. However, if it is used, it MAY be used either on its own or in conjunction with InetAddressType, as a pair."
Expand All @@ -177,7 +175,6 @@ class InetAddressIPv4z(TextualConvention, OctetString):
subtypeSpec += ConstraintsUnion(
ValueSizeConstraint(8, 8),
)
fixed_length = 8

if mibBuilder.loadTexts:
description = "Represents a non-global IPv4 network address, together with its zone index: Octets Contents Encoding 1-4 IPv4 address network-byte order 5-8 zone index network-byte order The corresponding InetAddressType value is ipv4z(3). The zone index (bytes 5-8) is used to disambiguate identical address values on nodes that have interfaces attached to different zones of the same scope. The zone index may contain the special value 0, which refers to the default zone for each scope. This textual convention SHOULD NOT be used directly in object definitions, as it restricts addresses to a specific format. However, if it is used, it MAY be used either on its own or in conjunction with InetAddressType, as a pair."
Expand All @@ -190,7 +187,6 @@ class InetAddressIPv6z(TextualConvention, OctetString):
subtypeSpec += ConstraintsUnion(
ValueSizeConstraint(20, 20),
)
fixed_length = 20

if mibBuilder.loadTexts:
description = "Represents a non-global IPv6 network address, together with its zone index: Octets Contents Encoding 1-16 IPv6 address network-byte order 17-20 zone index network-byte order The corresponding InetAddressType value is ipv6z(4). The zone index (bytes 17-20) is used to disambiguate identical address values on nodes that have interfaces attached to different zones of the same scope. The zone index may contain the special value 0, which refers to the default zone for each scope. This textual convention SHOULD NOT be used directly in object definitions, as it restricts addresses to a specific format. However, if it is used, it MAY be used either on its own or in conjunction with InetAddressType, as a pair."
Expand Down Expand Up @@ -229,7 +225,7 @@ class InetAddress(TextualConvention, OctetString):
}

@classmethod
def cloneFromName(cls, value, impliedFlag, parentRow, parentIndices):
def clone_from_name(cls, value, impliedFlag, parentRow, parentIndices):
for parentIndex in reversed(parentIndices):
if isinstance(parentIndex, InetAddressType):
try:
Expand All @@ -243,7 +239,7 @@ def cloneFromName(cls, value, impliedFlag, parentRow, parentIndices):
f"{cls.__name__} object encountered without preceding InetAddressType-like index: {value!r}"
)

def cloneAsName(self, impliedFlag, parentRow, parentIndices):
def clone_as_name(self, impliedFlag, parentRow, parentIndices):
for parentIndex in reversed(parentIndices):
if isinstance(parentIndex, InetAddressType):
try:
Expand Down
2 changes: 1 addition & 1 deletion pysnmp/smi/mibs/RFC1213-MIB.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@
atPhysAddress.setStatus("deprecated")
if mibBuilder.loadTexts:
atPhysAddress.setDescription("The media-dependent `physical' address. Setting this object to a null string (one of zero length) has the effect of invaliding the corresponding entry in the atTable object. That is, it effectively dissasociates the interface identified with said entry from the mapping identified with said entry. It is an implementation-specific matter as to whether the agent removes an invalidated entry from the table. Accordingly, management stations must be prepared to receive tabular information from agents that corresponds to entries not currently in use. Proper interpretation of such entries requires examination of the relevant atPhysAddress object.")
_AtNetAddress_Type = IpAddress
_AtNetAddress_Type = NetworkAddress
_AtNetAddress_Object = MibTableColumn
atNetAddress = _AtNetAddress_Object(
(1, 3, 6, 1, 2, 1, 3, 1, 1, 3),
Expand Down
8 changes: 4 additions & 4 deletions pysnmp/smi/mibs/SNMPv2-SMI.py
Original file line number Diff line number Diff line change
Expand Up @@ -1283,8 +1283,8 @@ def __init__(self, name):
def setFromName(self, obj, value, impliedFlag=None, parentIndices=None):
if not value:
raise error.SmiError(f"Short OID for index {obj!r}")
if hasattr(obj, "cloneFromName"):
return obj.cloneFromName(
if hasattr(obj, "clone_from_name"):
return obj.clone_from_name(
value, impliedFlag, parentRow=self, parentIndices=parentIndices
)
baseTag = obj.getTagSet().getBaseTag()
Expand Down Expand Up @@ -1313,8 +1313,8 @@ def setFromName(self, obj, value, impliedFlag=None, parentIndices=None):
raise error.SmiError(f"Unknown value type for index {obj!r}")

def getAsName(self, obj, impliedFlag=None, parentIndices=None):
if hasattr(obj, "cloneAsName"):
return obj.cloneAsName(
if hasattr(obj, "clone_as_name"):
return obj.clone_as_name(
impliedFlag, parentRow=self, parentIndices=parentIndices
)
baseTag = obj.getTagSet().getBaseTag()
Expand Down
20 changes: 20 additions & 0 deletions run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ def main():
parser.add_argument(
"--verbose", action="store_true", help="Run with verbose output"
)
parser.add_argument(
"--generate-mibs",
action="store_true",
help="Generate MIBs before running the tests",
)
parser.add_argument("--test-file", default="", help="Specific test file to run")
parser.add_argument("--test-path", default="tests", help="Path to test directory")
parser.add_argument("--args", default="", help="Additional pytest arguments")
Expand All @@ -40,6 +45,21 @@ def main():
print("Installing dependencies...", file=sys.stderr)
subprocess.run(["uv", "pip", "install", "-e", ".[dev]"], check=True)

if args.generate_mibs:
print("Generating MIBs for tests...", file=sys.stderr)
for mib_name in (
"NET-SNMP-EXAMPLES-MIB",
"IF-MIB",
"TCP-MIB",
"LEXTUDIO-TEST-MIB",
"CISCO-ENHANCED-IPSEC-FLOW-MIB",
):
subprocess.run(
["uv", "run", "mibdump", "--generate-mib-texts", mib_name],
check=True,
capture_output=True,
)

print("Running tests for this project...", file=sys.stderr)

# Build the command
Expand Down
35 changes: 35 additions & 0 deletions tests/proto/test_network_address.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import pytest
from pyasn1.type.namedtype import NamedType

from pysnmp.hlapi.v3arch.asyncio import ObjectIdentity, ObjectType, SnmpEngine
from pysnmp.proto.rfc1155 import NetworkAddress, IpAddress, TypeCoercionHackMixIn
from pysnmp.smi import builder, compiler, view


def test_clone_none():
Expand Down Expand Up @@ -42,3 +44,36 @@ def test_verifyComponent_invalidIdx():

with pytest.raises(Exception):
t._verify_component(1, IpAddress("10.2.3.4"))


def test_network_address_resolv():
with SnmpEngine() as snmp_engine:
mib_builder = snmp_engine.get_mib_builder()
mib_view_controller = view.MibViewController(mib_builder)
mib_builder.load_modules("RFC1213-MIB")
object_type = ObjectType(
ObjectIdentity("1.3.6.1.2.1.3.1.1.3.5.1.192.168.43.33")
)
resolved = object_type.resolve_with_mib(mib_view_controller)
assert (
resolved[0].prettyPrint()
== '''RFC1213-MIB::atNetAddress.5."NetworkAddress:
internet=192.168.43.33
"'''
)


def test_inet_address_resolv():
with SnmpEngine():
mib_builder = builder.MibBuilder()
compiler.addMibCompiler(mib_builder)
mib_view_controller = view.MibViewController(mib_builder)
mib_builder.load_modules("TCP-MIB")
object_type = ObjectType(
ObjectIdentity("1.3.6.1.2.1.6.20.1.4.1.4.127.0.0.1.2002")
)
resolved = object_type.resolve_with_mib(mib_view_controller)
assert (
resolved[0].prettyPrint()
== 'TCP-MIB::tcpListenerProcess.ipv4."127.0.0.1".2002'
)