diff options
Diffstat (limited to 'lib/snmp/src')
-rw-r--r-- | lib/snmp/src/agent/snmpa.erl | 24 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_agent.erl | 2 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_local_db.erl | 4 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_mib.erl | 2 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.app.src | 3 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.appup.src | 378 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.erl | 7 | ||||
-rw-r--r-- | lib/snmp/src/manager/depend.mk | 9 | ||||
-rw-r--r-- | lib/snmp/src/manager/modules.mk | 3 | ||||
-rw-r--r-- | lib/snmp/src/manager/snmpm.erl | 25 | ||||
-rw-r--r-- | lib/snmp/src/manager/snmpm_config.erl | 2 | ||||
-rw-r--r-- | lib/snmp/src/manager/snmpm_mpd.erl | 6 | ||||
-rw-r--r-- | lib/snmp/src/manager/snmpm_net_if_mt.erl | 1259 | ||||
-rw-r--r-- | lib/snmp/src/misc/snmp_log.erl | 110 | ||||
-rw-r--r-- | lib/snmp/src/misc/snmp_verbosity.erl | 6 |
15 files changed, 1721 insertions, 119 deletions
diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index c400aaddf7..b45a47ec6b 100644 --- a/lib/snmp/src/agent/snmpa.erl +++ b/lib/snmp/src/agent/snmpa.erl @@ -83,8 +83,11 @@ -export([add_agent_caps/2, del_agent_caps/1, get_agent_caps/0]). %% Audit Trail Log functions --export([log_to_txt/2, log_to_txt/3, log_to_txt/4, +-export([log_to_txt/1, + log_to_txt/2, log_to_txt/3, log_to_txt/4, log_to_txt/5, log_to_txt/6, log_to_txt/7, + log_to_io/1, log_to_io/2, log_to_io/3, + log_to_io/4, log_to_io/5, log_to_io/6, log_info/0, change_log_size/1, get_log_type/0, get_log_type/1, @@ -780,6 +783,8 @@ get_agent_caps() -> %%% Audit Trail Log functions %%%----------------------------------------------------------------- +log_to_txt(LogDir) -> + log_to_txt(LogDir, []). log_to_txt(LogDir, Mibs) -> OutFile = "snmpa_log.txt", LogName = ?audit_trail_log_name, @@ -800,6 +805,23 @@ log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> snmp:log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop). +log_to_io(LogDir) -> + log_to_io(LogDir, []). +log_to_io(LogDir, Mibs) -> + LogName = ?audit_trail_log_name, + LogFile = ?audit_trail_log_file, + snmp:log_to_io(LogDir, Mibs, LogName, LogFile). +log_to_io(LogDir, Mibs, LogName) -> + LogFile = ?audit_trail_log_file, + snmp:log_to_io(LogDir, Mibs, LogName, LogFile). +log_to_io(LogDir, Mibs, LogName, LogFile) -> + snmp:log_to_io(LogDir, Mibs, LogName, LogFile). +log_to_io(LogDir, Mibs, LogName, LogFile, Start) -> + snmp:log_to_io(LogDir, Mibs, LogName, LogFile, Start). +log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> + snmp:log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop). + + log_info() -> LogName = ?audit_trail_log_name, snmp_log:info(LogName). diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index 9cc986cf47..9d30e332f1 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -1281,7 +1281,7 @@ handle_call({backup, BackupDir}, From, #state{backup = undefined} = S) -> ?vtrace("backup server: ~p", [BackupServer]), {noreply, S#state{backup = {BackupServer, From}}}; -handle_call({backup, _BackupDir}, From, #state{backup = Backup} = S) -> +handle_call({backup, _BackupDir}, _From, #state{backup = Backup} = S) -> ?vinfo("backup already in progress: ~p", [Backup]), {reply, {error, backup_in_progress}, S}; diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl index 1ec8dd3874..2c0cad807a 100644 --- a/lib/snmp/src/agent/snmpa_local_db.erl +++ b/lib/snmp/src/agent/snmpa_local_db.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. 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 @@ -515,7 +515,7 @@ handle_call({backup, BackupDir}, From, {reply, Error, State} end; -handle_call({backup, _BackupDir}, From, #state{backup = Backup} = S) -> +handle_call({backup, _BackupDir}, _From, #state{backup = Backup} = S) -> ?vinfo("backup already in progress: ~p", [Backup]), {reply, {error, backup_in_progress}, S}; diff --git a/lib/snmp/src/agent/snmpa_mib.erl b/lib/snmp/src/agent/snmpa_mib.erl index 574467d38f..575a018c0c 100644 --- a/lib/snmp/src/agent/snmpa_mib.erl +++ b/lib/snmp/src/agent/snmpa_mib.erl @@ -580,7 +580,7 @@ handle_call({backup, BackupDir}, From, {reply, Error, State} end; -handle_call({backup, _BackupDir}, From, #state{backup = Backup} = S) -> +handle_call({backup, _BackupDir}, _From, #state{backup = Backup} = S) -> ?vinfo("backup already in progress: ~p", [Backup]), {reply, {error, backup_in_progress}, S}; diff --git a/lib/snmp/src/app/snmp.app.src b/lib/snmp/src/app/snmp.app.src index a880a14696..b11c1ef934 100644 --- a/lib/snmp/src/app/snmp.app.src +++ b/lib/snmp/src/app/snmp.app.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2009. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. 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 @@ -91,6 +91,7 @@ snmpm_mpd, snmpm_net_if, snmpm_net_if_filter, + snmpm_net_if_mt, snmpm_network_interface, snmpm_network_interface_filter, snmpm_server, diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index a0c065dba3..8b0946d319 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,7 +22,7 @@ %% ----- U p g r a d e ------------------------------------------------------- [ - {"4.21.7", + {"4.21.7", [ {load_module, snmp_conf, soft_purge, soft_purge, []}, {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, @@ -31,69 +31,166 @@ {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]} + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_mib, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] - }, + }, {"4.21.6", [ + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] }, {"4.21.5", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] }, {"4.21.4", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] }, {"4.21.3", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] }, {"4.21.2", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {load_module, snmpa_mpd, soft_purge, soft_purge, []}, {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, @@ -101,17 +198,34 @@ {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] }, {"4.21.1", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {load_module, snmpa_mpd, soft_purge, soft_purge, []}, {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, @@ -120,34 +234,53 @@ {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, - {update, snmp_note_store, soft, soft_purge, soft_purge, []} + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} ] }, {"4.21", [ - {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {load_module, snmpa_mpd, soft_purge, soft_purge, []}, {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, - {update, snmp_note_store, soft, soft_purge, soft_purge, []} - ] - } + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + + {add_module, snmpm_net_if_mt} + ] + } ], %% ------D o w n g r a d e --------------------------------------------------- [ - {"4.21.7", + {"4.21.7", [ {load_module, snmp_conf, soft_purge, soft_purge, []}, {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, @@ -156,69 +289,166 @@ {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]} + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_mib, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] - }, + }, {"4.21.6", [ + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] }, {"4.21.5", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] }, {"4.21.4", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] }, {"4.21.3", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] }, {"4.21.2", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {load_module, snmpa_mpd, soft_purge, soft_purge, []}, {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, @@ -226,17 +456,34 @@ {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, - {update, snmpa_agent, soft, soft_purge, soft_purge, []} + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] }, {"4.21.1", [ - {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {load_module, snmpa_mpd, soft_purge, soft_purge, []}, {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, @@ -245,26 +492,45 @@ {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, - {update, snmp_note_store, soft, soft_purge, soft_purge, []} + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] }, {"4.21", [ - {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_community_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_framework_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_standard_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, [snmp_conf]}, + + {load_module, snmp, soft_purge, soft_purge, [snmp_log]}, + {load_module, snmpm, soft_purge, soft_purge, [snmp]}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_verbosity, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, []}, + + {load_module, snmpa, soft_purge, soft_purge, [snmp]}, {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, + [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, {load_module, snmpa_mpd, soft_purge, soft_purge, []}, {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, {load_module, snmpa_trap, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf, snmpa_mib_lib]}, {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, {update, snmpa_mib, soft, soft_purge, soft_purge, []}, {update, snmpa_agent, soft, soft_purge, soft_purge, []}, - {update, snmp_note_store, soft, soft_purge, soft_purge, []} + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + + {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} ] } ] diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl index 3e0f05e604..fc03757e3f 100644 --- a/lib/snmp/src/app/snmp.erl +++ b/lib/snmp/src/app/snmp.erl @@ -50,6 +50,7 @@ read_mib/1, log_to_txt/5, log_to_txt/6, log_to_txt/7, + log_to_io/4, log_to_io/5, log_to_io/6, change_log_size/2, octet_string_to_bits/1, bits_to_octet_string/1, @@ -843,6 +844,12 @@ log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start) -> log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> snmp_log:log_to_txt(LogName, LogFile, LogDir, Mibs, OutFile, Start, Stop). +log_to_io(LogDir, Mibs, LogName, LogFile) -> + snmp_log:log_to_io(LogName, LogFile, LogDir, Mibs). +log_to_io(LogDir, Mibs, LogName, LogFile, Start) -> + snmp_log:log_to_io(LogName, LogFile, LogDir, Mibs, Start). +log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> + snmp_log:log_to_io(LogName, LogFile, LogDir, Mibs, Start, Stop). change_log_size(LogName, NewSize) -> snmp_log:change_size(LogName, NewSize). diff --git a/lib/snmp/src/manager/depend.mk b/lib/snmp/src/manager/depend.mk index 0e7e9e3df7..2e7783c8ed 100644 --- a/lib/snmp/src/manager/depend.mk +++ b/lib/snmp/src/manager/depend.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-2012. 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 @@ -49,6 +49,13 @@ $(EBIN)/snmpm_net_if.$(EMULATOR): \ snmpm_net_if.erl \ snmpm_network_interface.erl +$(EBIN)/snmpm_net_if_mt.$(EMULATOR): \ + ../../include/snmp_types.hrl \ + ../misc/snmp_debug.hrl \ + ../misc/snmp_verbosity.hrl \ + snmpm_net_if_mt.erl \ + snmpm_network_interface.erl + $(EBIN)/snmpm_server.$(EMULATOR): \ ../../include/snmp_types.hrl \ ../../include/STANDARD-MIB.hrl \ diff --git a/lib/snmp/src/manager/modules.mk b/lib/snmp/src/manager/modules.mk index 79f3dd65d9..d46545ea3f 100644 --- a/lib/snmp/src/manager/modules.mk +++ b/lib/snmp/src/manager/modules.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2009. All Rights Reserved. +# Copyright Ericsson AB 2004-2012. 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 @@ -31,6 +31,7 @@ MODULES = \ snmpm_mpd \ snmpm_misc_sup \ snmpm_net_if \ + snmpm_net_if_mt \ snmpm_net_if_filter \ snmpm_server \ snmpm_server_sup \ diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index 6d2ac8d747..89eaee9f80 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2012. 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 @@ -75,8 +75,11 @@ %% %% Logging + log_to_txt/1, log_to_txt/2, log_to_txt/3, log_to_txt/4, log_to_txt/5, log_to_txt/6, log_to_txt/7, + log_to_io/1, log_to_io/2, log_to_io/3, + log_to_io/4, log_to_io/5, log_to_io/6, change_log_size/1, get_log_type/0, set_log_type/1, @@ -1371,6 +1374,9 @@ cancel_async_request(UserId, ReqId) -> %%%----------------------------------------------------------------- %%% Audit Trail Log functions (for backward compatibility) %%%----------------------------------------------------------------- + +log_to_txt(LogDir) -> + log_to_txt(LogDir, []). log_to_txt(LogDir, Mibs) -> OutFile = "snmpm_log.txt", LogName = ?audit_trail_log_name, @@ -1391,6 +1397,23 @@ log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> snmp:log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop). +log_to_io(LogDir) -> + log_to_io(LogDir, []). +log_to_io(LogDir, Mibs) -> + LogName = ?audit_trail_log_name, + LogFile = ?audit_trail_log_file, + snmp:log_to_io(LogDir, Mibs, LogName, LogFile). +log_to_io(LogDir, Mibs, LogName) -> + LogFile = ?audit_trail_log_file, + snmp:log_to_io(LogDir, Mibs, LogName, LogFile). +log_to_io(LogDir, Mibs, LogName, LogFile) -> + snmp:log_to_io(LogDir, Mibs, LogName, LogFile). +log_to_io(LogDir, Mibs, LogName, LogFile, Start) -> + snmp:log_to_io(LogDir, Mibs, LogName, LogFile, Start). +log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> + snmp:log_to_io(LogDir, Mibs, LogFile, Start, Stop). + + change_log_size(NewSize) -> LogName = ?audit_trail_log_name, snmp:change_log_size(LogName, NewSize). diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index c2e57abddb..5bbf9e5542 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2012. 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 diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index 103c87d32b..883224143e 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -110,9 +110,9 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> #message{version = 'version-2', vsn_hdr = Community, data = Data} when State#state.v2c =:= true -> HS = ?empty_msg_size + length(Community), - (catch process_v1_v2c_msg('version-2', NoteStore, Msg, - Domain, Addr, Port, - Community, Data, HS, Logger)); + process_v1_v2c_msg('version-2', NoteStore, Msg, + Domain, Addr, Port, + Community, Data, HS, Logger); %% Version 3 #message{version = 'version-3', vsn_hdr = H, data = Data} diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl new file mode 100644 index 0000000000..3e87f6a7fb --- /dev/null +++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl @@ -0,0 +1,1259 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2004-2012. 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(snmpm_net_if_mt). + +-behaviour(gen_server). +-behaviour(snmpm_network_interface). + + +%% Network Interface callback functions +-export([ + start_link/2, + stop/1, + send_pdu/6, % Backward compatibillity + send_pdu/7, % Backward compatibillity + send_pdu/8, + + inform_response/4, + + note_store/2, + + info/1, + verbosity/2, + %% system_info_updated/2, + get_log_type/1, set_log_type/2, + filter_reset/1 + ]). + +%% gen_server callbacks +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + code_change/3, terminate/2]). + +-define(SNMP_USE_V3, true). +-include("snmp_types.hrl"). +-include("snmpm_internal.hrl"). +-include("snmpm_atl.hrl"). +-include("snmp_debug.hrl"). + +%% -define(VMODULE,"NET_IF"). +-include("snmp_verbosity.hrl"). + +-record(state, + { + server, + note_store, + sock, + mpd_state, + log, + irb = auto, % auto | {user, integer()} + irgc, + filter + }). + + +-define(DEFAULT_FILTER_MODULE, snmpm_net_if_filter). +-define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]). + +-ifdef(snmp_debug). +-define(GS_START_LINK(Args), + gen_server:start_link(?MODULE, Args, [{debug,[trace]}])). +-else. +-define(GS_START_LINK(Args), + gen_server:start_link(?MODULE, Args, [])). +-endif. + + +-define(IRGC_TIMEOUT, timer:minutes(5)). + +-define(ATL_SEQNO_INITIAL, 1). +-define(ATL_SEQNO_MAX, 2147483647). + + +%%%------------------------------------------------------------------- +%%% API +%%%------------------------------------------------------------------- +start_link(Server, NoteStore) -> + ?d("start_link -> entry with" + "~n Server: ~p" + "~n NoteStore: ~p", [Server, NoteStore]), + Args = [Server, NoteStore], + ?GS_START_LINK(Args). + +stop(Pid) -> + call(Pid, stop). + +send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) -> + send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO). + +send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) -> + Domain = snmpm_config:default_transport_domain(), + send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo). + +send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo) + when is_record(Pdu, pdu) -> + ?d("send_pdu -> entry with" + "~n Pid: ~p" + "~n Pdu: ~p" + "~n Vsn: ~p" + "~n MsgData: ~p" + "~n Domain: ~p" + "~n Addr: ~p" + "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]), + cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}). + +note_store(Pid, NoteStore) -> + call(Pid, {note_store, NoteStore}). + +inform_response(Pid, Ref, Addr, Port) -> + cast(Pid, {inform_response, Ref, Addr, Port}). + +info(Pid) -> + call(Pid, info). + +verbosity(Pid, V) -> + call(Pid, {verbosity, V}). + +%% system_info_updated(Pid, What) -> +%% call(Pid, {system_info_updated, What}). + +get_log_type(Pid) -> + call(Pid, get_log_type). + +set_log_type(Pid, NewType) -> + call(Pid, {set_log_type, NewType}). + +filter_reset(Pid) -> + cast(Pid, filter_reset). + + +%%%------------------------------------------------------------------- +%%% Callback functions from gen_server +%%%------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Func: init/1 +%% Returns: {ok, State} | +%% {ok, State, Timeout} | +%% ignore | +%% {stop, Reason} +%%-------------------------------------------------------------------- +init([Server, NoteStore]) -> + ?d("init -> entry with" + "~n Server: ~p" + "~n NoteStore: ~p", [Server, NoteStore]), + case (catch do_init(Server, NoteStore)) of + {error, Reason} -> + {stop, Reason}; + {ok, State} -> + {ok, State} + end. + +do_init(Server, NoteStore) -> + process_flag(trap_exit, true), + + %% -- Prio -- + {ok, Prio} = snmpm_config:system_info(prio), + process_flag(priority, Prio), + + %% -- Create inform request table -- + %% This should really be protected, but it also needs to + %% be writable for the worker processes, so... + ets:new(snmpm_inform_request_table, + [set, public, named_table, {keypos, 1}]), + + %% -- Verbosity -- + {ok, Verbosity} = snmpm_config:system_info(net_if_verbosity), + put(sname, mnif), + put(verbosity, Verbosity), + ?vlog("starting", []), + + %% -- MPD -- + {ok, Vsns} = snmpm_config:system_info(versions), + MpdState = snmpm_mpd:init(Vsns), + ?vdebug("MpdState: ~w", [MpdState]), + + %% -- Module dependent options -- + {ok, Opts} = snmpm_config:system_info(net_if_options), + + %% -- Inform response behaviour -- + {ok, IRB} = snmpm_config:system_info(net_if_irb), + IrGcRef = irgc_start(IRB), + + %% -- Socket -- + SndBuf = get_opt(Opts, sndbuf, default), + RecBuf = get_opt(Opts, recbuf, default), + BindTo = get_opt(Opts, bind_to, false), + NoReuse = get_opt(Opts, no_reuse, false), + {ok, Port} = snmpm_config:system_info(port), + {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, BindTo, NoReuse), + + %% Flow control -- + FilterOpts = get_opt(Opts, filter, []), + FilterMod = create_filter(FilterOpts), + ?vdebug("FilterMod: ~w", [FilterMod]), + + %% -- Audit trail log --- + {ok, ATL} = snmpm_config:system_info(audit_trail_log), + Log = do_init_log(ATL), + ?vdebug("Log: ~w", [Log]), + + %% -- Initiate counters --- + init_counters(), + + %% -- We are done --- + State = #state{server = Server, + note_store = NoteStore, + mpd_state = MpdState, + sock = Sock, + log = Log, + irb = IRB, + irgc = IrGcRef, + filter = FilterMod}, + ?vdebug("started", []), + {ok, State}. + + +%% Open port +do_open_port(Port, SendSz, RecvSz, BindTo, NoReuse) -> + ?vtrace("do_open_port -> entry with" + "~n Port: ~p" + "~n SendSz: ~p" + "~n RecvSz: ~p" + "~n BindTo: ~p" + "~n NoReuse: ~p", [Port, SendSz, RecvSz, BindTo, NoReuse]), + IpOpts1 = bind_to(BindTo), + IpOpts2 = no_reuse(NoReuse), + IpOpts3 = recbuf(RecvSz), + IpOpts4 = sndbuf(SendSz), + IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4], + OpenRes = + case init:get_argument(snmpm_fd) of + {ok, [[FdStr]]} -> + Fd = list_to_integer(FdStr), + gen_udp:open(0, [{fd, Fd}|IpOpts]); + error -> + gen_udp:open(Port, IpOpts) + end, + case OpenRes of + {error, _} = Error -> + throw(Error); + OK -> + OK + end. + +bind_to(true) -> + case snmpm_config:system_info(address) of + {ok, Addr} when is_list(Addr) -> + [{ip, list_to_tuple(Addr)}]; + {ok, Addr} -> + [{ip, Addr}]; + _ -> + [] + end; +bind_to(_) -> + []. + +no_reuse(false) -> + [{reuseaddr, true}]; +no_reuse(_) -> + []. + +recbuf(default) -> + []; +recbuf(Sz) -> + [{recbuf, Sz}]. + +sndbuf(default) -> + []; +sndbuf(Sz) -> + [{sndbuf, Sz}]. + + +create_filter(Opts) when is_list(Opts) -> + case get_opt(Opts, module, ?DEFAULT_FILTER_MODULE) of + ?DEFAULT_FILTER_MODULE = Mod -> + Mod; + Module -> + snmpm_network_interface_filter:verify(Module), + Module + end; +create_filter(BadOpts) -> + throw({error, {bad_filter_opts, BadOpts}}). + + +%% ---------------------------------------------------------------------- +%% Audit Trail Logger +%% ---------------------------------------------------------------------- + +%% Open log +do_init_log(false) -> + ?vtrace("do_init_log(false) -> entry", []), + undefined; +do_init_log(true) -> + ?vtrace("do_init_log(true) -> entry", []), + {ok, Type} = snmpm_config:system_info(audit_trail_log_type), + {ok, Dir} = snmpm_config:system_info(audit_trail_log_dir), + {ok, Size} = snmpm_config:system_info(audit_trail_log_size), + {ok, Repair} = snmpm_config:system_info(audit_trail_log_repair), + Name = ?audit_trail_log_name, + File = filename:absname(?audit_trail_log_file, Dir), + case snmpm_config:system_info(audit_trail_log_seqno) of + {ok, true} -> + Initial = ?ATL_SEQNO_INITIAL, + Max = ?ATL_SEQNO_MAX, + Module = snmpm_config, + Function = increment_counter, + Args = [atl_seqno, Initial, Max], + SeqNoGen = {Module, Function, Args}, + case snmp_log:create(Name, File, SeqNoGen, Size, Repair, true) of + {ok, Log} -> + ?vdebug("log created: ~w", [Log]), + {Name, Log, Type}; + {error, Reason} -> + throw({error, {failed_create_audit_log, Reason}}) + end; + _ -> + case snmp_log:create(Name, File, Size, Repair, true) of + {ok, Log} -> + ?vdebug("log created: ~w", [Log]), + {Name, Log, Type}; + {error, Reason} -> + throw({error, {failed_create_audit_log, Reason}}) + end + end. + + +%% ---------------------------------------------------------------------- + +%%-------------------------------------------------------------------- +%% Func: handle_call/3 +%% Returns: {reply, Reply, State} | +%% {reply, Reply, State, Timeout} | +%% {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, Reply, State} | (terminate/2 is called) +%% {stop, Reason, State} (terminate/2 is called) +%%-------------------------------------------------------------------- +handle_call({verbosity, Verbosity}, _From, State) -> + ?vlog("received verbosity request", []), + put(verbosity, Verbosity), + {reply, ok, State}; + +%% handle_call({system_info_updated, What}, _From, State) -> +%% ?vlog("received system_info_updated request with What = ~p", [What]), +%% {NewState, Reply} = handle_system_info_updated(State, What), +%% {reply, Reply, NewState}; + +handle_call(get_log_type, _From, State) -> + ?vlog("received get-log-type request", []), + Reply = (catch handle_get_log_type(State)), + {reply, Reply, State}; + +handle_call({set_log_type, NewType}, _From, State) -> + ?vlog("received set-log-type request with NewType = ~p", [NewType]), + {NewState, Reply} = (catch handle_set_log_type(State, NewType)), + {reply, Reply, NewState}; + +handle_call({note_store, Pid}, _From, State) -> + ?vlog("received new note_store: ~w", [Pid]), + {reply, ok, State#state{note_store = Pid}}; + +handle_call(stop, _From, State) -> + ?vlog("received stop request", []), + Reply = ok, + {stop, normal, Reply, State}; + +handle_call(info, _From, State) -> + ?vlog("received info request", []), + Reply = get_info(State), + {reply, Reply, State}; + +handle_call(Req, From, State) -> + warning_msg("received unknown request (from ~p): ~n~p", [Req, From]), + {reply, {error, {invalid_request, Req}}, State}. + + +%%-------------------------------------------------------------------- +%% Func: handle_cast/2 +%% Returns: {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} (terminate/2 is called) +%%-------------------------------------------------------------------- +handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}, + State) -> + ?vlog("received send_pdu message with" + "~n Pdu: ~p" + "~n Vsn: ~p" + "~n MsgData: ~p" + "~n Domain: ~p" + "~n Addr: ~p" + "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]), + maybe_process_extra_info(ExtraInfo), + handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State), + {noreply, State}; + +handle_cast({inform_response, Ref, Addr, Port}, State) -> + ?vlog("received inform_response message with" + "~n Ref: ~p" + "~n Addr: ~p" + "~n Port: ~p", [Ref, Addr, Port]), + handle_inform_response(Ref, Addr, Port, State), + {noreply, State}; + +handle_cast(filter_reset, State) -> + ?vlog("received filter_reset message", []), + reset_counters(), + {noreply, State}; + +handle_cast(Msg, State) -> + warning_msg("received unknown message: ~n~p", [Msg]), + {noreply, State}. + + +%%-------------------------------------------------------------------- +%% Func: handle_info/2 +%% Returns: {noreply, State} | +%% {noreply, State, Timeout} | +%% {stop, Reason, State} (terminate/2 is called) +%%-------------------------------------------------------------------- +handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> + ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]), + handle_udp(Ip, Port, Bytes, State), + {noreply, State}; + +handle_info(inform_response_gc, State) -> + ?vlog("received inform_response_gc message", []), + State2 = handle_inform_response_gc(State), + {noreply, State2}; + +handle_info({disk_log, _Node, Log, Info}, State) -> + ?vlog("received disk_log message: " + "~n Info: ~p", [Info]), + State2 = handle_disk_log(Log, Info, State), + {noreply, State2}; + +handle_info({'DOWN', _MRef, process, Pid, {net_if_worker, ExitStatus}}, + State) -> + ?vdebug("received DOWN message from net_if-worker: " + "~n ExitStatus: ~p", [ExitStatus]), + handle_worker_exit(Pid, ExitStatus), + {noreply, State}; + +handle_info(Info, State) -> + warning_msg("received unknown info: ~n~p", [Info]), + {noreply, State}. + + +%%-------------------------------------------------------------------- +%% Func: terminate/2 +%% Purpose: Shutdown the server +%% Returns: any (ignored by gen_server) +%%-------------------------------------------------------------------- +terminate(Reason, #state{log = Log, irgc = IrGcRef}) -> + ?vdebug("terminate: ~p", [Reason]), + irgc_stop(IrGcRef), + %% Close logs + do_close_log(Log), + ok. + + +do_close_log({Log, _Type}) -> + (catch snmp_log:sync(Log)), + (catch snmp_log:close(Log)), + ok; +do_close_log(_) -> + ok. + + +%%---------------------------------------------------------------------- +%% Func: code_change/3 +%% Purpose: Convert process state when code is changed +%% Returns: {ok, NewState} +%%---------------------------------------------------------------------- + +code_change(_Vsn, State, _Extra) -> + ?d("code_change -> entry with" + "~n Vsn: ~p" + "~n State: ~p" + "~n Extra: ~p", [_Vsn, State, _Extra]), + {ok, State}. + + +%%%------------------------------------------------------------------- +%%% Internal functions +%%%------------------------------------------------------------------- + +handle_udp(Addr, Port, Bytes, State) -> + Verbosity = get(verbosity), + spawn_opt(fun() -> + Log = worker_init(State, Verbosity), + Res = (catch maybe_handle_recv_msg( + Addr, Port, Bytes, + State#state{log = Log})), + worker_exit(udp, {Addr, Port}, Res) + end, + [monitor]). + + +maybe_handle_recv_msg(Addr, Port, Bytes, #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_recv(Addr, Port)) of + false -> + %% Drop the received packet + inc(netIfMsgInDrops), + ok; + _ -> + handle_recv_msg(Addr, Port, Bytes, State) + end. + + +handle_recv_msg(Addr, Port, Bytes, #state{server = Pid}) + when is_binary(Bytes) andalso (size(Bytes) =:= 0) -> + Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port}, + ok; + +handle_recv_msg(Addr, Port, Bytes, + #state{server = Pid, + note_store = NoteStore, + mpd_state = MpdState, + sock = Sock, + log = Log} = State) -> + Domain = snmp_conf:which_domain(Addr), % What the ****... + Logger = logger(Log, read, Addr, Port), + case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port, + MpdState, NoteStore, Logger)) of + + {ok, Vsn, Pdu, MS, ACM} -> + maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, MS, ACM, + Logger, State); + + {discarded, Reason, Report} -> + ?vdebug("discarded: ~p", [Reason]), + ErrorInfo = {failed_processing_message, Reason}, + Pid ! {snmp_error, ErrorInfo, Addr, Port}, + maybe_udp_send(State#state.filter, Sock, Addr, Port, Report), + ok; + + {discarded, Reason} -> + ?vdebug("discarded: ~p", [Reason]), + ErrorInfo = {failed_processing_message, Reason}, + Pid ! {snmp_error, ErrorInfo, Addr, Port}, + ok; + + Error -> + error_msg("processing of received message failed: " + "~n ~p", [Error]), + ok + end. + + +maybe_handle_recv_pdu(Addr, Port, + Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, + Logger, + #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_recv_pdu(Addr, Port, Type)) of + false -> + inc(netIfPduInDrops), + ok; + _ -> + handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) + end; +maybe_handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, + #state{filter = FilterMod} = State) + when is_record(Trap, trappdu) -> + case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of + false -> + inc(netIfPduInDrops), + ok; + _ -> + handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, State) + end; +maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) -> + handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State). + + +handle_recv_pdu(Addr, Port, + Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, + Logger, #state{server = Pid, irb = IRB} = State) -> + handle_inform_request(IRB, Pid, Vsn, Pdu, ACM, + Addr, Port, Logger, State); +handle_recv_pdu(Addr, Port, + _Vsn, #pdu{type = report} = Pdu, _PduMS, ok, + _Logger, + #state{server = Pid} = _State) -> + ?vtrace("received report - ok", []), + Pid ! {snmp_report, {ok, Pdu}, Addr, Port}, + ok; +handle_recv_pdu(Addr, Port, + _Vsn, #pdu{type = report} = Pdu, _PduMS, + {error, ReqId, Reason}, + _Logger, + #state{server = Pid} = _State) -> + ?vtrace("received report - error", []), + Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Addr, Port}, + ok; +handle_recv_pdu(Addr, Port, + _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, + _Logger, + #state{server = Pid} = _State) -> + ?vtrace("received snmpv2-trap", []), + Pid ! {snmp_trap, Pdu, Addr, Port}, + ok; +handle_recv_pdu(Addr, Port, + _Vsn, Trap, _PduMS, _ACM, + _Logger, + #state{server = Pid} = _State) when is_record(Trap, trappdu) -> + ?vtrace("received trappdu", []), + Pid ! {snmp_trap, Trap, Addr, Port}, + ok; +handle_recv_pdu(Addr, Port, + _Vsn, Pdu, _PduMS, _ACM, + _Logger, + #state{server = Pid} = _State) when is_record(Pdu, pdu) -> + ?vtrace("received pdu", []), + Pid ! {snmp_pdu, Pdu, Addr, Port}, + ok; +handle_recv_pdu(_Addr, _Port, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> + ?vlog("received unexpected pdu: " + "~n Pdu: ~p" + "~n ACM: ~p", [Pdu, ACM]), + ok. + + +handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Addr, Port, Logger, State) -> + ?vtrace("received inform-request (true)", []), + Pid ! {snmp_inform, ignore, Pdu, Addr, Port}, + RePdu = make_response_pdu(Pdu), + maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, State); +handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, + ACM, Addr, Port, _Logger, _State) -> + ?vtrace("received inform-request (false)", []), + + Pid ! {snmp_inform, ReqId, Pdu, Addr, Port}, + + %% Before we go any further, we need to check that we have not + %% already received this message (possible resend). + + Key = {ReqId, Addr, Port}, + case ets:lookup(snmpm_inform_request_table, Key) of + [_] -> + %% OK, we already know about this. We assume this + %% is a resend. Either the agent is really eager or + %% the user has not answered yet. Bad user! + ok; + [] -> + RePdu = make_response_pdu(Pdu), + Expire = t() + To, + Rec = {Key, Expire, {Vsn, ACM, RePdu}}, + ets:insert(snmpm_inform_request_table, Rec) + end, + ok. + +handle_inform_response(Ref, Addr, Port, State) -> + Verbosity = get(verbosity), + spawn_opt(fun() -> + Log = worker_init(State, Verbosity), + Res = (catch do_handle_inform_response( + Ref, + Addr, Port, + State#state{log = Log})), + worker_exit(inform_reponse, {Addr, Port}, Res) + end, + [monitor]). + + + +do_handle_inform_response(Ref, Addr, Port, State) -> + Key = {Ref, Addr, Port}, + case ets:lookup(snmpm_inform_request_table, Key) of + [{Key, _, {Vsn, ACM, RePdu}}] -> + Logger = logger(State#state.log, read, Addr, Port), + ets:delete(snmpm_inform_request_table, Key), + maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, + Logger, State); + [] -> + %% Already acknowledged, or the user was to slow to reply... + ok + end, + ok. + +maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, + #state{server = Pid, + sock = Sock, + filter = FilterMod}) -> + case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(RePdu))) of + false -> + inc(netIfPduOutDrops), + ok; + _ -> + case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of + {ok, Msg} -> + maybe_udp_send(FilterMod, Sock, Addr, Port, Msg); + {discarded, Reason} -> + ?vlog("failed generating response message:" + "~n Reason: ~p", [Reason]), + ReqId = RePdu#pdu.request_id, + ErrorInfo = {failed_generating_response, {RePdu, Reason}}, + Pid ! {snmp_error, ReqId, ErrorInfo, Addr, Port}, + ok + end + end. + +handle_inform_response_gc(#state{irb = IRB} = State) -> + ets:safe_fixtable(snmpm_inform_request_table, true), + do_irgc(ets:first(snmpm_inform_request_table), t()), + ets:safe_fixtable(snmpm_inform_request_table, false), + State#state{irgc = irgc_start(IRB)}. + +%% We are deleting at the same time as we are traversing the table!!! +do_irgc('$end_of_table', _) -> + ok; +do_irgc(Key, Now) -> + Next = ets:next(snmpm_inform_request_table, Key), + case ets:lookup(snmpm_inform_request_table, Key) of + [{Key, BestBefore, _}] when BestBefore < Now -> + ets:delete(snmpm_inform_request_table, Key); + _ -> + ok + end, + do_irgc(Next, Now). + +irgc_start(auto) -> + undefined; +irgc_start(_) -> + erlang:send_after(?IRGC_TIMEOUT, self(), inform_response_gc). + +irgc_stop(undefined) -> + ok; +irgc_stop(Ref) -> + (catch erlang:cancel_timer(Ref)). + + +handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) -> + Verbosity = get(verbosity), + spawn_opt(fun() -> + Log = worker_init(State, Verbosity), + Res = (catch maybe_handle_send_pdu( + Pdu, Vsn, MsgData, + Domain, Addr, Port, + State#state{log = Log})), + worker_exit(send_pdu, {Domain, Addr, Port}, Res) + end, + [monitor]). + +maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, + #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of + false -> + inc(netIfPduOutDrops), + ok; + _ -> + do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) + end. + +do_handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port, + #state{server = Pid, + note_store = NoteStore, + sock = Sock, + log = Log, + filter = FilterMod}) -> + Logger = logger(Log, write, Addr, Port), + case (catch snmpm_mpd:generate_msg(Vsn, NoteStore, + Pdu, MsgData, Logger)) of + {ok, Msg} -> + ?vtrace("do_handle_send_pdu -> message generated", []), + maybe_udp_send(FilterMod, Sock, Addr, Port, Msg); + {discarded, Reason} -> + ?vlog("PDU not sent: " + "~n PDU: ~p" + "~n Reason: ~p", [Pdu, Reason]), + Pid ! {snmp_error, Pdu, Reason}, + ok + end. + + +maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) -> + case (catch FilterMod:accept_send(Addr, Port)) of + false -> + inc(netIfMsgOutDrops), + ok; + _ -> + udp_send(Sock, Addr, Port, Msg) + end. + + +udp_send(Sock, Addr, Port, Msg) -> + case (catch gen_udp:send(Sock, Addr, Port, Msg)) of + ok -> + ?vdebug("sent ~w bytes to ~w:~w [~w]", + [sz(Msg), Addr, Port, Sock]), + ok; + {error, Reason} -> + error_msg("failed sending message to ~p:~p: " + "~n ~p",[Addr, Port, Reason]), + ok; + Error -> + error_msg("failed sending message to ~p:~p: " + "~n ~p",[Addr, Port, Error]), + ok + end. + +sz(B) when is_binary(B) -> + size(B); +sz(L) when is_list(L) -> + length(L); +sz(_) -> + undefined. + + +handle_disk_log(_Log, {wrap, NoLostItems}, State) -> + ?vlog("Audit Trail Log - wrapped: ~w previously logged items where lost", + [NoLostItems]), + State; +handle_disk_log(_Log, {truncated, NoLostItems}, State) -> + ?vlog("Audit Trail Log - truncated: ~w items where lost when truncating", + [NoLostItems]), + State; +handle_disk_log(_Log, full, State) -> + error_msg("Failed to write to Audit Trail Log (full)", []), + State; +handle_disk_log(_Log, {error_status, ok}, State) -> + State; +handle_disk_log(_Log, {error_status, {error, Reason}}, State) -> + error_msg("Error status received from Audit Trail Log: " + "~n~p", [Reason]), + State; +handle_disk_log(_Log, _Info, State) -> + State. + + +%% mk_discovery_msg('version-3', Pdu, _VsnHdr, UserName) -> +%% ScopedPDU = #scopedPdu{contextEngineID = "", +%% contextName = "", +%% data = Pdu}, +%% Bytes = snmp_pdus:enc_scoped_pdu(ScopedPDU), +%% MsgID = get(msg_id), +%% put(msg_id,MsgID+1), +%% UsmSecParams = +%% #usmSecurityParameters{msgAuthoritativeEngineID = "", +%% msgAuthoritativeEngineBoots = 0, +%% msgAuthoritativeEngineTime = 0, +%% msgUserName = UserName, +%% msgPrivacyParameters = "", +%% msgAuthenticationParameters = ""}, +%% SecBytes = snmp_pdus:enc_usm_security_parameters(UsmSecParams), +%% PduType = Pdu#pdu.type, +%% Hdr = #v3_hdr{msgID = MsgID, +%% msgMaxSize = 1000, +%% msgFlags = snmp_misc:mk_msg_flags(PduType, 0), +%% msgSecurityModel = ?SEC_USM, +%% msgSecurityParameters = SecBytes}, +%% Msg = #message{version = 'version-3', vsn_hdr = Hdr, data = Bytes}, +%% case (catch snmp_pdus:enc_message_only(Msg)) of +%% {'EXIT', Reason} -> +%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]), +%% error; +%% L when list(L) -> +%% {Msg, L} +%% end; +%% mk_discovery_msg(Version, Pdu, {Com, _, _, _, _}, UserName) -> +%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu}, +%% case catch snmp_pdus:enc_message(Msg) of +%% {'EXIT', Reason} -> +%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]), +%% error; +%% L when list(L) -> +%% {Msg, L} +%% end. + + +%% mk_msg('version-3', Pdu, {Context, User, EngineID, CtxEngineId, SecLevel}, +%% MsgData) -> +%% %% Code copied from snmp_mpd.erl +%% {MsgId, SecName, SecData} = +%% if +%% tuple(MsgData), Pdu#pdu.type == 'get-response' -> +%% MsgData; +%% true -> +%% Md = get(msg_id), +%% put(msg_id, Md + 1), +%% {Md, User, []} +%% end, +%% ScopedPDU = #scopedPdu{contextEngineID = CtxEngineId, +%% contextName = Context, +%% data = Pdu}, +%% ScopedPDUBytes = snmp_pdus:enc_scoped_pdu(ScopedPDU), + +%% PduType = Pdu#pdu.type, +%% V3Hdr = #v3_hdr{msgID = MsgId, +%% msgMaxSize = 1000, +%% msgFlags = snmp_misc:mk_msg_flags(PduType, SecLevel), +%% msgSecurityModel = ?SEC_USM}, +%% Message = #message{version = 'version-3', vsn_hdr = V3Hdr, +%% data = ScopedPDUBytes}, +%% SecEngineID = case PduType of +%% 'get-response' -> snmp_framework_mib:get_engine_id(); +%% _ -> EngineID +%% end, +%% case catch snmp_usm:generate_outgoing_msg(Message, SecEngineID, +%% SecName, SecData, SecLevel) of +%% {'EXIT', Reason} -> +%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]), +%% error; +%% {error, Reason} -> +%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]), +%% error; +%% Packet -> +%% Packet +%% end; +%% mk_msg(Version, Pdu, {Com, _User, _EngineID, _Ctx, _SecLevel}, _SecData) -> +%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu}, +%% case catch snmp_pdus:enc_message(Msg) of +%% {'EXIT', Reason} -> +%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]), +%% error; +%% B when list(B) -> +%% B +%% end. + + +%% handle_system_info_updated(#state{log = {Log, _OldType}} = State, +%% audit_trail_log_type = _What) -> +%% %% Just to make sure, check that ATL is actually enabled +%% case snmpm_config:system_info(audit_trail_log) of +%% {ok, true} -> +%% {ok, Type} = snmpm_config:system_info(audit_trail_log_type), +%% NewState = State#state{log = {Log, Type}}, +%% {NewState, ok}; +%% _ -> +%% {State, {error, {adt_not_enabled}}} +%% end; +%% handle_system_info_updated(_State, _What) -> +%% ok. + +handle_get_log_type(#state{log = {_Log, Value}} = State) -> + %% Just to make sure, check that ATL is actually enabled + case snmpm_config:system_info(audit_trail_log) of + {ok, true} -> + Type = + case {lists:member(read, Value), lists:member(write, Value)} of + {true, true} -> + read_write; + {true, false} -> + read; + {false, true} -> + write; + {false, false} -> + throw({State, {error, {bad_atl_type, Value}}}) + end, + {ok, Type}; + _ -> + {error, not_enabled} + end; +handle_get_log_type(_State) -> + {error, not_enabled}. + +handle_set_log_type(#state{log = {Log, OldValue}} = State, NewType) -> + %% Just to make sure, check that ATL is actually enabled + case snmpm_config:system_info(audit_trail_log) of + {ok, true} -> + NewValue = + case NewType of + read -> + [read]; + write -> + [write]; + read_write -> + [read,write]; + _ -> + throw({State, {error, {bad_atl_type, NewType}}}) + end, + NewState = State#state{log = {Log, NewValue}}, + OldType = + case {lists:member(read, OldValue), + lists:member(write, OldValue)} of + {true, true} -> + read_write; + {true, false} -> + read; + {false, true} -> + write; + {false, false} -> + throw({State, {error, {bad_atl_type, OldValue}}}) + end, + {NewState, {ok, OldType}}; + _ -> + {State, {error, not_enabled}} + end; +handle_set_log_type(State, _NewType) -> + {State, {error, not_enabled}}. + + +%% ------------------------------------------------------------------- + +worker_init(#state{log = undefined = Log}, Verbosity) -> + worker_init2(Log, Verbosity); +worker_init(#state{log = {Name, Log, Type}}, Verbosity) -> + case snmp_log:open(Name, Log) of + {ok, NewLog} -> + worker_init2({Name, NewLog, Type}, Verbosity); + {error, Reason} -> + warning_msg("NetIf worker ~p failed opening ATL: " + "~n ~p", [self(), Reason]), + NewLog = undefined, + worker_init2({Name, NewLog, Type}, Verbosity) + end; +worker_init(State, Verbosity) -> + ?vinfo("worker_init -> entry with invalid data: " + "~n State: ~p" + "~n Verbosity: ~p", [State, Verbosity]), + exit({worker_init, State, Verbosity}). + +worker_init2(Log, Verbosity) -> + put(sname, mnifw), + put(verbosity, Verbosity), + Log. + + +worker_exit(Tag, Info, Result) -> + exit({net_if_worker, {Tag, Info, Result}}). + +handle_worker_exit(_, {_, _, ok}) -> + ok; +handle_worker_exit(Pid, {udp, {Addr, Port}, ExitStatus}) -> + warning_msg("Worker process (~p) terminated " + "while processing (incomming) message from ~w:~w: " + "~n~p", [Pid, Addr, Port, ExitStatus]), + ok; +handle_worker_exit(Pid, {send_pdu, {Domain, Addr, Port}, ExitStatus}) -> + warning_msg("Worker process (~p) terminated " + "while processing (outgoing) pdu for [~w] ~w:~w: " + "~n~p", [Pid, Domain, Addr, Port, ExitStatus]), + ok; +handle_worker_exit(Pid, {inform_response, {Addr, Port}, ExitStatus}) -> + warning_msg("Worker process (~p) terminated " + "while processing (outgoing) inform response for ~w:~w: " + "~n~p", [Pid, Addr, Port, ExitStatus]), + ok; +handle_worker_exit(_, _) -> + ok. + + +%% ------------------------------------------------------------------- + +make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) -> + #pdu{type = 'get-response', + request_id = ReqId, + error_status = noError, + error_index = 0, + varbinds = Vbs}. + + +%% ---------------------------------------------------------------- + +pdu_type_of(#pdu{type = Type}) -> + Type; +pdu_type_of(TrapPdu) when is_record(TrapPdu, trappdu) -> + trap. + + +%% ------------------------------------------------------------------- + +%% At this point this function is used during testing +maybe_process_extra_info(?DEFAULT_EXTRA_INFO) -> + ok; +maybe_process_extra_info({?SNMPM_EXTRA_INFO_TAG, Fun}) + when is_function(Fun, 0) -> + (catch Fun()), + ok; +maybe_process_extra_info(_ExtraInfo) -> + ok. + + +%% ------------------------------------------------------------------- + +t() -> + {A,B,C} = erlang:now(), + A*1000000000+B*1000+(C div 1000). + + +%% ------------------------------------------------------------------- + +logger(undefined, _Type, _Addr, _Port) -> + fun(_) -> + ok + end; +logger({_Name, Log, Types}, Type, Addr, Port) -> + case lists:member(Type, Types) of + true -> + fun(Msg) -> + snmp_log:log(Log, Msg, Addr, Port) + end; + false -> + fun(_) -> + ok + end + end. + + +%% ------------------------------------------------------------------- + +%% info_msg(F, A) -> +%% ?snmpm_info("NET-IF server: " ++ F, A). + +warning_msg(F, A) -> + ?snmpm_warning("NET-IF server: " ++ F, A). + +error_msg(F, A) -> + ?snmpm_error("NET-IF server: " ++ F, A). + + + +%%%------------------------------------------------------------------- + +% get_opt(Key, Opts) -> +% ?vtrace("get option ~w", [Key]), +% snmp_misc:get_option(Key, Opts). + +get_opt(Opts, Key, Def) -> + ?vtrace("get option ~w with default ~p", [Key, Def]), + snmp_misc:get_option(Key, Opts, Def). + + +%% ------------------------------------------------------------------- + +get_info(#state{sock = Id}) -> + ProcSize = proc_mem(self()), + PortInfo = get_port_info(Id), + [{process_memory, ProcSize}, {port_info, PortInfo}]. + +proc_mem(P) when is_pid(P) -> + case (catch erlang:process_info(P, memory)) of + {memory, Sz} when is_integer(Sz) -> + Sz; + _ -> + undefined + end. +%% proc_mem(_) -> +%% undefined. + + +get_port_info(Id) -> + PortInfo = + case (catch erlang:port_info(Id)) of + PI when is_list(PI) -> + [{port_info, PI}]; + _ -> + [] + end, + PortStatus = + case (catch prim_inet:getstatus(Id)) of + {ok, PS} -> + [{port_status, PS}]; + _ -> + [] + end, + PortAct = + case (catch inet:getopts(Id, [active])) of + {ok, PA} -> + [{port_act, PA}]; + _ -> + [] + end, + PortStats = + case (catch inet:getstat(Id)) of + {ok, Stat} -> + [{port_stats, Stat}]; + _ -> + [] + end, + IfList = + case (catch inet:getif(Id)) of + {ok, IFs} -> + [{interfaces, IFs}]; + _ -> + [] + end, + BufSz = + case (catch inet:getopts(Id, [recbuf, sndbuf, buffer])) of + {ok, Sz} -> + [{buffer_size, Sz}]; + _ -> + [] + end, + [{socket, Id}] ++ + IfList ++ + PortStats ++ + PortInfo ++ + PortStatus ++ + PortAct ++ + BufSz. + + +%%----------------------------------------------------------------- +%% Counter functions +%%----------------------------------------------------------------- +init_counters() -> + F = fun(Counter) -> maybe_create_counter(Counter) end, + lists:map(F, counters()). + +reset_counters() -> + F = fun(Counter) -> snmpm_config:reset_stats_counter(Counter) end, + lists:map(F, counters()). + +maybe_create_counter(Counter) -> + snmpm_config:maybe_cre_stats_counter(Counter, 0). + +counters() -> + [ + netIfMsgOutDrops, + netIfMsgInDrops, + netIfPduOutDrops, + netIfPduInDrops + ]. + +inc(Name) -> inc(Name, 1). +inc(Name, N) -> snmpm_config:incr_stats_counter(Name, N). + +%% get_counters() -> +%% Counters = counters(), +%% get_counters(Counters, []). + +%% get_counters([], Acc) -> +%% lists:reverse(Acc); +%% get_counters([Counter|Counters], Acc) -> +%% case snmpm_config:get_stats_counter(Counter) of +%% {ok, CounterVal} -> +%% get_counters(Counters, [{Counter, CounterVal}|Acc]); +%% _ -> +%% get_counters(Counters, Acc) +%% end. + + +%% ---------------------------------------------------------------- + +call(Pid, Req) -> + call(Pid, Req, infinity). + +call(Pid, Req, Timeout) -> + gen_server:call(Pid, Req, Timeout). + +cast(Pid, Msg) -> + gen_server:cast(Pid, Msg). + diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index 2c781810ef..a8c5df0b64 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2011. All Rights Reserved. +%% Copyright Ericsson AB 1997-2012. 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 @@ -21,7 +21,7 @@ -export([ - create/4, create/5, create/6, + create/4, create/5, create/6, open/1, open/2, change_size/2, close/1, sync/1, info/1, log/4, log_to_txt/5, log_to_txt/6, log_to_txt/7, @@ -109,6 +109,24 @@ create(Name, File, SeqNoGen, Size, Repair, Notify) -> {error, {bad_args, Name, File, SeqNoGen, Size, Repair, Notify}}. +%% -- open --- + +%% Open an already existing ( = open ) log + +open(Name) -> + open(Name, #snmp_log{seqno = disabled}). +open(Name, #snmp_log{seqno = SeqNoGen} = _OldLog) -> + %% We include mode in the opts just to be on the safe side + case disk_log:open([{name, Name}, {mode, read_write}]) of + {ok, Log} -> + %% SeqNo must be proprly initiated also + {ok, #snmp_log{id = Log, seqno = SeqNoGen}}; + {repaired, Log, _RecBytes, _BadBytes} -> + {ok, #snmp_log{id = Log, seqno = SeqNoGen}}; + ERROR -> + ERROR + end. + %% -- close --- @@ -394,6 +412,14 @@ log_to_io(Log, FileName, Dir, Mibs, Start) -> log_to_io(Log, FileName, Dir, Mibs, Start, Stop) when is_list(Mibs) -> + ?vtrace("log_to_io -> entry with" + "~n Log: ~p" + "~n FileName: ~p" + "~n Dir: ~p" + "~n Mibs: ~p" + "~n Start: ~p" + "~n Stop: ~p", + [Log, FileName, Dir, Mibs, Start, Stop]), File = filename:join(Dir, FileName), Converter = fun(L) -> do_log_to_io(L, Mibs, Start, Stop) @@ -401,28 +427,10 @@ log_to_io(Log, FileName, Dir, Mibs, Start, Stop) log_convert(Log, File, Converter). -%% -- log_to_plain --- - -%% log_to_plain(Log, FileName, Dir) -> -%% log_to_plain(Log, FileName, Dir, null, null). - -%% log_to_plain(Log, FileName, Dir, Start) -> -%% log_to_plain(Log, FileName, Dir, Start, null). - -%% log_to_plain(Log, FileName, Dir, Start, Stop) -%% when is_list(Mibs) -> -%% File = filename:join(Dir, FileName), -%% Converter = fun(L) -> -%% do_log_to_plain(L, Start, Stop) -%% end, -%% log_convert(Log, File, Converter). - - %% -------------------------------------------------------------------- %% Internal functions %% -------------------------------------------------------------------- - %% -- log_convert --- log_convert(#snmp_log{id = Log}, File, Converter) -> @@ -431,6 +439,26 @@ log_convert(Log, File, Converter) -> do_log_convert(Log, File, Converter). do_log_convert(Log, File, Converter) -> + %% ?vtrace("do_log_converter -> entry with" + %% "~n Log: ~p" + %% "~n File: ~p" + %% "~n disk_log:info(Log): ~p", [Log, File, disk_log:info(Log)]), + {Pid, Ref} = + erlang:spawn_monitor( + fun() -> + Result = do_log_convert2(Log, File, Converter), + exit(Result) + end), + receive + {'DOWN', Ref, process, Pid, Result} -> + %% ?vtrace("do_log_converter -> received result" + %% "~n Result: ~p" + %% "~n disk_log:info(Log): ~p", + %% [Result, disk_log:info(Log)]), + Result + end. + +do_log_convert2(Log, File, Converter) -> %% First check if the caller process has already opened the %% log, because if we close an already open log we will cause %% a runtime error. @@ -439,29 +467,18 @@ do_log_convert(Log, File, Converter) -> Converter(Log); false -> %% Not yet member of the ruling party, apply for membership... - %% If a log is opened as read_write it is not possible to - %% open it as read_only. So, to get around this we open - %% it under a different name... - Log2 = convert_name(Log), - case log_open(Log2, File) of + case log_open(Log, File) of {ok, _} -> - Res = Converter(Log2), - disk_log:close(Log2), + Res = Converter(Log), + disk_log:close(Log), Res; {error, {name_already_open, _}} -> - Converter(Log2); + Converter(Log); {error, Reason} -> {error, {Log, Reason}} end end. -convert_name(Name) when is_list(Name) -> - Name ++ "_tmp"; -convert_name(Name) when is_atom(Name) -> - list_to_atom(atom_to_list(Name) ++ "_tmp"); -convert_name(Name) -> - lists:flatten(io_lib:format("~w_tmp", [Name])). - %% -- do_log_to_text --- @@ -705,21 +722,21 @@ tsf_ge(_Local,Universal,{universal_time,DateTime}) -> tsf_ge(Local,_Universal,DateTime) -> tsf_ge(Local,DateTime). -tsf_ge(TimeStamp,DateTime) -> +tsf_ge(TimeStamp, DateTime) -> T1 = calendar:datetime_to_gregorian_seconds(TimeStamp), T2 = calendar:datetime_to_gregorian_seconds(DateTime), T1 >= T2. -tsf_le(_Local,_Universal,null) -> +tsf_le(_Local, _Universal, null) -> true; -tsf_le(Local,_Universal,{local_time,DateTime}) -> - tsf_le(Local,DateTime); -tsf_le(_Local,Universal,{universal_time,DateTime}) -> - tsf_le(Universal,DateTime); -tsf_le(Local,_Universal,DateTime) -> +tsf_le(Local, _Universal, {local_time, DateTime}) -> + tsf_le(Local, DateTime); +tsf_le(_Local, Universal, {universal_time, DateTime}) -> + tsf_le(Universal, DateTime); +tsf_le(Local, _Universal, DateTime) -> tsf_le(Local,DateTime). -tsf_le(TimeStamp,DateTime) -> +tsf_le(TimeStamp, DateTime) -> T1 = calendar:datetime_to_gregorian_seconds(TimeStamp), T2 = calendar:datetime_to_gregorian_seconds(DateTime), T1 =< T2. @@ -864,11 +881,8 @@ do_std_log_open(Name, File, Size, Repair, Notify) -> log_open(Name, File) -> - Opts = [{name, Name}, - {file, File}, - {type, ?LOG_TYPE}, - {format, ?LOG_FORMAT}, - {mode, read_only}], + Opts = [{name, Name}, + {file, File}], case disk_log:open(Opts) of {error, {badarg, size}} -> {error, no_such_log}; diff --git a/lib/snmp/src/misc/snmp_verbosity.erl b/lib/snmp/src/misc/snmp_verbosity.erl index 85037ba2ae..df5986b7bc 100644 --- a/lib/snmp/src/misc/snmp_verbosity.erl +++ b/lib/snmp/src/misc/snmp_verbosity.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2000-2009. All Rights Reserved. +%% Copyright Ericsson AB 2000-2012. 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 @@ -76,7 +76,7 @@ format_timestamp({_N1, _N2, N3} = 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", + io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w ~w", [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), lists:flatten(FormatDate). @@ -144,6 +144,8 @@ image_of_sname(mse) -> "M-SERVER"; image_of_sname(msew) -> io_lib:format("M-SERVER-worker(~p)", [self()]); image_of_sname(mns) -> "M-NOTE-STORE"; image_of_sname(mnif) -> "M-NET-IF"; +image_of_sname(mnifl) -> "M-NET-IF-LOGGER"; +image_of_sname(mnifw) -> io_lib:format("M-NET-IF-worker(~p)", [self()]); image_of_sname(mconf) -> "M-CONF"; image_of_sname(mgr) -> "MGR"; |