]> granicus.if.org Git - php/commitdiff
fix FR #54502: allow user to change OID value output mode when SNMP_VALUE_OBJECT...
authorBoris Lytochkin <lytboris@php.net>
Sun, 17 Jul 2011 17:27:00 +0000 (17:27 +0000)
committerBoris Lytochkin <lytboris@php.net>
Sun, 17 Jul 2011 17:27:00 +0000 (17:27 +0000)
NEWS
UPGRADING
ext/snmp/snmp.c
ext/snmp/tests/snmp_get_valueretrieval.phpt
ext/snmp/tests/snmp_getvalue.phpt

diff --git a/NEWS b/NEWS
index 9bc1b7da0cc93cc3add446ab1610521220381057..7a792084906f4f98952f60afcba475b43c655319 100644 (file)
--- a/NEWS
+++ b/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)
index 534e8bf5b7c1241f30718ee1e51acc774faa1044..9fec6dd689b60850b92a24582034d05ec8661b9c 100755 (executable)
--- a/UPGRADING
+++ b/UPGRADING
@@ -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.
index 529be7e4a5e2c150d61d36cb758eb1c09f10cb27..7507640debb9c0f8e45ac23e8c942b6455738191 100644 (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_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_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_INTEGER:               /* 0x02, asn1.h */
-               snprintf(buf, buflen, "%ld", *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;
 
 #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) {
index 90bd0bab6407f8c5e04e6e6de0a3ccd82c1d22a2..660d643e41d004837e415df5f3d4aee86c837b8b 100644 (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)
index 0eefbb335e8f42e3da77dc3400c203f6563c2df1..178354a8cfbc7490f76c030b93547a16b10be8ab 100644 (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)