Merged revisions 140169 via svnmerge from
[asterisk-bristuff.git] / res / snmp / agent.c
blobc0eda9fe4b22120d27897d934d196d75ad1f2ec0
1 /*
2 * Copyright (C) 2006 Voop as
3 * Thorsten Lockert <tholo@voop.as>
5 * This program is free software, distributed under the terms of
6 * the GNU General Public License Version 2. See the LICENSE file
7 * at the top of the source tree.
8 */
10 /*! \file
12 * \brief SNMP Agent / SubAgent support for Asterisk
14 * \author Thorsten Lockert <tholo@voop.as>
17 #include "asterisk.h"
19 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
22 * There is some collision collision between netsmp and asterisk names,
23 * causing build under AST_DEVMODE to fail.
25 * The following PACKAGE_* macros are one place.
26 * Also netsnmp has an improper check for HAVE_DMALLOC_H, using
27 * #if HAVE_DMALLOC_H instead of #ifdef HAVE_DMALLOC_H
28 * As a countermeasure we define it to 0, however this will fail
29 * when the proper check is implemented.
31 #ifdef PACKAGE_NAME
32 #undef PACKAGE_NAME
33 #endif
34 #ifdef PACKAGE_BUGREPORT
35 #undef PACKAGE_BUGREPORT
36 #endif
37 #ifdef PACKAGE_STRING
38 #undef PACKAGE_STRING
39 #endif
40 #ifdef PACKAGE_TARNAME
41 #undef PACKAGE_TARNAME
42 #endif
43 #ifdef PACKAGE_VERSION
44 #undef PACKAGE_VERSION
45 #endif
46 #ifndef HAVE_DMALLOC_H
47 #define HAVE_DMALLOC_H 0 /* XXX we shouldn't do this */
48 #endif
50 #include <net-snmp/net-snmp-config.h>
51 #include <net-snmp/net-snmp-includes.h>
52 #include <net-snmp/agent/net-snmp-agent-includes.h>
54 #include "asterisk/paths.h" /* need ast_config_AST_SOCKET */
55 #include "asterisk/channel.h"
56 #include "asterisk/logger.h"
57 #include "asterisk/options.h"
58 #include "asterisk/indications.h"
59 #include "asterisk/ast_version.h"
60 #include "asterisk/pbx.h"
62 /* Colission between Net-SNMP and Asterisk */
63 #define unload_module ast_unload_module
64 #include "asterisk/module.h"
65 #undef unload_module
67 #include "agent.h"
69 /* Helper functions in Net-SNMP, header file not installed by default */
70 int header_generic(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **);
71 int header_simple_table(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **, int);
72 int register_sysORTable(oid *, size_t, const char *);
73 int unregister_sysORTable(oid *, size_t);
75 /* Forward declaration */
76 static void init_asterisk_mib(void);
79 * Anchor for all the Asterisk MIB values
81 static oid asterisk_oid[] = { 1, 3, 6, 1, 4, 1, 22736, 1 };
84 * MIB values -- these correspond to values in the Asterisk MIB,
85 * and MUST be kept in sync with the MIB for things to work as
86 * expected.
88 #define ASTVERSION 1
89 #define ASTVERSTRING 1
90 #define ASTVERTAG 2
92 #define ASTCONFIGURATION 2
93 #define ASTCONFUPTIME 1
94 #define ASTCONFRELOADTIME 2
95 #define ASTCONFPID 3
96 #define ASTCONFSOCKET 4
97 #define ASTCONFACTIVECALLS 5
98 #define ASTCONFPROCESSEDCALLS 6
100 #define ASTMODULES 3
101 #define ASTMODCOUNT 1
103 #define ASTINDICATIONS 4
104 #define ASTINDCOUNT 1
105 #define ASTINDCURRENT 2
107 #define ASTINDTABLE 3
108 #define ASTINDINDEX 1
109 #define ASTINDCOUNTRY 2
110 #define ASTINDALIAS 3
111 #define ASTINDDESCRIPTION 4
113 #define ASTCHANNELS 5
114 #define ASTCHANCOUNT 1
116 #define ASTCHANTABLE 2
117 #define ASTCHANINDEX 1
118 #define ASTCHANNAME 2
119 #define ASTCHANLANGUAGE 3
120 #define ASTCHANTYPE 4
121 #define ASTCHANMUSICCLASS 5
122 #define ASTCHANBRIDGE 6
123 #define ASTCHANMASQ 7
124 #define ASTCHANMASQR 8
125 #define ASTCHANWHENHANGUP 9
126 #define ASTCHANAPP 10
127 #define ASTCHANDATA 11
128 #define ASTCHANCONTEXT 12
129 #define ASTCHANMACROCONTEXT 13
130 #define ASTCHANMACROEXTEN 14
131 #define ASTCHANMACROPRI 15
132 #define ASTCHANEXTEN 16
133 #define ASTCHANPRI 17
134 #define ASTCHANACCOUNTCODE 18
135 #define ASTCHANFORWARDTO 19
136 #define ASTCHANUNIQUEID 20
137 #define ASTCHANCALLGROUP 21
138 #define ASTCHANPICKUPGROUP 22
139 #define ASTCHANSTATE 23
140 #define ASTCHANMUTED 24
141 #define ASTCHANRINGS 25
142 #define ASTCHANCIDDNID 26
143 #define ASTCHANCIDNUM 27
144 #define ASTCHANCIDNAME 28
145 #define ASTCHANCIDANI 29
146 #define ASTCHANCIDRDNIS 30
147 #define ASTCHANCIDPRES 31
148 #define ASTCHANCIDANI2 32
149 #define ASTCHANCIDTON 33
150 #define ASTCHANCIDTNS 34
151 #define ASTCHANAMAFLAGS 35
152 #define ASTCHANADSI 36
153 #define ASTCHANTONEZONE 37
154 #define ASTCHANHANGUPCAUSE 38
155 #define ASTCHANVARIABLES 39
156 #define ASTCHANFLAGS 40
157 #define ASTCHANTRANSFERCAP 41
159 #define ASTCHANTYPECOUNT 3
161 #define ASTCHANTYPETABLE 4
162 #define ASTCHANTYPEINDEX 1
163 #define ASTCHANTYPENAME 2
164 #define ASTCHANTYPEDESC 3
165 #define ASTCHANTYPEDEVSTATE 4
166 #define ASTCHANTYPEINDICATIONS 5
167 #define ASTCHANTYPETRANSFER 6
168 #define ASTCHANTYPECHANNELS 7
170 #define ASTCHANSCALARS 5
171 #define ASTCHANBRIDGECOUNT 1
173 void *agent_thread(void *arg)
175 ast_verb(2, "Starting %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");
177 snmp_enable_stderrlog();
179 if (res_snmp_agentx_subagent)
180 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
181 NETSNMP_DS_AGENT_ROLE,
184 init_agent("asterisk");
186 init_asterisk_mib();
188 init_snmp("asterisk");
190 if (!res_snmp_agentx_subagent)
191 init_master_agent();
193 while (res_snmp_dont_stop)
194 agent_check_and_process(1);
196 snmp_shutdown("asterisk");
198 ast_verb(2, "Terminating %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");
200 return NULL;
203 static u_char *
204 ast_var_channels(struct variable *vp, oid *name, size_t *length,
205 int exact, size_t *var_len, WriteMethod **write_method)
207 static unsigned long long_ret;
209 if (header_generic(vp, name, length, exact, var_len, write_method))
210 return NULL;
212 if (vp->magic != ASTCHANCOUNT)
213 return NULL;
215 long_ret = ast_active_channels();
217 return (u_char *)&long_ret;
220 static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length,
221 int exact, size_t *var_len, WriteMethod **write_method)
223 static unsigned long long_ret;
224 static u_char bits_ret[2];
225 static char string_ret[256];
226 struct ast_channel *chan, *bridge;
227 struct timeval tval;
228 u_char *ret = NULL;
229 int i, bit;
230 struct ast_str *out = ast_str_alloca(2048);
232 if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels()))
233 return NULL;
235 i = name[*length - 1] - 1;
236 for (chan = ast_channel_walk_locked(NULL);
237 chan && i;
238 chan = ast_channel_walk_locked(chan), i--)
239 ast_channel_unlock(chan);
240 if (chan == NULL)
241 return NULL;
242 *var_len = sizeof(long_ret);
244 switch (vp->magic) {
245 case ASTCHANINDEX:
246 long_ret = name[*length - 1];
247 ret = (u_char *)&long_ret;
248 break;
249 case ASTCHANNAME:
250 if (!ast_strlen_zero(chan->name)) {
251 strncpy(string_ret, chan->name, sizeof(string_ret));
252 string_ret[sizeof(string_ret) - 1] = '\0';
253 *var_len = strlen(string_ret);
254 ret = (u_char *)string_ret;
256 break;
257 case ASTCHANLANGUAGE:
258 if (!ast_strlen_zero(chan->language)) {
259 strncpy(string_ret, chan->language, sizeof(string_ret));
260 string_ret[sizeof(string_ret) - 1] = '\0';
261 *var_len = strlen(string_ret);
262 ret = (u_char *)string_ret;
264 break;
265 case ASTCHANTYPE:
266 strncpy(string_ret, chan->tech->type, sizeof(string_ret));
267 string_ret[sizeof(string_ret) - 1] = '\0';
268 *var_len = strlen(string_ret);
269 ret = (u_char *)string_ret;
270 break;
271 case ASTCHANMUSICCLASS:
272 if (!ast_strlen_zero(chan->musicclass)) {
273 strncpy(string_ret, chan->musicclass, sizeof(string_ret));
274 string_ret[sizeof(string_ret) - 1] = '\0';
275 *var_len = strlen(string_ret);
276 ret = (u_char *)string_ret;
278 break;
279 case ASTCHANBRIDGE:
280 if ((bridge = ast_bridged_channel(chan)) != NULL) {
281 strncpy(string_ret, bridge->name, sizeof(string_ret));
282 string_ret[sizeof(string_ret) - 1] = '\0';
283 *var_len = strlen(string_ret);
284 ret = (u_char *)string_ret;
286 break;
287 case ASTCHANMASQ:
288 if (chan->masq && !ast_strlen_zero(chan->masq->name)) {
289 strncpy(string_ret, chan->masq->name, sizeof(string_ret));
290 string_ret[sizeof(string_ret) - 1] = '\0';
291 *var_len = strlen(string_ret);
292 ret = (u_char *)string_ret;
294 break;
295 case ASTCHANMASQR:
296 if (chan->masqr && !ast_strlen_zero(chan->masqr->name)) {
297 strncpy(string_ret, chan->masqr->name, sizeof(string_ret));
298 string_ret[sizeof(string_ret) - 1] = '\0';
299 *var_len = strlen(string_ret);
300 ret = (u_char *)string_ret;
302 break;
303 case ASTCHANWHENHANGUP:
304 if (!ast_tvzero(chan->whentohangup)) {
305 gettimeofday(&tval, NULL);
306 long_ret = difftime(chan->whentohangup.tv_sec, tval.tv_sec) * 100 - tval.tv_usec / 10000;
307 ret= (u_char *)&long_ret;
309 break;
310 case ASTCHANAPP:
311 if (chan->appl) {
312 strncpy(string_ret, chan->appl, sizeof(string_ret));
313 string_ret[sizeof(string_ret) - 1] = '\0';
314 *var_len = strlen(string_ret);
315 ret = (u_char *)string_ret;
317 break;
318 case ASTCHANDATA:
319 if (chan->data) {
320 strncpy(string_ret, chan->data, sizeof(string_ret));
321 string_ret[sizeof(string_ret) - 1] = '\0';
322 *var_len = strlen(string_ret);
323 ret = (u_char *)string_ret;
325 break;
326 case ASTCHANCONTEXT:
327 strncpy(string_ret, chan->context, sizeof(string_ret));
328 string_ret[sizeof(string_ret) - 1] = '\0';
329 *var_len = strlen(string_ret);
330 ret = (u_char *)string_ret;
331 break;
332 case ASTCHANMACROCONTEXT:
333 strncpy(string_ret, chan->macrocontext, sizeof(string_ret));
334 string_ret[sizeof(string_ret) - 1] = '\0';
335 *var_len = strlen(string_ret);
336 ret = (u_char *)string_ret;
337 break;
338 case ASTCHANMACROEXTEN:
339 strncpy(string_ret, chan->macroexten, sizeof(string_ret));
340 string_ret[sizeof(string_ret) - 1] = '\0';
341 *var_len = strlen(string_ret);
342 ret = (u_char *)string_ret;
343 break;
344 case ASTCHANMACROPRI:
345 long_ret = chan->macropriority;
346 ret = (u_char *)&long_ret;
347 break;
348 case ASTCHANEXTEN:
349 strncpy(string_ret, chan->exten, sizeof(string_ret));
350 string_ret[sizeof(string_ret) - 1] = '\0';
351 *var_len = strlen(string_ret);
352 ret = (u_char *)string_ret;
353 break;
354 case ASTCHANPRI:
355 long_ret = chan->priority;
356 ret = (u_char *)&long_ret;
357 break;
358 case ASTCHANACCOUNTCODE:
359 if (!ast_strlen_zero(chan->accountcode)) {
360 strncpy(string_ret, chan->accountcode, sizeof(string_ret));
361 string_ret[sizeof(string_ret) - 1] = '\0';
362 *var_len = strlen(string_ret);
363 ret = (u_char *)string_ret;
365 break;
366 case ASTCHANFORWARDTO:
367 if (!ast_strlen_zero(chan->call_forward)) {
368 strncpy(string_ret, chan->call_forward, sizeof(string_ret));
369 string_ret[sizeof(string_ret) - 1] = '\0';
370 *var_len = strlen(string_ret);
371 ret = (u_char *)string_ret;
373 break;
374 case ASTCHANUNIQUEID:
375 strncpy(string_ret, chan->uniqueid, sizeof(string_ret));
376 string_ret[sizeof(string_ret) - 1] = '\0';
377 *var_len = strlen(string_ret);
378 ret = (u_char *)string_ret;
379 break;
380 case ASTCHANCALLGROUP:
381 long_ret = chan->callgroup;
382 ret = (u_char *)&long_ret;
383 break;
384 case ASTCHANPICKUPGROUP:
385 long_ret = chan->pickupgroup;
386 ret = (u_char *)&long_ret;
387 break;
388 case ASTCHANSTATE:
389 long_ret = chan->_state & 0xffff;
390 ret = (u_char *)&long_ret;
391 break;
392 case ASTCHANMUTED:
393 long_ret = chan->_state & AST_STATE_MUTE ? 1 : 2;
394 ret = (u_char *)&long_ret;
395 break;
396 case ASTCHANRINGS:
397 long_ret = chan->rings;
398 ret = (u_char *)&long_ret;
399 break;
400 case ASTCHANCIDDNID:
401 if (chan->cid.cid_dnid) {
402 strncpy(string_ret, chan->cid.cid_dnid, sizeof(string_ret));
403 string_ret[sizeof(string_ret) - 1] = '\0';
404 *var_len = strlen(string_ret);
405 ret = (u_char *)string_ret;
407 break;
408 case ASTCHANCIDNUM:
409 if (chan->cid.cid_num) {
410 strncpy(string_ret, chan->cid.cid_num, sizeof(string_ret));
411 string_ret[sizeof(string_ret) - 1] = '\0';
412 *var_len = strlen(string_ret);
413 ret = (u_char *)string_ret;
415 break;
416 case ASTCHANCIDNAME:
417 if (chan->cid.cid_name) {
418 strncpy(string_ret, chan->cid.cid_name, sizeof(string_ret));
419 string_ret[sizeof(string_ret) - 1] = '\0';
420 *var_len = strlen(string_ret);
421 ret = (u_char *)string_ret;
423 break;
424 case ASTCHANCIDANI:
425 if (chan->cid.cid_ani) {
426 strncpy(string_ret, chan->cid.cid_ani, sizeof(string_ret));
427 string_ret[sizeof(string_ret) - 1] = '\0';
428 *var_len = strlen(string_ret);
429 ret = (u_char *)string_ret;
431 break;
432 case ASTCHANCIDRDNIS:
433 if (chan->cid.cid_rdnis) {
434 strncpy(string_ret, chan->cid.cid_rdnis, sizeof(string_ret));
435 string_ret[sizeof(string_ret) - 1] = '\0';
436 *var_len = strlen(string_ret);
437 ret = (u_char *)string_ret;
439 break;
440 case ASTCHANCIDPRES:
441 long_ret = chan->cid.cid_pres;
442 ret = (u_char *)&long_ret;
443 break;
444 case ASTCHANCIDANI2:
445 long_ret = chan->cid.cid_ani2;
446 ret = (u_char *)&long_ret;
447 break;
448 case ASTCHANCIDTON:
449 long_ret = chan->cid.cid_ton;
450 ret = (u_char *)&long_ret;
451 break;
452 case ASTCHANCIDTNS:
453 long_ret = chan->cid.cid_tns;
454 ret = (u_char *)&long_ret;
455 break;
456 case ASTCHANAMAFLAGS:
457 long_ret = chan->amaflags;
458 ret = (u_char *)&long_ret;
459 break;
460 case ASTCHANADSI:
461 long_ret = chan->adsicpe;
462 ret = (u_char *)&long_ret;
463 break;
464 case ASTCHANTONEZONE:
465 if (chan->zone) {
466 strncpy(string_ret, chan->zone->country, sizeof(string_ret));
467 string_ret[sizeof(string_ret) - 1] = '\0';
468 *var_len = strlen(string_ret);
469 ret = (u_char *)string_ret;
471 break;
472 case ASTCHANHANGUPCAUSE:
473 long_ret = chan->hangupcause;
474 ret = (u_char *)&long_ret;
475 break;
476 case ASTCHANVARIABLES:
477 if (pbx_builtin_serialize_variables(chan, &out)) {
478 *var_len = strlen(out->str);
479 ret = (u_char *)out->str;
481 break;
482 case ASTCHANFLAGS:
483 bits_ret[0] = 0;
484 for (bit = 0; bit < 8; bit++)
485 bits_ret[0] |= ((chan->flags & (1 << bit)) >> bit) << (7 - bit);
486 bits_ret[1] = 0;
487 for (bit = 0; bit < 8; bit++)
488 bits_ret[1] |= (((chan->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
489 *var_len = 2;
490 ret = bits_ret;
491 break;
492 case ASTCHANTRANSFERCAP:
493 long_ret = chan->transfercapability;
494 ret = (u_char *)&long_ret;
495 default:
496 break;
498 ast_channel_unlock(chan);
499 return ret;
502 static u_char *ast_var_channel_types(struct variable *vp, oid *name, size_t *length,
503 int exact, size_t *var_len, WriteMethod **write_method)
505 static unsigned long long_ret;
506 struct ast_variable *channel_types, *next;
508 if (header_generic(vp, name, length, exact, var_len, write_method))
509 return NULL;
511 if (vp->magic != ASTCHANTYPECOUNT)
512 return NULL;
514 for (long_ret = 0, channel_types = next = ast_channeltype_list(); next; next = next->next)
515 long_ret++;
516 ast_variables_destroy(channel_types);
518 return (u_char *)&long_ret;
521 static u_char *ast_var_channel_types_table(struct variable *vp, oid *name, size_t *length,
522 int exact, size_t *var_len, WriteMethod **write_method)
524 const struct ast_channel_tech *tech = NULL;
525 struct ast_variable *channel_types, *next;
526 static unsigned long long_ret;
527 struct ast_channel *chan;
528 u_long i;
530 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
531 return NULL;
533 channel_types = ast_channeltype_list();
534 for (i = 1, next = channel_types; next && i != name[*length - 1]; next = next->next, i++)
536 if (next != NULL)
537 tech = ast_get_channel_tech(next->name);
538 ast_variables_destroy(channel_types);
539 if (next == NULL || tech == NULL)
540 return NULL;
542 switch (vp->magic) {
543 case ASTCHANTYPEINDEX:
544 long_ret = name[*length - 1];
545 return (u_char *)&long_ret;
546 case ASTCHANTYPENAME:
547 *var_len = strlen(tech->type);
548 return (u_char *)tech->type;
549 case ASTCHANTYPEDESC:
550 *var_len = strlen(tech->description);
551 return (u_char *)tech->description;
552 case ASTCHANTYPEDEVSTATE:
553 long_ret = tech->devicestate ? 1 : 2;
554 return (u_char *)&long_ret;
555 case ASTCHANTYPEINDICATIONS:
556 long_ret = tech->indicate ? 1 : 2;
557 return (u_char *)&long_ret;
558 case ASTCHANTYPETRANSFER:
559 long_ret = tech->transfer ? 1 : 2;
560 return (u_char *)&long_ret;
561 case ASTCHANTYPECHANNELS:
562 long_ret = 0;
563 for (chan = ast_channel_walk_locked(NULL); chan; chan = ast_channel_walk_locked(chan)) {
564 ast_channel_unlock(chan);
565 if (chan->tech == tech)
566 long_ret++;
568 return (u_char *)&long_ret;
569 default:
570 break;
572 return NULL;
575 static u_char *ast_var_channel_bridge(struct variable *vp, oid *name, size_t *length,
576 int exact, size_t *var_len, WriteMethod **write_method)
578 static unsigned long long_ret;
579 struct ast_channel *chan = NULL;
581 long_ret = 0;
582 if (header_generic(vp, name, length, exact, var_len, write_method))
583 return NULL;
585 while ((chan = ast_channel_walk_locked(chan))) {
586 if (ast_bridged_channel(chan))
587 long_ret++;
588 ast_channel_unlock(chan);
591 *var_len = sizeof(long_ret);
593 return (vp->magic == ASTCHANBRIDGECOUNT) ? (u_char *) &long_ret : NULL;
596 static u_char *ast_var_Config(struct variable *vp, oid *name, size_t *length,
597 int exact, size_t *var_len, WriteMethod **write_method)
599 static unsigned long long_ret;
600 struct timeval tval;
602 if (header_generic(vp, name, length, exact, var_len, write_method))
603 return NULL;
605 switch (vp->magic) {
606 case ASTCONFUPTIME:
607 gettimeofday(&tval, NULL);
608 long_ret = difftime(tval.tv_sec, ast_startuptime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_startuptime.tv_usec / 10000;
609 return (u_char *)&long_ret;
610 case ASTCONFRELOADTIME:
611 gettimeofday(&tval, NULL);
612 if (ast_lastreloadtime.tv_sec)
613 long_ret = difftime(tval.tv_sec, ast_lastreloadtime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_lastreloadtime.tv_usec / 10000;
614 else
615 long_ret = difftime(tval.tv_sec, ast_startuptime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_startuptime.tv_usec / 10000;
616 return (u_char *)&long_ret;
617 case ASTCONFPID:
618 long_ret = getpid();
619 return (u_char *)&long_ret;
620 case ASTCONFSOCKET:
621 *var_len = strlen(ast_config_AST_SOCKET);
622 return (u_char *)ast_config_AST_SOCKET;
623 case ASTCONFACTIVECALLS:
624 long_ret = ast_active_calls();
625 return (u_char *)&long_ret;
626 case ASTCONFPROCESSEDCALLS:
627 long_ret = ast_processed_calls();
628 return (u_char *)&long_ret;
629 default:
630 break;
632 return NULL;
635 static u_char *ast_var_indications(struct variable *vp, oid *name, size_t *length,
636 int exact, size_t *var_len, WriteMethod **write_method)
638 static unsigned long long_ret;
639 struct ind_tone_zone *tz = NULL;
641 if (header_generic(vp, name, length, exact, var_len, write_method))
642 return NULL;
644 switch (vp->magic) {
645 case ASTINDCOUNT:
646 long_ret = 0;
647 while ( (tz = ast_walk_indications(tz)) )
648 long_ret++;
650 return (u_char *)&long_ret;
651 case ASTINDCURRENT:
652 tz = ast_get_indication_zone(NULL);
653 if (tz) {
654 *var_len = strlen(tz->country);
655 return (u_char *)tz->country;
657 *var_len = 0;
658 return NULL;
659 default:
660 break;
662 return NULL;
665 static u_char *ast_var_indications_table(struct variable *vp, oid *name, size_t *length,
666 int exact, size_t *var_len, WriteMethod **write_method)
668 static unsigned long long_ret;
669 struct ind_tone_zone *tz = NULL;
670 int i;
672 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
673 return NULL;
675 i = name[*length - 1] - 1;
676 while ( (tz = ast_walk_indications(tz)) && i )
677 i--;
678 if (tz == NULL)
679 return NULL;
681 switch (vp->magic) {
682 case ASTINDINDEX:
683 long_ret = name[*length - 1];
684 return (u_char *)&long_ret;
685 case ASTINDCOUNTRY:
686 *var_len = strlen(tz->country);
687 return (u_char *)tz->country;
688 case ASTINDALIAS:
689 if (tz->alias) {
690 *var_len = strlen(tz->alias);
691 return (u_char *)tz->alias;
693 return NULL;
694 case ASTINDDESCRIPTION:
695 *var_len = strlen(tz->description);
696 return (u_char *)tz->description;
697 default:
698 break;
700 return NULL;
703 static int countmodule(const char *mod, const char *desc, int use, const char *like)
705 return 1;
708 static u_char *ast_var_Modules(struct variable *vp, oid *name, size_t *length,
709 int exact, size_t *var_len, WriteMethod **write_method)
711 static unsigned long long_ret;
713 if (header_generic(vp, name, length, exact, var_len, write_method))
714 return NULL;
716 if (vp->magic != ASTMODCOUNT)
717 return NULL;
719 long_ret = ast_update_module_list(countmodule, NULL);
721 return (u_char *)&long_ret;
724 static u_char *ast_var_Version(struct variable *vp, oid *name, size_t *length,
725 int exact, size_t *var_len, WriteMethod **write_method)
727 static unsigned long long_ret;
729 if (header_generic(vp, name, length, exact, var_len, write_method))
730 return NULL;
732 switch (vp->magic) {
733 case ASTVERSTRING:
735 const char *version = ast_get_version();
736 *var_len = strlen(version);
737 return (u_char *)version;
739 case ASTVERTAG:
740 sscanf(ast_get_version_num(), "%lu", &long_ret);
741 return (u_char *)&long_ret;
742 default:
743 break;
745 return NULL;
748 static int term_asterisk_mib(int majorID, int minorID, void *serverarg, void *clientarg)
750 unregister_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid));
751 return 0;
754 static void init_asterisk_mib(void)
756 static struct variable4 asterisk_vars[] = {
757 {ASTVERSTRING, ASN_OCTET_STR, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERSTRING}},
758 {ASTVERTAG, ASN_UNSIGNED, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERTAG}},
759 {ASTCONFUPTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFUPTIME}},
760 {ASTCONFRELOADTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFRELOADTIME}},
761 {ASTCONFPID, ASN_INTEGER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPID}},
762 {ASTCONFSOCKET, ASN_OCTET_STR, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFSOCKET}},
763 {ASTCONFACTIVECALLS, ASN_GAUGE, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFACTIVECALLS}},
764 {ASTCONFPROCESSEDCALLS, ASN_COUNTER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPROCESSEDCALLS}},
765 {ASTMODCOUNT, ASN_INTEGER, RONLY, ast_var_Modules , 2, {ASTMODULES, ASTMODCOUNT}},
766 {ASTINDCOUNT, ASN_INTEGER, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCOUNT}},
767 {ASTINDCURRENT, ASN_OCTET_STR, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCURRENT}},
768 {ASTINDINDEX, ASN_INTEGER, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDINDEX}},
769 {ASTINDCOUNTRY, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDCOUNTRY}},
770 {ASTINDALIAS, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDALIAS}},
771 {ASTINDDESCRIPTION, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDDESCRIPTION}},
772 {ASTCHANCOUNT, ASN_GAUGE, RONLY, ast_var_channels, 2, {ASTCHANNELS, ASTCHANCOUNT}},
773 {ASTCHANINDEX, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANINDEX}},
774 {ASTCHANNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANNAME}},
775 {ASTCHANLANGUAGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANLANGUAGE}},
776 {ASTCHANTYPE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTYPE}},
777 {ASTCHANMUSICCLASS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUSICCLASS}},
778 {ASTCHANBRIDGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANBRIDGE}},
779 {ASTCHANMASQ, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQ}},
780 {ASTCHANMASQR, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQR}},
781 {ASTCHANWHENHANGUP, ASN_TIMETICKS, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANWHENHANGUP}},
782 {ASTCHANAPP, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAPP}},
783 {ASTCHANDATA, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANDATA}},
784 {ASTCHANCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCONTEXT}},
785 {ASTCHANMACROCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROCONTEXT}},
786 {ASTCHANMACROEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROEXTEN}},
787 {ASTCHANMACROPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROPRI}},
788 {ASTCHANEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANEXTEN}},
789 {ASTCHANPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPRI}},
790 {ASTCHANACCOUNTCODE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANACCOUNTCODE}},
791 {ASTCHANFORWARDTO, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFORWARDTO}},
792 {ASTCHANUNIQUEID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANUNIQUEID}},
793 {ASTCHANCALLGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCALLGROUP}},
794 {ASTCHANPICKUPGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPICKUPGROUP}},
795 {ASTCHANSTATE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANSTATE}},
796 {ASTCHANMUTED, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUTED}},
797 {ASTCHANRINGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANRINGS}},
798 {ASTCHANCIDDNID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDDNID}},
799 {ASTCHANCIDNUM, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNUM}},
800 {ASTCHANCIDNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNAME}},
801 {ASTCHANCIDANI, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI}},
802 {ASTCHANCIDRDNIS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDRDNIS}},
803 {ASTCHANCIDPRES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDPRES}},
804 {ASTCHANCIDANI2, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI2}},
805 {ASTCHANCIDTON, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTON}},
806 {ASTCHANCIDTNS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTNS}},
807 {ASTCHANAMAFLAGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAMAFLAGS}},
808 {ASTCHANADSI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANADSI}},
809 {ASTCHANTONEZONE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTONEZONE}},
810 {ASTCHANHANGUPCAUSE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANHANGUPCAUSE}},
811 {ASTCHANVARIABLES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANVARIABLES}},
812 {ASTCHANFLAGS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFLAGS}},
813 {ASTCHANTRANSFERCAP, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTRANSFERCAP}},
814 {ASTCHANTYPECOUNT, ASN_INTEGER, RONLY, ast_var_channel_types, 2, {ASTCHANNELS, ASTCHANTYPECOUNT}},
815 {ASTCHANTYPEINDEX, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDEX}},
816 {ASTCHANTYPENAME, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPENAME}},
817 {ASTCHANTYPEDESC, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDESC}},
818 {ASTCHANTYPEDEVSTATE, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDEVSTATE}},
819 {ASTCHANTYPEINDICATIONS, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDICATIONS}},
820 {ASTCHANTYPETRANSFER, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPETRANSFER}},
821 {ASTCHANTYPECHANNELS, ASN_GAUGE, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPECHANNELS}},
822 {ASTCHANBRIDGECOUNT, ASN_GAUGE, RONLY, ast_var_channel_bridge, 3, {ASTCHANNELS, ASTCHANSCALARS, ASTCHANBRIDGECOUNT}},
825 register_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid),
826 "ASTERISK-MIB implementation for Asterisk.");
828 REGISTER_MIB("res_snmp", asterisk_vars, variable4, asterisk_oid);
830 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
831 SNMP_CALLBACK_SHUTDOWN,
832 term_asterisk_mib, NULL);
836 * Local Variables:
837 * c-basic-offset: 4
838 * c-file-offsets: ((case-label . 0))
839 * tab-width: 4
840 * indent-tabs-mode: t
841 * End: