]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
initial checkin of mod_snmp
authorDaniel Swarbrick <daniel@seventhsignal.de>
Fri, 21 Jan 2011 20:05:01 +0000 (21:05 +0100)
committerDaniel Swarbrick <daniel@seventhsignal.de>
Fri, 21 Jan 2011 20:05:01 +0000 (21:05 +0100)
src/mod/event_handlers/mod_snmp/FREESWITCH-MIB [new file with mode: 0644]
src/mod/event_handlers/mod_snmp/Makefile [new file with mode: 0644]
src/mod/event_handlers/mod_snmp/mod_snmp.c [new file with mode: 0644]
src/mod/event_handlers/mod_snmp/subagent.c [new file with mode: 0644]
src/mod/event_handlers/mod_snmp/subagent.h [new file with mode: 0644]

diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB
new file mode 100644 (file)
index 0000000..9584c8b
--- /dev/null
@@ -0,0 +1,110 @@
+FREESWITCH-MIB DEFINITIONS ::= BEGIN
+
+IMPORTS
+    OBJECT-TYPE, MODULE-IDENTITY,
+    Integer32, Gauge32, Counter32, Counter64, TimeTicks,
+    enterprises,
+        FROM SNMPv2-SMI
+
+    DisplayString
+        FROM SNMPv2-TC
+;
+
+
+freeswitch MODULE-IDENTITY
+    LAST-UPDATED    "201101170000Z"
+    ORGANIZATION    "www.freeswitch.org"
+    CONTACT-INFO
+        "Primary contact: Anthony Minessale II
+         Email: anthm@freeswitch.org"
+    DESCRIPTION
+        "This file defines the private FreeSWITCH SNMP MIB extensions."
+    REVISION        "201101170000Z"
+    DESCRIPTION
+        "First draft by daniel.swarbrick@seventhsignal.de"
+    ::= { enterprises 27880 }
+
+
+core        OBJECT IDENTIFIER ::= { freeswitch 1 }
+mod-sofia   OBJECT IDENTIFIER ::= { freeswitch 1001 }
+mod-skinny  OBJECT IDENTIFIER ::= { freeswitch 1002 }
+
+
+identity    OBJECT IDENTIFIER ::= { core 1 }
+
+versionString OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "FreeSWITCH version as a string"
+    ::= { identity 1 } 
+
+uuid OBJECT-TYPE
+    SYNTAX      DisplayString
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "FreeSWITCH core UUID"
+    ::= { identity 2 } 
+
+
+systemStats OBJECT IDENTIFIER ::= { core 2 }
+
+uptime OBJECT-TYPE
+    SYNTAX      TimeTicks
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "FreeSWITCH process uptime in hundredths of seconds"
+    ::= { systemStats 1 }
+
+sessionsSinceStartup OBJECT-TYPE
+    SYNTAX      Counter32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Number of sessions since FreeSWITCH process was started"
+    ::= { systemStats 2 }
+
+currentSessions OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Currently active sessions"
+    ::= { systemStats 3 }
+
+maxSessions OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Maximum permissible active sessions"
+    ::= { systemStats 4 }
+
+currentCalls OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Currently active calls"
+    ::= { systemStats 5 }
+
+sessionsPerSecond OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Current sessions per second"
+    ::= { systemStats 6 }
+
+maxSessionsPerSecond OBJECT-TYPE
+    SYNTAX      Gauge32
+    MAX-ACCESS  read-only
+    STATUS      current
+    DESCRIPTION
+        "Maximum permissible sessions per second"
+    ::= { systemStats 7 }
+
+END
diff --git a/src/mod/event_handlers/mod_snmp/Makefile b/src/mod/event_handlers/mod_snmp/Makefile
new file mode 100644 (file)
index 0000000..1d8827d
--- /dev/null
@@ -0,0 +1,7 @@
+include ../../../../build/modmake.rules
+
+LOCAL_CFLAGS=-I `net-snmp-config --cflags`
+LOCAL_LDFLAGS=`net-snmp-config --agent-libs`
+LOCAL_OBJS=subagent.o
+
+local_depend: $(LOCAL_OBJS)
diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c
new file mode 100644 (file)
index 0000000..040e82b
--- /dev/null
@@ -0,0 +1,138 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Swarbrick <daniel.swarbrick@seventhsignal.de>
+ * Stefan Knoblich <s.knoblich@axsentis.de>
+ * 
+ * mod_snmp.c -- SNMP AgentX Subagent Module
+ *
+ */
+#include <switch.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+
+#include "subagent.h"
+
+static struct {
+       switch_memory_pool_t *pool;
+       int shutdown;
+} globals;
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load);
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown);
+SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime);
+SWITCH_MODULE_DEFINITION(mod_snmp, mod_snmp_load, mod_snmp_shutdown, mod_snmp_runtime);
+
+
+static int snmp_callback_log(int major, int minor, void *serverarg, void *clientarg)
+{
+       struct snmp_log_message *slm = (struct snmp_log_message *) serverarg;
+       switch_log_printf(SWITCH_CHANNEL_LOG, slm->priority, "%s", slm->msg);
+       return SNMP_ERR_NOERROR;
+}
+
+
+static switch_state_handler_table_t state_handlers = {
+       /*.on_init */ NULL,
+       /*.on_routing */ NULL,
+       /*.on_execute */ NULL,
+       /*.on_hangup */ NULL,
+       /*.on_exchange_media */ NULL,
+       /*.on_soft_execute */ NULL,
+       /*.on_consume_media */ NULL,
+       /*.on_hibernate */ NULL,
+       /*.on_reset */ NULL,
+       /*.on_park */ NULL,
+       /*.on_reporting */ NULL
+};
+
+
+static switch_status_t load_config(switch_memory_pool_t *pool)
+{
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+       memset(&globals, 0, sizeof(globals));
+       globals.pool = pool;
+
+       return status;
+}
+
+
+SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load)
+{
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+
+       load_config(pool);
+
+       switch_core_add_state_handler(&state_handlers);
+       *module_interface = switch_loadable_module_create_module_interface(pool, modname);
+
+       /* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */
+       snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, snmp_callback_log, NULL);
+       snmp_enable_calllog();
+
+       netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1);
+       netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1);
+
+       init_agent("mod_snmp");
+       init_subagent();  
+       init_snmp("mod_snmp");
+
+       return status;
+}
+
+
+SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime)
+{
+       /* block on select() */
+       agent_check_and_process(1);
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown)
+{
+       globals.shutdown = 1;
+       switch_core_remove_state_handler(&state_handlers);
+
+       snmp_shutdown("mod_snmp");
+
+       return SWITCH_STATUS_SUCCESS;
+}
+
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c
new file mode 100644 (file)
index 0000000..8a9f2da
--- /dev/null
@@ -0,0 +1,189 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2011, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthm@freeswitch.org>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Daniel Swarbrick <daniel.swarbrick@seventhsignal.de>
+ * Stefan Knoblich <s.knoblich@axsentis.de>
+ * 
+ * mod_snmp.c -- SNMP AgentX Subagent Module
+ *
+ */
+#include <switch.h>
+#include <switch_version.h>
+
+#include <net-snmp/net-snmp-config.h>
+#include <net-snmp/net-snmp-includes.h>
+#include <net-snmp/agent/net-snmp-agent-includes.h>
+#include "subagent.h"
+
+
+static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 };
+static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 };
+
+/* identity sub-IDs - these must match MIB */
+enum {
+       versionString_oid = 1,
+       uuid_oid
+};
+
+
+/* systemStats sub-IDs - these must match MIB */
+enum {
+       uptime_oid = 1,
+       sessionsSinceStartup_oid,
+       currentSessions_oid,
+       maxSessions_oid,
+       currentCalls_oid,
+       sessionsPerSecond_oid,
+       maxSessionsPerSecond_oid
+};
+
+
+void init_subagent(void)
+{
+       DEBUGMSGTL(("init_nstAgentSubagentObject", "Initializing\n"));
+
+       netsnmp_register_handler(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY));
+       netsnmp_register_handler(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY));
+}
+
+
+int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests)
+{
+       static char const version[] = SWITCH_VERSION_FULL;
+       char uuid[40] = "";
+       netsnmp_request_info *request = NULL;
+       oid subid;
+
+       switch(reqinfo->mode) {
+               case MODE_GET:
+                       for (request = requests; request; request = request->next) {
+                               subid = request->requestvb->name[OID_LENGTH(systemStats_oid)];
+
+                               switch (subid) {
+                                       case versionString_oid:
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version));
+                                               break;
+                                       case uuid_oid:
+                                               strncpy(uuid, switch_core_get_uuid(), sizeof(uuid));
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid));
+                                               break;
+                                       default:
+                                               snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
+                                               netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+                               }
+                       }
+                       break;
+
+               case MODE_GETNEXT:
+                       snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n");
+                       break;
+
+               default:
+                       /* we should never get here, so this is a really bad error */
+                       snmp_log(LOG_ERR, "Unknown mode (%d) in handle_versionString\n", reqinfo->mode );
+                       return SNMP_ERR_GENERR;
+       }
+
+       return SNMP_ERR_NOERROR;
+}
+
+
+int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests)
+{
+       netsnmp_request_info *request = NULL;
+       oid subid;
+       switch_time_t uptime;
+       uint32_t int_val;
+
+       switch(reqinfo->mode) {
+               case MODE_GET:
+                       for (request = requests; request; request = request->next) {
+                               subid = request->requestvb->name[OID_LENGTH(systemStats_oid)];
+
+                               switch (subid) {
+                                       case uptime_oid:
+                                               uptime = switch_core_uptime() / 10000;
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime));
+                                               break;
+                                       case sessionsSinceStartup_oid:
+                                               int_val = switch_core_session_id() - 1;
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val));
+                                               break;
+                                       case currentSessions_oid:
+                                               int_val = switch_core_session_count();
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+                                               break;
+                                       case maxSessions_oid:
+                                               switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);;
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+                                               break;
+                                       case currentCalls_oid:
+                                               /*
+                                                * This is zero for now, since there is no convenient way to get total call
+                                                * count (not to be confused with session count), without touching the
+                                                * database.
+                                                */
+                                               int_val = 0;
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+                                               break;
+                                       case sessionsPerSecond_oid:
+                                               switch_core_session_ctl(SCSC_LAST_SPS, &int_val);
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+                                               break;
+                                       case maxSessionsPerSecond_oid:
+                                               switch_core_session_ctl(SCSC_SPS, &int_val);
+                                               snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val));
+                                               break;
+                                       default:
+                                               snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid);
+                                               netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
+                               }
+                       }
+                       break;
+
+               case MODE_GETNEXT:
+                       snmp_log(LOG_ERR, "MODE_GETNEXT not supported (yet)\n");
+                       break;
+
+               default:
+                       /* we should never get here, so this is a really bad error */
+                       snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode);
+                       return SNMP_ERR_GENERR;
+       }
+
+       return SNMP_ERR_NOERROR;
+}
+
+
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4:
+ */
diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h
new file mode 100644 (file)
index 0000000..8a57d8a
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef subagent_H
+#define subagent_H
+
+void init_subagent(void);
+Netsnmp_Node_Handler handle_identity;
+Netsnmp_Node_Handler handle_systemStats;
+
+#endif /* subagent_H */