fix FR #54502: allow user to change OID value output mode when SNMP_VALUE_OBJECT is used.

This commit is contained in:
Boris Lytochkin 2011-07-17 17:27:00 +00:00
parent a3592145f8
commit a80c2ee19b
5 changed files with 143 additions and 93 deletions

3
NEWS
View file

@ -221,6 +221,9 @@ PHP NEWS
. Allow ~infinite OIDs in GET/GETNEXT/SET queries. Autochunk them to max_oids
upon request.
. Introducing unit tests for extension with ~full coverage.
. Way of representing OID value can now be changed when SNMP_VALUE_OBJECT
is used for value output mode. Use or'ed SNMP_VALUE_LIBRARY(default if
not specified) or SNMP_VALUE_PLAIN. (FR #54502)
. Fixed bugs
. #44193 (snmp v3 noAuthNoPriv doesn't work)
. #45893 (Snmp buffer limited to 2048 char)

View file

@ -283,6 +283,13 @@ UPGRADE NOTES - PHP X.Y
- Multi OID get/getnext/set queries are now supported.
- New constants added for use in snmp_set_oid_output_format()
function.
- Function snmp_set_valueretrieval() changed it's behaviour:
SNMP_VALUE_OBJECT can be combined with one of
SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY resulting OID value
changes. When no SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY
is supplied with SNMP_VALUE_OBJECT, SNMP_VALUE_LIBRARY is used.
Prior to 5.4.0 when no SNMP_VALUE_PLAIN or SNMP_VALUE_LIBRARY
was supplied with SNMP_VALUE_OBJECT, SNMP_VALUE_PLAIN was used.
- Added feature-rich OO API (SNMP class)
- Dropped UCD-SNMP compatibility code. Consider upgrading to
net-snmp v5.3+. Net-SNMP v5.4+ is required for Windows version.

View file

@ -94,9 +94,9 @@ extern netsnmp_log_handler *logh_head;
}
#endif
#define SNMP_VALUE_LIBRARY 0
#define SNMP_VALUE_PLAIN 1
#define SNMP_VALUE_OBJECT 2
#define SNMP_VALUE_LIBRARY (0 << 0)
#define SNMP_VALUE_PLAIN (1 << 0)
#define SNMP_VALUE_OBJECT (1 << 1)
typedef struct snmp_session php_snmp_session;
#define PHP_SNMP_SESSION_RES_NAME "SNMP session"
@ -559,7 +559,7 @@ static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_D
int buflen = sizeof(sbuf) - 1;
int val_len = vars->val_len;
if (valueretrieval == SNMP_VALUE_LIBRARY) {
if ((valueretrieval & SNMP_VALUE_PLAIN) == 0) {
val_len += 32; /* snprint_value will add type info into value, make some space for it */
}
@ -575,96 +575,92 @@ static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_D
*buf = 0;
if (valueretrieval == SNMP_VALUE_LIBRARY) {
snprint_value(buf, buflen, vars->name, vars->name_length, vars);
ZVAL_STRING(snmpval, buf, 1);
if(dbuf){ /* malloc was used to store value */
efree(dbuf);
}
return;
}
MAKE_STD_ZVAL(val);
switch (vars->type) {
case ASN_BIT_STR: /* 0x03, asn1.h */
ZVAL_STRINGL(val, (char *)vars->val.bitstring, vars->val_len, 1);
break;
if (valueretrieval & SNMP_VALUE_PLAIN) {
switch (vars->type) {
case ASN_BIT_STR: /* 0x03, asn1.h */
ZVAL_STRINGL(val, (char *)vars->val.bitstring, vars->val_len, 1);
break;
case ASN_OCTET_STR: /* 0x04, asn1.h */
case ASN_OPAQUE: /* 0x44, snmp_impl.h */
ZVAL_STRINGL(val, (char *)vars->val.string, vars->val_len, 1);
break;
case ASN_OCTET_STR: /* 0x04, asn1.h */
case ASN_OPAQUE: /* 0x44, snmp_impl.h */
ZVAL_STRINGL(val, (char *)vars->val.string, vars->val_len, 1);
break;
case ASN_NULL: /* 0x05, asn1.h */
ZVAL_NULL(val);
break;
case ASN_NULL: /* 0x05, asn1.h */
ZVAL_NULL(val);
break;
case ASN_OBJECT_ID: /* 0x06, asn1.h */
snprint_objid(buf, buflen, vars->val.objid, vars->val_len / sizeof(oid));
ZVAL_STRING(val, buf, 1);
break;
case ASN_OBJECT_ID: /* 0x06, asn1.h */
snprint_objid(buf, buflen, vars->val.objid, vars->val_len / sizeof(oid));
ZVAL_STRING(val, buf, 1);
break;
case ASN_IPADDRESS: /* 0x40, snmp_impl.h */
snprintf(buf, buflen, "%d.%d.%d.%d",
(vars->val.string)[0], (vars->val.string)[1],
(vars->val.string)[2], (vars->val.string)[3]);
buf[buflen]=0;
ZVAL_STRING(val, buf, 1);
break;
case ASN_IPADDRESS: /* 0x40, snmp_impl.h */
snprintf(buf, buflen, "%d.%d.%d.%d",
(vars->val.string)[0], (vars->val.string)[1],
(vars->val.string)[2], (vars->val.string)[3]);
buf[buflen]=0;
ZVAL_STRING(val, buf, 1);
break;
case ASN_COUNTER: /* 0x41, snmp_impl.h */
case ASN_GAUGE: /* 0x42, snmp_impl.h */
/* ASN_UNSIGNED is the same as ASN_GAUGE */
case ASN_TIMETICKS: /* 0x43, snmp_impl.h */
case ASN_UINTEGER: /* 0x47, snmp_impl.h */
snprintf(buf, buflen, "%lu", *vars->val.integer);
buf[buflen]=0;
ZVAL_STRING(val, buf, 1);
break;
case ASN_COUNTER: /* 0x41, snmp_impl.h */
case ASN_GAUGE: /* 0x42, snmp_impl.h */
/* ASN_UNSIGNED is the same as ASN_GAUGE */
case ASN_TIMETICKS: /* 0x43, snmp_impl.h */
case ASN_UINTEGER: /* 0x47, snmp_impl.h */
snprintf(buf, buflen, "%lu", *vars->val.integer);
buf[buflen]=0;
ZVAL_STRING(val, buf, 1);
break;
case ASN_INTEGER: /* 0x02, asn1.h */
snprintf(buf, buflen, "%ld", *vars->val.integer);
buf[buflen]=0;
ZVAL_STRING(val, buf, 1);
break;
case ASN_INTEGER: /* 0x02, asn1.h */
snprintf(buf, buflen, "%ld", *vars->val.integer);
buf[buflen]=0;
ZVAL_STRING(val, buf, 1);
break;
#if defined(NETSNMP_WITH_OPAQUE_SPECIAL_TYPES) || defined(OPAQUE_SPECIAL_TYPES)
case ASN_OPAQUE_FLOAT: /* 0x78, asn1.h */
snprintf(buf, buflen, "%f", *vars->val.floatVal);
ZVAL_STRING(val, buf, 1);
break;
case ASN_OPAQUE_FLOAT: /* 0x78, asn1.h */
snprintf(buf, buflen, "%f", *vars->val.floatVal);
ZVAL_STRING(val, buf, 1);
break;
case ASN_OPAQUE_DOUBLE: /* 0x79, asn1.h */
snprintf(buf, buflen, "%Lf", *vars->val.doubleVal);
ZVAL_STRING(val, buf, 1);
break;
case ASN_OPAQUE_DOUBLE: /* 0x79, asn1.h */
snprintf(buf, buflen, "%Lf", *vars->val.doubleVal);
ZVAL_STRING(val, buf, 1);
break;
case ASN_OPAQUE_I64: /* 0x80, asn1.h */
printI64(buf, vars->val.counter64);
ZVAL_STRING(val, buf, 1);
break;
case ASN_OPAQUE_I64: /* 0x80, asn1.h */
printI64(buf, vars->val.counter64);
ZVAL_STRING(val, buf, 1);
break;
case ASN_OPAQUE_U64: /* 0x81, asn1.h */
case ASN_OPAQUE_U64: /* 0x81, asn1.h */
#endif
case ASN_COUNTER64: /* 0x46, snmp_impl.h */
printU64(buf, vars->val.counter64);
ZVAL_STRING(val, buf, 1);
break;
case ASN_COUNTER64: /* 0x46, snmp_impl.h */
printU64(buf, vars->val.counter64);
ZVAL_STRING(val, buf, 1);
break;
default:
ZVAL_STRING(val, "Unknown value type", 1);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown value type: %u", vars->type);
break;
default:
ZVAL_STRING(val, "Unknown value type", 1);
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown value type: %u", vars->type);
break;
}
} else /* use Net-SNMP value translation */ {
snprint_value(buf, buflen, vars->name, vars->name_length, vars);
ZVAL_STRING(val, buf, 1);
}
if (valueretrieval == SNMP_VALUE_PLAIN) {
*snmpval = *val;
zval_copy_ctor(snmpval);
} else {
if (valueretrieval & SNMP_VALUE_OBJECT) {
object_init(snmpval);
add_property_long(snmpval, "type", vars->type);
add_property_zval(snmpval, "value", val);
} else {
*snmpval = *val;
zval_copy_ctor(snmpval);
}
zval_ptr_dtor(&val);
@ -1655,16 +1651,12 @@ PHP_FUNCTION(snmp_set_valueretrieval)
RETURN_FALSE;
}
switch(method) {
case SNMP_VALUE_LIBRARY:
case SNMP_VALUE_PLAIN:
case SNMP_VALUE_OBJECT:
if (method >= 0 && method <= (SNMP_VALUE_LIBRARY|SNMP_VALUE_PLAIN|SNMP_VALUE_OBJECT)) {
SNMP_G(valueretrieval) = method;
RETURN_TRUE;
break;
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown SNMP value retrieval method '%ld'", method);
RETURN_FALSE;
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown SNMP value retrieval method '%ld'", method);
RETURN_FALSE;
}
}
/* }}} */
@ -1673,6 +1665,10 @@ PHP_FUNCTION(snmp_set_valueretrieval)
Return the method how the SNMP values will be returned */
PHP_FUNCTION(snmp_get_valueretrieval)
{
if (zend_parse_parameters_none() == FAILURE) {
RETURN_FALSE;
}
RETURN_LONG(SNMP_G(valueretrieval));
}
/* }}} */
@ -2200,16 +2196,11 @@ static int php_snmp_write_valueretrieval(php_snmp_object *snmp_object, zval *new
newval = &ztmp;
}
switch(Z_LVAL_P(newval)) {
case SNMP_VALUE_LIBRARY:
case SNMP_VALUE_PLAIN:
case SNMP_VALUE_OBJECT:
snmp_object->valueretrieval = Z_LVAL_P(newval);
break;
default:
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown SNMP value retrieval method '%ld'", Z_LVAL_P(newval));
ret = FAILURE;
break;
if (Z_LVAL_P(newval) >= 0 && Z_LVAL_P(newval) <= (SNMP_VALUE_LIBRARY|SNMP_VALUE_PLAIN|SNMP_VALUE_OBJECT)) {
snmp_object->valueretrieval = Z_LVAL_P(newval);
} else {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown SNMP value retrieval method '%ld'", Z_LVAL_P(newval));
ret = FAILURE;
}
if (newval == &ztmp) {

View file

@ -12,6 +12,7 @@ require_once(dirname(__FILE__).'/snmp_include.inc');
echo "Checking error handling\n";
var_dump(snmp_get_valueretrieval('noarg'));
var_dump(snmp_set_valueretrieval());
var_dump(snmp_set_valueretrieval('noarg'));
var_dump(snmp_set_valueretrieval(67));
@ -23,11 +24,20 @@ snmp_set_valueretrieval(SNMP_VALUE_PLAIN);
var_dump(snmp_get_valueretrieval() === SNMP_VALUE_PLAIN);
snmp_set_valueretrieval(SNMP_VALUE_OBJECT);
var_dump(snmp_get_valueretrieval() === SNMP_VALUE_OBJECT);
snmp_set_valueretrieval(SNMP_VALUE_PLAIN|SNMP_VALUE_OBJECT);
var_dump(snmp_get_valueretrieval() === (SNMP_VALUE_PLAIN|SNMP_VALUE_OBJECT));
snmp_set_valueretrieval(SNMP_VALUE_LIBRARY|SNMP_VALUE_OBJECT);
var_dump(snmp_get_valueretrieval() === (SNMP_VALUE_LIBRARY|SNMP_VALUE_OBJECT));
?>
--EXPECTF--
Checking error handling
int(%d)
Warning: snmp_get_valueretrieval() expects exactly 0 parameters, 1 given in %s on line %d
bool(false)
Warning: snmp_set_valueretrieval() expects exactly 1 parameter, 0 given in %s on line %d
bool(false)
Warning: snmp_set_valueretrieval() expects parameter 1 to be long, %s given in %s on line %d
bool(false)
@ -39,3 +49,5 @@ int(%d)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)

View file

@ -28,6 +28,29 @@ echo gettype($z)."\n";
var_dump($z->type);
var_dump($z->value);
echo "Get with SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN\n";
snmp_set_valueretrieval(SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN);
$z = snmpget($hostname, $community, '.1.3.6.1.2.1.1.1.0', $timeout, $retries);
echo gettype($z)."\n";
var_dump($z->type);
var_dump($z->value);
echo "Get with SNMP_VALUE_OBJECT for BITS OID\n";
snmp_set_valueretrieval(SNMP_VALUE_OBJECT);
$z = snmpget($hostname, $community, '.1.3.6.1.2.1.88.1.4.2.1.3.6.95.115.110.109.112.100.95.108.105.110.107.68.111.119.110', $timeout, $retries);
echo gettype($z)."\n";
var_dump($z->type);
var_dump($z->value);
echo "Get with SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN for BITS OID\n";
snmp_set_valueretrieval(SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN);
$z = snmpget($hostname, $community, '.1.3.6.1.2.1.88.1.4.2.1.3.6.95.115.110.109.112.100.95.108.105.110.107.68.111.119.110', $timeout, $retries);
echo gettype($z)."\n";
var_dump($z->type);
var_dump(is_numeric($z->value));
var_dump(is_string($z->value));
var_dump(bin2hex($z->value));
echo "Check parsing of different OID types\n";
snmp_set_valueretrieval(SNMP_VALUE_PLAIN);
var_dump(count(snmp2_walk($hostname, $community, '.', $timeout, $retries)));
@ -41,6 +64,20 @@ string(%d) "%s"
Get with SNMP_VALUE_OBJECT
object
int(4)
string(%d) "STRING: %s"
Get with SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN
object
int(4)
string(%d) "%s"
Get with SNMP_VALUE_OBJECT for BITS OID
object
int(4)
string(25) "BITS: %d %s"
Get with SNMP_VALUE_OBJECT | SNMP_VALUE_PLAIN for BITS OID
object
int(4)
bool(false)
bool(true)
string(2) "%d"
Check parsing of different OID types
int(%d)