Hello,
I would like to propose the attached patch to the Python bindings. This is a
patch to version 5.4.2.1. Currently, including null-bytes in octet strings
doesn't work because it's just treating the strings from Python as
null-terminated strings instead of getting their actual length. I discovered
this while attempting to set CISCO-VTP-MIB::vlanTrunkPortVlansEnabled*, which
is basically a bit-string and will often contain null-bytes.
As I'm new to contributing code to Net-SNMP, please let me know if I need to do
anything different to get this included in the codebase.
Thanks.
--
Regards,
Tommy Beadle ([email protected])
QA Engineer
Arbor Networks -- How Networks Grow
www.arbornetworks.com
--- python/netsnmp/client_intf.c.old 2008-09-04 18:52:42.000000000 -0400
+++ python/netsnmp/client_intf.c 2010-02-05 21:52:49.000000000 -0500
@@ -1081,20 +1081,22 @@ py_netsnmp_construct_varbind(void)
return PyObject_CallFunction(callable, "");
}
-static char *
-py_netsnmp_attr_string(PyObject *obj, char * attr_name)
+static int
+py_netsnmp_attr_string(PyObject *obj, char * attr_name, char **val,
+ Py_ssize_t *len)
{
- char *val = NULL;
-
+ *val = NULL;
if (obj && attr_name && PyObject_HasAttrString(obj, attr_name)) {
PyObject *attr = PyObject_GetAttrString(obj, attr_name);
if (attr) {
- val = PyString_AsString(attr);
+ int retval;
+ retval = PyString_AsStringAndSize(attr, val, len);
Py_DECREF(attr);
+ return retval;
}
}
- return val;
+ return -1;
}
static long
@@ -1395,6 +1397,8 @@ netsnmp_get(PyObject *self, PyObject *ar
int err_ind;
int err_num;
char err_str[STR_BUF_SIZE];
+ char *tmpstr;
+ Py_ssize_t tmplen;
oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
@@ -1406,7 +1410,10 @@ netsnmp_get(PyObject *self, PyObject *ar
ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
- strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+ if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+ goto done;
+ }
+ memcpy(&err_str, tmpstr, tmplen);
err_num = py_netsnmp_attr_long(session, "ErrorNum");
err_ind = py_netsnmp_attr_long(session, "ErrorInd");
@@ -1427,12 +1434,13 @@ netsnmp_get(PyObject *self, PyObject *ar
PyObject *varlist_iter = PyObject_GetIter(varlist);
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
- tag = py_netsnmp_attr_string(varbind, "tag");
- iid = py_netsnmp_attr_string(varbind, "iid");
-
-
- tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len,
- NULL, best_guess);
+ if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+ py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+ {
+ oid_arr_len = 0;
+ } else {
+ tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+ }
if (oid_arr_len) {
snmp_add_null_var(pdu, oid_arr, oid_arr_len);
@@ -1600,6 +1608,8 @@ netsnmp_getnext(PyObject *self, PyObject
int err_ind;
int err_num;
char err_str[STR_BUF_SIZE];
+ char *tmpstr;
+ Py_ssize_t tmplen;
oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
@@ -1611,7 +1621,10 @@ netsnmp_getnext(PyObject *self, PyObject
ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
- strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+ if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+ goto done;
+ }
+ memcpy(&err_str, tmpstr, tmplen);
err_num = py_netsnmp_attr_long(session, "ErrorNum");
err_ind = py_netsnmp_attr_long(session, "ErrorInd");
@@ -1632,11 +1645,13 @@ netsnmp_getnext(PyObject *self, PyObject
PyObject *varlist_iter = PyObject_GetIter(varlist);
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
- tag = py_netsnmp_attr_string(varbind, "tag");
- iid = py_netsnmp_attr_string(varbind, "iid");
-
- tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len,
- NULL, best_guess);
+ if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+ py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+ {
+ oid_arr_len = 0;
+ } else {
+ tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+ }
if (_debug_level)
printf("netsnmp_getnext: filling request: %s:%s:%d:%d\n",
@@ -1809,6 +1824,8 @@ netsnmp_walk(PyObject *self, PyObject *a
char err_str[STR_BUF_SIZE];
int notdone = 1;
int result_count = 0;
+ char *tmpstr;
+ Py_ssize_t tmplen;
oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
@@ -1827,7 +1844,10 @@ netsnmp_walk(PyObject *self, PyObject *a
}
ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
- strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+ if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+ goto done;
+ }
+ memcpy(&err_str, tmpstr, tmplen);
err_num = py_netsnmp_attr_long(session, "ErrorNum");
err_ind = py_netsnmp_attr_long(session, "ErrorInd");
@@ -1848,11 +1868,13 @@ netsnmp_walk(PyObject *self, PyObject *a
/* get the initial starting oids*/
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
- tag = py_netsnmp_attr_string(varbind, "tag");
- iid = py_netsnmp_attr_string(varbind, "iid");
-
- tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len,
- NULL, best_guess);
+ if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+ py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+ {
+ oid_arr_len = 0;
+ } else {
+ tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+ }
if (_debug_level)
printf("netsnmp_walk: filling request: %s:%s:%d:%d\n",
@@ -2079,6 +2101,8 @@ netsnmp_getbulk(PyObject *self, PyObject
int err_ind;
int err_num;
char err_str[STR_BUF_SIZE];
+ char *tmpstr;
+ Py_ssize_t tmplen;
oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
@@ -2093,7 +2117,10 @@ netsnmp_getbulk(PyObject *self, PyObject
ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
- strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+ if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+ goto done;
+ }
+ memcpy(&err_str, tmpstr, tmplen);
err_num = py_netsnmp_attr_long(session, "ErrorNum");
err_ind = py_netsnmp_attr_long(session, "ErrorInd");
@@ -2116,11 +2143,13 @@ netsnmp_getbulk(PyObject *self, PyObject
varbinds_iter = PyObject_GetIter(varbinds);
while (varbinds_iter && (varbind = PyIter_Next(varbinds_iter))) {
- tag = py_netsnmp_attr_string(varbind, "tag");
- iid = py_netsnmp_attr_string(varbind, "iid");
-
- tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len,
- NULL, best_guess);
+ if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+ py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+ {
+ oid_arr_len = 0;
+ } else {
+ tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, NULL, best_guess);
+ }
if (oid_arr_len) {
snmp_add_null_var(pdu, oid_arr, oid_arr_len);
@@ -2303,6 +2332,8 @@ netsnmp_set(PyObject *self, PyObject *ar
int err_ind;
int err_num;
char err_str[STR_BUF_SIZE];
+ char *tmpstr;
+ Py_ssize_t tmplen;
oid_arr = calloc(MAX_OID_LEN, sizeof(oid));
@@ -2315,7 +2346,10 @@ netsnmp_set(PyObject *self, PyObject *ar
ss = (SnmpSession *)py_netsnmp_attr_long(session, "sess_ptr");
/* PyObject_SetAttrString(); */
- strcpy(err_str, py_netsnmp_attr_string(session, "ErrorStr"));
+ if (py_netsnmp_attr_string(session, "ErrorStr", &tmpstr, &tmplen) < 0) {
+ goto done;
+ }
+ memcpy(&err_str, tmpstr, tmplen);
err_num = py_netsnmp_attr_long(session, "ErrorNum");
err_ind = py_netsnmp_attr_long(session, "ErrorInd");
@@ -2329,11 +2363,13 @@ netsnmp_set(PyObject *self, PyObject *ar
PyObject *varlist_iter = PyObject_GetIter(varlist);
while (varlist_iter && (varbind = PyIter_Next(varlist_iter))) {
- tag = py_netsnmp_attr_string(varbind, "tag");
- iid = py_netsnmp_attr_string(varbind, "iid");
-
- tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len,
- &type, best_guess);
+ if (py_netsnmp_attr_string(varbind, "tag", &tag, NULL) < 0 ||
+ py_netsnmp_attr_string(varbind, "iid", &iid, NULL) < 0)
+ {
+ oid_arr_len = 0;
+ } else {
+ tp = __tag2oid(tag, iid, oid_arr, &oid_arr_len, &type, best_guess);
+ }
if (oid_arr_len==0) {
if (verbose)
@@ -2344,7 +2380,10 @@ netsnmp_set(PyObject *self, PyObject *ar
}
if (type == TYPE_UNKNOWN) {
- type_str = py_netsnmp_attr_string(varbind, "type");
+ if (py_netsnmp_attr_string(varbind, "type", &type_str, NULL) < 0) {
+ snmp_free_pdu(pdu);
+ goto done;
+ }
type = __translate_appl_type(type_str);
if (type == TYPE_UNKNOWN) {
if (verbose)
@@ -2354,8 +2393,11 @@ netsnmp_set(PyObject *self, PyObject *ar
}
}
- val = py_netsnmp_attr_string(varbind, "val");
- strcpy(tmp_val_str, val);
+ if (py_netsnmp_attr_string(varbind, "val", &val, &tmplen) < 0) {
+ snmp_free_pdu(pdu);
+ goto done;
+ }
+ memcpy(tmp_val_str, val, tmplen);
if (type==TYPE_INTEGER && use_enums && tp && tp->enums) {
for(ep = tp->enums; ep; ep = ep->next) {
if (val && !strcmp(ep->label, val)) {
@@ -2364,7 +2406,7 @@ netsnmp_set(PyObject *self, PyObject *ar
}
}
}
- len = STRLEN(tmp_val_str);
+ len = (int)tmplen;
status = __add_var_val_str(pdu, oid_arr, oid_arr_len,
tmp_val_str, len, type);
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Net-snmp-coders mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders