Skip to content

Commit ee0d7f3

Browse files
author
Boris Lytochkin
committed
* new option for SNMP::get: force keys of return array be as in request array
* new option for SNMP::walk: use suffix of OID for keys in return array, not full OID
1 parent 1dc02ac commit ee0d7f3

File tree

4 files changed

+99
-17
lines changed

4 files changed

+99
-17
lines changed

ext/snmp/php_snmp.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ extern zend_module_entry snmp_module_entry;
4141
#include "TSRM.h"
4242
#endif
4343

44+
#include <net-snmp/net-snmp-config.h>
45+
#include <net-snmp/net-snmp-includes.h>
46+
4447
PHP_MINIT_FUNCTION(snmp);
4548
PHP_MSHUTDOWN_FUNCTION(snmp);
4649
PHP_MINFO_FUNCTION(snmp);
@@ -109,7 +112,8 @@ typedef struct _snmpobjarg {
109112
char *oid;
110113
char type;
111114
char *value;
112-
115+
oid name[MAX_OID_LEN];
116+
size_t name_length;
113117
} snmpobjarg;
114118

115119
ZEND_BEGIN_MODULE_GLOBALS(snmp)

ext/snmp/snmp.c

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ const zend_function_entry snmp_functions[] = {
421421
#define SNMP_CMD_WALK (1<<3)
422422
/* force values-only output */
423423
#define SNMP_NUMERIC_KEYS (1<<7)
424+
/* use user-supplied OID names for keys in array output mode in GET method */
425+
#define SNMP_ORIGINAL_NAMES_AS_KEYS (1<<8)
426+
/* use OID suffix (`index') for keys in array output mode in WALK method */
427+
#define SNMP_USE_SUFFIX_AS_KEYS (1<<9)
424428

425429
#ifdef COMPILE_DL_SNMP
426430
ZEND_GET_MODULE(snmp)
@@ -677,7 +681,7 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
677681
oid root[MAX_NAME_LEN];
678682
size_t rootlen = 0;
679683
int gotroot = 0;
680-
int status, count;
684+
int status, count, found;
681685
char buf[2048];
682686
char buf2[2048];
683687
int keepwalking=1;
@@ -716,6 +720,10 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
716720
memmove((char *)name, (char *)root, rootlen * sizeof(oid));
717721
name_length = rootlen;
718722
objid_query->offset = objid_query->count;
723+
724+
memmove((char *)objid_query->vars[0].name, (char *)root, rootlen * sizeof(oid));
725+
objid_query->vars[0].name_length = rootlen;
726+
719727
}
720728

