mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
fix FR #54502: allow user to change OID value output mode when SNMP_VALUE_OBJECT is used.
This commit is contained in:
parent
a3592145f8
commit
a80c2ee19b
5 changed files with 143 additions and 93 deletions
3
NEWS
3
NEWS
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
175
ext/snmp/snmp.c
175
ext/snmp/snmp.c
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue