00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "asterisk.h"
00018
00019 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 352955 $")
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #ifdef PACKAGE_NAME
00032 #undef PACKAGE_NAME
00033 #endif
00034 #ifdef PACKAGE_BUGREPORT
00035 #undef PACKAGE_BUGREPORT
00036 #endif
00037 #ifdef PACKAGE_STRING
00038 #undef PACKAGE_STRING
00039 #endif
00040 #ifdef PACKAGE_TARNAME
00041 #undef PACKAGE_TARNAME
00042 #endif
00043 #ifdef PACKAGE_VERSION
00044 #undef PACKAGE_VERSION
00045 #endif
00046 #ifndef HAVE_DMALLOC_H
00047 #define HAVE_DMALLOC_H 0
00048 #endif
00049
00050 #if defined(__OpenBSD__)
00051
00052
00053
00054
00055 #define __NetBSD_Version__ 0
00056 #endif
00057
00058 #include <net-snmp/net-snmp-config.h>
00059 #include <net-snmp/net-snmp-includes.h>
00060 #include <net-snmp/agent/net-snmp-agent-includes.h>
00061
00062 #include "asterisk/paths.h"
00063 #include "asterisk/channel.h"
00064 #include "asterisk/logger.h"
00065 #include "asterisk/options.h"
00066 #include "asterisk/indications.h"
00067 #include "asterisk/ast_version.h"
00068 #include "asterisk/pbx.h"
00069
00070
00071 #define unload_module ast_unload_module
00072 #include "asterisk/module.h"
00073 #undef unload_module
00074
00075 #include "agent.h"
00076
00077
00078 int header_generic(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **);
00079 int header_simple_table(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **, int);
00080 int register_sysORTable(oid *, size_t, const char *);
00081 int unregister_sysORTable(oid *, size_t);
00082
00083
00084 static void init_asterisk_mib(void);
00085
00086
00087
00088
00089 static oid asterisk_oid[] = { 1, 3, 6, 1, 4, 1, 22736, 1 };
00090
00091
00092
00093
00094
00095
00096 #define ASTVERSION 1
00097 #define ASTVERSTRING 1
00098 #define ASTVERTAG 2
00099
00100 #define ASTCONFIGURATION 2
00101 #define ASTCONFUPTIME 1
00102 #define ASTCONFRELOADTIME 2
00103 #define ASTCONFPID 3
00104 #define ASTCONFSOCKET 4
00105 #define ASTCONFACTIVECALLS 5
00106 #define ASTCONFPROCESSEDCALLS 6
00107
00108 #define ASTMODULES 3
00109 #define ASTMODCOUNT 1
00110
00111 #define ASTINDICATIONS 4
00112 #define ASTINDCOUNT 1
00113 #define ASTINDCURRENT 2
00114
00115 #define ASTINDTABLE 3
00116 #define ASTINDINDEX 1
00117 #define ASTINDCOUNTRY 2
00118 #define ASTINDALIAS 3
00119 #define ASTINDDESCRIPTION 4
00120
00121 #define ASTCHANNELS 5
00122 #define ASTCHANCOUNT 1
00123
00124 #define ASTCHANTABLE 2
00125 #define ASTCHANINDEX 1
00126 #define ASTCHANNAME 2
00127 #define ASTCHANLANGUAGE 3
00128 #define ASTCHANTYPE 4
00129 #define ASTCHANMUSICCLASS 5
00130 #define ASTCHANBRIDGE 6
00131 #define ASTCHANMASQ 7
00132 #define ASTCHANMASQR 8
00133 #define ASTCHANWHENHANGUP 9
00134 #define ASTCHANAPP 10
00135 #define ASTCHANDATA 11
00136 #define ASTCHANCONTEXT 12
00137 #define ASTCHANMACROCONTEXT 13
00138 #define ASTCHANMACROEXTEN 14
00139 #define ASTCHANMACROPRI 15
00140 #define ASTCHANEXTEN 16
00141 #define ASTCHANPRI 17
00142 #define ASTCHANACCOUNTCODE 18
00143 #define ASTCHANFORWARDTO 19
00144 #define ASTCHANUNIQUEID 20
00145 #define ASTCHANCALLGROUP 21
00146 #define ASTCHANPICKUPGROUP 22
00147 #define ASTCHANSTATE 23
00148 #define ASTCHANMUTED 24
00149 #define ASTCHANRINGS 25
00150 #define ASTCHANCIDDNID 26
00151 #define ASTCHANCIDNUM 27
00152 #define ASTCHANCIDNAME 28
00153 #define ASTCHANCIDANI 29
00154 #define ASTCHANCIDRDNIS 30
00155 #define ASTCHANCIDPRES 31
00156 #define ASTCHANCIDANI2 32
00157 #define ASTCHANCIDTON 33
00158 #define ASTCHANCIDTNS 34
00159 #define ASTCHANAMAFLAGS 35
00160 #define ASTCHANADSI 36
00161 #define ASTCHANTONEZONE 37
00162 #define ASTCHANHANGUPCAUSE 38
00163 #define ASTCHANVARIABLES 39
00164 #define ASTCHANFLAGS 40
00165 #define ASTCHANTRANSFERCAP 41
00166
00167 #define ASTCHANTYPECOUNT 3
00168
00169 #define ASTCHANTYPETABLE 4
00170 #define ASTCHANTYPEINDEX 1
00171 #define ASTCHANTYPENAME 2
00172 #define ASTCHANTYPEDESC 3
00173 #define ASTCHANTYPEDEVSTATE 4
00174 #define ASTCHANTYPEINDICATIONS 5
00175 #define ASTCHANTYPETRANSFER 6
00176 #define ASTCHANTYPECHANNELS 7
00177
00178 #define ASTCHANSCALARS 5
00179 #define ASTCHANBRIDGECOUNT 1
00180
00181 void *agent_thread(void *arg)
00182 {
00183 ast_verb(2, "Starting %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");
00184
00185 snmp_enable_stderrlog();
00186
00187 if (res_snmp_agentx_subagent)
00188 netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
00189 NETSNMP_DS_AGENT_ROLE,
00190 1);
00191
00192 init_agent("asterisk");
00193
00194 init_asterisk_mib();
00195
00196 init_snmp("asterisk");
00197
00198 if (!res_snmp_agentx_subagent)
00199 init_master_agent();
00200
00201 while (res_snmp_dont_stop)
00202 agent_check_and_process(1);
00203
00204 snmp_shutdown("asterisk");
00205
00206 ast_verb(2, "Terminating %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");
00207
00208 return NULL;
00209 }
00210
00211 static u_char *
00212 ast_var_channels(struct variable *vp, oid *name, size_t *length,
00213 int exact, size_t *var_len, WriteMethod **write_method)
00214 {
00215 static unsigned long long_ret;
00216
00217 if (header_generic(vp, name, length, exact, var_len, write_method))
00218 return NULL;
00219
00220 if (vp->magic != ASTCHANCOUNT)
00221 return NULL;
00222
00223 long_ret = ast_active_channels();
00224
00225 return (u_char *)&long_ret;
00226 }
00227
00228 static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length,
00229 int exact, size_t *var_len, WriteMethod **write_method)
00230 {
00231 static unsigned long long_ret;
00232 static u_char bits_ret[2];
00233 static char string_ret[256];
00234 struct ast_channel *chan, *bridge;
00235 struct timeval tval;
00236 u_char *ret = NULL;
00237 int i, bit;
00238 struct ast_str *out = ast_str_alloca(2048);
00239 struct ast_channel_iterator *iter;
00240
00241 if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels()))
00242 return NULL;
00243
00244 i = name[*length - 1] - 1;
00245
00246 if (!(iter = ast_channel_iterator_all_new())) {
00247 return NULL;
00248 }
00249
00250 while ((chan = ast_channel_iterator_next(iter)) && i) {
00251 ast_channel_unref(chan);
00252 i--;
00253 }
00254
00255 iter = ast_channel_iterator_destroy(iter);
00256
00257 if (chan == NULL) {
00258 return NULL;
00259 }
00260
00261 *var_len = sizeof(long_ret);
00262
00263 ast_channel_lock(chan);
00264
00265 switch (vp->magic) {
00266 case ASTCHANINDEX:
00267 long_ret = name[*length - 1];
00268 ret = (u_char *)&long_ret;
00269 break;
00270 case ASTCHANNAME:
00271 if (!ast_strlen_zero(chan->name)) {
00272 strncpy(string_ret, chan->name, sizeof(string_ret));
00273 string_ret[sizeof(string_ret) - 1] = '\0';
00274 *var_len = strlen(string_ret);
00275 ret = (u_char *)string_ret;
00276 }
00277 break;
00278 case ASTCHANLANGUAGE:
00279 if (!ast_strlen_zero(chan->language)) {
00280 strncpy(string_ret, chan->language, sizeof(string_ret));
00281 string_ret[sizeof(string_ret) - 1] = '\0';
00282 *var_len = strlen(string_ret);
00283 ret = (u_char *)string_ret;
00284 }
00285 break;
00286 case ASTCHANTYPE:
00287 strncpy(string_ret, chan->tech->type, sizeof(string_ret));
00288 string_ret[sizeof(string_ret) - 1] = '\0';
00289 *var_len = strlen(string_ret);
00290 ret = (u_char *)string_ret;
00291 break;
00292 case ASTCHANMUSICCLASS:
00293 if (!ast_strlen_zero(chan->musicclass)) {
00294 strncpy(string_ret, chan->musicclass, sizeof(string_ret));
00295 string_ret[sizeof(string_ret) - 1] = '\0';
00296 *var_len = strlen(string_ret);
00297 ret = (u_char *)string_ret;
00298 }
00299 break;
00300 case ASTCHANBRIDGE:
00301 if ((bridge = ast_bridged_channel(chan)) != NULL) {
00302 strncpy(string_ret, bridge->name, sizeof(string_ret));
00303 string_ret[sizeof(string_ret) - 1] = '\0';
00304 *var_len = strlen(string_ret);
00305 ret = (u_char *)string_ret;
00306 }
00307 break;
00308 case ASTCHANMASQ:
00309 if (chan->masq && !ast_strlen_zero(chan->masq->name)) {
00310 strncpy(string_ret, chan->masq->name, sizeof(string_ret));
00311 string_ret[sizeof(string_ret) - 1] = '\0';
00312 *var_len = strlen(string_ret);
00313 ret = (u_char *)string_ret;
00314 }
00315 break;
00316 case ASTCHANMASQR:
00317 if (chan->masqr && !ast_strlen_zero(chan->masqr->name)) {
00318 strncpy(string_ret, chan->masqr->name, sizeof(string_ret));
00319 string_ret[sizeof(string_ret) - 1] = '\0';
00320 *var_len = strlen(string_ret);
00321 ret = (u_char *)string_ret;
00322 }
00323 break;
00324 case ASTCHANWHENHANGUP:
00325 if (!ast_tvzero(chan->whentohangup)) {
00326 gettimeofday(&tval, NULL);
00327 long_ret = difftime(chan->whentohangup.tv_sec, tval.tv_sec) * 100 - tval.tv_usec / 10000;
00328 ret= (u_char *)&long_ret;
00329 }
00330 break;
00331 case ASTCHANAPP:
00332 if (chan->appl) {
00333 strncpy(string_ret, chan->appl, sizeof(string_ret));
00334 string_ret[sizeof(string_ret) - 1] = '\0';
00335 *var_len = strlen(string_ret);
00336 ret = (u_char *)string_ret;
00337 }
00338 break;
00339 case ASTCHANDATA:
00340 if (chan->data) {
00341 strncpy(string_ret, chan->data, sizeof(string_ret));
00342 string_ret[sizeof(string_ret) - 1] = '\0';
00343 *var_len = strlen(string_ret);
00344 ret = (u_char *)string_ret;
00345 }
00346 break;
00347 case ASTCHANCONTEXT:
00348 strncpy(string_ret, chan->context, sizeof(string_ret));
00349 string_ret[sizeof(string_ret) - 1] = '\0';
00350 *var_len = strlen(string_ret);
00351 ret = (u_char *)string_ret;
00352 break;
00353 case ASTCHANMACROCONTEXT:
00354 strncpy(string_ret, chan->macrocontext, sizeof(string_ret));
00355 string_ret[sizeof(string_ret) - 1] = '\0';
00356 *var_len = strlen(string_ret);
00357 ret = (u_char *)string_ret;
00358 break;
00359 case ASTCHANMACROEXTEN:
00360 strncpy(string_ret, chan->macroexten, sizeof(string_ret));
00361 string_ret[sizeof(string_ret) - 1] = '\0';
00362 *var_len = strlen(string_ret);
00363 ret = (u_char *)string_ret;
00364 break;
00365 case ASTCHANMACROPRI:
00366 long_ret = chan->macropriority;
00367 ret = (u_char *)&long_ret;
00368 break;
00369 case ASTCHANEXTEN:
00370 strncpy(string_ret, chan->exten, sizeof(string_ret));
00371 string_ret[sizeof(string_ret) - 1] = '\0';
00372 *var_len = strlen(string_ret);
00373 ret = (u_char *)string_ret;
00374 break;
00375 case ASTCHANPRI:
00376 long_ret = chan->priority;
00377 ret = (u_char *)&long_ret;
00378 break;
00379 case ASTCHANACCOUNTCODE:
00380 if (!ast_strlen_zero(chan->accountcode)) {
00381 strncpy(string_ret, chan->accountcode, sizeof(string_ret));
00382 string_ret[sizeof(string_ret) - 1] = '\0';
00383 *var_len = strlen(string_ret);
00384 ret = (u_char *)string_ret;
00385 }
00386 break;
00387 case ASTCHANFORWARDTO:
00388 if (!ast_strlen_zero(chan->call_forward)) {
00389 strncpy(string_ret, chan->call_forward, sizeof(string_ret));
00390 string_ret[sizeof(string_ret) - 1] = '\0';
00391 *var_len = strlen(string_ret);
00392 ret = (u_char *)string_ret;
00393 }
00394 break;
00395 case ASTCHANUNIQUEID:
00396 strncpy(string_ret, chan->uniqueid, sizeof(string_ret));
00397 string_ret[sizeof(string_ret) - 1] = '\0';
00398 *var_len = strlen(string_ret);
00399 ret = (u_char *)string_ret;
00400 break;
00401 case ASTCHANCALLGROUP:
00402 long_ret = chan->callgroup;
00403 ret = (u_char *)&long_ret;
00404 break;
00405 case ASTCHANPICKUPGROUP:
00406 long_ret = chan->pickupgroup;
00407 ret = (u_char *)&long_ret;
00408 break;
00409 case ASTCHANSTATE:
00410 long_ret = chan->_state & 0xffff;
00411 ret = (u_char *)&long_ret;
00412 break;
00413 case ASTCHANMUTED:
00414 long_ret = chan->_state & AST_STATE_MUTE ? 1 : 2;
00415 ret = (u_char *)&long_ret;
00416 break;
00417 case ASTCHANRINGS:
00418 long_ret = chan->rings;
00419 ret = (u_char *)&long_ret;
00420 break;
00421 case ASTCHANCIDDNID:
00422 if (chan->dialed.number.str) {
00423 strncpy(string_ret, chan->dialed.number.str, sizeof(string_ret));
00424 string_ret[sizeof(string_ret) - 1] = '\0';
00425 *var_len = strlen(string_ret);
00426 ret = (u_char *)string_ret;
00427 }
00428 break;
00429 case ASTCHANCIDNUM:
00430 if (chan->caller.id.number.valid && chan->caller.id.number.str) {
00431 strncpy(string_ret, chan->caller.id.number.str, sizeof(string_ret));
00432 string_ret[sizeof(string_ret) - 1] = '\0';
00433 *var_len = strlen(string_ret);
00434 ret = (u_char *)string_ret;
00435 }
00436 break;
00437 case ASTCHANCIDNAME:
00438 if (chan->caller.id.name.valid && chan->caller.id.name.str) {
00439 strncpy(string_ret, chan->caller.id.name.str, sizeof(string_ret));
00440 string_ret[sizeof(string_ret) - 1] = '\0';
00441 *var_len = strlen(string_ret);
00442 ret = (u_char *)string_ret;
00443 }
00444 break;
00445 case ASTCHANCIDANI:
00446 if (chan->caller.ani.number.valid && chan->caller.ani.number.str) {
00447 strncpy(string_ret, chan->caller.ani.number.str, sizeof(string_ret));
00448 string_ret[sizeof(string_ret) - 1] = '\0';
00449 *var_len = strlen(string_ret);
00450 ret = (u_char *)string_ret;
00451 }
00452 break;
00453 case ASTCHANCIDRDNIS:
00454 if (chan->redirecting.from.number.valid && chan->redirecting.from.number.str) {
00455 strncpy(string_ret, chan->redirecting.from.number.str, sizeof(string_ret));
00456 string_ret[sizeof(string_ret) - 1] = '\0';
00457 *var_len = strlen(string_ret);
00458 ret = (u_char *)string_ret;
00459 }
00460 break;
00461 case ASTCHANCIDPRES:
00462 long_ret = ast_party_id_presentation(&chan->caller.id);
00463 ret = (u_char *)&long_ret;
00464 break;
00465 case ASTCHANCIDANI2:
00466 long_ret = chan->caller.ani2;
00467 ret = (u_char *)&long_ret;
00468 break;
00469 case ASTCHANCIDTON:
00470 long_ret = chan->caller.id.number.plan;
00471 ret = (u_char *)&long_ret;
00472 break;
00473 case ASTCHANCIDTNS:
00474 long_ret = chan->dialed.transit_network_select;
00475 ret = (u_char *)&long_ret;
00476 break;
00477 case ASTCHANAMAFLAGS:
00478 long_ret = chan->amaflags;
00479 ret = (u_char *)&long_ret;
00480 break;
00481 case ASTCHANADSI:
00482 long_ret = chan->adsicpe;
00483 ret = (u_char *)&long_ret;
00484 break;
00485 case ASTCHANTONEZONE:
00486 if (chan->zone) {
00487 strncpy(string_ret, chan->zone->country, sizeof(string_ret));
00488 string_ret[sizeof(string_ret) - 1] = '\0';
00489 *var_len = strlen(string_ret);
00490 ret = (u_char *)string_ret;
00491 }
00492 break;
00493 case ASTCHANHANGUPCAUSE:
00494 long_ret = chan->hangupcause;
00495 ret = (u_char *)&long_ret;
00496 break;
00497 case ASTCHANVARIABLES:
00498 if (pbx_builtin_serialize_variables(chan, &out)) {
00499 *var_len = ast_str_strlen(out);
00500 ret = (u_char *)ast_str_buffer(out);
00501 }
00502 break;
00503 case ASTCHANFLAGS:
00504 bits_ret[0] = 0;
00505 for (bit = 0; bit < 8; bit++)
00506 bits_ret[0] |= ((chan->flags & (1 << bit)) >> bit) << (7 - bit);
00507 bits_ret[1] = 0;
00508 for (bit = 0; bit < 8; bit++)
00509 bits_ret[1] |= (((chan->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
00510 *var_len = 2;
00511 ret = bits_ret;
00512 break;
00513 case ASTCHANTRANSFERCAP:
00514 long_ret = chan->transfercapability;
00515 ret = (u_char *)&long_ret;
00516 default:
00517 break;
00518 }
00519
00520 ast_channel_unlock(chan);
00521 chan = ast_channel_unref(chan);
00522
00523 return ret;
00524 }
00525
00526 static u_char *ast_var_channel_types(struct variable *vp, oid *name, size_t *length,
00527 int exact, size_t *var_len, WriteMethod **write_method)
00528 {
00529 static unsigned long long_ret;
00530 struct ast_variable *channel_types, *next;
00531
00532 if (header_generic(vp, name, length, exact, var_len, write_method))
00533 return NULL;
00534
00535 if (vp->magic != ASTCHANTYPECOUNT)
00536 return NULL;
00537
00538 for (long_ret = 0, channel_types = next = ast_channeltype_list(); next; next = next->next)
00539 long_ret++;
00540 ast_variables_destroy(channel_types);
00541
00542 return (u_char *)&long_ret;
00543 }
00544
00545 static u_char *ast_var_channel_types_table(struct variable *vp, oid *name, size_t *length,
00546 int exact, size_t *var_len, WriteMethod **write_method)
00547 {
00548 const struct ast_channel_tech *tech = NULL;
00549 struct ast_variable *channel_types, *next;
00550 static unsigned long long_ret;
00551 struct ast_channel *chan;
00552 u_long i;
00553
00554 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
00555 return NULL;
00556
00557 channel_types = ast_channeltype_list();
00558 for (i = 1, next = channel_types; next && i != name[*length - 1]; next = next->next, i++)
00559 ;
00560 if (next != NULL)
00561 tech = ast_get_channel_tech(next->name);
00562 ast_variables_destroy(channel_types);
00563 if (next == NULL || tech == NULL)
00564 return NULL;
00565
00566 switch (vp->magic) {
00567 case ASTCHANTYPEINDEX:
00568 long_ret = name[*length - 1];
00569 return (u_char *)&long_ret;
00570 case ASTCHANTYPENAME:
00571 *var_len = strlen(tech->type);
00572 return (u_char *)tech->type;
00573 case ASTCHANTYPEDESC:
00574 *var_len = strlen(tech->description);
00575 return (u_char *)tech->description;
00576 case ASTCHANTYPEDEVSTATE:
00577 long_ret = tech->devicestate ? 1 : 2;
00578 return (u_char *)&long_ret;
00579 case ASTCHANTYPEINDICATIONS:
00580 long_ret = tech->indicate ? 1 : 2;
00581 return (u_char *)&long_ret;
00582 case ASTCHANTYPETRANSFER:
00583 long_ret = tech->transfer ? 1 : 2;
00584 return (u_char *)&long_ret;
00585 case ASTCHANTYPECHANNELS:
00586 {
00587 struct ast_channel_iterator *iter;
00588
00589 long_ret = 0;
00590
00591 if (!(iter = ast_channel_iterator_all_new())) {
00592 return NULL;
00593 }
00594
00595 while ((chan = ast_channel_iterator_next(iter))) {
00596 if (chan->tech == tech) {
00597 long_ret++;
00598 }
00599 chan = ast_channel_unref(chan);
00600 }
00601
00602 ast_channel_iterator_destroy(iter);
00603
00604 return (u_char *)&long_ret;
00605 }
00606 default:
00607 break;
00608 }
00609 return NULL;
00610 }
00611
00612 static u_char *ast_var_channel_bridge(struct variable *vp, oid *name, size_t *length,
00613 int exact, size_t *var_len, WriteMethod **write_method)
00614 {
00615 static unsigned long long_ret;
00616 struct ast_channel *chan = NULL;
00617 struct ast_channel_iterator *iter;
00618
00619 long_ret = 0;
00620
00621 if (header_generic(vp, name, length, exact, var_len, write_method)) {
00622 return NULL;
00623 }
00624
00625 if (!(iter = ast_channel_iterator_all_new())) {
00626 return NULL;
00627 }
00628
00629 while ((chan = ast_channel_iterator_next(iter))) {
00630 ast_channel_lock(chan);
00631 if (ast_bridged_channel(chan)) {
00632 long_ret++;
00633 }
00634 ast_channel_unlock(chan);
00635 chan = ast_channel_unref(chan);
00636 }
00637
00638 ast_channel_iterator_destroy(iter);
00639
00640 *var_len = sizeof(long_ret);
00641
00642 return (vp->magic == ASTCHANBRIDGECOUNT) ? (u_char *) &long_ret : NULL;
00643 }
00644
00645 static u_char *ast_var_Config(struct variable *vp, oid *name, size_t *length,
00646 int exact, size_t *var_len, WriteMethod **write_method)
00647 {
00648 static unsigned long long_ret;
00649 struct timeval tval;
00650
00651 if (header_generic(vp, name, length, exact, var_len, write_method))
00652 return NULL;
00653
00654 switch (vp->magic) {
00655 case ASTCONFUPTIME:
00656 gettimeofday(&tval, NULL);
00657 long_ret = difftime(tval.tv_sec, ast_startuptime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_startuptime.tv_usec / 10000;
00658 return (u_char *)&long_ret;
00659 case ASTCONFRELOADTIME:
00660 gettimeofday(&tval, NULL);
00661 if (ast_lastreloadtime.tv_sec)
00662 long_ret = difftime(tval.tv_sec, ast_lastreloadtime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_lastreloadtime.tv_usec / 10000;
00663 else
00664 long_ret = difftime(tval.tv_sec, ast_startuptime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_startuptime.tv_usec / 10000;
00665 return (u_char *)&long_ret;
00666 case ASTCONFPID:
00667 long_ret = getpid();
00668 return (u_char *)&long_ret;
00669 case ASTCONFSOCKET:
00670 *var_len = strlen(ast_config_AST_SOCKET);
00671 return (u_char *)ast_config_AST_SOCKET;
00672 case ASTCONFACTIVECALLS:
00673 long_ret = ast_active_calls();
00674 return (u_char *)&long_ret;
00675 case ASTCONFPROCESSEDCALLS:
00676 long_ret = ast_processed_calls();
00677 return (u_char *)&long_ret;
00678 default:
00679 break;
00680 }
00681 return NULL;
00682 }
00683
00684 static u_char *ast_var_indications(struct variable *vp, oid *name, size_t *length,
00685 int exact, size_t *var_len, WriteMethod **write_method)
00686 {
00687 static unsigned long long_ret;
00688 static char ret_buf[128];
00689 struct ast_tone_zone *tz = NULL;
00690
00691 if (header_generic(vp, name, length, exact, var_len, write_method))
00692 return NULL;
00693
00694 switch (vp->magic) {
00695 case ASTINDCOUNT:
00696 {
00697 struct ao2_iterator i;
00698
00699 long_ret = 0;
00700
00701 i = ast_tone_zone_iterator_init();
00702 while ((tz = ao2_iterator_next(&i))) {
00703 tz = ast_tone_zone_unref(tz);
00704 long_ret++;
00705 }
00706 ao2_iterator_destroy(&i);
00707
00708 return (u_char *) &long_ret;
00709 }
00710 case ASTINDCURRENT:
00711 tz = ast_get_indication_zone(NULL);
00712 if (tz) {
00713 ast_copy_string(ret_buf, tz->country, sizeof(ret_buf));
00714 *var_len = strlen(ret_buf);
00715 tz = ast_tone_zone_unref(tz);
00716 return (u_char *) ret_buf;
00717 }
00718 *var_len = 0;
00719 return NULL;
00720 default:
00721 break;
00722 }
00723 return NULL;
00724 }
00725
00726 static u_char *ast_var_indications_table(struct variable *vp, oid *name, size_t *length,
00727 int exact, size_t *var_len, WriteMethod **write_method)
00728 {
00729 static unsigned long long_ret;
00730 static char ret_buf[256];
00731 struct ast_tone_zone *tz = NULL;
00732 int i;
00733 struct ao2_iterator iter;
00734
00735 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1)) {
00736 return NULL;
00737 }
00738
00739 i = name[*length - 1] - 1;
00740
00741 iter = ast_tone_zone_iterator_init();
00742
00743 while ((tz = ao2_iterator_next(&iter)) && i) {
00744 tz = ast_tone_zone_unref(tz);
00745 i--;
00746 }
00747 ao2_iterator_destroy(&iter);
00748
00749 if (tz == NULL) {
00750 return NULL;
00751 }
00752
00753 switch (vp->magic) {
00754 case ASTINDINDEX:
00755 ast_tone_zone_unref(tz);
00756 long_ret = name[*length - 1];
00757 return (u_char *)&long_ret;
00758 case ASTINDCOUNTRY:
00759 ast_copy_string(ret_buf, tz->country, sizeof(ret_buf));
00760 ast_tone_zone_unref(tz);
00761 *var_len = strlen(ret_buf);
00762 return (u_char *) ret_buf;
00763 case ASTINDALIAS:
00764
00765 ast_tone_zone_unref(tz);
00766 return NULL;
00767 case ASTINDDESCRIPTION:
00768 ast_tone_zone_lock(tz);
00769 ast_copy_string(ret_buf, tz->description, sizeof(ret_buf));
00770 ast_tone_zone_unlock(tz);
00771 ast_tone_zone_unref(tz);
00772 *var_len = strlen(ret_buf);
00773 return (u_char *) ret_buf;
00774 default:
00775 ast_tone_zone_unref(tz);
00776 break;
00777 }
00778 return NULL;
00779 }
00780
00781 static int countmodule(const char *mod, const char *desc, int use, const char *like)
00782 {
00783 return 1;
00784 }
00785
00786 static u_char *ast_var_Modules(struct variable *vp, oid *name, size_t *length,
00787 int exact, size_t *var_len, WriteMethod **write_method)
00788 {
00789 static unsigned long long_ret;
00790
00791 if (header_generic(vp, name, length, exact, var_len, write_method))
00792 return NULL;
00793
00794 if (vp->magic != ASTMODCOUNT)
00795 return NULL;
00796
00797 long_ret = ast_update_module_list(countmodule, NULL);
00798
00799 return (u_char *)&long_ret;
00800 }
00801
00802 static u_char *ast_var_Version(struct variable *vp, oid *name, size_t *length,
00803 int exact, size_t *var_len, WriteMethod **write_method)
00804 {
00805 static unsigned long long_ret;
00806
00807 if (header_generic(vp, name, length, exact, var_len, write_method))
00808 return NULL;
00809
00810 switch (vp->magic) {
00811 case ASTVERSTRING:
00812 {
00813 const char *version = ast_get_version();
00814 *var_len = strlen(version);
00815 return (u_char *)version;
00816 }
00817 case ASTVERTAG:
00818 sscanf(ast_get_version_num(), "%30lu", &long_ret);
00819 return (u_char *)&long_ret;
00820 default:
00821 break;
00822 }
00823 return NULL;
00824 }
00825
00826 static int term_asterisk_mib(int majorID, int minorID, void *serverarg, void *clientarg)
00827 {
00828 unregister_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid));
00829 return 0;
00830 }
00831
00832 static void init_asterisk_mib(void)
00833 {
00834 static struct variable4 asterisk_vars[] = {
00835 {ASTVERSTRING, ASN_OCTET_STR, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERSTRING}},
00836 {ASTVERTAG, ASN_UNSIGNED, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERTAG}},
00837 {ASTCONFUPTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFUPTIME}},
00838 {ASTCONFRELOADTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFRELOADTIME}},
00839 {ASTCONFPID, ASN_INTEGER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPID}},
00840 {ASTCONFSOCKET, ASN_OCTET_STR, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFSOCKET}},
00841 {ASTCONFACTIVECALLS, ASN_GAUGE, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFACTIVECALLS}},
00842 {ASTCONFPROCESSEDCALLS, ASN_COUNTER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPROCESSEDCALLS}},
00843 {ASTMODCOUNT, ASN_INTEGER, RONLY, ast_var_Modules , 2, {ASTMODULES, ASTMODCOUNT}},
00844 {ASTINDCOUNT, ASN_INTEGER, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCOUNT}},
00845 {ASTINDCURRENT, ASN_OCTET_STR, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCURRENT}},
00846 {ASTINDINDEX, ASN_INTEGER, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDINDEX}},
00847 {ASTINDCOUNTRY, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDCOUNTRY}},
00848 {ASTINDALIAS, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDALIAS}},
00849 {ASTINDDESCRIPTION, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDDESCRIPTION}},
00850 {ASTCHANCOUNT, ASN_GAUGE, RONLY, ast_var_channels, 2, {ASTCHANNELS, ASTCHANCOUNT}},
00851 {ASTCHANINDEX, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANINDEX}},
00852 {ASTCHANNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANNAME}},
00853 {ASTCHANLANGUAGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANLANGUAGE}},
00854 {ASTCHANTYPE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTYPE}},
00855 {ASTCHANMUSICCLASS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUSICCLASS}},
00856 {ASTCHANBRIDGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANBRIDGE}},
00857 {ASTCHANMASQ, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQ}},
00858 {ASTCHANMASQR, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQR}},
00859 {ASTCHANWHENHANGUP, ASN_TIMETICKS, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANWHENHANGUP}},
00860 {ASTCHANAPP, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAPP}},
00861 {ASTCHANDATA, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANDATA}},
00862 {ASTCHANCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCONTEXT}},
00863 {ASTCHANMACROCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROCONTEXT}},
00864 {ASTCHANMACROEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROEXTEN}},
00865 {ASTCHANMACROPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROPRI}},
00866 {ASTCHANEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANEXTEN}},
00867 {ASTCHANPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPRI}},
00868 {ASTCHANACCOUNTCODE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANACCOUNTCODE}},
00869 {ASTCHANFORWARDTO, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFORWARDTO}},
00870 {ASTCHANUNIQUEID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANUNIQUEID}},
00871 {ASTCHANCALLGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCALLGROUP}},
00872 {ASTCHANPICKUPGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPICKUPGROUP}},
00873 {ASTCHANSTATE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANSTATE}},
00874 {ASTCHANMUTED, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUTED}},
00875 {ASTCHANRINGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANRINGS}},
00876 {ASTCHANCIDDNID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDDNID}},
00877 {ASTCHANCIDNUM, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNUM}},
00878 {ASTCHANCIDNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNAME}},
00879 {ASTCHANCIDANI, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI}},
00880 {ASTCHANCIDRDNIS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDRDNIS}},
00881 {ASTCHANCIDPRES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDPRES}},
00882 {ASTCHANCIDANI2, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI2}},
00883 {ASTCHANCIDTON, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTON}},
00884 {ASTCHANCIDTNS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTNS}},
00885 {ASTCHANAMAFLAGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAMAFLAGS}},
00886 {ASTCHANADSI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANADSI}},
00887 {ASTCHANTONEZONE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTONEZONE}},
00888 {ASTCHANHANGUPCAUSE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANHANGUPCAUSE}},
00889 {ASTCHANVARIABLES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANVARIABLES}},
00890 {ASTCHANFLAGS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFLAGS}},
00891 {ASTCHANTRANSFERCAP, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTRANSFERCAP}},
00892 {ASTCHANTYPECOUNT, ASN_INTEGER, RONLY, ast_var_channel_types, 2, {ASTCHANNELS, ASTCHANTYPECOUNT}},
00893 {ASTCHANTYPEINDEX, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDEX}},
00894 {ASTCHANTYPENAME, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPENAME}},
00895 {ASTCHANTYPEDESC, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDESC}},
00896 {ASTCHANTYPEDEVSTATE, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDEVSTATE}},
00897 {ASTCHANTYPEINDICATIONS, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDICATIONS}},
00898 {ASTCHANTYPETRANSFER, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPETRANSFER}},
00899 {ASTCHANTYPECHANNELS, ASN_GAUGE, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPECHANNELS}},
00900 {ASTCHANBRIDGECOUNT, ASN_GAUGE, RONLY, ast_var_channel_bridge, 3, {ASTCHANNELS, ASTCHANSCALARS, ASTCHANBRIDGECOUNT}},
00901 };
00902
00903 register_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid),
00904 "ASTERISK-MIB implementation for Asterisk.");
00905
00906 REGISTER_MIB("res_snmp", asterisk_vars, variable4, asterisk_oid);
00907
00908 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
00909 SNMP_CALLBACK_SHUTDOWN,
00910 term_asterisk_mib, NULL);
00911 }
00912
00913
00914
00915
00916
00917
00918
00919
00920