aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src/agent
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp/src/agent')
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl23
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl16
-rw-r--r--lib/snmp/src/agent/snmp_generic.erl4
-rw-r--r--lib/snmp/src/agent/snmp_generic_mnesia.erl5
-rw-r--r--lib/snmp/src/agent/snmp_notification_mib.erl11
-rw-r--r--lib/snmp/src/agent/snmp_standard_mib.erl279
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl204
-rw-r--r--lib/snmp/src/agent/snmp_user_based_sm_mib.erl64
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl259
-rw-r--r--lib/snmp/src/agent/snmpa.erl244
-rw-r--r--lib/snmp/src/agent/snmpa_acm.erl28
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl296
-rw-r--r--lib/snmp/src/agent/snmpa_authentication_service.erl11
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl74
-rw-r--r--lib/snmp/src/agent/snmpa_internal.hrl4
-rw-r--r--lib/snmp/src/agent/snmpa_local_db.erl2
-rw-r--r--lib/snmp/src/agent/snmpa_mib_lib.erl59
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl148
-rw-r--r--lib/snmp/src/agent/snmpa_net_if.erl81
-rw-r--r--lib/snmp/src/agent/snmpa_set_lib.erl63
-rw-r--r--lib/snmp/src/agent/snmpa_target_cache.erl4
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl239
-rw-r--r--lib/snmp/src/agent/snmpa_usm.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_vacm.erl41
24 files changed, 1740 insertions, 440 deletions
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index a2ee7bf0c9..77307aa7ad 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. 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
@@ -18,12 +18,14 @@
%%
-module(snmp_community_mib).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([configure/1, reconfigure/1,
snmpCommunityTable/1, snmpCommunityTable/3,
snmpTargetAddrExtTable/3,
community2vacm/2, vacm2community/2,
get_target_addr_ext_mms/2]).
--export([add_community/5, delete_community/1]).
+-export([add_community/5, add_community/6, delete_community/1]).
-export([check_community/1]).
-include("SNMP-COMMUNITY-MIB.hrl").
@@ -126,12 +128,16 @@ read_community_config_files(Dir) ->
Comms.
check_community({Index, CommunityName, SecName, CtxName, TransportTag}) ->
+ EngineID = get_engine_id(),
+ check_community({Index, CommunityName, SecName,
+ EngineID, CtxName, TransportTag});
+check_community({Index, CommunityName, SecName,
+ EngineID, CtxName, TransportTag}) ->
snmp_conf:check_string(Index,{gt,0}),
snmp_conf:check_string(CommunityName),
snmp_conf:check_string(SecName),
snmp_conf:check_string(CtxName),
snmp_conf:check_string(TransportTag),
- EngineID = get_engine_id(),
Comm = {Index, CommunityName, SecName, EngineID, CtxName, TransportTag,
?'StorageType_nonVolatile', ?'RowStatus_active'},
{ok, Comm};
@@ -171,6 +177,13 @@ table_del_row(Tab, Key) ->
%% FIXME: does not work with mnesia
add_community(Idx, CommName, SecName, CtxName, TransportTag) ->
Community = {Idx, CommName, SecName, CtxName, TransportTag},
+ do_add_community(Community).
+
+add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) ->
+ Community = {Idx, CommName, SecName, EngineId, CtxName, TransportTag},
+ do_add_community(Community).
+
+do_add_community(Community) ->
case (catch check_community(Community)) of
{ok, Row} ->
Key = element(1, Row),
@@ -334,6 +347,8 @@ get_target_addr_ext_mms(TDomain, TAddress, Key) ->
get_target_addr_ext_mms(TDomain, TAddress, NextKey)
end
end.
+
+
%%-----------------------------------------------------------------
%% Instrumentation Functions
%%-----------------------------------------------------------------
@@ -345,7 +360,7 @@ snmpCommunityTable(print) ->
PrintRow =
fun(Prefix, Row) ->
lists:flatten(
- io_lib:format("~sIndex: ~p"
+ io_lib:format("~sIndex: ~p"
"~n~sName: ~p"
"~n~sSecurityName: ~p"
"~n~sContextEngineID: ~p"
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index 0916e2ec74..0d7866d94d 100644
--- a/lib/snmp/src/agent/snmp_framework_mib.erl
+++ b/lib/snmp/src/agent/snmp_framework_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. 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
@@ -37,6 +37,8 @@
%%% over all known contexts.
%%%-----------------------------------------------------------------
%% External exports
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([init/0, configure/1]).
-export([intContextTable/1, intContextTable/3,
intAgentUDPPort/1, intAgentIpAddress/1,
@@ -371,15 +373,27 @@ intAgentUDPPort(Op) ->
intAgentIpAddress(Op) ->
snmp_generic:variable_func(Op, db(intAgentIpAddress)).
+snmpEngineID(print) ->
+ VarAndValue = [{snmpEngineID, snmpEngineID(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineID(Op) ->
snmp_generic:variable_func(Op, db(snmpEngineID)).
+snmpEngineMaxMessageSize(print) ->
+ VarAndValue = [{snmpEngineMaxMessageSize, snmpEngineMaxMessageSize(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineMaxMessageSize(Op) ->
snmp_generic:variable_func(Op, db(snmpEngineMaxMessageSize)).
+snmpEngineBoots(print) ->
+ VarAndValue = [{snmpEngineBoots, snmpEngineBoots(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineBoots(Op) ->
snmp_generic:variable_func(Op, db(snmpEngineBoots)).
+snmpEngineTime(print) ->
+ VarAndValue = [{snmpEngineTime, snmpEngineTime(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
snmpEngineTime(get) ->
{value, get_engine_time()}.
diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl
index 508aa090d9..06afa68d96 100644
--- a/lib/snmp/src/agent/snmp_generic.erl
+++ b/lib/snmp/src/agent/snmp_generic.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. 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
@@ -18,6 +18,8 @@
%%
-module(snmp_generic).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([variable_func/2, variable_func/3, variable_get/1, variable_set/2]).
-export([table_func/2, table_func/4,
table_set_row/5, table_set_cols/3, table_set_cols/4,
diff --git a/lib/snmp/src/agent/snmp_generic_mnesia.erl b/lib/snmp/src/agent/snmp_generic_mnesia.erl
index a73aad5b33..ce42af404b 100644
--- a/lib/snmp/src/agent/snmp_generic_mnesia.erl
+++ b/lib/snmp/src/agent/snmp_generic_mnesia.erl
@@ -121,7 +121,7 @@ table_func(set, RowIndex, Cols, Name) ->
fun() ->
snmp_generic:table_set_row(
{Name, mnesia}, nofunc,
- {snmp_generic_mnesia, table_try_make_consistent},
+ fun table_try_make_consistent/2,
RowIndex, Cols)
end) of
{atomic, Value} ->
@@ -368,7 +368,8 @@ table_set_elements(Name, RowIndex, Cols) ->
_ -> false
end.
table_set_elements(Name, RowIndex, Cols, ConsFunc) ->
- #table_info{index_types = Indexes, first_own_index = FirstOwnIndex} =
+ #table_info{index_types = Indexes,
+ first_own_index = FirstOwnIndex} =
snmp_generic:table_info(Name),
AddCol = if
FirstOwnIndex == 0 -> 2;
diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl
index 16e43f05d7..720ac749b8 100644
--- a/lib/snmp/src/agent/snmp_notification_mib.erl
+++ b/lib/snmp/src/agent/snmp_notification_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. 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
@@ -18,6 +18,8 @@
%%
-module(snmp_notification_mib).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([configure/1, reconfigure/1, invalidate_cache/0,
snmpNotifyTable/1, snmpNotifyTable/3,
snmpNotifyFilterTable/3, snmpNotifyFilterProfileTable/3,
@@ -271,9 +273,12 @@ find_targets(Key, TargAddrs, Db, Res) ->
get_targets([{TagList, Addr, TargetName, Params, Timeout, Retry}|T],
Tag, Type, Name) ->
case snmp_misc:is_tag_member(Tag, TagList) of
- true -> [{Name, {Addr, TargetName, Params, type(Type, Timeout, Retry)}}|
- get_targets(T, Tag, Type, Name)];
+ true ->
+ ?vtrace("tag ~w *is* member", [Tag]),
+ [{Name, {Addr, TargetName, Params, type(Type, Timeout, Retry)}}|
+ get_targets(T, Tag, Type, Name)];
false ->
+ ?vtrace("tag ~w is *not* member", [Tag]),
get_targets(T, Tag, Type, Name)
end;
get_targets([], _Tag, _Type, _Name) ->
diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl
index 3928a8afe6..b6834d278c 100644
--- a/lib/snmp/src/agent/snmp_standard_mib.erl
+++ b/lib/snmp/src/agent/snmp_standard_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2010. 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
@@ -33,11 +33,35 @@
-define(disabled, 2).
%% External exports
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([configure/1, reconfigure/1, reset/0, sys_up_time/0, sys_up_time/1,
snmp_enable_authen_traps/1, snmp_enable_authen_traps/2,
sys_object_id/1, sys_object_id/2, sys_or_table/3,
variable_func/1, variable_func/2,
inc/1, inc/2]).
+-export([sysDescr/1, sysContact/1, sysName/1, sysLocation/1,
+ sysServices/1, sysUpTime/1, snmpEnableAuthenTraps/1,
+ sysObjectID/1,
+ snmpInPkts/1, snmpOutPkts/1,
+ snmpInBadVersions/1,
+ snmpInBadCommunityNames/1, snmpInBadCommunityUses/1,
+ snmpInASNParseErrs/1,
+ snmpInTooBigs/1,
+ snmpInNoSuchNames/1, snmpInBadValues/1,
+ snmpInReadOnlys/1, snmpInGenErrs/1,
+ snmpInTotalReqVars/1, snmpInTotalSetVars/1,
+ snmpInGetRequests/1, snmpInSetRequests/1,
+ snmpInGetNexts/1,
+ snmpInGetResponses/1, snmpInTraps/1,
+ snmpOutTooBigs/1,
+ snmpOutNoSuchNames/1,
+ snmpOutBadValues/1,
+ snmpOutGenErrs/1,
+ snmpOutGetRequests/1, snmpOutSetRequests/1,
+ snmpOutGetNexts/1,
+ snmpOutGetResponses/1,
+ snmpOutTraps/1]).
-export([dummy/1, snmp_set_serial_no/1, snmp_set_serial_no/2]).
-export([add_agent_caps/2, del_agent_caps/1, get_agent_caps/0]).
-export([check_standard/1]).
@@ -200,18 +224,257 @@ variable_func(get, Name) ->
inc(Name) -> inc(Name, 1).
inc(Name, N) -> ets:update_counter(snmp_agent_table, Name, N).
+
+sysDescr(print) ->
+ VarAndValue = [{sysDescr, sysDescr(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysDescr(get) ->
+ VarDB = db(sysDescr),
+ snmp_generic:variable_get(VarDB).
+
+
+sysContact(print) ->
+ VarAndValue = [{sysContact, sysContact(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysContact(get) ->
+ VarDB = db(sysContact),
+ snmp_generic:variable_get(VarDB).
+
+
+sysName(print) ->
+ VarAndValue = [{sysName, sysName(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysName(get) ->
+ VarDB = db(sysName),
+ snmp_generic:variable_get(VarDB).
+
+
+sysLocation(print) ->
+ VarAndValue = [{sysLocation, sysLocation(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysLocation(get) ->
+ VarDB = db(sysLocation),
+ snmp_generic:variable_get(VarDB).
+
+
+sysServices(print) ->
+ VarAndValue = [{sysServices, sysServices(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+sysServices(get) ->
+ VarDB = db(sysServices),
+ snmp_generic:variable_get(VarDB).
+
+
+snmpInPkts(print) ->
+ gen_counter(print, snmpInPkts);
+snmpInPkts(get) ->
+ gen_counter(get, snmpInPkts).
+
+
+snmpOutPkts(print) ->
+ gen_counter(print, snmpOutPkts);
+snmpOutPkts(get) ->
+ gen_counter(get, snmpOutPkts).
+
+
+snmpInASNParseErrs(print) ->
+ gen_counter(print, snmpInASNParseErrs);
+snmpInASNParseErrs(get) ->
+ gen_counter(get, snmpInASNParseErrs).
+
+
+snmpInBadCommunityNames(print) ->
+ gen_counter(print, snmpInBadCommunityNames);
+snmpInBadCommunityNames(get) ->
+ gen_counter(get, snmpInBadCommunityNames).
+
+
+snmpInBadCommunityUses(print) ->
+ gen_counter(print, snmpInBadCommunityUses);
+
+snmpInBadCommunityUses(get) ->
+ gen_counter(get, snmpInBadCommunityUses).
+
+
+snmpInBadVersions(print) ->
+ gen_counter(print, snmpInBadVersions);
+snmpInBadVersions(get) ->
+ gen_counter(get, snmpInBadVersions).
+
+
+snmpInTooBigs(print) ->
+ gen_counter(print, snmpInTooBigs);
+snmpInTooBigs(get) ->
+ gen_counter(get, snmpInTooBigs).
+
+
+snmpInNoSuchNames(print) ->
+ gen_counter(print, snmpInNoSuchNames);
+snmpInNoSuchNames(get) ->
+ gen_counter(get, snmpInNoSuchNames).
+
+
+snmpInBadValues(print) ->
+ gen_counter(print, snmpInBadValues);
+snmpInBadValues(get) ->
+ gen_counter(get, snmpInBadValues).
+
+
+snmpInReadOnlys(print) ->
+ gen_counter(print, snmpInReadOnlys);
+snmpInReadOnlys(get) ->
+ gen_counter(get, snmpInReadOnlys).
+
+
+snmpInGenErrs(print) ->
+ gen_counter(print, snmpInGenErrs);
+snmpInGenErrs(get) ->
+ gen_counter(get, snmpInGenErrs).
+
+
+snmpInTotalReqVars(print) ->
+ gen_counter(print, snmpInTotalReqVars);
+snmpInTotalReqVars(get) ->
+ gen_counter(get, snmpInTotalReqVars).
+
+
+snmpInTotalSetVars(print) ->
+ gen_counter(print, snmpInTotalSetVars);
+snmpInTotalSetVars(get) ->
+ gen_counter(get, snmpInTotalSetVars).
+
+
+snmpInGetRequests(print) ->
+ gen_counter(print, snmpInGetRequests);
+snmpInGetRequests(get) ->
+ gen_counter(get, snmpInGetRequests).
+
+
+snmpInSetRequests(print) ->
+ gen_counter(print, snmpInSetRequests);
+snmpInSetRequests(get) ->
+ gen_counter(get, snmpInSetRequests).
+
+
+snmpInGetNexts(print) ->
+ gen_counter(print, snmpInGetNexts);
+snmpInGetNexts(get) ->
+ gen_counter(get, snmpInGetNexts).
+
+
+snmpInGetResponses(print) ->
+ gen_counter(print, snmpInGetResponses);
+snmpInGetResponses(get) ->
+ gen_counter(get, snmpInGetResponses).
+
+
+snmpInTraps(print) ->
+ gen_counter(print, snmpInTraps);
+snmpInTraps(get) ->
+ gen_counter(get, snmpInTraps).
+
+
+snmpOutTooBigs(print) ->
+ gen_counter(print, snmpOutTooBigs);
+snmpOutTooBigs(get) ->
+ gen_counter(get, snmpOutTooBigs).
+
+
+snmpOutNoSuchNames(print) ->
+ gen_counter(print, snmpOutNoSuchNames);
+snmpOutNoSuchNames(get) ->
+ gen_counter(get, snmpOutNoSuchNames).
+
+
+snmpOutBadValues(print) ->
+ gen_counter(print, snmpOutBadValues);
+snmpOutBadValues(get) ->
+ gen_counter(get, snmpOutBadValues).
+
+
+snmpOutGenErrs(print) ->
+ gen_counter(print, snmpOutGenErrs);
+snmpOutGenErrs(get) ->
+ gen_counter(get, snmpOutGenErrs).
+
+
+snmpOutGetRequests(print) ->
+ gen_counter(print, snmpOutGetRequests);
+snmpOutGetRequests(get) ->
+ gen_counter(get, snmpOutGetRequests).
+
+
+snmpOutSetRequests(print) ->
+ gen_counter(print, snmpOutSetRequests);
+snmpOutSetRequests(get) ->
+ gen_counter(get, snmpOutSetRequests).
+
+
+snmpOutGetNexts(print) ->
+ gen_counter(print, snmpOutGetNexts);
+snmpOutGetNexts(get) ->
+ gen_counter(get, snmpOutGetNexts).
+
+
+snmpOutGetResponses(print) ->
+ gen_counter(print, snmpOutGetResponses);
+snmpOutGetResponses(get) ->
+ gen_counter(get, snmpOutGetResponses).
+
+
+snmpOutTraps(print) ->
+ gen_counter(print, snmpOutTraps);
+snmpOutTraps(get) ->
+ gen_counter(get, snmpOutTraps).
+
+
+gen_counter(print, Counter) ->
+ Val = gen_counter(get, Counter),
+ VarAndValue = [{Counter, Val}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
+gen_counter(get, Counter) ->
+ variable_func(get, Counter).
+
+
%%-----------------------------------------------------------------
%% This is the instrumentation function for sysUpTime.
%%-----------------------------------------------------------------
+sysUpTime(print) ->
+ sys_up_time(print);
+sysUpTime(get) ->
+ sys_up_time(get).
+
sys_up_time() ->
snmpa:sys_up_time().
+sys_up_time(print) ->
+ VarAndValue = [{sysUpTime, sys_up_time(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
sys_up_time(get) ->
{value, snmpa:sys_up_time()}.
+
%%-----------------------------------------------------------------
%% This is the instrumentation function for snmpEnableAuthenTraps
%%-----------------------------------------------------------------
+
+snmpEnableAuthenTraps(print) ->
+ snmp_enable_authen_traps(print);
+snmpEnableAuthenTraps(get) ->
+ snmp_enable_authen_traps(get).
+
+
+snmp_enable_authen_traps(print) ->
+ VarAndValue = [{snmpEnableAuthenTraps, snmp_enable_authen_traps(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
snmp_enable_authen_traps(new) ->
snmp_generic:variable_func(new, db(snmpEnableAuthenTraps));
@@ -224,9 +487,19 @@ snmp_enable_authen_traps(get) ->
snmp_enable_authen_traps(set, NewVal) ->
snmp_generic:variable_func(set, NewVal, db(snmpEnableAuthenTraps)).
+
%%-----------------------------------------------------------------
-%% This is the instrumentation function for sysObjectId
+%% This is the instrumentation function for sysObjectID
%%-----------------------------------------------------------------
+sysObjectID(print) ->
+ sys_object_id(print);
+sysObjectID(get) ->
+ sys_object_id(get).
+
+sys_object_id(print) ->
+ VarAndValue = [{sysObjectID, sys_object_id(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
sys_object_id(new) ->
snmp_generic:variable_func(new, db(sysObjectID));
@@ -239,6 +512,7 @@ sys_object_id(get) ->
sys_object_id(set, NewVal) ->
snmp_generic:variable_func(set, NewVal, db(sysObjectID)).
+
%%-----------------------------------------------------------------
%% This is a dummy instrumentation function for objects like
%% snmpTrapOID, that is accessible-for-notify, with different
@@ -247,6 +521,7 @@ sys_object_id(set, NewVal) ->
%%-----------------------------------------------------------------
dummy(_Op) -> ok.
+
%%-----------------------------------------------------------------
%% This is the instrumentation function for snmpSetSerialNo.
%% It is always volatile.
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index d5c4ec2578..a45db89c09 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2011. 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
@@ -18,22 +18,26 @@
%%
-module(snmp_target_mib).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([configure/1, reconfigure/1,
snmpTargetSpinLock/1, snmpTargetSpinLock/2,
snmpTargetAddrTable/1, snmpTargetAddrTable/3,
snmpTargetParamsTable/1, snmpTargetParamsTable/3,
get_target_addrs/0, get_target_engine_id/1, set_target_engine_id/2,
is_valid_tag/3, get/3, table_next/2]).
--export([add_addr/10, delete_addr/1,
+-export([add_addr/10, add_addr/11, delete_addr/1,
add_params/5, delete_params/1]).
-export([check_target_addr/1, check_target_params/1]).
+-export([default_domain/0]).
--include("snmp_types.hrl").
--include("snmp_tables.hrl").
--include("SNMP-TARGET-MIB.hrl").
--include("SNMPv2-TC.hrl").
--include("SNMPv2-TM.hrl").
--include("SNMP-FRAMEWORK-MIB.hrl").
+-include_lib("snmp/include/snmp_types.hrl").
+-include_lib("snmp/include/snmp_tables.hrl").
+-include_lib("snmp/include/SNMP-TARGET-MIB.hrl").
+-include_lib("snmp/include/SNMPv2-TC.hrl").
+-include_lib("snmp/include/SNMPv2-TM.hrl").
+-include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl").
+-include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl").
-define(VMODULE,"TARGET-MIB").
-include("snmp_verbosity.hrl").
@@ -53,6 +57,12 @@
%%-----------------------------------------------------------------
+
+default_domain() ->
+ snmpUDPDomain.
+
+
+%%-----------------------------------------------------------------
%% Func: configure/1
%% Args: Dir is the directory where the configuration files are found.
%% Purpose: If the tables doesn't exist, this function reads
@@ -143,39 +153,51 @@ read_target_config_files(Dir) ->
%% {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId,
%% TMask, MMS}
%%-----------------------------------------------------------------
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS}) ->
+
+check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
+ Params, EngineId, TMask, MMS}) ->
?vtrace("check target address with:"
- "~n Name: ~s"
- "~n Ip: ~p"
- "~n Udp: ~p"
- "~n Timeout: ~p"
- "~n RetryCount: ~p"
- "~n TagList: ~p"
- "~n Params: ~p"
- "~n EngineId: ~p"
- "~n TMask: ~p"
- "~n MMS: ~p",
- [Name,Ip,Udp,Timeout,RetryCount,
- TagList,Params,EngineId,TMask,MMS]),
+ "~n Name: ~s"
+ "~n Domain: ~p"
+ "~n Ip: ~p"
+ "~n Udp: ~p"
+ "~n Timeout: ~p"
+ "~n RetryCount: ~p"
+ "~n TagList: ~p"
+ "~n Params: ~p"
+ "~n EngineId: ~p"
+ "~n TMask: ~p"
+ "~n MMS: ~p",
+ [Name,
+ Domain, Ip, Udp,
+ Timeout, RetryCount,
+ TagList, Params, EngineId, TMask, MMS]),
snmp_conf:check_string(Name,{gt,0}),
- snmp_conf:check_ip(Ip),
+ snmp_conf:check_domain(Domain),
+ snmp_conf:check_ip(Domain, Ip),
snmp_conf:check_integer(Udp, {gt, 0}),
snmp_conf:check_integer(Timeout, {gte, 0}),
snmp_conf:check_integer(RetryCount, {gte,0}),
snmp_conf:check_string(TagList),
snmp_conf:check_string(Params),
check_engine_id(EngineId),
- TAddr = Ip ++ [Udp div 256, Udp rem 256],
- check_mask(TMask, TAddr),
+ TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp),
+ TDomain = snmp_conf:mk_tdomain(Domain),
+ check_tmask(TDomain, TMask, TAddress),
snmp_conf:check_packet_size(MMS),
?vtrace("check target address done",[]),
-
- Addr = {Name, ?snmpUDPDomain, TAddr, Timeout,
+ Addr = {Name, TDomain, TAddress, Timeout,
RetryCount, TagList, Params,
?'StorageType_nonVolatile', ?'RowStatus_active', EngineId,
TMask, MMS}, % Values for Augmenting table in SNMP-COMMUNITY-MIB
{ok, Addr};
+check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
+ Params, EngineId, TMask, MMS}) ->
+ Domain = default_domain(),
+ check_target_addr({Name,
+ Domain, Ip, Udp,
+ Timeout, RetryCount, TagList,
+ Params, EngineId, TMask, MMS});
check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
EngineId}) ->
check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
@@ -198,12 +220,13 @@ check_engine_id(discovery) ->
check_engine_id(EngineId) ->
snmp_conf:check_string(EngineId).
-check_mask([], _TAddr) ->
+
+check_tmask(_TDomain, [], _TAddress) ->
ok;
-check_mask(TMask, TAddr) when length(TMask) == length(TAddr) ->
- snmp_conf:check_taddress(TMask);
-check_mask(TMask, _TAddr) ->
- throw({error, {invalid_mask, TMask}}).
+check_tmask(TDomain, TMask, TAddress) when length(TMask) =:= length(TAddress) ->
+ snmp_conf:check_taddress(TDomain, TMask);
+check_tmask(_TDomain, TMask, _TAddr) ->
+ throw({error, {invalid_tmask, TMask}}).
%%-----------------------------------------------------------------
@@ -265,7 +288,13 @@ table_del_row(Tab, Key) ->
add_addr(Name, Ip, Port, Timeout, Retry, TagList,
Params, EngineId, TMask, MMS) ->
- Addr = {Name, Ip, Port, Timeout, Retry, TagList,
+ Domain = default_domain(),
+ add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList,
+ Params, EngineId, TMask, MMS).
+
+add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList,
+ Params, EngineId, TMask, MMS) ->
+ Addr = {Name, Domain, Ip, Port, Timeout, Retry, TagList,
Params, EngineId, TMask, MMS},
case (catch check_target_addr(Addr)) of
{ok, Row} ->
@@ -345,8 +374,11 @@ maybe_create_var(Var) ->
init_var(Var) -> ets:insert(snmp_agent_table, {Var, 0}).
vars() ->
- [snmpUnavailableContexts,
- snmpUnknownContexts].
+ [
+ snmpUnavailableContexts,
+ snmpUnknownContexts
+ ].
+
%%-----------------------------------------------------------------
%% API functions
@@ -357,10 +389,18 @@ is_valid_tag(Tag, TDomain, TAddress) ->
is_valid_tag(TDomain, TAddress, Tag, []).
is_valid_tag(TDomain, TAddress, Tag, Key) ->
+ ?vtrace("is_valid_tag -> entry with"
+ "~n TDomain: ~p"
+ "~n TAddress: ~p"
+ "~n Tag: ~p"
+ "~n Key: ~p", [TDomain, TAddress, Tag, Key]),
case table_next(snmpTargetAddrTable, Key) of
endOfTable ->
+ ?vtrace("is_valid_tag -> endOfTable", []),
false;
NextKey ->
+ ?vtrace("is_valid_tag -> next key found"
+ "~n NextKey: ~p", [NextKey]),
case get(snmpTargetAddrTable, NextKey, [?snmpTargetAddrTDomain,
?snmpTargetAddrTAddress,
?snmpTargetAddrTagList,
@@ -369,6 +409,8 @@ is_valid_tag(TDomain, TAddress, Tag, Key) ->
{value, TAddress}, % RFC2576: chapters 5.2.1 & 5.3
{value, TagList},
{value, []}] ->
+ ?vtrace("is_valid_tag -> found with exact match"
+ "~n TagList: ~p", [TagList]),
case snmp_misc:is_tag_member(Tag, TagList) of
true ->
?vtrace("is_valid_tag -> exact: "
@@ -384,9 +426,14 @@ is_valid_tag(TDomain, TAddress, Tag, Key) ->
{value, TAddress2},
{value, TagList},
{value, TMask}] when TMask =/= [] ->
+ ?vtrace("is_valid_tag -> found with exact match"
+ "~n TagList: ~p"
+ "~n TMask: ~p", [TagList, TMask]),
case snmp_misc:is_tmask_match(TAddress, TAddress2,
TMask) of
true ->
+ ?vtrace("is_valid_tag -> "
+ "tmask match - now check tag member", []),
case snmp_misc:is_tag_member(Tag, TagList) of
true ->
?vtrace("is_valid_tag -> masked: "
@@ -399,10 +446,12 @@ is_valid_tag(TDomain, TAddress, Tag, Key) ->
Tag, NextKey)
end;
false ->
+ ?vtrace("is_valid_tag -> tmask NO match", []),
is_valid_tag(TDomain, TAddress,
Tag, NextKey)
end;
_ ->
+ ?vtrace("is_valid_tag -> not found - try next", []),
is_valid_tag(TDomain, TAddress, Tag, NextKey)
end
end.
@@ -521,6 +570,10 @@ set_target_engine_id(TargetAddrName, EngineId) ->
%%-----------------------------------------------------------------
%% Instrumentation Functions
%%-----------------------------------------------------------------
+snmpTargetSpinLock(print) ->
+ VarAndValue = [{snmpTargetSpinLock, snmpTargetSpinLock(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
snmpTargetSpinLock(new) ->
snmp_generic:variable_func(new, {snmpTargetSpinLock, volatile}),
{A1,A2,A3} = erlang:now(),
@@ -567,7 +620,9 @@ snmpTargetAddrTable(print) ->
[Prefix, element(?snmpTargetAddrName, Row),
Prefix, element(?snmpTargetAddrTDomain, Row),
case element(?snmpTargetAddrTDomain, Row) of
- ?snmpUDPDomain -> udp;
+ ?snmpUDPDomain -> snmpUDPDomain;
+ ?transportDomainUdpIpv4 -> transportDomainUdpIpv4;
+ ?transportDomainUdpIpv6 -> transportDomainUdpIpv6;
_ -> undefined
end,
Prefix, element(?snmpTargetAddrTAddress, Row),
@@ -601,12 +656,9 @@ snmpTargetAddrTable(print) ->
?'snmpTargetAddrRowStatus_active' -> active;
_ -> undefined
end,
- Prefix,
- element(?snmpTargetAddrEngineId, Row),
- Prefix,
- element(?snmpTargetAddrTMask, Row),
- Prefix,
- element(?snmpTargetAddrMMS, Row)]))
+ Prefix, element(?snmpTargetAddrEngineId, Row),
+ Prefix, element(?snmpTargetAddrTMask, Row),
+ Prefix, element(?snmpTargetAddrMMS, Row)]))
end,
snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow);
%% Op == new | delete
@@ -619,14 +671,14 @@ snmpTargetAddrTable(get, RowIndex, Cols) ->
snmpTargetAddrTable(get_next, RowIndex, Cols) ->
next(snmpTargetAddrTable, RowIndex, Cols);
snmpTargetAddrTable(set, RowIndex, Cols0) ->
- %% BMK BMK BMK
- case (catch verify_targetAddrTable_cols(Cols0, [])) of
+ %% BMK BMK
+ case (catch verify_targetAddrTable_cols(Cols0)) of
{ok, Cols} ->
snmp_notification_mib:invalidate_cache(),
%% Add columns for augmenting table snmpTargetAddrExtTable and for
- %% target engine ID. Target engine ID is set to "". The function
+ %% target engine ID. Target engine ID is set to "". The function
%% get_target_engine_id will return "" unless a value is set using
- %% set_target_engine_id. If it is "" Informs can't be sent to the
+ %% set_target_engine_id. If it is "" Informs can't be sent to the
%% target.
NCols = Cols ++ [{?snmpTargetAddrEngineId, ""},
{?snmpTargetAddrTMask, []},
@@ -637,12 +689,12 @@ snmpTargetAddrTable(set, RowIndex, Cols0) ->
Error
end;
snmpTargetAddrTable(is_set_ok, RowIndex, Cols0) ->
- case (catch verify_targetAddrTable_cols(Cols0, [])) of
+ case (catch verify_targetAddrTable_cols(Cols0)) of
{ok, Cols} ->
%% Add columns for augmenting table snmpTargetAddrExtTable and for
- %% target engine ID. Target engine ID is set to "". The function
+ %% target engine ID. Target engine ID is set to "". The function
%% get_target_engine_id will return "" unless a value is set using
- %% set_target_engine_id. If it is "" Informs can't be sent to the
+ %% set_target_engine_id. If it is "" Informs can't be sent to the
%% target.
NCols = Cols ++ [{?snmpTargetAddrEngineId, ""},
{?snmpTargetAddrTMask, []},
@@ -656,55 +708,83 @@ snmpTargetAddrTable(Op, Arg1, Arg2) ->
Db = db(snmpTargetAddrTable),
snmp_generic:table_func(Op, Arg1, Arg2, Db).
+verify_targetAddrTable_cols(Cols) ->
+ ValidCols0 = verify_targetAddrTable_cols(Cols, []),
+ %% Make a last pass to verify TDomain and TAddress.
+ ValidCols0.
+
verify_targetAddrTable_cols([], Cols) ->
{ok, lists:reverse(Cols)};
-verify_targetAddrTable_cols([{Col, Val0}|Cols], Acc) ->
- Val = verify_targetAddrTable_col(Col, Val0),
- verify_targetAddrTable_cols(Cols, [{Col, Val}|Acc]).
+verify_targetAddrTable_cols([{Col, Val0}|Cols], ValidCols) ->
+ Val = verify_targetAddrTable_col(Col, Val0, ValidCols),
+ verify_targetAddrTable_cols(Cols, [{Col, Val}|ValidCols]).
-verify_targetAddrTable_col(?snmpTargetAddrName, Name) ->
+verify_targetAddrTable_col(?snmpTargetAddrName, Name, _) ->
case (catch snmp_conf:check_string(Name)) of
ok ->
Name;
_ ->
wrongValue(?snmpTargetAddrName)
end;
-verify_targetAddrTable_col(?snmpTargetAddrTAddress, TAddr) ->
- case (catch snmp_conf:check_taddress(TAddr)) of
+verify_targetAddrTable_col(?snmpTargetAddrTDomain, TDomain, _) ->
+ case (catch snmp_conf:check_tdomain(TDomain)) of
ok ->
- TAddr;
+ TDomain;
_ ->
- wrongValue(?snmpTargetAddrTAddress)
+ wrongValue(?snmpTargetAddrTDomain)
+ end;
+%% In order to (properly) validate the TAddress,
+%% the TDomain must already have been validated
+%% (the format of TAddress depends on TDomain).
+verify_targetAddrTable_col(?snmpTargetAddrTAddress, TAddress, ValidCols) ->
+ case lists:keysearch(?snmpTargetAddrTDomain, 1, ValidCols) of
+ {value, {?snmpTargetAddrTDomain, TDomain}} ->
+ case (catch snmp_conf:check_taddress(TDomain, TAddress)) of
+ ok ->
+ TAddress;
+ _ ->
+ wrongValue(?snmpTargetAddrTAddress)
+ end;
+ false ->
+ %% The user did not provide us with a TDomain, which
+ %% must mean that he/she intends to use the old domain.
+ TDomain = snmp_conf:mk_tdomain(default_domain()),
+ case (catch snmp_conf:check_taddress(TDomain, TAddress)) of
+ ok ->
+ TAddress;
+ _ ->
+ wrongValue(?snmpTargetAddrTAddress)
+ end
end;
-verify_targetAddrTable_col(?snmpTargetAddrTimeout, Timeout) ->
+verify_targetAddrTable_col(?snmpTargetAddrTimeout, Timeout, _) ->
case (catch snmp_conf:check_integer(Timeout)) of
ok when Timeout >= 0 ->
Timeout;
_ ->
wrongValue(?snmpTargetAddrTimeout)
end;
-verify_targetAddrTable_col(?snmpTargetAddrRetryCount, Retry) ->
+verify_targetAddrTable_col(?snmpTargetAddrRetryCount, Retry, _) ->
case (catch snmp_conf:check_integer(Retry)) of
ok when Retry >= 0 ->
Retry;
_ ->
wrongValue(?snmpTargetAddrRetryCount)
end;
-verify_targetAddrTable_col(?snmpTargetAddrTagList, TagList) ->
+verify_targetAddrTable_col(?snmpTargetAddrTagList, TagList, _) ->
case (catch snmp_conf:check_string(TagList)) of
ok ->
TagList;
_ ->
wrongValue(?snmpTargetAddrTagList)
end;
-verify_targetAddrTable_col(?snmpTargetAddrParams, Params) ->
+verify_targetAddrTable_col(?snmpTargetAddrParams, Params, _) ->
case (catch snmp_conf:check_string(Params)) of
ok ->
Params;
_ ->
wrongValue(?snmpTargetAddrParams)
end;
-verify_targetAddrTable_col(_, Val) ->
+verify_targetAddrTable_col(_, Val, _) ->
Val.
diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
index 7b881f888c..69cebc858b 100644
--- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
+++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2010. 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
@@ -18,12 +18,20 @@
%%
-module(snmp_user_based_sm_mib).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([configure/1, reconfigure/1,
usmUserSpinLock/1, usmUserSpinLock/2,
usmUserTable/1, usmUserTable/3,
table_next/2,
is_engine_id_known/1, get_user/2, get_user_from_security_name/2,
mk_key_change/3, mk_key_change/5, extract_new_key/3, mk_random/1]).
+-export([usmStatsUnsupportedSecLevels/1,
+ usmStatsNotInTimeWindows/1,
+ usmStatsUnknownUserNames/1,
+ usmStatsUnknownEngineIDs/1,
+ usmStatsWrongDigests/1,
+ usmStatsDecryptionErrors/1]).
-export([add_user/1, add_user/13, delete_user/1]).
%% Internal
@@ -301,6 +309,54 @@ gc_tabs() ->
%%-----------------------------------------------------------------
%% Counter functions
%%-----------------------------------------------------------------
+
+usmStatsUnsupportedSecLevels(print) ->
+ VarAndValue = [{usmStatsUnsupportedSecLevels,
+ usmStatsUnsupportedSecLevels(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsUnsupportedSecLevels(get) ->
+ get_counter(usmStatsUnsupportedSecLevels).
+
+usmStatsNotInTimeWindows(print) ->
+ VarAndValue = [{usmStatsNotInTimeWindows, usmStatsNotInTimeWindows(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsNotInTimeWindows(get) ->
+ get_counter(usmStatsNotInTimeWindows).
+
+usmStatsUnknownUserNames(print) ->
+ VarAndValue = [{usmStatsUnknownUserNames, usmStatsUnknownUserNames(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsUnknownUserNames(get) ->
+ get_counter(usmStatsUnknownUserNames).
+
+usmStatsUnknownEngineIDs(print) ->
+ VarAndValue = [{usmStatsUnknownEngineIDs, usmStatsUnknownEngineIDs(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsUnknownEngineIDs(get) ->
+ get_counter(usmStatsUnknownEngineIDs).
+
+usmStatsWrongDigests(print) ->
+ VarAndValue = [{usmStatsWrongDigests, usmStatsWrongDigests(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsWrongDigests(get) ->
+ get_counter(usmStatsWrongDigests).
+
+usmStatsDecryptionErrors(print) ->
+ VarAndValue = [{usmStatsDecryptionErrors, usmStatsDecryptionErrors(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+usmStatsDecryptionErrors(get) ->
+ get_counter(usmStatsDecryptionErrors).
+
+
+get_counter(Name) ->
+ case (catch ets:lookup(snmp_agent_table, Name)) of
+ [{_, Val}] ->
+ {value, Val};
+ _ ->
+ genErr
+ end.
+
+
init_vars() -> lists:map(fun maybe_create_var/1, vars()).
maybe_create_var(Var) ->
@@ -321,6 +377,7 @@ vars() ->
usmStatsDecryptionErrors
].
+
%%-----------------------------------------------------------------
%% API functions
%%-----------------------------------------------------------------
@@ -372,6 +429,11 @@ get_user_from_security_name(EngineID, SecName) ->
%%-----------------------------------------------------------------
%% Instrumentation Functions
%%-----------------------------------------------------------------
+
+usmUserSpinLock(print) ->
+ VarAndValue = [{usmUserSpinLock, usmUserSpinLock(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
usmUserSpinLock(new) ->
snmp_generic:variable_func(new, {usmUserSpinLock, volatile}),
{A1,A2,A3} = erlang:now(),
diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
index 873ab00545..2cee91b081 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -18,6 +18,8 @@
%%
-module(snmp_view_based_acm_mib).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([configure/1, reconfigure/1, table_next/2, get/3]).
-export([vacmAccessTable/1, vacmAccessTable/3,
@@ -131,7 +133,6 @@ check_vacm({vacmSecurityToGroup, SecModel, SecName, GroupName}) ->
{ok, SecM} = snmp_conf:check_sec_model(SecModel, []),
snmp_conf:check_string(SecName),
snmp_conf:check_string(GroupName),
-
Vacm = {SecM, SecName, GroupName,
?'StorageType_nonVolatile', ?'RowStatus_active'},
{ok, {vacmSecurityToGroup, Vacm}};
@@ -179,15 +180,22 @@ init_tabs(Sec2Group, Access, View) ->
snmpa_local_db:table_delete(db(vacmSecurityToGroupTable)),
snmpa_local_db:table_create(db(vacmSecurityToGroupTable)),
init_sec2group_table(Sec2Group),
+
+ ?vdebug("create vacm access table",[]),
+ snmpa_vacm:cleanup(),
init_access_table(Access),
+
?vdebug("create vacm view-tree-family table",[]),
snmpa_local_db:table_delete(db(vacmViewTreeFamilyTable)),
snmpa_local_db:table_create(db(vacmViewTreeFamilyTable)),
- init_view_table(View).
+ init_view_table(View),
+
+ ?vdebug("table(s) initiated",[]),
+ ok.
init_sec2group_table([Row | T]) ->
-% ?vtrace("init security-to-group table: "
-% "~n Row: ~p",[Row]),
+%% ?vtrace("init security-to-group table: "
+%% "~n Row: ~p",[Row]),
Key1 = element(1, Row),
Key2 = element(2, Row),
Key = [Key1, length(Key2) | Key2],
@@ -195,22 +203,20 @@ init_sec2group_table([Row | T]) ->
init_sec2group_table(T);
init_sec2group_table([]) -> true.
-init_access_table([{GN, Prefix, Model, Level, Row} | T]) ->
-% ?vtrace("init access table: "
-% "~n GN: ~p"
-% "~n Prefix: ~p"
-% "~n Model: ~p"
-% "~n Level: ~p"
-% "~n Row: ~p",[GN, Prefix, Model, Level, Row]),
- Key = [length(GN) | GN] ++ [length(Prefix) | Prefix] ++ [Model, Level],
- snmpa_vacm:insert([{Key, Row}], false),
- init_access_table(T);
-init_access_table([]) ->
- snmpa_vacm:dump_table().
+make_access_key(GN, Prefix, Model, Level) ->
+ [length(GN) | GN] ++ [length(Prefix) | Prefix] ++ [Model, Level].
+
+make_access_entry({GN, Prefix, Model, Level, Row}) ->
+ Key = make_access_key(GN, Prefix, Model, Level),
+ {Key, Row}.
+
+init_access_table(TableData) ->
+ TableData2 = [make_access_entry(E) || E <- TableData],
+ snmpa_vacm:insert(TableData2, true).
init_view_table([Row | T]) ->
-% ?vtrace("init view table: "
-% "~n Row: ~p",[Row]),
+%% ?vtrace("init view table: "
+%% "~n Row: ~p",[Row]),
Key1 = element(1, Row),
Key2 = element(2, Row),
Key = [length(Key1) | Key1] ++ [length(Key2) | Key2],
@@ -239,6 +245,7 @@ add_sec2group(SecModel, SecName, GroupName) ->
Key = [Key1, length(Key2) | Key2],
case table_cre_row(vacmSecurityToGroupTable, Key, Row) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
false ->
{error, create_failed}
@@ -252,6 +259,7 @@ add_sec2group(SecModel, SecName, GroupName) ->
delete_sec2group(Key) ->
case table_del_row(vacmSecurityToGroupTable, Key) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
ok;
false ->
{error, delete_failed}
@@ -266,11 +274,9 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
Match, RV, WV, NV},
case (catch check_vacm(Access)) of
{ok, {vacmAccess, {GN, Pref, SM, SL, Row}}} ->
- Key1 = [length(GN) | GN],
- Key2 = [length(Pref) | Pref],
- Key3 = [SM, SL],
- Key = Key1 ++ Key2 ++ Key3,
+ Key = make_access_key(GN, Pref, SM, SL),
snmpa_vacm:insert([{Key, Row}], false),
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
{error, Reason} ->
{error, Reason};
@@ -279,6 +285,7 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
end.
delete_access(Key) ->
+ snmpa_agent:invalidate_ca_cache(),
snmpa_vacm:delete(Key).
@@ -291,6 +298,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) ->
Key = [length(Key1) | Key1] ++ [length(Key2) | Key2],
case table_cre_row(vacmViewTreeFamilyTable, Key, Row) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
false ->
{error, create_failed}
@@ -304,6 +312,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) ->
delete_view_tree_fam(Key) ->
case table_del_row(vacmViewTreeFamilyTable, Key) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
ok;
false ->
{error, delete_failed}
@@ -346,6 +355,49 @@ vacmContextTable(Op, Arg1, Arg2) ->
snmp_framework_mib:intContextTable(Op, Arg1, Arg2).
+vacmSecurityToGroupTable(print) ->
+ Table = vacmSecurityToGroupTable,
+ DB = db(Table),
+ FOI = foi(Table),
+ PrintRow =
+ fun(Prefix, Row) ->
+ lists:flatten(
+ io_lib:format("~sSecurityModel: ~p (~w)"
+ "~n~sSecurityName: ~p"
+ "~n~sGroupName: ~p"
+ "~n~sStorageType: ~p (~w)"
+ "~n~sStatus: ~p (~w)",
+ [Prefix, element(?vacmSecurityModel, Row),
+ case element(?vacmSecurityModel, Row) of
+ ?SEC_ANY -> any;
+ ?SEC_V1 -> v1;
+ ?SEC_V2C -> v2c;
+ ?SEC_USM -> usm;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmSecurityName, Row),
+ Prefix, element(?vacmGroupName, Row),
+ Prefix, element(?vacmSecurityToGroupStorageType, Row),
+ case element(?vacmSecurityToGroupStorageType, Row) of
+ ?'vacmSecurityToGroupStorageType_readOnly' -> readOnly;
+ ?'vacmSecurityToGroupStorageType_permanent' -> permanent;
+ ?'vacmSecurityToGroupStorageType_nonVolatile' -> nonVolatile;
+ ?'vacmSecurityToGroupStorageType_volatile' -> volatile;
+ ?'vacmSecurityToGroupStorageType_other' -> other;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmSecurityToGroupStatus, Row),
+ case element(?vacmSecurityToGroupStatus, Row) of
+ ?'vacmSecurityToGroupStatus_destroy' -> destroy;
+ ?'vacmSecurityToGroupStatus_createAndWait' -> createAndWait;
+ ?'vacmSecurityToGroupStatus_createAndGo' -> createAndGo;
+ ?'vacmSecurityToGroupStatus_notReady' -> notReady;
+ ?'vacmSecurityToGroupStatus_notInService' -> notInService;
+ ?'vacmSecurityToGroupStatus_active' -> active;
+ _ -> undefined
+ end]))
+ end,
+ snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow);
vacmSecurityToGroupTable(Op) ->
snmp_generic:table_func(Op, db(vacmSecurityToGroupTable)).
@@ -400,13 +452,13 @@ verify_vacmSecurityToGroupTable_cols([{Col, Val0}|Cols], Acc) ->
verify_vacmSecurityToGroupTable_col(?vacmSecurityModel, Model) ->
case Model of
any -> ?SEC_ANY;
- v1 -> ?SEC_ANY;
- v2c -> ?SEC_ANY;
- usm -> ?SEC_ANY;
+ v1 -> ?SEC_V1;
+ v2c -> ?SEC_V2C;
+ usm -> ?SEC_USM;
?SEC_ANY -> ?SEC_ANY;
- ?SEC_V1 -> ?SEC_ANY;
- ?SEC_V2C -> ?SEC_ANY;
- ?SEC_USM -> ?SEC_ANY;
+ ?SEC_V1 -> ?SEC_V1;
+ ?SEC_V2C -> ?SEC_V2C;
+ ?SEC_USM -> ?SEC_USM;
_ ->
?vlog("verification of vacmSecurityModel(~w) ~p failed",
[?vacmSecurityModel, Model]),
@@ -443,6 +495,49 @@ verify_vacmSecurityToGroupTable_col(_, Val) ->
%% {RowIndex, {Col4, Col5, ..., Col9}}
%%
%%-----------------------------------------------------------------
+vacmAccessTable(print) ->
+ %% M�ste jag g�ra om alla entrien till {RowIdx, Row}?
+ TableInfo = get_table(vacmAccessTable),
+ PrintRow =
+ fun(Prefix, Row) ->
+ lists:flatten(
+ io_lib:format("~sContextMatch: ~p (~w)"
+ "~n~sReadViewName: ~p"
+ "~n~sWriteViewName: ~p"
+ "~n~sNotifyViewName: ~p"
+ "~n~sStorageType: ~p (~w)"
+ "~n~sStatus: ~p (~w)",
+ [Prefix, element(?vacmAccessContextMatch-3, Row),
+ case element(?vacmAccessContextMatch-3, Row) of
+ ?vacmAccessContextMatch_exact -> exact;
+ ?vacmAccessContextMatch_prefix -> prefix;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmAccessReadViewName-3, Row),
+ Prefix, element(?vacmAccessWriteViewName-3, Row),
+ Prefix, element(?vacmAccessNotifyViewName-3, Row),
+ Prefix, element(?vacmAccessStorageType-3, Row),
+ case element(?vacmAccessStorageType-3, Row) of
+ ?vacmAccessStorageType_other -> other ;
+ ?vacmAccessStorageType_volatile -> volatile;
+ ?vacmAccessStorageType_nonVolatile -> nonVolatile;
+ ?vacmAccessStorageType_permanent -> permanent;
+ ?vacmAccessStorageType_readOnly -> readOnly;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmAccessStatus-3, Row),
+ case element(?vacmAccessStatus-3, Row) of
+ ?vacmAccessStatus_destroy -> destroy;
+ ?vacmAccessStatus_createAndWait -> createAndWait;
+ ?vacmAccessStatus_createAndGo -> createAndGo;
+ ?vacmAccessStatus_notReady -> notReady;
+ ?vacmAccessStatus_notInService -> notInService;
+ ?vacmAccessStatus_active -> active;
+ _ -> undefined
+ end
+ ]))
+ end,
+ snmpa_mib_lib:print_table(vacmAccessTable, {ok, TableInfo}, PrintRow);
vacmAccessTable(_Op) ->
ok.
vacmAccessTable(get, RowIndex, Cols) ->
@@ -538,24 +633,24 @@ verify_vacmAccessTable_col(?vacmAccessContextPrefix, Pref) ->
verify_vacmAccessTable_col(?vacmAccessSecurityModel, Model) ->
case Model of
any -> ?SEC_ANY;
- v1 -> ?SEC_ANY;
- v2c -> ?SEC_ANY;
- usm -> ?SEC_ANY;
+ v1 -> ?SEC_V1;
+ v2c -> ?SEC_V2C;
+ usm -> ?SEC_USM;
?SEC_ANY -> ?SEC_ANY;
- ?SEC_V1 -> ?SEC_ANY;
- ?SEC_V2C -> ?SEC_ANY;
- ?SEC_USM -> ?SEC_ANY;
+ ?SEC_V1 -> ?SEC_V1;
+ ?SEC_V2C -> ?SEC_V2C;
+ ?SEC_USM -> ?SEC_USM;
_ ->
wrongValue(?vacmAccessSecurityModel)
end;
verify_vacmAccessTable_col(?vacmAccessSecurityLevel, Level) ->
case Level of
- noAuthNoPriv -> 1;
- authNoPriv -> 2;
- authPriv -> 3;
- 1 -> 1;
- 2 -> 2;
- 3 -> 3;
+ noAuthNoPriv -> ?vacmAccessSecurityLevel_noAuthNoPriv;
+ authNoPriv -> ?vacmAccessSecurityLevel_authNoPriv;
+ authPriv -> ?vacmAccessSecurityLevel_authPriv;
+ ?vacmAccessSecurityLevel_noAuthNoPriv -> ?vacmAccessSecurityLevel_noAuthNoPriv;
+ ?vacmAccessSecurityLevel_authNoPriv -> ?vacmAccessSecurityLevel_authNoPriv;
+ ?vacmAccessSecurityLevel_authPriv -> ?vacmAccessSecurityLevel_authPriv;
_ -> wrongValue(?vacmAccessSecurityLevel)
end;
verify_vacmAccessTable_col(?vacmAccessContextMatch, Match) ->
@@ -662,6 +757,7 @@ do_get_next(RowIndex, Cols) ->
end
end.
+
%%-----------------------------------------------------------------
%% Functions to manipulate vacmAccessRows.
%%-----------------------------------------------------------------
@@ -694,29 +790,76 @@ split_cols([Col | Cols], PreCols) when Col =< 3 ->
split_cols(Cols, PreCols) ->
{PreCols, Cols}.
+vacmViewSpinLock(print) ->
+ VarAndValue = [{vacmViewSpinLock, vacmViewSpinLock(get)}],
+ snmpa_mib_lib:print_variables(VarAndValue);
+
vacmViewSpinLock(new) ->
- snmp_generic:variable_func(new, {vacmViewSpinLock, volatile}),
+ snmp_generic:variable_func(new, volatile_db(vacmViewSpinLock)),
{A1,A2,A3} = erlang:now(),
random:seed(A1,A2,A3),
Val = random:uniform(2147483648) - 1,
- snmp_generic:variable_func(set, Val, {vacmViewSpinLock, volatile});
+ snmp_generic:variable_func(set, Val, volatile_db(vacmViewSpinLock));
vacmViewSpinLock(delete) ->
ok;
vacmViewSpinLock(get) ->
- snmp_generic:variable_func(get, {vacmViewSpinLock, volatile}).
+ snmp_generic:variable_func(get, volatile_db(vacmViewSpinLock)).
vacmViewSpinLock(is_set_ok, NewVal) ->
- case snmp_generic:variable_func(get, {vacmViewSpinLock, volatile}) of
+ case snmp_generic:variable_func(get, volatile_db(vacmViewSpinLock)) of
{value, NewVal} -> noError;
_ -> inconsistentValue
end;
vacmViewSpinLock(set, NewVal) ->
snmp_generic:variable_func(set, (NewVal + 1) rem 2147483648,
- {vacmViewSpinLock, volatile}).
-
-
+ volatile_db(vacmViewSpinLock)).
+
+
+vacmViewTreeFamilyTable(print) ->
+ Table = vacmViewTreeFamilyTable,
+ DB = db(Table),
+ FOI = foi(Table),
+ PrintRow =
+ fun(Prefix, Row) ->
+ lists:flatten(
+ io_lib:format("~sViewName: ~p"
+ "~n~sSubtree: ~p"
+ "~n~sMask: ~p"
+ "~n~sType: ~p (~w)"
+ "~n~sStorageType: ~p (~w)"
+ "~n~sStatus: ~p (~w)",
+ [Prefix, element(?vacmViewTreeFamilyViewName, Row),
+ Prefix, element(?vacmViewTreeFamilySubtree, Row),
+ Prefix, element(?vacmViewTreeFamilyMask, Row),
+ Prefix, element(?vacmViewTreeFamilyType, Row),
+ case element(?vacmViewTreeFamilyType, Row) of
+ ?vacmViewTreeFamilyType_included -> included;
+ ?vacmViewTreeFamilyType_excluded -> excluded;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmViewTreeFamilyStorageType, Row),
+ case element(?vacmViewTreeFamilyStorageType, Row) of
+ ?vacmViewTreeFamilyStorageType_readOnly -> readOnly;
+ ?vacmViewTreeFamilyStorageType_permanent -> permanent;
+ ?vacmViewTreeFamilyStorageType_nonVolatile -> nonVolatile;
+ ?vacmViewTreeFamilyStorageType_volatile -> volatile;
+ ?vacmViewTreeFamilyStorageType_other -> other;
+ _ -> undefined
+ end,
+ Prefix, element(?vacmViewTreeFamilyStatus, Row),
+ case element(?vacmViewTreeFamilyStatus, Row) of
+ ?vacmViewTreeFamilyStatus_destroy -> destroy;
+ ?vacmViewTreeFamilyStatus_createAndWait -> createAndWait;
+ ?vacmViewTreeFamilyStatus_createAndGo -> createAndGo;
+ ?vacmViewTreeFamilyStatus_notReady -> notReady;
+ ?vacmViewTreeFamilyStatus_notInService -> notInService;
+ ?vacmViewTreeFamilyStatus_active -> active;
+ _ -> undefined
+ end]))
+ end,
+ snmpa_mib_lib:print_table(Table, DB, FOI, PrintRow);
vacmViewTreeFamilyTable(Op) ->
snmp_generic:table_func(Op, db(vacmViewTreeFamilyTable)).
vacmViewTreeFamilyTable(get_next, RowIndex, Cols) ->
@@ -793,7 +936,25 @@ table_next(Name, RestOid) ->
snmp_generic:table_next(db(Name), RestOid).
-db(X) -> snmpa_agent:db(X).
+get_table(vacmAccessTable) ->
+ do_get_vacmAccessTable([], []).
+
+do_get_vacmAccessTable(Key0, Acc) ->
+ case snmpa_vacm:get_next_row(Key0) of
+ {Key, _Row} = Entry ->
+ do_get_vacmAccessTable(Key, [Entry | Acc]);
+ false ->
+ lists:reverse(Acc)
+ end.
+
+
+%%-----------------------------------------------------------------
+%% Wrappers
+%%-----------------------------------------------------------------
+
+db(X) -> snmpa_agent:db(X).
+volatile_db(X) -> {X, volatile}.
+
fa(vacmSecurityToGroupTable) -> ?vacmGroupName;
fa(vacmViewTreeFamilyTable) -> ?vacmViewTreeFamilyMask.
diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl
index 5ff0883be3..c400aaddf7 100644
--- a/lib/snmp/src/agent/snmpa.erl
+++ b/lib/snmp/src/agent/snmpa.erl
@@ -60,6 +60,7 @@
register_subagent/3, unregister_subagent/2,
+ send_notification2/3,
send_notification/3, send_notification/4, send_notification/5,
send_notification/6, send_notification/7,
send_trap/3, send_trap/4,
@@ -105,9 +106,12 @@
set_request_limit/1, set_request_limit/2
]).
+-export([print_mib_info/0, print_mib_tables/0, print_mib_variables/0]).
+
-include("snmpa_atl.hrl").
+-include("snmpa_internal.hrl").
--define(EXTRA_INFO, undefined).
+-define(DISCO_EXTRA_INFO, undefined).
%%-----------------------------------------------------------------
@@ -283,6 +287,186 @@ whereis_mib(Agent, Mib) when is_atom(Mib) ->
%% -
+mibs_info() ->
+ [
+ {snmp_standard_mib,
+ [],
+ [
+ sysDescr,
+ sysObjectID,
+ sysContact,
+ sysName,
+ sysLocation,
+ sysServices,
+ snmpEnableAuthenTraps,
+ sysUpTime,
+ snmpInPkts,
+ snmpOutPkts,
+ snmpInBadVersions,
+ snmpInBadCommunityNames,
+ snmpInBadCommunityUses,
+ snmpInASNParseErrs,
+ snmpInTooBigs,
+ snmpInNoSuchNames,
+ snmpInBadValues,
+ snmpInReadOnlys,
+ snmpInGenErrs,
+ snmpInTotalReqVars,
+ snmpInTotalSetVars,
+ snmpInGetRequests,
+ snmpInSetRequests,
+ snmpInGetNexts,
+ snmpInGetResponses,
+ snmpInTraps,
+ snmpOutTooBigs,
+ snmpOutNoSuchNames,
+ snmpOutBadValues,
+ snmpOutGenErrs,
+ snmpOutGetRequests,
+ snmpOutSetRequests,
+ snmpOutGetNexts,
+ snmpOutGetResponses,
+ snmpOutTraps
+ ]
+ },
+ {snmp_framework_mib,
+ [
+ ],
+ [
+ snmpEngineID,
+ snmpEngineBoots,
+ snmpEngineTime,
+ snmpEngineMaxMessageSize
+ ]
+ },
+ {snmp_view_based_acm_mib,
+ [
+ vacmAccessTable,
+ vacmSecurityToGroupTable,
+ vacmViewTreeFamilyTable
+ ],
+ [
+ vacmViewSpinLock
+ ]
+ },
+ {snmp_target_mib,
+ [
+ snmpTargetAddrTable,
+ snmpTargetParamsTable
+ ],
+ [
+ snmpTargetSpinLock
+ ]
+ },
+ {snmp_community_mib,
+ [
+ snmpCommunityTable
+ ],
+ []
+ },
+ {snmp_notification_mib,
+ [
+ snmpNotifyTable
+ ],
+ []},
+ {snmp_user_based_sm_mib,
+ [
+ usmUserTable
+ ],
+ [
+ usmUserSpinLock,
+ usmStatsUnsupportedSecLevels,
+ usmStatsNotInTimeWindows,
+ usmStatsUnknownUserNames,
+ usmStatsUnknownEngineIDs,
+ usmStatsWrongDigests,
+ usmStatsDecryptionErrors
+ ]
+ }
+ ].
+
+print_mib_info() ->
+ MibsInfo = mibs_info(),
+ print_mib_info(MibsInfo).
+
+print_mib_info([]) ->
+ io:format("~n", []),
+ ok;
+print_mib_info([{Mod, Tables, Variables} | MibsInfo]) ->
+ io:format("~n** ~s ** ~n~n", [make_pretty_mib(Mod)]),
+ print_mib_variables2(Mod, Variables),
+ print_mib_tables2(Mod, Tables),
+ io:format("~n", []),
+ print_mib_info(MibsInfo).
+
+
+print_mib_tables() ->
+ Tables = [{Mod, Tabs} || {Mod, Tabs, _Vars} <- mibs_info()],
+ print_mib_tables(Tables).
+
+print_mib_tables([]) ->
+ ok;
+print_mib_tables([{Mod, Tabs}|MibTabs])
+ when is_atom(Mod) andalso is_list(Tabs) ->
+ print_mib_tables(Mod, Tabs),
+ print_mib_tables(MibTabs);
+print_mib_tables([_|MibTabs]) ->
+ print_mib_tables(MibTabs).
+
+print_mib_tables(_Mod, [] = _Tables) ->
+ ok;
+print_mib_tables(Mod, Tables) ->
+ io:format("~n** ~s ** ~n~n", [make_pretty_mib(Mod)]),
+ print_mib_tables2(Mod, Tables),
+ io:format("~n", []).
+
+print_mib_tables2(Mod, Tables) ->
+ [(catch Mod:Table(print)) || Table <- Tables].
+
+
+print_mib_variables() ->
+ Variables = [{Mod, Vars} || {Mod, _Tabs, Vars} <- mibs_info()],
+ print_mib_variables(Variables).
+
+print_mib_variables([]) ->
+ ok;
+print_mib_variables([{Mod, Vars}|MibVars])
+ when is_atom(Mod) andalso is_list(Vars) ->
+ print_mib_variables(Mod, Vars),
+ print_mib_variables(MibVars);
+print_mib_variables([_|MibVars]) ->
+ print_mib_variables(MibVars).
+
+print_mib_variables(_Mod, [] = _Vars) ->
+ ok;
+print_mib_variables(Mod, Vars) ->
+ io:format("~n** ~s ** ~n~n", [make_pretty_mib(Mod)]),
+ print_mib_variables2(Mod, Vars),
+ io:format("~n", []).
+
+print_mib_variables2(Mod, Variables) ->
+ Vars = [{Var, (catch Mod:Var(get))} || Var <- Variables],
+ snmpa_mib_lib:print_variables(Vars).
+
+
+make_pretty_mib(snmp_view_based_acm_mib) ->
+ "SNMP-VIEW-BASED-ACM-MIB";
+make_pretty_mib(snmp_target_mib) ->
+ "SNMP-TARGET-MIB";
+make_pretty_mib(snmp_community_mib) ->
+ "SNMP-COMMUNITY-MIB";
+make_pretty_mib(snmp_notification_mib) ->
+ "SNMP-NOTIFICATION-MIB";
+make_pretty_mib(snmp_user_based_sm_mib) ->
+ "SNMP-USER-BASED-SM-MIB";
+make_pretty_mib(snmp_framework_mib) ->
+ "SNMP-FRAMEWORK-MIB";
+make_pretty_mib(Mod) ->
+ atom_to_list(Mod).
+
+
+%% -
+
mib_of(Oid) ->
snmpa_agent:mib_of(Oid).
@@ -414,22 +598,56 @@ set_request_limit(Agent, NewLimit) ->
%% -
+send_notification2(Agent, Notification, SendOpts) ->
+ snmpa_agent:send_notification(Agent, Notification, SendOpts).
+
send_notification(Agent, Notification, Recv) ->
- send_notification(Agent, Notification, Recv, "", "", []).
+ SendOpts =
+ [
+ {receiver, Recv},
+ {varbinds, []},
+ {name, ""},
+ {context, ""},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO}
+ ],
+ send_notification2(Agent, Notification, SendOpts).
send_notification(Agent, Notification, Recv, Varbinds) ->
- send_notification(Agent, Notification, Recv, "", "", Varbinds).
+ SendOpts =
+ [
+ {receiver, Recv},
+ {varbinds, Varbinds},
+ {name, ""},
+ {context, ""},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO}
+ ],
+ send_notification2(Agent, Notification, SendOpts).
send_notification(Agent, Notification, Recv, NotifyName, Varbinds) ->
- send_notification(Agent, Notification, Recv, NotifyName, "", Varbinds).
+ SendOpts =
+ [
+ {receiver, Recv},
+ {varbinds, Varbinds},
+ {name, NotifyName},
+ {context, ""},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO}
+ ],
+ send_notification2(Agent, Notification, SendOpts).
send_notification(Agent, Notification, Recv, NotifyName,
ContextName, Varbinds)
when (is_list(NotifyName) andalso
is_list(ContextName) andalso
is_list(Varbinds)) ->
- snmpa_agent:send_trap(Agent, Notification, NotifyName,
- ContextName, Recv, Varbinds).
+ SendOpts =
+ [
+ {receiver, Recv},
+ {varbinds, Varbinds},
+ {name, NotifyName},
+ {context, ContextName},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO}
+ ],
+ send_notification2(Agent, Notification, SendOpts).
send_notification(Agent, Notification, Recv,
NotifyName, ContextName, Varbinds, LocalEngineID)
@@ -437,8 +655,16 @@ send_notification(Agent, Notification, Recv,
is_list(ContextName) andalso
is_list(Varbinds) andalso
is_list(LocalEngineID)) ->
- snmpa_agent:send_trap(Agent, Notification, NotifyName,
- ContextName, Recv, Varbinds, LocalEngineID).
+ SendOpts =
+ [
+ {receiver, Recv},
+ {varbinds, Varbinds},
+ {name, NotifyName},
+ {context, ContextName},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO},
+ {local_engine_id, LocalEngineID}
+ ],
+ send_notification2(Agent, Notification, SendOpts).
%% Kept for backwards compatibility
send_trap(Agent, Trap, Community) ->
@@ -473,7 +699,7 @@ discovery(TargetName, Notification, Varbinds, DiscoHandler)
discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler).
discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler) ->
- ExtraInfo = ?EXTRA_INFO,
+ ExtraInfo = ?DISCO_EXTRA_INFO,
discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler,
ExtraInfo).
diff --git a/lib/snmp/src/agent/snmpa_acm.erl b/lib/snmp/src/agent/snmpa_acm.erl
index 6ad4f0b442..42a0d4d6a3 100644
--- a/lib/snmp/src/agent/snmpa_acm.erl
+++ b/lib/snmp/src/agent/snmpa_acm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1997-2011. 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
@@ -62,11 +62,13 @@
%% {error, Reason} |
%% {discarded, Variable, Reason}
%% Types: Pdu = #pdu
-%% ACMData = acm_data() = {community, Community, Address} |
-%% {v3, MsgID, SecModel, SecName, SecLevel,
-%% ContextEngineID, ContextName, SecData}
+%% ACMData = acm_data() =
+%% {community, SecModel, Community, TDomain, TAddress} |
+%% {v3, MsgID, SecModel, SecName, SecLevel,
+%% ContextEngineID, ContextName, SecData}
%% Community = string()
-%% Address = ip() ++ udp() (list)
+%% TDomain = ?transportDomainUdpIpv4 | ?transportDomainUdpIpv6
+%% TAddress = ip() ++ udp() (list)
%% MsgID = integer() <not used>
%% SecModel = ?SEC_* (see snmp_types.hrl)
%% SecName = string()
@@ -114,7 +116,10 @@ error2status(_) -> genErr.
%% discarded: no error response is sent
%% authentication_failure: no error response is sent, a trap is generated
%%-----------------------------------------------------------------
-init_ca(Pdu, {community, SecModel, Community, TAddr}) ->
+init_ca(Pdu, {community, SecModel, Community, TAddress}) ->
+ TDomain = snmp_conf:mk_tdomain(snmp_target_mib:default_domain()),
+ init_ca(Pdu, {community, SecModel, Community, TDomain, TAddress});
+init_ca(Pdu, {community, SecModel, Community, TDomain, TAddress}) ->
%% This is a v1 or v2c request. Use SNMP-COMMUNITY-MIB to
%% map the community to vacm parameters.
?vtrace("check access for ~n"
@@ -126,18 +131,18 @@ init_ca(Pdu, {community, SecModel, Community, TAddr}) ->
_ -> read
end,
?vtrace("View type: ~p", [ViewType]),
- CaCacheKey = {Community, SecModel, TAddr, ViewType},
+ CaCacheKey = {Community, SecModel, TDomain, TAddress, ViewType},
case check_ca_cache(CaCacheKey) of
false ->
- case snmp_community_mib:community2vacm(Community,
- {?snmpUDPDomain,TAddr}) of
+ case snmp_community_mib:community2vacm(Community,
+ {TDomain, TAddress}) of
{SecName, _ContextEngineId, ContextName} ->
%% Maybe we should check that the contextEngineID
%% matches the local engineID?
%% It better, since we don't impl. proxy.
?vtrace("get mib view"
"~n Security name: ~p"
- "~n Context name: ~p",[SecName,ContextName]),
+ "~n Context name: ~p",[SecName, ContextName]),
case snmpa_vacm:get_mib_view(ViewType, SecModel, SecName,
?'SnmpSecurityLevel_noAuthNoPriv',
ContextName) of
@@ -153,7 +158,7 @@ init_ca(Pdu, {community, SecModel, Community, TAddr}) ->
end;
undefined ->
{authentication_failure, snmpInBadCommunityNames,
- {bad_community_name, TAddr, Community}}
+ {bad_community_name, TDomain, TAddress, Community}}
end;
Res ->
Res
@@ -219,6 +224,7 @@ upd_ca_cache(KeyVal) ->
invalidate_ca_cache() ->
erase(ca_cache).
+
%%-----------------------------------------------------------------
%% Func: check(Res) -> {ok, MibView} | {discarded, Variable, Reason}
%% Args: Res = {ok, AccessFunc} |
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index e3178aacc6..9cc986cf47 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -30,7 +30,7 @@
-export([subagent_set/2,
load_mibs/2, unload_mibs/2, which_mibs/1, whereis_mib/2, info/1,
register_subagent/3, unregister_subagent/2,
- send_trap/6, send_trap/7,
+ send_notification/3,
register_notification_filter/5,
unregister_notification_filter/2,
which_notification_filter/1,
@@ -62,14 +62,20 @@
-export([increment_counter/3]).
-export([restart_worker/1, restart_set_worker/1]).
+%% For backward compatibillity
+-export([send_trap/6, send_trap/7]).
+
%% Internal exports
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
terminate/2, code_change/3, tr_var/2, tr_varbind/1,
- handle_pdu/8, worker/2, worker_loop/1, do_send_trap/7]).
+ handle_pdu/8, worker/2, worker_loop/1,
+ do_send_trap/7, do_send_trap/8]).
%% <BACKWARD-COMPAT>
-export([handle_pdu/7]).
%% </BACKWARD-COMPAT>
+-include("snmpa_internal.hrl").
+
-ifndef(default_verbosity).
-define(default_verbosity,silence).
-endif.
@@ -114,14 +120,15 @@
{gb_max_vbs, GbMaxVBs},
{extra, Extra}]}).
-define(mk_send_trap_wreq(TrapRec, NotifyName, ContextName,
- Recv, Vbs, LocalEngineID),
+ Recv, Vbs, LocalEngineID, Extra),
#wrequest{cmd = send_trap,
info = [{trap_rec, TrapRec},
{notify_name, NotifyName},
{context_name, ContextName},
{receiver, Recv},
{varbinds, Vbs},
- {local_engine_id, LocalEngineID}]}).
+ {local_engine_id, LocalEngineID},
+ {extra, Extra}]}).
-define(mk_terminate_wreq(), #wrequest{cmd = terminate, info = []}).
-define(mk_verbosity_wreq(V), #wrequest{cmd = verbosity,
info = [{verbosity, V}]}).
@@ -569,6 +576,11 @@ which_notification_filter(Agent) ->
call(Agent, which_notification_filter).
+send_notification(Agent, Notification, SendOpts) ->
+ Msg = {send_notif, Notification, SendOpts},
+ maybe_call(Agent, Msg).
+
+%% <BACKWARD-COMPAT>
send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) ->
?d("send_trap -> entry with"
"~n self(): ~p"
@@ -580,14 +592,15 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) ->
"~n Varbinds: ~p",
[self(), Agent, wis(Agent),
Trap, NotifyName, CtxName, Recv, Varbinds]),
- Msg = {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds},
- case (wis(Agent) =:= self()) of
- false ->
- call(Agent, Msg);
- true ->
- Agent ! Msg
- end.
-
+ SendOpts = [
+ {receiver, Recv},
+ {varbinds, Varbinds},
+ {name, NotifyName},
+ {context, CtxName},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO}
+ ],
+ send_notification(Agent, Trap, SendOpts).
+
send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) ->
?d("send_trap -> entry with"
"~n self(): ~p"
@@ -600,14 +613,17 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) ->
"~n LocalEngineID: ~p",
[self(), Agent, wis(Agent),
Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID]),
- Msg =
- {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID},
- case (wis(Agent) =:= self()) of
- false ->
- call(Agent, Msg);
- true ->
- Agent ! Msg
- end.
+ SendOpts = [
+ {receiver, Recv},
+ {varbinds, Varbinds},
+ {name, NotifyName},
+ {context, CtxName},
+ {extra, ?DEFAULT_NOTIF_EXTRA_INFO},
+ {local_engine_id, LocalEngineID}
+ ],
+ send_notification(Agent, Trap, SendOpts).
+
+%% </BACKWARD-COMPAT>
%% -- Discovery functions --
@@ -696,8 +712,10 @@ wis(Atom) when is_atom(Atom) ->
whereis(Atom).
-forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds) ->
- Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds}.
+forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds,
+ ExtraInfo) ->
+ Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds,
+ ExtraInfo}.
%%-----------------------------------------------------------------
@@ -788,6 +806,22 @@ handle_info(worker_available, S) ->
?vdebug("worker available",[]),
{noreply, S#state{worker_state = ready}};
+handle_info({send_notif, Notification, SendOpts}, S) ->
+ ?vlog("[handle_info] send notif request:"
+ "~n Notification: ~p"
+ "~n SendOpts: ~p",
+ [Notification, SendOpts]),
+ case (catch handle_send_trap(S, Notification, SendOpts)) of
+ {ok, NewS} ->
+ {noreply, NewS};
+ {'EXIT', R} ->
+ ?vinfo("Trap not sent:~n ~p", [R]),
+ {noreply, S};
+ _ ->
+ {noreply, S}
+ end;
+
+%% <BACKWARD-COMPAT>
handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) ->
?vlog("[handle_info] send trap request:"
"~n Trap: ~p"
@@ -796,9 +830,10 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) ->
"~n Recv: ~p"
"~n Varbinds: ~p",
[Trap, NotifyName, ContextName, Recv, Varbinds]),
- LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
- case catch handle_send_trap(S, Trap, NotifyName, ContextName,
- Recv, Varbinds, LocalEngineID) of
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ LocalEngineID = local_engine_id(S),
+ case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
+ Recv, Varbinds, LocalEngineID, ExtraInfo)) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -818,8 +853,9 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds,
"~n Varbinds: ~p"
"~n LocalEngineID: ~p",
[Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID]),
- case catch handle_send_trap(S, Trap, NotifyName, ContextName,
- Recv, Varbinds, LocalEngineID) of
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
+ Recv, Varbinds, LocalEngineID, ExtraInfo)) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -828,8 +864,31 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds,
_ ->
{noreply, S}
end;
+%% </BACKWARD-COMPAT>
handle_info({forward_trap, TrapRecord, NotifyName, ContextName,
+ Recv, Varbinds, ExtraInfo}, S) ->
+ ?vlog("[handle_info] forward trap request:"
+ "~n TrapRecord: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n Recv: ~p"
+ "~n Varbinds: ~p",
+ [TrapRecord, NotifyName, ContextName, Recv, Varbinds]),
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ case (catch maybe_send_trap(S, TrapRecord, NotifyName, ContextName,
+ Recv, Varbinds, LocalEngineID, ExtraInfo)) of
+ {ok, NewS} ->
+ {noreply, NewS};
+ {'EXIT', R} ->
+ ?vinfo("Trap not sent:~n ~p", [R]),
+ {noreply, S};
+ _ ->
+ {noreply, S}
+ end;
+
+%% <BACKWARD-COMPAT>
+handle_info({forward_trap, TrapRecord, NotifyName, ContextName,
Recv, Varbinds}, S) ->
?vlog("[handle_info] forward trap request:"
"~n TrapRecord: ~p"
@@ -838,9 +897,10 @@ handle_info({forward_trap, TrapRecord, NotifyName, ContextName,
"~n Recv: ~p"
"~n Varbinds: ~p",
[TrapRecord, NotifyName, ContextName, Recv, Varbinds]),
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
case (catch maybe_send_trap(S, TrapRecord, NotifyName, ContextName,
- Recv, Varbinds, LocalEngineID)) of
+ Recv, Varbinds, LocalEngineID, ExtraInfo)) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -849,6 +909,7 @@ handle_info({forward_trap, TrapRecord, NotifyName, ContextName,
_ ->
{noreply, S}
end;
+%% </BACKWARD-COMPAT>
handle_info({backup_done, Reply}, #state{backup = {_, From}} = S) ->
?vlog("[handle_info] backup done:"
@@ -917,6 +978,7 @@ handle_info({'EXIT', Pid, Reason}, S) ->
end,
{noreply, S}
end;
+
handle_info({'DOWN', Ref, process, Pid, {mibs_cache_reply, Reply}},
#state{mibs_cache_request = {Pid, Ref, From}} = S) ->
?vlog("reply from the mibs cache request handler (~p): ~n~p",
@@ -951,6 +1013,23 @@ handle_call(restart_set_worker, _From, #state{set_worker = Pid} = S) ->
end,
{reply, ok, S};
+handle_call({send_notif, Notification, SendOpts}, _From, S) ->
+ ?vlog("[handle_call] send notif request:"
+ "~n Notification: ~p"
+ "~n SendOpts: ~p",
+ [Notification, SendOpts]),
+ case (catch handle_send_trap(S, Notification, SendOpts)) of
+ {ok, NewS} ->
+ {reply, ok, NewS};
+ {'EXIT', Reason} ->
+ ?vinfo("Trap not sent:~n ~p", [Reason]),
+ {reply, {error, {send_failed, Reason}}, S};
+ _ ->
+ ?vinfo("Trap not sent", []),
+ {reply, {error, send_failed}, S}
+ end;
+
+%% <BACKWARD-COMPAT>
handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds},
_From, S) ->
?vlog("[handle_call] send trap request:"
@@ -960,19 +1039,10 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds},
"~n Recv: ~p"
"~n Varbinds: ~p",
[Trap, NotifyName, ContextName, Recv, Varbinds]),
- LocalEngineID =
- case S#state.type of
- master_agent ->
- ?DEFAULT_LOCAL_ENGINE_ID;
- _ ->
- %% subagent -
- %% we don't need this, eventually the trap sent request
- %% will reach the master-agent and then it will look up
- %% the proper engine id.
- ignore
- end,
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ LocalEngineID = local_engine_id(S),
case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
- Recv, Varbinds, LocalEngineID)) of
+ Recv, Varbinds, LocalEngineID, ExtraInfo)) of
{ok, NewS} ->
{reply, ok, NewS};
{'EXIT', Reason} ->
@@ -994,8 +1064,9 @@ handle_call({send_trap, Trap, NotifyName,
"~n Varbinds: ~p"
"~n LocalEngineID: ~p",
[Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID]),
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
- Recv, Varbinds, LocalEngineID)) of
+ Recv, Varbinds, LocalEngineID, ExtraInfo)) of
{ok, NewS} ->
{reply, ok, NewS};
{'EXIT', Reason} ->
@@ -1005,6 +1076,7 @@ handle_call({send_trap, Trap, NotifyName,
?vinfo("Trap not sent", []),
{reply, {error, send_failed}, S}
end;
+%% </BACKWARD-COMPAT>
handle_call({discovery,
TargetName, Notification, ContextName, Vbs, DiscoHandler,
@@ -1261,27 +1333,27 @@ handle_call({me_of, Oid}, _From, S) ->
{reply, Reply, S};
handle_call(get_log_type, _From, S) ->
- ?vlog("get_log_type", []),
+ ?vlog("handle_call(get_log_type) -> entry with", []),
Reply = handle_get_log_type(S),
{reply, Reply, S};
handle_call({set_log_type, NewType}, _From, S) ->
- ?vlog("set_log_type -> "
+ ?vlog("handle_call(set_log_type) -> entry with"
"~n NewType: ~p", [NewType]),
Reply = handle_set_log_type(S, NewType),
{reply, Reply, S};
handle_call(get_request_limit, _From, S) ->
- ?vlog("get_request_limit", []),
+ ?vlog("handle_call(get_request_limit) -> entry with", []),
Reply = handle_get_request_limit(S),
{reply, Reply, S};
handle_call({set_request_limit, NewLimit}, _From, S) ->
- ?vlog("set_request_limit -> "
+ ?vlog("handle_call(set_request_limit) -> entry with"
"~n NewLimit: ~p", [NewLimit]),
Reply = handle_set_request_limit(S, NewLimit),
{reply, Reply, S};
-
+
handle_call(stop, _From, S) ->
{stop, normal, ok, S};
@@ -1585,7 +1657,10 @@ handle_backup_res([{Who, Crap}|Results], Acc) ->
%% because we (for some reason) support the function
%% snmpa:current_community().
%%-----------------------------------------------------------------
-cheat({community, _SecModel, Community, _IpUdp}, Address, ContextName) ->
+cheat({community, _SecModel, Community, _TAddress}, Address, ContextName) ->
+ {Community, Address, ContextName};
+cheat({community, _SecModel, Community, _TDomain, _TAddress},
+ Address, ContextName) ->
{Community, Address, ContextName};
cheat(_, Address, ContextName) ->
{"", Address, ContextName}.
@@ -1613,7 +1688,7 @@ invalidate_ca_cache() ->
MasterAgent ! invalidate_ca_cache;
false ->
%% This is running on a sub-agent node,
- %% so sent skip it
+ %% so skip it
ok
end;
_ -> % Not on this node
@@ -1640,19 +1715,24 @@ spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra) ->
proc_lib:spawn_link(?MODULE, handle_pdu, Args).
spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs,
- LocalEngineID) ->
+ LocalEngineID, ExtraInfo) ->
Dict = get(),
proc_lib:spawn_link(?MODULE, do_send_trap,
[TrapRec, NotifyName, ContextName,
- Recv, Vbs, LocalEngineID, Dict]).
+ Recv, Vbs, LocalEngineID, ExtraInfo, Dict]).
do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
LocalEngineID, Dict) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, ExtraInfo, Dict).
+do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, ExtraInfo, Dict) ->
lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict),
put(sname, trap_sender_short_name(get(sname))),
?vlog("starting",[]),
snmpa_trap:send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
- LocalEngineID, get(net_if)).
+ LocalEngineID, ExtraInfo, get(net_if)).
worker(Master, Dict) ->
lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict),
@@ -1699,12 +1779,13 @@ worker_loop(Master) ->
Recv = proplists:get_value(receiver, Info),
Vbs = proplists:get_value(varbinds, Info),
LocalEngineID = proplists:get_value(local_engine_id, Info),
+ Extra = proplists:get_value(extra, Info),
SendTrapRes =
try
begin
snmpa_trap:send_trap(TrapRec, NotifyName,
ContextName, Recv, Vbs,
- LocalEngineID,
+ LocalEngineID, Extra,
get(net_if))
end
catch
@@ -1749,11 +1830,13 @@ worker_loop(Master) ->
%% We don't trap exits!
{send_trap,
- TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID} ->
+ TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID,
+ ExtraInfo} ->
?vtrace("worker_loop -> send trap:"
"~n ~p", [TrapRec]),
snmpa_trap:send_trap(TrapRec, NotifyName,
- ContextName, Recv, Vbs, LocalEngineID,
+ ContextName, Recv, Vbs,
+ LocalEngineID, ExtraInfo,
get(net_if)),
Master ! worker_available;
@@ -1918,34 +2001,58 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) ->
ok
end.
+get_send_opt(Key, Default, SendOpts) ->
+ case lists:keysearch(Key, 1, SendOpts) of
+ {value, {Key, Value}} ->
+ Value;
+ false ->
+ Default
+ end.
+
+handle_send_trap(S, Notification, SendOpts) ->
+ NotifyName = get_send_opt(name, "", SendOpts),
+ ContextName = get_send_opt(context, "", SendOpts),
+ Recv = get_send_opt(receiver, no_receiver, SendOpts),
+ Varbinds = get_send_opt(varbinds, [], SendOpts),
+ ExtraInfo = get_send_opt(extra, ?DEFAULT_NOTIF_EXTRA_INFO, SendOpts),
+ LocalEngineID =
+ case lists:keysearch(local_engine_id, 1, SendOpts) of
+ {value, {local_engine_id, Value}} ->
+ Value;
+ false ->
+ local_engine_id(S)
+ end,
+ handle_send_trap(S, Notification, NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID, ExtraInfo).
-handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds,
- LocalEngineID) ->
+handle_send_trap(#state{type = Type} = S,
+ Notification, NotifyName, ContextName, Recv, Varbinds,
+ LocalEngineID, ExtraInfo) ->
?vtrace("handle_send_trap -> entry with"
- "~n S#state.type: ~p"
- "~n TrapName: ~p"
- "~n NotifyName: ~p"
- "~n ContextName: ~p"
- "~n LocalEngineID: ~p",
- [S#state.type, TrapName, NotifyName, ContextName, LocalEngineID]),
- case snmpa_trap:construct_trap(TrapName, Varbinds) of
+ "~n Agent type: ~p"
+ "~n TrapName: ~p"
+ "~n NotifyName: ~p"
+ "~n ContextName: ~p"
+ "~n LocalEngineID: ~p",
+ [Type, Notification, NotifyName, ContextName, LocalEngineID]),
+ case snmpa_trap:construct_trap(Notification, Varbinds) of
{ok, TrapRecord, VarList} ->
?vtrace("handle_send_trap -> construction complete: "
"~n TrapRecord: ~p"
"~n VarList: ~p",
[TrapRecord, VarList]),
- case S#state.type of
+ case Type of
subagent ->
?vtrace("handle_send_trap -> [sub] forward trap",[]),
maybe_forward_trap(S, TrapRecord, NotifyName,
- ContextName, Recv, VarList),
+ ContextName, Recv, VarList, ExtraInfo),
{ok, S};
master_agent ->
?vtrace("handle_send_trap -> "
"[master] handle send trap",[]),
maybe_send_trap(S, TrapRecord, NotifyName,
ContextName, Recv, VarList,
- LocalEngineID)
+ LocalEngineID, ExtraInfo)
end;
error ->
error
@@ -1953,7 +2060,7 @@ handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds,
maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S,
- TrapRec, NotifyName, ContextName, Recv, V) ->
+ TrapRec, NotifyName, ContextName, Recv, V, ExtraInfo) ->
?vtrace("maybe_forward_trap -> entry with"
"~n NFs: ~p", [NFs]),
case filter_notification(NFs, [], TrapRec) of
@@ -1969,13 +2076,15 @@ maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S,
{send, [], TrapRec2} ->
?vtrace("maybe_forward_trap -> forward trap:"
"~n ~p", [TrapRec2]),
- forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V),
+ forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V,
+ ExtraInfo),
{ok, S};
{send, Removed, TrapRec2} ->
?vtrace("maybe_forward_trap -> forward trap:"
"~n ~p", [TrapRec2]),
- forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V),
+ forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V,
+ ExtraInfo),
NFs2 = del_notification_filter(Removed, NFs),
{ok, S#state{nfilters = NFs2}}
end.
@@ -1983,7 +2092,7 @@ maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S,
maybe_send_trap(#state{nfilters = NFs} = S,
TrapRec, NotifyName, ContextName, Recv, Varbinds,
- LocalEngineID) ->
+ LocalEngineID, ExtraInfo) ->
?vtrace("maybe_send_trap -> entry with"
"~n NFs: ~p", [NFs]),
case filter_notification(NFs, [], TrapRec) of
@@ -2001,7 +2110,7 @@ maybe_send_trap(#state{nfilters = NFs} = S,
"~n ~p", [TrapRec2]),
do_handle_send_trap(S, TrapRec2,
NotifyName, ContextName, Recv, Varbinds,
- LocalEngineID);
+ LocalEngineID, ExtraInfo);
{send, Removed, TrapRec2} ->
?vtrace("maybe_send_trap -> send trap:"
@@ -2009,36 +2118,37 @@ maybe_send_trap(#state{nfilters = NFs} = S,
NFs2 = del_notification_filter(Removed, NFs),
do_handle_send_trap(S#state{nfilters = NFs2}, TrapRec2,
NotifyName, ContextName, Recv, Varbinds,
- LocalEngineID)
+ LocalEngineID, ExtraInfo)
end.
do_handle_send_trap(S, TrapRec, NotifyName, ContextName, Recv, Varbinds,
- LocalEngineID) ->
+ LocalEngineID, ExtraInfo) ->
Vbs = snmpa_trap:try_initialise_vars(get(mibserver), Varbinds),
case S#state.type of
subagent ->
forward_trap(S#state.parent, TrapRec, NotifyName, ContextName,
- Recv, Vbs),
+ Recv, Vbs, ExtraInfo),
{ok, S};
master_agent when S#state.multi_threaded =:= false ->
?vtrace("do_handle_send_trap -> send trap:"
"~n ~p", [TrapRec]),
snmpa_trap:send_trap(TrapRec, NotifyName, ContextName,
- Recv, Vbs, LocalEngineID, get(net_if)),
+ Recv, Vbs, LocalEngineID, ExtraInfo,
+ get(net_if)),
{ok, S};
master_agent when S#state.worker_state =:= busy ->
%% Main worker busy => create new worker
?vtrace("do_handle_send_trap -> main worker busy: "
"spawn a trap sender", []),
spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs,
- LocalEngineID),
+ LocalEngineID, ExtraInfo),
{ok, S};
master_agent ->
%% Send to main worker
?vtrace("do_handle_send_trap -> send to main worker",[]),
S#state.worker ! ?mk_send_trap_wreq(TrapRec, NotifyName,
ContextName, Recv, Vbs,
- LocalEngineID),
+ LocalEngineID, ExtraInfo),
{ok, S#state{worker_state = busy}}
end.
@@ -2137,7 +2247,7 @@ send_discovery(S, From,
TargetName, Record, ContextName, InitVars,
DiscoHandler, ExtraInfo) ->
case snmpa_trap:send_discovery(TargetName, Record, ContextName,
- InitVars, get(net_if)) of
+ InitVars, get(net_if), ExtraInfo) of
{ok, Sender, SecLevel} ->
Disco = #disco{from = From,
rec = Record,
@@ -2214,9 +2324,12 @@ handle_discovery_response(#state{disco = #disco{target = TargetName,
#disco{rec = Record,
ctx = ContextName,
ivbs = InitVars} = Disco,
- case snmpa_trap:send_discovery(TargetName, Record,
+ case snmpa_trap:send_discovery(TargetName,
+ Record,
ContextName,
- InitVars, get(net_if)) of
+ InitVars,
+ get(net_if),
+ ExtraInfo) of
{ok, Sender, _SecLevel} ->
?vdebug("handle_discovery_response(1) -> "
"stage 2 trap sent", []),
@@ -4028,6 +4141,7 @@ mapfoldl(F, Eas, Accu0, [Hd|Tail]) ->
{Accu2,[R|Rs]};
mapfoldl(_F, _Eas, Accu, []) -> {Accu,[]}.
+
%%-----------------------------------------------------------------
%% Runtime debugging of the agent.
%%-----------------------------------------------------------------
@@ -4094,6 +4208,18 @@ subagents_verbosity(_,_V) ->
%% ---------------------------------------------------------------------
+local_engine_id(#state{type = master_agent}) ->
+ ?DEFAULT_LOCAL_ENGINE_ID;
+local_engine_id(_) ->
+ %% subagent -
+ %% we don't need this now, eventually the trap send
+ %% request will reach the master-agent and then it
+ %% will look up the proper engine id.
+ ignore.
+
+
+%% ---------------------------------------------------------------------
+
handle_get_log_type(#state{net_if_mod = Mod})
when Mod =/= undefined ->
case (catch Mod:get_log_type(get(net_if))) of
@@ -4140,7 +4266,7 @@ handle_set_request_limit(_, _) ->
{error, not_supported}.
-agent_info(#state{worker = W, set_worker = SW}) ->
+agent_info(#state{worker = W, set_worker = SW}) ->
case (catch get_agent_info(W, SW)) of
Info when is_list(Info) ->
Info;
@@ -4261,6 +4387,14 @@ user_err(F, A) ->
%% ---------------------------------------------------------------------
+maybe_call(Server, Req) ->
+ case (wis(Server) =:= self()) of
+ false ->
+ call(Server, Req);
+ true ->
+ Server ! Req
+ end.
+
call(Server, Req) ->
gen_server:call(Server, Req, infinity).
diff --git a/lib/snmp/src/agent/snmpa_authentication_service.erl b/lib/snmp/src/agent/snmpa_authentication_service.erl
index 572fab7fbf..b5ff8460c6 100644
--- a/lib/snmp/src/agent/snmpa_authentication_service.erl
+++ b/lib/snmp/src/agent/snmpa_authentication_service.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
@@ -29,11 +29,12 @@ behaviour_info(_) ->
%%-----------------------------------------------------------------
%% init_check_access(Pdu, ACMData)
%% Pdu = #pdu
-%% ACMData = acm_data() = {community, Community, Address} |
-%% {v3, MsgID, SecModel, SecName, SecLevel,
-%% ContextEngineID, ContextName, SecData}
+%% ACMData = acm_data() = {community, SecModel, Community, TDomain, TAddress} |
+%% {v3, MsgID, SecModel, SecName, SecLevel,
+%% ContextEngineID, ContextName, SecData}
%% Community = string()
-%% Address = ip() ++ udp() (list)
+%% TDomain = ?transportDomainUdpIpv4 | ?transportDomainUdpIpv6
+%% TAddress = ip() ++ udp() (list)
%% MsgID = integer() <not used>
%% SecModel = ?SEC_* (see snmp_types.hrl)
%% SecName = string()
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index b14a0c806c..c17a6abbd7 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2011. 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
@@ -19,6 +19,8 @@
-module(snmpa_conf).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
-export([
%% agent.conf
agent_entry/2,
@@ -46,7 +48,7 @@
%% target_addr.conf
target_addr_entry/5, target_addr_entry/6,
- target_addr_entry/8, target_addr_entry/10,
+ target_addr_entry/8, target_addr_entry/10, target_addr_entry/11,
write_target_addr_config/2, write_target_addr_config/3,
append_target_addr_config/2,
read_target_addr_config/1,
@@ -422,7 +424,8 @@ target_addr_entry(Name,
EngineId,
TMask) ->
target_addr_entry(Name, Ip, 162, TagList,
- ParamsName, EngineId, TMask, 2048).
+ ParamsName, EngineId,
+ TMask, 2048).
target_addr_entry(Name,
Ip,
@@ -433,7 +436,8 @@ target_addr_entry(Name,
TMask,
MaxMessageSize) ->
target_addr_entry(Name, Ip, Udp, 1500, 3, TagList,
- ParamsName, EngineId, TMask, MaxMessageSize).
+ ParamsName, EngineId,
+ TMask, MaxMessageSize).
target_addr_entry(Name,
Ip,
@@ -445,7 +449,24 @@ target_addr_entry(Name,
EngineId,
TMask,
MaxMessageSize) ->
+ target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp,
+ Timeout, RetryCount, TagList,
+ ParamsName, EngineId,
+ TMask, MaxMessageSize).
+
+target_addr_entry(Name,
+ Domain,
+ Ip,
+ Udp,
+ Timeout,
+ RetryCount,
+ TagList,
+ ParamsName,
+ EngineId,
+ TMask,
+ MaxMessageSize) ->
{Name,
+ Domain,
Ip,
Udp,
Timeout,
@@ -463,9 +484,13 @@ write_target_addr_config(Dir, Conf) ->
"%% The data is inserted into the snmpTargetAddrTable defined\n"
"%% in SNMP-TARGET-MIB, and in the snmpTargetAddrExtTable defined\n"
"%% in SNMP-COMMUNITY-MIB.\n"
-"%% Each row is a 10-tuple:\n"
-"%% {Name, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId,\n"
-"%% TMask, MaxMessageSize}.\n"
+"%% Each row is a 10 or 11-tuple (Domain is optional):\n"
+"%% {Name, \n"
+"%% Domain, Ip, Port, \n"
+"%% Timeout, RetryCount, TagList, ParamsName, EngineId,\n"
+"%% TMask, MaxMessageSize}.\n"
+"%% The value of Domain decide the format of the Ip and TMask values. \n"
+"%% If not present, classic Ipv4 is assumed. \n"
"%% The EngineId value is only used if Inform-Requests are sent to this\n"
"%% target. If Informs are not sent, this value is ignored, and can be\n"
"%% e.g. an empty string. However, if Informs are sent, it is essential\n"
@@ -519,16 +544,31 @@ write_target_addr_conf(Fd, Hdr, Conf) ->
write_target_addr_conf(Fd, Conf) ->
Fun = fun(Entry) -> do_write_target_addr_conf(Fd, Entry) end,
- lists:foreach(Fun, Conf).
+ lists:foreach(Fun, Conf),
+ ok.
do_write_target_addr_conf(Fd,
- {Name, Ip, Udp,
+ {Name,
+ Ip, Udp,
+ Timeout, RetryCount, TagList,
+ ParamsName, EngineId,
+ TMask, MaxMessageSize}) ->
+ Domain = snmp_target_mib:default_domain(),
+ do_write_target_addr_conf(Fd,
+ {Name,
+ Domain, Ip, Udp,
+ Timeout, RetryCount, TagList,
+ ParamsName, EngineId,
+ TMask, MaxMessageSize});
+do_write_target_addr_conf(Fd,
+ {Name,
+ Domain, Ip, Udp,
Timeout, RetryCount, TagList,
ParamsName, EngineId,
TMask, MaxMessageSize}) ->
io:format(Fd,
- "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
- [Name, Ip, Udp, Timeout, RetryCount, TagList,
+ "{\"~s\", ~w, ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
+ [Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
ParamsName, EngineId, TMask, MaxMessageSize]);
do_write_target_addr_conf(_Fd, Crap) ->
error({bad_target_addr_config, Crap}).
@@ -544,13 +584,13 @@ target_params_entry(Name, Vsn) ->
target_params_entry(Name, Vsn, SecName, SecLevel).
target_params_entry(Name, Vsn, SecName, SecLevel) ->
- MPModel = if Vsn == v1 -> v1;
- Vsn == v2 -> v2c;
- Vsn == v3 -> v3
+ MPModel = if Vsn =:= v1 -> v1;
+ Vsn =:= v2 -> v2c;
+ Vsn =:= v3 -> v3
end,
- SecModel = if Vsn == v1 -> v1;
- Vsn == v2 -> v2c;
- Vsn == v3 -> usm
+ SecModel = if Vsn =:= v1 -> v1;
+ Vsn =:= v2 -> v2c;
+ Vsn =:= v3 -> usm
end,
target_params_entry(Name, MPModel, SecModel, SecName, SecLevel).
diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl
index 671a3e4aaf..c435b519d9 100644
--- a/lib/snmp/src/agent/snmpa_internal.hrl
+++ b/lib/snmp/src/agent/snmpa_internal.hrl
@@ -22,7 +22,9 @@
-include_lib("snmp/src/app/snmp_internal.hrl").
--define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()).
+%% The DEFAULT_LOCAL_ENGINE_ID macro can only be used by the master_agent!!
+-define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()).
+-define(DEFAULT_NOTIF_EXTRA_INFO, {snmpa_default_notification_extra_info}).
%% -- Max number of VBs in a Get-BULK response --
%% (( The default value, 1000, is *way* more ))
diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl
index 0babc74d16..ab277fc3e9 100644
--- a/lib/snmp/src/agent/snmpa_local_db.erl
+++ b/lib/snmp/src/agent/snmpa_local_db.erl
@@ -1118,7 +1118,7 @@ table_func(is_set_ok, RowIndex, Cols, NameDb) ->
table_func(set, RowIndex, Cols, NameDb) ->
snmp_generic:table_set_row(NameDb,
nofunc,
- {snmp_generic, table_try_make_consistent},
+ fun snmp_generic:table_try_make_consistent/3,
RowIndex,
Cols);
diff --git a/lib/snmp/src/agent/snmpa_mib_lib.erl b/lib/snmp/src/agent/snmpa_mib_lib.erl
index ae94aca6d8..3c94cc8095 100644
--- a/lib/snmp/src/agent/snmpa_mib_lib.erl
+++ b/lib/snmp/src/agent/snmpa_mib_lib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
@@ -19,7 +19,8 @@
-module(snmpa_mib_lib).
-export([table_cre_row/3, table_del_row/2]).
--export([get_table/2, print_table/3, print_table/4, print_tables/1]).
+-export([get_table/2]).
+-export([print_variables/1, print_table/3, print_table/4, print_tables/1]).
-export([gc_tab/3, gc_tab/5]).
-include("SNMPv2-TC.hrl").
@@ -81,31 +82,69 @@ get_table(NameDb, FOI, Key, Acc) ->
end.
+print_variables(Variables) when is_list(Variables) ->
+ Variables2 = print_variables_prefixify(Variables),
+ lists:foreach(fun({Variable, ValueResult, Prefix}) ->
+ print_variable(Variable, ValueResult, Prefix)
+ end, Variables2),
+ ok.
+
+print_variable(Variable, {value, Val}, Prefix) when is_atom(Variable) ->
+ io:format("~w~s=> ~p~n", [Variable, Prefix, Val]);
+print_variable(Variable, Error, Prefix) when is_atom(Variable) ->
+ io:format("~w~s=> [e] ~p~n", [Variable, Prefix, Error]).
+
+print_variables_prefixify(Variables) ->
+ MaxVarLength = print_variables_maxlength(Variables),
+ print_variables_prefixify(Variables, MaxVarLength, []).
+
+print_variables_prefixify([], _MaxVarLength, Acc) ->
+ lists:reverse(Acc);
+print_variables_prefixify([{Var, Res}|Variables], MaxVarLength, Acc) ->
+ Prefix = make_variable_print_prefix(Var, MaxVarLength),
+ print_variables_prefixify(Variables, MaxVarLength,
+ [{Var, Res, Prefix}|Acc]).
+
+make_variable_print_prefix(Var, MaxVarLength) ->
+ lists:duplicate(MaxVarLength - length(atom_to_list(Var)) + 1, $ ).
+
+print_variables_maxlength(Variables) ->
+ print_variables_maxlength(Variables, 0).
+
+print_variables_maxlength([], MaxLength) ->
+ MaxLength;
+print_variables_maxlength([{Var, _}|Variables], MaxLength) when is_atom(Var) ->
+ VarLen = length(atom_to_list(Var)),
+ if
+ VarLen > MaxLength ->
+ print_variables_maxlength(Variables, VarLen);
+ true ->
+ print_variables_maxlength(Variables, MaxLength)
+ end.
+
+
print_tables(Tables) when is_list(Tables) ->
lists:foreach(fun({Table, DB, FOI, PrintRow}) ->
print_table(Table, DB, FOI, PrintRow)
end, Tables),
ok.
-%% print_table(Table, DB, FOI, PrintRow) ->
-%% TableInfo = get_table(DB(Table), FOI(Table)),
-%% print_table(Table, TableInfo, PrintRow),
-%% ok.
-
print_table(Table, DB, FOI, PrintRow) ->
TableInfo = get_table(DB, FOI),
print_table(Table, TableInfo, PrintRow).
print_table(Table, TableInfo, PrintRow) when is_function(PrintRow, 2) ->
- io:format("~w => ~n", [Table]),
+ io:format("~w =>", [Table]),
do_print_table(TableInfo, PrintRow).
+do_print_table({ok, [] = _TableInfo}, _PrintRow) ->
+ io:format(" -~n", []);
do_print_table({ok, TableInfo}, PrintRow) when is_function(PrintRow, 2) ->
+ io:format("~n", []),
lists:foreach(fun({RowIdx, Row}) ->
io:format(" ~w => ~n~s~n",
[RowIdx, PrintRow(" ", Row)])
- end, TableInfo),
- io:format("~n", []);
+ end, TableInfo);
do_print_table({error, {invalid_rowindex, BadRowIndex, []}}, _PrintRow) ->
io:format("Error: Bad rowindex ~w~n", [BadRowIndex]);
do_print_table({error, {invalid_rowindex, BadRowIndex, TableInfo}}, PrintRow) ->
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index e9d6cdeaa8..2d37ea56f0 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -32,6 +32,7 @@
-include("SNMP-MPD-MIB.hrl").
-include("SNMPv2-TM.hrl").
-include("SNMP-FRAMEWORK-MIB.hrl").
+-include("TRANSPORT-ADDRESS-MIB.hrl").
-define(VMODULE,"MPD").
-include("snmp_verbosity.hrl").
@@ -115,8 +116,8 @@ reset() ->
%% Func: process_packet(Packet, TDomain, TAddress, State, Log) ->
%% {ok, SnmpVsn, Pdu, PduMS, ACMData} | {discarded, Reason}
%% Types: Packet = binary()
-%% TDomain = snmpUDPDomain | atom()
-%% TAddress = {Ip, Udp}
+%% TDomain = snmpUDPDomain | transportDomain()
+%% TAddress = {Ip, Udp} (*but* depends on TDomain)
%% State = #state
%% Purpose: This is the main Message Dispatching function. (see
%% section 4.2.1 in rfc2272)
@@ -182,24 +183,30 @@ discarded_pdu(Variable) -> inc(Variable).
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain,
+v1_v2c_proc(Vsn, NoteStore, Community, Domain,
{Ip, Udp}, LocalEngineID,
Data, HS, Log, Packet) ->
- TAddress = tuple_to_list(Ip) ++ [Udp div 256, Udp rem 256],
- AgentMS = get_engine_max_message_size(LocalEngineID),
- MgrMS = snmp_community_mib:get_target_addr_ext_mms(?snmpUDPDomain,
- TAddress),
- PduMS = case MgrMS of
- {ok, MMS} when MMS < AgentMS -> MMS - HS;
- _ -> AgentMS - HS
- end,
+ TDomain = snmp_conf:mk_tdomain(Domain),
+ TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp),
+ AgentMS = get_engine_max_message_size(LocalEngineID),
+ MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress),
+ PduMS = case MgrMS of
+ {ok, MMS} when MMS < AgentMS -> MMS - HS;
+ _ -> AgentMS - HS
+ end,
case (catch snmp_pdus:dec_pdu(Data)) of
Pdu when is_record(Pdu, pdu) ->
Log(Pdu#pdu.type, Packet),
inc_snmp_in_vars(Pdu),
#pdu{request_id = ReqId} = Pdu,
- OkRes = {ok, Vsn, Pdu, PduMS,
- {community, sec_model(Vsn), Community, TAddress}},
+
+ %% <TDomain>
+ %% We have added TDomain, what are the consequences?
+ ACMData =
+ {community, sec_model(Vsn), Community, TDomain, TAddress},
+ OkRes = {ok, Vsn, Pdu, PduMS, ACMData},
+ %% </TDomain>
+
%% Make sure that we don't process duplicate SET request
%% twice. We don't know what could happen in that case.
%% The mgr does, so he has to generate a new SET request.
@@ -216,8 +223,6 @@ v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain,
snmp_note_store:set_note(NoteStore,
100, Key, true),
%% Uses ACMData that snmpa_acm knows of.
- %% snmpUDPDomain is implicit, since that's the only
- %% one we handle.
OkRes;
true ->
{discarded, duplicate_pdu}
@@ -275,12 +280,12 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) ->
"~n msgSecurityParameters = ~w",
[MsgID, MMS, MsgFlags, MsgSecurityModel, SecParams]),
%% 7.2.4
- SecModule = get_security_module(MsgSecurityModel),
+ SecModule = get_security_module(MsgSecurityModel),
%% 7.2.5
- SecLevel = check_sec_level(MsgFlags),
+ SecLevel = check_sec_level(MsgFlags),
IsReportable = snmp_misc:is_reportable(MsgFlags),
%% 7.2.6
- ?vtrace("v3_proc -> [7.2.6]"
+ ?vtrace("v3_proc -> [7.2.4-7.2.6]"
"~n SecModule = ~p"
"~n SecLevel = ~p"
"~n IsReportable = ~p",
@@ -541,7 +546,7 @@ check_sec_module_result(Res, V3Hdr, Data, LocalEngineID, IsReportable, Log) ->
?vdebug("security module result [7.2.6-b]:"
"~n Reason: ~p", [Reason]),
throw({discarded, {securityError, Reason}});
- {error, Reason, ErrorInfo} when IsReportable == true -> % case 7.2.6 a
+ {error, Reason, ErrorInfo} when IsReportable =:= true -> % case 7.2.6 a
?vdebug("security module result when reportable [7.2.6-a]:"
"~n Reason: ~p"
"~n ErrorInfo: ~p", [Reason, ErrorInfo]),
@@ -584,7 +589,7 @@ generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) ->
generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log, 1).
generate_response_msg(Vsn, RePdu, Type,
- {community, _SecModel, Community, _IpUdp},
+ {community, _SecModel, Community, _TDomain, _TAddress},
LocalEngineID,
Log, _) ->
case catch snmp_pdus:enc_pdu(RePdu) of
@@ -987,12 +992,15 @@ generate_discovery_msg2(NoteStore, Pdu,
discovery_note_timeout(Timeout) ->
(Timeout div 100) + 1.
-generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]},
+generate_discovery_msg(NoteStore, {TDomain, TAddress},
Pdu, ScopedPduBytes,
ContextEngineID, ManagerEngineID,
SecModel, SecName, SecLevelFlag,
InitialUserName,
ContextName, Timeout) ->
+
+ {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress),
+
%% 7.1.7
?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]),
MsgID = generate_msg_id(),
@@ -1033,7 +1041,7 @@ generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]},
%% Log(Packet),
inc_snmp_out_vars(Pdu),
?vdebug("generate_discovery_msg -> done", []),
- {Packet, {{A,B,C,D}, U1 bsl 8 + U2}};
+ {Packet, Address};
Error ->
throw(Error)
@@ -1063,6 +1071,34 @@ generate_sec_discovery_msg(Message, SecModule,
end.
+transform_taddr(?snmpUDPDomain, TAddress) ->
+ transform_taddr(?transportDomainUdpIpv4, TAddress);
+transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) ->
+ Domain = transportDomainUdpIpv4,
+ Addr = {A,B,C,D},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(?transportDomainUdpIpv4, BadAddr) ->
+ {error, {bad_transportDomainUdpIpv4_address, BadAddr}};
+transform_taddr(?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) ->
+ Domain = transportDomainUdpIpv6,
+ Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(?transportDomainUdpIpv6, BadAddr) ->
+ {error, {bad_transportDomainUdpIpv6_address, BadAddr}};
+transform_taddr(BadTDomain, TAddress) ->
+ case lists:member(BadTDomain, snmp_conf:all_tdomains()) of
+ true ->
+ {error, {unsupported_tdomain, BadTDomain, TAddress}};
+ false ->
+ {error, {unknown_tdomain, BadTDomain, TAddress}}
+ end.
+
+
process_taddrs(Dests) ->
?vtrace("process_taddrs -> entry with"
"~n Dests: ~p", [Dests]),
@@ -1072,46 +1108,44 @@ process_taddrs([], Acc) ->
?vtrace("process_taddrs -> entry when done with"
"~n Acc: ~p", [Acc]),
lists:reverse(Acc);
-
+
%% v3
-process_taddrs([{{?snmpUDPDomain, [A,B,C,D,U1,U2]}, SecData} | T], Acc) ->
+process_taddrs([{{TDomain, TAddress}, SecData} | T], Acc) ->
?vtrace("process_taddrs -> entry when v3 with"
- "~n A: ~p"
- "~n B: ~p"
- "~n C: ~p"
- "~n D: ~p"
- "~n U1: ~p"
- "~n U2: ~p"
- "~n SecData: ~p", [A, B, C, D, U1, U2, SecData]),
- Entry = {{snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, SecData},
- process_taddrs(T, [Entry | Acc]);
-%% Bad v3
-process_taddrs([{{TDomain, TAddr}, _SecData} | T], Acc) ->
- ?vtrace("process_taddrs -> entry when bad v3 with"
- "~n TDomain: ~p"
- "~n TAddr: ~p", [TDomain, TAddr]),
- user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]),
- process_taddrs(T, Acc);
+ "~n TDomain: ~p"
+ "~n TAddress: ~p"
+ "~n SecData: ~p", [TDomain, TAddress, SecData]),
+ case transform_taddr(TDomain, TAddress) of
+ {ok, DestAddr} ->
+ ?vtrace("process_taddrs -> transformed: "
+ "~n DestAddr: ~p", [DestAddr]),
+ Entry = {DestAddr, SecData},
+ process_taddrs(T, [Entry | Acc]);
+ {error, Reason} ->
+ ?vinfo("Failed transforming v3 domain and address"
+ "~n Reason: ~p", [Reason]),
+ user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]),
+ process_taddrs(T, Acc)
+ end;
%% v1 & v2
-process_taddrs([{?snmpUDPDomain, [A,B,C,D,U1,U2]} | T], Acc) ->
+process_taddrs([{TDomain, TAddress} | T], Acc) ->
?vtrace("process_taddrs -> entry when v1/v2 with"
- "~n A: ~p"
- "~n B: ~p"
- "~n C: ~p"
- "~n D: ~p"
- "~n U1: ~p"
- "~n U2: ~p", [A, B, C, D, U1, U2]),
- Entry = {snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}},
- process_taddrs(T, [Entry | Acc]);
-%% Bad v1 or v2
-process_taddrs([{TDomain, TAddr} | T], Acc) ->
- ?vtrace("process_taddrs -> entry when bad v1/v2 with"
- "~n TDomain: ~p"
- "~n TAddr: ~p", [TDomain, TAddr]),
- user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]),
- process_taddrs(T, Acc);
+ "~n TDomain: ~p"
+ "~n TAddress: ~p", [TDomain, TAddress]),
+ case transform_taddr(TDomain, TAddress) of
+ {ok, DestAddr} ->
+ ?vtrace("process_taddrs -> transformed: "
+ "~n DestAddr: ~p", [DestAddr]),
+ Entry = DestAddr,
+ process_taddrs(T, [Entry | Acc]);
+ {error, Reason} ->
+ ?vinfo("Failed transforming v1/v2 domain and address: "
+ "~n Reason: ~p", [Reason]),
+ user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]),
+ process_taddrs(T, Acc)
+ end;
process_taddrs(Crap, Acc) ->
- throw({error, {taddrs_crap, Crap, Acc}}).
+ throw({error, {bad_taddrs, Crap, Acc}}).
mk_v1_v2_packet_list(To, Packet, Len, Pdu) ->
diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl
index 97a7a63dee..79c85a6e4e 100644
--- a/lib/snmp/src/agent/snmpa_net_if.erl
+++ b/lib/snmp/src/agent/snmpa_net_if.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
@@ -314,6 +314,14 @@ loop(S) ->
NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined),
loop(NewS);
+ %% We dont use the extra-info at this time, ...
+ {send_pdu, Vsn, Pdu, MsgData, To, _ExtraInfo} ->
+ ?vdebug("send pdu: "
+ "~n Pdu: ~p"
+ "~n To: ~p", [Pdu, To]),
+ NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined),
+ loop(NewS);
+
%% Informs
{send_pdu_req, Vsn, Pdu, MsgData, To, From} ->
?vdebug("send pdu request: "
@@ -324,7 +332,18 @@ loop(S) ->
NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, From),
loop(NewS);
+ %% We dont use the extra-info at this time, ...
+ {send_pdu_req, Vsn, Pdu, MsgData, To, From, _ExtraInfo} ->
+ ?vdebug("send pdu request: "
+ "~n Pdu: ~p"
+ "~n To: ~p"
+ "~n From: ~p",
+ [Pdu, To, toname(From)]),
+ NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, From),
+ loop(NewS);
+
%% Discovery Inform
+ %% <BACKWARD-COMPAT>
{send_discovery, Pdu, MsgData, To, From} ->
?vdebug("received send discovery request: "
"~n Pdu: ~p"
@@ -333,6 +352,18 @@ loop(S) ->
[Pdu, To, toname(From)]),
NewS = handle_send_discovery(S, Pdu, MsgData, To, From),
loop(NewS);
+ %% </BACKWARD-COMPAT>
+
+ %% Discovery Inform
+ {send_discovery, Pdu, MsgData, To, From, ExtraInfo} ->
+ ?vdebug("received send discovery request: "
+ "~n Pdu: ~p"
+ "~n To: ~p"
+ "~n From: ~p"
+ "~n ExtraInfo: ~p",
+ [Pdu, To, toname(From), ExtraInfo]),
+ NewS = handle_send_discovery(S, Pdu, MsgData, To, From),
+ loop(NewS);
{discarded_pdu, _Vsn, ReqId, _ACMData, Variable, _Extra} ->
?vdebug("discard PDU: ~p", [Variable]),
@@ -504,7 +535,6 @@ handle_discovery_response(_Ip, _Port, #pdu{request_id = ReqId} = Pdu,
S
end.
-
handle_recv(#state{usock = Sock,
mpd_state = MpdState,
note_store = NS,
@@ -513,7 +543,9 @@ handle_recv(#state{usock = Sock,
LogF = fun(Type, Data) ->
log(Log, Type, Data, Ip, Port)
end,
- case (catch snmpa_mpd:process_packet(Packet, snmpUDPDomain, {Ip, Port},
+ Domain = snmp_conf:which_domain(Ip), % What the ****...
+ case (catch snmpa_mpd:process_packet(Packet,
+ Domain, {Ip, Port},
MpdState, NS, LogF)) of
{ok, _Vsn, Pdu, _PduMS, {discovery, ManagerEngineId}} ->
handle_discovery_response(Ip, Port, Pdu, ManagerEngineId, S);
@@ -636,7 +668,6 @@ process_taddrs([{{_Domain, AddrAndPort}, _SecData}|T], Acc) ->
process_taddrs([{_Domain, AddrAndPort}|T], Acc) ->
process_taddrs(T, [AddrAndPort|Acc]).
-
merge_taddrs(To1, To2) ->
merge_taddrs(To1, To2, []).
@@ -776,15 +807,49 @@ handle_send_pdu1(#state{log = Log,
usock = Sock,
filter = FilterMod}, Type, Addresses) ->
SendFun =
- fun({snmpUDPDomain, {Ip, Port}, Packet}) when is_binary(Packet) ->
- ?vdebug("sending packet:"
+ fun({snmpUDPDomain, {Ip, Port}, Packet})
+ when is_binary(Packet) ->
+ ?vdebug("[snmpUDPDomain] sending packet:"
+ "~n size: ~p"
+ "~n to: ~p:~p",
+ [sz(Packet), Ip, Port]),
+ maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
+
+ ({snmpUDPDomain, {Ip, Port}, {Packet, _LogData}})
+ when is_binary(Packet) ->
+ ?vdebug("[snmpUDPDomain] sending encrypted packet:"
+ "~n size: ~p"
+ "~n to: ~p:~p",
+ [sz(Packet), Ip, Port]),
+ maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
+
+ ({transportDomainUdpIpv4, {Ip, Port}, Packet})
+ when is_binary(Packet) ->
+ ?vdebug("[transportDomainUdpIpv4] sending packet:"
+ "~n size: ~p"
+ "~n to: ~p:~p",
+ [sz(Packet), Ip, Port]),
+ maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
+
+ ({transportDomainUdpIpv4, {Ip, Port}, {Packet, _LogData}})
+ when is_binary(Packet) ->
+ ?vdebug("[transportDomainUdpIpv4] sending encrypted packet:"
+ "~n size: ~p"
+ "~n to: ~p:~p",
+ [sz(Packet), Ip, Port]),
+ maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
+
+ ({transportDomainUdpIpv6, {Ip, Port}, Packet})
+ when is_binary(Packet) ->
+ ?vdebug("[transportDomainUdpIpv6] sending packet:"
"~n size: ~p"
"~n to: ~p:~p",
[sz(Packet), Ip, Port]),
maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet);
- ({snmpUDPDomain, {Ip, Port}, {Packet, _LogData}}) when is_binary(Packet) ->
- ?vdebug("sending encrypted packet:"
+ ({transportDomainUdpIpv6, {Ip, Port}, {Packet, _LogData}})
+ when is_binary(Packet) ->
+ ?vdebug("[transportDomainUdpIpv6] sending encrypted packet:"
"~n size: ~p"
"~n to: ~p:~p",
[sz(Packet), Ip, Port]),
diff --git a/lib/snmp/src/agent/snmpa_set_lib.erl b/lib/snmp/src/agent/snmpa_set_lib.erl
index 191029f6db..9f355855b4 100644
--- a/lib/snmp/src/agent/snmpa_set_lib.erl
+++ b/lib/snmp/src/agent/snmpa_set_lib.erl
@@ -143,8 +143,8 @@ consistency_check(Varbinds) ->
consistency_check(Varbinds, []).
consistency_check([{TableOid, TableVbs} | Varbinds], Done) ->
?vtrace("consistency_check -> entry with"
- "~n TableOid: ~p"
- "~n TableVbs: ~p",[TableOid,TableVbs]),
+ "~n TableOid: ~p"
+ "~n TableVbs: ~p", [TableOid, TableVbs]),
TableOpsWithShortOids = deletePrefixes(TableOid, TableVbs),
[#ivarbind{mibentry = MibEntry}|_] = TableVbs,
case is_set_ok_table(MibEntry, TableOpsWithShortOids) of
@@ -158,7 +158,7 @@ consistency_check([{TableOid, TableVbs} | Varbinds], Done) ->
end;
consistency_check([IVarbind | Varbinds], Done) ->
?vtrace("consistency_check -> entry with"
- "~n IVarbind: ~p",[IVarbind]),
+ "~n IVarbind: ~p", [IVarbind]),
#ivarbind{varbind = Varbind, mibentry = MibEntry} = IVarbind,
#varbind{value = Value, org_index = OrgIndex} = Varbind,
case is_set_ok_variable(MibEntry, Value) of
@@ -358,32 +358,39 @@ make_value_a_correct_value(Value, ASN1Type, Mfa) ->
%% Runtime debug support
%%-----------------------------------------------------------------
-% XXX: This function match on the exakt return codes from EXIT
-% messages. As of this writing it was not decided if this is
-% the right way so don't blindly do things this way.
-%
-% We fake a real EXIT signal as the return value because the
-% result is passed to the function snmpa_agent:validate_err()
-% that expect it.
+%% XYZ: This function match on the exakt return codes from EXIT
+%% messages. As of this writing it was not decided if this is
+%% the right way so don't blindly do things this way.
+%%
+%% We fake a real EXIT signal as the return value because the
+%% result is passed to the function snmpa_agent:validate_err()
+%% that expect it.
dbg_apply(M,F,A) ->
- Result =
- case get(verbosity) of
- false ->
- (catch apply(M,F,A));
- _ ->
- ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]),
- Res = (catch apply(M,F,A)),
- ?vlog("~n returned: ~p", [Res]),
- Res
- end,
- case Result of
+ case maybe_verbose_apply(M, F, A) of
+ %% <Future proofing>
+ %% As of R15 we get extra info containing,
+ %% among other things, line numbers.
+ {'EXIT', {undef, [{M, F, A, _} | _]}} ->
+ {'EXIT', {hook_undef, {M, F, A}}};
+ {'EXIT', {function_clause, [{M, F, A, _} | _]}} ->
+ {'EXIT', {hook_function_clause, {M, F, A}}};
+
+ %% This is really overkill, but just to be on the safe side...
+ {'EXIT', {undef, {M, F, A, _}}} ->
+ {'EXIT', {hook_undef, {M, F, A}}};
+ {'EXIT', {function_clause, {M, F, A, _}}} ->
+ {'EXIT', {hook_function_clause, {M, F, A}}};
+ %% </Future proofing>
+
+
+ %% Old format format for compatibility
{'EXIT', {undef, [{M, F, A} | _]}} ->
{'EXIT', {hook_undef, {M, F, A}}};
{'EXIT', {function_clause, [{M, F, A} | _]}} ->
{'EXIT', {hook_function_clause, {M, F, A}}};
- % XXX: Old format for compatibility
+ % XYZ: Older format for compatibility
{'EXIT', {undef, {M, F, A}}} ->
{'EXIT', {hook_undef, {M, F, A}}};
{'EXIT', {function_clause, {M, F, A}}} ->
@@ -393,3 +400,15 @@ dbg_apply(M,F,A) ->
Result
end.
+
+maybe_verbose_apply(M, F, A) ->
+ case get(verbosity) of
+ false ->
+ (catch apply(M,F,A));
+ _ ->
+ ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]),
+ Res = (catch apply(M,F,A)),
+ ?vlog("~n returned: ~p", [Res]),
+ Res
+ end.
+
diff --git a/lib/snmp/src/agent/snmpa_target_cache.erl b/lib/snmp/src/agent/snmpa_target_cache.erl
index 6fdecacc68..2aa35aa46a 100644
--- a/lib/snmp/src/agent/snmpa_target_cache.erl
+++ b/lib/snmp/src/agent/snmpa_target_cache.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2010. 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,6 +21,8 @@
-behaviour(gen_server).
%% External exports
+%% Avoid warning for local function demonitor/1 clashing with autoimported BIF.
+-compile({no_auto_import,[demonitor/1]}).
-export([start_link/2, stop/0, verbosity/1]).
-export([
diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index 3b31c8d909..994d926224 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2011. 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
@@ -24,27 +24,34 @@
%% External exports
-export([construct_trap/2,
try_initialise_vars/2,
- send_trap/6, send_trap/7]).
--export([send_discovery/5]).
+ send_trap/6, send_trap/7, send_trap/8]).
+-export([send_discovery/6]).
%% Internal exports
--export([init_v2_inform/9,
- init_v3_inform/9, init_v3_inform/10,
+-export([init_v2_inform/9, init_v2_inform/10,
+ init_v3_inform/9, init_v3_inform/10, init_v3_inform/11,
send_inform/6]).
--export([init_discovery_inform/12, send_discovery_inform/5]).
-
--include("snmp_types.hrl").
--include("snmpa_internal.hrl").
--include("SNMPv2-MIB.hrl").
--include("SNMPv2-TM.hrl").
--include("SNMPv2-TC.hrl").
--include("SNMP-FRAMEWORK-MIB.hrl").
--include("SNMP-TARGET-MIB.hrl").
+-export([init_discovery_inform/13, send_discovery_inform/5]).
+
+%% <BACKWARD-COMPAT>
+-export([send_discovery/5,
+ init_discovery_inform/12]).
+%% </BACKWARD-COMPAT>
+
+-include_lib("snmp/include/snmp_types.hrl").
+-include_lib("snmp/src/agent/snmpa_internal.hrl").
+-include_lib("snmp/include/SNMPv2-MIB.hrl").
+-include_lib("snmp/include/SNMPv2-TM.hrl").
+-include_lib("snmp/include/SNMPv2-TC.hrl").
+-include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl").
+-include_lib("snmp/include/SNMP-TARGET-MIB.hrl").
+-include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl").
-define(enterpriseSpecific, 6).
-define(VMODULE,"TRAP").
-include("snmp_verbosity.hrl").
+-include("snmpa_internal.hrl").
%%-----------------------------------------------------------------
@@ -335,41 +342,51 @@ make_varbind_list(Varbinds) ->
%% SnmpTargetAddrTable (using the Tag).
%%-----------------------------------------------------------------
send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, NetIf) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
+ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, ExtraInfo, NetIf).
+
+send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, ExtraInfo, NetIf) ->
LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
- LocalEngineID, NetIf).
+ LocalEngineID, ExtraInfo, NetIf).
%% The agent normally does not care about the result,
%% but since it can be usefull when debugging, add
%% some info when we fail to send the trap(s).
-send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, NetIf) ->
+send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID,
+ ExtraInfo, NetIf) ->
try
begin
do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
- LocalEngineID, NetIf)
+ LocalEngineID, ExtraInfo, NetIf)
end
catch
T:E ->
Info = [{args, [TrapRec, NotifyName, ContextName,
- Recv, Vbs, LocalEngineID, NetIf]},
+ Recv, Vbs, LocalEngineID, ExtraInfo, NetIf]},
{tag, T},
{err, E},
{stacktrace, erlang:get_stacktrace()}],
{error, {failed_sending_trap, Info}}
end.
-
do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
- LocalEngineID, NetIf) ->
+ LocalEngineID, ExtraInfo, NetIf) ->
VarbindList = make_varbind_list(Vbs),
Dests = find_dests(NotifyName),
send_trap_pdus(Dests, ContextName, {TrapRec, VarbindList}, [], [], [],
- Recv, LocalEngineID, NetIf).
+ Recv, LocalEngineID, ExtraInfo, NetIf).
send_discovery(TargetName, Record, ContextName, Vbs, NetIf) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ send_discovery(TargetName, Record, ContextName, Vbs, NetIf, ExtraInfo).
+send_discovery(TargetName, Record, ContextName, Vbs, NetIf, ExtraInfo) ->
case find_dest(TargetName) of
{ok, Dest} ->
- send_discovery_pdu(Dest, Record, ContextName, Vbs, NetIf);
+ send_discovery_pdu(Dest, Record, ContextName, Vbs, NetIf,
+ ExtraInfo);
Error ->
Error
end.
@@ -377,8 +394,13 @@ send_discovery(TargetName, Record, ContextName, Vbs, NetIf) ->
get_values(VariablesWithType) ->
{Order, Varbinds} = extract_order(VariablesWithType, 1),
+ ?vtrace("get_values -> "
+ "~n Order: ~p"
+ "~n Varbinds: ~p", [Order, Varbinds]),
case snmpa_agent:do_get(snmpa_acm:get_root_mib_view(), Varbinds, true) of
{noError, _, NewVarbinds} ->
+ ?vtrace("get_values -> values retrieved"
+ "~n NewVarbinds: ~p", [NewVarbinds]),
%% NewVarbinds is the result of:
%% first a reverse, then a sort on the oid field and finally
%% a reverse during the get-processing so we need to re-sort
@@ -456,11 +478,13 @@ split_variables([]) -> {[], []}.
%% NOTE: This function is executed in the master agent's context
%%-----------------------------------------------------------------
find_dests("") ->
+ ?vtrace("find destinations", []),
snmp_notification_mib:get_targets();
find_dests(NotifyName) ->
+ ?vtrace("find destinations for ~p", [NotifyName]),
case snmp_notification_mib:get_targets(NotifyName) of
[] ->
- ?vlog("No dests found for snmpNotifyName: ~p",[NotifyName]),
+ ?vlog("No dests found for NotifyName: ~p", [NotifyName]),
[];
Dests ->
Dests
@@ -545,7 +569,8 @@ find_dest(TargetName) ->
send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel},
Timeout, Retry},
- Record, ContextName, Vbs, NetIf) ->
+ Record, ContextName, Vbs, NetIf,
+ ExtraInfo) ->
?vdebug("send_discovery_pdu -> entry with "
"~n Destination address: ~p"
"~n Target name: ~p"
@@ -555,9 +580,10 @@ send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel},
"~n Timeout: ~p"
"~n Retry: ~p"
"~n Record: ~p"
- "~n ContextName: ~p",
+ "~n ContextName: ~p"
+ "~n ExtraInfo: ~p",
[Dest, TargetName, SecModel, SecName, SecLevel,
- Timeout, Retry, Record, ContextName]),
+ Timeout, Retry, Record, ContextName, ExtraInfo]),
case get_mib_view(SecModel, SecName, SecLevel, ContextName) of
{ok, MibView} ->
case check_all_varbinds(Record, Vbs, MibView) of
@@ -567,7 +593,7 @@ send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel},
SecModel, SecName, SecLevel,
TargetName, ContextName,
Timeout, Retry,
- SysUpTime, NetIf);
+ SysUpTime, NetIf, ExtraInfo);
false ->
{error, {mibview_validation_failed, Vbs, MibView}}
end;
@@ -577,7 +603,7 @@ send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel},
send_discovery_pdu(Record, Dest, Vbs,
SecModel, SecName, SecLevel, TargetName,
- ContextName, Timeout, Retry, SysUpTime, NetIf) ->
+ ContextName, Timeout, Retry, SysUpTime, NetIf, ExtraInfo) ->
{_Oid, IVbs} = mk_v2_trap(Record, Vbs, SysUpTime), % v2 refers to SMIv2;
Sender = proc_lib:spawn_link(?MODULE, init_discovery_inform,
[self(),
@@ -586,13 +612,25 @@ send_discovery_pdu(Record, Dest, Vbs,
ContextName,
Timeout, Retry,
IVbs, NetIf,
- get(verbosity)]),
+ get(verbosity),
+ ExtraInfo]),
{ok, Sender, SecLevel}.
init_discovery_inform(Parent,
Dest,
SecModel, SecName, SecLevel, TargetName,
ContextName, Timeout, Retry, Vbs, NetIf, Verbosity) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ init_discovery_inform(Parent,
+ Dest,
+ SecModel, SecName, SecLevel, TargetName,
+ ContextName, Timeout, Retry, Vbs, NetIf,
+ Verbosity, ExtraInfo).
+init_discovery_inform(Parent,
+ Dest,
+ SecModel, SecName, SecLevel, TargetName,
+ ContextName, Timeout, Retry, Vbs, NetIf,
+ Verbosity, ExtraInfo) ->
put(verbosity, Verbosity),
put(sname, madis),
Pdu = make_discovery_pdu(Vbs),
@@ -600,7 +638,7 @@ init_discovery_inform(Parent,
SecLevelFlag = mk_flag(SecLevel),
SecData = {SecModel, SecName, SecLevelFlag, TargetName},
MsgData = {SecData, ContextEngineId, ContextName},
- Msg = {send_discovery, Pdu, MsgData, Dest, self()},
+ Msg = {send_discovery, Pdu, MsgData, Dest, self(), ExtraInfo},
?MODULE:send_discovery_inform(Parent, Timeout*10, Retry, Msg, NetIf).
%% note_timeout(Timeout, Retry)
@@ -644,11 +682,11 @@ send_discovery_inform(Parent, Timeout, Retry, Msg, NetIf) ->
%% should be used for the target, and determine the message
%% specific parameters to be used.
%%-----------------------------------------------------------------
-send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
- Type} | T],
+send_trap_pdus([{DestAddr, TargetName,
+ {MpModel, SecModel, SecName, SecLevel}, Type} | T],
ContextName,
{TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv,
- LocalEngineID, NetIf) ->
+ LocalEngineID, ExtraInfo, NetIf) ->
?vdebug("send trap pdus: "
"~n Destination address: ~p"
"~n Target name: ~p"
@@ -674,13 +712,13 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
[{DestAddr, Community} | V1Res],
V2Res, V3Res, Recv,
- LocalEngineID, NetIf);
+ LocalEngineID, ExtraInfo, NetIf);
undefined ->
?vdebug("No community found for v1 dest: ~p",
[element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res, V2Res, V3Res, Recv,
- LocalEngineID, NetIf)
+ LocalEngineID, ExtraInfo, NetIf)
end;
true when MpModel =:= ?MP_V2C ->
?vtrace("send_trap_pdus -> v2c mp model",[]),
@@ -695,13 +733,14 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res,
[{DestAddr, Community, Type}|V2Res],
- V3Res, Recv, LocalEngineID, NetIf);
+ V3Res, Recv,
+ LocalEngineID, ExtraInfo, NetIf);
undefined ->
?vdebug("No community found for v2c dest: ~p",
[element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res, V2Res, V3Res, Recv,
- LocalEngineID, NetIf)
+ LocalEngineID, ExtraInfo, NetIf)
end;
true when MpModel =:= ?MP_V3 ->
?vtrace("send_trap_pdus -> v3 mp model",[]),
@@ -710,20 +749,20 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res, V2Res,
[{DestAddr, MsgData, Type} | V3Res],
- Recv, LocalEngineID, NetIf);
+ Recv, LocalEngineID, ExtraInfo, NetIf);
true ->
?vlog("bad MpModel ~p for dest ~p",
[MpModel, element(2, DestAddr)]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res, V2Res, V3Res, Recv,
- LocalEngineID, NetIf);
+ LocalEngineID, ExtraInfo, NetIf);
_ ->
?vlog("no access for dest: "
"~n ~p in target ~p",
[element(2, DestAddr), TargetName]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
V1Res, V2Res, V3Res, Recv,
- LocalEngineID, NetIf)
+ LocalEngineID, ExtraInfo, NetIf)
end;
{discarded, Reason} ->
?vlog("mib view error ~p for"
@@ -731,24 +770,27 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel},
"~n SecName: ~w",
[Reason, element(2, DestAddr), SecName]),
send_trap_pdus(T, ContextName, {TrapRec, Vbs},
- V1Res, V2Res, V3Res, Recv, LocalEngineID, NetIf)
+ V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, ExtraInfo, NetIf)
end;
-send_trap_pdus([], ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res,
- Recv, LocalEngineID, NetIf) ->
+send_trap_pdus([], ContextName, {TrapRec, Vbs},
+ V1Res, V2Res, V3Res, Recv,
+ LocalEngineID, ExtraInfo,
+ NetIf) ->
SysUpTime = snmp_standard_mib:sys_up_time(),
?vdebug("send trap pdus with sysUpTime ~p", [SysUpTime]),
InformRecvs = get_inform_recvs(V2Res ++ V3Res),
InformTargets = [Addr || {Addr, _, _, _} <- InformRecvs],
deliver_recv(Recv, snmp_targets, InformTargets),
- send_v1_trap(TrapRec, V1Res, Vbs, NetIf, SysUpTime),
- send_v2_trap(TrapRec, V2Res, Vbs, Recv, NetIf, SysUpTime),
- send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, NetIf,
+ send_v1_trap(TrapRec, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime),
+ send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime),
+ send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, ExtraInfo, NetIf,
SysUpTime, ContextName).
-send_v1_trap(_TrapRec, [], _Vbs, _NetIf, _SysUpTime) ->
+send_v1_trap(_TrapRec, [], _Vbs, _ExtraInfo, _NetIf, _SysUpTime) ->
ok;
send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec},
- V1Res, Vbs, NetIf, SysUpTime) ->
+ V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) ->
?vdebug("prepare to send v1 trap "
"~n '~p'"
"~n with"
@@ -760,9 +802,10 @@ send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec},
lists:foreach(fun({Community, Addrs}) ->
?vtrace("send v1 trap pdu to ~p",[Addrs]),
NetIf ! {send_pdu, 'version-1', TrapPdu,
- {community, Community}, Addrs}
+ {community, Community}, Addrs, ExtraInfo}
end, AddrCommunities);
-send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, NetIf, SysUpTime) ->
+send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf,
+ SysUpTime) ->
%% Use alg. in rfc2089 to map a v2 trap to a v1 trap
% delete Counter64 objects from vbs
?vdebug("prepare to send v1 trap '~p'",[Oid]),
@@ -784,31 +827,31 @@ send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, NetIf, SysUpTime) ->
lists:foreach(fun({Community, Addrs}) ->
?vtrace("send v1 trap to ~p",[Addrs]),
NetIf ! {send_pdu, 'version-1', TrapPdu,
- {community, Community}, Addrs}
+ {community, Community}, Addrs, ExtraInfo}
end, AddrCommunities).
-send_v2_trap(_TrapRec, [], _Vbs, _Recv, _NetIf, _SysUpTime) ->
+send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) ->
ok;
-send_v2_trap(TrapRec, V2Res, Vbs, Recv, NetIf, SysUpTime) ->
+send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime) ->
?vdebug("prepare to send v2 trap",[]),
{_Oid, IVbs} = mk_v2_trap(TrapRec, Vbs, SysUpTime),
- TrapRecvs = get_trap_recvs(V2Res),
- InformRecvs = get_inform_recvs(V2Res),
- do_send_v2_trap(TrapRecvs, IVbs, NetIf),
- do_send_v2_inform(InformRecvs, IVbs, Recv, NetIf).
+ TrapRecvs = get_trap_recvs(V2Res),
+ InformRecvs = get_inform_recvs(V2Res),
+ do_send_v2_trap(TrapRecvs, IVbs, ExtraInfo, NetIf),
+ do_send_v2_inform(InformRecvs, IVbs, Recv, ExtraInfo, NetIf).
-send_v3_trap(_TrapRec, [], _Vbs, _Recv, _LocalEngineID,
+send_v3_trap(_TrapRec, [], _Vbs, _Recv, _LocalEngineID, _ExtraInfo,
_NetIf, _SysUpTime, _ContextName) ->
ok;
-send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID,
+send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, ExtraInfo,
NetIf, SysUpTime, ContextName) ->
?vdebug("prepare to send v3 trap",[]),
{_Oid, IVbs} = mk_v2_trap(TrapRec, Vbs, SysUpTime), % v2 refers to SMIv2;
TrapRecvs = get_trap_recvs(V3Res), % same SMI for v3
InformRecvs = get_inform_recvs(V3Res),
- do_send_v3_trap(TrapRecvs, ContextName, IVbs, NetIf),
+ do_send_v3_trap(TrapRecvs, ContextName, IVbs, ExtraInfo, NetIf),
do_send_v3_inform(InformRecvs, ContextName, IVbs, Recv,
- LocalEngineID, NetIf).
+ LocalEngineID, ExtraInfo, NetIf).
mk_v2_trap(#notification{oid = Oid}, Vbs, SysUpTime) ->
@@ -846,60 +889,70 @@ get_inform_recvs(InformRecvs) ->
[{Addr, MsgData, Timeout, Retry} ||
{Addr, MsgData, {inform, Timeout, Retry}} <- InformRecvs].
-do_send_v2_trap([], _Vbs, _NetIf) ->
+do_send_v2_trap([], _Vbs, _ExtraInfo, _NetIf) ->
ok;
-do_send_v2_trap(Recvs, Vbs, NetIf) ->
+do_send_v2_trap(Recvs, Vbs, ExtraInfo, NetIf) ->
TrapPdu = make_v2_notif_pdu(Vbs, 'snmpv2-trap'),
AddrCommunities = mk_addr_communities(Recvs),
lists:foreach(fun({Community, Addrs}) ->
?vtrace("~n send v2 trap to ~p",[Addrs]),
NetIf ! {send_pdu, 'version-2', TrapPdu,
- {community, Community}, Addrs}
+ {community, Community}, Addrs, ExtraInfo}
end, AddrCommunities),
ok.
-do_send_v2_inform([], _Vbs, _Recv, _NetIf) ->
+do_send_v2_inform([], _Vbs, _Recv, _ExtraInfo, _NetIf) ->
ok;
-do_send_v2_inform(Recvs, Vbs, Recv, NetIf) ->
+do_send_v2_inform(Recvs, Vbs, Recv, ExtraInfo, NetIf) ->
lists:foreach(
fun({Addr, Community, Timeout, Retry}) ->
?vtrace("~n start inform sender to send v2 inform to ~p",
[Addr]),
proc_lib:spawn_link(?MODULE, init_v2_inform,
[Addr, Timeout, Retry, Vbs,
- Recv, NetIf, Community,
+ Recv, ExtraInfo, NetIf, Community,
get(verbosity), get(sname)])
end,
Recvs).
-do_send_v3_trap([], _ContextName, _Vbs, _NetIf) ->
+do_send_v3_trap([], _ContextName, _Vbs, _ExtraInfo, _NetIf) ->
ok;
-do_send_v3_trap(Recvs, ContextName, Vbs, NetIf) ->
+do_send_v3_trap(Recvs, ContextName, Vbs, ExtraInfo, NetIf) ->
TrapPdu = make_v2_notif_pdu(Vbs, 'snmpv2-trap'), % Yes, v2
ContextEngineId = snmp_framework_mib:get_engine_id(),
lists:foreach(fun(Recv) ->
?vtrace("~n send v3 notif to ~p",[Recv]),
NetIf ! {send_pdu, 'version-3', TrapPdu,
- {v3, ContextEngineId, ContextName}, [Recv]}
+ {v3, ContextEngineId, ContextName},
+ [Recv], ExtraInfo}
end, Recvs),
ok.
-do_send_v3_inform([], _ContextName, _Vbs, _Recv, _LocalEngineID, _NetIf) ->
+do_send_v3_inform([], _ContextName, _Vbs, _Recv,
+ _LocalEngineID, _ExtraInfo, _NetIf) ->
ok;
-do_send_v3_inform(Recvs, ContextName, Vbs, Recv, LocalEngineID, NetIf) ->
+do_send_v3_inform(Recvs, ContextName, Vbs, Recv,
+ LocalEngineID, ExtraInfo, NetIf) ->
lists:foreach(
fun({Addr, MsgData, Timeout, Retry}) ->
?vtrace("~n start inform sender to send v3 inform to ~p",
[Addr]),
proc_lib:spawn_link(?MODULE, init_v3_inform,
[{Addr, MsgData}, Timeout, Retry, Vbs,
- Recv, LocalEngineID, NetIf, ContextName,
+ Recv, LocalEngineID, ExtraInfo,
+ NetIf, ContextName,
get(verbosity), get(sname)])
end,
Recvs).
%% New process
-init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community,V,S) ->
+init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community, V, S) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, ExtraInfo, NetIf,
+ Community, V, S).
+
+init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, ExtraInfo, NetIf,
+ Community, V, S) ->
%% Make a new Inform for each recipient; they need unique
%% request-ids!
put(verbosity,V),
@@ -908,17 +961,26 @@ init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community,V,S) ->
[Timeout,Retry]),
InformPdu = make_v2_notif_pdu(Vbs, 'inform-request'),
Msg = {send_pdu_req, 'version-2', InformPdu, {community, Community},
- [Addr], self()},
+ [Addr], self(), ExtraInfo},
?MODULE:send_inform(Addr, Timeout*10, Retry, Msg, Recv, NetIf).
%% New process
init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, ContextName, V, S) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID,
- init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID,
+ init_v3_inform(Addr, Timeout, Retry, Vbs, Recv,
+ LocalEngineID, ExtraInfo,
+ NetIf, ContextName, V, S).
+
+init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, NetIf,
+ ContextName, V, S) ->
+ ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO,
+ init_v3_inform(Addr, Timeout, Retry, Vbs, Recv,
+ LocalEngineID, ExtraInfo,
NetIf, ContextName, V, S).
-init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID,
+init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, ExtraInfo,
NetIf, ContextName, V, S) ->
%% Make a new Inform for each recipient; they need unique
%% request-ids!
@@ -929,7 +991,7 @@ init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID,
InformPdu = make_v2_notif_pdu(Vbs, 'inform-request'), % Yes, v2
ContextEngineId = LocalEngineID,
Msg = {send_pdu_req, 'version-3', InformPdu,
- {v3, ContextEngineId, ContextName}, [Addr], self()},
+ {v3, ContextEngineId, ContextName}, [Addr], self(), ExtraInfo},
?MODULE:send_inform(Addr, Timeout*10, Retry, Msg, Recv, NetIf).
send_inform(Addr, _Timeout, -1, _Msg, Recv, _NetIf) ->
@@ -1017,9 +1079,27 @@ transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2
Addr = {A1, A2, A3, A4},
Port = P1 bsl 8 + P2,
{Addr, Port};
+transform_taddr({?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}) -> % v2
+ Addr = {A1, A2, A3, A4},
+ Port = P1 bsl 8 + P2,
+ {Addr, Port};
+transform_taddr({?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}) -> % v2
+ Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+ Port = P1 bsl 8 + P2,
+ {Addr, Port};
transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3
Addr = {A1, A2, A3, A4},
Port = P1 bsl 8 + P2,
+ {Addr, Port};
+transform_taddr({{?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3
+ Addr = {A1, A2, A3, A4},
+ Port = P1 bsl 8 + P2,
+ {Addr, Port};
+transform_taddr({{?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}, _MsgData}) -> % v3
+ Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+ Port = P1 bsl 8 + P2,
{Addr, Port}.
@@ -1069,13 +1149,14 @@ mk_addr_communities(Recvs) ->
[{Addr, Comm} | T] = lists:keysort(2, Recvs),
mic(T, Comm, [Addr], []).
-mic([{Addr, Comm} | T], CurComm, AddrList, Res) when Comm == CurComm ->
+mic([{Addr, Comm} | T], CurComm, AddrList, Res) when Comm =:= CurComm ->
mic(T, CurComm, [Addr | AddrList], Res);
mic([{Addr, Comm} | T], CurComm, AddrList, Res) ->
mic(T, Comm, [Addr], [{CurComm, AddrList} | Res]);
mic([], CurComm, AddrList, Res) ->
[{CurComm, AddrList} | Res].
+
%%-----------------------------------------------------------------
%% Convert the SecurityLevel into a flag value used by snmpa_mpd
%%-----------------------------------------------------------------
diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl
index ae584bb3c1..6f54307f9f 100644
--- a/lib/snmp/src/agent/snmpa_usm.erl
+++ b/lib/snmp/src/agent/snmpa_usm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2010. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2011. 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
@@ -18,6 +18,10 @@
%%
-module(snmpa_usm).
+%% Avoid warning for local function error/1 clashing with autoimported BIF.
+-compile({no_auto_import,[error/1]}).
+%% Avoid warning for local function error/2 clashing with autoimported BIF.
+-compile({no_auto_import,[error/2]}).
-export([
process_incoming_msg/4, process_incoming_msg/5,
generate_outgoing_msg/5, generate_outgoing_msg/6,
@@ -326,7 +330,6 @@ non_authoritative(SecName,
end
end.
-
is_auth(?usmNoAuthProtocol, _, _, _, SecName, _, _, _, _) -> % 3.2.5
error(usmStatsUnsupportedSecLevels,
?usmStatsUnsupportedSecLevels_instance, SecName); % OTP-5464
@@ -609,8 +612,7 @@ authenticate_outgoing(Message, UsmSecParams,
end,
?vtrace("authenticate_outgoing -> encode message only",[]),
snmp_pdus:enc_message_only(Message2).
-
-
+
%%-----------------------------------------------------------------
%% Auth and priv algorithms
@@ -749,14 +751,19 @@ set_engine_latest_time(SnmpEngineID, EngineTime) ->
%%-----------------------------------------------------------------
%% Utility functions
%%-----------------------------------------------------------------
+-spec error(term()) -> no_return().
error(Reason) ->
throw({error, Reason}).
+-spec error(term(), term()) -> no_return().
error(Reason, ErrorInfo) ->
throw({error, Reason, ErrorInfo}).
+-spec error(term(), term(), term()) -> no_return().
error(Variable, Oid, SecName) ->
error(Variable, Oid, SecName, []).
+
+-spec error(term(), term(), term(), [term()]) -> no_return().
error(Variable, Oid, SecName, Opts) ->
Val = inc(Variable),
ErrorInfo = {#varbind{oid = Oid,
@@ -768,7 +775,6 @@ error(Variable, Oid, SecName, Opts) ->
inc(Name) -> ets:update_counter(snmp_agent_table, Name, 1).
-
get_counter(Name) ->
case (catch ets:lookup(snmp_agent_table, Name)) of
[{_, Val}] ->
@@ -776,8 +782,3 @@ get_counter(Name) ->
_ ->
0
end.
-
-
-
-
-
diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl
index d17ed73ab7..dadcf32543 100644
--- a/lib/snmp/src/agent/snmpa_vacm.erl
+++ b/lib/snmp/src/agent/snmpa_vacm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2009. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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([get_mib_view/5]).
-export([init/1, init/2, backup/1]).
-export([delete/1, get_row/1, get_next_row/1, insert/1, insert/2,
- dump_table/0]).
+ cleanup/0, dump_table/0]).
-include("SNMPv2-TC.hrl").
-include("SNMP-VIEW-BASED-ACM-MIB.hrl").
@@ -272,14 +272,20 @@ delete(Key) ->
ets:delete(snmpa_vacm, Key),
dump_table().
+
+cleanup() ->
+ ets:delete_all_objects(snmpa_vacm),
+ dump_table().
+
dump_table(true) ->
dump_table();
dump_table(_) ->
ok.
+
dump_table() ->
[{_, FName}] = ets:lookup(snmp_agent_table, snmpa_vacm_file),
- TmpName = FName ++ ".tmp",
+ TmpName = unique_table_name(FName),
case ets:tab2file(snmpa_vacm, TmpName) of
ok ->
case file:rename(TmpName, FName) of
@@ -294,6 +300,35 @@ dump_table() ->
[FName, Reason])
end.
+%% This little thing is an attempt to create a "unique" filename
+%% in order to minimize the risk of two processes at the same
+%% time dumping the table.
+unique_table_name(Pre) ->
+ %% We want something that is guaranteed to be unique,
+ %% therefor we use erlang:now() instead of os:timestamp()
+ unique_table_name(Pre, erlang:now()).
+
+unique_table_name(Pre, {_A, _B, C} = 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_~w",
+ [YYYY, MM, DD, Hour, Min, Sec, round(C/1000)]),
+ unique_table_name2(Pre, FormatDate).
+
+unique_table_name2(Pre, FormatedDate) ->
+ PidPart = unique_table_name_pid(),
+ lists:flatten(io_lib:format("~s.~s~s.tmp", [Pre, PidPart, FormatedDate])).
+
+unique_table_name_pid() ->
+ case string:tokens(pid_to_list(self()), [$<,$.,$>]) of
+ [A, B, C] ->
+ A ++ B ++ C ++ ".";
+ _ ->
+ ""
+ end.
+
%%-----------------------------------------------------------------
%% Alg.