Annotation of embedaddon/php/ext/snmp/snmp.c, revision 1.1.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>