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