721729
if ((ss = snmp_open(session)) == NULL) {
@@ -731,11 +739,11 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
731739
if (st & (SNMP_CMD_GET | SNMP_CMD_GETNEXT)) {
732740
pdu = snmp_pdu_create((st & SNMP_CMD_GET) ? SNMP_MSG_GET : SNMP_MSG_GETNEXT);
733741
for (count = 0; objid_query->offset < objid_query->count && count < objid_query->step; objid_query->offset++, count++){
734-
name_length = MAX_OID_LEN;
735-
if (!snmp_parse_oid(objid_query->vars[objid_query->offset].oid, name, &name_length)) {
742+
objid_query->vars[objid_query->offset].name_length = MAX_OID_LEN;
743+
if (!snmp_parse_oid(objid_query->vars[objid_query->offset].oid, objid_query->vars[objid_query->offset].name, &(objid_query->vars[objid_query->offset].name_length))) {
736744
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", objid_query->vars[objid_query->offset].oid);
737745
} else {
738-
snmp_add_null_var(pdu, name, name_length);
746+
snmp_add_null_var(pdu, objid_query->vars[objid_query->offset].name, objid_query->vars[objid_query->offset].name_length);
739747
}
740748
}
741749
if(pdu->variables == NULL){
@@ -747,16 +755,16 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
747755
} else if (st & SNMP_CMD_SET) {
748756
pdu = snmp_pdu_create(SNMP_MSG_SET);
749757
for (count = 0; objid_query->offset < objid_query->count && count < objid_query->step; objid_query->offset++, count++){
750-
name_length = MAX_OID_LEN;
751-
if (!snmp_parse_oid(objid_query->vars[objid_query->offset].oid, name, &name_length)) {
758+
objid_query->vars[objid_query->offset].name_length = MAX_OID_LEN;
759+
if (!snmp_parse_oid(objid_query->vars[objid_query->offset].oid, objid_query->vars[objid_query->offset].name, &(objid_query->vars[objid_query->offset].name_length))) {
752760
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", objid_query->vars[objid_query->offset].oid);
753761
snmp_free_pdu(pdu);
754762
snmp_close(ss);
755763
RETVAL_FALSE;
756764
return;
757765
} else {
758-
if ((snmp_errno = snmp_add_var(pdu, name, name_length, objid_query->vars[objid_query->offset].type, objid_query->vars[objid_query->offset].value))) {
759-
snprint_objid(buf, sizeof(buf), name, name_length);
766+
if ((snmp_errno = snmp_add_var(pdu, objid_query->vars[objid_query->offset].name, objid_query->vars[objid_query->offset].name_length, objid_query->vars[objid_query->offset].type, objid_query->vars[objid_query->offset].value))) {
767+
snprint_objid(buf, sizeof(buf), objid_query->vars[objid_query->offset].name, objid_query->vars[objid_query->offset].name_length);
760768
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not add variable: OID='%s' type='%c' value='%s': %s", buf, objid_query->vars[objid_query->offset].type, objid_query->vars[objid_query->offset].value, snmp_api_errstring(snmp_errno));
761769
snmp_free_pdu(pdu);
762770
snmp_close(ss);
@@ -823,6 +831,34 @@ static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
823831
}
824832
if (st & SNMP_NUMERIC_KEYS) {
825833
add_next_index_zval(return_value, snmpval);
834+
} else if (st & SNMP_ORIGINAL_NAMES_AS_KEYS && st & SNMP_CMD_GET) {
835+
found = 0;
836+
for (count = 0; count < objid_query->count; count++) {
837+
if (objid_query->vars[count].name_length == vars->name_length && snmp_oid_compare(objid_query->vars[count].name, objid_query->vars[count].name_length, vars->name, vars->name_length) == 0) {
838+
found = 1;
839+
objid_query->vars[count].name_length = 0; /* mark this name as used */
840+
break;
841+
}
842+
}
843+
if (found) {
844+
add_assoc_zval(return_value, objid_query->vars[count].oid, snmpval);
845+
} else {
846+
snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length);
847+
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find original OID name for '%s'", buf2);
848+
}
849+
} else if (st & SNMP_USE_SUFFIX_AS_KEYS && st & SNMP_CMD_WALK) {
850+
snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length);
851+
if (objid_query->vars[0].name_length <= vars->name_length && snmp_oid_compare(objid_query->vars[0].name, objid_query->vars[0].name_length, vars->name, objid_query->vars[0].name_length) == 0) {
852+
buf2[0] = '\0';
853+
count = objid_query->vars[0].name_length;
854+
while(count < vars->name_length){
855+
sprintf(buf, "%lu.", vars->name[count]);
856+
strcat(buf2, buf);
857+
count++;
858+
}
859+
buf2[strlen(buf2) - 1] = '\0'; /* remove trailing '.' */
860+
}
861+
add_assoc_zval(return_value, buf2, snmpval);
826862
} else {
827863
snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length);
828864
add_assoc_zval(return_value, buf2, snmpval);
@@ -1276,6 +1312,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
12761312
zval **oid, **value, **type;
12771313
char *a1, *a2, *a3, *a4, *a5, *a6, *a7;
12781314
int a1_len, a2_len, a3_len, a4_len, a5_len, a6_len, a7_len;
1315+
zend_bool use_orignames = 0, suffix_keys = 0;
12791316
long timeout = SNMP_DEFAULT_TIMEOUT;
12801317
long retries = SNMP_DEFAULT_RETRIES;
12811318
int argc = ZEND_NUM_ARGS();
@@ -1327,12 +1364,21 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
13271364
RETURN_FALSE;
13281365
}
13291366
} else if (st & SNMP_CMD_WALK) {
1330-
if (zend_parse_parameters(argc TSRMLS_CC, "Z|ll", &oid, &(objid_query.non_repeaters), &(objid_query.max_repetitions)) == FAILURE) {
1367+
if (zend_parse_parameters(argc TSRMLS_CC, "Z|bll", &oid, &suffix_keys, &(objid_query.non_repeaters), &(objid_query.max_repetitions)) == FAILURE) {
13311368
RETURN_FALSE;
13321369
}
1370+
if (suffix_keys) {
1371+
st |= SNMP_USE_SUFFIX_AS_KEYS;
1372+
}
1373+
} else if (st & SNMP_CMD_GET) {
1374+
if (zend_parse_parameters(argc TSRMLS_CC, "Z|b", &oid, &use_orignames) == FAILURE) {
1375+
RETURN_FALSE;
1376+
}
1377+
if (use_orignames) {
1378+
st |= SNMP_ORIGINAL_NAMES_AS_KEYS;
1379+
}
13331380
} else {
1334-
/* SNMP_CMD_GET
1335-
* SNMP_CMD_GETNEXT
1381+
/* SNMP_CMD_GETNEXT
13361382
*/
13371383
if (zend_parse_parameters(argc TSRMLS_CC, "Z", &oid) == FAILURE) {
13381384
RETURN_FALSE;

ext/snmp/tests/snmp-object-error.phpt

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ var_dump($session->get('.1.3.6.1.2.1.1.1.0'));
4646
var_dump($session->close());
4747

4848
$session = new SNMP(SNMP_VERSION_2c, $hostname, $community, $timeout, $retries);
49-
var_dump($session->walk('.1.3.6.1.2.1.1', ''));
50-
var_dump($session->walk('.1.3.6.1.2.1.1', 0, ''));
49+
var_dump($session->walk('.1.3.6.1.2.1.1', FALSE, ''));
50+
var_dump($session->walk('.1.3.6.1.2.1.1', FALSE, 0, ''));
5151
var_dump($session->get());
52+
var_dump($session->getnext());
5253
var_dump($session->set());
5354

5455
var_dump($session->max_oids);
@@ -75,13 +76,16 @@ Warning: SNMP::get(): Invalid or uninitialized SNMP object in %s on line %d
7576
bool(false)
7677
bool(true)
7778

78-
Warning: SNMP::walk() expects parameter 2 to be long, string given in %s on line %d
79+
Warning: SNMP::walk() expects parameter 3 to be long, string given in %s on line %d
7980
bool(false)
8081

81-
Warning: SNMP::walk() expects parameter 3 to be long, string given in %s on line %d
82+
Warning: SNMP::walk() expects parameter 4 to be long, string given in %s on line %d
83+
bool(false)
84+
85+
Warning: SNMP::get() expects at least 1 parameter, 0 given in %s on line %d
8286
bool(false)
8387

84-
Warning: SNMP::get() expects exactly 1 parameter, 0 given in %s on line %d
88+
Warning: SNMP::getnext() expects exactly 1 parameter, 0 given in %s on line %d
8589
bool(false)
8690

8791
Warning: SNMP::set() expects exactly 3 parameters, 0 given in %s on line %d

ext/snmp/tests/snmp-object.phpt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ var_dump($session->get('.1.3.6.1.2.1.1.1.0'));
3030
var_dump($session->getnext('.1.3.6.1.2.1.1.1.0'));
3131
var_dump($session->close());
3232

33+
echo "GET with preserving original OID names\n";
34+
$session = new SNMP(SNMP_VERSION_2c, $hostname, $community, $timeout, $retries);
35+
$orig = array('.1.3.6.1.2.1.1.1.0', '.1.3.6.1.2.1.1.5.0');
36+
$result = $session->get($orig, TRUE);
37+
foreach($orig as $oid){
38+
var_dump($result[$oid]);
39+
}
40+
var_dump($session->close());
41+
3342
echo "WALK multiple on single OID\n";
3443
$session = new SNMP(SNMP_VERSION_2c, $hostname, $community, $timeout, $retries);
3544
$z = $session->walk('.1.3.6.1.2.1.1');
@@ -67,6 +76,15 @@ var_dump(key($z));
6776
var_dump(array_shift($z));
6877
var_dump($session->close());
6978

79+
echo "WALK multiple on single OID with OID suffix as keys\n";
80+
$session = new SNMP(SNMP_VERSION_2c, $hostname, $community, $timeout, $retries);
81+
$z = $session->walk('.1.3.6.1.2.1.1', TRUE);
82+
var_dump(gettype($z));
83+
var_dump(count($z));
84+
var_dump(key($z));
85+
var_dump(array_shift($z));
86+
var_dump($session->close());
87+
7088
echo "SNMPv3 (default security settings)\n";
7189
$session = new SNMP(SNMP_VERSION_3, $hostname, $user_noauth, $timeout, $retries);
7290
#$session->setSecurity($user_noauth, 'noAuthNoPriv', '', '', '', '', '', '');
@@ -126,6 +144,10 @@ SNMPv2
126144
string(%d) "%S"
127145
string(%d) "%S"
128146
bool(true)
147+
GET with preserving original OID names
148+
string(%d) "%s"
149+
string(%d) "%s"
150+
bool(true)
129151
WALK multiple on single OID
130152
string(5) "array"
131153
int(%d)
@@ -150,6 +172,12 @@ int(%d)
150172
string(%d) "%S"
151173
string(%d) "%S"
152174
bool(true)
175+
WALK multiple on single OID with OID suffix as keys
176+
string(5) "array"
177+
int(%d)
178+
string(3) "1.0"
179+
string(%d) "%s"
180+
bool(true)
153181
SNMPv3 (default security settings)
154182
string(%d) "%S"
155183
string(%d) "%S"

0 commit comments

Comments
 (0)