PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - snmp - snmp.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 464
Code covered: 7.1 % Executed lines: 33
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Rasmus Lerdorf <rasmus@php.net>                             |
      16                 :    |          Mike Jackson <mhjack@tscnet.com>                            |
      17                 :    |          Steven Lawrance <slawrance@technologist.com>                |
      18                 :    |          Harrie Hazewinkel <harrie@lisanza.net>                      |
      19                 :    |          Johann Hanne <jonny@nurfuerspam.de>                         |
      20                 :    +----------------------------------------------------------------------+
      21                 :  */
      22                 : 
      23                 : /* $Id: snmp.c 289918 2009-10-25 20:17:04Z jani $ */
      24                 : 
      25                 : #ifdef HAVE_CONFIG_H
      26                 : #include "config.h"
      27                 : #endif
      28                 : 
      29                 : #include "php.h"
      30                 : #include "ext/standard/info.h"
      31                 : #include "php_snmp.h"
      32                 : 
      33                 : #if HAVE_SNMP
      34                 : 
      35                 : #include <sys/types.h>
      36                 : #ifdef PHP_WIN32
      37                 : #include <winsock2.h>
      38                 : #include <errno.h>
      39                 : #include <process.h>
      40                 : #include "win32/time.h"
      41                 : #elif defined(NETWARE)
      42                 : #ifdef USE_WINSOCK
      43                 : #include <novsock2.h>
      44                 : #else
      45                 : #include <sys/socket.h>
      46                 : #endif
      47                 : #include <errno.h>
      48                 : #include <sys/timeval.h>
      49                 : #else
      50                 : #include <sys/socket.h>
      51                 : #include <netinet/in.h>
      52                 : #include <arpa/inet.h>
      53                 : #ifndef _OSD_POSIX
      54                 : #include <sys/errno.h>
      55                 : #else
      56                 : #include <errno.h>  /* BS2000/OSD uses <errno.h>, not <sys/errno.h> */
      57                 : #endif
      58                 : #include <netdb.h>
      59                 : #endif
      60                 : #ifdef HAVE_UNISTD_H
      61                 : #include <unistd.h>
      62                 : #endif
      63                 : 
      64                 : #ifndef __P
      65                 : #ifdef __GNUC__
      66                 : #define __P(args) args
      67                 : #else
      68                 : #define __P(args) ()
      69                 : #endif
      70                 : #endif
      71                 : 
      72                 : #ifdef HAVE_NET_SNMP
      73                 : #include <net-snmp/net-snmp-config.h>
      74                 : #include <net-snmp/net-snmp-includes.h>
      75                 : #else
      76                 : #ifdef HAVE_DEFAULT_STORE_H
      77                 : #include "default_store.h"
      78                 : #endif
      79                 : #include "asn1.h"
      80                 : #include "snmp_api.h"
      81                 : #include "snmp_client.h"
      82                 : #include "snmp_impl.h"
      83                 : #include "snmp.h"
      84                 : #include "snmpv3.h"
      85                 : #include "keytools.h"
      86                 : #include "parse.h"
      87                 : #include "mib.h"
      88                 : #ifndef PHP_WIN32
      89                 : /* this doesn't appear to be needed under win32 (perhaps at all)
      90                 :  * and the header file is not present in my UCD-SNMP headers */
      91                 : # include "version.h"
      92                 : #endif
      93                 : #include "transform_oids.h"
      94                 : #endif
      95                 : /* Ugly macro, since the length of OIDs in UCD-SNMP and NET-SNMP
      96                 :  * is different and this way the code is not full of 'ifdef's.
      97                 :  */
      98                 : #define OIDSIZE(p) (sizeof(p)/sizeof(oid))
      99                 : 
     100                 : /* For really old ucd-snmp versions.. */
     101                 : #ifndef HAVE_SNMP_PARSE_OID
     102                 : #define snmp_parse_oid read_objid
     103                 : #endif
     104                 : 
     105                 : #define SNMP_VALUE_LIBRARY      0
     106                 : #define SNMP_VALUE_PLAIN        1
     107                 : #define SNMP_VALUE_OBJECT       2
     108                 : 
     109                 : ZEND_DECLARE_MODULE_GLOBALS(snmp)
     110                 : static PHP_GINIT_FUNCTION(snmp);
     111                 : 
     112                 : /* constant - can be shared among threads */
     113                 : static oid objid_mib[] = {1, 3, 6, 1, 2, 1};
     114                 : 
     115                 : /* {{{ snmp_functions[]
     116                 :  */
     117                 : zend_function_entry snmp_functions[] = {
     118                 :         PHP_FE(snmpget, NULL)
     119                 :         PHP_FE(snmpgetnext, NULL)
     120                 :         PHP_FE(snmpwalk, NULL)
     121                 :         PHP_FE(snmprealwalk, NULL)
     122                 :         PHP_FALIAS(snmpwalkoid, snmprealwalk, NULL)
     123                 :         PHP_FE(snmp_get_quick_print, NULL)
     124                 :         PHP_FE(snmp_set_quick_print, NULL)
     125                 : #ifdef HAVE_NET_SNMP
     126                 :         PHP_FE(snmp_set_enum_print, NULL)
     127                 :         PHP_FE(snmp_set_oid_output_format, NULL)
     128                 :         PHP_FALIAS(snmp_set_oid_numeric_print, snmp_set_oid_output_format, NULL)
     129                 : #endif
     130                 :         PHP_FE(snmpset, NULL)
     131                 : 
     132                 :         PHP_FE(snmp2_get, NULL)
     133                 :         PHP_FE(snmp2_getnext, NULL)
     134                 :         PHP_FE(snmp2_walk, NULL)
     135                 :         PHP_FE(snmp2_real_walk, NULL)
     136                 :         PHP_FE(snmp2_set, NULL)
     137                 : 
     138                 :         PHP_FE(snmp3_get, NULL)
     139                 :         PHP_FE(snmp3_getnext, NULL)
     140                 :         PHP_FE(snmp3_walk, NULL)
     141                 :         PHP_FE(snmp3_real_walk, NULL)
     142                 :         PHP_FE(snmp3_set, NULL)
     143                 :         PHP_FE(snmp_set_valueretrieval, NULL)
     144                 :         PHP_FE(snmp_get_valueretrieval, NULL)
     145                 : 
     146                 :         PHP_FE(snmp_read_mib, NULL)
     147                 :         {NULL,NULL,NULL}
     148                 : };
     149                 : /* }}} */
     150                 : 
     151                 : #define SNMP_CMD_GET            1
     152                 : #define SNMP_CMD_GETNEXT        2
     153                 : #define SNMP_CMD_WALK           3
     154                 : #define SNMP_CMD_REALWALK       4
     155                 : #define SNMP_CMD_SET            11
     156                 : 
     157                 : /* {{{ snmp_module_entry
     158                 :  */
     159                 : zend_module_entry snmp_module_entry = {
     160                 :         STANDARD_MODULE_HEADER,
     161                 :         "snmp",
     162                 :         snmp_functions,
     163                 :         PHP_MINIT(snmp),
     164                 :         PHP_MSHUTDOWN(snmp),
     165                 :         NULL,
     166                 :         NULL,
     167                 :         PHP_MINFO(snmp),
     168                 :         NO_VERSION_YET,
     169                 :         PHP_MODULE_GLOBALS(snmp),
     170                 :         PHP_GINIT(snmp),
     171                 :         NULL,
     172                 :         NULL,
     173                 :         STANDARD_MODULE_PROPERTIES_EX
     174                 : };
     175                 : /* }}} */
     176                 : 
     177                 : #ifdef COMPILE_DL_SNMP
     178                 : ZEND_GET_MODULE(snmp)
     179                 : #endif
     180                 : 
     181                 : /* THREAD_LS snmp_module php_snmp_module; - may need one of these at some point */
     182                 : 
     183                 : /* {{{ PHP_GINIT_FUNCTION
     184                 :  */
     185                 : static PHP_GINIT_FUNCTION(snmp)
     186           13565 : {
     187           13565 :         snmp_globals->valueretrieval = SNMP_VALUE_LIBRARY;
     188           13565 : }
     189                 : /* }}} */
     190                 : 
     191                 : /* {{{ PHP_MINIT_FUNCTION
     192                 :  */
     193                 : PHP_MINIT_FUNCTION(snmp)
     194           13565 : {
     195           13565 :         init_snmp("snmpapp");
     196                 : 
     197                 : #ifdef NETSNMP_DS_LIB_DONT_PERSIST_STATE
     198                 :         /* Prevent update of the snmpapp.conf file */
     199           13565 :         netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1);
     200                 : #endif
     201                 : 
     202                 : #ifdef HAVE_NET_SNMP
     203           13565 :         REGISTER_LONG_CONSTANT("SNMP_OID_OUTPUT_FULL", NETSNMP_OID_OUTPUT_FULL, CONST_CS | CONST_PERSISTENT);
     204           13565 :         REGISTER_LONG_CONSTANT("SNMP_OID_OUTPUT_NUMERIC", NETSNMP_OID_OUTPUT_NUMERIC, CONST_CS | CONST_PERSISTENT);
     205                 : #endif
     206                 : 
     207           13565 :         REGISTER_LONG_CONSTANT("SNMP_VALUE_LIBRARY", SNMP_VALUE_LIBRARY, CONST_CS | CONST_PERSISTENT);
     208           13565 :         REGISTER_LONG_CONSTANT("SNMP_VALUE_PLAIN", SNMP_VALUE_PLAIN, CONST_CS | CONST_PERSISTENT);
     209           13565 :         REGISTER_LONG_CONSTANT("SNMP_VALUE_OBJECT", SNMP_VALUE_OBJECT, CONST_CS | CONST_PERSISTENT);
     210                 : 
     211           13565 :         REGISTER_LONG_CONSTANT("SNMP_BIT_STR", ASN_BIT_STR, CONST_CS | CONST_PERSISTENT);
     212           13565 :         REGISTER_LONG_CONSTANT("SNMP_OCTET_STR", ASN_OCTET_STR, CONST_CS | CONST_PERSISTENT);
     213           13565 :         REGISTER_LONG_CONSTANT("SNMP_OPAQUE", ASN_OPAQUE, CONST_CS | CONST_PERSISTENT);
     214           13565 :         REGISTER_LONG_CONSTANT("SNMP_NULL", ASN_NULL, CONST_CS | CONST_PERSISTENT);
     215           13565 :         REGISTER_LONG_CONSTANT("SNMP_OBJECT_ID", ASN_OBJECT_ID, CONST_CS | CONST_PERSISTENT);
     216           13565 :         REGISTER_LONG_CONSTANT("SNMP_IPADDRESS", ASN_IPADDRESS, CONST_CS | CONST_PERSISTENT);
     217           13565 :         REGISTER_LONG_CONSTANT("SNMP_COUNTER", ASN_GAUGE, CONST_CS | CONST_PERSISTENT);
     218           13565 :         REGISTER_LONG_CONSTANT("SNMP_UNSIGNED", ASN_UNSIGNED, CONST_CS | CONST_PERSISTENT);
     219           13565 :         REGISTER_LONG_CONSTANT("SNMP_TIMETICKS", ASN_TIMETICKS, CONST_CS | CONST_PERSISTENT);
     220           13565 :         REGISTER_LONG_CONSTANT("SNMP_UINTEGER", ASN_UINTEGER, CONST_CS | CONST_PERSISTENT);
     221           13565 :         REGISTER_LONG_CONSTANT("SNMP_INTEGER", ASN_INTEGER, CONST_CS | CONST_PERSISTENT);
     222           13565 :         REGISTER_LONG_CONSTANT("SNMP_COUNTER64", ASN_COUNTER64, CONST_CS | CONST_PERSISTENT);
     223                 : 
     224           13565 :         return SUCCESS;
     225                 : }
     226                 : /* }}} */
     227                 : 
     228                 : /* {{{ PHP_MSHUTDOWN_FUNCTION
     229                 :  */
     230                 : PHP_MSHUTDOWN_FUNCTION(snmp)
     231           13598 : {
     232           13598 :         snmp_shutdown("snmpapp");
     233                 : 
     234           13598 :         return SUCCESS;
     235                 : }
     236                 : /* }}} */
     237                 : 
     238                 : /* {{{ PHP_MINFO_FUNCTION
     239                 :  */
     240                 : PHP_MINFO_FUNCTION(snmp)
     241               6 : {
     242               6 :         php_info_print_table_start();
     243                 : #ifdef HAVE_NET_SNMP
     244               6 :         php_info_print_table_row(2, "NET-SNMP Support", "enabled");
     245               6 :         php_info_print_table_row(2, "NET-SNMP Version", netsnmp_get_version());
     246                 : #else
     247                 :         php_info_print_table_row(2, "UCD-SNMP Support", "enabled");
     248                 :         php_info_print_table_row(2, "UCD-SNMP Version", VersionInfo);
     249                 : #endif
     250               6 :         php_info_print_table_end();
     251               6 : }
     252                 : /* }}} */
     253                 : 
     254                 : static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_DC)
     255               0 : {
     256                 :         zval *val;
     257                 : #if I64CHARSZ > 2047
     258                 :         char buf[I64CHARSZ + 1];
     259                 : #else
     260                 :         char buf[2048];
     261                 : #endif
     262                 : 
     263               0 :         buf[0] = 0;
     264                 : 
     265               0 :         if (SNMP_G(valueretrieval) == SNMP_VALUE_LIBRARY) {
     266                 : #ifdef HAVE_NET_SNMP
     267               0 :                 snprint_value(buf, sizeof(buf), vars->name, vars->name_length, vars);
     268                 : #else
     269                 :                 sprint_value(buf,vars->name, vars->name_length, vars);
     270                 : #endif
     271               0 :                 ZVAL_STRING(snmpval, buf, 1);
     272               0 :                 return;
     273                 :         }
     274                 : 
     275               0 :         MAKE_STD_ZVAL(val);
     276                 : 
     277               0 :         switch (vars->type) {
     278                 :         case ASN_BIT_STR:               /* 0x03, asn1.h */
     279               0 :                 ZVAL_STRINGL(val, vars->val.bitstring, vars->val_len, 1);
     280               0 :                 break;
     281                 : 
     282                 :         case ASN_OCTET_STR:             /* 0x04, asn1.h */
     283                 :         case ASN_OPAQUE:                /* 0x44, snmp_impl.h */
     284               0 :                 ZVAL_STRINGL(val, vars->val.string, vars->val_len, 1);
     285               0 :                 break;
     286                 : 
     287                 :         case ASN_NULL:                  /* 0x05, asn1.h */
     288               0 :                 ZVAL_NULL(val);
     289               0 :                 break;
     290                 : 
     291                 :         case ASN_OBJECT_ID:             /* 0x06, asn1.h */
     292                 : #ifdef HAVE_NET_SNMP
     293               0 :                 snprint_objid(buf, sizeof(buf), vars->val.objid, vars->val_len / sizeof(oid));
     294                 : #else
     295                 :                 sprint_objid(buf, vars->val.objid, vars->val_len / sizeof(oid));
     296                 : #endif
     297                 : 
     298               0 :                 ZVAL_STRING(val, buf, 1);
     299               0 :                 break;
     300                 : 
     301                 :         case ASN_IPADDRESS:             /* 0x40, snmp_impl.h */
     302               0 :                 snprintf(buf, sizeof(buf)-1, "%d.%d.%d.%d",
     303                 :                          (vars->val.string)[0], (vars->val.string)[1],
     304                 :                          (vars->val.string)[2], (vars->val.string)[3]);
     305               0 :                 buf[sizeof(buf)-1]=0;
     306               0 :                 ZVAL_STRING(val, buf, 1);
     307               0 :                 break;
     308                 : 
     309                 :         case ASN_COUNTER:               /* 0x41, snmp_impl.h */
     310                 :         case ASN_GAUGE:                 /* 0x42, snmp_impl.h */
     311                 :         /* ASN_UNSIGNED is the same as ASN_GAUGE */
     312                 :         case ASN_TIMETICKS:             /* 0x43, snmp_impl.h */
     313                 :         case ASN_UINTEGER:              /* 0x47, snmp_impl.h */
     314               0 :                 snprintf(buf, sizeof(buf)-1, "%lu", *vars->val.integer);
     315               0 :                 buf[sizeof(buf)-1]=0;
     316               0 :                 ZVAL_STRING(val, buf, 1);
     317               0 :                 break;
     318                 : 
     319                 :         case ASN_INTEGER:               /* 0x02, asn1.h */
     320               0 :                 snprintf(buf, sizeof(buf)-1, "%ld", *vars->val.integer);
     321               0 :                 buf[sizeof(buf)-1]=0;
     322               0 :                 ZVAL_STRING(val, buf, 1);
     323               0 :                 break;
     324                 : 
     325                 :         case ASN_COUNTER64:             /* 0x46, snmp_impl.h */
     326               0 :                 printU64(buf, vars->val.counter64);
     327               0 :                 ZVAL_STRING(val, buf, 1);
     328               0 :                 break;
     329                 : 
     330                 :         default:
     331               0 :                 ZVAL_STRING(val, "Unknown value type", 1);
     332                 :                 break;
     333                 :         }
     334                 : 
     335               0 :         if (SNMP_G(valueretrieval) == SNMP_VALUE_PLAIN) {
     336               0 :                 *snmpval = *val;
     337               0 :                 zval_copy_ctor(snmpval);
     338                 :         } else {
     339               0 :                 object_init(snmpval);
     340               0 :                 add_property_long(snmpval, "type", vars->type);
     341               0 :                 add_property_zval(snmpval, "value", val);
     342                 :         }
     343                 : }
     344                 : 
     345                 : /* {{{ php_snmp_internal
     346                 : *
     347                 : * Generic SNMP object fetcher (for all SNMP versions)
     348                 : *
     349                 : * st=SNMP_CMD_GET   get - query an agent with SNMP-GET.
     350                 : * st=SNMP_CMD_GETNEXT   getnext - query an agent with SNMP-GETNEXT.
     351                 : * st=SNMP_CMD_WALK   walk - walk the mib and return a single dimensional array 
     352                 : *          containing the values.
     353                 : * st=SNMP_CMD_REALWALK   realwalk() and walkoid() - walk the mib and return an 
     354                 : *          array of oid,value pairs.
     355                 : * st=SNMP_CMD_SET  set() - query an agent and set a single value
     356                 : *
     357                 : */
     358                 : static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st, 
     359                 :                                                         struct snmp_session *session,
     360                 :                                                         char *objid,
     361                 :                                                         char type,
     362                 :                                                         char* value) 
     363               0 : {
     364                 :         struct snmp_session *ss;
     365               0 :         struct snmp_pdu *pdu=NULL, *response;
     366                 :         struct variable_list *vars;
     367                 :         oid name[MAX_NAME_LEN];
     368                 :         size_t name_length;
     369                 :         oid root[MAX_NAME_LEN];
     370               0 :         size_t rootlen = 0;
     371               0 :         int gotroot = 0;
     372                 :         int status, count;
     373                 :         char buf[2048];
     374                 :         char buf2[2048];
     375               0 :         int keepwalking=1;
     376                 :         char *err;
     377               0 :         zval *snmpval = NULL;
     378                 : 
     379               0 :         if (st >= SNMP_CMD_WALK) { /* walk */
     380               0 :                 rootlen = MAX_NAME_LEN;
     381               0 :                 if (strlen(objid)) { /* on a walk, an empty string means top of tree - no error */
     382               0 :                         if (snmp_parse_oid(objid, root, &rootlen)) {
     383               0 :                                 gotroot = 1;
     384                 :                         } else {
     385               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", objid);
     386                 :                         }
     387                 :                 }
     388                 : 
     389               0 :                 if (!gotroot) {
     390               0 :                         memmove((char *) root, (char *) objid_mib, sizeof(objid_mib));
     391               0 :                         rootlen = sizeof(objid_mib) / sizeof(oid);
     392               0 :                         gotroot = 1;
     393                 :                 }
     394                 :         }
     395                 : 
     396               0 :         if ((ss = snmp_open(session)) == NULL) {
     397               0 :                 snmp_error(session, NULL, NULL, &err);
     398               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open snmp connection: %s", err);
     399               0 :                 free(err);
     400               0 :                 RETURN_FALSE;
     401                 :         }
     402                 : 
     403               0 :         if (st >= SNMP_CMD_WALK) {
     404               0 :                 memmove((char *)name, (char *)root, rootlen * sizeof(oid));
     405               0 :                 name_length = rootlen;
     406               0 :                 switch(st) {
     407                 :                         case SNMP_CMD_WALK:
     408                 :                         case SNMP_CMD_REALWALK:
     409               0 :                                 array_init(return_value);
     410               0 :                                 break;
     411                 :                         default:
     412               0 :                                 RETVAL_TRUE;
     413                 :                                 break;
     414                 :                 }
     415                 :         }
     416                 : 
     417               0 :         while (keepwalking) {
     418               0 :                 keepwalking = 0;
     419               0 :                 if ((st == SNMP_CMD_GET) || (st == SNMP_CMD_GETNEXT)) {
     420               0 :                         name_length = MAX_OID_LEN;
     421               0 :                         if (!snmp_parse_oid(objid, name, &name_length)) {
     422               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", objid);
     423               0 :                                 snmp_close(ss);
     424               0 :                                 RETURN_FALSE;
     425                 :                         }
     426               0 :                         pdu = snmp_pdu_create((st == SNMP_CMD_GET) ? SNMP_MSG_GET : SNMP_MSG_GETNEXT);
     427               0 :                         snmp_add_null_var(pdu, name, name_length);
     428               0 :                 } else if (st == SNMP_CMD_SET) {
     429               0 :                         pdu = snmp_pdu_create(SNMP_MSG_SET);
     430               0 :                         if (snmp_add_var(pdu, name, name_length, type, value)) {
     431                 : #ifdef HAVE_NET_SNMP
     432               0 :                                 snprint_objid(buf, sizeof(buf), name, name_length);
     433                 : #else
     434                 :                                 sprint_objid(buf, name, name_length);
     435                 : #endif
     436               0 :                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not add variable: %s %c %s", buf, type, value);
     437               0 :                                 snmp_free_pdu(pdu);
     438               0 :                                 snmp_close(ss);
     439               0 :                                 RETURN_FALSE;
     440                 :                         }
     441               0 :                 } else if (st >= SNMP_CMD_WALK) {
     442               0 :                         if (session->version == SNMP_VERSION_1) {
     443               0 :                                 pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
     444                 :                         } else {
     445               0 :                                 pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
     446               0 :                                 pdu->non_repeaters = 0;
     447               0 :                                 pdu->max_repetitions = 20;
     448                 :                         }
     449               0 :                         snmp_add_null_var(pdu, name, name_length);
     450                 :                 }
     451                 : 
     452               0 : retry:
     453               0 :                 status = snmp_synch_response(ss, pdu, &response);
     454               0 :                 if (status == STAT_SUCCESS) {
     455               0 :                         if (response->errstat == SNMP_ERR_NOERROR) {
     456               0 :                                 for (vars = response->variables; vars; vars = vars->next_variable) {
     457               0 :                                         if (st >= SNMP_CMD_WALK && st != SNMP_CMD_SET && 
     458                 :                                                 (vars->name_length < rootlen || memcmp(root, vars->name, rootlen * sizeof(oid)))) {
     459                 :                                                 continue;       /* not part of this subtree */
     460                 :                                         }
     461                 : 
     462               0 :                                         if (st != SNMP_CMD_SET) {
     463               0 :                                                 MAKE_STD_ZVAL(snmpval);
     464               0 :                                                 php_snmp_getvalue(vars, snmpval TSRMLS_CC);
     465                 :                                         }
     466                 : 
     467               0 :                                         if (st == SNMP_CMD_GET) {
     468               0 :                                                 *return_value = *snmpval;
     469               0 :                                                 zval_copy_ctor(return_value);
     470               0 :                                                 zval_ptr_dtor(&snmpval);
     471               0 :                                                 snmp_free_pdu(response);
     472               0 :                                                 snmp_close(ss);
     473               0 :                                                 return;
     474               0 :                                         } else if (st == SNMP_CMD_GETNEXT) {
     475               0 :                                                 *return_value = *snmpval;
     476               0 :                                                 zval_copy_ctor(return_value);
     477               0 :                                                 snmp_free_pdu(response);
     478               0 :                                                 snmp_close(ss);
     479               0 :                                                 return;
     480               0 :                                         } else if (st == SNMP_CMD_WALK) {
     481               0 :                                                 add_next_index_zval(return_value,snmpval); /* Add to returned array */
     482               0 :                                         } else if (st == SNMP_CMD_REALWALK && vars->type != SNMP_ENDOFMIBVIEW && vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) {
     483                 : #ifdef HAVE_NET_SNMP
     484               0 :                                                 snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length);
     485                 : #else
     486                 :                                                 sprint_objid(buf2, vars->name, vars->name_length);
     487                 : #endif
     488               0 :                                                 add_assoc_zval(return_value,buf2,snmpval);
     489                 :                                         }
     490               0 :                                         if (st >= SNMP_CMD_WALK && st != SNMP_CMD_SET) {
     491               0 :                                                 if (vars->type != SNMP_ENDOFMIBVIEW && 
     492                 :                                                         vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) {
     493               0 :                                                         if (snmp_oid_compare(name, name_length, vars->name, vars->name_length) >= 0) {
     494               0 :                                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error: OID not increasing: %s",name);
     495               0 :                                                                 keepwalking = 0;
     496                 :                                                         } else {
     497               0 :                                                                 memmove((char *)name, (char *)vars->name,vars->name_length * sizeof(oid));
     498               0 :                                                                 name_length = vars->name_length;
     499               0 :                                                                 keepwalking = 1;
     500                 :                                                         }
     501                 :                                                 }
     502                 :                                         }
     503                 :                                 }       
     504                 :                         } else {
     505               0 :                                 if (st != SNMP_CMD_WALK || response->errstat != SNMP_ERR_NOSUCHNAME) {
     506               0 :                                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in packet: %s", snmp_errstring(response->errstat));
     507               0 :                                         if (response->errstat == SNMP_ERR_NOSUCHNAME) {
     508               0 :                                                 for (count=1, vars = response->variables; vars && count != response->errindex;
     509               0 :                                                 vars = vars->next_variable, count++);
     510               0 :                                                 if (vars) {
     511                 : #ifdef HAVE_NET_SNMP
     512               0 :                                                         snprint_objid(buf, sizeof(buf), vars->name, vars->name_length);
     513                 : #else
     514                 :                                                         sprint_objid(buf,vars->name, vars->name_length);
     515                 : #endif
     516                 :                                                 }
     517               0 :                                                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "This name does not exist: %s",buf);
     518                 :                                         }
     519               0 :                                         if (st == SNMP_CMD_GET) {
     520               0 :                                                 if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GET)) != NULL) {
     521               0 :                                                         snmp_free_pdu(response);
     522               0 :                                                         goto retry;
     523                 :                                                 }
     524               0 :                                         } else if (st == SNMP_CMD_SET) {
     525               0 :                                                 if ((pdu = snmp_fix_pdu(response, SNMP_MSG_SET)) != NULL) {
     526               0 :                                                         snmp_free_pdu(response);
     527               0 :                                                         goto retry;
     528                 :                                                 }
     529               0 :                                         } else if (st == SNMP_CMD_GETNEXT) {
     530               0 :                                                 if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) != NULL) {
     531               0 :                                                         snmp_free_pdu(response);
     532               0 :                                                         goto retry;
     533                 :                                                 }
     534               0 :                                         } else if (st >= SNMP_CMD_WALK) { /* Here we do walks. */
     535               0 :                                                 if ((pdu = snmp_fix_pdu(response, ((session->version == SNMP_VERSION_1)
     536                 :                                                                                 ? SNMP_MSG_GETNEXT
     537                 :                                                                                 : SNMP_MSG_GETBULK))) != NULL) {
     538               0 :                                                         snmp_free_pdu(response);
     539               0 :                                                         goto retry;
     540                 :                                                 }
     541                 :                                         }
     542               0 :                                         snmp_free_pdu(response);
     543               0 :                                         snmp_close(ss);
     544               0 :                                         if (st == SNMP_CMD_WALK || st == SNMP_CMD_REALWALK) {
     545               0 :                                                 zval_dtor(return_value);
     546                 :                                         }
     547               0 :                                         RETURN_FALSE;
     548                 :                                 }
     549                 :                         }
     550               0 :                 } else if (status == STAT_TIMEOUT) {
     551               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "No response from %s", session->peername);
     552               0 :                         if (st == SNMP_CMD_WALK || st == SNMP_CMD_REALWALK) {
     553               0 :                                 zval_dtor(return_value);
     554                 :                         }
     555               0 :                         snmp_close(ss);
     556               0 :                         RETURN_FALSE;
     557                 :                 } else {    /* status == STAT_ERROR */
     558               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred, quitting");
     559               0 :                         if (st == SNMP_CMD_WALK || st == SNMP_CMD_REALWALK) {
     560               0 :                                 zval_dtor(return_value);
     561                 :                         }
     562               0 :                         snmp_close(ss);
     563               0 :                         RETURN_FALSE;
     564                 :                 }
     565               0 :                 if (response) {
     566               0 :                         snmp_free_pdu(response);
     567                 :                 }
     568                 :         } /* keepwalking */
     569               0 :         snmp_close(ss);
     570                 : }
     571                 : /* }}} */
     572                 : 
     573                 : /* {{{ php_snmp
     574                 : *
     575                 : * Generic community based SNMP handler for version 1 and 2.
     576                 : * This function makes use of the internal SNMP object fetcher.
     577                 : * The object fetcher is shared with SNMPv3.
     578                 : *
     579                 : * st=SNMP_CMD_GET   get - query an agent with SNMP-GET.
     580                 : * st=SNMP_CMD_GETNEXT   getnext - query an agent with SNMP-GETNEXT.
     581                 : * st=SNMP_CMD_WALK   walk - walk the mib and return a single dimensional array 
     582                 : *          containing the values.
     583                 : * st=SNMP_CMD_REALWALK   realwalk() and walkoid() - walk the mib and return an 
     584                 : *          array of oid,value pairs.
     585                 : * st=5-8 ** Reserved **
     586                 : * st=SNMP_CMD_SET  set() - query an agent and set a single value
     587                 : *
     588                 : */
     589                 : static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) 
     590               0 : {
     591                 :         zval **a1, **a2, **a3, **a4, **a5, **a6, **a7;
     592                 :         struct snmp_session session;
     593               0 :         long timeout=SNMP_DEFAULT_TIMEOUT;
     594               0 :         long retries=SNMP_DEFAULT_RETRIES;
     595               0 :         int myargc = ZEND_NUM_ARGS();
     596               0 :         char type = (char) 0;
     597               0 :         char *value = (char *) 0;
     598                 :         char hostname[MAX_NAME_LEN];
     599               0 :         int remote_port = 161;
     600                 :         char *pptr;
     601                 : 
     602               0 :         if (myargc < 3 || myargc > 7 ||
     603                 :                 zend_get_parameters_ex(myargc, &a1, &a2, &a3, &a4, &a5, &a6, &a7) == FAILURE) {
     604               0 :                 WRONG_PARAM_COUNT;
     605                 :         }
     606                 : 
     607               0 :         convert_to_string_ex(a1);
     608               0 :         convert_to_string_ex(a2);
     609               0 :         convert_to_string_ex(a3);
     610                 :         
     611               0 :         if (st == SNMP_CMD_SET) {
     612               0 :                 if (myargc < 5) {
     613               0 :                         WRONG_PARAM_COUNT;
     614                 :                 }
     615                 : 
     616               0 :                 convert_to_string_ex(a4);
     617               0 :                 convert_to_string_ex(a5);
     618                 : 
     619               0 :                 if(myargc > 5) {
     620               0 :                         convert_to_long_ex(a6);
     621               0 :                         timeout = Z_LVAL_PP(a6);
     622                 :                 }
     623                 : 
     624               0 :                 if(myargc > 6) {
     625               0 :                         convert_to_long_ex(a7);
     626               0 :                         retries = Z_LVAL_PP(a7);
     627                 :                 }
     628                 : 
     629               0 :                 type = Z_STRVAL_PP(a4)[0];
     630               0 :                 value = Z_STRVAL_PP(a5);
     631                 :         } else {
     632               0 :                 if(myargc > 3) {
     633               0 :                         convert_to_long_ex(a4);
     634               0 :                         timeout = Z_LVAL_PP(a4);
     635                 :                 }
     636                 : 
     637               0 :                 if(myargc > 4) {
     638               0 :                         convert_to_long_ex(a5);
     639               0 :                         retries = Z_LVAL_PP(a5);
     640                 :                 }
     641                 :         }
     642                 : 
     643               0 :         snmp_sess_init(&session);
     644               0 :         strlcpy(hostname, Z_STRVAL_PP(a1), sizeof(hostname));
     645               0 :         if ((pptr = strchr (hostname, ':'))) {
     646               0 :                 remote_port = strtol (pptr + 1, NULL, 0);
     647                 :         }
     648                 : 
     649               0 :         session.peername = hostname;
     650               0 :         session.remote_port = remote_port;
     651               0 :         session.version = version;
     652                 :         /*
     653                 :         * FIXME: potential memory leak
     654                 :         * This is a workaround for an "artifact" (Mike Slifcak)
     655                 :         * in (at least) ucd-snmp 3.6.1 which frees
     656                 :         * memory it did not allocate
     657                 :         */
     658                 : #ifdef UCD_SNMP_HACK
     659                 :         session.community = (u_char *)strdup(Z_STRVAL_PP(a2)); /* memory freed by SNMP library, strdup NOT estrdup */
     660                 : #else
     661               0 :         session.community = (u_char *)Z_STRVAL_PP(a2);
     662                 : #endif
     663               0 :         session.community_len = Z_STRLEN_PP(a2);
     664               0 :         session.retries = retries;
     665               0 :         session.timeout = timeout;
     666                 :         
     667               0 :         session.authenticator = NULL;
     668                 : 
     669               0 :         php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, &session, Z_STRVAL_PP(a3), type, value);
     670                 : }
     671                 : /* }}} */
     672                 : 
     673                 : /* {{{ proto string snmpget(string host, string community, string object_id [, int timeout [, int retries]]) 
     674                 :    Fetch a SNMP object */
     675                 : PHP_FUNCTION(snmpget)
     676               0 : {
     677               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GET, SNMP_VERSION_1);
     678               0 : }
     679                 : /* }}} */
     680                 : 
     681                 : /* {{{ proto string snmpgetnext(string host, string community, string object_id [, int timeout [, int retries]]) 
     682                 :    Fetch a SNMP object */
     683                 : PHP_FUNCTION(snmpgetnext)
     684               0 : {
     685               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GETNEXT, SNMP_VERSION_1);
     686               0 : }
     687                 : /* }}} */
     688                 : 
     689                 : /* {{{ proto array snmpwalk(string host, string community, string object_id [, int timeout [, int retries]]) 
     690                 :    Return all objects under the specified object id */
     691                 : PHP_FUNCTION(snmpwalk)
     692               0 : {
     693               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_WALK, SNMP_VERSION_1);
     694               0 : }
     695                 : /* }}} */
     696                 : 
     697                 : /* {{{ proto array snmprealwalk(string host, string community, string object_id [, int timeout [, int retries]])
     698                 :    Return all objects including their respective object id withing the specified one */
     699                 : PHP_FUNCTION(snmprealwalk)
     700               0 : {
     701               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_REALWALK, SNMP_VERSION_1);
     702               0 : }
     703                 : /* }}} */
     704                 : 
     705                 : /* {{{ proto bool snmp_get_quick_print(void)
     706                 :    Return the current status of quick_print */
     707                 : PHP_FUNCTION(snmp_get_quick_print)
     708               0 : {
     709               0 :         if (ZEND_NUM_ARGS() != 0) {
     710               0 :                 WRONG_PARAM_COUNT;
     711                 :         }
     712                 : 
     713                 : #ifdef HAVE_NET_SNMP
     714               0 :         RETURN_BOOL(netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT));
     715                 : #else
     716                 :         RETURN_BOOL(snmp_get_quick_print());
     717                 : #endif
     718                 : }
     719                 : /* }}} */
     720                 : 
     721                 : /* {{{ proto void snmp_set_quick_print(int quick_print)
     722                 :    Return all objects including their respective object id withing the specified one */
     723                 : PHP_FUNCTION(snmp_set_quick_print)
     724               0 : {
     725               0 :         int argc = ZEND_NUM_ARGS();
     726                 :         long a1;
     727                 : 
     728               0 :         if (zend_parse_parameters(argc TSRMLS_CC, "l", &a1) == FAILURE) {
     729               0 :                 return;
     730                 :         }
     731                 : 
     732                 : #ifdef HAVE_NET_SNMP
     733               0 :         netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, (int) a1);
     734                 : #else
     735                 :         snmp_set_quick_print((int)a1);
     736                 : #endif
     737                 : }
     738                 : /* }}} */
     739                 : 
     740                 : #ifdef HAVE_NET_SNMP
     741                 : /* {{{ proto void snmp_set_enum_print(int enum_print)
     742                 :    Return all values that are enums with their enum value instead of the raw integer */
     743                 : PHP_FUNCTION(snmp_set_enum_print)
     744               0 : {
     745               0 :         int argc = ZEND_NUM_ARGS();
     746                 :         long a1;
     747                 : 
     748               0 :         if (zend_parse_parameters(argc TSRMLS_CC, "l", &a1) == FAILURE) {
     749               0 :                 return;
     750                 :         }
     751                 : 
     752               0 :         netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, (int) a1);
     753                 : } 
     754                 : /* }}} */
     755                 : 
     756                 : /* {{{ proto void snmp_set_oid_output_format(int oid_format)
     757                 :    Set the OID output format. */
     758                 : PHP_FUNCTION(snmp_set_oid_output_format)
     759               0 : {
     760               0 :         int argc = ZEND_NUM_ARGS();
     761                 :         long a1;
     762                 : 
     763               0 :         if (zend_parse_parameters(argc TSRMLS_CC, "l", &a1) == FAILURE) {
     764               0 :                 return;
     765                 :         }
     766                 : 
     767               0 :         switch ((int) a1) {
     768                 :                 case 0:
     769                 :                 case NETSNMP_OID_OUTPUT_FULL:
     770               0 :                         a1 = NETSNMP_OID_OUTPUT_FULL;
     771               0 :                         break;
     772                 : 
     773                 :                 default:
     774                 :                 case NETSNMP_OID_OUTPUT_NUMERIC:
     775               0 :                         a1 = NETSNMP_OID_OUTPUT_NUMERIC;
     776                 :                         break;
     777                 :         }
     778                 : 
     779               0 :         netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, a1);
     780                 : } 
     781                 : /* }}} */
     782                 : #endif
     783                 : 
     784                 : /* {{{ proto int snmpset(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]]) 
     785                 :    Set the value of a SNMP object */
     786                 : PHP_FUNCTION(snmpset)
     787               0 : {
     788               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_SET, SNMP_VERSION_1);
     789               0 : }
     790                 : /* }}} */
     791                 : 
     792                 : /* {{{ int netsnmp_session_set_sec_name(struct snmp_session *s, char *name)
     793                 :    Set the security name in the snmpv3 session */
     794                 : static int netsnmp_session_set_sec_name(struct snmp_session *s, char *name)
     795               0 : {
     796               0 :         if ((s) && (name)) {
     797               0 :                 s->securityName = strdup(name);
     798               0 :                 s->securityNameLen = strlen(s->securityName);
     799               0 :                 return (0);
     800                 :         }
     801               0 :         return (-1);
     802                 : }
     803                 : /* }}} */
     804                 : 
     805                 : /* {{{ int netsnmp_session_set_sec_level(struct snmp_session *s, char *level)
     806                 :    Set the security level in the snmpv3 session */
     807                 : static int netsnmp_session_set_sec_level(struct snmp_session *s, char *level TSRMLS_DC)
     808               0 : {
     809               0 :         if ((s) && (level)) {
     810               0 :                 if (!strcasecmp(level, "noAuthNoPriv") || !strcasecmp(level, "nanp")) {
     811               0 :                         s->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
     812               0 :                         return (0);
     813               0 :                 } else if (!strcasecmp(level, "authNoPriv") || !strcasecmp(level, "anp")) {
     814               0 :                         s->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
     815               0 :                         return (0);
     816               0 :                 } else if (!strcasecmp(level, "authPriv") || !strcasecmp(level, "ap")) {
     817               0 :                         s->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
     818               0 :                         return (0);
     819                 :                 }
     820                 :         }
     821               0 :         return (-1);
     822                 : }
     823                 : /* }}} */
     824                 : 
     825                 : /* {{{ int netsnmp_session_set_auth_protocol(struct snmp_session *s, char *prot)
     826                 :    Set the authentication protocol in the snmpv3 session */
     827                 : static int netsnmp_session_set_auth_protocol(struct snmp_session *s, char *prot TSRMLS_DC)
     828               0 : {
     829               0 :         if ((s) && (prot)) {
     830               0 :                 if (!strcasecmp(prot, "MD5")) {
     831               0 :                         s->securityAuthProto = usmHMACMD5AuthProtocol;
     832               0 :                         s->securityAuthProtoLen = OIDSIZE(usmHMACMD5AuthProtocol);
     833               0 :                         return (0);
     834               0 :                 } else if (!strcasecmp(prot, "SHA")) {
     835               0 :                         s->securityAuthProto = usmHMACSHA1AuthProtocol;
     836               0 :                         s->securityAuthProtoLen = OIDSIZE(usmHMACSHA1AuthProtocol);
     837               0 :                         return (0);
     838                 :                 }
     839                 :         }
     840               0 :         return (-1);
     841                 : }
     842                 : /* }}} */
     843                 : 
     844                 : /* {{{ int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot)
     845                 :    Set the security protocol in the snmpv3 session */
     846                 : static int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot TSRMLS_DC)
     847               0 : {
     848               0 :         if ((s) && (prot)) {
     849               0 :                 if (!strcasecmp(prot, "DES")) {
     850               0 :                         s->securityPrivProto = usmDESPrivProtocol;
     851               0 :                         s->securityPrivProtoLen = OIDSIZE(usmDESPrivProtocol);
     852               0 :                         return (0);
     853                 : #ifdef HAVE_AES
     854               0 :                 } else if (!strcasecmp(prot, "AES128")
     855                 : #ifdef SNMP_VALIDATE_ERR
     856                 : /* 
     857                 : * In Net-SNMP before 5.2, the following symbols exist:
     858                 : * usmAES128PrivProtocol, usmAES192PrivProtocol, usmAES256PrivProtocol
     859                 : * In an effort to be more standards-compliant, 5.2 removed the last two.
     860                 : * As of 5.2, the symbols are:
     861                 : * usmAESPrivProtocol, usmAES128PrivProtocol
     862                 : * 
     863                 : * As we want this extension to compile on both versions, we use the latter
     864                 : * symbol on purpose, as it's defined to be the same as the former.
     865                 : *
     866                 : * However, in 5.2 the type of usmAES128PrivProtocol is a pointer, not an
     867                 : * array, so we cannot use the OIDSIZE macro because it uses sizeof().
     868                 : *
     869                 : */
     870                 :                         || !strcasecmp(prot, "AES")) {
     871               0 :                         s->securityPrivProto = usmAES128PrivProtocol;
     872               0 :                         s->securityPrivProtoLen = USM_PRIV_PROTO_AES128_LEN;
     873               0 :                         return (0);
     874                 : #else                   
     875                 :                 ) {
     876                 :                         s->securityPrivProto = usmAES128PrivProtocol;
     877                 :                         s->securityPrivProtoLen = OIDSIZE(usmAES128PrivProtocol);
     878                 :                         return (0);
     879                 :                 } else if (!strcasecmp(prot, "AES192")) {
     880                 :                         s->securityPrivProto = usmAES192PrivProtocol;
     881                 :                         s->securityPrivProtoLen = OIDSIZE(usmAES192PrivProtocol);
     882                 :                         return (0);
     883                 :                 } else if (!strcasecmp(prot, "AES256")) {
     884                 :                         s->securityPrivProto = usmAES256PrivProtocol;
     885                 :                         s->securityPrivProtoLen = OIDSIZE(usmAES256PrivProtocol);
     886                 :                         return (0);
     887                 : #endif
     888                 : #endif
     889                 :                 }
     890                 :         }
     891               0 :         return (-1);
     892                 : }
     893                 : /* }}} */
     894                 : 
     895                 : /* {{{ int netsnmp_session_gen_auth_key(struct snmp_session *s, char *pass)
     896                 :    Make key from pass phrase in the snmpv3 session */
     897                 : static int netsnmp_session_gen_auth_key(struct snmp_session *s, char *pass TSRMLS_DC)
     898               0 : {
     899                 :         /*
     900                 :          * make master key from pass phrases 
     901                 :          */
     902               0 :         if ((s) && (pass) && strlen(pass)) {
     903               0 :                 s->securityAuthKeyLen = USM_AUTH_KU_LEN;
     904               0 :                 if (s->securityAuthProto == NULL) {
     905                 :                         /* get .conf set default */
     906               0 :                         const oid *def = get_default_authtype(&(s->securityAuthProtoLen));
     907               0 :                         s->securityAuthProto = snmp_duplicate_objid(def, s->securityAuthProtoLen);
     908                 :                 }
     909               0 :                 if (s->securityAuthProto == NULL) {
     910                 :                         /* assume MD5 */
     911               0 :                         s->securityAuthProto =
     912                 :                                 snmp_duplicate_objid(usmHMACMD5AuthProtocol, OIDSIZE(usmHMACMD5AuthProtocol));
     913               0 :                         s->securityAuthProtoLen = OIDSIZE(usmHMACMD5AuthProtocol);
     914                 :                 }
     915               0 :                 if (generate_Ku(s->securityAuthProto, s->securityAuthProtoLen,
     916                 :                                 (u_char *) pass, strlen(pass),
     917                 :                                 s->securityAuthKey, &(s->securityAuthKeyLen)) != SNMPERR_SUCCESS) {
     918               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error generating a key for authentication pass phrase");
     919               0 :                         return (-2);
     920                 :                 }
     921               0 :                 return (0);
     922                 :         }
     923               0 :         return (-1);
     924                 : }
     925                 : /* }}} */
     926                 : 
     927                 : /* {{{ int netsnmp_session_gen_sec_key(struct snmp_session *s, u_char *pass)
     928                 :    Make key from pass phrase in the snmpv3 session */
     929                 : static int netsnmp_session_gen_sec_key(struct snmp_session *s, u_char *pass TSRMLS_DC)
     930               0 : {
     931               0 :         if ((s) && (pass) && strlen(pass)) {
     932               0 :                 s->securityPrivKeyLen = USM_PRIV_KU_LEN;
     933               0 :                 if (s->securityPrivProto == NULL) {
     934                 :                         /* get .conf set default */
     935               0 :                         const oid *def = get_default_privtype(&(s->securityPrivProtoLen));
     936               0 :                         s->securityPrivProto = snmp_duplicate_objid(def, s->securityPrivProtoLen);
     937                 :                 }
     938               0 :                 if (s->securityPrivProto == NULL) {
     939                 :                         /* assume DES */
     940               0 :                         s->securityPrivProto = snmp_duplicate_objid(usmDESPrivProtocol,
     941                 :                                 OIDSIZE(usmDESPrivProtocol));
     942               0 :                         s->securityPrivProtoLen = OIDSIZE(usmDESPrivProtocol);
     943                 :                 }
     944               0 :                 if (generate_Ku(s->securityAuthProto, s->securityAuthProtoLen,
     945                 :                                 pass, strlen(pass),
     946                 :                                 s->securityPrivKey, &(s->securityPrivKeyLen)) != SNMPERR_SUCCESS) {
     947               0 :                         php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error generating a key for privacy pass phrase");
     948               0 :                         return (-2);
     949                 :                 }
     950               0 :                 return (0);
     951                 :         }
     952               0 :         return (-1);
     953                 : }
     954                 : /* }}} */
     955                 : 
     956                 : /* {{{ proto string snmp2_get(string host, string community, string object_id [, int timeout [, int retries]]) 
     957                 :    Fetch a SNMP object */
     958                 : PHP_FUNCTION(snmp2_get)
     959               0 : {
     960               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GET, SNMP_VERSION_2c);
     961               0 : }
     962                 : /* }}} */
     963                 : 
     964                 : /* {{{ proto string snmp2_getnext(string host, string community, string object_id [, int timeout [, int retries]]) 
     965                 :    Fetch a SNMP object */
     966                 : PHP_FUNCTION(snmp2_getnext)
     967               0 : {
     968               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GETNEXT, SNMP_VERSION_2c);
     969               0 : }
     970                 : /* }}} */
     971                 : 
     972                 : /* {{{ proto array snmp2_walk(string host, string community, string object_id [, int timeout [, int retries]]) 
     973                 :    Return all objects under the specified object id */
     974                 : PHP_FUNCTION(snmp2_walk)
     975               0 : {
     976               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_WALK, SNMP_VERSION_2c);
     977               0 : }
     978                 : /* }}} */
     979                 : 
     980                 : /* {{{ proto array snmp2_real_walk(string host, string community, string object_id [, int timeout [, int retries]])
     981                 :    Return all objects including their respective object id withing the specified one */
     982                 : PHP_FUNCTION(snmp2_real_walk)
     983               0 : {
     984               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_REALWALK, SNMP_VERSION_2c);
     985               0 : }
     986                 : /* }}} */
     987                 : 
     988                 : /* {{{ proto int snmp2_set(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]]) 
     989                 :    Set the value of a SNMP object */
     990                 : PHP_FUNCTION(snmp2_set)
     991               0 : {
     992               0 :         php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_SET, SNMP_VERSION_2c);
     993               0 : }
     994                 : /* }}} */
     995                 : 
     996                 : /* {{{ proto void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st)
     997                 : *
     998                 : * Generic SNMPv3 object fetcher
     999                 : * From here is passed on the the common internal object fetcher.
    1000                 : *
    1001                 : * st=SNMP_CMD_GET   snmp3_get() - query an agent and return a single value.
    1002                 : * st=SNMP_CMD_GETNEXT   snmp3_getnext() - query an agent and return the next single value.
    1003                 : * st=SNMP_CMD_WALK   snmp3_walk() - walk the mib and return a single dimensional array 
    1004                 : *                       containing the values.
    1005                 : * st=SNMP_CMD_REALWALK   snmp3_real_walk() - walk the mib and return an 
    1006                 : *                            array of oid,value pairs.
    1007                 : * st=SNMP_CMD_SET  snmp3_set() - query an agent and set a single value
    1008                 : *
    1009                 : */
    1010                 : static void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st)
    1011               0 : {
    1012                 :         zval **a1, **a2, **a3, **a4, **a5, **a6, **a7, **a8, **a9, **a10, **a11, **a12;
    1013                 :         struct snmp_session session;
    1014               0 :         long timeout=SNMP_DEFAULT_TIMEOUT;
    1015               0 :         long retries=SNMP_DEFAULT_RETRIES;
    1016               0 :         int myargc = ZEND_NUM_ARGS();
    1017               0 :         char type = (char) 0;
    1018               0 :         char *value = (char *) 0;
    1019                 :         char hostname[MAX_NAME_LEN];
    1020               0 :         int remote_port = 161;
    1021                 :         char *pptr;
    1022                 : 
    1023               0 :         if (myargc < 8 || myargc > 12 ||
    1024                 :                 zend_get_parameters_ex(myargc, &a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8, &a9, &a10, &a11, &a12) == FAILURE) {
    1025               0 :                 WRONG_PARAM_COUNT;
    1026                 :         }
    1027                 : 
    1028               0 :         snmp_sess_init(&session);
    1029                 :         /* This is all SNMPv3 */
    1030               0 :         session.version = SNMP_VERSION_3;
    1031                 : 
    1032                 :         /* Reading the hostname and its optional non-default port number */
    1033               0 :         convert_to_string_ex(a1);
    1034               0 :         strlcpy(hostname, Z_STRVAL_PP(a1), sizeof(hostname));
    1035               0 :         if ((pptr = strchr (hostname, ':'))) {
    1036               0 :                 remote_port = strtol (pptr + 1, NULL, 0);
    1037                 :         }
    1038               0 :         session.peername = hostname;
    1039               0 :         session.remote_port = remote_port;
    1040                 : 
    1041                 :         /* Setting the security name. */
    1042               0 :         convert_to_string_ex(a2);
    1043               0 :         if (netsnmp_session_set_sec_name(&session, Z_STRVAL_PP(a2))) {
    1044               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could net set security name: %s", Z_STRVAL_PP(a2));
    1045               0 :                 RETURN_FALSE;
    1046                 :         }
    1047                 : 
    1048                 :         /* Setting the security level. */
    1049               0 :         convert_to_string_ex(a3);
    1050               0 :         if (netsnmp_session_set_sec_level(&session, Z_STRVAL_PP(a3) TSRMLS_CC)) {
    1051               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid security level: %s", Z_STRVAL_PP(a3));
    1052               0 :                 RETURN_FALSE;
    1053                 :         }
    1054                 : 
    1055                 :         /* Setting the authentication protocol. */
    1056               0 :         convert_to_string_ex(a4);
    1057               0 :         if (netsnmp_session_set_auth_protocol(&session, Z_STRVAL_PP(a4) TSRMLS_CC)) {
    1058               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid authentication protocol: %s", Z_STRVAL_PP(a4));
    1059               0 :                 RETURN_FALSE;
    1060                 :         }
    1061                 : 
    1062                 :         /* Setting the authentication passphrase. */
    1063               0 :         convert_to_string_ex(a5);
    1064               0 :         if (netsnmp_session_gen_auth_key(&session, Z_STRVAL_PP(a5) TSRMLS_CC)) {
    1065               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not generate key for authentication pass phrase: %s", Z_STRVAL_PP(a4));
    1066               0 :                 RETURN_FALSE;
    1067                 :         }
    1068                 : 
    1069                 :         /* Setting the security protocol. */
    1070               0 :         convert_to_string_ex(a6);
    1071               0 :         if (netsnmp_session_set_sec_protocol(&session, Z_STRVAL_PP(a6) TSRMLS_CC) &&
    1072                 :                         (0 != strlen(Z_STRVAL_PP(a6)))) {
    1073               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid security protocol: %s", Z_STRVAL_PP(a6));
    1074               0 :                 RETURN_FALSE;
    1075                 :         }
    1076                 : 
    1077                 :         /* Setting the security protocol passphrase. */
    1078               0 :         convert_to_string_ex(a7);
    1079               0 :         if (netsnmp_session_gen_sec_key(&session, Z_STRVAL_PP(a7) TSRMLS_CC) &&
    1080                 :                                                         (0 != strlen(Z_STRVAL_PP(a7)))) {
    1081               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not generate key for security pass phrase: %s", Z_STRVAL_PP(a7));
    1082               0 :                 RETURN_FALSE;
    1083                 :         }
    1084                 : 
    1085               0 :         if (st == SNMP_CMD_SET) {
    1086               0 :                 if (myargc < 10) {
    1087               0 :                         WRONG_PARAM_COUNT;
    1088                 :                 }
    1089               0 :                 if (myargc > 10) {
    1090               0 :                         convert_to_long_ex(a11);
    1091               0 :                         timeout = Z_LVAL_PP(a11);
    1092                 :                 }
    1093               0 :                 if (myargc > 11) {
    1094               0 :                         convert_to_long_ex(a12);
    1095               0 :                         retries = Z_LVAL_PP(a12);
    1096                 :                 }
    1097               0 :                 convert_to_string_ex(a9);
    1098               0 :                 convert_to_string_ex(a10);
    1099               0 :                 type = Z_STRVAL_PP(a9)[0];
    1100               0 :                 value = Z_STRVAL_PP(a10);
    1101                 :         } else {
    1102               0 :                 if (myargc > 8) {
    1103               0 :                         convert_to_long_ex(a9);
    1104               0 :                         timeout = Z_LVAL_PP(a9);
    1105                 :                 }
    1106               0 :                 if (myargc > 9) {
    1107               0 :                         convert_to_long_ex(a10);
    1108               0 :                         retries = Z_LVAL_PP(a10);
    1109                 :                 }
    1110                 :         }
    1111                 : 
    1112               0 :         session.retries = retries;
    1113               0 :         session.timeout = timeout;
    1114                 : 
    1115               0 :         php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, &session, Z_STRVAL_PP(a8), type, value);
    1116                 : }
    1117                 : /* }}} */
    1118                 : 
    1119                 : /* {{{ proto int snmp3_get(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])
    1120                 :    Fetch the value of a SNMP object */
    1121                 : PHP_FUNCTION(snmp3_get)
    1122               0 : {
    1123               0 :         php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GET);
    1124               0 : }
    1125                 : /* }}} */
    1126                 : 
    1127                 : /* {{{ proto int snmp3_getnext(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])
    1128                 :    Fetch the value of a SNMP object */
    1129                 : PHP_FUNCTION(snmp3_getnext)
    1130               0 : {
    1131               0 :         php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GETNEXT);
    1132               0 : }
    1133                 : /* }}} */
    1134                 : 
    1135                 : /* {{{ proto int snmp3_walk(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])
    1136                 :    Fetch the value of a SNMP object */
    1137                 : PHP_FUNCTION(snmp3_walk)
    1138               0 : {
    1139               0 :         php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_WALK);
    1140               0 : }
    1141                 : /* }}} */
    1142                 : 
    1143                 : /* {{{ proto int snmp3_real_walk(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id [, int timeout [, int retries]])
    1144                 :    Fetch the value of a SNMP object */
    1145                 : PHP_FUNCTION(snmp3_real_walk)
    1146               0 : {
    1147               0 :         php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_REALWALK);
    1148               0 : }
    1149                 : /* }}} */
    1150                 : 
    1151                 : /* {{{ proto int snmp3_set(string host, string sec_name, string sec_level, string auth_protocol, string auth_passphrase, string priv_protocol, string priv_passphrase, string object_id, string type, mixed value [, int timeout [, int retries]])
    1152                 :    Fetch the value of a SNMP object */
    1153                 : PHP_FUNCTION(snmp3_set)
    1154               0 : {
    1155               0 :         php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_SET);
    1156               0 : }
    1157                 : /* }}} */
    1158                 : 
    1159                 : /* {{{ proto int snmp_set_valueretrieval(int method)
    1160                 :    Specify the method how the SNMP values will be returned */
    1161                 : PHP_FUNCTION(snmp_set_valueretrieval)
    1162               0 : {
    1163                 :         zval **method;
    1164                 : 
    1165               0 :         if (ZEND_NUM_ARGS() != 1 ||
    1166                 :                 zend_get_parameters_ex(ZEND_NUM_ARGS(), &method) == FAILURE) {
    1167               0 :                 WRONG_PARAM_COUNT;
    1168                 :         }
    1169                 : 
    1170               0 :         convert_to_long_ex(method);
    1171                 : 
    1172               0 :         if ((Z_LVAL_PP(method) == SNMP_VALUE_LIBRARY) ||
    1173                 :             (Z_LVAL_PP(method) == SNMP_VALUE_PLAIN) ||
    1174                 :             (Z_LVAL_PP(method) == SNMP_VALUE_OBJECT)) {
    1175               0 :                 SNMP_G(valueretrieval) = Z_LVAL_PP(method);
    1176                 :         }
    1177                 : }
    1178                 : /* }}} */
    1179                 : 
    1180                 : /* {{{ proto int snmp_get_valueretrieval()
    1181                 :    Return the method how the SNMP values will be returned */
    1182                 : PHP_FUNCTION(snmp_get_valueretrieval)
    1183               0 : {
    1184               0 :         RETURN_LONG(SNMP_G(valueretrieval));
    1185                 : }
    1186                 : /* }}} */
    1187                 : 
    1188                 : /* {{{ proto int snmp_read_mib(string filename)
    1189                 :    Reads and parses a MIB file into the active MIB tree. */
    1190                 : PHP_FUNCTION(snmp_read_mib)
    1191               0 : {
    1192                 :         zval **filename;
    1193                 : 
    1194               0 :         if (ZEND_NUM_ARGS() != 1 ||
    1195                 :                 zend_get_parameters_ex(ZEND_NUM_ARGS(), &filename) == FAILURE) {
    1196               0 :                 WRONG_PARAM_COUNT;
    1197                 :         }
    1198                 : 
    1199               0 :         convert_to_string_ex(filename);
    1200                 : 
    1201                 :         /* Prevent read_mib() from printing any errors. */
    1202               0 :         snmp_disable_stderrlog();
    1203                 :         
    1204               0 :         if (!read_mib(Z_STRVAL_PP(filename))) {
    1205               0 :                 char *error = strerror(errno);
    1206               0 :                 php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading MIB file '%s': %s", Z_STRVAL_PP(filename), error);
    1207               0 :                 RETURN_FALSE;
    1208                 :         }
    1209               0 :         RETURN_TRUE;
    1210                 : }
    1211                 : /* }}} */
    1212                 : 
    1213                 : #endif
    1214                 : 
    1215                 : /*
    1216                 :  * Local variables:
    1217                 :  * tab-width: 4
    1218                 :  * c-basic-offset: 4
    1219                 :  * End:
    1220                 :  * vim600: sw=4 ts=4 fdm=marker
    1221                 :  * vim<600: sw=4 ts=4
    1222                 :  */

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:18 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.