php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #37865
Patch ext_snmp_v1.0.1.patch revision 2010-08-11 07:59 UTC by saimoun at saimoun dot fr
Patch ext_snmp.patch revision 2010-07-28 09:55 UTC by saimoun at saimoun dot fr

Patch ext_snmp_v1.0.1.patch for SNMP related Bug #37865

Patch version 2010-08-11 07:59 UTC

Return to Bug #37865 | Download this patch
This patch renders other patches obsolete

Obsolete patches:

Patch Revisions:

Developer: saimoun@saimoun.fr

diff -ru snmp.old/php_snmp.h snmp/php_snmp.h
--- snmp.old/php_snmp.h	2010-08-11 09:53:05.717261431 +0200
+++ snmp/php_snmp.h	2010-08-11 09:49:50.905494244 +0200
@@ -63,6 +63,7 @@
 PHP_FUNCTION(snmp3_walk);
 PHP_FUNCTION(snmp3_real_walk);
 PHP_FUNCTION(snmp3_set);
+PHP_FUNCTION(snmp3_mset);
 
 PHP_FUNCTION(snmp_set_valueretrieval);
 PHP_FUNCTION(snmp_get_valueretrieval);
diff -ru snmp.old/snmp.c snmp/snmp.c
--- snmp.old/snmp.c	2010-08-11 09:53:05.717261431 +0200
+++ snmp/snmp.c	2010-08-11 09:49:50.893261764 +0200
@@ -17,6 +17,7 @@
    |          Steven Lawrance <slawrance@technologist.com>                |
    |          Harrie Hazewinkel <harrie@lisanza.net>                      |
    |          Johann Hanne <jonny@nurfuerspam.de>                         |
+   |	      Simon Lasnier <saimoun@saimoun.fr>			  |
    +----------------------------------------------------------------------+
  */
 
@@ -287,6 +288,21 @@
 	ZEND_ARG_INFO(0, retries)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp3_mset, 0, 0, 10)
+	ZEND_ARG_INFO(0, host)
+	ZEND_ARG_INFO(0, sec_name)
+	ZEND_ARG_INFO(0, sec_level)
+	ZEND_ARG_INFO(0, auth_protocol)
+	ZEND_ARG_INFO(0, auth_passphrase)
+	ZEND_ARG_INFO(0, priv_protocol)
+	ZEND_ARG_INFO(0, priv_passphrase)
+	ZEND_ARG_INFO(0, object_ids)
+	ZEND_ARG_INFO(0, types)
+	ZEND_ARG_INFO(0, values)
+	ZEND_ARG_INFO(0, timeout)
+	ZEND_ARG_INFO(0, retries)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_set_valueretrieval, 0, 0, 1)
 	ZEND_ARG_INFO(0, method)
 ZEND_END_ARG_INFO()
@@ -327,6 +343,7 @@
 	PHP_FE(snmp3_walk, 				arginfo_snmp3_walk)
 	PHP_FE(snmp3_real_walk, 		arginfo_snmp3_real_walk)
 	PHP_FE(snmp3_set, 				arginfo_snmp3_set)
+	PHP_FE(snmp3_mset, 				arginfo_snmp3_mset)
 	PHP_FE(snmp_set_valueretrieval, arginfo_snmp_set_valueretrieval)
 	PHP_FE(snmp_get_valueretrieval, arginfo_snmp_get_valueretrieval)
 
@@ -430,6 +447,7 @@
 #ifdef HAVE_NET_SNMP
 	php_info_print_table_row(2, "NET-SNMP Support", "enabled");
 	php_info_print_table_row(2, "NET-SNMP Version", netsnmp_get_version());
+	php_info_print_table_row(2, "Multiple SET Request Support", "enabled");
 #else
 	php_info_print_table_row(2, "UCD-SNMP Support", "enabled");
 	php_info_print_table_row(2, "UCD-SNMP Version", VersionInfo);
