Coder Social home page Coder Social logo

python-netsnmpagent's Introduction

                        python-netsnmpagent Module
       Copyright (c) 2013-2019 Pieter Hollants <[email protected]>
       Licensed under the GNU Lesser Public License (LGPL) version 3


WHAT IS IT?

python-netsnmpagent is a Python module that facilitates writing Net-SNMP
subagents in Python. Subagents connect to a locally running Master agent
(snmpd) over a Unix domain socket (eg. "/var/run/agentx/master") and using the
AgentX protocol (RFC2741). They implement custom Management Information Base
(MIB) modules that extend the local node's MIB tree. Usually, this requires
writing a MIB as well, ie. a text file that specifies the structure, names
and data types of the information within the MIB module.

python-netsnmpagent was written after a lot of frustration trying to fix the
python-agentx module hosted on Sourceforge. I fixed some smaller issues there
but when it came to making sure that you could actually walk the whole MIB, not
just the variables registered, I realized that it would not make much sense to
reimplement the complete behavior of a proper SNMP agent when the NetSNMP API
actually can handle those things for you. Also, to be honest, I don't get
python-agentx's design :-)

python-netsnmpagent, by contrast, in the first line focusses on making the
net-snmp C agent API accessible from Python. Though I will try not to just
pass through every library call 1:1 but wrap them in a useful manner.

net-snmp itself also comes with a Python module (see the "python" subdirectory
in the source distribution), however it seems to offer bindings that implement
the client side only, not the agent side.


REQUIREMENTS

python-netsnmpagent requires the net-snmp libraries to be installed. The
runtime libraries are enough, development files are not necessary.

Tested versions include 5.4.2 (included with SUSE Linux Enterprise Server 11
SP2), 5.4.3 (included with Ubuntu 12.04 LTS) and net-snmp 5.7.3 (included with
openSUSE 12.3). While the intent is to support both net-snmp 5.4.x and 5.7.x
versions at least for the near future, I want to avoid double code paths
whereever possible. I therefore have to stick to the net-snmp 5.4.x way of
things at certain places indicated by code comments.

python-netsnmpagent has been tested and is compatible with:
- Python 2.6
- Python 2.7
- Python 3.5 (since November 1st, 2016)


LICENSE

Version older than May 28th, 2016 were licensed under the GNU General Public
License (GPL), version 3. Since May 28th, 2016, python-netsnmpagent is being
licensed under the GNU Lesser General Public License (LGPL), version 3. See
http://www.gnu.org/licenses/lgpl-3.0.txt or the included file LICENSE.


DOWNLOAD

The PyPI page with distribution archives is available at

  http://pypi.python.org/pypi/netsnmpagent

Binary RPMs for SuSE distributions are available via search.opensuse.org and
the Open Build Service Project page at

  https://build.opensuse.org/package/show?package=python-netsnmpagent&project=home%3Apfhllnts

If you wish to follow development more closely clone the GitHub repo:

  https://github.com/pief/python-netsnmpagent.git


INSTALLATION

If you do not use a ready package for your Linux distribution, you can install
directly from source using

  python setup.py install

This will most probably require appropriate rights (eg. being "root").


EXAMPLE USAGE

The "examples" subdirectory contains well-commented example agents that should
give you a quickstart on how to use python-netsnmpagent. Read the "README" file
contained there for a short introduction on the different examples.


API

The Python API has not really been documented yet. For now, please see the
example agents' source code for info on how to use the python-netsnmpagent
module.

NOTE: Since 2019-07-24 the OctetString interface has been changed to return a
bytes() array instead of a String. This is to accomodate the fact that
OctetStrings may contain NUL bytes, i.e. in the case of MAC addresses.


TESTS

python-netsnmpagent now comes with integration tests to test the net-snmp
integration. Type "make tests" to run them. See tests/README for the reasons
why "nosetests" can't be run directly.


TODO

- notifications/traps
- more tests


CREDITS

python-netsnmpagent was inspired by python-agentx, courtesy of Bozhin Zafirov
<[email protected]>. I blatantly ripped some ideas and some lines of code, shame
on me.

SNMP contexts support and various other additions were implemented by Steven
Hiscocks <[email protected]>.

