diff options
author | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2009-11-20 14:54:40 +0000 |
commit | 84adefa331c4159d432d22840663c38f155cd4c1 (patch) | |
tree | bff9a9c66adda4df2106dfd0e5c053ab182a12bd /lib/snmp/src/app | |
download | otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.gz otp-84adefa331c4159d432d22840663c38f155cd4c1.tar.bz2 otp-84adefa331c4159d432d22840663c38f155cd4c1.zip |
The R13B03 release.OTP_R13B03
Diffstat (limited to 'lib/snmp/src/app')
-rw-r--r-- | lib/snmp/src/app/Makefile | 141 | ||||
-rw-r--r-- | lib/snmp/src/app/depend.mk | 29 | ||||
-rw-r--r-- | lib/snmp/src/app/modules.mk | 28 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.app.src | 134 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.appup.src | 73 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.config | 154 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.erl | 939 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp_app.erl | 175 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp_app_sup.erl | 119 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp_internal.hrl | 40 |
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). + + + |