aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp/src/app')
-rw-r--r--lib/snmp/src/app/Makefile141
-rw-r--r--lib/snmp/src/app/depend.mk29
-rw-r--r--lib/snmp/src/app/modules.mk28
-rw-r--r--lib/snmp/src/app/snmp.app.src134
-rw-r--r--lib/snmp/src/app/snmp.appup.src73
-rw-r--r--lib/snmp/src/app/snmp.config154
-rw-r--r--lib/snmp/src/app/snmp.erl939
-rw-r--r--lib/snmp/src/app/snmp_app.erl175
-rw-r--r--lib/snmp/src/app/snmp_app_sup.erl119
-rw-r--r--lib/snmp/src/app/snmp_internal.hrl40
10 files changed, 1832 insertions, 0 deletions
diff --git a/lib/snmp/src/app/Makefile b/lib/snmp/src/app/Makefile
new file mode 100644
index 0000000000..d89eb4e723
--- /dev/null
+++ b/lib/snmp/src/app/Makefile
@@ -0,0 +1,141 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2003-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# 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.
+#
+# %CopyrightEnd%
+
+include $(ERL_TOP)/make/target.mk
+
+EBIN = ../../ebin
+
+include $(ERL_TOP)/make/$(TARGET)/otp.mk
+
+# ----------------------------------------------------
+# Application version
+# ----------------------------------------------------
+include ../../vsn.mk
+
+VSN = $(SNMP_VSN)
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
+
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+include modules.mk
+
+ERL_FILES = $(MODULES:%=%.erl)
+
+HRL_FILES = $(HRLS:%=%.hrl)
+
+TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+EXT_HRL_FILES = \
+ ../../include/snmp_types.hrl \
+ ../../include/snmp_tables.hrl
+
+APP_FILE = snmp.app
+APPUP_FILE = snmp.appup
+
+APP_SRC = $(APP_FILE).src
+APP_TARGET = $(EBIN)/$(APP_FILE)
+
+APPUP_SRC = $(APPUP_FILE).src
+APPUP_TARGET = $(EBIN)/$(APPUP_FILE)
+
+# ----------------------------------------------------
+# SNMP FLAGS
+# ----------------------------------------------------
+ifeq ($(SNMP_DEFAULT_VERBOSITY),)
+ SNMP_FLAGS = -Ddefault_verbosity=silence
+else
+ SNMP_FLAGS = -Ddefault_verbosity=$(SNMP_DEFAULT_VERBOSITY)
+endif
+
+ifeq ($(SNMP_DEBUG),d)
+ SNMP_FLAGS += -Dsnmp_debug
+endif
+
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ifeq ($(WARN_UNUSED_VARS),true)
+ERL_COMPILE_FLAGS += +warn_unused_vars
+endif
+
+ERL_COMPILE_FLAGS += -I../misc \
+ -Dversion=\"$(VSN)$(PRE_VSN)\" \
+ +'{parse_transform,sys_pre_attributes}' \
+ +'{attribute,insert,app_vsn,$(APP_VSN)}' \
+ -I$(ERL_TOP)/lib/stdlib \
+ $(SNMP_FLAGS)
+
+# ----------------------------------------------------
+# Targets
+# ----------------------------------------------------
+
+debug:
+ @$(MAKE) TYPE=debug opt
+
+opt: $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
+
+
+clean:
+ rm -f $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET)
+ rm -f core *~
+
+docs:
+
+info:
+ @echo "VSN: $(VSN)"
+ @echo "APP_VSN: $(APP_VSN)"
+
+
+# ----------------------------------------------------
+# Special Build Targets
+# ----------------------------------------------------
+
+$(APP_TARGET): $(APP_SRC) ../../vsn.mk
+ sed -e 's;%VSN%;$(VSN);' $< > $@
+
+$(APPUP_TARGET): $(APPUP_SRC) ../../vsn.mk
+ sed -e 's;%VSN%;$(VSN);' $< > $@
+
+# ----------------------------------------------------
+# Release Target
+# ----------------------------------------------------
+include $(ERL_TOP)/make/otp_release_targets.mk
+
+release_spec: opt
+ $(INSTALL_DIR) $(RELSYSDIR)/src
+ $(INSTALL_DIR) $(RELSYSDIR)/src/app
+ $(INSTALL_DATA) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)/src/app
+ $(INSTALL_DIR) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(TARGET_FILES) $(APP_TARGET) $(APPUP_TARGET) \
+ $(RELSYSDIR)/ebin
+ $(INSTALL_DIR) $(RELSYSDIR)/include
+ $(INSTALL_DATA) $(EXT_HRL_FILES) $(RELSYSDIR)/include
+
+release_docs_spec:
+
+include depend.mk
diff --git a/lib/snmp/src/app/depend.mk b/lib/snmp/src/app/depend.mk
new file mode 100644
index 0000000000..1080cb5693
--- /dev/null
+++ b/lib/snmp/src/app/depend.mk
@@ -0,0 +1,29 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# 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.
+#
+# %CopyrightEnd%
+
+$(EBIN)/snmp.$(EMULATOR): \
+ snmp.erl
+
+$(EBIN)/snmp_app.$(EMULATOR): \
+ snmp_app.erl
+
+$(EBIN)/snmp_app_sup.$(EMULATOR): \
+ snmp_app_sup.erl
+
+
diff --git a/lib/snmp/src/app/modules.mk b/lib/snmp/src/app/modules.mk
new file mode 100644
index 0000000000..678f15de5c
--- /dev/null
+++ b/lib/snmp/src/app/modules.mk
@@ -0,0 +1,28 @@
+#-*-makefile-*- ; force emacs to enter makefile-mode
+
+# %CopyrightBegin%
+#
+# Copyright Ericsson AB 2004-2009. All Rights Reserved.
+#
+# The contents of this file are subject to the Erlang Public License,
+# Version 1.1, (the "License"); you may not use this file except in
+# compliance with the License. You should have received a copy of the
+# Erlang Public License along with this software. If not, it can be
+# retrieved online at http://www.erlang.org/.
+#
+# 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.
+#
+# %CopyrightEnd%
+
+MODULES = \
+ snmp \
+ snmp_app \
+ snmp_app_sup
+
+HRLS = \
+ snmp_internal
+
+
diff --git a/lib/snmp/src/app/snmp.app.src b/lib/snmp/src/app/snmp.app.src
new file mode 100644
index 0000000000..a880a14696
--- /dev/null
+++ b/lib/snmp/src/app/snmp.app.src
@@ -0,0 +1,134 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+{application, snmp,
+ [{description, "SNMP CXC 138 13"},
+ {vsn, "%VSN%"},
+ {modules, [
+ %% Compiler modules (not in the runtime part of the app)
+% snmpc,
+% snmpc_lib,
+% snmpc_mib_gram,
+% snmpc_mib_to_hrl,
+% snmpc_misc,
+% snmpc_tok,
+
+ %% Application modules
+ snmp,
+ snmp_app,
+ snmp_app_sup,
+
+ %% Agent modules
+ snmpa,
+ snmpa_acm,
+ snmpa_agent,
+ snmpa_agent_sup,
+ snmpa_app,
+ snmpa_authentication_service,
+ snmpa_conf,
+ snmpa_error,
+ snmpa_discovery_handler,
+ snmpa_discovery_handler_default,
+ snmpa_error_io,
+ snmpa_error_logger,
+ snmpa_error_report,
+ snmpa_general_db,
+ snmpa_local_db,
+ snmpa_mib,
+ snmpa_mib_data,
+ snmpa_mib_lib,
+ snmpa_misc_sup,
+ snmpa_mpd,
+ snmpa_net_if,
+ snmpa_net_if_filter,
+ snmpa_network_interface,
+ snmpa_network_interface_filter,
+ snmpa_notification_delivery_info_receiver,
+ snmpa_notification_filter,
+ snmpa_set,
+ snmpa_set_lib,
+ snmpa_set_mechanism,
+ snmpa_supervisor,
+ snmpa_svbl,
+ snmpa_symbolic_store,
+ snmpa_target_cache,
+ snmpa_trap,
+ snmpa_usm,
+ snmpa_vacm,
+ snmp_community_mib,
+ snmp_framework_mib,
+ snmp_generic,
+ snmp_generic_mnesia,
+ snmp_index,
+ snmp_notification_mib,
+ snmp_shadow_table,
+ snmp_standard_mib,
+ snmp_target_mib,
+ snmp_user_based_sm_mib,
+ snmp_view_based_acm_mib,
+
+ %% Manager modules:
+ snmpm,
+ snmpm_conf,
+ snmpm_config,
+ snmpm_misc_sup,
+ snmpm_mpd,
+ snmpm_net_if,
+ snmpm_net_if_filter,
+ snmpm_network_interface,
+ snmpm_network_interface_filter,
+ snmpm_server,
+ snmpm_server_sup,
+ snmpm_supervisor,
+ snmpm_user,
+ snmpm_user_default,
+ snmpm_user_old,
+ snmpm_usm,
+
+ %% Misc modules
+ snmp_conf,
+ snmp_config,
+ snmp_log,
+ snmp_mini_mib,
+ snmp_misc,
+ snmp_note_store,
+ snmp_pdus,
+ snmp_usm,
+ snmp_verbosity
+
+ ]},
+ %% Which registered process exist depend on the configuration:
+ %% If an agent is configured, then the following processes is
+ %% also started: snmp_agent_sup, snmp_local_db, snmp_master_agent,
+ %% snmp_misc_sup, snmpa_supervisor and
+ %% snmp_symbolic_store
+ %% If an manager is configured, the the following processes is
+ %% also started: snmpm_supervisor, snmpm_config, snmpm_server,
+ %% snmpm_net_if
+ %%
+ %%
+ {registered, [snmp_app_sup]},
+ {env, []},
+ %% If v3 authentication or encryption is used, 'crypto' must be started
+ %% before snmp.
+ %% The SNMP application _may_ also depend on mnesia (depends on the
+ %% configuration and use), and in that case mnesia must also be started,
+ %% before snmp.
+ {applications, [kernel, stdlib]},
+ {mod, {snmp_app, []}}]}.
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
new file mode 100644
index 0000000000..3abce3d759
--- /dev/null
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -0,0 +1,73 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+{"%VSN%",
+
+%% ----- U p g r a d e -------------------------------------------------------
+
+ [
+ {"4.14",
+ [
+ {load_module, snmpm_user, soft_purge, soft_purge, []},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_user_default]}
+ ]
+ },
+ {"4.13.5",
+ [
+ {load_module, snmpm_user, soft_purge, soft_purge, []},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
+ {load_module, snmpa_mib_data, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {update, snmpa_net_if, soft, soft_purge, soft_purge, []},
+ {update, snmpm_config, soft, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]},
+ {add_module, snmpm_net_if_filter},
+ {add_module, snmpm_network_interface_filter}
+ ]
+ }
+ ],
+
+%% ------D o w n g r a d e ---------------------------------------------------
+
+ [
+ {"4.14",
+ [
+ {load_module, snmpm_user, soft_purge, soft_purge, []},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]}
+ ]
+ },
+ {"4.13.5",
+ [
+ {load_module, snmpm_user, soft_purge, soft_purge, []},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
+ {load_module, snmpa_mib_data, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {update, snmpa_net_if, soft, soft_purge, soft_purge, []},
+ {update, snmpm_config, soft, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user_default]},
+ {remove, {snmpm_net_if_filter, soft_purge, brutal_purge}},
+ {remove, {snmpm_network_interface_filter, soft_purge, brutal_purge}}
+ ]
+ }
+ ]
+}.
+
diff --git a/lib/snmp/src/app/snmp.config b/lib/snmp/src/app/snmp.config
new file mode 100644
index 0000000000..b66ef5d7df
--- /dev/null
+++ b/lib/snmp/src/app/snmp.config
@@ -0,0 +1,154 @@
+%% Example snmp (node) config file
+%% [{snmp, [snmp_app()]
+%% snmp_app() -> {agent, agent_opts()} | {manager, manager_opts()}
+%%
+%% -- Agent types --
+%% agent_opts() -> [agent_opt()]
+%% agent_opt() -> {agent_type, agent_type()} |
+%% {agent_verbosity, verbosity()} |
+%% {versions, versions()} |
+%% {priority, atom()} |
+%% {set_mechanism, module()} |
+%% {authentication_service, module()} |
+%% {multi_threaded, bool()} |
+%% {db_dir, dir()} |
+%% {local_db, local_db_opts()} |
+%% {net_if, net_if_opts()} |
+%% {mibs, [string()]} |
+%% {mib_storage, mib_storage()} |
+%% {mib_server, mib_server_opts()} |
+%% {audit_trail_log, audit_trail_log_opts()} |
+%% {error_report_mod, module()} |
+%% {note_store, note_store_opts()} |
+%% {symbolic_store, symbolic_store_opts()} |
+%% {config, config_opts()}
+%% {supervisor, supervisor_opts()}
+%% agent_type() -> master | sub
+%% local_db_opts() -> [local_db_opt()]
+%% local_db_opt() -> {repair, repair()} |
+%% {auto_save, auto_save()} |
+%% {verbosity, verbosity()}
+%% repair() -> true | false | force
+%% auto_save() -> integer() | infinity
+%% net_if_opts() -> [net_if_opt()]
+%% net_if_opt() -> {module, atom()} |
+%% {verbosity, verbosity()} |
+%% {options, net_if_options()}
+%% net_if_options() -> [net_if_option()]
+%% net_if_option() -> Note that these are basically dependant on which net-if
+%% module is beeing used, but the options described here
+%% are the ones that snmp_net_if (the default value for
+%% the module option) handles:
+%% {bind_to, bool()} |
+%% {recbuf, integer()} |
+%% {no_reuse, bool()}
+%% {req_limit, integer() | infinity}
+%% mib_server_opts() -> [mib_server_opt()]
+%% mib_server_opt() -> {mibentry_override, bool()} |
+%% {trapentry_override, bool()} |
+%% {verbosity, verbosity()}
+%% mib_storage() -> ets |
+%% {dets, dir()} | {dets, dir(), action()} |
+%% {mnesia, [node()]} |
+%% {mnesia, [node()], action()} |
+%% action() -> clear | keep
+%% symbolic_store_opts() -> [symbolic_store_opt()]
+%% symbolic_store_opt() -> {verbosity, verbosity()}
+%% supervisor_opts() -> [supervisor_opt()]
+%% supervisor_opt() -> {verbosity, verbosity()}
+%% config_opts() -> [config_opt()]
+%% config_opt() -> {dir, dir()} |
+%% {force_load, bool()} |
+%% {verbosity, verbosity()}
+%%
+%%
+%% -- Manager types --
+%% manager_options() -> [manager_option()]
+%% manager_option() -> {net_if, mgr_net_if_opts()} |
+%% {note_store, note_store_opts()} |
+%% {config, mgr_config_opts()} |
+%% {mibs, [string()]} |
+%% {priority, priority()} |
+%% {audit_trail_log, audit_trail_log_opts()} |
+%% {versions, versions()}
+%% mgr_net_if_opts() -> [mgr_net_if_opt()]
+%% mgr_net_if_opt() -> {module, atom()} |
+%% {verbosity, verbosity()} |
+%% {options, mgr_net_if_options()}
+%% mgr_net_if_options() -> [mgr_net_if_option()]
+%% mgr_net_if_option() -> Note that these are basically dependant on which
+%% net-if module is beeing used, but the options
+%% described here are the ones of the snmpm_net_if
+%% (the default value for the module option):
+%% {recbuf, integer()} |
+%% {bind_to, bool()} |
+%% {no_reuse, bool()}
+%% mgr_config_opts() -> {dir, dir()} |
+%% {verbosity, verbosity()}
+%%
+%% -- Common types --
+%% module() -> atom()
+%% verbosity() -> silence | info | log | debug | trace
+%% versions() -> [version()]
+%% version() -> v1 | v2 | v3
+%% audit_trail_log_opts() -> [audit_trail_log_opt()]
+%% audit_trail_log_opt() -> {type, atl_type()} |
+%% {dir, atl_dir()} |
+%% {size, atl_size()} |
+%% {repair, atl_repair()}
+%% atl_type() -> read | write | read_write
+%% atl_dir() -> dir()
+%% atl_size() -> {max_bytes(), max_files()}
+%% atl_repair() -> true | false | truncate
+%% max_bytes() -> integer()
+%% max_files() -> integer()
+%% dir() -> string()
+%% note_store_opts() -> [note_store_opt()]
+%% note_store_opt() -> {verbosity, verbosity()} |
+%% {timeout, integer()}
+%%
+
+[{snmp,
+ [
+ {agent,
+ [{agent_type, master},
+ {agent_verbosity, trace},
+ {priority, normal},
+ {versions, [v1,v2,v3]},
+ {multi_threaded, true},
+ {config, [{verbosity, trace},
+ {dir, "/ldisk/snmp/agent/conf"},
+ {force_load, true}]},
+ {db_dir, "/ldisk/snmp/agent/db"},
+ {local_db, [{repair, true},
+ {verbosity, silence}]},
+ {net_if,
+ [{module, snmp_net_if},
+ {verbosity, log},
+ {options, [{recbuf, 10240}, {req_limit, 32}]}]},
+ {audit_trail_log, [{type, read_write_log},
+ {dir, "/ldisk/snmp/agent/log"}]},
+ {mib_storage, {dets, "/ldisk/snmp/agent/mibs", clear}},
+ {mib_server, [{mibentry_override,true},
+ {trapentry_override,true},
+ {verbosity,info}]}
+ ]
+ },
+ {manager,
+ [{priority, normal},
+ {versions, [v1,v2,v3]},
+ {config, [{dir, "/ldisk/snmp/manager/conf"},
+ {verbosity, trace}]},
+ {server, [{verbosity, trace}]},
+ {net_if,
+ [{module, snmpm_net_if},
+ {verbosity, log},
+ {options, [{recbuf, 10240}]}]},
+ {audit_trail_log, [{dir, "/ldisk/snmp/manager/log"},
+ {size, {10,10240}},
+ {repair, true}]}
+ ]
+ }
+ ]
+ }
+].
diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl
new file mode 100644
index 0000000000..3e0f05e604
--- /dev/null
+++ b/lib/snmp/src/app/snmp.erl
@@ -0,0 +1,939 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(snmp).
+
+
+%%----------------------------------------------------------------------
+%% This module contains the user interface to the snmp toolkit.
+%%----------------------------------------------------------------------
+
+%% Application exports
+-export([start/0, start/1, stop/0,
+ start_agent/0, start_agent/1,
+ start_manager/0, start_manager/1,
+ config/0,
+
+ versions1/0, versions2/0,
+ print_versions/1, print_versions/2,
+ print_version_info/0, print_version_info/1,
+
+ date_and_time/0,
+ universal_time_to_date_and_time/1,
+ local_time_to_date_and_time_dst/1,
+ date_and_time_to_universal_time_dst/1,
+ validate_date_and_time/1, validate_date_and_time/2,
+ date_and_time_to_string/1, date_and_time_to_string/2,
+ date_and_time_to_string2/1,
+
+ str_apply/1,
+
+ sys_up_time/1, system_start_time/1,
+
+ passwd2localized_key/3, localize_key/3,
+
+ read_mib/1,
+
+ log_to_txt/5, log_to_txt/6, log_to_txt/7,
+ change_log_size/2,
+
+ octet_string_to_bits/1, bits_to_octet_string/1,
+
+ enable_trace/0, disable_trace/0,
+ set_trace/1, reset_trace/1,
+ set_trace/2, set_trace/3]).
+
+%% Compiler exports
+-export([c/1, c/2, is_consistent/1, mib_to_hrl/1,
+ compile/3]).
+
+%% Agent exports (Dont use these, they will be removed eventually)
+-export([current_request_id/0, current_community/0, current_address/0,
+ current_context/0, current_net_if_data/0,
+
+ get_symbolic_store_db/0,
+ name_to_oid/1, name_to_oid/2,
+ oid_to_name/1, oid_to_name/2,
+ int_to_enum/2, int_to_enum/3,
+ enum_to_int/2, enum_to_int/3,
+
+ get/2,
+ info/1,
+ load_mibs/2, unload_mibs/2, dump_mibs/0, dump_mibs/1,
+
+ register_subagent/3, unregister_subagent/2,
+
+ send_notification/3, send_notification/4, send_notification/5,
+ send_notification/6,
+ send_trap/3, send_trap/4,
+
+ add_agent_caps/2, del_agent_caps/1, get_agent_caps/0,
+
+ log_to_txt/2, log_to_txt/3, log_to_txt/4,
+ change_log_size/1
+
+ ]).
+
+%% This is for XREF
+-deprecated([{c, 1, eventually},
+ {c, 2, eventually},
+ {compile, 3, eventually},
+ {is_consistent, 1, eventually},
+ {mib_to_hrl, 1, eventually},
+
+ {change_log_size, 1, eventually},
+ {log_to_txt, 2, eventually},
+ {log_to_txt, 3, eventually},
+ {log_to_txt, 4, eventually},
+
+ {current_request_id, 0, eventually},
+ {current_community, 0, eventually},
+ {current_address, 0, eventually},
+ {current_context, 0, eventually},
+ {current_net_if_data, 0, eventually},
+
+ {get_symbolic_store_db, 0, eventually},
+ {name_to_oid, 1, eventually},
+ {name_to_oid, 2, eventually},
+ {oid_to_name, 1, eventually},
+ {oid_to_name, 2, eventually},
+ {int_to_enum, 2, eventually},
+ {int_to_enum, 3, eventually},
+ {enum_to_int, 2, eventually},
+ {enum_to_int, 3, eventually},
+
+ {get, 2, eventually},
+ {info, 1, eventually},
+ {load_mibs, 2, eventually},
+ {unload_mibs, 2, eventually},
+ {dump_mibs, 0, eventually},
+ {dump_mibs, 1, eventually},
+
+ {register_subagent, 3, eventually},
+ {unregister_subagent, 2, eventually},
+
+ {send_notification, 3, eventually},
+ {send_notification, 4, eventually},
+ {send_notification, 5, eventually},
+ {send_notification, 6, eventually},
+ {send_trap, 3, eventually},
+ {send_trap, 4, eventually},
+
+ {add_agent_caps, 2, eventually},
+ {del_agent_caps, 1, eventually},
+ {get_agent_caps, 0, eventually}]).
+
+
+-define(APPLICATION, snmp).
+
+
+%%-----------------------------------------------------------------
+%% Application
+%%-----------------------------------------------------------------
+
+start() ->
+ application:start(?APPLICATION).
+
+stop() ->
+ application:stop(?APPLICATION).
+
+start(p) ->
+ start(permanent);
+start(tr) ->
+ start(transient);
+start(te) ->
+ start(temporary);
+start(Type) ->
+ application:start(?APPLICATION, Type).
+
+
+start_agent() ->
+ snmp_app:start_agent().
+
+start_agent(Type) ->
+ snmp_app:start_agent(Type).
+
+start_manager() ->
+ snmp_app:start_manager().
+
+start_manager(Type) ->
+ snmp_app:start_manager(Type).
+
+
+config() -> snmp_config:config().
+
+
+%%-----------------------------------------------------------------
+
+enable_trace() ->
+ HandleSpec = {fun handle_trace_event/2, dummy},
+ dbg:tracer(process, HandleSpec).
+
+disable_trace() ->
+ dbg:stop().
+
+set_trace(Module) when is_atom(Module) ->
+ set_trace([Module]);
+set_trace(Modules) when is_list(Modules) ->
+ Opts = [], % Use default values for all options
+ set_trace(Modules, Opts).
+
+reset_trace(Module) when is_atom(Module) ->
+ set_trace(Module, disable);
+reset_trace(Modules) when is_list(Modules) ->
+ set_trace(Modules, disable).
+
+set_trace(Module, disable) when is_atom(Module) ->
+ dbg:ctp(Module);
+set_trace(Module, Opts) when is_atom(Module) andalso is_list(Opts) ->
+ (catch set_trace(all, Module, Opts));
+set_trace(Modules, Opts) when is_list(Modules) ->
+ (catch set_trace(all, Modules, Opts)).
+
+set_trace(Item, Module, Opts) when is_atom(Module) ->
+ set_trace(Item, [{Module, []}], Opts);
+set_trace(_Item, Modules, disable) when is_list(Modules) ->
+ DisableTrace =
+ fun(Module) when is_atom(Module) ->
+ dbg:ctp(Module);
+ (_) ->
+ ok
+ end,
+ lists:foreach(DisableTrace, Modules);
+set_trace(Item, Modules, Opts) when is_list(Modules) ->
+ Mods = parse_modules(Modules, Opts),
+ SetTrace =
+ fun({Module, ModOpts}) ->
+ set_module_trace(Module, ModOpts)
+ end,
+ lists:foreach(SetTrace, Mods),
+ Flags =
+ case lists:keysearch(timestamp, 1, Opts) of
+ {value, {timestamp, false}} ->
+ [call];
+ _ ->
+ [call, timestamp]
+ end,
+ case dbg:p(Item, Flags) of
+ {ok, _} ->
+ ok;
+ Error ->
+ Error
+ end.
+
+set_module_trace(Module, disable) ->
+ dbg:ctp(Module);
+set_module_trace(Module, Opts) ->
+ ReturnTrace =
+ case lists:keysearch(return_trace, 1, Opts) of
+ {value, {return_trace, false}} ->
+ [];
+ _ ->
+ %% Default is allways to include return values
+ [{return_trace}]
+ end,
+ TraceRes =
+ case lists:keysearch(scope, 1, Opts) of
+ {value, {scope, all_functions}} ->
+ dbg:tpl(Module, [{'_', [], ReturnTrace}]);
+ {value, {scope, exported_functions}} ->
+ dbg:tp(Module, [{'_', [], ReturnTrace}]);
+ {value, {scope, Func}} when is_atom(Func) ->
+ dbg:tpl(Module, Func, [{'_', [], ReturnTrace}]);
+ {value, {scope, {Func, Arity}}} when is_atom(Func) andalso
+ is_integer(Arity) ->
+ dbg:tpl(Module, Func, Arity, [{'_', [], ReturnTrace}]);
+ false ->
+ %% Default scope is exported functions
+ dbg:tp(Module, [{'_', [], ReturnTrace}])
+ end,
+ case TraceRes of
+ {error, Reason} ->
+ throw({error, {failed_enabling_trace, Module, Opts, Reason}});
+ _ ->
+ ok
+ end.
+
+
+parse_modules(Modules, Opts) ->
+ parse_modules(Modules, Opts, []).
+
+parse_modules([], _Opts, Acc) ->
+ lists:reverse(Acc);
+
+parse_modules([Module|Modules], Opts, Acc)
+ when is_atom(Module) andalso is_list(Opts) ->
+ parse_modules(Modules, Opts, [{Module, Opts}|Acc]);
+
+parse_modules([{Module, ModOpts}|Modules], Opts, Acc)
+ when is_atom(Module) andalso is_list(ModOpts) andalso is_list(Opts) ->
+ NewModOpts = update_trace_options(Opts, ModOpts),
+ parse_modules(Modules, Opts, [{Module, NewModOpts}|Acc]);
+
+parse_modules([_|Modules], Opts, Acc) ->
+ parse_modules(Modules, Opts, Acc).
+
+
+update_trace_options([], Opts) ->
+ Opts;
+update_trace_options([{Key, _} = Opt|Opts], ModOpts) ->
+ case lists:keysearch(Key, 1, ModOpts) of
+ {value, _} ->
+ update_trace_options(Opts, ModOpts);
+ _ ->
+ update_trace_options(Opts, [Opt|ModOpts])
+ end;
+update_trace_options([_|Opts], ModOpts) ->
+ update_trace_options(Opts, ModOpts).
+
+
+handle_trace_event({trace, Who, call, Event}, Data) ->
+ io:format("*** call trace event *** "
+ "~n Who: ~p"
+ "~n Event: ~p"
+ "~n", [Who, Event]),
+ Data;
+handle_trace_event({trace, Who, return_from, Func, Value}, Data) ->
+ io:format("*** return trace event *** "
+ "~n Who: ~p"
+ "~n Function: ~p"
+ "~n Value: ~p"
+ "~n", [Who, Func, Value]),
+ Data;
+handle_trace_event({trace_ts, Who, call, {Mod, Func, Args}, Ts}, Data)
+ when is_atom(Mod) andalso is_atom(Func) andalso is_list(Args) ->
+ io:format("*** call trace event ~s *** "
+ "~n Who: ~p"
+ "~n Mod: ~p"
+ "~n Func: ~p"
+ "~n Args: ~p"
+ "~n", [format_timestamp(Ts), Who, Mod, Func, Args]),
+ Data;
+handle_trace_event({trace_ts, Who, call, Event, Ts}, Data) ->
+ io:format("*** call trace event ~s *** "
+ "~n Who: ~p"
+ "~n Event: ~p"
+ "~n", [format_timestamp(Ts), Who, Event]),
+ Data;
+handle_trace_event({trace_ts, Who, return_from, {Mod, Func, Arity}, Value, Ts},
+ Data)
+ when is_atom(Mod) andalso is_atom(Func) andalso is_integer(Arity) ->
+ io:format("*** return trace event ~s *** "
+ "~n Who: ~p"
+ "~n Mod: ~p"
+ "~n Func: ~p"
+ "~n Arity: ~p"
+ "~n Value: ~p"
+ "~n", [format_timestamp(Ts), Who, Mod, Func, Arity, Value]),
+ Data;
+handle_trace_event({trace_ts, Who, return_from, Func, Value, Ts}, Data) ->
+ io:format("*** return trace event ~s *** "
+ "~n Who: ~p"
+ "~n Function: ~p"
+ "~n Value: ~p"
+ "~n", [format_timestamp(Ts), Who, Func, Value]),
+ Data;
+handle_trace_event(TraceEvent, Data) ->
+ io:format("*** trace event *** "
+ "~n TraceEvent: ~p"
+ "~n", [TraceEvent]),
+ Data.
+
+format_timestamp({_N1, _N2, N3} = Now) ->
+ {Date, Time} = calendar:now_to_datetime(Now),
+ {YYYY,MM,DD} = Date,
+ {Hour,Min,Sec} = Time,
+ FormatDate =
+ io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w",
+ [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]),
+ lists:flatten(FormatDate).
+
+
+%%-----------------------------------------------------------------
+%% {ok, Vs} = snmp:versions1(), snmp:print_versions(Vs).
+
+print_version_info() ->
+ {ok, Vs} = versions1(),
+ print_versions(Vs).
+
+print_version_info(Prefix) ->
+ {ok, Vs} = versions1(),
+ print_versions(Prefix, Vs).
+
+print_versions(Versions) ->
+ print_versions("", Versions).
+
+print_versions(Prefix, Versions)
+ when is_list(Prefix) andalso is_list(Versions) ->
+ do_print_versions(Prefix, Versions);
+print_versions(Prefix, Versions)
+ when (is_integer(Prefix) andalso (Prefix >= 0)) andalso is_list(Versions) ->
+ do_print_versions(lists:duplicate(Prefix, $ ), Versions);
+print_versions(Prefix, BadVersions)
+ when is_list(Prefix) orelse (is_integer(Prefix) andalso (Prefix >= 0)) ->
+ {error, {bad_versions, BadVersions}};
+print_versions(Prefix, BadVersions)
+ when is_list(BadVersions) ->
+ {error, {bad_prefix, Prefix}};
+print_versions(Prefix, BadVersions) ->
+ {error, {bad_args, Prefix, BadVersions}}.
+
+do_print_versions(Prefix, Versions) ->
+ print_sys_info(Prefix, Versions),
+ print_os_info(Prefix, Versions),
+ print_mods_info(Prefix, Versions).
+
+print_sys_info(Prefix, Versions) ->
+ case key1search(sys_info, Versions) of
+ {value, SysInfo} when is_list(SysInfo) ->
+ {value, Arch} = key1search(arch, SysInfo, "Not found"),
+ {value, Ver} = key1search(ver, SysInfo, "Not found"),
+ io:format("~sSystem info: "
+ "~n~s Arch: ~s"
+ "~n~s Ver: ~s"
+ "~n", [Prefix,
+ Prefix, Arch,
+ Prefix, Ver]),
+ ok;
+ _ ->
+ io:format("System info: Not found~n", []),
+ not_found
+ end.
+
+print_os_info(Prefix, Versions) ->
+ case key1search(os_info, Versions) of
+ {value, OsInfo} when is_list(OsInfo) ->
+ Fam =
+ case key1search(fam, OsInfo, "Not found") of
+ {value, F} when is_atom(F) ->
+ atom_to_list(F);
+ {value, LF} when is_list(LF) ->
+ LF;
+ {value, XF} ->
+ lists:flatten(io_lib:format("~p", [XF]))
+ end,
+ Name =
+ case key1search(name, OsInfo) of
+ {value, N} when is_atom(N) ->
+ "[" ++ atom_to_list(N) ++ "]";
+ {value, LN} when is_list(LN) ->
+ "[" ++ LN ++ "]";
+ not_found ->
+ ""
+ end,
+ Ver =
+ case key1search(ver, OsInfo, "Not found") of
+ {value, T} when is_tuple(T) ->
+ tversion(T);
+ {value, LV} when is_list(LV) ->
+ LV;
+ {value, XV} ->
+ lists:flatten(io_lib:format("~p", [XV]))
+ end,
+ io:format("~sOS info: "
+ "~n~s Family: ~s ~s"
+ "~n~s Ver: ~s"
+ "~n", [Prefix,
+ Prefix, Fam, Name,
+ Prefix, Ver]),
+ ok;
+ _ ->
+ io:format("~sOS info: Not found~n", [Prefix]),
+ not_found
+ end.
+
+tversion(T) ->
+ L = tuple_to_list(T),
+ lversion(L).
+
+lversion([]) ->
+ "";
+lversion([A]) ->
+ integer_to_list(A);
+lversion([A|R]) ->
+ integer_to_list(A) ++ "." ++ lversion(R).
+
+print_mods_info(Prefix, Versions) ->
+ case key1search(mod_info, Versions) of
+ {value, ModsInfo} when is_list(ModsInfo) ->
+ io:format("~sModule info: ~n", [Prefix]),
+ F = fun(MI) -> print_mod_info(Prefix, MI) end,
+ lists:foreach(F, ModsInfo);
+ _ ->
+ io:format("~sModule info: Not found~n", [Prefix]),
+ not_found
+ end.
+
+print_mod_info(Prefix, {Module, Info}) ->
+ Vsn =
+ case key1search(vsn, Info) of
+ {value, I} when is_integer(I) ->
+ integer_to_list(I);
+ _ ->
+ "Not found"
+ end,
+ AppVsn =
+ case key1search(app_vsn, Info) of
+ {value, S1} when is_list(S1) ->
+ S1;
+ _ ->
+ "Not found"
+ end,
+ CompVer =
+ case key1search(compiler_version, Info) of
+ {value, S2} when is_list(S2) ->
+ S2;
+ _ ->
+ "Not found"
+ end,
+ CompDate =
+ case key1search(compile_time, Info) of
+ {value, {Year, Month, Day, Hour, Min, Sec}} ->
+ lists:flatten(
+ io_lib:format("~w-~2..0w-~2..0w ~2..0w:~2..0w:~2..0w",
+ [Year, Month, Day, Hour, Min, Sec]));
+ _ ->
+ "Not found"
+ end,
+ io:format("~s ~w:~n"
+ "~s Vsn: ~s~n"
+ "~s App vsn: ~s~n"
+ "~s Compiler ver: ~s~n"
+ "~s Compile time: ~s~n",
+ [Prefix, Module,
+ Prefix, Vsn,
+ Prefix, AppVsn,
+ Prefix, CompVer,
+ Prefix, CompDate]),
+ ok.
+
+key1search(Key, Vals) ->
+ case lists:keysearch(Key, 1, Vals) of
+ {value, {Key, Val}} ->
+ {value, Val};
+ false ->
+ not_found
+ end.
+
+key1search(Key, Vals, Def) ->
+ case key1search(Key, Vals) of
+ not_found ->
+ {value, Def};
+ Value ->
+ Value
+ end.
+
+
+%%-----------------------------------------------------------------
+
+versions1() ->
+ case ms1() of
+ {ok, Mods} ->
+ {ok, version_info(Mods)};
+ Error ->
+ Error
+ end.
+
+versions2() ->
+ case ms2() of
+ {ok, Mods} ->
+ {ok, version_info(Mods)};
+ Error ->
+ Error
+ end.
+
+version_info(Mods) ->
+ SysInfo = sys_info(),
+ OsInfo = os_info(),
+ ModInfo = [mod_version_info(Mod) || Mod <- Mods],
+ [{sys_info, SysInfo}, {os_info, OsInfo}, {mod_info, ModInfo}].
+
+mod_version_info(Mod) ->
+ Info = Mod:module_info(),
+ {value, {attributes, Attr}} = lists:keysearch(attributes, 1, Info),
+ {value, {vsn, [Vsn]}} = lists:keysearch(vsn, 1, Attr),
+ {value, {app_vsn, AppVsn}} = lists:keysearch(app_vsn, 1, Attr),
+ {value, {compile, Comp}} = lists:keysearch(compile, 1, Info),
+ {value, {version, Ver}} = lists:keysearch(version, 1, Comp),
+ {value, {time, Time}} = lists:keysearch(time, 1, Comp),
+ {Mod, [{vsn, Vsn},
+ {app_vsn, AppVsn},
+ {compiler_version, Ver},
+ {compile_time, Time}]}.
+
+sys_info() ->
+ SysArch = string:strip(erlang:system_info(system_architecture),right,$\n),
+ SysVer = string:strip(erlang:system_info(system_version),right,$\n),
+ [{arch, SysArch}, {ver, SysVer}].
+
+os_info() ->
+ V = os:version(),
+ case os:type() of
+ {OsFam, OsName} ->
+ [{fam, OsFam}, {name, OsName}, {ver, V}];
+ OsFam ->
+ [{fam, OsFam}, {ver, V}]
+ end.
+
+ms1() ->
+ App = ?APPLICATION,
+ LibDir = code:lib_dir(App),
+ File = filename:join([LibDir, "ebin", atom_to_list(App) ++ ".app"]),
+ case file:consult(File) of
+ {ok, [{application, App, AppFile}]} ->
+ case lists:keysearch(modules, 1, AppFile) of
+ {value, {modules, Mods}} ->
+ {ok, Mods};
+ _ ->
+ {error, {invalid_format, modules}}
+ end;
+ Error ->
+ {error, {invalid_format, Error}}
+ end.
+
+ms2() ->
+ application:get_key(?APPLICATION, modules).
+
+
+%%-----------------------------------------------------------------
+%% Returns: current time as a DateAndTime type (defined in rfc1903)
+%%-----------------------------------------------------------------
+date_and_time() ->
+ UTC = calendar:universal_time(),
+ Local = calendar:universal_time_to_local_time(UTC),
+ date_and_time(Local, UTC).
+
+date_and_time(Local, UTC) ->
+ DiffSecs = calendar:datetime_to_gregorian_seconds(Local) -
+ calendar:datetime_to_gregorian_seconds(UTC),
+ short_time(Local) ++ diff(DiffSecs).
+
+short_time({{Y,M,D},{H,Mi,S}}) ->
+ [y1(Y), y2(Y), M, D, H, Mi, S, 0].
+
+%% This function will only be called if there has been some
+%% validation error, and as it is strict, it allways returns
+%% false.
+strict_validation(_What, _Data) ->
+ false.
+
+kiribati_validation(diff, Diff) ->
+ check_kiribati_diff(Diff);
+kiribati_validation(_What, _Data) ->
+ false.
+
+check_kiribati_diff([$+, H, M])
+ when ((0 =< H) andalso (H < 14) andalso (0 =< M) andalso (M < 60)) orelse
+ ((H =:= 14) andalso (M =:= 0)) ->
+ true;
+check_kiribati_diff([$-, H, M])
+ when ((0 =< H) andalso (H < 14) andalso (0 =< M) andalso (M < 60)) orelse
+ ((H =:= 14) andalso (M =:= 0)) ->
+ true;
+check_kiribati_diff(_) ->
+ false.
+
+
+date_and_time_to_string2(DAT) ->
+ Validate = fun(What, Data) -> kiribati_validation(What, Data) end,
+ date_and_time_to_string(DAT, Validate).
+
+date_and_time_to_string(DAT) ->
+ Validate = fun(What, Data) -> strict_validation(What, Data) end,
+ date_and_time_to_string(DAT, Validate).
+date_and_time_to_string(DAT, Validate) when is_function(Validate) ->
+ case validate_date_and_time(DAT, Validate) of
+ true ->
+ dat2str(DAT);
+ false ->
+ exit({badarg, {?MODULE, date_and_time_to_string, [DAT]}})
+ end.
+
+dat2str([Y1,Y2, Mo, D, H, M, S, Ds | Diff]) ->
+ lists:flatten(io_lib:format("~w-~w-~w,~w:~w:~w.~w",
+ [y(Y1,Y2),Mo,D,H,M,S,Ds]) ++
+ case Diff of
+ [Sign,Hd,Md] ->
+ io_lib:format(",~c~w:~w",
+ [Sign,Hd,Md]);
+ _ -> []
+ end).
+
+
+y1(Y) -> (Y bsr 8) band 255.
+y2(Y) -> Y band 255.
+
+y(Y1, Y2) -> 256 * Y1 + Y2.
+
+diff(Secs) ->
+ case calendar:seconds_to_daystime(Secs) of
+ {0, {H, M,_}} ->
+ [$+, H, M];
+ {-1, _} ->
+ {0, {H, M, _}} = calendar:seconds_to_daystime(-Secs),
+ [$-, H, M]
+ end.
+
+universal_time_to_date_and_time(UTC) ->
+ short_time(UTC) ++ [$+, 0, 0].
+
+local_time_to_date_and_time_dst(Local) ->
+ case calendar:local_time_to_universal_time_dst(Local) of
+ [] ->
+ [];
+ [UTC] ->
+ [date_and_time(Local, UTC)];
+ [UTC1, UTC2] ->
+ [date_and_time(Local, UTC1), date_and_time(Local, UTC2)]
+ end.
+
+date_and_time_to_universal_time_dst([Y1, Y2, Mo, D, H, M, S, _Ds]) ->
+ %% Local time specified, convert to UTC
+ Local = {{y(Y1,Y2), Mo, D}, {H, M, S}},
+ calendar:local_time_to_universal_time_dst(Local);
+date_and_time_to_universal_time_dst([Y1, Y2, Mo, D, H, M, S, _Ds, Sign, Hd, Md]) ->
+ %% Time specified as local time + diff from UTC. Conv to UTC.
+ Local = {{y(Y1,Y2), Mo, D}, {H, M, S}},
+ LocalSecs = calendar:datetime_to_gregorian_seconds(Local),
+ Diff = (Hd*60 + Md)*60,
+ UTCSecs = if Sign == $+ -> LocalSecs - Diff;
+ Sign == $- -> LocalSecs + Diff
+ end,
+ [calendar:gregorian_seconds_to_datetime(UTCSecs)].
+
+
+validate_date_and_time(DateAndTime) ->
+ Validate = fun(What, Data) -> strict_validation(What, Data) end,
+ validate_date_and_time(DateAndTime, Validate).
+
+validate_date_and_time(DateAndTime, Validate) when is_function(Validate) ->
+ do_validate_date_and_time(DateAndTime, Validate).
+
+do_validate_date_and_time([Y1,Y2, Mo, D, H, M, S, Ds | Diff], Validate)
+ when ((0 =< Y1) andalso (0 =< Y2)) andalso
+ ((0 < Mo) andalso (Mo < 13)) andalso
+ ((0 < D) andalso (D < 32) andalso (0 =< H)) andalso
+ (H < 24) andalso
+ ((0 =< M) andalso (M < 60)) andalso
+ ((0 =< S) andalso (S < 61)) andalso
+ ((0 =< Ds) andalso (Ds < 10)) ->
+ case check_diff(Diff, Validate) of
+ true ->
+ Year = y(Y1,Y2),
+ case calendar:valid_date(Year, Mo, D) of
+ true ->
+ true;
+ _ ->
+ Validate(valid_date, {Year, Mo, D})
+ end;
+ false ->
+ false
+ end;
+do_validate_date_and_time([Y1,Y2, Mo, D, H, M, S, Ds | Diff], Validate) ->
+ Valid =
+ Validate(year, {Y1, Y2}) andalso
+ Validate(month, Mo) andalso
+ Validate(day, D) andalso
+ Validate(hour, H) andalso
+ Validate(minute, M) andalso
+ Validate(seconds, S) andalso
+ Validate(deci_seconds, Ds),
+ if
+ Valid =:= true ->
+ case check_diff(Diff, Validate) of
+ true ->
+ Year = y(Y1,Y2),
+ case calendar:valid_date(Year, Mo, D) of
+ true ->
+ true;
+ _ ->
+ Validate(valid_date, {Year, Mo, D})
+ end;
+ false ->
+ false
+ end;
+ true ->
+ false
+ end;
+do_validate_date_and_time(_, _) ->
+ false.
+
+%% OTP-4206 (now according to RFC-2579)
+check_diff([], _) ->
+ true;
+check_diff([$+, H, M], _)
+ when (0 =< H) andalso (H < 14) andalso (0 =< M) andalso (M < 60) ->
+ true;
+check_diff([$-, H, M], _)
+ when (0 =< H) andalso (H < 14) andalso (0 =< M) andalso (M < 60) ->
+ true;
+check_diff(Diff, Validate) ->
+ Validate(diff, Diff).
+
+
+%%-----------------------------------------------------------------
+%% System start- and up-time
+%%-----------------------------------------------------------------
+
+system_start_time(agent) ->
+ snmpa:system_start_time();
+system_start_time(manager) ->
+ snmpm:system_start_time().
+
+sys_up_time(agent) ->
+ snmpa:sys_up_time();
+sys_up_time(manager) ->
+ snmpm:sys_up_time().
+
+
+
+%%-----------------------------------------------------------------
+%% Utility functions for OCTET-STRING / BITS conversion.
+%%-----------------------------------------------------------------
+
+octet_string_to_bits(S) ->
+ snmp_pdus:octet_str_to_bits(S).
+
+bits_to_octet_string(B) ->
+ snmp_pdus:bits_to_str(B).
+
+
+%%%-----------------------------------------------------------------
+%%% USM functions
+%%%-----------------------------------------------------------------
+
+passwd2localized_key(Alg, Passwd, EngineID) ->
+ snmp_usm:passwd2localized_key(Alg, Passwd, EngineID).
+
+localize_key(Alg, Key, EngineID) ->
+ snmp_usm:localize_key(Alg, Key, EngineID).
+
+
+%%%-----------------------------------------------------------------
+%%% Read a mib
+%%%-----------------------------------------------------------------
+
+read_mib(FileName) ->
+ snmp_misc:read_mib(FileName).
+
+
+%%%-----------------------------------------------------------------
+%%% Audit Trail Log functions
+%%%-----------------------------------------------------------------
+
+log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile) ->
+ snmp_log:log_to_txt(LogName, LogFile, LogDir, Mibs, OutFile).
+log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start) ->
+ snmp_log:log_to_txt(LogName, LogFile, LogDir, Mibs, OutFile, Start).
+log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) ->
+ snmp_log:log_to_txt(LogName, LogFile, LogDir, Mibs, OutFile, Start, Stop).
+
+
+change_log_size(LogName, NewSize) ->
+ snmp_log:change_size(LogName, NewSize).
+
+
+%%%-----------------------------------------------------------------
+%%% Misc
+%%%-----------------------------------------------------------------
+
+%% Usage: erl -s snmp str_apply '{Mod,Func,ArgList}'
+str_apply([Atom]) ->
+ Str = atom_to_list(Atom),
+ {Mod,Func,Args} = to_erlang_term(Str),
+ apply(Mod,Func,Args).
+
+to_erlang_term(String) ->
+ {ok, Tokens, _} = erl_scan:string(lists:append([String, ". "])),
+ {ok,Term} = erl_parse:parse_term(Tokens),
+ Term.
+
+
+%%%-----------------------------------------------------------------
+%%% BACKWARD COMPATIBILLITY CRAP
+%%%-----------------------------------------------------------------
+
+c(File) -> snmpc:compile(File).
+c(File, Options) -> snmpc:compile(File, Options).
+
+is_consistent(Filenames) ->
+ snmpc:is_consistent(Filenames).
+
+mib_to_hrl(MibName) ->
+ snmpc:mib_to_hrl(MibName).
+
+compile(Input, Output, Options) ->
+ snmpc:compile(Input, Output, Options).
+
+get_symbolic_store_db() -> snmpa:get_symbolic_store_db().
+
+name_to_oid(Name) -> snmpa:name_to_oid(Name).
+name_to_oid(Db, Name) -> snmpa:name_to_oid(Db, Name).
+oid_to_name(OID) -> snmpa:oid_to_name(OID).
+oid_to_name(Db, OID) -> snmpa:oid_to_name(Db, OID).
+enum_to_int(Name, Enum) -> snmpa:enum_to_int(Name, Enum).
+enum_to_int(Db, Name, Enum) -> snmpa:enum_to_int(Db, Name, Enum).
+int_to_enum(Name, Int) -> snmpa:int_to_enum(Name, Int).
+int_to_enum(Db, Name, Int) -> snmpa:int_to_enum(Db, Name, Int).
+
+current_request_id() -> snmpa:current_request_id().
+current_context() -> snmpa:current_context().
+current_community() -> snmpa:current_community().
+current_address() -> snmpa:current_address().
+current_net_if_data() -> snmpa:current_net_if_data().
+
+get(Agent, Vars) -> snmpa:get(Agent, Vars).
+info(Agent) -> snmpa:info(Agent).
+dump_mibs() -> snmpa:dump_mibs().
+dump_mibs(File) -> snmpa:dump_mibs(File).
+load_mibs(Agent, Mibs) -> snmpa:load_mibs(Agent, Mibs).
+unload_mibs(Agent, Mibs) -> snmpa:unload_mibs(Agent, Mibs).
+send_notification(Agent, Notification, Recv) ->
+ snmpa:send_notification(Agent, Notification, Recv).
+send_notification(Agent, Notification, Recv, Varbinds) ->
+ snmpa:send_notification(Agent, Notification, Recv, Varbinds).
+send_notification(Agent, Notification, Recv, NotifyName, Varbinds) ->
+ snmpa:send_notification(Agent, Notification, Recv, NotifyName, Varbinds).
+send_notification(Agent, Notification, Recv, NotifyName,
+ ContextName, Varbinds) ->
+ snmpa:send_notification(Agent, Notification, Recv, NotifyName,
+ ContextName, Varbinds).
+send_trap(Agent, Trap, Community) ->
+ snmpa:send_trap(Agent, Trap, Community).
+send_trap(Agent, Trap, Community, Varbinds) ->
+ snmpa:send_trap(Agent, Trap, Community, Varbinds).
+register_subagent(Agent, SubTree, SubAgent) ->
+ snmpa:register_subagent(Agent, SubTree, SubAgent).
+unregister_subagent(Agent, SubOidOrPid) ->
+ snmpa:unregister_subagent(Agent, SubOidOrPid).
+
+add_agent_caps(Oid, Descr) -> snmpa:add_agent_caps(Oid, Descr).
+del_agent_caps(Index) -> snmpa:del_agent_caps(Index).
+get_agent_caps() -> snmpa:get_agent_caps().
+
+log_to_txt(LogDir, Mibs) ->
+ snmpa:log_to_txt(LogDir, Mibs).
+log_to_txt(LogDir, Mibs, OutFile) ->
+ snmpa:log_to_txt(LogDir, Mibs, OutFile).
+log_to_txt(LogDir, Mibs, OutFile, LogName) ->
+ snmpa:log_to_txt(LogDir, Mibs, OutFile, LogName).
+change_log_size(NewSize) ->
+ snmpa:change_log_size(NewSize).
+
+
+
diff --git a/lib/snmp/src/app/snmp_app.erl b/lib/snmp/src/app/snmp_app.erl
new file mode 100644
index 0000000000..deb42cc373
--- /dev/null
+++ b/lib/snmp/src/app/snmp_app.erl
@@ -0,0 +1,175 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(snmp_app).
+
+-behaviour(application).
+
+-include("snmp_debug.hrl").
+
+
+%%%-----------------------------------------------------------------
+%%% This module implements the SNMP application.
+%%%-----------------------------------------------------------------
+-export([start/2, stop/0, stop/1, config_change/3]).
+-export([start_agent/0, start_agent/1, start_agent/2]).
+-export([start_manager/0, start_manager/1, start_manager/2]).
+
+start(Type, []) ->
+ ?d("start -> entry with"
+ "~n Type. ~p", [Type]),
+ %% This is the new snmp application config format
+ %% First start the (new) central supervisor,
+ {ok, Pid} = snmp_app_sup:start_link(),
+ Entities = entities(),
+ ok = start_entities(Type, Entities),
+ {ok, Pid}.
+
+entities() ->
+ entities([agent, manager], []).
+
+entities([], []) ->
+ ?d("entities -> entry when no entities", []),
+
+ %% Could be old style snmp (agent) application config format
+ %% but could also be a skeleton start, which means that neither
+ %% agent nor manager config has been specified
+
+ case get_env() of
+ [] ->
+ %% Skeleton start
+ ?d("entities -> skeleton start", []),
+ [];
+ OldConf when is_list(OldConf) ->
+ ?d("entities -> old style config: ~n~p", [OldConf]),
+ %% Old style snmp (agent) application config format
+ Conf = snmpa_app:convert_config(OldConf),
+ ?d("entities -> converted config: ~n~p", [Conf]),
+ [{agent, Conf}]
+ end;
+entities([], E) ->
+ ?d("entities -> done", []),
+ lists:reverse(E);
+entities([ET|ETs], E) ->
+ ?d("entities -> entry with"
+ "~n ET: ~p", [ET]),
+ case application:get_env(snmp, ET) of
+ {ok, Conf} ->
+ entities(ETs, [{ET, Conf}|E]);
+ _ ->
+ entities(ETs, E)
+ end.
+
+start_entities(_Type, []) ->
+ ok;
+start_entities(Type, [{agent, Opts}|Entities]) ->
+ case start_agent(Type, Opts) of
+ ok ->
+ start_entities(Type, Entities);
+ Error ->
+ Error
+ end;
+start_entities(Type, [{manager, Opts}|Entities]) ->
+ case start_manager(Type, Opts) of
+ ok ->
+ start_entities(Type, Entities);
+ Error ->
+ Error
+ end;
+start_entities(Type, [BadEntity|Entities]) ->
+ error_msg("Bad snmp configuration: ~n: ~p", [BadEntity]),
+ start_entities(Type, Entities).
+
+
+start_agent() ->
+ start_agent(normal).
+
+start_agent(Type) when is_atom(Type) ->
+ case application:get_env(snmp, agent) of
+ {ok, Opts} ->
+ start_agent(Type, Opts);
+ _ ->
+ {error, missing_config}
+ end;
+start_agent(Opts) when is_list(Opts) ->
+ start_agent(normal, Opts);
+start_agent(BadArg) ->
+ {error, {bad_arg, BadArg}}.
+
+start_agent(Type, Opts) ->
+ ?d("start_agent -> entry", []),
+ case snmp_app_sup:start_agent(Type, Opts) of
+ {ok, _} ->
+ ok;
+ Error ->
+ Error
+ end.
+
+start_manager() ->
+ start_manager(normal).
+
+start_manager(Type) when is_atom(Type) ->
+ case application:get_env(snmp, manager) of
+ {ok, Opts} ->
+ start_manager(Type, Opts);
+ _ ->
+ {error, missing_config}
+ end;
+start_manager(Opts) when is_list(Opts) ->
+ start_manager(normal, Opts);
+start_manager(BadArg) ->
+ {error, {bad_arg, BadArg}}.
+
+start_manager(Type, Opts) ->
+ ?d("start manager -> entry", []),
+ case snmp_app_sup:start_manager(Type, Opts) of
+ {ok, _} ->
+ ok;
+ Error ->
+ Error
+ end.
+
+
+stop(_) ->
+ ok.
+
+stop() ->
+ snmp_app_sup:stop().
+
+
+get_env() ->
+ Env = application:get_all_env(snmp),
+ DeleteElem = [included_applications],
+ F = fun({Key, _}) -> lists:member(Key, DeleteElem) end,
+ lists:dropwhile(F, Env).
+
+
+%%-----------------------------------------------------------------
+%% The presence of this function means that we will accept changes
+%% in the configuration parameters. However, we won't react upon
+%% those changes until the app is restarted. So we just return
+%% ok.
+%%-----------------------------------------------------------------
+config_change(_Changed, _New, _Removed) ->
+ ok.
+
+%% ---------------------------------------------------------------------
+
+error_msg(F, A) ->
+ error_logger:error_msg("~w: " ++ F ++ "~n", [?MODULE|A]).
+
diff --git a/lib/snmp/src/app/snmp_app_sup.erl b/lib/snmp/src/app/snmp_app_sup.erl
new file mode 100644
index 0000000000..d0c190b51f
--- /dev/null
+++ b/lib/snmp/src/app/snmp_app_sup.erl
@@ -0,0 +1,119 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2003-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+-module(snmp_app_sup).
+
+-include("snmp_debug.hrl").
+
+-behaviour(supervisor).
+
+
+%% External exports
+-export([start_link/0, start_agent/2, start_manager/2]).
+
+%% Internal exports
+-export([stop/0]).
+
+
+%% supervisor callbacks
+-export([init/1]).
+
+-define(SERVER, ?MODULE).
+
+
+%%%-------------------------------------------------------------------
+%%% API
+%%%-------------------------------------------------------------------
+start_link() ->
+ ?d("start_link -> entry",[]),
+ SupName = {local, ?MODULE},
+ supervisor:start_link(SupName, ?MODULE, []).
+
+stop() ->
+ ?d("stop -> entry", []),
+ case whereis(?SERVER) of
+ Pid when is_pid(Pid) ->
+ ?d("stop -> Pid: ~p", [Pid]),
+ exit(Pid, shutdown),
+ ?d("stop -> stopped", []),
+ ok;
+ _ ->
+ ?d("stop -> not running", []),
+ not_running
+ end.
+
+
+start_agent(Type, Opts) ->
+ ?d("start_agent -> entry with"
+ "~n Type: ~p"
+ "~n Opts: ~p", [Type, Opts]),
+ Restart = get_restart(Opts, permanent),
+ start_sup_child(snmpa_supervisor, Restart, [Type, Opts]).
+
+
+start_manager(Type, Opts) ->
+ ?d("start_manager -> entry with"
+ "~n Type: ~p"
+ "~n Opts: ~p", [Type, Opts]),
+ Restart = get_restart(Opts, transient),
+ start_sup_child(snmpm_supervisor, Restart, [Type, Opts]).
+
+
+%%%-------------------------------------------------------------------
+%%% Callback functions from supervisor
+%%%-------------------------------------------------------------------
+
+%%--------------------------------------------------------------------
+%% Func: init/1
+%% Returns: {ok, {SupFlags, [ChildSpec]}} |
+%% ignore |
+%% {error, Reason}
+%%--------------------------------------------------------------------
+init(_Args) ->
+ ?d("init -> entry", []),
+ Flags = {one_for_one, 0, 1},
+ Sups = [],
+ {ok, {Flags, Sups}}.
+
+
+%%%-------------------------------------------------------------------
+%%% Internal functions
+%%%-------------------------------------------------------------------
+
+get_restart(Opts, Def) ->
+ get_opt(Opts, restart_type, Def).
+
+get_opt(Opts, Key, Def) ->
+ snmp_misc:get_option(Key, Opts, Def).
+
+start_sup_child(Mod, Type, Args) ->
+ Spec = sup_spec(Mod, Type, Args),
+ supervisor:start_child(?MODULE, Spec).
+
+sup_spec(Name, Type, Args) ->
+ {Name,
+ {Name, start_link, Args},
+ Type, 2000, supervisor, [Name, supervisor]}.
+
+
+% i(F) ->
+% i(F, []).
+
+% i(F, A) ->
+% io:format("~p: " ++ F ++ "~n", [?MODULE|A]).
+
diff --git a/lib/snmp/src/app/snmp_internal.hrl b/lib/snmp/src/app/snmp_internal.hrl
new file mode 100644
index 0000000000..5ff715e0b7
--- /dev/null
+++ b/lib/snmp/src/app/snmp_internal.hrl
@@ -0,0 +1,40 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% 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.
+%%
+%% %CopyrightEnd%
+%%
+
+-ifndef(snmp_internal).
+-define(snmp_internal, true).
+
+-ifndef(APPLICATION).
+-define(APPLICATION, snmp).
+-endif.
+
+-define(snmp_info(C, F, A), ?snmp_msg(info_msg, C, F, A)).
+-define(snmp_warning(C, F, A), ?snmp_msg(warning_msg, C, F, A)).
+-define(snmp_error(C, F, A), ?snmp_msg(error_msg, C, F, A)).
+
+-define(snmp_msg(Func, Component, Format, Args),
+%% io:format("[ ~w : ~s : ~w : ~p ] ~n" ++ Format ++ "~n",
+%% [?APPLICATION, Component, ?MODULE, self() | Args]),
+ (catch error_logger:Func("[ ~w : ~s : ~w : ~p ] ~n" ++ Format ++ "~n",
+ [?APPLICATION, Component, ?MODULE, self() | Args]))).
+
+-endif. % -ifdef(snmp_internal).
+
+
+