Return to snmp.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / ext / snmp |
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: */