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