Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception EasySNMPUnknownObjectIDError raised for an OID that exists #15

Closed
nnathan opened this issue Jun 10, 2015 · 3 comments
Closed

Comments

@nnathan
Copy link
Contributor

nnathan commented Jun 10, 2015

I haven't investigated the code yet, but I found the following bug in easysnmp.

I have installed the stock SNMP agent with the default configuration.

I fetch a single OID using snmpget command:

$ snmpget -On -v 2c -c redacted localhost 1.3.6.1.4.1.2021.11.53.0
.1.3.6.1.4.1.2021.11.53.0 = Counter32: 444734235

Now, when I use easysnmp with the following script:

import easysnmp

oids = ['1.3.6.1.4.1.2021.11.53.0']

print easysnmp.easy.snmp_get(
        oids,
        hostname='localhost',
        version=2,
        community='redacted'
)

I get the following exception:

Traceback (most recent call last):
  File "test_easysnmp.py", line 9, in <module>
    community='redacted'
  File "/srv/virtualenvs/bpl-poll-consumer/local/lib/python2.7/site-packages/easysnmp/easy.py", line 20, in snmp_get
    return session.get(oids)
  File "/srv/virtualenvs/bpl-poll-consumer/local/lib/python2.7/site-packages/easysnmp/session.py", line 299, in get
    interface.get(self, varlist)
easysnmp.exceptions.EasySNMPUnknownObjectIDError: unknown object id (1.3.6.1.4.1.2021.11.53.0)

So the easysnmp.interface is raising the exception except the OID itself does exist as demonstrated by the above snmpget command.

@nnathan
Copy link
Contributor Author

nnathan commented Jun 10, 2015

I have found the offending code and I'm working on a patch.

First, this line is a problem since py_netsnmp_attr_string(varbind, "oid_index", &iid, NULL) < 0 returns -1 since the attribute exists, is a None type, but not a string. This is because no index exists.

So I patched in the following function and fixed up the lines as follows:

/* returns 1 if None object, 0 if not None, and -1 if error */
static int py_netsnmp_attr_is_none_object(PyObject *obj, char *attr_name)
{
    int retval = -1;

    if (obj && attr_name)
    {
        PyObject *attr = PyObject_GetAttrString(obj, attr_name);

        if (attr)
        {
            /* 1 if Py_None or 0 otherwise */
            retval = (attr == Py_None);

            Py_DECREF(attr);
        }
    }

    return retval;
}
/* [...] */

            while (varlist_iter && (varbind = PyIter_Next(varlist_iter)))
            {
                if (py_netsnmp_attr_string(varbind, "oid", &tag, NULL) < 0 ||
                    (!py_netsnmp_attr_is_none_object(varbind, "oid_index") &&
                     py_netsnmp_attr_string(varbind, "oid_index", &iid, NULL) < 0)
                   )
/* [...] */

However now I'm getting a segfault here at this line:

    if (iid && *iid && oid_arr_len)
    {
        __concat_oid_str(oid_arr, oid_arr_len, iid);
    }
    return rtp;

Presumably, iid isn't set to NULL. I explicitly set it to NULL in the netsnmp_get function, and now I get the following output:

$ python test_easysnmp.py
([<SNMPVariable value=None (oid='1.3.6.1.4.1.2021.11.53.0', oid_index=None, snmp_type=None)>], True)
[<SNMPVariable value='444734235' (oid='iso.3.6.1.4.1.2021.11.53.0', oid_index='', snmp_type='COUNTER')>]

I'll work on a thorough patch that validates this. I'm surprised this isn't picked up by the unit tests.

@nnathan
Copy link
Contributor Author

nnathan commented Jun 10, 2015

Actually, just looking at the successful output from my last response, it appears that the oid_index=''. Perhaps oid_index should always be set to an empty string by the easysnmp library. I'm not sure how that will affect the code.

Let me know your insight.

Thanks.

@bwks
Copy link

bwks commented Jun 10, 2015

@nnathan Thought I would mention that if you add the leading '.' to the oid the exception is not raised.

oids = ['1.3.6.1.4.1.2021.11.53.0']
EasySNMPUnknownObjectIDError: unknown object id (1.3.6.1.4.1.2021.11.53.0)
oids = ['.1.3.6.1.4.1.2021.11.53.0']
EasySNMPTimeoutError: timed out while connecting to remote host (I dont have snmp open on localhost)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants