aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2006-02-26 20:46:11 +0000
committermarkster <markster@f38db490-d61c-443f-a65b-d21fe96a405b>2006-02-26 20:46:11 +0000
commit9dc45031753b6c466b322dd105af10a156c11eaa (patch)
treedc11dea95379b474e67d6e7b12cff34e6154e4e4
parent181407f0739de8cfd78f71645cbc49f5063996c2 (diff)
Add SNMP support (bug #6439)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@11193 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--configs/res_snmp.conf.sample10
-rw-r--r--doc/asterisk-mib.txt717
-rw-r--r--doc/digium-mib.txt17
-rw-r--r--doc/snmp.txt36
-rw-r--r--res/Makefile8
-rw-r--r--res/res_snmp.c148
-rw-r--r--res/snmp/agent.c845
-rw-r--r--res/snmp/agent.h40
8 files changed, 1821 insertions, 0 deletions
diff --git a/configs/res_snmp.conf.sample b/configs/res_snmp.conf.sample
new file mode 100644
index 000000000..5ca09d576
--- /dev/null
+++ b/configs/res_snmp.conf.sample
@@ -0,0 +1,10 @@
+;
+; Configuration file for res_snmp
+;
+
+[general]
+; We run as a subagent per default -- to run as a full agent
+; we must run as root (to be able to bind to port 161)
+;subagent = yes
+; SNMP must be explicitly enabled to be active
+;enabled = yes
diff --git a/doc/asterisk-mib.txt b/doc/asterisk-mib.txt
new file mode 100644
index 000000000..f4d6656f9
--- /dev/null
+++ b/doc/asterisk-mib.txt
@@ -0,0 +1,717 @@
+ASTERISK-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ OBJECT-TYPE, MODULE-IDENTITY, Integer32, Counter32, TimeTicks
+ FROM SNMPv2-SMI
+
+ TEXTUAL-CONVENTION, DisplayString, TruthValue
+ FROM SNMPv2-TC
+
+ digium
+ FROM DIGIUM-MIB;
+
+asterisk MODULE-IDENTITY
+ LAST-UPDATED "200602041900Z"
+ ORGANIZATION "Digium, Inc."
+ CONTACT-INFO
+ "Mark Spencer
+ Email: markster@digium.com"
+ DESCRIPTION
+ "Asterisk is an Open Source PBX. This MIB defined
+ objects for managing Asterisk instances."
+ ::= { digium 1 }
+
+asteriskVersion OBJECT IDENTIFIER ::= { asterisk 1 }
+asteriskConfiguration OBJECT IDENTIFIER ::= { asterisk 2 }
+asteriskModules OBJECT IDENTIFIER ::= { asterisk 3 }
+asteriskIndications OBJECT IDENTIFIER ::= { asterisk 4 }
+asteriskChannels OBJECT IDENTIFIER ::= { asterisk 5 }
+
+-- asteriskVersion
+
+astVersionString OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Text version string of the version of Asterisk that
+ the SNMP Agent was compiled to run against."
+ ::= { asteriskVersion 1 }
+
+astVersionTag OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "SubVersion revision of the version of Asterisk that
+ the SNMP Agent was compiled to run against -- this is
+ typically 0 for release-versions of Asterisk."
+ ::= { asteriskVersion 2 }
+
+-- asteriskConfiguration
+
+astConfigUpTime OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Time ticks since Asterisk was started."
+ ::= { asteriskConfiguration 1 }
+
+astConfigReloadTime OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Time ticks since Asterisk was last reloaded."
+ ::= { asteriskConfiguration 2 }
+
+astConfigPid OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The process id of the running Asterisk process."
+ ::= { asteriskConfiguration 3 }
+
+astConfigSocket OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "The control socket for giving Asterisk commands."
+ ::= { asteriskConfiguration 4 }
+
+-- asteriskModules
+
+astNumModules OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of modules currently loaded into Asterisk."
+ ::= { asteriskModules 1 }
+
+-- asteriskIndications
+
+astNumIndications OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of indications currently defined in Asterisk."
+ ::= { asteriskIndications 1 }
+
+astCurrentIndication OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Default indication zone to use."
+ ::= { asteriskIndications 2 }
+
+astIndicationsTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF AstIndicationsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Table with all the indication zones currently know to
+ the running Asterisk instance."
+ ::= { asteriskIndications 3 }
+
+astIndicationsEntry OBJECT-TYPE
+ SYNTAX AstIndicationsEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Information about a single indication zone."
+ INDEX { astIndIndex }
+ ::= { astIndicationsTable 1 }
+
+AstIndicationsEntry ::= SEQUENCE {
+ astIndIndex Integer32,
+ astIndCountry DisplayString,
+ astIndAlias DisplayString,
+ astIndDescription DisplayString
+}
+
+astIndIndex OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Numerical index into the table of indication zones."
+ ::= { astIndicationsEntry 1 }
+
+astIndCountry OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Country for which the indication zone is valid,
+ typically this is the ISO 2-letter code of the country."
+ ::= { astIndicationsEntry 2 }
+
+astIndAlias OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ ""
+ ::= { astIndicationsEntry 3 }
+
+astIndDescription OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Description of the indication zone, usually the full
+ name of the country it is valid for."
+ ::= { astIndicationsEntry 4 }
+
+-- asteriskChannels
+
+astNumChannels OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current number of active channels."
+ ::= { asteriskChannels 1 }
+
+astChanTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF AstChanEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Table with details of the currently active channels
+ in the Asterisk instance."
+ ::= { asteriskChannels 2 }
+
+astChanEntry OBJECT-TYPE
+ SYNTAX AstChanEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Details of a single channel."
+ INDEX { astChanIndex }
+ ::= { astChanTable 1 }
+
+AstChanEntry ::= SEQUENCE {
+ astChanIndex Integer32,
+ astChanName DisplayString,
+ astChanLanguage DisplayString,
+ astChanType DisplayString,
+ astChanMusicClass DisplayString,
+ astChanBridge DisplayString,
+ astChanMasq DisplayString,
+ astChanMasqr DisplayString,
+ astChanWhenHangup TimeTicks,
+ astChanApp DisplayString,
+ astChanData DisplayString,
+ astChanContext DisplayString,
+ astChanMacroContext DisplayString,
+ astChanMacroExten DisplayString,
+ astChanMacroPri Integer32,
+ astChanExten DisplayString,
+ astChanPri Integer32,
+ astChanAccountCode DisplayString,
+ astChanForwardTo DisplayString,
+ astChanUniqueId DisplayString,
+ astChanCallGroup Unsigned32,
+ astChanPickupGroup Unsigned32,
+ astChanState INTEGER,
+ astChanMuted TruthValue,
+ astChanRings Integer32,
+ astChanCidDNID DisplayString,
+ astChanCidNum DisplayString,
+ astChanCidName DisplayString,
+ astChanCidANI DisplayString,
+ astChanCidRDNIS DisplayString,
+ astChanCidPresentation DisplayString,
+ astChanCidANI2 Integer32,
+ astChanCidTON Integer32,
+ astChanCidTNS Integer32,
+ astChanAMAFlags INTEGER,
+ astChanADSI INTEGER,
+ astChanToneZone DisplayString,
+ astChanHangupCause INTEGER,
+ astChanVariables DisplayString,
+ astChanFlags BITS,
+ astChanTransferCap INTEGER
+}
+
+astChanIndex OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index into the channel table."
+ ::= { astChanEntry 1 }
+
+astChanName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Name of the currentl channel."
+ ::= { astChanEntry 2 }
+
+astChanLanguage OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Which language the current channel is configured to
+ use -- used mainly for prompts."
+ ::= { astChanEntry 3 }
+
+astChanType OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Underlying technology for the current channel."
+ ::= { astChanEntry 4 }
+
+astChanMusicClass OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Music class to be used for Music on Hold for this
+ channel."
+ ::= { astChanEntry 5 }
+
+astChanBridge OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Which channel this channel is currently bridged (in a
+ conversation) with."
+ ::= { astChanEntry 6 }
+
+astChanMasq OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Channel masquerading for us."
+ ::= { astChanEntry 7 }
+
+astChanMasqr OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Channel we are masquerading for."
+ ::= { astChanEntry 8 }
+
+astChanWhenHangup OBJECT-TYPE
+ SYNTAX TimeTicks
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "How long until this channel will be hung up."
+ ::= { astChanEntry 9 }
+
+astChanApp OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current application for the channel."
+ ::= { astChanEntry 10 }
+
+astChanData OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Arguments passed to the current application."
+ ::= { astChanEntry 11 }
+
+astChanContext OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current extension context."
+ ::= { astChanEntry 12 }
+
+astChanMacroContext OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current macro context."
+ ::= { astChanEntry 13 }
+
+astChanMacroExten OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current macro extension."
+ ::= { astChanEntry 14 }
+
+astChanMacroPri OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current macro priority."
+ ::= { astChanEntry 15 }
+
+astChanExten OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current extension."
+ ::= { astChanEntry 16 }
+
+astChanPri OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Current priority."
+ ::= { astChanEntry 17 }
+
+astChanAccountCode OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Account Code for billing."
+ ::= { astChanEntry 18 }
+
+astChanForwardTo OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Where to forward to if asked to dial on this
+ interface."
+ ::= { astChanEntry 19 }
+
+astChanUniqueId OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Unique Channel Identifier."
+ ::= { astChanEntry 20 }
+
+astChanCallGroup OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Call Group."
+ ::= { astChanEntry 21 }
+
+astChanPickupGroup OBJECT-TYPE
+ SYNTAX Unsigned32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Pickup Group."
+ ::= { astChanEntry 22 }
+
+astChanState OBJECT-TYPE
+ SYNTAX INTEGER {
+ stateDown(0),
+ stateReserved(1),
+ stateOffHook(2),
+ stateDialing(3),
+ stateRing(4),
+ stateRinging(5),
+ stateUp(6),
+ stateBusy(7),
+ stateDialingOffHook(8),
+ statePreRing(9)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Channel state."
+ ::= { astChanEntry 23 }
+
+astChanMuted OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Transmission of voice data has been muted."
+ ::= { astChanEntry 24 }
+
+astChanRings OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of rings so far."
+ ::= { astChanEntry 25 }
+
+astChanCidDNID OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Dialled Number ID."
+ ::= { astChanEntry 26 }
+
+astChanCidNum OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Caller Number."
+ ::= { astChanEntry 27 }
+
+astChanCidName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Caller Name."
+ ::= { astChanEntry 28 }
+
+astCanCidANI OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "ANI"
+ ::= { astChanEntry 29 }
+
+astChanCidRDNIS OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Redirected Dialled Number Service."
+ ::= { astChanEntry 30 }
+
+astChanCidPresentation OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number Presentation/Screening."
+ ::= { astChanEntry 31 }
+
+astChanCidANI2 OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "ANI 2 (info digit)."
+ ::= { astChanEntry 32 }
+
+astChanCidTON OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Type of Number."
+ ::= { astChanEntry 33 }
+
+astChanCidTNS OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Transit Network Select."
+ ::= { astChanEntry 34 }
+
+astChanAMAFlags OBJECT-TYPE
+ SYNTAX INTEGER {
+ Default(0),
+ Omit(1),
+ Billing(2),
+ Documentation(3)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "AMA Flags."
+ ::= { astChanEntry 35 }
+
+astChanADSI OBJECT-TYPE
+ SYNTAX INTEGER {
+ Unknown(0),
+ Available(1),
+ Unavailable(2),
+ OffHookOnly(3)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Whether or not ADSI is detected on CPE."
+ ::= { astChanEntry 36 }
+
+astChanToneZone OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Indication zone to use for channel."
+ ::= { astChanEntry 37 }
+
+astChanHangupCause OBJECT-TYPE
+ SYNTAX INTEGER {
+ NotDefined(0),
+ Unregistered(3),
+ Normal(16),
+ Busy(17),
+ NoAnswer(19),
+ Congestion(34),
+ Failure(38),
+ NoSuchDriver(66)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Why is the channel hung up."
+ ::= { astChanEntry 38 }
+
+astChanVariables OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Channel Variables defined for this channel."
+ ::= { astChanEntry 39 }
+
+astChanFlags OBJECT-TYPE
+ SYNTAX BITS {
+ WantsJitter(0),
+ DeferDTMF(1),
+ WriteInterrupt(2),
+ Blocking(3),
+ Zombie(4),
+ Exception(5),
+ MusicOnHold(6),
+ Spying(7),
+ NativeBridge(8),
+ AutoIncrementingLoop(9)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Flags set on this channel."
+ ::= { astChanEntry 40 }
+
+astChanTransferCap OBJECT-TYPE
+ SYNTAX INTEGER {
+ Speech(0),
+ Digital(8),
+ RestrictedDigital(9),
+ 3kAudio(16),
+ DigitalWithTones(17),
+ Video(24)
+ }
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Transfer Capabilities for this channel."
+ ::= { astChanEntry 41 }
+
+astNumChanTypes OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of channel types (technologies) supported."
+ ::= { asteriskChannels 3 }
+
+astChanTypeTable OBJECT-TYPE
+ SYNTAX SEQUENCE OF AstChanTypeEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Table with details of the supported channel types."
+ ::= { asteriskChannels 4 }
+
+astChanTypeEntry OBJECT-TYPE
+ SYNTAX AstChanTypeEntry
+ MAX-ACCESS not-accessible
+ STATUS current
+ DESCRIPTION
+ "Information about a technology we support, including
+ how many channels are currently using this technology."
+ INDEX { astChanTypeIndex }
+ ::= { astChanTypeTable 1 }
+
+AstChanTypeEntry ::= SEQUENCE {
+ astChanTypeIndex Integer32,
+ astChanTypeName DisplayString,
+ astChanTypeDesc DisplayString,
+ astChanTypeDeviceState Integer32,
+ astChanTypeIndications Integer32,
+ astChanTypeTransfer Integer32,
+ astChanTypeChannels Gauge32
+}
+
+astChanTypeIndex OBJECT-TYPE
+ SYNTAX Integer32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Index into the table of channel types."
+ ::= { astChanTypeEntry 1 }
+
+astChanTypeName OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Unique name of the technology we are describing."
+ ::= { astChanTypeEntry 2 }
+
+astChanTypeDesc OBJECT-TYPE
+ SYNTAX DisplayString
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Description of the channel type (technology)."
+ ::= { astChanTypeEntry 3 }
+
+astChanTypeDeviceState OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Whether the current technology can hold device states."
+ ::= { astChanTypeEntry 4 }
+
+astChanTypeIndications OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Whether the current technology supports progress indication."
+ ::= { astChanTypeEntry 5 }
+
+astChanTypeTransfer OBJECT-TYPE
+ SYNTAX TruthValue
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Whether the current technology supports transfers, where
+ Asterisk can get out from inbetween two bridged channels."
+ ::= { astChanTypeEntry 6 }
+
+astChanTypeChannels OBJECT-TYPE
+ SYNTAX Gauge32
+ MAX-ACCESS read-only
+ STATUS current
+ DESCRIPTION
+ "Number of active channels using the current technology."
+ ::= { astChanTypeEntry 7 }
+
+END
diff --git a/doc/digium-mib.txt b/doc/digium-mib.txt
new file mode 100644
index 000000000..018a080dd
--- /dev/null
+++ b/doc/digium-mib.txt
@@ -0,0 +1,17 @@
+DIGIUM-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+ enterprises
+ FROM SNMPv2-SMI;
+
+digium MODULE-IDENTITY
+ LAST-UPDATED "200602041900Z"
+ ORGANIZATION "Digium, Inc."
+ CONTACT-INFO
+ "Mark Spencer
+ Email: markster@digium.com"
+ DESCRIPTION
+ ""
+ ::= { enterprises 22736 }
+
+END
diff --git a/doc/snmp.txt b/doc/snmp.txt
new file mode 100644
index 000000000..afab91c3e
--- /dev/null
+++ b/doc/snmp.txt
@@ -0,0 +1,36 @@
+Asterisk SNMP Support
+---------------------
+
+Rudimentary support for SNMP access to Asterisk is available. To build
+this, one needs to have Net-SNMP development headers and libraries on
+the build system, including any libraries Net-SNMP depends on.
+
+Note that on some (many?) Linux-distributions the dependency list in
+the net-snmp-devel list is not complete, and additional RPMs will need
+to be installed. This is typically seen as attempts to build res_snmp
+as net-snmp-devel is available, but then failures to find certain
+libraries.
+
+SNMP support comes in two varieties -- as a sub-agent to a running SNMP
+daemon using the AgentX protocol, or as a full standalone agent. If
+you wish to run a full standalone agent, Asterisk must run as root in
+order to find to port 161.
+
+Configuring access when running as a full agent is something that is
+left as an exercise to the reader.
+
+To enable access to the Asterisk SNMP subagent from a master SNMP
+daemon, one will need to enable AgentX support, and also make sure that
+Asterisk will be able to access the Unix domain socket. One way of
+doing this is to add the following to /etc/snmp/snmpd.conf:
+
+ # Enable AgentX support
+ master agentx
+
+ # Set permissions on AgentX socket and containing
+ # directory such that process in group 'asterisk'
+ # will be able to connect
+ agentXPerms 0660 0550 nobody asterisk
+
+This assumes that you run Asterisk under group 'asterisk' (and does
+not care what user you run as).
diff --git a/res/Makefile b/res/Makefile
index 2759f4e49..08ee8e14a 100644
--- a/res/Makefile
+++ b/res/Makefile
@@ -32,6 +32,11 @@ ifeq (${OSPLIB},)
MODS:=$(filter-out res_osp.so,$(MODS))
endif
+ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/include/net-snmp/net-snmp-config.h),)
+ SNMP_LDLIBS+=$(shell net-snmp-config --agent-libs)
+ MODS+=res_snmp.so
+endif
+
ifeq (${WITH_SMDI},)
MODS:=$(filter-out res_smdi.so,$(MODS))
endif
@@ -108,6 +113,9 @@ res_features.so: res_features.o
res_config_odbc.so: res_config_odbc.o
$(CC) $(SOLINK) -o $@ ${CYGSOLINK} $< ${CYGSOLIB} ${CYG_RES_CONFIG_ODBC_LIB}
+res_snmp.so: res_snmp.o snmp/agent.o
+ $(CC) $(SOLINK) ${SNMP_LDFLAGS} -o $@ ${CYGSOLINK} res_snmp.o snmp/agent.o ${CYGSOLIB} ${SNMP_LDLIBS}
+
ifneq ($(wildcard .depend),)
include .depend
endif
diff --git a/res/res_snmp.c b/res/res_snmp.c
new file mode 100644
index 000000000..e62e6fb05
--- /dev/null
+++ b/res/res_snmp.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2006 Voop as
+ * Thorsten Lockert <tholo@voop.as>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief SNMP Agent / SubAgent support for Asterisk
+ *
+ * \author Thorsten Lockert <tholo@voop.as>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/channel.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+#include "asterisk/options.h"
+
+#include "snmp/agent.h"
+
+#define MODULE_DESCRIPTION "SNMP [Sub]Agent for Asterisk"
+
+int res_snmp_agentx_subagent;
+int res_snmp_dont_stop;
+int res_snmp_enabled;
+
+static pthread_t thread;
+
+static int load_config(void)
+{
+ struct ast_variable *var;
+ struct ast_config *cfg;
+ char *cat;
+
+ res_snmp_enabled = 0;
+ res_snmp_agentx_subagent = 1;
+ cfg = ast_config_load("res_snmp.conf");
+ if (cfg) {
+ cat = ast_category_browse(cfg, NULL);
+ while (cat) {
+ var = ast_variable_browse(cfg, cat);
+
+ if (strcasecmp(cat, "general") == 0) {
+ while (var) {
+ if (strcasecmp(var->name, "subagent") == 0) {
+ if (ast_true(var->value))
+ res_snmp_agentx_subagent = 1;
+ else if (ast_false(var->value))
+ res_snmp_agentx_subagent = 0;
+ else {
+ ast_log(LOG_ERROR, "Value '%s' does not evaluate to true or false.\n",
+ var->value);
+ ast_config_destroy(cfg);
+ return 1;
+ }
+ } else if (strcasecmp(var->name, "enabled") == 0) {
+ res_snmp_enabled = ast_true(var->value);
+ } else {
+ ast_log(LOG_ERROR, "Unrecognized variable '%s' in category '%s'\n",
+ var->name, cat);
+ ast_config_destroy(cfg);
+ return 1;
+ }
+ var = var->next;
+ }
+ }
+ else {
+ ast_log(LOG_ERROR, "Unrecognized category '%s'\n", cat);
+ ast_config_destroy(cfg);
+ return 1;
+ }
+
+ cat = ast_category_browse(cfg, cat);
+ }
+ ast_config_destroy(cfg);
+ }
+
+ return 0;
+}
+
+int load_module(void)
+{
+ load_config();
+
+ ast_verbose(VERBOSE_PREFIX_1 "Loading [Sub]Agent Module\n");
+
+ res_snmp_dont_stop = 1;
+ if (res_snmp_enabled)
+ return ast_pthread_create(&thread, NULL, agent_thread, NULL);
+ else
+ return 0;
+}
+
+int unload_module(void)
+{
+ ast_verbose(VERBOSE_PREFIX_1 "Unloading [Sub]Agent Module\n");
+
+ res_snmp_dont_stop = 0;
+ return pthread_join(thread, NULL);
+}
+
+int reload(void)
+{
+ ast_verbose(VERBOSE_PREFIX_1 "Reloading [Sub]Agent Module\n");
+
+ res_snmp_dont_stop = 0;
+ pthread_join(thread, NULL);
+
+ load_config();
+
+ res_snmp_dont_stop = 1;
+ if (res_snmp_enabled)
+ return ast_pthread_create(&thread, NULL, agent_thread, NULL);
+ else
+ return 0;
+}
+
+int usecount(void)
+{
+ return 0;
+}
+
+char *key(void)
+{
+ return ASTERISK_GPL_KEY;
+}
+
+char *description(void)
+{
+ return MODULE_DESCRIPTION;
+}
+
+/*
+ * Local Variables:
+ * c-file-style: gnu
+ * c-basic-offset: 4
+ * c-file-offsets: ((case-label . 0))
+ * tab-width: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/res/snmp/agent.c b/res/snmp/agent.c
new file mode 100644
index 000000000..740f5c10e
--- /dev/null
+++ b/res/snmp/agent.c
@@ -0,0 +1,845 @@
+/*
+ * Copyright (C) 2006 Voop as
+ * Thorsten Lockert <tholo@voop.as>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief SNMP Agent / SubAgent support for Asterisk
+ *
+ * \author Thorsten Lockert <tholo@voop.as>
+ */
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+/*
+ * These conflict with ones in Asterisk header files, so
+ * get rid of them. They'll be back after the next few
+ * includes...
+ */
+#undef HAVE_GETLOADAVG
+#undef HAVE_STRCASESTR
+
+#include <pthread.h>
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/channel.h"
+#include "asterisk/logger.h"
+#include "asterisk/options.h"
+#include "asterisk/indications.h"
+#include "asterisk/version.h"
+#include "asterisk/pbx.h"
+
+/* Colission between Net-SNMP and Asterisk */
+#define unload_module ast_unload_module
+#include "asterisk/module.h"
+#undef unload_module
+
+#include "agent.h"
+
+/* Helper functions in Net-SNMP, header file not installed by default */
+int header_generic(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **);
+int header_simple_table(struct variable *, oid *, size_t *, int, size_t *, WriteMethod **, int);
+int register_sysORTable(oid *, size_t, const char *);
+int unregister_sysORTable(oid *, size_t);
+
+/* Not defined in header files */
+extern char ast_config_AST_SOCKET[];
+
+/* Forward declaration */
+static void init_asterisk_mib(void);
+
+/*
+ * Anchor for all the Asterisk MIB values
+ */
+static oid asterisk_oid[] = { 1, 3, 6, 1, 4, 1, 22736, 1 };
+
+/*
+ * MIB values -- these correspond to values in the Asterisk MIB,
+ * and MUST be kept in sync with the MIB for things to work as
+ * expected.
+ */
+#define ASTVERSION 1
+#define ASTVERSTRING 1
+#define ASTVERTAG 2
+
+#define ASTCONFIGURATION 2
+#define ASTCONFUPTIME 1
+#define ASTCONFRELOADTIME 2
+#define ASTCONFPID 3
+#define ASTCONFSOCKET 4
+
+#define ASTMODULES 3
+#define ASTMODCOUNT 1
+
+#define ASTINDICATIONS 4
+#define ASTINDCOUNT 1
+#define ASTINDCURRENT 2
+
+#define ASTINDTABLE 3
+#define ASTINDINDEX 1
+#define ASTINDCOUNTRY 2
+#define ASTINDALIAS 3
+#define ASTINDDESCRIPTION 4
+
+#define ASTCHANNELS 5
+#define ASTCHANCOUNT 1
+
+#define ASTCHANTABLE 2
+#define ASTCHANINDEX 1
+#define ASTCHANNAME 2
+#define ASTCHANLANGUAGE 3
+#define ASTCHANTYPE 4
+#define ASTCHANMUSICCLASS 5
+#define ASTCHANBRIDGE 6
+#define ASTCHANMASQ 7
+#define ASTCHANMASQR 8
+#define ASTCHANWHENHANGUP 9
+#define ASTCHANAPP 10
+#define ASTCHANDATA 11
+#define ASTCHANCONTEXT 12
+#define ASTCHANMACROCONTEXT 13
+#define ASTCHANMACROEXTEN 14
+#define ASTCHANMACROPRI 15
+#define ASTCHANEXTEN 16
+#define ASTCHANPRI 17
+#define ASTCHANACCOUNTCODE 18
+#define ASTCHANFORWARDTO 19
+#define ASTCHANUNIQUEID 20
+#define ASTCHANCALLGROUP 21
+#define ASTCHANPICKUPGROUP 22
+#define ASTCHANSTATE 23
+#define ASTCHANMUTED 24
+#define ASTCHANRINGS 25
+#define ASTCHANCIDDNID 26
+#define ASTCHANCIDNUM 27
+#define ASTCHANCIDNAME 28
+#define ASTCHANCIDANI 29
+#define ASTCHANCIDRDNIS 30
+#define ASTCHANCIDPRES 31
+#define ASTCHANCIDANI2 32
+#define ASTCHANCIDTON 33
+#define ASTCHANCIDTNS 34
+#define ASTCHANAMAFLAGS 35
+#define ASTCHANADSI 36
+#define ASTCHANTONEZONE 37
+#define ASTCHANHANGUPCAUSE 38
+#define ASTCHANVARIABLES 39
+#define ASTCHANFLAGS 40
+#define ASTCHANTRANSFERCAP 41
+
+#define ASTCHANTYPECOUNT 3
+
+#define ASTCHANTYPETABLE 4
+#define ASTCHANTYPEINDEX 1
+#define ASTCHANTYPENAME 2
+#define ASTCHANTYPEDESC 3
+#define ASTCHANTYPEDEVSTATE 4
+#define ASTCHANTYPEINDICATIONS 5
+#define ASTCHANTYPETRANSFER 6
+#define ASTCHANTYPECHANNELS 7
+
+void *agent_thread(void *arg)
+{
+ ast_verbose(VERBOSE_PREFIX_2 "Starting %sAgent\n", res_snmp_agentx_subagent ? "Sub" : "");
+
+ snmp_enable_stderrlog();
+
+ if (res_snmp_agentx_subagent)
+ netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID,
+ NETSNMP_DS_AGENT_ROLE,
+ 1);
+
+ init_agent("asterisk");
+
+ init_asterisk_mib();
+
+ init_snmp("asterisk");
+
+ if (!res_snmp_agentx_subagent)
+ init_master_agent();
+
+ while (res_snmp_dont_stop)
+ agent_check_and_process(1);
+
+ snmp_shutdown("asterisk");
+
+ ast_verbose(VERBOSE_PREFIX_2 "Terminating %sAgent\n",
+ res_snmp_agentx_subagent ? "Sub" : "");
+
+ return NULL;
+}
+
+static u_char *
+ast_var_channels(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTCHANCOUNT:
+ long_ret = ast_active_channels();
+ return (u_char *)&long_ret;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static u_char *ast_var_channels_table(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+ static u_char bits_ret[2];
+ static char string_ret[256];
+ struct ast_channel *chan, *bridge;
+ struct timeval tval;
+ u_char *ret;
+ int i, bit;
+
+ if (header_simple_table(vp, name, length, exact, var_len, write_method, ast_active_channels()))
+ return NULL;
+
+ i = name[*length - 1] - 1;
+ for (chan = ast_channel_walk_locked(NULL);
+ chan && i;
+ chan = ast_channel_walk_locked(chan), i--)
+ ast_mutex_unlock(&chan->lock);
+ if (chan == NULL)
+ return NULL;
+ *var_len = sizeof(long_ret);
+
+ switch (vp->magic) {
+ case ASTCHANINDEX:
+ long_ret = name[*length - 1];
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANNAME:
+ if (!ast_strlen_zero(chan->name)) {
+ strncpy(string_ret, chan->name, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANLANGUAGE:
+ if (!ast_strlen_zero(chan->language)) {
+ strncpy(string_ret, chan->language, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANTYPE:
+ strncpy(string_ret, chan->tech->type, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ break;
+ case ASTCHANMUSICCLASS:
+ if (!ast_strlen_zero(chan->musicclass)) {
+ strncpy(string_ret, chan->musicclass, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANBRIDGE:
+ if ((bridge = ast_bridged_channel(chan)) != NULL) {
+ strncpy(string_ret, bridge->name, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANMASQ:
+ if (chan->masq && !ast_strlen_zero(chan->masq->name)) {
+ strncpy(string_ret, chan->masq->name, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANMASQR:
+ if (chan->masqr && !ast_strlen_zero(chan->masqr->name)) {
+ strncpy(string_ret, chan->masqr->name, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANWHENHANGUP:
+ if (chan->whentohangup) {
+ gettimeofday(&tval, NULL);
+ long_ret = difftime(chan->whentohangup, tval.tv_sec) * 100 - tval.tv_usec / 10000;
+ ret= (u_char *)&long_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANAPP:
+ if (chan->appl) {
+ strncpy(string_ret, chan->appl, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANDATA:
+ if (chan->data) {
+ strncpy(string_ret, chan->data, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANCONTEXT:
+ strncpy(string_ret, chan->context, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ break;
+ case ASTCHANMACROCONTEXT:
+ strncpy(string_ret, chan->macrocontext, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ break;
+ case ASTCHANMACROEXTEN:
+ strncpy(string_ret, chan->macroexten, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ break;
+ case ASTCHANMACROPRI:
+ long_ret = chan->macropriority;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANEXTEN:
+ strncpy(string_ret, chan->exten, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ break;
+ case ASTCHANPRI:
+ long_ret = chan->priority;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANACCOUNTCODE:
+ if (!ast_strlen_zero(chan->accountcode)) {
+ strncpy(string_ret, chan->accountcode, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANFORWARDTO:
+ if (!ast_strlen_zero(chan->call_forward)) {
+ strncpy(string_ret, chan->call_forward, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANUNIQUEID:
+ strncpy(string_ret, chan->uniqueid, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ break;
+ case ASTCHANCALLGROUP:
+ long_ret = chan->callgroup;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANPICKUPGROUP:
+ long_ret = chan->pickupgroup;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANSTATE:
+ long_ret = chan->_state & 0xffff;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANMUTED:
+ long_ret = chan->_state & AST_STATE_MUTE ? 1 : 2;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANRINGS:
+ long_ret = chan->rings;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANCIDDNID:
+ if (chan->cid.cid_dnid) {
+ strncpy(string_ret, chan->cid.cid_dnid, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANCIDNUM:
+ if (chan->cid.cid_num) {
+ strncpy(string_ret, chan->cid.cid_num, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANCIDNAME:
+ if (chan->cid.cid_name) {
+ strncpy(string_ret, chan->cid.cid_name, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANCIDANI:
+ if (chan->cid.cid_ani) {
+ strncpy(string_ret, chan->cid.cid_ani, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANCIDRDNIS:
+ if (chan->cid.cid_rdnis) {
+ strncpy(string_ret, chan->cid.cid_rdnis, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANCIDPRES:
+ long_ret = chan->cid.cid_pres;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANCIDANI2:
+ long_ret = chan->cid.cid_ani2;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANCIDTON:
+ long_ret = chan->cid.cid_ton;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANCIDTNS:
+ long_ret = chan->cid.cid_tns;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANAMAFLAGS:
+ long_ret = chan->amaflags;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANADSI:
+ long_ret = chan->adsicpe;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANTONEZONE:
+ if (chan->zone) {
+ strncpy(string_ret, chan->zone->country, sizeof(string_ret));
+ string_ret[sizeof(string_ret) - 1] = '\0';
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANHANGUPCAUSE:
+ long_ret = chan->hangupcause;
+ ret = (u_char *)&long_ret;
+ break;
+ case ASTCHANVARIABLES:
+ if (pbx_builtin_serialize_variables(chan, string_ret, sizeof(string_ret))) {
+ *var_len = strlen(string_ret);
+ ret = (u_char *)string_ret;
+ }
+ else
+ ret = NULL;
+ break;
+ case ASTCHANFLAGS:
+ bits_ret[0] = 0;
+ for (bit = 0; bit < 8; bit++)
+ bits_ret[0] |= ((chan->flags & (1 << bit)) >> bit) << (7 - bit);
+ bits_ret[1] = 0;
+ for (bit = 0; bit < 8; bit++)
+ bits_ret[1] |= (((chan->flags >> 8) & (1 << bit)) >> bit) << (7 - bit);
+ *var_len = 2;
+ ret = bits_ret;
+ break;
+ case ASTCHANTRANSFERCAP:
+ long_ret = chan->transfercapability;
+ ret = (u_char *)&long_ret;
+ break;
+ default:
+ ret = NULL;
+ break;
+ }
+ ast_mutex_unlock(&chan->lock);
+ return ret;
+}
+
+static u_char *ast_var_channel_types(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+ struct ast_variable *channel_types, *next;
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTCHANTYPECOUNT:
+ long_ret = 0;
+ for (channel_types = next = ast_channeltype_list(); next; next = next->next) {
+ long_ret++;
+ }
+ ast_variables_destroy(channel_types);
+ return (u_char *)&long_ret;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static u_char *ast_var_channel_types_table(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ const struct ast_channel_tech *tech = NULL;
+ struct ast_variable *channel_types, *next;
+ static unsigned long long_ret;
+ struct ast_channel *chan;
+ u_long i;
+
+ if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
+ return NULL;
+
+ channel_types = ast_channeltype_list();
+ for (i = 1, next = channel_types; next && i != name[*length - 1]; next = next->next, i++)
+ ;
+ if (next != NULL)
+ tech = ast_get_channel_tech(next->name);
+ ast_variables_destroy(channel_types);
+ if (next == NULL || tech == NULL)
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTCHANTYPEINDEX:
+ long_ret = name[*length - 1];
+ return (u_char *)&long_ret;
+ case ASTCHANTYPENAME:
+ *var_len = strlen(tech->type);
+ return (u_char *)tech->type;
+ case ASTCHANTYPEDESC:
+ *var_len = strlen(tech->description);
+ return (u_char *)tech->description;
+ case ASTCHANTYPEDEVSTATE:
+ long_ret = tech->devicestate ? 1 : 2;
+ return (u_char *)&long_ret;
+ case ASTCHANTYPEINDICATIONS:
+ long_ret = tech->indicate ? 1 : 2;
+ return (u_char *)&long_ret;
+ case ASTCHANTYPETRANSFER:
+ long_ret = tech->transfer ? 1 : 2;
+ return (u_char *)&long_ret;
+ case ASTCHANTYPECHANNELS:
+ long_ret = 0;
+ for (chan = ast_channel_walk_locked(NULL); chan; chan = ast_channel_walk_locked(chan)) {
+ ast_mutex_unlock(&chan->lock);
+ if (chan->tech == tech)
+ long_ret++;
+ }
+ return (u_char *)&long_ret;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static u_char *ast_var_Config(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+ struct timeval tval;
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTCONFUPTIME:
+ gettimeofday(&tval, NULL);
+ long_ret = difftime(tval.tv_sec, ast_startuptime) * 100 + tval.tv_usec / 10000;
+ return (u_char *)&long_ret;
+ case ASTCONFRELOADTIME:
+ gettimeofday(&tval, NULL);
+ if (ast_lastreloadtime)
+ long_ret = difftime(tval.tv_sec, ast_lastreloadtime) * 100 + tval.tv_usec / 10000;
+ else
+ long_ret = difftime(tval.tv_sec, ast_startuptime) * 100 + tval.tv_usec / 10000;
+ return (u_char *)&long_ret;
+ case ASTCONFPID:
+ long_ret = getpid();
+ return (u_char *)&long_ret;
+ case ASTCONFSOCKET:
+ *var_len = strlen(ast_config_AST_SOCKET);
+ return (u_char *)ast_config_AST_SOCKET;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static u_char *ast_var_indications(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+ struct tone_zone *tz;
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTINDCOUNT:
+ if (ast_mutex_lock(&tzlock)) {
+ ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
+ snmp_log(LOG_ERR, "Unable to lock tone_zones list in ast_var_indications\n");
+ return NULL;
+ }
+ long_ret = 0;
+ for (tz = tone_zones; tz; tz = tz->next)
+ long_ret++;
+ ast_mutex_unlock(&tzlock);
+
+ return (u_char *)&long_ret;
+ case ASTINDCURRENT:
+ tz = ast_get_indication_zone(NULL);
+ if (tz) {
+ *var_len = strlen(tz->country);
+ return (u_char *)tz->country;
+ }
+ *var_len = 0;
+ return NULL;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static u_char *ast_var_indications_table(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+ struct tone_zone *tz;
+ int i;
+
+ if (header_simple_table(vp, name, length, exact, var_len, write_method, -1))
+ return NULL;
+
+ if (ast_mutex_lock(&tzlock)) {
+ ast_log(LOG_WARNING, "Unable to lock tone_zones list\n");
+ snmp_log(LOG_ERR, "Unable to lock tone_zones list in ast_var_indications_table\n");
+ return NULL;
+ }
+ i = name[*length - 1] - 1;
+ for (tz = tone_zones; tz && i; tz = tz->next)
+ i--;
+ ast_mutex_unlock(&tzlock);
+ if (tz == NULL)
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTINDINDEX:
+ long_ret = name[*length - 1];
+ return (u_char *)&long_ret;
+ case ASTINDCOUNTRY:
+ *var_len = strlen(tz->country);
+ return (u_char *)tz->country;
+ case ASTINDALIAS:
+ if (tz->alias) {
+ *var_len = strlen(tz->alias);
+ return (u_char *)tz->alias;
+ }
+ return NULL;
+ case ASTINDDESCRIPTION:
+ *var_len = strlen(tz->description);
+ return (u_char *)tz->description;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static int countmodule(const char *mod, const char *desc, int use, const char *like)
+{
+ return 1;
+}
+
+static u_char *ast_var_Modules(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTMODCOUNT:
+ long_ret = ast_update_module_list(countmodule, NULL);
+ return (u_char *)&long_ret;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static u_char *ast_var_Version(struct variable *vp, oid *name, size_t *length,
+ int exact, size_t *var_len, WriteMethod **write_method)
+{
+ static unsigned long long_ret;
+
+ if (header_generic(vp, name, length, exact, var_len, write_method))
+ return NULL;
+
+ switch (vp->magic) {
+ case ASTVERSTRING:
+ *var_len = strlen(ASTERISK_VERSION);
+ return (u_char *)ASTERISK_VERSION;
+ case ASTVERTAG:
+ long_ret = ASTERISK_VERSION_NUM;
+ return (u_char *)&long_ret;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+static int term_asterisk_mib(int majorID, int minorID, void *serverarg, void *clientarg)
+{
+ unregister_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid));
+ return 0;
+}
+
+static void init_asterisk_mib(void)
+{
+ static struct variable4 asterisk_vars[] = {
+ {ASTVERSTRING, ASN_OCTET_STR, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERSTRING}},
+ {ASTVERTAG, ASN_UNSIGNED, RONLY, ast_var_Version, 2, {ASTVERSION, ASTVERTAG}},
+ {ASTCONFUPTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFUPTIME}},
+ {ASTCONFRELOADTIME, ASN_TIMETICKS, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFRELOADTIME}},
+ {ASTCONFPID, ASN_INTEGER, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFPID}},
+ {ASTCONFSOCKET, ASN_OCTET_STR, RONLY, ast_var_Config, 2, {ASTCONFIGURATION, ASTCONFSOCKET}},
+ {ASTMODCOUNT, ASN_INTEGER, RONLY, ast_var_Modules , 2, {ASTMODULES, ASTMODCOUNT}},
+ {ASTINDCOUNT, ASN_INTEGER, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCOUNT}},
+ {ASTINDCURRENT, ASN_OCTET_STR, RONLY, ast_var_indications, 2, {ASTINDICATIONS, ASTINDCURRENT}},
+ {ASTINDINDEX, ASN_INTEGER, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDINDEX}},
+ {ASTINDCOUNTRY, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDCOUNTRY}},
+ {ASTINDALIAS, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDALIAS}},
+ {ASTINDDESCRIPTION, ASN_OCTET_STR, RONLY, ast_var_indications_table, 4, {ASTINDICATIONS, ASTINDTABLE, 1, ASTINDDESCRIPTION}},
+ {ASTCHANCOUNT, ASN_INTEGER, RONLY, ast_var_channels, 2, {ASTCHANNELS, ASTCHANCOUNT}},
+ {ASTCHANINDEX, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANINDEX}},
+ {ASTCHANNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANNAME}},
+ {ASTCHANLANGUAGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANLANGUAGE}},
+ {ASTCHANTYPE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTYPE}},
+ {ASTCHANMUSICCLASS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUSICCLASS}},
+ {ASTCHANBRIDGE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANBRIDGE}},
+ {ASTCHANMASQ, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQ}},
+ {ASTCHANMASQR, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMASQR}},
+ {ASTCHANWHENHANGUP, ASN_TIMETICKS, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANWHENHANGUP}},
+ {ASTCHANAPP, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAPP}},
+ {ASTCHANDATA, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANDATA}},
+ {ASTCHANCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCONTEXT}},
+ {ASTCHANMACROCONTEXT, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROCONTEXT}},
+ {ASTCHANMACROEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROEXTEN}},
+ {ASTCHANMACROPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMACROPRI}},
+ {ASTCHANEXTEN, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANEXTEN}},
+ {ASTCHANPRI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPRI}},
+ {ASTCHANACCOUNTCODE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANACCOUNTCODE}},
+ {ASTCHANFORWARDTO, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFORWARDTO}},
+ {ASTCHANUNIQUEID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANUNIQUEID}},
+ {ASTCHANCALLGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCALLGROUP}},
+ {ASTCHANPICKUPGROUP, ASN_UNSIGNED, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANPICKUPGROUP}},
+ {ASTCHANSTATE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANSTATE}},
+ {ASTCHANMUTED, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANMUTED}},
+ {ASTCHANRINGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANRINGS}},
+ {ASTCHANCIDDNID, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDDNID}},
+ {ASTCHANCIDNUM, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNUM}},
+ {ASTCHANCIDNAME, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDNAME}},
+ {ASTCHANCIDANI, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI}},
+ {ASTCHANCIDRDNIS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDRDNIS}},
+ {ASTCHANCIDPRES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDPRES}},
+ {ASTCHANCIDANI2, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDANI2}},
+ {ASTCHANCIDTON, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTON}},
+ {ASTCHANCIDTNS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANCIDTNS}},
+ {ASTCHANAMAFLAGS, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANAMAFLAGS}},
+ {ASTCHANADSI, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANADSI}},
+ {ASTCHANTONEZONE, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTONEZONE}},
+ {ASTCHANHANGUPCAUSE, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANHANGUPCAUSE}},
+ {ASTCHANVARIABLES, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANVARIABLES}},
+ {ASTCHANFLAGS, ASN_OCTET_STR, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANFLAGS}},
+ {ASTCHANTRANSFERCAP, ASN_INTEGER, RONLY, ast_var_channels_table, 4, {ASTCHANNELS, ASTCHANTABLE, 1, ASTCHANTRANSFERCAP}},
+ {ASTCHANTYPECOUNT, ASN_INTEGER, RONLY, ast_var_channel_types, 2, {ASTCHANNELS, ASTCHANTYPECOUNT}},
+ {ASTCHANTYPEINDEX, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDEX}},
+ {ASTCHANTYPENAME, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPENAME}},
+ {ASTCHANTYPEDESC, ASN_OCTET_STR, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDESC}},
+ {ASTCHANTYPEDEVSTATE, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEDEVSTATE}},
+ {ASTCHANTYPEINDICATIONS, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPEINDICATIONS}},
+ {ASTCHANTYPETRANSFER, ASN_INTEGER, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPETRANSFER}},
+ {ASTCHANTYPECHANNELS, ASN_GAUGE, RONLY, ast_var_channel_types_table, 4, {ASTCHANNELS, ASTCHANTYPETABLE, 1, ASTCHANTYPECHANNELS}},
+ };
+
+ register_sysORTable(asterisk_oid, OID_LENGTH(asterisk_oid),
+ "ASTERISK-MIB implementation for Asterisk.");
+
+ REGISTER_MIB("res_snmp", asterisk_vars, variable4, asterisk_oid);
+
+ snmp_register_callback(SNMP_CALLBACK_LIBRARY,
+ SNMP_CALLBACK_SHUTDOWN,
+ term_asterisk_mib, NULL);
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * c-file-offsets: ((case-label . 0))
+ * tab-width: 4
+ * indent-tabs-mode: t
+ * End:
+ */
diff --git a/res/snmp/agent.h b/res/snmp/agent.h
new file mode 100644
index 000000000..21389d6c9
--- /dev/null
+++ b/res/snmp/agent.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2006 Voop as
+ * Thorsten Lockert <tholo@voop.as>
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief SNMP Agent / SubAgent support for Asterisk
+ *
+ * \author Thorsten Lockert <tholo@voop.as>
+ */
+
+/*!
+ * \internal
+ * \brief Thread running the SNMP Agent or Subagent
+ * \param Not used -- required by pthread_create
+ * \return A pointer with return status -- not used
+ *
+ * This represent the main thread of the SNMP [sub]agent, and
+ * will initialize SNMP and loop, processing requests until
+ * termination is requested by resetting the flag in
+ * \ref res_snmp_dontStop.
+ */
+void *agent_thread(void *);
+
+/*!
+ * \internal
+ * Flag saying whether we run as a Subagent or full Agent
+ */
+extern int res_snmp_agentx_subagent;
+
+/*!
+ * \internal
+ * Flag stating the agent thread should not terminate
+ */
+extern int res_snmp_dont_stop;