@@ -678,7 +696,7 @@
 						if (vars->type != SNMP_ENDOFMIBVIEW && 
 							vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) {
 							if (snmp_oid_compare(name, name_length, vars->name, vars->name_length) >= 0) {
-								php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error: OID not increasing: %s",name);
+								php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error: OID not increasing: %s",(char*)name);
 								keepwalking = 0;
 							} else {
 								memmove((char *)name, (char *)vars->name,vars->name_length * sizeof(oid));
@@ -1302,6 +1320,171 @@
 }
 /* }}} */
 
+/* {{{ proto int snmp3_mset(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, array object_ids, array types, array values [, int timeout [, int retries]])
+   Fetch values of multiple SNMP objects */
+PHP_FUNCTION(snmp3_mset)
+{
+	char *a1, *a2, *a3, *a4, *a5, *a6, *a7;
+	int a1_len, a2_len, a3_len, a4_len, a5_len, a6_len, a7_len;
+	zval *z_oids, *z_types, *z_values, **curr_oid, **curr_type, **curr_value;
+	HashTable *h_oids, *h_types, *h_values;
+	HashPosition ptr_oids, ptr_types, ptr_values;
+	struct snmp_session session, *ss = NULL;
+	struct snmp_pdu *pdu = NULL, *response;
+	long timeout = SNMP_DEFAULT_TIMEOUT;
+	long retries = SNMP_DEFAULT_RETRIES;
+	char hostname[MAX_NAME_LEN];
+	char buf[2048];
+	int remote_port = 161, status;
+	char *pptr = NULL, *err = NULL;
+	int argc = ZEND_NUM_ARGS();
+	oid the_oid[MAX_OID_LEN];
+	size_t the_oid_len;
+	zval type, value;
+	
+	if (zend_parse_parameters(argc TSRMLS_CC, "sssssssaaa|ll", &a1, &a1_len, &a2, &a2_len,
+	    &a3, &a3_len, &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &z_oids, &z_types,
+	    &z_values, &timeout, &retries) == FAILURE) {
+		return;
+	}
+
+	h_oids = Z_ARRVAL_P(z_oids);
+	h_types = Z_ARRVAL_P(z_types);
+	h_values = Z_ARRVAL_P(z_values);
+
+	snmp_sess_init(&session);
+	session.version = SNMP_VERSION_3;
+
+	/* Reading the hostname and its optional non-default port number */
+	strlcpy(hostname, a1, sizeof(hostname));
+	if ((pptr = strchr(hostname, ':'))) {
+		remote_port = strtol(pptr + 1, NULL, 0);
+	}
+	session.peername = hostname;
+	session.remote_port = remote_port;
+
+	/* Setting the security name. */
+	if (netsnmp_session_set_sec_name(&session, a2)) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could net set security name: %s", a2);
+		RETURN_FALSE;
+	}
+
+	/* Setting the security level. */
+	if (netsnmp_session_set_sec_level(&session, a3 TSRMLS_CC)) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid security level: %s", a3);
+		RETURN_FALSE;
+	}
+
+	/* Setting the authentication protocol. */
+	if (netsnmp_session_set_auth_protocol(&session, a4 TSRMLS_CC)) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid authentication protocol: %s", a4);
+		RETURN_FALSE;
+	}
+
+	/* Setting the authentication passphrase. */
+	if (netsnmp_session_gen_auth_key(&session, a5 TSRMLS_CC)) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not generate key for authentication pass phrase: %s", a5);
+		RETURN_FALSE;
+	}
+
+	/* Setting the security protocol. */
+	if (netsnmp_session_set_sec_protocol(&session, a6 TSRMLS_CC) && a6_len) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid security protocol: %s", a6);
+		RETURN_FALSE;
+	}
+
+	/* Setting the security protocol passphrase. */
+	if (netsnmp_session_gen_sec_key(&session, a7 TSRMLS_CC) && a7_len) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not generate key for security pass phrase: %s", a7);
+		RETURN_FALSE;
+	}
+
+	session.retries = retries;
+	session.timeout = timeout;
+
+	if ((ss = snmp_open(&session)) == NULL) {
+		snmp_error(&session, NULL, NULL, &err);
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open snmp connection: %s", err);
+		free(err);
+		RETURN_FALSE;
+	}
+
+	pdu = snmp_pdu_create(SNMP_MSG_SET);
+
+	for (zend_hash_internal_pointer_reset_ex(h_oids, &ptr_oids),
+	     zend_hash_internal_pointer_reset_ex(h_types, &ptr_types),
+	     zend_hash_internal_pointer_reset_ex(h_values, &ptr_values) ;
+		zend_hash_get_current_data_ex(h_oids, (void**) &curr_oid, &ptr_oids) == SUCCESS
+	        && zend_hash_get_current_data_ex(h_types, (void**) &curr_type, &ptr_types) == SUCCESS
+		&& zend_hash_get_current_data_ex(h_values, (void**) &curr_value, &ptr_values) == SUCCESS ;
+		    zend_hash_move_forward_ex(h_oids, &ptr_oids),
+		    zend_hash_move_forward_ex(h_types, &ptr_types),
+		    zend_hash_move_forward_ex(h_values, &ptr_values) ) {
+	    
+	    if (Z_TYPE_PP(curr_oid) != IS_STRING) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Each object identifier (in the array) must be a string", buf);
+		snmp_free_pdu(pdu);
+		snmp_close(ss);
+		RETURN_FALSE;
+	    }
+
+	    the_oid_len = MAX_OID_LEN;
+	    if (snmp_parse_oid(Z_STRVAL_PP(curr_oid), the_oid, &the_oid_len) == NULL) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", Z_STRVAL_PP(curr_oid));
+		snmp_free_pdu(pdu);
+		snmp_close(ss);
+		RETURN_FALSE;
+	    }
+	    
+	    type = **curr_type;
+	    value = **curr_value;
+	    zval_copy_ctor(&type);
+	    zval_copy_ctor(&value);
+	    convert_to_string(&type);
+	    convert_to_string(&value);
+
+	    if (snmp_add_var(pdu, the_oid, the_oid_len, (Z_STRVAL(type))[0], Z_STRVAL(value))) {
+#ifdef HAVE_NET_SNMP
+		snprint_objid(buf, sizeof(buf), the_oid, the_oid_len);
+#else
+		sprint_objid(buf, the_oid, the_oid_len);
+#endif
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not add variable: %s %c %s", buf, (Z_STRVAL(type))[0], Z_STRVAL(value));
+		zval_dtor(&value);
+		zval_dtor(&type);
+		snmp_free_pdu(pdu);
+		snmp_close(ss);
+		RETURN_FALSE;
+	    }
+	    
+	    zval_dtor(&value);
+	    zval_dtor(&type);
+	}
+
+	status = snmp_synch_response(ss, pdu, &response);
+
+	if (status != STAT_SUCCESS || response->errstat != SNMP_ERR_NOERROR) {
+	    if (status == STAT_SUCCESS) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in packet: %s", snmp_errstring(response->errstat));
+		snmp_free_pdu(response);
+	    } else if (status == STAT_TIMEOUT) {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "No response from %s", session.peername);
+	    } else {
+		php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred, quitting");
+	    }
+	    snmp_close(ss);
+	    RETURN_FALSE;
+	}
+	
+	if (response) {
+	    snmp_free_pdu(response);
+	}
+	
+	snmp_close(ss);
+	RETURN_TRUE;
+}
+/* }}} */
+
 /* {{{ proto void snmp_set_valueretrieval(int method)
    Specify the method how the SNMP values will be returned */
 PHP_FUNCTION(snmp_set_valueretrieval)
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 12:01:27 2024 UTC