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: 369013 $")
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(ast_channel_name(chan))) {
00276 ast_copy_string(string_ret, ast_channel_name(chan), sizeof(string_ret));
00277 *var_len = strlen(string_ret);
00278 ret = (u_char *)string_ret;
00279 }
00280 break;
00281 case ASTCHANLANGUAGE:
00282 if (!ast_strlen_zero(ast_channel_language(chan))) {
00283 ast_copy_string(string_ret, ast_channel_language(chan), sizeof(string_ret));
00284 *var_len = strlen(string_ret);
00285 ret = (u_char *)string_ret;
00286 }
00287 break;
00288 case ASTCHANTYPE:
00289 ast_copy_string(string_ret, ast_channel_tech(chan)->type, sizeof(string_ret));
00290 *var_len = strlen(string_ret);
00291 ret = (u_char *)string_ret;
00292 break;
00293 case ASTCHANMUSICCLASS:
00294 if (!ast_strlen_zero(ast_channel_musicclass(chan))) {
00295 ast_copy_string(string_ret, ast_channel_musicclass(chan), sizeof(string_ret));
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 ast_copy_string(string_ret, ast_channel_name(bridge), sizeof(string_ret));
00303 *var_len = strlen(string_ret);
00304 ret = (u_char *)string_ret;
00305 }
00306 break;
00307 case ASTCHANMASQ:
00308 if (ast_channel_masq(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masq(chan)))) {
00309 ast_copy_string(string_ret, ast_channel_name(ast_channel_masq(chan)), sizeof(string_ret));
00310 *var_len = strlen(string_ret);
00311 ret = (u_char *)string_ret;
00312 }
00313 break;
00314 case ASTCHANMASQR:
00315 if (ast_channel_masqr(chan) && !ast_strlen_zero(ast_channel_name(ast_channel_masqr(chan)))) {
00316 ast_copy_string(string_ret, ast_channel_name(ast_channel_masqr(chan)), sizeof(string_ret));
00317 *var_len = strlen(string_ret);
00318 ret = (u_char *)string_ret;
00319 }
00320 break;
00321 case ASTCHANWHENHANGUP:
00322 if (!ast_tvzero(*ast_channel_whentohangup(chan))) {
00323 gettimeofday(&tval, NULL);
00324 long_ret = difftime(ast_channel_whentohangup(chan)->tv_sec, tval.tv_sec) * 100 - tval.tv_usec / 10000;
00325 ret= (u_char *)&long_ret;
00326 }
00327 break;
00328 case ASTCHANAPP:
00329 if (ast_channel_appl(chan)) {
00330 ast_copy_string(string_ret, ast_channel_appl(chan), sizeof(string_ret));
00331 *var_len = strlen(string_ret);
00332 ret = (u_char *)string_ret;
00333 }
00334 break;
00335 case ASTCHANDATA:
00336 if (ast_channel_data(chan)) {
00337 ast_copy_string(string_ret, ast_channel_data(chan), sizeof(string_ret));
00338 *var_len = strlen(string_ret);
00339 ret = (u_char *)string_ret;
00340 }
00341 break;
00342 case ASTCHANCONTEXT:
00343 ast_copy_string(string_ret, ast_channel_context(chan), sizeof(string_ret));
00344 *var_len = strlen(string_ret);
00345 ret = (u_char *)string_ret;
00346 break;
00347 case ASTCHANMACROCONTEXT:
00348 ast_copy_string(string_ret, ast_channel_macrocontext(chan), sizeof(string_ret));
00349 *var_len = strlen(string_ret);
00350 ret = (u_char *)string_ret;
00351 break;
00352 case ASTCHANMACROEXTEN:
00353 ast_copy_string(string_ret, ast_channel_macroexten(chan), sizeof(string_ret));
00354 *var_len = strlen(string_ret);
00355 ret = (u_char *)string_ret;
00356 break;
00357 case ASTCHANMACROPRI:
00358 long_ret = ast_channel_macropriority(chan);
00359 ret = (u_char *)&long_ret;
00360 break;
00361 case ASTCHANEXTEN:
00362 ast_copy_string(string_ret, ast_channel_exten(chan), sizeof(string_ret));
00363 *var_len = strlen(string_ret);
00364 ret = (u_char *)string_ret;
00365 break;
00366 case ASTCHANPRI:
00367 long_ret = ast_channel_priority(chan);
00368 ret = (u_char *)&long_ret;
00369 break;
00370 case ASTCHANACCOUNTCODE:
00371 if (!ast_strlen_zero(ast_channel_accountcode(chan))) {
00372 ast_copy_string(string_ret, ast_channel_accountcode(chan), sizeof(string_ret));
00373 *var_len = strlen(string_ret);
00374 ret = (u_char *)string_ret;
00375 }
00376 break;
00377 case ASTCHANFORWARDTO:
00378 if (!ast_strlen_zero(ast_channel_call_forward(chan))) {
00379 ast_copy_string(string_ret, ast_channel_call_forward(chan), sizeof(string_ret));
00380 *var_len = strlen(string_ret);
00381 ret = (u_char *)string_ret;
00382 }
00383 break;
00384 case ASTCHANUNIQUEID:
00385 ast_copy_string(string_ret, ast_channel_uniqueid(chan), sizeof(string_ret));
00386 *var_len = strlen(string_ret);
00387 ret = (u_char *)string_ret;
00388 break;
00389 case ASTCHANCALLGROUP:
00390 long_ret = ast_channel_callgroup(chan);
00391 ret = (u_char *)&long_ret;
00392 break;
00393 case ASTCHANPICKUPGROUP:
00394 long_ret = ast_channel_pickupgroup(chan);
00395 ret = (u_char *)&long_ret;
00396 break;
00397 case ASTCHANSTATE:
00398 long_ret = ast_channel_state(chan) & 0xffff;
00399 ret = (u_char *)&long_ret;
00400 break;
00401 case ASTCHANMUTED:
00402 long_ret = ast_channel_state(chan) & AST_STATE_MUTE ? 1 : 2;
00403 ret = (u_char *)&long_ret;
00404 break;
00405 case ASTCHANRINGS:
00406 long_ret = ast_channel_rings(chan);
00407 ret = (u_char *)&long_ret;
00408 break;
00409 case ASTCHANCIDDNID:
00410 if (ast_channel_dialed(chan)->number.str) {
00411 ast_copy_string(string_ret, ast_channel_dialed(chan)->number.str, sizeof(string_ret));
00412 *var_len = strlen(string_ret);
00413 ret = (u_char *)string_ret;
00414 }
00415 break;
00416 case ASTCHANCIDNUM:
00417 if (ast_channel_caller(chan)->id.number.valid && ast_channel_caller(chan)->id.number.str) {
00418 ast_copy_string(string_ret, ast_channel_caller(chan)->id.number.str, sizeof(string_ret));
00419 *var_len = strlen(string_ret);
00420 ret = (u_char *)string_ret;
00421 }
00422 break;
00423 case ASTCHANCIDNAME:
00424 if (ast_channel_caller(chan)->id.name.valid && ast_channel_caller(chan)->id.name.str) {
00425 ast_copy_string(string_ret, ast_channel_caller(chan)->id.name.str, sizeof(string_ret));
00426 *var_len = strlen(string_ret);
00427 ret = (u_char *)string_ret;
00428 }
00429 break;
00430 case ASTCHANCIDANI:
00431 if (ast_channel_caller(chan)->ani.number.valid && ast_channel_caller(chan)->ani.number.str) {
00432 ast_copy_string(string_ret, ast_channel_caller(chan)->ani.number.str, sizeof(string_ret));
00433 *var_len = strlen(string_ret);
00434 ret = (u_char *)string_ret;
00435 }
00436 break;
00437 case ASTCHANCIDRDNIS:
00438 if (ast_channel_redirecting(chan)->from.number.valid && ast_channel_redirecting(chan)->from.number.str) {
00439 ast_copy_string(string_ret, ast_channel_redirecting(chan)->from.number.str, sizeof(string_ret));
00440 *var_len = strlen(string_ret);
00441 ret = (u_char *)string_ret;
00442 }
00443 break;
00444 case ASTCHANCIDPRES:
00445 long_ret = ast_party_id_presentation(&ast_channel_caller(chan)->id);
00446 ret = (u_char *)&long_ret;
00447 break;
00448 case ASTCHANCIDANI2:
00449 long_ret = ast_channel_caller(chan)->ani2;
00450 ret = (u_char *)&long_ret;
00451 break;
00452 case ASTCHANCIDTON:
00453 long_ret = ast_channel_caller(chan)->id.number.plan;
00454 ret = (u_char *)&long_ret;
00455 break;
00456 case ASTCHANCIDTNS:
00457 long_ret = ast_channel_dialed(chan)->transit_network_select;
00458 ret = (u_char *)&long_ret;
00459 break;
00460 case ASTCHANAMAFLAGS:
00461 long_ret = ast_channel_amaflags(chan);
00462 ret = (u_char *)&long_ret;
00463 break;
00464 case ASTCHANADSI:
00465 long_ret = ast_channel_adsicpe(chan);
00466 ret = (u_char *)&long_ret;
00467 break;
00468 case ASTCHANTONEZONE:
00469 if (ast_channel_zone(chan)) {
00470 ast_copy_string(string_ret, ast_channel_zone(chan)->country, sizeof(string_ret));
00471 *var_len = strlen(string_ret);
00472 ret = (u_char *)string_ret;
00473 }
00474 break;
00475 case ASTCHANHANGUPCAUSE:
00476 long_ret = ast_channel_hangupcause(chan);
00477 ret = (u_char *)&long_ret;
00478 break;
00479 case ASTCHANVARIABLES:
00480 if (pbx_builtin_serialize_variables(chan, &out)) {
00481 *var_len = ast_str_strlen(out);
00482 ret = (u_char *)ast_str_buffer(out);
00483 }
00484 break;
00485 case ASTCHANFLAGS:
00486 bits_ret[0] = 0;
00487 for (bit = 0; bit < 8; bit++)
00488 bits_ret[0] |= ((ast_channel_flags(chan)->flags & (1 << bit)) >> bit) << (7 - bit);
00489 bits_ret[1] = 0;
00490 for (bit = 0; bit < 8; bit++)
00491 bits_ret[1] |= (((ast_channel_flags(chan)->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
00492 *var_len = 2;
00493 ret = bits_ret;
00494 break;
00495 case ASTCHANTRANSFERCAP:
00496 long_ret = ast_channel_transfercapability(chan);
00497 ret = (u_char *)&long_ret;
00498 default:
00499 break;
00500 }
00501
00502 ast_channel_unlock(chan);
00503 chan = ast_channel_unref(chan);
00504
00505 return ret;
00506 }
00507
00508 static u_char *ast_var_channel_types(struct variable *vp, oid *name, size_t *length,
00509 int exact, size_t *var_len, WriteMethod **write_method)
00510 {
00511 static unsigned long long_ret;
00512 struct ast_variable *channel_types, *next;
00513
00514 if (header_generic(vp, name, length, exact, var_len, write_method))
00515 return NULL;
00516
00517 if (vp->magic != ASTCHANTYPECOUNT)
00518 return NULL;
00519
00520 for (long_ret = 0, channel_types = next = ast_channeltype_list(); next; next = next->next)
00521 long_ret++;
00522 ast_variables_destroy(channel_types);
00523
00524 return (u_char *)&long_ret;
00525 }
00526
00527 static u_char *ast_var_channel_types_table(struct variable *vp, oid *name, size_t *length,
00528 int exact, size_t *var_len, WriteMethod **write_method)
00529 {
00530 const struct ast_channel_tech *tech = NULL;
00531 struct ast_variable *channel_types, *next;
00532 static unsigned long long_ret;
00533 struct ast_channel *chan;
00534 u_long i;
00535
00536 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
00537 return NULL;
00538
00539 channel_types = ast_channeltype_list();
00540 for (i = 1, next = channel_types; next && i != name[*length - 1]; next = next->next, i++)
00541 ;
00542 if (next != NULL)
00543 tech = ast_get_channel_tech(next->name);
00544 ast_variables_destroy(channel_types);
00545 if (next == NULL || tech == NULL)
00546 return NULL;
00547
00548 switch (vp->magic) {
00549 case ASTCHANTYPEINDEX:
00550 long_ret = name[*length - 1];
00551 return (u_char *)&long_ret;
00552 case ASTCHANTYPENAME:
00553 *var_len = strlen(tech->type);
00554 return (u_char *)tech->type;
00555 case ASTCHANTYPEDESC:
00556 *var_len = strlen(tech->description);
00557 return (u_char *)tech->description;
00558 case ASTCHANTYPEDEVSTATE:
00559 long_ret = tech->devicestate ? 1 : 2;
00560 return (u_char *)&long_ret;
00561 case ASTCHANTYPEINDICATIONS:
00562 long_ret = tech->indicate ? 1 : 2;
00563 return (u_char *)&long_ret;
00564 case ASTCHANTYPETRANSFER:
00565 long_ret = tech->transfer ? 1 : 2;
00566 return (u_char *)&long_ret;
00567 case ASTCHANTYPECHANNELS:
00568 {
00569 struct ast_channel_iterator *iter;
00570
00571 long_ret = 0;
00572
00573 if (!(iter = ast_channel_iterator_all_new())) {
00574 return NULL;
00575 }
00576
00577 while ((chan = ast_channel_iterator_next(iter))) {
00578 if (ast_channel_tech(chan) == tech) {
00579 long_ret++;
00580 }
00581 chan = ast_channel_unref(chan);
00582 }
00583
00584 ast_channel_iterator_destroy(iter);
00585
00586 return (u_char *)&long_ret;
00587 }
00588 default:
00589 break;
00590 }
00591 return NULL;
00592 }
00593
00594 static u_char *ast_var_channel_bridge(struct variable *vp, oid *name, size_t *length,
00595 int exact, size_t *var_len, WriteMethod **write_method)
00596 {
00597 static unsigned long long_ret;
00598 struct ast_channel *chan = NULL;
00599 struct ast_channel_iterator *iter;
00600
00601 long_ret = 0;
00602
00603 if (header_generic(vp, name, length, exact, var_len, write_method)) {
00604 return NULL;
00605 }
00606
00607 if (!(iter = ast_channel_iterator_all_new())) {
00608 return NULL;
00609 }
00610
00611 while ((chan = ast_channel_iterator_next(iter))) {
00612 ast_channel_lock(chan);
00613 if (ast_bridged_channel(chan)) {
00614 long_ret++;
00615 }
00616 ast_channel_unlock(chan);
00617 chan = ast_channel_unref(chan);
00618 }
00619
00620 ast_channel_iterator_destroy(iter);
00621
00622 *var_len = sizeof(long_ret);
00623
00624 return (vp->magic == ASTCHANBRIDGECOUNT) ? (u_char *) &long_ret : NULL;
00625 }
00626
00627 static u_char *ast_var_Config(struct variable *vp, oid *name, size_t *length,
00628 int exact, size_t *var_len, WriteMethod **write_method)
00629 {
00630 static unsigned long long_ret;
00631 struct timeval tval;
00632
00633 if (header_generic(vp, name, length, exact, var_len, write_method))
00634 return NULL;
00635
00636 switch (vp->magic) {
00637 case ASTCONFUPTIME:
00638 gettimeofday(&tval, NULL);
00639 long_ret = difftime(tval.tv_sec, ast_startuptime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_startuptime.tv_usec / 10000;
00640 return (u_char *)&long_ret;
00641 case ASTCONFRELOADTIME:
00642 gettimeofday(&tval, NULL);
00643 if (ast_lastreloadtime.tv_sec)
00644 long_ret = difftime(tval.tv_sec, ast_lastreloadtime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_lastreloadtime.tv_usec / 10000;
00645 else
00646 long_ret = difftime(tval.tv_sec, ast_startuptime.tv_sec) * 100 + tval.tv_usec / 10000 - ast_startuptime.tv_usec / 10000;
00647 return (u_char *)&long_ret;
00648 case ASTCONFPID:
00649 long_ret = getpid();
00650 return (u_char *)&long_ret;
00651 case ASTCONFSOCKET:
00652 *var_len = strlen(ast_config_AST_SOCKET);
00653 return (u_char *)ast_config_AST_SOCKET;
00654 case ASTCONFACTIVECALLS:
00655 long_ret = ast_active_calls();
00656 return (u_char *)&long_ret;
00657 case ASTCONFPROCESSEDCALLS:
00658 long_ret = ast_processed_calls();
00659 return (u_char *)&long_ret;
00660 default:
00661 break;
00662 }
00663 return NULL;
00664 }
00665
00666 static u_char *ast_var_indications(struct variable *vp, oid *name, size_t *length,
00667 int exact, size_t *var_len, WriteMethod **write_method)
00668 {
00669 static unsigned long long_ret;
00670 static char ret_buf[128];
00671 struct ast_tone_zone *tz = NULL;
00672
00673 if (header_generic(vp, name, length, exact, var_len, write_method))
00674 return NULL;
00675
00676 switch (vp->magic) {
00677 case ASTINDCOUNT:
00678 {
00679 struct ao2_iterator i;
00680
00681 long_ret = 0;
00682
00683 i = ast_tone_zone_iterator_init();
00684 while ((tz = ao2_iterator_next(&i))) {
00685 tz = ast_tone_zone_unref(tz);
00686 long_ret++;
00687 }
00688 ao2_iterator_destroy(&i);
00689
00690 return (u_char *) &long_ret;
00691 }
00692 case ASTINDCURRENT:
00693 tz = ast_get_indication_zone(NULL);
00694 if (tz) {
00695 ast_copy_string(ret_buf, tz->country, sizeof(ret_buf));
00696 *var_len = strlen(ret_buf);
00697 tz = ast_tone_zone_unref(tz);
00698 return (u_char *) ret_buf;
00699 }
00700 *var_len = 0;
00701 return NULL;
00702 default:
00703 break;
00704 }
00705 return NULL;
00706 }
00707
00708 static u_char *ast_var_indications_table(struct variable *vp, oid *name, size_t *length,
00709 int exact, size_t *var_len, WriteMethod **write_method)
00710 {
00711 static unsigned long long_ret;
00712 static char ret_buf[256];
00713 struct ast_tone_zone *tz = NULL;
00714 int i;
00715 struct ao2_iterator iter;
00716
00717 if (header_simple_table(vp, name, length, exact, var_len, write_method, -1)) {
00718 return NULL;
00719 }
00720
00721 i = name[*length - 1] - 1;
00722
00723 iter = ast_tone_zone_iterator_init();
00724
00725 while ((tz = ao2_iterator_next(&iter)) && i) {
00726 tz = ast_tone_zone_unref(tz);
00727 i--;
00728 }
00729 ao2_iterator_destroy(&iter);
00730
00731 if (tz == NULL) {
00732 return NULL;
00733 }
00734
00735 switch (vp->magic) {
00736 case ASTINDINDEX:
00737 ast_tone_zone_unref(tz);
00738 long_ret = name[*length - 1];
00739 return (u_char *)&long_ret;
00740 case ASTINDCOUNTRY:
00741 ast_copy_string(ret_buf, tz->country, sizeof(ret_buf));
00742 ast_tone_zone_unref(tz);
00743 *var_len = strlen(ret_buf);
00744 return (u_char *) ret_buf;
00745 case ASTINDALIAS:
00746
00747 ast_tone_zone_unref(tz);
00748 return NULL;
00749 case ASTINDDESCRIPTION:
00750 ast_tone_zone_lock(tz);
00751 ast_copy_string(ret_buf, tz->description, sizeof(ret_buf));
00752 ast_tone_zone_unlock(tz);
00753 ast_tone_zone_unref(tz);
00754 *var_len = strlen(ret_buf);
00755 return (u_char *) ret_buf;
00756 default:
00757 ast_tone_zone_unref(tz);
00758 break;
00759 }
00760 return NULL;
00761 }
00762
00763 static int countmodule(const char *mod, const char *desc, int use, const char *like)
00764 {
00765 return 1;
00766 }
00767
00768 static u_char *ast_var_Modules(struct variable *vp, oid *name, size_t *length,
00769 int exact, size_t *var_len, WriteMethod **write_method)
00770 {
00771 static unsigned long long_ret;
00772
00773 if (header_generic(vp, name, length, exact, var_len, write_method))
00774 return NULL;
00775
00776 if (vp->magic != ASTMODCOUNT)
00777 return NULL;
00778
00779 long_ret = ast_update_module_list(countmodule, NULL);
00780
00781 return (u_char *)&long_ret;
00782 }
00783
00784 static u_char *ast_var_Version(struct variable *vp, oid *name, size_t *length,
00785 int exact, size_t *var_len, WriteMethod **write_method)
00786 {
00787 static unsigned long long_ret;
00788
00789 if (header_generic(vp, name, length, exact, var_len, write_method))
00790 return NULL;
00791
00792 switch (vp->magic) {
00793 case ASTVERSTRING:
00794 {
00795 const char *version = ast_get_version();
00796 *var_len = strlen(version);
00797 return (u_char *)version;
00798 }
00799 case ASTVERTAG:
00800 sscanf(ast_get_version_num(), "%30lu", &long_ret);
00801 return (u_char *)&long_ret;
00802 default:
00803 break;
00804 }
00805 return NULL;
00806 }
00807
00808 static int term_asterisk_mib(int majorID, int minorID, void *serverarg, void *clientarg)
00809 {
00810 unregister_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid));
00811 return 0;
00812 }
00813
00814 static void init_asterisk_mib(void)
00815 {
00816 static struct variable4 asterisk_vars[] = {
00817 {ASTVERSTRING, ASN_OCTET_STR, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERSTRING}},
00818 {ASTVERTAG, ASN_UNSIGNED, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERTAG}},
00819 {ASTCONFUPTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFUPTIME}},
00820 {ASTCONFRELOADTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFRELOADTIME}},
00821 {ASTCONFPID, ASN_INTEGER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPID}},
00822 {ASTCONFSOCKET, ASN_OCTET_STR, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFSOCKET}},
00823 {ASTCONFACTIVECALLS, ASN_GAUGE, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFACTIVECALLS}},
00824 {ASTCONFPROCESSEDCALLS, ASN_COUNTER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPROCESSEDCALLS}},
00825 {ASTMODCOUNT, ASN_INTEGER, RONLY, ast_var_Modules , 2, {ASTMODULES, ASTMODCOUNT}},
00826 {ASTINDCOUNT, ASN_INTEGER, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCOUNT}},
00827 {ASTINDCURRENT, ASN_OCTET_STR, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCURRENT}},
00828 {ASTINDINDEX, ASN_INTEGER, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDINDEX}},
00829 {ASTINDCOUNTRY, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDCOUNTRY}},
00830 {ASTINDALIAS, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDALIAS}},
00831 {ASTINDDESCRIPTION, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDDESCRIPTION}},
00832 {ASTCHANCOUNT, ASN_GAUGE, RONLY, ast_var_channels, 2, {ASTCHANNELS, ASTCHANCOUNT}},
00833 {ASTCHANINDEX, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANINDEX}},
00834 {ASTCHANNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANNAME}},
00835 {ASTCHANLANGUAGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANLANGUAGE}},
00836 {ASTCHANTYPE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTYPE}},
00837 {ASTCHANMUSICCLASS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUSICCLASS}},
00838 {ASTCHANBRIDGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANBRIDGE}},
00839 {ASTCHANMASQ, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQ}},
00840 {ASTCHANMASQR, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQR}},
00841 {ASTCHANWHENHANGUP, ASN_TIMETICKS, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANWHENHANGUP}},
00842 {ASTCHANAPP, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAPP}},
00843 {ASTCHANDATA, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANDATA}},
00844 {ASTCHANCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCONTEXT}},
00845 {ASTCHANMACROCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROCONTEXT}},
00846 {ASTCHANMACROEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROEXTEN}},
00847 {ASTCHANMACROPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROPRI}},
00848 {ASTCHANEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANEXTEN}},
00849 {ASTCHANPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPRI}},
00850 {ASTCHANACCOUNTCODE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANACCOUNTCODE}},
00851 {ASTCHANFORWARDTO, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFORWARDTO}},
00852 {ASTCHANUNIQUEID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANUNIQUEID}},
00853 {ASTCHANCALLGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCALLGROUP}},
00854 {ASTCHANPICKUPGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPICKUPGROUP}},
00855 {ASTCHANSTATE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANSTATE}},
00856 {ASTCHANMUTED, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUTED}},
00857 {ASTCHANRINGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANRINGS}},
00858 {ASTCHANCIDDNID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDDNID}},
00859 {ASTCHANCIDNUM, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNUM}},
00860 {ASTCHANCIDNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNAME}},
00861 {ASTCHANCIDANI, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI}},
00862 {ASTCHANCIDRDNIS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDRDNIS}},
00863 {ASTCHANCIDPRES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDPRES}},
00864 {ASTCHANCIDANI2, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI2}},
00865 {ASTCHANCIDTON, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTON}},
00866 {ASTCHANCIDTNS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTNS}},
00867 {ASTCHANAMAFLAGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAMAFLAGS}},
00868 {ASTCHANADSI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANADSI}},
00869 {ASTCHANTONEZONE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTONEZONE}},
00870 {ASTCHANHANGUPCAUSE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANHANGUPCAUSE}},
00871 {ASTCHANVARIABLES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANVARIABLES}},
00872 {ASTCHANFLAGS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFLAGS}},
00873 {ASTCHANTRANSFERCAP, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTRANSFERCAP}},
00874 {ASTCHANTYPECOUNT, ASN_INTEGER, RONLY, ast_var_channel_types, 2, {ASTCHANNELS, ASTCHANTYPECOUNT}},
00875 {ASTCHANTYPEINDEX, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDEX}},
00876 {ASTCHANTYPENAME, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPENAME}},
00877 {ASTCHANTYPEDESC, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDESC}},
00878 {ASTCHANTYPEDEVSTATE, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDEVSTATE}},
00879 {ASTCHANTYPEINDICATIONS, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDICATIONS}},
00880 {ASTCHANTYPETRANSFER, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPETRANSFER}},
00881 {ASTCHANTYPECHANNELS, ASN_GAUGE, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPECHANNELS}},
00882 {ASTCHANBRIDGECOUNT, ASN_GAUGE, RONLY, ast_var_channel_bridge, 3, {ASTCHANNELS, ASTCHANSCALARS, ASTCHANBRIDGECOUNT}},
00883 };
00884
00885 register_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid),
00886 "ASTERISK-MIB implementation for Asterisk.");
00887
00888 REGISTER_MIB("res_snmp", asterisk_vars, variable4, asterisk_oid);
00889
00890 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
00891 SNMP_CALLBACK_SHUTDOWN,
00892 term_asterisk_mib, NULL);
00893 }
00894
00895
00896
00897
00898
00899
00900
00901
00902