Support for Gauge32, Float and TruthValue variable types was implemented based
on a merge request by Bill Randle <[email protected]>.

The bug that DisplayStrings/OctetStrings got truncated when trying to update
them with a string larger that the original InitVal was hunted down and fixed
by Max "mk23" Kalika <[email protected]>.

Tobias Deiminger <[email protected]> contributed fixes related to
using IpAddress objects as table indices.

Konrad Gräfe <[email protected]> fixed among other things the OctetString
interface to return bytes() instead of a String so NUL bytes are accounted for.

Additional smaller bugfixes were done by Anton Todorov <[email protected]>.

python-netsnmpagent's People

Contributors

atodorov-storpool avatar csdexter avatar haxtibal avatar j123b567 avatar jdevera avatar kgraefe avatar kwirk avatar ltworf avatar pief avatar pouralijan avatar rkojedzinszky avatar swaeberle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-netsnmpagent's Issues

Can not update table entry with python code

Hi,

I set up a table with python. Now I want to change values at runtime from inside the python script. Therefor I tried to store references of the types of a row:

If I try...:

rcnt = agent.Counter32(500)
rflag = agent.Integer32(99)

row = self._stats_table.addRow([agent.Integer32(1)])
row.setRowCell(2, agent.DisplayString("Some name"))
row.setRowCell(3, rcnt)
row.setRowCell(4, rflag)

...

rcnt.update(1000)
rflag.update(5000)

...the table is not updated and I do not understand why. I always have to clear() the whole table and set values newly. Is that the only way doing it? Unfortunately the simple-example only demonstrates updates on scalar types.

Strings inside tables erroneously get a dot (".") suffix

Under openSUSE 13.1, string objects inside tables seem to erroneously get a dot (".") suffix that ordinary string objects don't:

pief@e6400:~/python-netsnmpagent/examples> snmpwalk -v 2c -c public -M+. localhost:5555 SIMPLE-MIB::simpleMIB
[...]
SIMPLE-MIB::simpleOctetString.0 = STRING: Hello World
SIMPLE-MIB::simpleDisplayString.0 = STRING: Nice to meet you
SIMPLE-MIB::firstTableNumber.0 = Gauge32: 3
SIMPLE-MIB::firstTableEntryDesc."aa" = STRING: Prague.
SIMPLE-MIB::firstTableEntryDesc."ab" = STRING: Barcelona.
SIMPLE-MIB::firstTableEntryDesc."bb" = STRING: Unknown place.
[...]

I can't remember seeing this under openSUSE 12.2, so it might be due to different net-snmp versions. Needs investigation.

I can't update row Counter64

Hi,

I ran the simple agent to read linux network interfaces eth0, eth1 and eth2:

