Browse Source

- Improved SNMP extension:

. Allow ~infinite OIDs in GET/GETNEXT/SET queries. Autochunk them to max_oids
    upon request.
experimental/with_scalar_types
Boris Lytochkin 15 years ago
parent
commit
dc781e2520
  1. 8
      NEWS
  2. 1
      ext/snmp/php_snmp.h
  3. 68
      ext/snmp/snmp.c
  4. 36
      ext/snmp/tests/snmp_parse_oid.phpt

8
NEWS

@ -200,9 +200,11 @@ PHP NEWS
- Improved SNMP extension:
. Added OO API. FR #53594.
. Sanitized return values of existing functions. Now it returns FALSE on
failure
. Introducing unit tests for extension with ~full coverage
. Fixed bugs #44193, #44193, #45893, #46065, #51336, #53862
failure.
. Allow ~infinite OIDs in GET/GETNEXT/SET queries. Autochunk them to max_oids
upon request.
. Introducing unit tests for extension with ~full coverage.
. Fixed bugs #44193, #44193, #45893, #46065, #51336, #53862.
## UNSORTED ##

1
ext/snmp/php_snmp.h

@ -83,6 +83,7 @@ PHP_METHOD(SNMP, set);
typedef struct _php_snmp_object {
zend_object zo;
struct snmp_session *session;
int max_oids;
int valueretrieval;
int quick_print;
#ifdef HAVE_NET_SNMP

68
ext/snmp/snmp.c

@ -405,13 +405,12 @@ typedef struct _snmpobjarg {
} snmpobjarg;
#define SNMP_MAXOIDS_IN_PDU 64
struct objid_set {
int count;
int offset;
int step;
int array_output;
snmpobjarg vars[SNMP_MAXOIDS_IN_PDU];
snmpobjarg *vars;
};
/* {{{ snmp_functions[]
@ -548,7 +547,7 @@ static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_D
buf = dbuf;
buflen = val_len;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "malloc() failed: %s, fallback to static array", strerror(errno));
php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed: %s, fallback to static array", strerror(errno));
}
}
@ -931,6 +930,11 @@ static int php_snmp_parse_oid(int st, struct objid_set *objid_set, zval **oid, z
objid_set->count = 0;
objid_set->array_output = ((st & SNMP_CMD_WALK) ? TRUE : FALSE);
if (Z_TYPE_PP(oid) == IS_STRING) {
objid_set->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg));
if (objid_set->vars == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed while parsing oid: %s", strerror(errno));
return FALSE;
}
objid_set->vars[objid_set->count].oid = Z_STRVAL_PP(oid);
if (st & SNMP_CMD_SET) {
if (Z_TYPE_PP(type) == IS_STRING && Z_TYPE_PP(value) == IS_STRING) {
@ -952,6 +956,11 @@ static int php_snmp_parse_oid(int st, struct objid_set *objid_set, zval **oid, z
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Got empty OID array");
return FALSE;
}
objid_set->vars = (snmpobjarg *)emalloc(sizeof(snmpobjarg) * zend_hash_num_elements(Z_ARRVAL_PP(oid)));
if (objid_set->vars == NULL) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "emalloc() failed while parsing oid array: %s", strerror(errno));
return FALSE;
}
objid_set->array_output = ( (st & SNMP_CMD_SET) ? FALSE : TRUE );
for ( zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(oid), &pos_oid);
zend_hash_get_current_data_ex(Z_ARRVAL_PP(oid), (void **) &tmp_oid, &pos_oid) == SUCCESS;
@ -992,11 +1001,7 @@ static int php_snmp_parse_oid(int st, struct objid_set *objid_set, zval **oid, z
}
}
}
if (objid_set->count++ >= SNMP_MAXOIDS_IN_PDU) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not process more than %u OIDs in singe GET/GETNEXT/SET query", SNMP_MAXOIDS_IN_PDU);
return FALSE;
}
objid_set->count++;
}
}
@ -1269,7 +1274,7 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
long timeout = SNMP_DEFAULT_TIMEOUT;
long retries = SNMP_DEFAULT_RETRIES;
int non_repeaters = 0;
int max_repetitions = 20;
int max_repetitions = -1;
int argc = ZEND_NUM_ARGS();
struct objid_set objid_set;
php_snmp_session *session;
@ -1345,6 +1350,12 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
zval *object = getThis();
PHP_SNMP_SESSION_FROM_OBJECT(session, object);
snmp_object = (php_snmp_object *)zend_object_store_get_object(object TSRMLS_CC);
if (snmp_object->max_oids > 0) {
objid_set.step = snmp_object->max_oids;
if (max_repetitions < 0) { // unspecified in function call, use session-wise
max_repetitions = snmp_object->max_oids;
}
}
valueretrieval = snmp_object->valueretrieval;
#ifdef HAVE_NET_SNMP
glob_snmp_object.enum_print = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM);
@ -1359,7 +1370,13 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
#endif
}
if (max_repetitions < 0) {
max_repetitions = 20; // provide correct default value
}
php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, session, &objid_set, non_repeaters, max_repetitions, valueretrieval);
efree(objid_set.vars);
if (session_less_mode) {
netsnmp_session_free(&session);
@ -1678,6 +1695,7 @@ PHP_METHOD(snmp, open)
if (netsnmp_session_init(&(snmp_object->session), version, a1, a2, timeout, retries TSRMLS_CC)) {
return;
}
snmp_object->max_oids = 0;
snmp_object->valueretrieval = SNMP_G(valueretrieval);
#ifdef HAVE_NET_SNMP
snmp_object->enum_print = netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM);
@ -1931,6 +1949,15 @@ static HashTable *php_snmp_get_properties(zval *object TSRMLS_DC)
}
/* }}} */
/* {{{ */
static int php_snmp_read_max_oids(php_snmp_object *snmp_object, zval **retval TSRMLS_DC)
{
MAKE_STD_ZVAL(*retval);
ZVAL_LONG(*retval, snmp_object->max_oids);
return SUCCESS;
}
/* }}} */
/* {{{ */
static int php_snmp_read_valueretrieval(php_snmp_object *snmp_object, zval **retval TSRMLS_DC)
{
@ -1969,6 +1996,28 @@ static int php_snmp_read_oid_output_format(php_snmp_object *snmp_object, zval **
/* }}} */
#endif
/* {{{ */
static int php_snmp_write_max_oids(php_snmp_object *snmp_object, zval *newval TSRMLS_DC)
{
zval ztmp;
int ret = SUCCESS;
if (Z_TYPE_P(newval) != IS_LONG) {
ztmp = *newval;
zval_copy_ctor(&ztmp);
convert_to_long(&ztmp);
newval = &ztmp;
}
snmp_object->max_oids = Z_LVAL_P(newval);
if (newval == &ztmp) {
zval_dtor(newval);
}
return ret;
}
/* }}} */
/* {{{ */
static int php_snmp_write_valueretrieval(php_snmp_object *snmp_object, zval *newval TSRMLS_DC)
{
@ -2096,6 +2145,7 @@ static zend_function_entry php_snmp_class_methods[] = {
{ "" #name "", sizeof("" #name "") - 1, php_snmp_read_##name, php_snmp_write_##name }
const php_snmp_prop_handler php_snmp_property_entries[] = {
PHP_SNMP_PROPERTY_ENTRY_RECORD(max_oids),
PHP_SNMP_PROPERTY_ENTRY_RECORD(valueretrieval),
PHP_SNMP_PROPERTY_ENTRY_RECORD(quick_print),
#ifdef HAVE_NET_SNMP

36
ext/snmp/tests/snmp_parse_oid.phpt

@ -1,36 +0,0 @@
--TEST--
Function snmp_parse_oid
--CREDITS--
Boris Lytochkin
--SKIPIF--
<?php
require_once(dirname(__FILE__).'/skipif.inc');
?>
--FILE--
<?php
require_once(dirname(__FILE__).'/snmp_include.inc');
//EXPECTF format is quickprint OFF
snmp_set_quick_print(false);
snmp_set_valueretrieval(SNMP_VALUE_PLAIN);
$oid1 = 'SNMPv2-MIB::sysContact.0';
$type1 = 's';
$oldvalue1 = snmpget($hostname, $communityWrite, $oid1, $timeout, $retries);
$newvalue1 = $oldvalue1 . '0';
echo "Checking SNMP_MAXOIDS_IN_PDU\n";
$i = 0;
$oids = array();
while($i++ < 128){
$oids[] = '.1.3.6.1.2.1.1.7.0';
}
$z = snmp2_get($hostname, $community, $oids, $timeout, $retries);
var_dump($z);
?>
--EXPECTF--
Checking SNMP_MAXOIDS_IN_PDU
Warning: snmp2_get(): Could not process more than %d OIDs in singe GET/GETNEXT/SET query in %s on line %d
bool(false)
Loading…
Cancel
Save