Annotation of embedaddon/php/ext/snmp/snmp.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 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 321634 2012-01-01 13:15:04Z felipe $ */
! 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: /* {{{ arginfo */
! 116: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmpget, 0, 0, 3)
! 117: ZEND_ARG_INFO(0, host)
! 118: ZEND_ARG_INFO(0, community)
! 119: ZEND_ARG_INFO(0, object_id)
! 120: ZEND_ARG_INFO(0, timeout)
! 121: ZEND_ARG_INFO(0, retries)
! 122: ZEND_END_ARG_INFO()
! 123:
! 124: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmpgetnext, 0, 0, 3)
! 125: ZEND_ARG_INFO(0, host)
! 126: ZEND_ARG_INFO(0, community)
! 127: ZEND_ARG_INFO(0, object_id)
! 128: ZEND_ARG_INFO(0, timeout)
! 129: ZEND_ARG_INFO(0, retries)
! 130: ZEND_END_ARG_INFO()
! 131:
! 132: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmpwalk, 0, 0, 3)
! 133: ZEND_ARG_INFO(0, host)
! 134: ZEND_ARG_INFO(0, community)
! 135: ZEND_ARG_INFO(0, object_id)
! 136: ZEND_ARG_INFO(0, timeout)
! 137: ZEND_ARG_INFO(0, retries)
! 138: ZEND_END_ARG_INFO()
! 139:
! 140: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmprealwalk, 0, 0, 3)
! 141: ZEND_ARG_INFO(0, host)
! 142: ZEND_ARG_INFO(0, community)
! 143: ZEND_ARG_INFO(0, object_id)
! 144: ZEND_ARG_INFO(0, timeout)
! 145: ZEND_ARG_INFO(0, retries)
! 146: ZEND_END_ARG_INFO()
! 147:
! 148: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_get_quick_print, 0, 0, 1)
! 149: ZEND_ARG_INFO(0, d)
! 150: ZEND_END_ARG_INFO()
! 151:
! 152: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_set_quick_print, 0, 0, 1)
! 153: ZEND_ARG_INFO(0, quick_print)
! 154: ZEND_END_ARG_INFO()
! 155:
! 156: #ifdef HAVE_NET_SNMP
! 157: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_set_enum_print, 0, 0, 1)
! 158: ZEND_ARG_INFO(0, enum_print)
! 159: ZEND_END_ARG_INFO()
! 160:
! 161: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_set_oid_output_format, 0, 0, 1)
! 162: ZEND_ARG_INFO(0, oid_format)
! 163: ZEND_END_ARG_INFO()
! 164: #endif
! 165:
! 166: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmpset, 0, 0, 5)
! 167: ZEND_ARG_INFO(0, host)
! 168: ZEND_ARG_INFO(0, community)
! 169: ZEND_ARG_INFO(0, object_id)
! 170: ZEND_ARG_INFO(0, type)
! 171: ZEND_ARG_INFO(0, value)
! 172: ZEND_ARG_INFO(0, timeout)
! 173: ZEND_ARG_INFO(0, retries)
! 174: ZEND_END_ARG_INFO()
! 175:
! 176: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp2_get, 0, 0, 3)
! 177: ZEND_ARG_INFO(0, host)
! 178: ZEND_ARG_INFO(0, community)
! 179: ZEND_ARG_INFO(0, object_id)
! 180: ZEND_ARG_INFO(0, timeout)
! 181: ZEND_ARG_INFO(0, retries)
! 182: ZEND_END_ARG_INFO()
! 183:
! 184: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp2_getnext, 0, 0, 3)
! 185: ZEND_ARG_INFO(0, host)
! 186: ZEND_ARG_INFO(0, community)
! 187: ZEND_ARG_INFO(0, object_id)
! 188: ZEND_ARG_INFO(0, timeout)
! 189: ZEND_ARG_INFO(0, retries)
! 190: ZEND_END_ARG_INFO()
! 191:
! 192: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp2_walk, 0, 0, 3)
! 193: ZEND_ARG_INFO(0, host)
! 194: ZEND_ARG_INFO(0, community)
! 195: ZEND_ARG_INFO(0, object_id)
! 196: ZEND_ARG_INFO(0, timeout)
! 197: ZEND_ARG_INFO(0, retries)
! 198: ZEND_END_ARG_INFO()
! 199:
! 200: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp2_real_walk, 0, 0, 3)
! 201: ZEND_ARG_INFO(0, host)
! 202: ZEND_ARG_INFO(0, community)
! 203: ZEND_ARG_INFO(0, object_id)
! 204: ZEND_ARG_INFO(0, timeout)
! 205: ZEND_ARG_INFO(0, retries)
! 206: ZEND_END_ARG_INFO()
! 207:
! 208: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp2_set, 0, 0, 5)
! 209: ZEND_ARG_INFO(0, host)
! 210: ZEND_ARG_INFO(0, community)
! 211: ZEND_ARG_INFO(0, object_id)
! 212: ZEND_ARG_INFO(0, type)
! 213: ZEND_ARG_INFO(0, value)
! 214: ZEND_ARG_INFO(0, timeout)
! 215: ZEND_ARG_INFO(0, retries)
! 216: ZEND_END_ARG_INFO()
! 217:
! 218: ZEND_BEGIN_ARG_INFO_EX(arginfo_php_snmpv3, 0, 0, 2)
! 219: ZEND_ARG_INFO(0, s)
! 220: ZEND_ARG_INFO(0, st)
! 221: ZEND_END_ARG_INFO()
! 222:
! 223: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp3_get, 0, 0, 8)
! 224: ZEND_ARG_INFO(0, host)
! 225: ZEND_ARG_INFO(0, sec_name)
! 226: ZEND_ARG_INFO(0, sec_level)
! 227: ZEND_ARG_INFO(0, auth_protocol)
! 228: ZEND_ARG_INFO(0, auth_passphrase)
! 229: ZEND_ARG_INFO(0, priv_protocol)
! 230: ZEND_ARG_INFO(0, priv_passphrase)
! 231: ZEND_ARG_INFO(0, object_id)
! 232: ZEND_ARG_INFO(0, timeout)
! 233: ZEND_ARG_INFO(0, retries)
! 234: ZEND_END_ARG_INFO()
! 235:
! 236: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp3_getnext, 0, 0, 8)
! 237: ZEND_ARG_INFO(0, host)
! 238: ZEND_ARG_INFO(0, sec_name)
! 239: ZEND_ARG_INFO(0, sec_level)
! 240: ZEND_ARG_INFO(0, auth_protocol)
! 241: ZEND_ARG_INFO(0, auth_passphrase)
! 242: ZEND_ARG_INFO(0, priv_protocol)
! 243: ZEND_ARG_INFO(0, priv_passphrase)
! 244: ZEND_ARG_INFO(0, object_id)
! 245: ZEND_ARG_INFO(0, timeout)
! 246: ZEND_ARG_INFO(0, retries)
! 247: ZEND_END_ARG_INFO()
! 248:
! 249: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp3_walk, 0, 0, 8)
! 250: ZEND_ARG_INFO(0, host)
! 251: ZEND_ARG_INFO(0, sec_name)
! 252: ZEND_ARG_INFO(0, sec_level)
! 253: ZEND_ARG_INFO(0, auth_protocol)
! 254: ZEND_ARG_INFO(0, auth_passphrase)
! 255: ZEND_ARG_INFO(0, priv_protocol)
! 256: ZEND_ARG_INFO(0, priv_passphrase)
! 257: ZEND_ARG_INFO(0, object_id)
! 258: ZEND_ARG_INFO(0, timeout)
! 259: ZEND_ARG_INFO(0, retries)
! 260: ZEND_END_ARG_INFO()
! 261:
! 262: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp3_real_walk, 0, 0, 8)
! 263: ZEND_ARG_INFO(0, host)
! 264: ZEND_ARG_INFO(0, sec_name)
! 265: ZEND_ARG_INFO(0, sec_level)
! 266: ZEND_ARG_INFO(0, auth_protocol)
! 267: ZEND_ARG_INFO(0, auth_passphrase)
! 268: ZEND_ARG_INFO(0, priv_protocol)
! 269: ZEND_ARG_INFO(0, priv_passphrase)
! 270: ZEND_ARG_INFO(0, object_id)
! 271: ZEND_ARG_INFO(0, timeout)
! 272: ZEND_ARG_INFO(0, retries)
! 273: ZEND_END_ARG_INFO()
! 274:
! 275: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp3_set, 0, 0, 10)
! 276: ZEND_ARG_INFO(0, host)
! 277: ZEND_ARG_INFO(0, sec_name)
! 278: ZEND_ARG_INFO(0, sec_level)
! 279: ZEND_ARG_INFO(0, auth_protocol)
! 280: ZEND_ARG_INFO(0, auth_passphrase)
! 281: ZEND_ARG_INFO(0, priv_protocol)
! 282: ZEND_ARG_INFO(0, priv_passphrase)
! 283: ZEND_ARG_INFO(0, object_id)
! 284: ZEND_ARG_INFO(0, type)
! 285: ZEND_ARG_INFO(0, value)
! 286: ZEND_ARG_INFO(0, timeout)
! 287: ZEND_ARG_INFO(0, retries)
! 288: ZEND_END_ARG_INFO()
! 289:
! 290: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_set_valueretrieval, 0, 0, 1)
! 291: ZEND_ARG_INFO(0, method)
! 292: ZEND_END_ARG_INFO()
! 293:
! 294: ZEND_BEGIN_ARG_INFO(arginfo_snmp_get_valueretrieval, 0)
! 295: ZEND_END_ARG_INFO()
! 296:
! 297: ZEND_BEGIN_ARG_INFO_EX(arginfo_snmp_read_mib, 0, 0, 1)
! 298: ZEND_ARG_INFO(0, filename)
! 299: ZEND_END_ARG_INFO()
! 300: /* }}} */
! 301:
! 302: /* {{{ snmp_functions[]
! 303: */
! 304: const zend_function_entry snmp_functions[] = {
! 305: PHP_FE(snmpget, arginfo_snmpget)
! 306: PHP_FE(snmpgetnext, arginfo_snmpgetnext)
! 307: PHP_FE(snmpwalk, arginfo_snmpwalk)
! 308: PHP_FE(snmprealwalk, arginfo_snmprealwalk)
! 309: PHP_FALIAS(snmpwalkoid, snmprealwalk, arginfo_snmprealwalk)
! 310: PHP_FE(snmp_get_quick_print, arginfo_snmp_get_quick_print)
! 311: PHP_FE(snmp_set_quick_print, arginfo_snmp_set_quick_print)
! 312: #ifdef HAVE_NET_SNMP
! 313: PHP_FE(snmp_set_enum_print, arginfo_snmp_set_enum_print)
! 314: PHP_FE(snmp_set_oid_output_format, arginfo_snmp_set_oid_output_format)
! 315: PHP_FALIAS(snmp_set_oid_numeric_print, snmp_set_oid_output_format, arginfo_snmp_set_oid_output_format)
! 316: #endif
! 317: PHP_FE(snmpset, arginfo_snmpset)
! 318:
! 319: PHP_FE(snmp2_get, arginfo_snmp2_get)
! 320: PHP_FE(snmp2_getnext, arginfo_snmp2_getnext)
! 321: PHP_FE(snmp2_walk, arginfo_snmp2_walk)
! 322: PHP_FE(snmp2_real_walk, arginfo_snmp2_real_walk)
! 323: PHP_FE(snmp2_set, arginfo_snmp2_set)
! 324:
! 325: PHP_FE(snmp3_get, arginfo_snmp3_get)
! 326: PHP_FE(snmp3_getnext, arginfo_snmp3_getnext)
! 327: PHP_FE(snmp3_walk, arginfo_snmp3_walk)
! 328: PHP_FE(snmp3_real_walk, arginfo_snmp3_real_walk)
! 329: PHP_FE(snmp3_set, arginfo_snmp3_set)
! 330: PHP_FE(snmp_set_valueretrieval, arginfo_snmp_set_valueretrieval)
! 331: PHP_FE(snmp_get_valueretrieval, arginfo_snmp_get_valueretrieval)
! 332:
! 333: PHP_FE(snmp_read_mib, arginfo_snmp_read_mib)
! 334: PHP_FE_END
! 335: };
! 336: /* }}} */
! 337:
! 338: #define SNMP_CMD_GET 1
! 339: #define SNMP_CMD_GETNEXT 2
! 340: #define SNMP_CMD_WALK 3
! 341: #define SNMP_CMD_REALWALK 4
! 342: #define SNMP_CMD_SET 11
! 343:
! 344: /* {{{ snmp_module_entry
! 345: */
! 346: zend_module_entry snmp_module_entry = {
! 347: STANDARD_MODULE_HEADER,
! 348: "snmp",
! 349: snmp_functions,
! 350: PHP_MINIT(snmp),
! 351: PHP_MSHUTDOWN(snmp),
! 352: NULL,
! 353: NULL,
! 354: PHP_MINFO(snmp),
! 355: NO_VERSION_YET,
! 356: PHP_MODULE_GLOBALS(snmp),
! 357: PHP_GINIT(snmp),
! 358: NULL,
! 359: NULL,
! 360: STANDARD_MODULE_PROPERTIES_EX
! 361: };
! 362: /* }}} */
! 363:
! 364: #ifdef COMPILE_DL_SNMP
! 365: ZEND_GET_MODULE(snmp)
! 366: #endif
! 367:
! 368: /* THREAD_LS snmp_module php_snmp_module; - may need one of these at some point */
! 369:
! 370: /* {{{ PHP_GINIT_FUNCTION
! 371: */
! 372: static PHP_GINIT_FUNCTION(snmp)
! 373: {
! 374: snmp_globals->valueretrieval = SNMP_VALUE_LIBRARY;
! 375: }
! 376: /* }}} */
! 377:
! 378: /* {{{ PHP_MINIT_FUNCTION
! 379: */
! 380: PHP_MINIT_FUNCTION(snmp)
! 381: {
! 382: init_snmp("snmpapp");
! 383:
! 384: #ifdef NETSNMP_DS_LIB_DONT_PERSIST_STATE
! 385: /* Prevent update of the snmpapp.conf file */
! 386: netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1);
! 387: #endif
! 388:
! 389: #ifdef HAVE_NET_SNMP
! 390: REGISTER_LONG_CONSTANT("SNMP_OID_OUTPUT_FULL", NETSNMP_OID_OUTPUT_FULL, CONST_CS | CONST_PERSISTENT);
! 391: REGISTER_LONG_CONSTANT("SNMP_OID_OUTPUT_NUMERIC", NETSNMP_OID_OUTPUT_NUMERIC, CONST_CS | CONST_PERSISTENT);
! 392: #endif
! 393:
! 394: REGISTER_LONG_CONSTANT("SNMP_VALUE_LIBRARY", SNMP_VALUE_LIBRARY, CONST_CS | CONST_PERSISTENT);
! 395: REGISTER_LONG_CONSTANT("SNMP_VALUE_PLAIN", SNMP_VALUE_PLAIN, CONST_CS | CONST_PERSISTENT);
! 396: REGISTER_LONG_CONSTANT("SNMP_VALUE_OBJECT", SNMP_VALUE_OBJECT, CONST_CS | CONST_PERSISTENT);
! 397:
! 398: REGISTER_LONG_CONSTANT("SNMP_BIT_STR", ASN_BIT_STR, CONST_CS | CONST_PERSISTENT);
! 399: REGISTER_LONG_CONSTANT("SNMP_OCTET_STR", ASN_OCTET_STR, CONST_CS | CONST_PERSISTENT);
! 400: REGISTER_LONG_CONSTANT("SNMP_OPAQUE", ASN_OPAQUE, CONST_CS | CONST_PERSISTENT);
! 401: REGISTER_LONG_CONSTANT("SNMP_NULL", ASN_NULL, CONST_CS | CONST_PERSISTENT);
! 402: REGISTER_LONG_CONSTANT("SNMP_OBJECT_ID", ASN_OBJECT_ID, CONST_CS | CONST_PERSISTENT);
! 403: REGISTER_LONG_CONSTANT("SNMP_IPADDRESS", ASN_IPADDRESS, CONST_CS | CONST_PERSISTENT);
! 404: REGISTER_LONG_CONSTANT("SNMP_COUNTER", ASN_GAUGE, CONST_CS | CONST_PERSISTENT);
! 405: REGISTER_LONG_CONSTANT("SNMP_UNSIGNED", ASN_UNSIGNED, CONST_CS | CONST_PERSISTENT);
! 406: REGISTER_LONG_CONSTANT("SNMP_TIMETICKS", ASN_TIMETICKS, CONST_CS | CONST_PERSISTENT);
! 407: REGISTER_LONG_CONSTANT("SNMP_UINTEGER", ASN_UINTEGER, CONST_CS | CONST_PERSISTENT);
! 408: REGISTER_LONG_CONSTANT("SNMP_INTEGER", ASN_INTEGER, CONST_CS | CONST_PERSISTENT);
! 409: REGISTER_LONG_CONSTANT("SNMP_COUNTER64", ASN_COUNTER64, CONST_CS | CONST_PERSISTENT);
! 410:
! 411: return SUCCESS;
! 412: }
! 413: /* }}} */
! 414:
! 415: /* {{{ PHP_MSHUTDOWN_FUNCTION
! 416: */
! 417: PHP_MSHUTDOWN_FUNCTION(snmp)
! 418: {
! 419: snmp_shutdown("snmpapp");
! 420:
! 421: return SUCCESS;
! 422: }
! 423: /* }}} */
! 424:
! 425: /* {{{ PHP_MINFO_FUNCTION
! 426: */
! 427: PHP_MINFO_FUNCTION(snmp)
! 428: {
! 429: php_info_print_table_start();
! 430: #ifdef HAVE_NET_SNMP
! 431: php_info_print_table_row(2, "NET-SNMP Support", "enabled");
! 432: php_info_print_table_row(2, "NET-SNMP Version", netsnmp_get_version());
! 433: #else
! 434: php_info_print_table_row(2, "UCD-SNMP Support", "enabled");
! 435: php_info_print_table_row(2, "UCD-SNMP Version", VersionInfo);
! 436: #endif
! 437: php_info_print_table_end();
! 438: }
! 439: /* }}} */
! 440:
! 441: static void php_snmp_getvalue(struct variable_list *vars, zval *snmpval TSRMLS_DC)
! 442: {
! 443: zval *val;
! 444: #if I64CHARSZ > 2047
! 445: char buf[I64CHARSZ + 1];
! 446: #else
! 447: char buf[2048];
! 448: #endif
! 449:
! 450: buf[0] = 0;
! 451:
! 452: if (SNMP_G(valueretrieval) == SNMP_VALUE_LIBRARY) {
! 453: #ifdef HAVE_NET_SNMP
! 454: snprint_value(buf, sizeof(buf), vars->name, vars->name_length, vars);
! 455: #else
! 456: sprint_value(buf,vars->name, vars->name_length, vars);
! 457: #endif
! 458: ZVAL_STRING(snmpval, buf, 1);
! 459: return;
! 460: }
! 461:
! 462: MAKE_STD_ZVAL(val);
! 463:
! 464: switch (vars->type) {
! 465: case ASN_BIT_STR: /* 0x03, asn1.h */
! 466: ZVAL_STRINGL(val, vars->val.bitstring, vars->val_len, 1);
! 467: break;
! 468:
! 469: case ASN_OCTET_STR: /* 0x04, asn1.h */
! 470: case ASN_OPAQUE: /* 0x44, snmp_impl.h */
! 471: ZVAL_STRINGL(val, vars->val.string, vars->val_len, 1);
! 472: break;
! 473:
! 474: case ASN_NULL: /* 0x05, asn1.h */
! 475: ZVAL_NULL(val);
! 476: break;
! 477:
! 478: case ASN_OBJECT_ID: /* 0x06, asn1.h */
! 479: #ifdef HAVE_NET_SNMP
! 480: snprint_objid(buf, sizeof(buf), vars->val.objid, vars->val_len / sizeof(oid));
! 481: #else
! 482: sprint_objid(buf, vars->val.objid, vars->val_len / sizeof(oid));
! 483: #endif
! 484:
! 485: ZVAL_STRING(val, buf, 1);
! 486: break;
! 487:
! 488: case ASN_IPADDRESS: /* 0x40, snmp_impl.h */
! 489: snprintf(buf, sizeof(buf)-1, "%d.%d.%d.%d",
! 490: (vars->val.string)[0], (vars->val.string)[1],
! 491: (vars->val.string)[2], (vars->val.string)[3]);
! 492: buf[sizeof(buf)-1]=0;
! 493: ZVAL_STRING(val, buf, 1);
! 494: break;
! 495:
! 496: case ASN_COUNTER: /* 0x41, snmp_impl.h */
! 497: case ASN_GAUGE: /* 0x42, snmp_impl.h */
! 498: /* ASN_UNSIGNED is the same as ASN_GAUGE */
! 499: case ASN_TIMETICKS: /* 0x43, snmp_impl.h */
! 500: case ASN_UINTEGER: /* 0x47, snmp_impl.h */
! 501: snprintf(buf, sizeof(buf)-1, "%lu", *vars->val.integer);
! 502: buf[sizeof(buf)-1]=0;
! 503: ZVAL_STRING(val, buf, 1);
! 504: break;
! 505:
! 506: case ASN_INTEGER: /* 0x02, asn1.h */
! 507: snprintf(buf, sizeof(buf)-1, "%ld", *vars->val.integer);
! 508: buf[sizeof(buf)-1]=0;
! 509: ZVAL_STRING(val, buf, 1);
! 510: break;
! 511:
! 512: case ASN_COUNTER64: /* 0x46, snmp_impl.h */
! 513: printU64(buf, vars->val.counter64);
! 514: ZVAL_STRING(val, buf, 1);
! 515: break;
! 516:
! 517: default:
! 518: ZVAL_STRING(val, "Unknown value type", 1);
! 519: break;
! 520: }
! 521:
! 522: if (SNMP_G(valueretrieval) == SNMP_VALUE_PLAIN) {
! 523: *snmpval = *val;
! 524: zval_copy_ctor(snmpval);
! 525: } else {
! 526: object_init(snmpval);
! 527: add_property_long(snmpval, "type", vars->type);
! 528: add_property_zval(snmpval, "value", val);
! 529: }
! 530: }
! 531:
! 532: /* {{{ php_snmp_internal
! 533: *
! 534: * Generic SNMP object fetcher (for all SNMP versions)
! 535: *
! 536: * st=SNMP_CMD_GET get - query an agent with SNMP-GET.
! 537: * st=SNMP_CMD_GETNEXT getnext - query an agent with SNMP-GETNEXT.
! 538: * st=SNMP_CMD_WALK walk - walk the mib and return a single dimensional array
! 539: * containing the values.
! 540: * st=SNMP_CMD_REALWALK realwalk() and walkoid() - walk the mib and return an
! 541: * array of oid,value pairs.
! 542: * st=SNMP_CMD_SET set() - query an agent and set a single value
! 543: *
! 544: */
! 545: static void php_snmp_internal(INTERNAL_FUNCTION_PARAMETERS, int st,
! 546: struct snmp_session *session,
! 547: char *objid,
! 548: char type,
! 549: char* value)
! 550: {
! 551: struct snmp_session *ss;
! 552: struct snmp_pdu *pdu=NULL, *response;
! 553: struct variable_list *vars;
! 554: oid name[MAX_NAME_LEN];
! 555: size_t name_length;
! 556: oid root[MAX_NAME_LEN];
! 557: size_t rootlen = 0;
! 558: int gotroot = 0;
! 559: int status, count;
! 560: char buf[2048];
! 561: char buf2[2048];
! 562: int keepwalking=1;
! 563: char *err;
! 564: zval *snmpval = NULL;
! 565:
! 566: if (st >= SNMP_CMD_WALK) { /* walk */
! 567: rootlen = MAX_NAME_LEN;
! 568: if (strlen(objid)) { /* on a walk, an empty string means top of tree - no error */
! 569: if (snmp_parse_oid(objid, root, &rootlen)) {
! 570: gotroot = 1;
! 571: } else {
! 572: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", objid);
! 573: }
! 574: }
! 575:
! 576: if (!gotroot) {
! 577: memmove((char *) root, (char *) objid_mib, sizeof(objid_mib));
! 578: rootlen = sizeof(objid_mib) / sizeof(oid);
! 579: gotroot = 1;
! 580: }
! 581: }
! 582:
! 583: if ((ss = snmp_open(session)) == NULL) {
! 584: snmp_error(session, NULL, NULL, &err);
! 585: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not open snmp connection: %s", err);
! 586: free(err);
! 587: RETURN_FALSE;
! 588: }
! 589:
! 590: if (st >= SNMP_CMD_WALK) {
! 591: memmove((char *)name, (char *)root, rootlen * sizeof(oid));
! 592: name_length = rootlen;
! 593: switch(st) {
! 594: case SNMP_CMD_WALK:
! 595: case SNMP_CMD_REALWALK:
! 596: array_init(return_value);
! 597: break;
! 598: default:
! 599: RETVAL_TRUE;
! 600: break;
! 601: }
! 602: }
! 603:
! 604: while (keepwalking) {
! 605: keepwalking = 0;
! 606: if ((st == SNMP_CMD_GET) || (st == SNMP_CMD_GETNEXT)) {
! 607: name_length = MAX_OID_LEN;
! 608: if (!snmp_parse_oid(objid, name, &name_length)) {
! 609: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid object identifier: %s", objid);
! 610: snmp_close(ss);
! 611: RETURN_FALSE;
! 612: }
! 613: pdu = snmp_pdu_create((st == SNMP_CMD_GET) ? SNMP_MSG_GET : SNMP_MSG_GETNEXT);
! 614: snmp_add_null_var(pdu, name, name_length);
! 615: } else if (st == SNMP_CMD_SET) {
! 616: pdu = snmp_pdu_create(SNMP_MSG_SET);
! 617: if (snmp_add_var(pdu, name, name_length, type, value)) {
! 618: #ifdef HAVE_NET_SNMP
! 619: snprint_objid(buf, sizeof(buf), name, name_length);
! 620: #else
! 621: sprint_objid(buf, name, name_length);
! 622: #endif
! 623: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not add variable: %s %c %s", buf, type, value);
! 624: snmp_free_pdu(pdu);
! 625: snmp_close(ss);
! 626: RETURN_FALSE;
! 627: }
! 628: } else if (st >= SNMP_CMD_WALK) {
! 629: if (session->version == SNMP_VERSION_1) {
! 630: pdu = snmp_pdu_create(SNMP_MSG_GETNEXT);
! 631: } else {
! 632: pdu = snmp_pdu_create(SNMP_MSG_GETBULK);
! 633: pdu->non_repeaters = 0;
! 634: pdu->max_repetitions = 20;
! 635: }
! 636: snmp_add_null_var(pdu, name, name_length);
! 637: }
! 638:
! 639: retry:
! 640: status = snmp_synch_response(ss, pdu, &response);
! 641: if (status == STAT_SUCCESS) {
! 642: if (response->errstat == SNMP_ERR_NOERROR) {
! 643: for (vars = response->variables; vars; vars = vars->next_variable) {
! 644: if (st >= SNMP_CMD_WALK && st != SNMP_CMD_SET &&
! 645: (vars->name_length < rootlen || memcmp(root, vars->name, rootlen * sizeof(oid)))) {
! 646: continue; /* not part of this subtree */
! 647: }
! 648:
! 649: if (st != SNMP_CMD_SET) {
! 650: MAKE_STD_ZVAL(snmpval);
! 651: php_snmp_getvalue(vars, snmpval TSRMLS_CC);
! 652: }
! 653:
! 654: if (st == SNMP_CMD_GET) {
! 655: *return_value = *snmpval;
! 656: zval_copy_ctor(return_value);
! 657: zval_ptr_dtor(&snmpval);
! 658: snmp_free_pdu(response);
! 659: snmp_close(ss);
! 660: return;
! 661: } else if (st == SNMP_CMD_GETNEXT) {
! 662: *return_value = *snmpval;
! 663: zval_copy_ctor(return_value);
! 664: snmp_free_pdu(response);
! 665: snmp_close(ss);
! 666: return;
! 667: } else if (st == SNMP_CMD_WALK) {
! 668: add_next_index_zval(return_value,snmpval); /* Add to returned array */
! 669: } else if (st == SNMP_CMD_REALWALK && vars->type != SNMP_ENDOFMIBVIEW && vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) {
! 670: #ifdef HAVE_NET_SNMP
! 671: snprint_objid(buf2, sizeof(buf2), vars->name, vars->name_length);
! 672: #else
! 673: sprint_objid(buf2, vars->name, vars->name_length);
! 674: #endif
! 675: add_assoc_zval(return_value,buf2,snmpval);
! 676: }
! 677: if (st >= SNMP_CMD_WALK && st != SNMP_CMD_SET) {
! 678: if (vars->type != SNMP_ENDOFMIBVIEW &&
! 679: vars->type != SNMP_NOSUCHOBJECT && vars->type != SNMP_NOSUCHINSTANCE) {
! 680: if (snmp_oid_compare(name, name_length, vars->name, vars->name_length) >= 0) {
! 681: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error: OID not increasing: %s",name);
! 682: keepwalking = 0;
! 683: } else {
! 684: memmove((char *)name, (char *)vars->name,vars->name_length * sizeof(oid));
! 685: name_length = vars->name_length;
! 686: keepwalking = 1;
! 687: }
! 688: }
! 689: }
! 690: }
! 691: } else {
! 692: if ((st != SNMP_CMD_WALK && st != SNMP_CMD_REALWALK) || response->errstat != SNMP_ERR_NOSUCHNAME) {
! 693: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error in packet: %s", snmp_errstring(response->errstat));
! 694: if (response->errstat == SNMP_ERR_NOSUCHNAME) {
! 695: for (count=1, vars = response->variables; vars && count != response->errindex;
! 696: vars = vars->next_variable, count++);
! 697: if (vars) {
! 698: #ifdef HAVE_NET_SNMP
! 699: snprint_objid(buf, sizeof(buf), vars->name, vars->name_length);
! 700: #else
! 701: sprint_objid(buf,vars->name, vars->name_length);
! 702: #endif
! 703: }
! 704: php_error_docref(NULL TSRMLS_CC, E_WARNING, "This name does not exist: %s",buf);
! 705: }
! 706: if (st == SNMP_CMD_GET) {
! 707: if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GET)) != NULL) {
! 708: snmp_free_pdu(response);
! 709: goto retry;
! 710: }
! 711: } else if (st == SNMP_CMD_SET) {
! 712: if ((pdu = snmp_fix_pdu(response, SNMP_MSG_SET)) != NULL) {
! 713: snmp_free_pdu(response);
! 714: goto retry;
! 715: }
! 716: } else if (st == SNMP_CMD_GETNEXT) {
! 717: if ((pdu = snmp_fix_pdu(response, SNMP_MSG_GETNEXT)) != NULL) {
! 718: snmp_free_pdu(response);
! 719: goto retry;
! 720: }
! 721: } else if (st >= SNMP_CMD_WALK) { /* Here we do walks. */
! 722: if ((pdu = snmp_fix_pdu(response, ((session->version == SNMP_VERSION_1)
! 723: ? SNMP_MSG_GETNEXT
! 724: : SNMP_MSG_GETBULK))) != NULL) {
! 725: snmp_free_pdu(response);
! 726: goto retry;
! 727: }
! 728: }
! 729: snmp_free_pdu(response);
! 730: snmp_close(ss);
! 731: if (st == SNMP_CMD_WALK || st == SNMP_CMD_REALWALK) {
! 732: zval_dtor(return_value);
! 733: }
! 734: RETURN_FALSE;
! 735: }
! 736: }
! 737: } else if (status == STAT_TIMEOUT) {
! 738: php_error_docref(NULL TSRMLS_CC, E_WARNING, "No response from %s", session->peername);
! 739: if (st == SNMP_CMD_WALK || st == SNMP_CMD_REALWALK) {
! 740: zval_dtor(return_value);
! 741: }
! 742: snmp_close(ss);
! 743: RETURN_FALSE;
! 744: } else { /* status == STAT_ERROR */
! 745: php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred, quitting");
! 746: if (st == SNMP_CMD_WALK || st == SNMP_CMD_REALWALK) {
! 747: zval_dtor(return_value);
! 748: }
! 749: snmp_close(ss);
! 750: RETURN_FALSE;
! 751: }
! 752: if (response) {
! 753: snmp_free_pdu(response);
! 754: }
! 755: } /* keepwalking */
! 756: snmp_close(ss);
! 757: }
! 758: /* }}} */
! 759:
! 760: /* {{{ php_snmp
! 761: *
! 762: * Generic community based SNMP handler for version 1 and 2.
! 763: * This function makes use of the internal SNMP object fetcher.
! 764: * The object fetcher is shared with SNMPv3.
! 765: *
! 766: * st=SNMP_CMD_GET get - query an agent with SNMP-GET.
! 767: * st=SNMP_CMD_GETNEXT getnext - query an agent with SNMP-GETNEXT.
! 768: * st=SNMP_CMD_WALK walk - walk the mib and return a single dimensional array
! 769: * containing the values.
! 770: * st=SNMP_CMD_REALWALK realwalk() and walkoid() - walk the mib and return an
! 771: * array of oid,value pairs.
! 772: * st=5-8 ** Reserved **
! 773: * st=SNMP_CMD_SET set() - query an agent and set a single value
! 774: *
! 775: */
! 776: static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version)
! 777: {
! 778: char *a1, *a2, *a3;
! 779: int a1_len, a2_len, a3_len;
! 780: struct snmp_session session;
! 781: long timeout = SNMP_DEFAULT_TIMEOUT;
! 782: long retries = SNMP_DEFAULT_RETRIES;
! 783: char type = (char) 0;
! 784: char *value = (char *) 0, *stype = "";
! 785: int value_len, stype_len;
! 786: char hostname[MAX_NAME_LEN];
! 787: int remote_port = 161;
! 788: char *pptr;
! 789: int argc = ZEND_NUM_ARGS();
! 790:
! 791: if (st == SNMP_CMD_SET) {
! 792: if (zend_parse_parameters(argc TSRMLS_CC, "sssss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &stype, &stype_len, &value, &value_len, &timeout, &retries) == FAILURE) {
! 793: return;
! 794: }
! 795: } else {
! 796: /* SNMP_CMD_GET
! 797: * SNMP_CMD_GETNEXT
! 798: * SNMP_CMD_WALK
! 799: * SNMP_CMD_REALWALK
! 800: */
! 801: if (zend_parse_parameters(argc TSRMLS_CC, "sss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &timeout, &retries) == FAILURE) {
! 802: return;
! 803: }
! 804: }
! 805:
! 806: if (st == SNMP_CMD_SET) {
! 807: type = stype[0];
! 808: }
! 809:
! 810: snmp_sess_init(&session);
! 811: strlcpy(hostname, a1, sizeof(hostname));
! 812: if ((pptr = strchr (hostname, ':'))) {
! 813: remote_port = strtol (pptr + 1, NULL, 0);
! 814: }
! 815:
! 816: session.peername = hostname;
! 817: session.remote_port = remote_port;
! 818: session.version = version;
! 819: /*
! 820: * FIXME: potential memory leak
! 821: * This is a workaround for an "artifact" (Mike Slifcak)
! 822: * in (at least) ucd-snmp 3.6.1 which frees
! 823: * memory it did not allocate
! 824: */
! 825: #ifdef UCD_SNMP_HACK
! 826: session.community = (u_char *)strdup(a2); /* memory freed by SNMP library, strdup NOT estrdup */
! 827: #else
! 828: session.community = (u_char *)a2;
! 829: #endif
! 830: session.community_len = a2_len;
! 831: session.retries = retries;
! 832: session.timeout = timeout;
! 833:
! 834: session.authenticator = NULL;
! 835:
! 836: php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, &session, a3, type, value);
! 837: }
! 838: /* }}} */
! 839:
! 840: /* {{{ proto string snmpget(string host, string community, string object_id [, int timeout [, int retries]])
! 841: Fetch a SNMP object */
! 842: PHP_FUNCTION(snmpget)
! 843: {
! 844: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GET, SNMP_VERSION_1);
! 845: }
! 846: /* }}} */
! 847:
! 848: /* {{{ proto string snmpgetnext(string host, string community, string object_id [, int timeout [, int retries]])
! 849: Fetch a SNMP object */
! 850: PHP_FUNCTION(snmpgetnext)
! 851: {
! 852: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GETNEXT, SNMP_VERSION_1);
! 853: }
! 854: /* }}} */
! 855:
! 856: /* {{{ proto array snmpwalk(string host, string community, string object_id [, int timeout [, int retries]])
! 857: Return all objects under the specified object id */
! 858: PHP_FUNCTION(snmpwalk)
! 859: {
! 860: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_WALK, SNMP_VERSION_1);
! 861: }
! 862: /* }}} */
! 863:
! 864: /* {{{ proto array snmprealwalk(string host, string community, string object_id [, int timeout [, int retries]])
! 865: Return all objects including their respective object id withing the specified one */
! 866: PHP_FUNCTION(snmprealwalk)
! 867: {
! 868: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_REALWALK, SNMP_VERSION_1);
! 869: }
! 870: /* }}} */
! 871:
! 872: /* {{{ proto bool snmp_get_quick_print(void)
! 873: Return the current status of quick_print */
! 874: PHP_FUNCTION(snmp_get_quick_print)
! 875: {
! 876: if (zend_parse_parameters_none() == FAILURE) {
! 877: return;
! 878: }
! 879:
! 880: #ifdef HAVE_NET_SNMP
! 881: RETURN_BOOL(netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT));
! 882: #else
! 883: RETURN_BOOL(snmp_get_quick_print());
! 884: #endif
! 885: }
! 886: /* }}} */
! 887:
! 888: /* {{{ proto void snmp_set_quick_print(int quick_print)
! 889: Return all objects including their respective object id withing the specified one */
! 890: PHP_FUNCTION(snmp_set_quick_print)
! 891: {
! 892: long a1;
! 893:
! 894: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &a1) == FAILURE) {
! 895: return;
! 896: }
! 897:
! 898: #ifdef HAVE_NET_SNMP
! 899: netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_QUICK_PRINT, (int) a1);
! 900: #else
! 901: snmp_set_quick_print((int)a1);
! 902: #endif
! 903: }
! 904: /* }}} */
! 905:
! 906: #ifdef HAVE_NET_SNMP
! 907: /* {{{ proto void snmp_set_enum_print(int enum_print)
! 908: Return all values that are enums with their enum value instead of the raw integer */
! 909: PHP_FUNCTION(snmp_set_enum_print)
! 910: {
! 911: long a1;
! 912:
! 913: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &a1) == FAILURE) {
! 914: return;
! 915: }
! 916:
! 917: netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_PRINT_NUMERIC_ENUM, (int) a1);
! 918: }
! 919: /* }}} */
! 920:
! 921: /* {{{ proto void snmp_set_oid_output_format(int oid_format)
! 922: Set the OID output format. */
! 923: PHP_FUNCTION(snmp_set_oid_output_format)
! 924: {
! 925: long a1;
! 926:
! 927: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &a1) == FAILURE) {
! 928: return;
! 929: }
! 930:
! 931: switch ((int) a1) {
! 932: case 0:
! 933: case NETSNMP_OID_OUTPUT_FULL:
! 934: a1 = NETSNMP_OID_OUTPUT_FULL;
! 935: break;
! 936:
! 937: default:
! 938: case NETSNMP_OID_OUTPUT_NUMERIC:
! 939: a1 = NETSNMP_OID_OUTPUT_NUMERIC;
! 940: break;
! 941: }
! 942:
! 943: netsnmp_ds_set_int(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_OID_OUTPUT_FORMAT, a1);
! 944: }
! 945: /* }}} */
! 946: #endif
! 947:
! 948: /* {{{ proto int snmpset(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]])
! 949: Set the value of a SNMP object */
! 950: PHP_FUNCTION(snmpset)
! 951: {
! 952: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_SET, SNMP_VERSION_1);
! 953: }
! 954: /* }}} */
! 955:
! 956: /* {{{ int netsnmp_session_set_sec_name(struct snmp_session *s, char *name)
! 957: Set the security name in the snmpv3 session */
! 958: static int netsnmp_session_set_sec_name(struct snmp_session *s, char *name)
! 959: {
! 960: if ((s) && (name)) {
! 961: s->securityName = strdup(name);
! 962: s->securityNameLen = strlen(s->securityName);
! 963: return (0);
! 964: }
! 965: return (-1);
! 966: }
! 967: /* }}} */
! 968:
! 969: /* {{{ int netsnmp_session_set_sec_level(struct snmp_session *s, char *level)
! 970: Set the security level in the snmpv3 session */
! 971: static int netsnmp_session_set_sec_level(struct snmp_session *s, char *level TSRMLS_DC)
! 972: {
! 973: if ((s) && (level)) {
! 974: if (!strcasecmp(level, "noAuthNoPriv") || !strcasecmp(level, "nanp")) {
! 975: s->securityLevel = SNMP_SEC_LEVEL_NOAUTH;
! 976: return (0);
! 977: } else if (!strcasecmp(level, "authNoPriv") || !strcasecmp(level, "anp")) {
! 978: s->securityLevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
! 979: return (0);
! 980: } else if (!strcasecmp(level, "authPriv") || !strcasecmp(level, "ap")) {
! 981: s->securityLevel = SNMP_SEC_LEVEL_AUTHPRIV;
! 982: return (0);
! 983: }
! 984: }
! 985: return (-1);
! 986: }
! 987: /* }}} */
! 988:
! 989: /* {{{ int netsnmp_session_set_auth_protocol(struct snmp_session *s, char *prot)
! 990: Set the authentication protocol in the snmpv3 session */
! 991: static int netsnmp_session_set_auth_protocol(struct snmp_session *s, char *prot TSRMLS_DC)
! 992: {
! 993: if ((s) && (prot)) {
! 994: if (!strcasecmp(prot, "MD5")) {
! 995: s->securityAuthProto = usmHMACMD5AuthProtocol;
! 996: s->securityAuthProtoLen = OIDSIZE(usmHMACMD5AuthProtocol);
! 997: return (0);
! 998: } else if (!strcasecmp(prot, "SHA")) {
! 999: s->securityAuthProto = usmHMACSHA1AuthProtocol;
! 1000: s->securityAuthProtoLen = OIDSIZE(usmHMACSHA1AuthProtocol);
! 1001: return (0);
! 1002: }
! 1003: }
! 1004: return (-1);
! 1005: }
! 1006: /* }}} */
! 1007:
! 1008: /* {{{ int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot)
! 1009: Set the security protocol in the snmpv3 session */
! 1010: static int netsnmp_session_set_sec_protocol(struct snmp_session *s, char *prot TSRMLS_DC)
! 1011: {
! 1012: if ((s) && (prot)) {
! 1013: if (!strcasecmp(prot, "DES")) {
! 1014: s->securityPrivProto = usmDESPrivProtocol;
! 1015: s->securityPrivProtoLen = OIDSIZE(usmDESPrivProtocol);
! 1016: return (0);
! 1017: #ifdef HAVE_AES
! 1018: } else if (!strcasecmp(prot, "AES128")
! 1019: #ifdef SNMP_VALIDATE_ERR
! 1020: /*
! 1021: * In Net-SNMP before 5.2, the following symbols exist:
! 1022: * usmAES128PrivProtocol, usmAES192PrivProtocol, usmAES256PrivProtocol
! 1023: * In an effort to be more standards-compliant, 5.2 removed the last two.
! 1024: * As of 5.2, the symbols are:
! 1025: * usmAESPrivProtocol, usmAES128PrivProtocol
! 1026: *
! 1027: * As we want this extension to compile on both versions, we use the latter
! 1028: * symbol on purpose, as it's defined to be the same as the former.
! 1029: *
! 1030: * However, in 5.2 the type of usmAES128PrivProtocol is a pointer, not an
! 1031: * array, so we cannot use the OIDSIZE macro because it uses sizeof().
! 1032: *
! 1033: */
! 1034: || !strcasecmp(prot, "AES")) {
! 1035: s->securityPrivProto = usmAES128PrivProtocol;
! 1036: s->securityPrivProtoLen = USM_PRIV_PROTO_AES128_LEN;
! 1037: return (0);
! 1038: #else
! 1039: ) {
! 1040: s->securityPrivProto = usmAES128PrivProtocol;
! 1041: s->securityPrivProtoLen = OIDSIZE(usmAES128PrivProtocol);
! 1042: return (0);
! 1043: } else if (!strcasecmp(prot, "AES192")) {
! 1044: s->securityPrivProto = usmAES192PrivProtocol;
! 1045: s->securityPrivProtoLen = OIDSIZE(usmAES192PrivProtocol);
! 1046: return (0);
! 1047: } else if (!strcasecmp(prot, "AES256")) {
! 1048: s->securityPrivProto = usmAES256PrivProtocol;
! 1049: s->securityPrivProtoLen = OIDSIZE(usmAES256PrivProtocol);
! 1050: return (0);
! 1051: #endif
! 1052: #endif
! 1053: }
! 1054: }
! 1055: return (-1);
! 1056: }
! 1057: /* }}} */
! 1058:
! 1059: /* {{{ int netsnmp_session_gen_auth_key(struct snmp_session *s, char *pass)
! 1060: Make key from pass phrase in the snmpv3 session */
! 1061: static int netsnmp_session_gen_auth_key(struct snmp_session *s, char *pass TSRMLS_DC)
! 1062: {
! 1063: /*
! 1064: * make master key from pass phrases
! 1065: */
! 1066: if ((s) && (pass) && strlen(pass)) {
! 1067: s->securityAuthKeyLen = USM_AUTH_KU_LEN;
! 1068: if (s->securityAuthProto == NULL) {
! 1069: /* get .conf set default */
! 1070: const oid *def = get_default_authtype(&(s->securityAuthProtoLen));
! 1071: s->securityAuthProto = snmp_duplicate_objid(def, s->securityAuthProtoLen);
! 1072: }
! 1073: if (s->securityAuthProto == NULL) {
! 1074: /* assume MD5 */
! 1075: s->securityAuthProto =
! 1076: snmp_duplicate_objid(usmHMACMD5AuthProtocol, OIDSIZE(usmHMACMD5AuthProtocol));
! 1077: s->securityAuthProtoLen = OIDSIZE(usmHMACMD5AuthProtocol);
! 1078: }
! 1079: if (generate_Ku(s->securityAuthProto, s->securityAuthProtoLen,
! 1080: (u_char *) pass, strlen(pass),
! 1081: s->securityAuthKey, &(s->securityAuthKeyLen)) != SNMPERR_SUCCESS) {
! 1082: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error generating a key for authentication pass phrase");
! 1083: return (-2);
! 1084: }
! 1085: return (0);
! 1086: }
! 1087: return (-1);
! 1088: }
! 1089: /* }}} */
! 1090:
! 1091: /* {{{ int netsnmp_session_gen_sec_key(struct snmp_session *s, u_char *pass)
! 1092: Make key from pass phrase in the snmpv3 session */
! 1093: static int netsnmp_session_gen_sec_key(struct snmp_session *s, u_char *pass TSRMLS_DC)
! 1094: {
! 1095: if ((s) && (pass) && strlen(pass)) {
! 1096: s->securityPrivKeyLen = USM_PRIV_KU_LEN;
! 1097: if (s->securityPrivProto == NULL) {
! 1098: /* get .conf set default */
! 1099: const oid *def = get_default_privtype(&(s->securityPrivProtoLen));
! 1100: s->securityPrivProto = snmp_duplicate_objid(def, s->securityPrivProtoLen);
! 1101: }
! 1102: if (s->securityPrivProto == NULL) {
! 1103: /* assume DES */
! 1104: s->securityPrivProto = snmp_duplicate_objid(usmDESPrivProtocol,
! 1105: OIDSIZE(usmDESPrivProtocol));
! 1106: s->securityPrivProtoLen = OIDSIZE(usmDESPrivProtocol);
! 1107: }
! 1108: if (generate_Ku(s->securityAuthProto, s->securityAuthProtoLen,
! 1109: pass, strlen(pass),
! 1110: s->securityPrivKey, &(s->securityPrivKeyLen)) != SNMPERR_SUCCESS) {
! 1111: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error generating a key for privacy pass phrase");
! 1112: return (-2);
! 1113: }
! 1114: return (0);
! 1115: }
! 1116: return (-1);
! 1117: }
! 1118: /* }}} */
! 1119:
! 1120: /* {{{ proto string snmp2_get(string host, string community, string object_id [, int timeout [, int retries]])
! 1121: Fetch a SNMP object */
! 1122: PHP_FUNCTION(snmp2_get)
! 1123: {
! 1124: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GET, SNMP_VERSION_2c);
! 1125: }
! 1126: /* }}} */
! 1127:
! 1128: /* {{{ proto string snmp2_getnext(string host, string community, string object_id [, int timeout [, int retries]])
! 1129: Fetch a SNMP object */
! 1130: PHP_FUNCTION(snmp2_getnext)
! 1131: {
! 1132: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_GETNEXT, SNMP_VERSION_2c);
! 1133: }
! 1134: /* }}} */
! 1135:
! 1136: /* {{{ proto array snmp2_walk(string host, string community, string object_id [, int timeout [, int retries]])
! 1137: Return all objects under the specified object id */
! 1138: PHP_FUNCTION(snmp2_walk)
! 1139: {
! 1140: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_WALK, SNMP_VERSION_2c);
! 1141: }
! 1142: /* }}} */
! 1143:
! 1144: /* {{{ proto array snmp2_real_walk(string host, string community, string object_id [, int timeout [, int retries]])
! 1145: Return all objects including their respective object id withing the specified one */
! 1146: PHP_FUNCTION(snmp2_real_walk)
! 1147: {
! 1148: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_REALWALK, SNMP_VERSION_2c);
! 1149: }
! 1150: /* }}} */
! 1151:
! 1152: /* {{{ proto int snmp2_set(string host, string community, string object_id, string type, mixed value [, int timeout [, int retries]])
! 1153: Set the value of a SNMP object */
! 1154: PHP_FUNCTION(snmp2_set)
! 1155: {
! 1156: php_snmp(INTERNAL_FUNCTION_PARAM_PASSTHRU,SNMP_CMD_SET, SNMP_VERSION_2c);
! 1157: }
! 1158: /* }}} */
! 1159:
! 1160: /* {{{ proto void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st)
! 1161: *
! 1162: * Generic SNMPv3 object fetcher
! 1163: * From here is passed on the common internal object fetcher.
! 1164: *
! 1165: * st=SNMP_CMD_GET snmp3_get() - query an agent and return a single value.
! 1166: * st=SNMP_CMD_GETNEXT snmp3_getnext() - query an agent and return the next single value.
! 1167: * st=SNMP_CMD_WALK snmp3_walk() - walk the mib and return a single dimensional array
! 1168: * containing the values.
! 1169: * st=SNMP_CMD_REALWALK snmp3_real_walk() - walk the mib and return an
! 1170: * array of oid,value pairs.
! 1171: * st=SNMP_CMD_SET snmp3_set() - query an agent and set a single value
! 1172: *
! 1173: */
! 1174: static void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st)
! 1175: {
! 1176: char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
! 1177: int a1_len, a2_len, a3_len, a4_len, a5_len, a6_len, a7_len, a8_len;
! 1178: struct snmp_session session;
! 1179: long timeout = SNMP_DEFAULT_TIMEOUT;
! 1180: long retries = SNMP_DEFAULT_RETRIES;
! 1181: char type = (char) 0;
! 1182: char *value = (char *) 0, *stype = "";
! 1183: int stype_len, value_len;
! 1184: char hostname[MAX_NAME_LEN];
! 1185: int remote_port = 161;
! 1186: char *pptr;
! 1187: int argc = ZEND_NUM_ARGS();
! 1188:
! 1189: if (st == SNMP_CMD_SET) {
! 1190: if (zend_parse_parameters(argc TSRMLS_CC, "ssssssssss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len,
! 1191: &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &a8, &a8_len, &stype, &stype_len, &value, &value_len, &timeout, &retries) == FAILURE) {
! 1192: return;
! 1193: }
! 1194: } else {
! 1195: /* SNMP_CMD_GET
! 1196: * SNMP_CMD_GETNEXT
! 1197: * SNMP_CMD_WALK
! 1198: * SNMP_CMD_REALWALK
! 1199: */
! 1200: if (zend_parse_parameters(argc TSRMLS_CC, "ssssssss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len,
! 1201: &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &a8, &a8_len, &timeout, &retries) == FAILURE) {
! 1202: return;
! 1203: }
! 1204: }
! 1205:
! 1206: snmp_sess_init(&session);
! 1207: /* This is all SNMPv3 */
! 1208: session.version = SNMP_VERSION_3;
! 1209:
! 1210: /* Reading the hostname and its optional non-default port number */
! 1211: strlcpy(hostname, a1, sizeof(hostname));
! 1212: if ((pptr = strchr(hostname, ':'))) {
! 1213: remote_port = strtol(pptr + 1, NULL, 0);
! 1214: }
! 1215: session.peername = hostname;
! 1216: session.remote_port = remote_port;
! 1217:
! 1218: /* Setting the security name. */
! 1219: if (netsnmp_session_set_sec_name(&session, a2)) {
! 1220: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could net set security name: %s", a2);
! 1221: RETURN_FALSE;
! 1222: }
! 1223:
! 1224: /* Setting the security level. */
! 1225: if (netsnmp_session_set_sec_level(&session, a3 TSRMLS_CC)) {
! 1226: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid security level: %s", a3);
! 1227: RETURN_FALSE;
! 1228: }
! 1229:
! 1230: /* Setting the authentication protocol. */
! 1231: if (netsnmp_session_set_auth_protocol(&session, a4 TSRMLS_CC)) {
! 1232: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid authentication protocol: %s", a4);
! 1233: RETURN_FALSE;
! 1234: }
! 1235:
! 1236: /* Setting the authentication passphrase. */
! 1237: if (netsnmp_session_gen_auth_key(&session, a5 TSRMLS_CC)) {
! 1238: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not generate key for authentication pass phrase: %s", a5);
! 1239: RETURN_FALSE;
! 1240: }
! 1241:
! 1242: /* Setting the security protocol. */
! 1243: if (netsnmp_session_set_sec_protocol(&session, a6 TSRMLS_CC) && a6_len) {
! 1244: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid security protocol: %s", a6);
! 1245: RETURN_FALSE;
! 1246: }
! 1247:
! 1248: /* Setting the security protocol passphrase. */
! 1249: if (netsnmp_session_gen_sec_key(&session, a7 TSRMLS_CC) && a7_len) {
! 1250: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not generate key for security pass phrase: %s", a7);
! 1251: RETURN_FALSE;
! 1252: }
! 1253:
! 1254: if (st == SNMP_CMD_SET) {
! 1255: type = stype[0];
! 1256: }
! 1257:
! 1258: session.retries = retries;
! 1259: session.timeout = timeout;
! 1260:
! 1261: php_snmp_internal(INTERNAL_FUNCTION_PARAM_PASSTHRU, st, &session, a8, type, value);
! 1262: }
! 1263: /* }}} */
! 1264:
! 1265: /* {{{ 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]])
! 1266: Fetch the value of a SNMP object */
! 1267: PHP_FUNCTION(snmp3_get)
! 1268: {
! 1269: php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GET);
! 1270: }
! 1271: /* }}} */
! 1272:
! 1273: /* {{{ 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]])
! 1274: Fetch the value of a SNMP object */
! 1275: PHP_FUNCTION(snmp3_getnext)
! 1276: {
! 1277: php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_GETNEXT);
! 1278: }
! 1279: /* }}} */
! 1280:
! 1281: /* {{{ 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]])
! 1282: Fetch the value of a SNMP object */
! 1283: PHP_FUNCTION(snmp3_walk)
! 1284: {
! 1285: php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_WALK);
! 1286: }
! 1287: /* }}} */
! 1288:
! 1289: /* {{{ 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]])
! 1290: Fetch the value of a SNMP object */
! 1291: PHP_FUNCTION(snmp3_real_walk)
! 1292: {
! 1293: php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_REALWALK);
! 1294: }
! 1295: /* }}} */
! 1296:
! 1297: /* {{{ 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]])
! 1298: Fetch the value of a SNMP object */
! 1299: PHP_FUNCTION(snmp3_set)
! 1300: {
! 1301: php_snmpv3(INTERNAL_FUNCTION_PARAM_PASSTHRU, SNMP_CMD_SET);
! 1302: }
! 1303: /* }}} */
! 1304:
! 1305: /* {{{ proto void snmp_set_valueretrieval(int method)
! 1306: Specify the method how the SNMP values will be returned */
! 1307: PHP_FUNCTION(snmp_set_valueretrieval)
! 1308: {
! 1309: long method;
! 1310:
! 1311: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &method) == FAILURE) {
! 1312: return;
! 1313: }
! 1314:
! 1315: if ((method == SNMP_VALUE_LIBRARY) || (method == SNMP_VALUE_PLAIN) || (method == SNMP_VALUE_OBJECT)) {
! 1316: SNMP_G(valueretrieval) = method;
! 1317: }
! 1318: }
! 1319: /* }}} */
! 1320:
! 1321: /* {{{ proto int snmp_get_valueretrieval()
! 1322: Return the method how the SNMP values will be returned */
! 1323: PHP_FUNCTION(snmp_get_valueretrieval)
! 1324: {
! 1325: RETURN_LONG(SNMP_G(valueretrieval));
! 1326: }
! 1327: /* }}} */
! 1328:
! 1329: /* {{{ proto int snmp_read_mib(string filename)
! 1330: Reads and parses a MIB file into the active MIB tree. */
! 1331: PHP_FUNCTION(snmp_read_mib)
! 1332: {
! 1333: char *filename;
! 1334: int filename_len;
! 1335:
! 1336: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
! 1337: return;
! 1338: }
! 1339:
! 1340: /* Prevent read_mib() from printing any errors. */
! 1341: snmp_disable_stderrlog();
! 1342:
! 1343: if (!read_mib(filename)) {
! 1344: char *error = strerror(errno);
! 1345: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error while reading MIB file '%s': %s", filename, error);
! 1346: RETURN_FALSE;
! 1347: }
! 1348: RETURN_TRUE;
! 1349: }
! 1350: /* }}} */
! 1351:
! 1352: #endif
! 1353:
! 1354: /*
! 1355: * Local variables:
! 1356: * tab-width: 4
! 1357: * c-basic-offset: 4
! 1358: * End:
! 1359: * vim600: sw=4 ts=4 fdm=marker
! 1360: * vim<600: sw=4 ts=4
! 1361: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>