{'NETWORKZ-MIB::firstTable': {'type': 'Table',
'value': {0: {2: {'type': 'OctetString', 'value': 'Unknown place'},
3: {'type': 'Counter64', 'value': 0}},
'1': {2: 'eth0', 3: 204064872L},
'2': {2: 'eth1', 3: 134064843},
'3': {2: 'eth2', 3: 988190442}}},

When I execute:

snmpwalk -v 2c -c public -M+. localhost:5555 NETWORKZ-MIB::simpleMIB
shows me:
NETWORKZ-MIB::ifDescr."1" = STRING: eth0
NETWORKZ-MIB::ifDescr."2" = STRING: eth1
NETWORKZ-MIB::ifDescr."3" = STRING: eth2
NETWORKZ-MIB::ifInBytes."1" = Counter64: 204064872
NETWORKZ-MIB::ifInBytes."2" = Counter64: 134064843
NETWORKZ-MIB::ifInBytes."3" = Counter64: 988190442

When I execute again the snmpwalk, the result is the same. I can't update Counter64 values

The code is:

Add the first table row

firstTableRow1 = firstTable.addRow([agent.DisplayString("1")])
firstTableRow1.setRowCell(2, agent.DisplayString("eth0"))
firstTableRow1.setRowCell(3, agent.Counter64(get_in_bytes("eth0")))

Add the second table row

firstTableRow2 = firstTable.addRow([agent.DisplayString("2")])
firstTableRow2.setRowCell(2, agent.DisplayString("eth1"))
#firstTableRow2.setRowCell(3, agent.Integer32(28))
firstTableRow2.setRowCell(3, agent.Counter64(get_in_bytes("eth1")))

Add the third table row

firstTableRow3 = firstTable.addRow([agent.DisplayString("3")])
firstTableRow3.setRowCell(2, agent.DisplayString("eth2"))
#firstTableRow3.setRowCell(3, agent.Integer32(18))
firstTableRow3.setRowCell(3, agent.Counter64(get_in_bytes("eth2")))

The function get_in_bytes() allow me to get the input bytes on the interface

Juan Carlos

Segfault with Table.clear()

I am using an agent that builds a table and periodically clears it. Rarely I receive a segmentation fault. Narrowing down the code and using valgrind, it spots invalid memory reads.

The attached script demonstrates:

$ valgrind python ./snmp-agent.py 
==169269== Memcheck, a memory error detector
==169269== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==169269== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==169269== Command: python ./snmp-agent.py
==169269== 
[Error] MIB search path: ...
[Error] Cannot find module (UCD-SNMP-MIB): At line 1 in (none)
[Error] Cannot find module (UCD-DEMO-MIB): At line 1 in (none)
[Error] Cannot find module (NET-SNMP-AGENT-MIB): At line 1 in (none)
[Error] Cannot find module (NET-SNMP-PASS-MIB): At line 1 in (none)
[Error] Cannot find module (NET-SNMP-EXTEND-MIB): At line 1 in (none)
[Error] Cannot find module (UCD-DLMOD-MIB): At line 1 in (none)
[Error] Cannot find module (NET-SNMP-VACM-MIB): At line 1 in (none)
Cycle 0
Cycle 1
==169269== Invalid read of size 8
==169269==    at 0x56DC16E: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x576FF4: ??? (in /usr/bin/python3.11)
==169269==    by 0x53AC2B: PyObject_Vectorcall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x52360A: PyEval_EvalCode (in /usr/bin/python3.11)
==169269==    by 0x647496: ??? (in /usr/bin/python3.11)
==169269==    by 0x644D4E: ??? (in /usr/bin/python3.11)
==169269==    by 0x65100F: ??? (in /usr/bin/python3.11)
==169269==    by 0x650D5A: _PyRun_SimpleFileObject (in /usr/bin/python3.11)
==169269==    by 0x650B83: _PyRun_AnyFileObject (in /usr/bin/python3.11)
==169269==    by 0x64F90E: Py_RunMain (in /usr/bin/python3.11)
==169269==    by 0x6275C6: Py_BytesMain (in /usr/bin/python3.11)
==169269==  Address 0x6616ee0 is 32 bytes inside a block of size 48 free'd
==169269==    at 0x484317B: free (vg_replace_malloc.c:872)
==169269==    by 0x588BC04: netsnmp_table_data_delete_row (table_data.c:144)
==169269==    by 0x588CCB2: netsnmp_table_dataset_remove_and_delete_row (table_dataset.c:201)
==169269==    by 0x588CCB2: netsnmp_table_dataset_remove_and_delete_row (table_dataset.c:192)
==169269==    by 0x4862F79: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x486240D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x4862B0C: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x56D942A: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x52360A: PyEval_EvalCode (in /usr/bin/python3.11)
==169269==    by 0x647496: ??? (in /usr/bin/python3.11)
==169269==  Block was alloc'd at
==169269==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
==169269==    by 0x588D7AD: netsnmp_table_data_set_create_row_from_defaults (table_dataset.c:292)
==169269==    by 0x4862F79: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x486240D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x4862B0C: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x56D942A: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x51F066: _PyObject_FastCallDictTstate (in /usr/bin/python3.11)
==169269==    by 0x565972: ??? (in /usr/bin/python3.11)
==169269==    by 0x517E54: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269== 
==169269== Invalid read of size 8
==169269==    at 0x56DC4FB: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x543E9B: _PyObject_GenericGetAttrWithDict (in /usr/bin/python3.11)
==169269==    by 0x51E473: PyObject_GetAttr (in /usr/bin/python3.11)
==169269==    by 0x52BF94: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x52360A: PyEval_EvalCode (in /usr/bin/python3.11)
==169269==    by 0x647496: ??? (in /usr/bin/python3.11)
==169269==    by 0x644D4E: ??? (in /usr/bin/python3.11)
==169269==    by 0x65100F: ??? (in /usr/bin/python3.11)
==169269==    by 0x650D5A: _PyRun_SimpleFileObject (in /usr/bin/python3.11)
==169269==    by 0x650B83: _PyRun_AnyFileObject (in /usr/bin/python3.11)
==169269==    by 0x64F90E: Py_RunMain (in /usr/bin/python3.11)
==169269==    by 0x6275C6: Py_BytesMain (in /usr/bin/python3.11)
==169269==  Address 0x6616ee0 is 32 bytes inside a block of size 48 free'd
==169269==    at 0x484317B: free (vg_replace_malloc.c:872)
==169269==    by 0x588BC04: netsnmp_table_data_delete_row (table_data.c:144)
==169269==    by 0x588CCB2: netsnmp_table_dataset_remove_and_delete_row (table_dataset.c:201)
==169269==    by 0x588CCB2: netsnmp_table_dataset_remove_and_delete_row (table_dataset.c:192)
==169269==    by 0x4862F79: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x486240D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x4862B0C: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x56D942A: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x52360A: PyEval_EvalCode (in /usr/bin/python3.11)
==169269==    by 0x647496: ??? (in /usr/bin/python3.11)
==169269==  Block was alloc'd at
==169269==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
==169269==    by 0x588D7AD: netsnmp_table_data_set_create_row_from_defaults (table_dataset.c:292)
==169269==    by 0x4862F79: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x486240D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x4862B0C: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x56D942A: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x51F066: _PyObject_FastCallDictTstate (in /usr/bin/python3.11)
==169269==    by 0x565972: ??? (in /usr/bin/python3.11)
==169269==    by 0x517E54: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269== 
==169269== Invalid read of size 8
==169269==    at 0x56E4DC9: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56E2949: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x52360A: PyEval_EvalCode (in /usr/bin/python3.11)
==169269==    by 0x647496: ??? (in /usr/bin/python3.11)
==169269==    by 0x644D4E: ??? (in /usr/bin/python3.11)
==169269==    by 0x65100F: ??? (in /usr/bin/python3.11)
==169269==    by 0x650D5A: _PyRun_SimpleFileObject (in /usr/bin/python3.11)
==169269==    by 0x650B83: _PyRun_AnyFileObject (in /usr/bin/python3.11)
==169269==    by 0x64F90E: Py_RunMain (in /usr/bin/python3.11)
==169269==  Address 0x6616ee0 is 32 bytes inside a block of size 48 free'd
==169269==    at 0x484317B: free (vg_replace_malloc.c:872)
==169269==    by 0x588BC04: netsnmp_table_data_delete_row (table_data.c:144)
==169269==    by 0x588CCB2: netsnmp_table_dataset_remove_and_delete_row (table_dataset.c:201)
==169269==    by 0x588CCB2: netsnmp_table_dataset_remove_and_delete_row (table_dataset.c:192)
==169269==    by 0x4862F79: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x486240D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x4862B0C: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x56D942A: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x52360A: PyEval_EvalCode (in /usr/bin/python3.11)
==169269==    by 0x647496: ??? (in /usr/bin/python3.11)
==169269==  Block was alloc'd at
==169269==    at 0x48455EF: calloc (vg_replace_malloc.c:1328)
==169269==    by 0x588D7AD: netsnmp_table_data_set_create_row_from_defaults (table_dataset.c:292)
==169269==    by 0x4862F79: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x486240D: ??? (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x4862B0C: ffi_call (in /usr/lib/x86_64-linux-gnu/libffi.so.8.1.2)
==169269==    by 0x56D942A: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x56D8612: ??? (in /usr/lib/python3.11/lib-dynload/_ctypes.cpython-311-x86_64-linux-gnu.so)
==169269==    by 0x517EB2: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269==    by 0x52B93F: _PyEval_EvalFrameDefault (in /usr/bin/python3.11)
==169269==    by 0x51F066: _PyObject_FastCallDictTstate (in /usr/bin/python3.11)
==169269==    by 0x565972: ??? (in /usr/bin/python3.11)
==169269==    by 0x517E54: _PyObject_MakeTpCall (in /usr/bin/python3.11)
==169269== 
==169269== 
==169269== HEAP SUMMARY:
==169269==     in use at exit: 988,875 bytes in 9,574 blocks
==169269==   total heap usage: 26,267 allocs, 16,693 frees, 14,983,444 bytes allocated
==169269== 
==169269== LEAK SUMMARY:
==169269==    definitely lost: 0 bytes in 0 blocks
==169269==    indirectly lost: 0 bytes in 0 blocks
==169269==      possibly lost: 0 bytes in 0 blocks
==169269==    still reachable: 988,875 bytes in 9,574 blocks
==169269==         suppressed: 0 bytes in 0 blocks
==169269== Rerun with --leak-check=full to see details of leaked memory
==169269== 
==169269== For lists of detected and suppressed errors, rerun with: -s
==169269== ERROR SUMMARY: 4 errors from 3 contexts (suppressed: 0 from 0)

snmp-agent.py.txt

Howewer, if I apply the following simple diff:

--- netsnmpagent.py.orig	2023-12-26 19:04:50.313345452 +0100
+++ netsnmpagent.py	2023-12-26 19:05:59.302824678 +0100
@@ -912,14 +912,11 @@
 				return retdict
 
 			def clear(self):
-				row = self._dataset.contents.table.contents.first_row
-				while bool(row):
-					nextrow = row.contents.next
+				while bool(row := self._dataset.contents.table.contents.first_row):
 					libnsX.netsnmp_table_dataset_remove_and_delete_row(
 						self._dataset,
 						row
 					)
-					row = nextrow
 				if self._counterobj:
 					self._counterobj.update(0)
 

The mentioned warning from valgrind disappears. And since then, my application is not crashing. Howewer, I am not sure why this does solve my issue, I dont know python's ctype's internals.

No Gauge32 available

Hi,

I want to implement a gauge, but netsnmpAgent has no Gauge32.
e.g.

activeSessionAvg = agent.Gauge32(
    oidstr   = ....,
    initval  = 0,
    writable = False
)

Error message is:

AttributeError: 'netsnmpAgent' object has no attribute 'Gauge32'

pkg_resources.DistributionNotFound exception when using netsnmpagent.py directly from source tree

c77f52a introduced code that uses pkg_resources to get the module's version, as defined in setup.py. When using netsnmpagent.py directly from the source tree, eg. by running the example agents, this fails unless a "make install" is performed:

[...]
* Starting the simple example agent...
Traceback (most recent call last):
  File "simple_agent.py", line 47, in <module>
    import netsnmpagent
  File "/home/pief/python-netsnmpagent/netsnmpagent.py", line 29, in <module>
    __version__ = pkg_resources.require("netsnmpagent")[0].version
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 690, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python2.7/site-packages/pkg_resources.py", line 588, in resolve
    raise DistributionNotFound(req)
pkg_resources.DistributionNotFound: netsnmpagent
* Cleaning up...

No support for OctetStrings with zeros.

The library uses ctypes.create_string_buffer and ctypes.string_at etc.
This causes an issue when trying to work with buffers that should be returned as hexadecimal.
For example if I want to return IPv6 address of MAC as an octet string and one of the bytes is zero I will get a partial result (the prefix of the buffer until we hit the zero byte).

This can most likely be fixed by using ctypes.c_ubyte * N to create the buffers instead ctype.create_string_buffer

Can't reach subagent from system-wide level

Hello.

First of all, thank you for that library, since it appears to be the most alive Pyhon-SNMP implementation.

I tried to run simple agent example, from the master branch, that was successful. After that I tried to do as comments say at the beginning of simple_agent.py.

However this time I had response:

snmpwalk -v 2c -c secret -M+. localhost SIMPLE-MIB::simpleMIB
SIMPLE-MIB::simpleMIB = No Such Object available on this agent at this OID

Also, I noted that nowadays <rosecret> is called simply secret inside the /etc/snmp/snmpd.conf.

And in comments:

Then, from a separate console and from inside the python-netsnmpagent
directory, you can run

I believe you meant from /examples directory, since SIMPLE_MIB.txt is available only there?

Cannot update table entry

Hi,

I'm trying to update a table entry with snmpset but I always get an error.

I used the MIB "SIMPLE-MIB.txt" and the python program "simple_agent.py" to play with. First I changed the lines "MAX-ACCESS" to "read-write". Next I updated a simple object which worked fine and then I tried the update a table entry which failed.

Traces:

 $ snmpget -v 2c -c public -m$PWD/mibs/SIMPLE-MIB.txt localhost:5555 SIMPLE-MIB::simpleInteger.0
SIMPLE-MIB::simpleInteger.0 = INTEGER: 0
$ snmpset -v 2c -c private -m$PWD/mibs/SIMPLE-MIB.txt localhost:5555 SIMPLE-MIB::simpleInteger.0 i 123
SIMPLE-MIB::simpleInteger.0 = INTEGER: 123
$ snmpget -v 2c -c public -m$PWD/mibs/SIMPLE-MIB.txt localhost:5555 SIMPLE-MIB::simpleInteger.0       
SIMPLE-MIB::simpleInteger.0 = INTEGER: 123
$  snmpget -v 2c -c public -m$PWD/mibs/SIMPLE-MIB.txt localhost:5555 SIMPLE-MIB::secondTableEntryDesc.1
SIMPLE-MIB::secondTableEntryDesc.1 = STRING: foo0
$  snmpset -v 2c -c private -m$PWD/mibs/SIMPLE-MIB.txt localhost:5555 SIMPLE-MIB::secondTableEntryDesc.1 s hello
Error in packet.
Reason: notWritable (That object does not support modification)
Failed object: SIMPLE-MIB::secondTableEntryDesc.1

Any ideas?

Kind regards,
Rob

Please consider pushing to pypi

Hi,

I'm using this module to run an SNMP subagent, thank you for your work.

It'd be great to have a version of this in pipy that can run the examples.

Thanks!

Edit: I see the tags are there :)

Couldn't install from github

We need the latest version of netsnmpagent package with proper python3 support, but unfortunately couldn't install it directly from github since there is no setup.py and version in pypi archive doesn't work with python3.4.

Please make project installable directly from github or publish new fresh release on pypi.

python: undefined symbol: snmp_register_callback

Hello,

I am trying to use the Python package netsnmpagent-0.5.3.tar.gz to setup a sub-agent. When I run the example "run_simple_agent.sh" I get the following error:

AttributeError: python: undefined symbol: snmp_register_callback

Script output:

  • Preparing snmpd environment...

  • Our snmpd instance is now listening on localhost, port 5555.
    From a second console, use the net-snmp command line utilities like this:

    cd /home/robm/snmp/src/python/netsnmpagent-0.5.3/examples
    snmpwalk -v 2c -c public -M+. localhost:5555 SIMPLE-MIB::simpleMIB
    snmptable -v 2c -c public -M+. -Ci localhost:5555 SIMPLE-MIB::firstTable
    snmpget -v 2c -c public -M+. localhost:5555 SIMPLE-MIB::simpleInteger.0
    snmpset -v 2c -c simple -M+. localhost:5555 SIMPLE-MIB::simpleInteger.0 i 123

  • Starting the simple example agent...
    Traceback (most recent call last):
    File "simple_agent.py", line 47, in
    import netsnmpagent
    File "/home/robm/snmp/src/python/netsnmpagent-0.5.3/netsnmpagent.py", line 24, in
    from netsnmpapi import *
    File "/home/robm/snmp/src/python/netsnmpagent-0.5.3/netsnmpapi.py", line 55, in
    for f in [ libnsa.snmp_register_callback ]:
    File "/usr/lib/python2.7/ctypes/init.py", line 378, in getattr
    func = self.getitem(name)
    File "/usr/lib/python2.7/ctypes/init.py", line 383, in getitem
    func = self._FuncPtr((name_or_ordinal, self))
    AttributeError: python: undefined symbol: snmp_register_callback

I am using the net-snmp-5.7.3 package which I configured the following way:
configure --with-mib-modules=smux

Any help will be appreciated.

Kind regards,
Rob

Callback support?

Thank you for doing this work! I experienced the same problem as you -- hardly any support for SNMP agents other than through C or Perl.
I think your model is nicer than the "push persist" mode of snmpd, but snmpd is still better suited for interactions with the environment -- local modifications over SNMP, and on-the-spot lookups in response to SNMP inquiries.
Have you considered permitting callback functions to make that sort of thing possible with your agent? Matching against a beginning-of-OID as in snmpd should work nicely. Such a construct could implement more dynamic getting, as wel as setting of values than now possible with python-netsnmpagent.

Wrong RFC in README

As far as I understand correct RFC for SNMP AgentX protocol is RFC2741 and not RFC2747 as mentioned in README.

References to exampleCounter in simple_agent.py

Was just running the simple_agent.py to get my feet wet. There was a minor bug with a few references to example (rather than simple).

  • exampleCounter64
  • EXAMPLE-MIB
  • exampleCounter32Context2
  • exampleCounter64Context2

self._status update failed at agent reconnexion

In netsnmpagent.py, line 183, the regex match is not correct :

The line is:
and re.match("AgentX subagent connected", msgtext):

It should be started with .* like this:
and re.match(".*AgentX subagent connected", msgtext):

Because the full message is :
"NET-SNMP version 5.9 AgentX subagent connected"

And the match is never taken, without the .*

Thanks,
Amandine
Erreur_regex_match_snmpagent

How to update Counter64 objects in the table

I have declared table like this

MyTable = agent.Table(
    oidstr  = "MY-MIB::MyTable",
    indexes = [
        agent.DisplayString(),
        agent.Unsigned32()
    ],
    columns = [
        (1, agent.DisplayString("NA")),
        (2, agent.Unsigned32(1)),
        (3, agent.DisplayString("NA")),
        (4, agent.DisplayString("NA")),
        (5, agent.Unsigned32(0)),
        (6, agent.Unsigned32(0)),
        (7, agent.DisplayString("NA")),
        (8, agent.DisplayString("NA")),
        (9, agent.Integer32(0)),
        (10, agent.Counter64(0)),
        (11, agent.Counter64(0)),
        (12, agent.Counter64(0)),
        (13, agent.Counter64(0)),
        (14, agent.Integer32(0)),
        (15, agent.Integer32(0)),
        (16, agent.Integer32(0)),
    ]
)

but the counter64 object is no updating when call it in setRowCell

rd.setRowCell(13, agent.Counter64(5000))

I am missing something?

Can't use IpAddress as table index

Using an IpAddress object as table index fails with

AttributeError: 'IpAddress' object has no attribute '_asntype'

Example snippet for how to reproduce:

tableWithIpIndex = agent.Table(
    oidstr = "SIMPLE-MIB::thirdTable",
    indexes = [
        agent.IpAddress()
    ],
    columns = [
        (2, agent.DisplayString("")),
        (3, agent.IpAddress("0.0.0.0"))
    ],
)
row1 = tableWithIpIndex.addRow([agent.IpAddress("192.168.0.1")])
row1.setRowCell(2, agent.DisplayString("Some value"))
row1.setRowCell(3, agent.IpAddress("192.168.0.1"))

The first part of a potential fix is simple, just initialize IpAddress with the missing attributes, e.g.:

class IpAddress(object):
    def __init__(self):
        self._flags = WATCHER_FIXED_SIZE
        self._asntype = ASN_IPADDRESS
        self._cvar = ctypes.c_uint(0)
        self._data_size = ctypes.sizeof(self._cvar)
        self._max_size  = self._data_size
        self.update(initval)

Now comes the tricky part. There's an open Net-SNMP Bug 2136. Its impact is that Net-SNMP expects an IP address in network byte order if used as column instance, but in host byte order if used as index. This hits us if we're on little-endian machines like Intel x86-64.

Without further measures our example would give the correct cell value, but a reversed index

AGENTX-MIB::agentxObjects.30187.1.2.6.1.3.1.0.168.192 = IpAddress: 192.168.0.1

I'll send a pull request soon, with a suggestion how to fix the second issue too. It will produce expected output (at least if RFC 3416, section 4.2.2.1 is taken as a reference for how it should be)

AGENTX-MIB::agentxObjects.30187.1.2.6.1.3.192.168.0.1 = IpAddress: 192.168.0.1

OSError: /usr/lib64/libnetsnmphelpers.so.10: undefined symbol: snmp_free_var

Hi Pieter-

This is a shot in the dark here, but I'm encountering an issue with loading the netsnmp shared libraries in python, and I thought maybe you had some insight:

>>> ctypes.CDLL("libnetsnmphelpers.so.10")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib64/python2.6/ctypes/__init__.py", line 353, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /usr/lib64/libnetsnmphelpers.so.10: undefined symbol: snmp_free_var

Yet that symbol exists in that library:

# readelf -Ws  /usr/lib64/libnetsnmphelpers.so.10 | grep snmp_free_var
    12: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND snmp_free_var
    56: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND snmp_free_varbind

I've tried it with ctypes.RTLD_GLOBAL set to the mode, but that doesn't do anything.

Here is the version of the OS and library:

# cat /etc/redhat-release 
CentOS release 5.8 (Final)
# rpm -q net-snmp
net-snmp-5.3.2.2-17.el5_8.1

Interestingly though, it works on CentOS 6.x

>>> ctypes.cdll.LoadLibrary(ctypes.util.find_library("netsnmphelpers"))
<CDLL 'libnetsnmphelpers.so.20', handle 9d7890 at 7fe1caf76690>

# cat /etc/redhat-release 
CentOS release 6.5 (Final)
# rpm -q net-snmp
net-snmp-5.5-49.el6_5.1.x86_64

Any insight would help, but I understand if this cannot be helped.

Separate the update process from request processing

Hi,

First of all, I wanted to thank you. It's really hard to find AgentX implementations written in Python that actually work.

But I have to admit I'm having trouble with the update process.

In your example, you launch the updates when agent.check_and_process() unlocks (when receiving a request).

However in my case, I need the data to be ready sooner. I can't afford to lose time to get the new values.

I am thinking about using another thread, which will deal with the updates, but it implies to use locks almost everywhere, and I want to avoid
that as much as possible.

Do you know if it is possible to launch the updates BEFORE (and independently from) a request reception?

Thank you in advance for your answer.

Best regards,
Salem

Updated DisplayString can not be longer than initval

I am creating a displayString with code like the following. It seems the updated value for a display string gets cuts off at the initval length of the string. If I make the initval longer or shorter, the updated value reflect this as well.

version = agent.DisplayString(oidstr="PRODUCT-MIB::version", initval="123")
version.update("98765")
>> Result from SNMP PRODUCT-MIB::version is: 987

getRegistered(context) throws exception when OctetString is DateTime

I'm setting an OctetString as follows as an SNMP DateTime object

I'm not sure if the way I'm setting the DateTime is correct for SNMP, but when I do a snmpwalk, I'm able to see the variable just fine. Except the program blows up when I call dump_registered()

setup

import struct
import time

# setup the agent as in simple_agent.py example, then

time_millisecs = 1577836800000

# convert milliseconds to an OctetString
value = time.gmtime(time_millisecs / 1000)
value = struct.pack(
                            ">HBBBBBB",
                            value.tm_year,
                            value.tm_mon,
                            value.tm_mday,
                            value.tm_hour,
                            value.tm_min,
                            value.tm_sec,
                            0,
                        )
new_row.setRowCell(2, agent.OctetString(value))

# the above is fine, but it then blows up when the following is called
dump_registered(agent)

stacktrace

Traceback (most recent call last):
  File "./snmp_agent.py", line 465, in <module>
    main()
  File "./snmp_agent.py", line 435, in main
    dump_registered(agent)
  File "./snmp_agent.py", line 342, in dump_registered
    variables = agent.getRegistered(context)
  File "~/my_venv/lib/python3.8/site-packages/netsnmpagent.py", line 949, in getRegistered
    "value": snmpobj.value()
  File "~/my_venv/lib/python3.8/site-packages/netsnmpagent.py", line 895, in value
    retdict[indices][int(data.contents.column)] = u(ctypes.string_at(data.contents.data.string, data.contents.data_len))
  File "~/my_venv/lib/python3.8/site-packages/netsnmpagent.py", line 51, in u
    return s if isinstance("Test", bytes) else s.decode(locale.getpreferredencoding())
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe4 in position 1: invalid continuation byte
Exception ignored in: <module 'threading' from '/usr/lib/python3.8/threading.py'>
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 1388, in _shutdown
    lock.acquire()
KeyboardInterrupt: 
* Cleaning up...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.