diff options
Diffstat (limited to 'lib/snmp/src')
24 files changed, 2047 insertions, 663 deletions
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index 5644a43345..3debe0a30e 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -25,7 +25,7 @@ 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"). @@ -128,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}; @@ -173,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), diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl index 1cd69b430f..3da5766b44 100644 --- a/lib/snmp/src/agent/snmp_notification_mib.erl +++ b/lib/snmp/src/agent/snmp_notification_mib.erl @@ -273,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_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 270a5fd5b6..b2f2417b02 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -26,16 +26,18 @@ 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"). @@ -49,6 +51,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 @@ -139,39 +147,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, @@ -194,12 +214,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}}). %%----------------------------------------------------------------- @@ -261,7 +282,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} -> @@ -341,8 +368,11 @@ maybe_create_var(Var) -> init_var(Var) -> ets:insert(snmp_agent_table, {Var, 0}). vars() -> - [snmpUnavailableContexts, - snmpUnknownContexts]. + [ + snmpUnavailableContexts, + snmpUnknownContexts + ]. + %%----------------------------------------------------------------- %% API functions @@ -562,6 +592,8 @@ snmpTargetAddrTable(print) -> Prefix, element(?snmpTargetAddrTDomain, Row), case element(?snmpTargetAddrTDomain, Row) of ?snmpUDPDomain -> udp; + ?transportDomainUdpIpv4 -> udpIpv4; + ?transportDomainUdpIpv6 -> udpIpv6; _ -> undefined end, Prefix, element(?snmpTargetAddrTAddress, Row), @@ -610,14 +642,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, []}, @@ -628,12 +660,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, []}, @@ -647,55 +679,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/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index 22fbd33add..b2e4f253ab 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, @@ -108,8 +109,9 @@ -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). %%----------------------------------------------------------------- @@ -596,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) @@ -619,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) -> @@ -655,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..30bd34a205 100644 --- a/lib/snmp/src/agent/snmpa_acm.erl +++ b/lib/snmp/src/agent/snmpa_acm.erl @@ -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 f70885b2ec..e4cfeddb6a 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,10 +62,16 @@ -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/7, worker/2, worker_loop/1, do_send_trap/7]). + handle_pdu/7, worker/2, worker_loop/1, + do_send_trap/7, do_send_trap/8]). + +-include("snmpa_internal.hrl"). -ifndef(default_verbosity). -define(default_verbosity,silence). @@ -527,6 +533,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" @@ -538,13 +549,33 @@ 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) -> +%% ?d("send_trap -> entry with" +%% "~n self(): ~p" +%% "~n Agent: ~p [~p]" +%% "~n Trap: ~p" +%% "~n NotifyName: ~p" +%% "~n CtxName: ~p" +%% "~n Recv: ~p" +%% "~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. send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> ?d("send_trap -> entry with" @@ -558,14 +589,38 @@ 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). + +%% send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> +%% ?d("send_trap -> entry with" +%% "~n self(): ~p" +%% "~n Agent: ~p [~p]" +%% "~n Trap: ~p" +%% "~n NotifyName: ~p" +%% "~n CtxName: ~p" +%% "~n Recv: ~p" +%% "~n Varbinds: ~p" +%% "~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. + +%% </BACKWARD-COMPAT> %% -- Discovery functions -- @@ -655,7 +710,14 @@ wis(Atom) when is_atom(Atom) -> forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds) -> - Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds}. + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds, + ExtraInfo). + +forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds, + ExtraInfo) -> + Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds, + ExtraInfo}. %%----------------------------------------------------------------- @@ -745,6 +807,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 trap request:" + "~n Notification: ~p" + "~n SendOpts: ~p", + [Notification, SendOpts]), + case (catch handle_send_trap(cast, 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" @@ -753,9 +831,10 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) -> "~n Recv: ~p" "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, - case catch handle_send_trap(S, Trap, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID) of + case (catch handle_send_trap(S, Trap, NotifyName, ContextName, + Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -775,8 +854,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} -> @@ -785,8 +865,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" @@ -795,9 +898,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} -> @@ -806,6 +910,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:" @@ -908,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_info] send trap request:" + "~n Notification: ~p" + "~n SendOpts: ~p", + [Notification, SendOpts]), + case (catch handle_send_trap(call, 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:" @@ -917,19 +1039,20 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, "~n Recv: ~p" "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, 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. + %% 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 end, 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} -> @@ -951,8 +1074,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} -> @@ -962,6 +1086,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, @@ -1470,7 +1595,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}. @@ -1523,19 +1651,24 @@ spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, 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), @@ -1550,21 +1683,34 @@ worker_loop(Master) -> handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra), Master ! worker_available; - %% We don't trap exits! + %% We don't trap EXITs! {TrapRec, NotifyName, ContextName, Recv, Vbs} -> ?vtrace("worker_loop -> send trap:" "~n ~p", [TrapRec]), snmpa_trap:send_trap(TrapRec, NotifyName, - ContextName, Recv, Vbs, get(net_if)), + ContextName, Recv, Vbs, + ?DEFAULT_NOTIF_EXTRA_INFO, + get(net_if)), Master ! worker_available; - %% We don't trap exits! + %% We don't trap EXITs! {send_trap, TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID} -> ?vtrace("worker_loop -> send trap:" "~n ~p", [TrapRec]), snmpa_trap:send_trap(TrapRec, NotifyName, - ContextName, Recv, Vbs, LocalEngineID, + ContextName, Recv, Vbs, + LocalEngineID, ?DEFAULT_NOTIF_EXTRA_INFO, + get(net_if)), + Master ! worker_available; + + {send_trap, + 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, ExtraInfo, get(net_if)), Master ! worker_available; @@ -1713,34 +1859,79 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) -> ok end. +get_opt(Key, Default, SendOpts) -> + case lists:keysearch(Key, 1, SendOpts) of + {value, {Key, Value}} -> + Value; + false -> + Default + end. -handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds, - LocalEngineID) -> +handle_send_trap(call, #state{type = master_agent} = S, + Notification, SendOpts) -> + SendOpts2 = + case lists:keymember(local_engine_id, 1, SendOpts) of + true -> + SendOpts; + false -> + [{local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID}|SendOpts] + end, + handle_send_trap(S, Notification, SendOpts2); +handle_send_trap(call, S, Notification, SendOpts) -> + SendOpts2 = + case lists:keymember(local_engine_id, 1, SendOpts) of + true -> + SendOpts; + false -> + %% 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. + [{local_engine_id, ignore}|SendOpts] + end, + handle_send_trap(S, Notification, SendOpts2); +handle_send_trap(_, S, Notification, SendOpts) -> + handle_send_trap(S, Notification, SendOpts). + +handle_send_trap(S, Notification, SendOpts) -> + NotifyName = get_opt(name, "", SendOpts), + ContextName = get_opt(context, "", SendOpts), + Recv = get_opt(receiver, no_receiver, SendOpts), + Varbinds = get_opt(varbinds, [], SendOpts), + ExtraInfo = get_opt(extra, ?DEFAULT_NOTIF_EXTRA_INFO, SendOpts), + LocalEngineID = + get_opt(local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID, SendOpts), + handle_send_trap(S, Notification, NotifyName, ContextName, Recv, Varbinds, + LocalEngineID, ExtraInfo). + +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 Agent 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 + [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 @@ -1748,7 +1939,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 @@ -1764,13 +1955,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. @@ -1778,7 +1971,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 @@ -1796,7 +1989,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:" @@ -1804,36 +1997,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 ! {send_trap, TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID}, + LocalEngineID, ExtraInfo}, {ok, S#state{worker_state = busy}} end. @@ -1932,7 +2126,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, @@ -2009,9 +2203,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", []), @@ -3971,6 +4168,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..d406c58ee4 100644 --- a/lib/snmp/src/agent/snmpa_authentication_service.erl +++ b/lib/snmp/src/agent/snmpa_authentication_service.erl @@ -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 b4fc716b3e..4e5aab5319 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -48,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, @@ -447,7 +447,23 @@ target_addr_entry(Name, EngineId, TMask, MaxMessageSize) -> + target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp, + Timeout, RetryCount, TagList, ParamsName, + TMask, MaxMessageSize). + +target_addr_entry(Name, + Domain, + Ip, + Udp, + Timeout, + RetryCount, + TagList, + ParamsName, + EngineId, + TMask, + MaxMessageSize) -> {Name, + Domain, Ip, Udp, Timeout, @@ -465,9 +481,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" @@ -521,16 +541,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}). @@ -546,13 +581,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 9fa874f119..a91f30a4a6 100644 --- a/lib/snmp/src/agent/snmpa_internal.hrl +++ b/lib/snmp/src/agent/snmpa_internal.hrl @@ -23,6 +23,7 @@ -include_lib("snmp/src/app/snmp_internal.hrl"). -define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()). +-define(DEFAULT_NOTIF_EXTRA_INFO, {snmpa_default_notification_extra_info}). -define(snmpa_info(F, A), ?snmp_info("agent", F, A)). -define(snmpa_warning(F, A), ?snmp_warning("agent", F, A)). diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index fd75b98f84..39a4246d26 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -115,8 +115,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 +182,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 +222,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 +279,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", @@ -531,7 +535,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]), @@ -574,7 +578,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 diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 97a7a63dee..bbc5568cde 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -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_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index 450cb2e9f4..3c7ae804a5 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -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,25 +342,36 @@ 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). -send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, NetIf) -> +send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, + ExtraInfo, NetIf) -> (catch do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, NetIf)). + LocalEngineID, ExtraInfo, NetIf)). 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. @@ -440,11 +458,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 @@ -529,7 +549,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" @@ -539,9 +560,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 @@ -551,7 +573,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; @@ -561,7 +583,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(), @@ -570,13 +592,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), @@ -584,7 +618,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) @@ -628,11 +662,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" @@ -658,13 +692,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",[]), @@ -679,13 +713,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",[]), @@ -694,20 +729,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" @@ -715,24 +750,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" @@ -744,9 +782,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]), @@ -768,31 +807,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) -> @@ -830,60 +869,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), @@ -892,17 +941,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! @@ -913,7 +971,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) -> @@ -1001,9 +1059,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}. @@ -1053,13 +1129,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 f35d1f1916..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 @@ -330,7 +330,6 @@ non_authoritative(SecName, end end. - is_auth(?usmNoAuthProtocol, _, _, _, SecName, _, _, _, _) -> % 3.2.5 error(usmStatsUnsupportedSecLevels, ?usmStatsUnsupportedSecLevels_instance, SecName); % OTP-5464 @@ -613,8 +612,7 @@ authenticate_outgoing(Message, UsmSecParams, end, ?vtrace("authenticate_outgoing -> encode message only",[]), snmp_pdus:enc_message_only(Message2). - - + %%----------------------------------------------------------------- %% Auth and priv algorithms @@ -753,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, @@ -772,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}] -> @@ -780,8 +782,3 @@ get_counter(Name) -> _ -> 0 end. - - - - - diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index de0e5d6e14..5deb40be0f 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,10 +22,56 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.19", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm_usm, soft_purge, soft_purge, []}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_misc, soft_purge, soft_purge, []}, + {load_module, snmp_config, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmpa_trap, soft_purge, soft_purge, + [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, + {load_module, snmpa_acm, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd, snmp_target_mib]}, + {load_module, snmpa_conf, soft_purge, soft_purge, + [snmp_notification_mib]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, + [snmp_conf, snmp_target_mib]}, + {load_module, snmp_community_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf]}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, + {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + {update, snmpa_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, + [snmpa_acm, snmpa_mpd, snmpa_trap]} + ] + }, {"4.18", [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm_usm, soft_purge, soft_purge, []}, {load_module, snmp_misc, soft_purge, soft_purge, []}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_config, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmpa_conf, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, + [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, + {load_module, snmpa_acm, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd, snmp_target_mib]}, {load_module, snmpa, soft_purge, soft_purge, [snmp_community_mib, snmp_framework_mib, @@ -33,6 +79,8 @@ snmp_target_mib, snmp_user_based_sm_mib, snmp_view_based_acm_mib]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, + [snmp_conf, snmp_target_mib, snmpa_mib_lib]}, {load_module, snmp_community_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, {load_module, snmp_framework_mib, soft_purge, soft_purge, @@ -45,7 +93,15 @@ [snmpa_mib_lib]}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmpa_mib_lib, snmpa_vacm]}, - {load_module, snmpa_mib_lib, soft_purge, soft_purge, []} + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + + {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, + {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + + {update, snmpa_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, + [snmpa_acm, snmpa_mpd, snmpa_trap]} ] } ], @@ -53,10 +109,58 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.19", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm_usm, soft_purge, soft_purge, []}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_misc, soft_purge, soft_purge, []}, + {load_module, snmp_config, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmpa_trap, soft_purge, soft_purge, + [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, + {load_module, snmpa_acm, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd, snmp_target_mib]}, + {load_module, snmpa_conf, soft_purge, soft_purge, + [snmp_notification_mib]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, + [snmp_conf, snmp_target_mib]}, + {load_module, snmp_community_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmp_conf]}, + + {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, + {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + + {update, snmpa_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, + [snmpa_acm, snmpa_mpd, snmpa_trap]} + ] + }, {"4.18", [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm_usm, soft_purge, soft_purge, []}, {load_module, snmp_misc, soft_purge, soft_purge, []}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_config, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, + [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, + {load_module, snmpa_acm, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd, snmp_target_mib]}, {load_module, snmpa, soft_purge, soft_purge, [snmp_community_mib, snmp_framework_mib, @@ -64,6 +168,8 @@ snmp_target_mib, snmp_user_based_sm_mib, snmp_view_based_acm_mib]}, + {load_module, snmp_notification_mib, soft_purge, soft_purge, + [snmp_conf, snmp_target_mib, snmpa_mib_lib]}, {load_module, snmp_community_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, {load_module, snmp_framework_mib, soft_purge, soft_purge, @@ -76,7 +182,15 @@ [snmpa_mib_lib]}, {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, [snmpa_mib_lib, snmpa_vacm]}, - {load_module, snmpa_mib_lib, soft_purge, soft_purge, []} + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + + {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, + {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + + {update, snmpa_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, + [snmpa_acm, snmpa_mpd, snmpa_trap]} ] } ] diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index 5b6321b4c3..49f7d66b9a 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -57,15 +57,16 @@ usm_user_info/3, update_usm_user_info/4, %% - %% Basic SNMP API - sync_get/3, sync_get/4, sync_get/5, sync_get/6, - async_get/3, async_get/4, async_get/5, async_get/6, - sync_get_next/3, sync_get_next/4, sync_get_next/5, sync_get_next/6, - async_get_next/3, async_get_next/4, async_get_next/5, async_get_next/6, - sync_set/3, sync_set/4, sync_set/5, sync_set/6, - async_set/3, async_set/4, async_set/5, async_set/6, - sync_get_bulk/5, sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, - async_get_bulk/5, async_get_bulk/6, async_get_bulk/7, async_get_bulk/8, + %% Basic SNMP API (version "3"). + sync_get2/3, sync_get2/4, + async_get2/3, async_get2/4, + sync_get_next2/3, sync_get_next2/4, + async_get_next2/3, async_get_next2/4, + sync_set2/3, sync_set2/4, + async_set2/3, async_set2/4, + sync_get_bulk2/5, sync_get_bulk2/6, + async_get_bulk2/5, async_get_bulk2/6, + cancel_async_request/2, %% @@ -91,7 +92,61 @@ -export([format_reason/1, format_reason/2]). -%% Backward compatibillity exports +%% Backward compatibillity exports (API version "2") +-export([ + sync_get/3, sync_get/4, sync_get/5, sync_get/6, + async_get/3, async_get/4, async_get/5, async_get/6, + sync_get_next/3, sync_get_next/4, sync_get_next/5, sync_get_next/6, + async_get_next/3, async_get_next/4, async_get_next/5, async_get_next/6, + sync_set/3, sync_set/4, sync_set/5, sync_set/6, + async_set/3, async_set/4, async_set/5, async_set/6, + sync_get_bulk/5, sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, + async_get_bulk/5, async_get_bulk/6, async_get_bulk/7, async_get_bulk/8 + ]). + +%% Backward compatibillity exports (API version "1") +-deprecated({agent_info, 3}). +-deprecated({update_agent_info, 5}). +-deprecated({g, 3}). +-deprecated({g, 4}). +-deprecated({g, 5}). +-deprecated({g, 6}). +-deprecated({g, 7}). +-deprecated({ag, 3}). +-deprecated({ag, 4}). +-deprecated({ag, 5}). +-deprecated({ag, 6}). +-deprecated({ag, 7}). +-deprecated({gn, 3}). +-deprecated({gn, 4}). +-deprecated({gn, 5}). +-deprecated({gn, 6}). +-deprecated({gn, 7}). +-deprecated({agn, 3}). +-deprecated({agn, 4}). +-deprecated({agn, 5}). +-deprecated({agn, 6}). +-deprecated({agn, 7}). +-deprecated({gb, 5}). +-deprecated({gb, 6}). +-deprecated({gb, 7}). +-deprecated({gb, 8}). +-deprecated({gb, 9}). +-deprecated({agb, 5}). +-deprecated({agb, 6}). +-deprecated({agb, 7}). +-deprecated({agb, 8}). +-deprecated({agb, 9}). +-deprecated({s, 3}). +-deprecated({s, 4}). +-deprecated({s, 5}). +-deprecated({s, 6}). +-deprecated({s, 7}). +-deprecated({as, 3}). +-deprecated({as, 4}). +-deprecated({as, 5}). +-deprecated({as, 6}). +-deprecated({as, 7}). -export([ agent_info/3, update_agent_info/5, g/3, g/4, g/5, g/6, g/7, @@ -108,12 +163,12 @@ -export([start_link/3, snmpm_start_verify/2, snmpm_start_verify/3]). --include("snmp_debug.hrl"). +-include_lib("snmp/src/misc/snmp_debug.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). -include("snmpm_atl.hrl"). --include("snmp_types.hrl"). +-include("snmpm_internal.hrl"). -define(DEFAULT_AGENT_PORT, 161). --define(DEFAULT_CONTEXT, ""). %% This function is called when the snmp application @@ -393,24 +448,12 @@ agent_info(Addr, Port, Item) -> end. update_agent_info(UserId, TargetName, Item, Val) -> -%% p("update_agent_info -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Item: ~p" -%% "~n Val: ~p", [UserId, TargetName, Item, Val]), snmpm_config:update_agent_info(UserId, TargetName, Item, Val). %% Backward compatibillity functions update_agent_info(UserId, Addr, Port, Item, Val) -> -%% p("update_agent_info -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n Item: ~p" -%% "~n Val: ~p", [UserId, Addr, Port, Item, Val]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("update_agent_info -> TargetName: ~p", [TargetName]), update_agent_info(UserId, TargetName, Item, Val); Error -> Error @@ -472,94 +515,54 @@ which_usm_users(EngineID) when is_list(EngineID) -> %% --- synchroneous get-request --- %% +sync_get2(UserId, TargetName, Oids) -> + sync_get2(UserId, TargetName, Oids, []). + +sync_get2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:sync_get2(UserId, TargetName, Oids, SendOpts). + +%% <BACKWARD-COMPAT> sync_get(UserId, TargetName, Oids) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Oids: ~p", [UserId, TargetName, Oids]), - sync_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). - -sync_get(UserId, TargetName, Context, Oids) when is_list(Oids) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p", [UserId, TargetName, Context, Oids]), - snmpm_server:sync_get(UserId, TargetName, Context, Oids); - -sync_get(UserId, TargetName, Oids, Timeout) when is_integer(Timeout) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", [UserId, TargetName, Oids, Timeout]), - sync_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout). + sync_get2(UserId, TargetName, Oids). + +sync_get(UserId, TargetName, Oids, Timeout) + when is_list(Oids) andalso is_integer(Timeout) -> + SendOpts = [{timeout, Timeout}], + sync_get2(UserId, TargetName, Oids, SendOpts); +sync_get(UserId, TargetName, Context, [OH|_] = Oids) + when is_list(Context) andalso is_list(OH) -> + SendOpts = [{context, Context}], + sync_get2(UserId, TargetName, Oids, SendOpts). sync_get(UserId, TargetName, Context, Oids, Timeout) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", [UserId, TargetName, Context, Oids, Timeout]), - snmpm_server:sync_get(UserId, TargetName, Context, Oids, Timeout). + SendOpts = [{context, Context}, {timeout, Timeout}], + sync_get2(UserId, TargetName, Oids, SendOpts). sync_get(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p" -%% "~n ExtraInfo: ~p", -%% [UserId, TargetName, Context, Oids, Timeout, ExtraInfo]), - snmpm_server:sync_get(UserId, TargetName, Context, Oids, Timeout, - ExtraInfo). + SendOpts = [{context, Context}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> g(UserId, Addr, Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Oids: ~p", [UserId, Addr, Oids]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). g(UserId, Addr, CtxName, Oids) when is_list(CtxName) andalso is_list(Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p", [UserId, Addr, CtxName, Oids]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids); g(UserId, Addr, Port, Oids) when is_integer(Port) andalso is_list(Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n Oids: ~p", [UserId, Addr, Port, Oids]), g(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids); g(UserId, Addr, Oids, Timeout) when is_list(Oids) andalso is_integer(Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", [UserId, Addr, Oids, Timeout]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Timeout). g(UserId, Addr, Port, CtxName, Oids) when is_integer(Port) andalso is_list(CtxName) andalso is_list(Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p", [UserId, Addr, Port, CtxName, Oids]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("g -> TargetName: ~p", [TargetName]), sync_get(UserId, TargetName, CtxName, Oids); Error -> Error @@ -567,59 +570,28 @@ g(UserId, Addr, Port, CtxName, Oids) g(UserId, Addr, Port, Oids, Timeout) when is_integer(Port) andalso is_list(Oids) andalso is_integer(Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", -%% [UserId, Addr, Oids, Timeout]), g(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Timeout); g(UserId, Addr, CtxName, Oids, Timeout) when is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", -%% [UserId, Addr, CtxName, Oids, Timeout]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids, Timeout). g(UserId, Addr, Port, CtxName, Oids, Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", -%% [UserId, Addr, Port, CtxName, Oids, Timeout]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("g -> TargetName: ~p", [TargetName]), sync_get(UserId, TargetName, CtxName, Oids, Timeout); Error -> Error end. g(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p" -%% "~n ExtraInfo: ~p", -%% [UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("g -> TargetName: ~p", [TargetName]), sync_get(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo); Error -> Error end. +%% </DEPRECATED> @@ -629,23 +601,36 @@ g(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) -> %% through a call to handle_pdu/5 %% -async_get(UserId, TargetName, Oids) -> - async_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). +async_get2(UserId, TargetName, Oids) -> + async_get2(UserId, TargetName, Oids, []). + +async_get2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:async_get2(UserId, TargetName, Oids, SendOpts). -async_get(UserId, TargetName, Context, Oids) when is_list(Oids) -> - snmpm_server:async_get(UserId, TargetName, Context, Oids); +%% <BACKWARD-COMPAT> +async_get(UserId, TargetName, Oids) -> + async_get2(UserId, TargetName, Oids). async_get(UserId, TargetName, Oids, Expire) when is_integer(Expire) -> - async_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Expire). + SendOpts = [{timeout, Expire}], + async_get2(UserId, TargetName, Oids, SendOpts); +async_get(UserId, TargetName, Context, Oids) + when is_list(Context) andalso is_list(Oids) -> + SendOpts = [{context, Context}], + async_get2(UserId, TargetName, Oids, SendOpts). async_get(UserId, TargetName, Context, Oids, Expire) -> - snmpm_server:async_get(UserId, TargetName, Context, Oids, Expire). + SendOpts = [{timeout, Expire}, {context, Context}], + async_get2(UserId, TargetName, Oids, SendOpts). async_get(UserId, TargetName, Context, Oids, Expire, ExtraInfo) -> - snmpm_server:async_get(UserId, TargetName, Context, Oids, Expire, - ExtraInfo). + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_get2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> ag(UserId, Addr, Oids) -> ag(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). @@ -690,31 +675,44 @@ ag(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- synchroneous get_next-request --- %% -sync_get_next(UserId, TargetName, Oids) -> - sync_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). +sync_get_next2(UserId, TargetName, Oids) -> + sync_get_next2(UserId, TargetName, Oids, []). -sync_get_next(UserId, TargetName, Context, Oids) - when is_list(Context) andalso is_list(Oids) -> - snmpm_server:sync_get_next(UserId, TargetName, Context, Oids); +sync_get_next2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:sync_get_next2(UserId, TargetName, Oids, SendOpts). + +%% <BACKWARD-COMPAT> +sync_get_next(UserId, TargetName, Oids) -> + sync_get_next2(UserId, TargetName, Oids). sync_get_next(UserId, TargetName, Oids, Timeout) when is_list(Oids) andalso is_integer(Timeout) -> - sync_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout). + SendOpts = [{timeout, Timeout}], + sync_get_next2(UserId, TargetName, Oids, SendOpts); +sync_get_next(UserId, TargetName, Context, Oids) + when is_list(Context) andalso is_list(Oids) -> + SendOpts = [{context, Context}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). sync_get_next(UserId, TargetName, Context, Oids, Timeout) -> - snmpm_server:sync_get_next(UserId, TargetName, Context, Oids, Timeout). + SendOpts = [{timeout, Timeout}, {context, Context}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). sync_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) -> - snmpm_server:sync_get_next(UserId, TargetName, Context, Oids, Timeout, - ExtraInfo). + SendOpts = [{timeout, Timeout}, {context, Context}, {extra, ExtraInfo}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> gn(UserId, Addr, Oids) -> gn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). @@ -759,30 +757,44 @@ gn(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- asynchroneous get_next-request --- %% +async_get_next2(UserId, TargetName, Oids) -> + async_get_next2(UserId, TargetName, Oids, []). + +async_get_next2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:async_get_next2(UserId, TargetName, Oids, SendOpts). + +%% <BACKWARD-COMPAT> async_get_next(UserId, TargetName, Oids) -> - async_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). + async_get_next2(UserId, TargetName, Oids). +async_get_next(UserId, TargetName, Oids, Expire) + when is_list(Oids) andalso is_integer(Expire) -> + SendOpts = [{timeout, Expire}], + async_get_next2(UserId, TargetName, Oids, SendOpts); async_get_next(UserId, TargetName, Context, Oids) when is_list(Context) andalso is_list(Oids) -> - snmpm_server:async_get_next(UserId, TargetName, Context, Oids); + SendOpts = [{context, Context}], + async_get_next2(UserId, TargetName, Oids, SendOpts). -async_get_next(UserId, TargetName, Oids, Timeout) - when is_list(Oids) andalso is_integer(Timeout) -> - async_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout). +async_get_next(UserId, TargetName, Context, Oids, Expire) -> + SendOpts = [{timeout, Expire}, {context, Context}], + async_get_next2(UserId, TargetName, Oids, SendOpts). -async_get_next(UserId, TargetName, Context, Oids, Timeout) -> - snmpm_server:async_get_next(UserId, TargetName, Context, Oids, Timeout). +async_get_next(UserId, TargetName, Context, Oids, Expire, ExtraInfo) -> + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_get_next2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> -async_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) -> - snmpm_server:async_get_next(UserId, TargetName, Context, Oids, Timeout, - ExtraInfo). +%% <DEPRECATED> agn(UserId, Addr, Oids) -> agn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). @@ -828,31 +840,44 @@ agn(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- synchroneous set-request --- %% -sync_set(UserId, TargetName, VarsAndVals) -> - sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals). +sync_set2(UserId, TargetName, VarsAndVals) -> + sync_set2(UserId, TargetName, VarsAndVals, []). -sync_set(UserId, TargetName, Context, VarsAndVals) - when is_list(Context) andalso is_list(VarsAndVals) -> - snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals); +sync_set2(UserId, TargetName, VarsAndVals, SendOpts) + when is_list(VarsAndVals) andalso is_list(SendOpts) -> + snmpm_server:sync_set2(UserId, TargetName, VarsAndVals, SendOpts). + +%% <BACKWARD-COMPAT> +sync_set(UserId, TargetName, VarsAndVals) -> + sync_set2(UserId, TargetName, VarsAndVals). sync_set(UserId, TargetName, VarsAndVals, Timeout) when is_list(VarsAndVals) andalso is_integer(Timeout) -> - sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Timeout). + SendOpts = [{timeout, Timeout}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts); +sync_set(UserId, TargetName, Context, VarsAndVals) + when is_list(Context) andalso is_list(VarsAndVals) -> + SendOpts = [{context, Context}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). sync_set(UserId, TargetName, Context, VarsAndVals, Timeout) -> - snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals, Timeout). + SendOpts = [{timeout, Timeout}, {context, Context}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). sync_set(UserId, TargetName, Context, VarsAndVals, Timeout, ExtraInfo) -> - snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals, Timeout, - ExtraInfo). + SendOpts = [{timeout, Timeout}, {context, Context}, {extra, ExtraInfo}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> s(UserId, Addr, VarsAndVals) -> s(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals). @@ -906,31 +931,44 @@ s(UserId, Addr, Port, CtxName, VarsAndVals, Timeout, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- asynchroneous set-request --- %% -async_set(UserId, TargetName, VarsAndVals) -> - async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals). +async_set2(UserId, TargetName, VarsAndVals) -> + async_set2(UserId, TargetName, VarsAndVals, []). -async_set(UserId, TargetName, Context, VarsAndVals) - when is_list(Context) andalso is_list(VarsAndVals) -> - snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals); +async_set2(UserId, TargetName, VarsAndVals, SendOpts) + when is_list(VarsAndVals) andalso is_list(SendOpts) -> + snmpm_server:async_set2(UserId, TargetName, VarsAndVals, SendOpts). + +%% <BACKWARD-COMPAT> +async_set(UserId, TargetName, VarsAndVals) -> + async_set2(UserId, TargetName, VarsAndVals). async_set(UserId, TargetName, VarsAndVals, Expire) when is_list(VarsAndVals) andalso is_integer(Expire) -> - async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Expire). + SendOpts = [{timeout, Expire}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts); +async_set(UserId, TargetName, Context, VarsAndVals) + when is_list(Context) andalso is_list(VarsAndVals) -> + SendOpts = [{context, Context}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). async_set(UserId, TargetName, Context, VarsAndVals, Expire) -> - snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals, Expire). + SendOpts = [{timeout, Expire}, {context, Context}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). async_set(UserId, TargetName, Context, VarsAndVals, Expire, ExtraInfo) -> - snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals, Expire, - ExtraInfo). + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> as(UserId, Addr, VarsAndVals) -> as(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals). @@ -984,44 +1022,77 @@ as(UserId, Addr, Port, CtxName, VarsAndVals, Expire, ExtraInfo) -> Error -> Error end. - - +%% </DEPRECATED> %% --- synchroneous get-bulk --- %% -sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> - sync_get_bulk(UserId, TargetName, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids). +sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). -sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) +sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) when is_integer(NonRep) andalso is_integer(MaxRep) andalso - is_list(Context) andalso - is_list(Oids) -> - snmpm_server:sync_get_bulk(UserId, TargetName, - NonRep, MaxRep, - Context, Oids); + is_list(Oids) andalso + is_list(SendOpts) -> + %% p("sync_get_bulk -> entry with" + %% "~n UserId: ~p" + %% "~n TargetName: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n SendOpts: ~p", + %% [UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), + snmpm_server:sync_get_bulk2(UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts). + +%% <BACKWARD-COMPAT> +sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Timeout) when is_integer(NonRep) andalso is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Timeout) -> - sync_get_bulk(UserId, TargetName, NonRep, MaxRep, - ?DEFAULT_CONTEXT, Oids, Timeout). + SendOpts = [{timeout, Timeout}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts); +sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) + when is_integer(NonRep) andalso + is_integer(MaxRep) andalso + is_list(Context) andalso + is_list(Oids) -> + %% p("sync_get_bulk -> entry with" + %% "~n UserId: ~p" + %% "~n TargetName: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Context: ~p" + %% "~n Oids: ~p", [UserId, TargetName, NonRep, MaxRep, Context, Oids]), + SendOpts = [{context, Context}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout) -> - snmpm_server:sync_get_bulk(UserId, TargetName, NonRep, MaxRep, - Context, Oids, Timeout). + SendOpts = [{timeout, Timeout}, {context, Context}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout, ExtraInfo) -> - snmpm_server:sync_get_bulk(UserId, TargetName, NonRep, MaxRep, - Context, Oids, Timeout, ExtraInfo). + SendOpts = [{timeout, Timeout}, {context, Context}, {extra, ExtraInfo}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> gb(UserId, Addr, NonRep, MaxRep, Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, NonRep, MaxRep, Oids]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids). gb(UserId, Addr, Port, NonRep, MaxRep, Oids) @@ -1029,6 +1100,14 @@ gb(UserId, Addr, Port, NonRep, MaxRep, Oids) is_integer(NonRep) andalso is_integer(MaxRep) andalso is_list(Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, Oids]), gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids); gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids) @@ -1036,6 +1115,14 @@ gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids) is_integer(MaxRep) andalso is_list(CtxName) andalso is_list(Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, NonRep, MaxRep, CtxName, Oids]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids); gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout) @@ -1043,6 +1130,14 @@ gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout) is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, NonRep, MaxRep, Oids, Timeout]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids, Timeout). gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids) @@ -1051,8 +1146,18 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids) is_integer(MaxRep) andalso is_list(CtxName) andalso is_list(Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids]), case target_name(Addr, Port) of {ok, TargetName} -> + %% p("gb -> TargetName: ~p", [TargetName]), sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids); Error -> Error @@ -1064,6 +1169,15 @@ gb(UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout) is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout]), gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Timeout); gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout) @@ -1072,10 +1186,29 @@ gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout) is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids, Timeout). gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout]), case target_name(Addr, Port) of {ok, TargetName} -> sync_get_bulk(UserId, TargetName, @@ -1085,6 +1218,17 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout) -> end. gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p" + %% "~n ExtraInfo: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo]), case target_name(Addr, Port) of {ok, TargetName} -> sync_get_bulk(UserId, TargetName, @@ -1092,42 +1236,55 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- asynchroneous get-bulk --- %% -async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> - async_get_bulk(UserId, TargetName, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids). +async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). -async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) +async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) when is_integer(NonRep) andalso is_integer(MaxRep) andalso - is_list(Context) andalso - is_list(Oids) -> - snmpm_server:async_get_bulk(UserId, TargetName, - NonRep, MaxRep, Context, Oids); + is_list(Oids) andalso + is_list(SendOpts) -> + snmpm_server:async_get_bulk2(UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts). + +%% <BACKWARD-COMPAT> +async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids). async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Expire) when is_integer(NonRep) andalso is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Expire) -> - async_get_bulk(UserId, TargetName, - NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Expire). + SendOpts = [{timeout, Expire}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts); +async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) + when is_integer(NonRep) andalso + is_integer(MaxRep) andalso + is_list(Context) andalso + is_list(Oids) -> + SendOpts = [{context, Context}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Expire) -> - snmpm_server:async_get_bulk(UserId, TargetName, - NonRep, MaxRep, Context, Oids, Expire). + SendOpts = [{timeout, Expire}, {context, Context}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Expire, ExtraInfo) -> - snmpm_server:async_get_bulk(UserId, TargetName, - NonRep, MaxRep, - Context, Oids, Expire, ExtraInfo). + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> agb(UserId, Addr, NonRep, MaxRep, Oids) -> agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids). @@ -1200,6 +1357,7 @@ agb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> cancel_async_request(UserId, ReqId) -> diff --git a/lib/snmp/src/manager/snmpm_internal.hrl b/lib/snmp/src/manager/snmpm_internal.hrl index 5d9b32e3f6..53ad41c6b0 100644 --- a/lib/snmp/src/manager/snmpm_internal.hrl +++ b/lib/snmp/src/manager/snmpm_internal.hrl @@ -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 @@ -20,6 +20,11 @@ -ifndef(snmpm_internal). -define(snmpm_internal, true). +-define(DEFAULT_CONTEXT, ""). +-define(SNMPM_EXTRA_INFO_TAG, snmpm_extra_info_tag). +-define(DEFAULT_EXTRA_INFO, {?SNMPM_EXTRA_INFO_TAG}). + + -include_lib("snmp/src/app/snmp_internal.hrl"). -define(snmpm_info(F, A), ?snmp_info("manager", F, A)). diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index 07156dacd9..3d248fff57 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -99,7 +99,7 @@ stop(Pid) -> call(Pid, stop). send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) -> - send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, undefined). + send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO). send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) when is_record(Pdu, pdu) -> @@ -380,13 +380,14 @@ handle_call(Req, From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_cast({send_pdu, Pdu, Vsn, MsgData, Addr, Port, _ExtraInfo}, State) -> +handle_cast({send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}, State) -> ?vlog("received send_pdu message with" "~n Pdu: ~p" "~n Vsn: ~p" "~n MsgData: ~p" "~n Addr: ~p" "~n Port: ~p", [Pdu, Vsn, MsgData, Addr, Port]), + maybe_process_extra_info(ExtraInfo), maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State), {noreply, State}; @@ -999,6 +1000,19 @@ pdu_type_of(TrapPdu) when is_record(TrapPdu, trappdu) -> %% ------------------------------------------------------------------- +%% At this point this function is used during testing +maybe_process_extra_info(?DEFAULT_EXTRA_INFO) -> + ok; +maybe_process_extra_info({?SNMPM_EXTRA_INFO_TAG, Fun}) + when is_function(Fun, 0) -> + (catch Fun()), + ok; +maybe_process_extra_info(_ExtraInfo) -> + ok. + + +%% ------------------------------------------------------------------- + t() -> {A,B,C} = erlang:now(), A*1000000000+B*1000+(C div 1000). diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl index d64b5b1d53..b8d7cf6375 100644 --- a/lib/snmp/src/manager/snmpm_server.erl +++ b/lib/snmp/src/manager/snmpm_server.erl @@ -32,14 +32,14 @@ register_user/4, register_user_monitor/4, unregister_user/1, - sync_get/4, sync_get/5, sync_get/6, - async_get/4, async_get/5, async_get/6, - sync_get_next/4, sync_get_next/5, sync_get_next/6, - async_get_next/4, async_get_next/5, async_get_next/6, - sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, - async_get_bulk/6, async_get_bulk/7, async_get_bulk/8, - sync_set/4, sync_set/5, sync_set/6, - async_set/4, async_set/5, async_set/6, + sync_get2/4, + async_get2/4, + sync_get_next2/4, + async_get_next2/4, + sync_get_bulk2/6, + async_get_bulk2/6, + sync_set2/4, + async_set2/4, cancel_async_request/2, %% discovery/2, discovery/3, discovery/4, discovery/5, discovery/6, @@ -55,6 +55,20 @@ ]). +%% <BACKWARD-COMPAT> +-export([sync_get/4, sync_get/5, sync_get/6, + async_get/4, async_get/5, async_get/6, + sync_get_next/4, sync_get_next/5, sync_get_next/6, + async_get_next/4, async_get_next/5, async_get_next/6, + sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, + async_get_bulk/6, async_get_bulk/7, async_get_bulk/8, + sync_set/4, sync_set/5, sync_set/6, + async_set/4, async_set/5, async_set/6 + ]). +%% </BACKWARD-COMPAT> + + + %% Internal exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). @@ -75,13 +89,39 @@ -define(SERVER, ?MODULE). --define(SYNC_GET_TIMEOUT, 5000). --define(SYNC_SET_TIMEOUT, 5000). --define(DEFAULT_ASYNC_EXPIRE, 5000). --define(EXTRA_INFO, undefined). - --define(SNMP_AGENT_PORT, 161). - +-define(DEFAULT_SYNC_TIMEOUT, timer:seconds(5)). +-define(DEFAULT_SYNC_GET_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). +-define(DEFAULT_SYNC_GET_NEXT_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). +-define(DEFAULT_SYNC_GET_BULK_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). +-define(DEFAULT_SYNC_SET_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). + +-define(DEFAULT_ASYNC_TIMEOUT, timer:seconds(5)). +-define(DEFAULT_ASYNC_GET_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). +-define(DEFAULT_ASYNC_GET_NEXT_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). +-define(DEFAULT_ASYNC_GET_BULK_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). +-define(DEFAULT_ASYNC_SET_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). + +-define(SNMP_AGENT_PORT, 161). + +-define(SYNC_GET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_GET_TIMEOUT, SendOpts)). +-define(SYNC_GET_NEXT_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_GET_NEXT_TIMEOUT, SendOpts)). +-define(SYNC_GET_BULK_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_GET_BULK_TIMEOUT, SendOpts)). +-define(SYNC_SET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_SET_TIMEOUT, SendOpts)). + +-define(ASYNC_GET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_GET_TIMEOUT, SendOpts)). +-define(ASYNC_GET_NEXT_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_GET_NEXT_TIMEOUT, SendOpts)). +-define(ASYNC_GET_BULK_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_GET_BULK_TIMEOUT, SendOpts)). +-define(ASYNC_SET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_SET_TIMEOUT, SendOpts)). + +-define(GET_EXTRA(SendOpts), get_opt(extra, ?DEFAULT_EXTRA_INFO, SendOpts)). -ifdef(snmp_debug). -define(GS_START_LINK(Args), @@ -192,82 +232,140 @@ unregister_user(UserId) -> %% -- [sync] get -- +%% The reason why we have a sync_get2 is to simplify backward +%% compatibillity. + +%% sync_get2(UserId, TargetName, Oids) -> +%% sync_get2(UserId, TargetName, Oids, []). +sync_get2(UserId, TargetName, Oids, Opts) -> + call({sync_get, self(), UserId, TargetName, Oids, Opts}). + + +%% <BACKWARD-COMPAT> sync_get(UserId, TargetName, CtxName, Oids) -> sync_get(UserId, TargetName, CtxName, Oids, - ?SYNC_GET_TIMEOUT). + ?DEFAULT_SYNC_GET_TIMEOUT). sync_get(UserId, TargetName, CtxName, Oids, Timeout) -> - sync_get(UserId, TargetName, CtxName, Oids, Timeout, ?EXTRA_INFO). + sync_get(UserId, TargetName, CtxName, Oids, Timeout, ?DEFAULT_EXTRA_INFO). sync_get(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo) when is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> - call({sync_get, self(), UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}). + Opts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get2(UserId, TargetName, Oids, Opts). +%% </BACKWARD-COMPAT> + + %% -- [async] get -- +%% async_get2(UserId, TargetName, Oids) -> +%% async_get2(UserId, TargetName, Oids, []). +async_get2(UserId, TargetName, Oids, SendOpts) -> + call({async_get, self(), UserId, TargetName, Oids, SendOpts}). + + +%% <BACKWARD-COMPAT> async_get(UserId, TargetName, CtxName, Oids) -> async_get(UserId, TargetName, CtxName, Oids, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_GET_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_get(UserId, TargetName, CtxName, Oids, Expire) -> - async_get(UserId, TargetName, CtxName, Oids, Expire, ?EXTRA_INFO). + async_get(UserId, TargetName, CtxName, Oids, Expire, ?DEFAULT_EXTRA_INFO). async_get(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo) when (is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) andalso (Expire >= 0)) -> - call({async_get, self(), UserId, TargetName, CtxName, Oids, Expire, - ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_get2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> + + %% -- [sync] get-next -- +%% sync_get_next2(UserId, TargetName, Oids) -> +%% sync_get_next2(UserId, TargetName, Oids, []). +sync_get_next2(UserId, TargetName, Oids, SendOpts) -> + call({sync_get_next, self(), UserId, TargetName, Oids, SendOpts}). + + +%% <BACKWARD-COMPAT> sync_get_next(UserId, TargetName, CtxName, Oids) -> - sync_get_next(UserId, TargetName, CtxName, Oids, ?SYNC_GET_TIMEOUT, - ?EXTRA_INFO). + sync_get_next(UserId, TargetName, CtxName, Oids, + ?DEFAULT_SYNC_GET_TIMEOUT, ?DEFAULT_EXTRA_INFO). sync_get_next(UserId, TargetName, CtxName, Oids, Timeout) -> - sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ?EXTRA_INFO). + sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, + ?DEFAULT_EXTRA_INFO). sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo) when is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> - call({sync_get_next, self(), UserId, TargetName, CtxName, Oids, Timeout, - ExtraInfo}). + SendOpts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). +%% <BACKWARD-COMPAT> + + %% -- [async] get-next -- +%% async_get_next2(UserId, TargetName, Oids) -> +%% async_get_next2(UserId, TargetName, Oids, []). +async_get_next2(UserId, TargetName, Oids, SendOpts) -> + call({async_get_next, self(), UserId, TargetName, Oids, SendOpts}). + + async_get_next(UserId, TargetName, CtxName, Oids) -> async_get_next(UserId, TargetName, CtxName, Oids, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_GET_NEXT_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_get_next(UserId, TargetName, CtxName, Oids, Expire) -> - async_get_next(UserId, TargetName, CtxName, Oids, Expire, ?EXTRA_INFO). + async_get_next(UserId, TargetName, CtxName, Oids, Expire, + ?DEFAULT_EXTRA_INFO). async_get_next(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo) when (is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) andalso (Expire >= 0)) -> - call({async_get_next, self(), UserId, TargetName, CtxName, Oids, - Expire, ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_get_next2(UserId, TargetName, Oids, SendOpts). + + %% -- [sync] get-bulk -- +%% sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> +%% sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). +sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> + %% p("sync_get_bulk2 -> entry with" + %% "~n UserId: ~p" + %% "~n TargetName: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n SendOpts: ~p", + %% [UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), + call({sync_get_bulk, self(), UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts}). + sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids) -> sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - ?SYNC_GET_TIMEOUT, ?EXTRA_INFO). + ?DEFAULT_SYNC_GET_TIMEOUT, ?DEFAULT_EXTRA_INFO). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout) -> sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - Timeout, ?EXTRA_INFO). + Timeout, ?DEFAULT_EXTRA_INFO). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) @@ -277,20 +375,28 @@ sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout, is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> - call({sync_get_bulk, self(), UserId, TargetName, - NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo}). + SendOpts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). + %% -- [async] get-bulk -- +%% async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> +%% async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). +async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> + call({async_get_bulk, self(), UserId, TargetName, NonRep, MaxRep, + Oids, SendOpts}). + + async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids) -> async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_GET_BULK_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire) -> async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - Expire, ?EXTRA_INFO). + Expire, ?DEFAULT_EXTRA_INFO). async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo) @@ -300,45 +406,61 @@ async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire, is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) -> - call({async_get_bulk, self(), UserId, TargetName, - NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). + + %% -- [sync] set -- %% VarsAndValues is: {PlainOid, o|s|i, Value} (unknown mibs) | {Oid, Value} +%% sync_set2(UserId, TargetName, VarsAndVals) -> +%% sync_set2(UserId, TargetName, VarsAndVals, []). +sync_set2(UserId, TargetName, VarsAndVals, SendOpts) -> + call({sync_set, self(), UserId, TargetName, VarsAndVals, SendOpts}). + + sync_set(UserId, TargetName, CtxName, VarsAndVals) -> sync_set(UserId, TargetName, CtxName, VarsAndVals, - ?SYNC_SET_TIMEOUT, ?EXTRA_INFO). + ?DEFAULT_SYNC_SET_TIMEOUT, ?DEFAULT_EXTRA_INFO). sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout) -> sync_set(UserId, TargetName, CtxName, VarsAndVals, - Timeout, ?EXTRA_INFO). + Timeout, ?DEFAULT_EXTRA_INFO). sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo) when is_list(TargetName) andalso is_list(CtxName) andalso is_list(VarsAndVals) andalso is_integer(Timeout) -> - call({sync_set, self(), UserId, TargetName, - CtxName, VarsAndVals, Timeout, ExtraInfo}). + SendOpts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). + + %% -- [async] set -- +%% async_set2(UserId, TargetName, VarsAndVals) -> +%% async_set2(UserId, TargetName, VarsAndVals, []). +async_set2(UserId, TargetName, VarsAndVals, SendOpts) -> + call({async_set, self(), UserId, TargetName, VarsAndVals, SendOpts}). + + async_set(UserId, TargetName, CtxName, VarsAndVals) -> async_set(UserId, TargetName, CtxName, VarsAndVals, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_SET_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_set(UserId, TargetName, CtxName, VarsAndVals, Expire) -> async_set(UserId, TargetName, CtxName, VarsAndVals, - Expire, ?EXTRA_INFO). + Expire, ?DEFAULT_EXTRA_INFO). async_set(UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo) when (is_list(TargetName) andalso is_list(CtxName) andalso is_list(VarsAndVals) andalso is_integer(Expire) andalso (Expire >= 0)) -> - call({async_set, self(), UserId, TargetName, - CtxName, VarsAndVals, Expire, ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). cancel_async_request(UserId, ReqId) -> @@ -571,9 +693,26 @@ handle_call({unregister_user, UserId}, _From, State) -> %% We will reply to this request later, when the reply comes in from the %% agent, or when the timeout hits (unless we get an error now). -handle_call({sync_get, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, +handle_call({sync_get, Pid, UserId, TargetName, Oids, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_get request for: " + "~n ~p", [UserId, TargetName, Oids]), + case (catch handle_sync_get(Pid, + UserId, TargetName, Oids, SendOpts, + From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade +handle_call({sync_get, + Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_get [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received sync_get request for: " + "~n ~p", [UserId, TargetName, CtxName, Oids]), case (catch handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State)) of @@ -582,10 +721,30 @@ handle_call({sync_get, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInf Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> + + +handle_call({sync_get_next, Pid, UserId, TargetName, Oids, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_get_next request for: " + "~n ~p", [UserId, TargetName, SendOpts]), + case (catch handle_sync_get_next(Pid, + UserId, TargetName, Oids, SendOpts, + From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; -handle_call({sync_get_next, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_get_next [~p] request", [CtxName]), +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade +handle_call({sync_get_next, + Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, + From, State) -> + ?vlog("[~p,~p,~p] received sync_get_next request for" + "~n ~p", [UserId, TargetName, CtxName, Oids]), case (catch handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State)) of @@ -594,13 +753,31 @@ handle_call({sync_get_next, Pid, UserId, TargetName, CtxName, Oids, Timeout, Ext Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> %% Check agent version? This op not in v1 +handle_call({sync_get_bulk, + Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_get_bulk request for: " + "~n ~p", [UserId, TargetName, Oids]), + case (catch handle_sync_get_bulk(Pid, + UserId, TargetName, NonRep, MaxRep, Oids, + SendOpts, From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({sync_get_bulk, Pid, UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_get_bulk [~p] request", [CtxName]), + ?vlog("[~p,~p] received sync_get_bulk request for: ~p" + "~n ~p", [UserId, TargetName, CtxName, Oids]), case (catch handle_sync_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, @@ -610,12 +787,31 @@ handle_call({sync_get_bulk, Pid, UserId, TargetName, Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> + + +handle_call({sync_set, + Pid, UserId, TargetName, VarsAndVals, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_set request for: " + "~n ~p", [UserId, TargetName, VarsAndVals]), + case (catch handle_sync_set(Pid, + UserId, TargetName, VarsAndVals, SendOpts, + From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({sync_set, Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_set [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received sync_set request for: " + "~n ~p", [UserId, TargetName, CtxName, VarsAndVals]), case (catch handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo, From, State)) of @@ -624,45 +820,105 @@ handle_call({sync_set, Pid, UserId, TargetName, Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> +handle_call({async_get, Pid, UserId, TargetName, Oids, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_get request for: " + "~n ~p", [UserId, TargetName, Oids]), + Reply = (catch handle_async_get(Pid, + UserId, TargetName, Oids, SendOpts, + State)), + {reply, Reply, State}; + + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_get, Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_get [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_get request for: " + "~n ~p", [UserId, TargetName, CtxName, Oids]), Reply = (catch handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> + + +handle_call({async_get_next, Pid, UserId, TargetName, Oids, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_get_next request for: " + "~n ~p", [UserId, TargetName, Oids]), + Reply = (catch handle_async_get_next(Pid, + UserId, TargetName, Oids, SendOpts, + State)), + {reply, Reply, State}; +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_get_next, Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_get_next [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_get_next request for: ", + [UserId, TargetName, CtxName, Oids]), Reply = (catch handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> %% Check agent version? This op not in v1 +handle_call({async_get_bulk, + Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_get_bulk request for: " + "~n ~p", [UserId, TargetName, Oids]), + Reply = (catch handle_async_get_bulk(Pid, + UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts, + State)), + {reply, Reply, State}; + + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_get_bulk, Pid, UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_get_bulk [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_get_bulk request for: " + "~n ~p", [UserId, TargetName, CtxName, Oids]), Reply = (catch handle_async_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> + + +handle_call({async_set, + Pid, UserId, TargetName, VarsAndVals, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_set request for: " + "~n ~p", [UserId, TargetName, VarsAndVals]), + Reply = (catch handle_async_set(Pid, + UserId, TargetName, VarsAndVals, SendOpts, + State)), + {reply, Reply, State}; +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_set, Pid, UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_set [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_set request for: " + "~n ~p", [UserId, TargetName, CtxName, VarsAndVals]), Reply = (catch handle_async_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> handle_call({cancel_async_request, UserId, ReqId}, _From, State) -> @@ -901,36 +1157,46 @@ terminate(Reason, #state{gct = GCT}) -> handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State). + +handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> ?vtrace("handle_sync_get -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, Oids, SendOpts, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get -> send a ~p message", [Vsn]), - ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port, - ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_get_request(Oids, Vsn, MsgData, + Addr, Port, Extra, State), ?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_GET_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_get -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = get, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = get, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; Error -> @@ -940,39 +1206,49 @@ handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, Error end. - handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, From, State). + +handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, + From, State) -> ?vtrace("handle_sync_get_next -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, Oids, SendOpts, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]), - ReqId = send_get_next_request(Oids, Vsn, MsgData, - Addr, Port, ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_get_next_request(Oids, Vsn, MsgData, + Addr, Port, Extra, State), ?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_GET_NEXT_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_get_next -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = get_next, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = get_next, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -987,39 +1263,50 @@ handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout, handle_sync_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, + SendOpts, From, State). + +handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, + From, State) -> ?vtrace("handle_sync_get_bulk -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n NonRep: ~p" "~n MaxRep: ~p" "~n Oids: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, - Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]), - ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, - NonRep, MaxRep, ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, + NonRep, MaxRep, Extra, State), ?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_GET_BULK_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_get_bulk -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = get_bulk, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = get_bulk, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -1033,36 +1320,47 @@ handle_sync_get_bulk(Pid, UserId, TargetName, CtxName, handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, + From, State). + +handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> ?vtrace("handle_sync_set -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n VarsAndVals: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, VarsAndVals, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_set -> send a ~p message", [Vsn]), - ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Addr, Port, ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_set_request(VarsAndVals, Vsn, MsgData, + Addr, Port, Extra, State), ?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_SET_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_set -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = set, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = set, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -1076,20 +1374,30 @@ handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State). + +handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> ?vtrace("handle_async_get -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, Oids, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_get -> send a ~p message", [Vsn]), + Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port, - ExtraInfo, State), + Extra, State), ?vdebug("handle_async_get -> ReqId: ~p", [ReqId]), + Expire = ?ASYNC_GET_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, @@ -1114,20 +1422,30 @@ handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State). + +handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> ?vtrace("handle_async_get_next -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, Oids, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_get_next -> send a ~p message", [Vsn]), + Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Addr, Port, ExtraInfo, State), + Addr, Port, Extra, State), ?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]), + Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, @@ -1153,22 +1471,36 @@ handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire, handle_async_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_get_bulk(Pid, + UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, + State). + +handle_async_get_bulk(Pid, + UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, + State) -> ?vtrace("handle_async_get_bulk -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n NonRep: ~p" "~n MaxRep: ~p" "~n Oids: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]), + Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, - NonRep, MaxRep, ExtraInfo, State), + NonRep, MaxRep, Extra, State), ?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]), + Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, @@ -1192,20 +1524,30 @@ handle_async_get_bulk(Pid, UserId, TargetName, CtxName, handle_async_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State). + +handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> ?vtrace("handle_async_set -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n VarsAndVals: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, VarsAndVals, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, VarsAndVals, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_set -> send a ~p message", [Vsn]), + Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Addr, Port, ExtraInfo, State), + Addr, Port, Extra, State), ?vdebug("handle_async_set -> ReqId: ~p", [ReqId]), + Expire = ?ASYNC_SET_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, @@ -2798,10 +3140,7 @@ request_id() -> %%---------------------------------------------------------------------- -agent_data(TargetName, CtxName) -> - agent_data(TargetName, CtxName, []). - -agent_data(TargetName, CtxName, Config) -> +agent_data(TargetName, SendOpts) -> case snmpm_config:agent_info(TargetName, all) of {ok, Info} -> Version = agent_data_item(version, Info), @@ -2813,15 +3152,18 @@ agent_data(TargetName, CtxName, Config) -> DefSecLevel = agent_data_item(sec_level, Info), EngineId = agent_data_item(engine_id, Info), + CtxName = agent_data_item(context, + SendOpts, + ?DEFAULT_CONTEXT), SecModel = agent_data_item(sec_model, - Config, + SendOpts, DefSecModel), SecName = agent_data_item(sec_name, - Config, + SendOpts, DefSecName), SecLevel = agent_data_item(sec_level, - Config, + SendOpts, DefSecLevel), {SecModel, SecName, mk_sec_level_flag(SecLevel), @@ -2831,10 +3173,10 @@ agent_data(TargetName, CtxName, Config) -> DefSecModel = agent_data_item(sec_model, Info), Comm = agent_data_item(community, - Config, + SendOpts, DefComm), SecModel = agent_data_item(sec_model, - Config, + SendOpts, DefSecModel), {Comm, SecModel} @@ -3003,6 +3345,12 @@ default_agent_config() -> %%---------------------------------------------------------------------- +get_opt(Key, Default, Opts) -> + proplists:get_value(Key, Opts, Default). + + +%%---------------------------------------------------------------------- + is_started(#state{net_if = _Pid, net_if_mod = _Mod}) -> %% Mod:is_started(Pid) and snmpm_config:is_started(). case snmpm_config:is_started() of diff --git a/lib/snmp/src/manager/snmpm_usm.erl b/lib/snmp/src/manager/snmpm_usm.erl index 449127844a..ef2070a90e 100644 --- a/lib/snmp/src/manager/snmpm_usm.erl +++ b/lib/snmp/src/manager/snmpm_usm.erl @@ -476,14 +476,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, diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 4d2f5d8f92..cb5b3bbfbd 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -37,7 +37,13 @@ check_timer/1, - check_ip/1, check_taddress/1, + check_domain/1, + check_tdomain/1, + mk_tdomain/1, + which_domain/1, + check_ip/1, check_ip/2, + check_taddress/1, check_taddress/2, + mk_taddress/3, check_packet_size/1, @@ -52,8 +58,10 @@ -define(SNMP_USE_V3, true). --include("snmp_types.hrl"). --include("SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). +-include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl"). +-include_lib("snmp/include/SNMPv2-TM.hrl"). -define(VMODULE,"CONF"). -include("snmp_verbosity.hrl"). @@ -338,15 +346,96 @@ check_sec_level(BadSecLevel) -> %% --------- -check_taddress(X) when is_list(X) andalso (length(X) =:= 6) -> +check_tdomain(TDomain) -> + SupportedTDomains = + [ + ?snmpUDPDomain, + ?transportDomainUdpIpv4, + ?transportDomainUdpIpv6 + ], + AllTDomains = + [ + ?transportDomainUdpIpv4, + ?transportDomainUdpIpv6, + ?transportDomainUdpIpv4z, + ?transportDomainUdpIpv6z, + ?transportDomainTcpIpv4, + ?transportDomainTcpIpv6, + ?transportDomainTcpIpv4z, + ?transportDomainTcpIpv6z, + ?transportDomainSctpIpv4, + ?transportDomainSctpIpv6, + ?transportDomainSctpIpv4z, + ?transportDomainSctpIpv6z, + ?transportDomainLocal, + ?transportDomainUdpDns, + ?transportDomainTcpDns, + ?transportDomainSctpDns + ], + case lists:member(TDomain, SupportedTDomains) of + true -> + ok; + false -> + case lists:member(TDomain, AllTDomains) of + true -> + error({unsupported_tdomain, TDomain}); + false -> + error({unknown_tdomain, TDomain}) + end + end. + + +%% --------- + +mk_tdomain(snmpUDPDomain) -> + ?snmpUDPDomain; +mk_tdomain(transportDomainUdpIpv4) -> + ?transportDomainUdpIpv4; +mk_tdomain(transportDomainUdpIpv6) -> + ?transportDomainUdpIpv6; +mk_tdomain(BadDomain) -> + error({bad_domain, BadDomain}). + + +%% --------- + +check_taddress(X) -> + check_taddress(snmpUDPDomain, X). + +check_taddress(?snmpUDPDomain, X) -> + check_taddress(transportDomainUdpIpv4, X); +check_taddress(snmpUDPDomain, X) -> + check_taddress(transportDomainUdpIpv4, X); + +check_taddress(?transportDomainUdpIpv4, X) -> + check_taddress(transportDomainUdpIpv4, X); +check_taddress(transportDomainUdpIpv4, X) + when is_list(X) andalso (length(X) =:= 6) -> case (catch all_integer(X)) of true -> ok; false -> error({invalid_taddress, X}) end; -check_taddress(X) -> - error({invalid_taddress, X}). +check_taddress(transportDomainUdpIpv4, X) -> + error({invalid_taddress, X}); + +check_taddress(?transportDomainUdpIpv6, X) -> + check_taddress(transportDomainUdpIpv6, X); +check_taddress(transportDomainUdpIpv6, X) + when is_list(X) andalso (length(X) =:= 10) -> + case (catch all_integer(X)) of + true -> + ok; + false -> + error({invalid_taddress, X}) + end; +check_taddress(transportDomainUdpIpv6, X) -> + error({invalid_taddress, X}); + +check_taddress(BadDomain, _X) -> + error({invalid_tdomain, BadDomain}). + %% --------- @@ -385,15 +474,115 @@ do_check_timer(WaitFor, Factor, Incr, Retry) -> %% --------- -check_ip(X) when is_list(X) andalso (length(X) =:= 4) -> +check_domain(Domain) -> + SupportedDomains = + [ + snmpUDPDomain, + transportDomainUdpIpv4, + transportDomainUdpIpv6 + ], + AllDomains = + [ + transportDomainUdpIpv4, + transportDomainUdpIpv6, + transportDomainUdpIpv4z, + transportDomainUdpIpv6z, + transportDomainTcpIpv4, + transportDomainTcpIpv6, + transportDomainTcpIpv4z, + transportDomainTcpIpv6z, + transportDomainSctpIpv4, + transportDomainSctpIpv6, + transportDomainSctpIpv4z, + transportDomainSctpIpv6z, + transportDomainLocal, + transportDomainUdpDns, + transportDomainTcpDns, + transportDomainSctpDns + ], + case lists:member(Domain, SupportedDomains) of + true -> + ok; + false -> + case lists:member(Domain, AllDomains) of + true -> + error({unsupported_domain, Domain}); + false -> + error({unknown_domain, Domain}) + end + end. + + +%% --------- + +%% The values of Ip and Port has both been checked at this +%% point, so we dont need to do that again. +mk_taddress(snmpUDPDomain, Ip, Port) -> + mk_taddress(transportDomainUdpIpv4, Ip, Port); +mk_taddress(transportDomainUdpIpv4, Ip, Port) when is_list(Ip) -> + Ip ++ [Port div 256, Port rem 256]; +mk_taddress(transportDomainUdpIpv4 = Domain, Ip, Port) when is_tuple(Ip) -> + mk_taddress(Domain, tuple_to_list(Ip), Port); +mk_taddress(transportDomainUdpIpv6, Ip, Port) when is_list(Ip) -> + Ip ++ [Port div 256, Port rem 256]; +mk_taddress(transportDomainUdpIpv6 = Domain, Ip, Port) when is_tuple(Ip) -> + mk_taddress(Domain, tuple_to_list(Ip), Port); + +%% These are just for convenience +mk_taddress(?snmpUDPDomain, Ip, Port) -> + mk_taddress(snmpUDPDomain, Ip, Port); +mk_taddress(?transportDomainUdpIpv4, Ip, Port) -> + mk_taddress(transportDomainUdpIpv4, Ip, Port); +mk_taddress(?transportDomainUdpIpv6, Ip, Port) -> + mk_taddress(transportDomainUdpIpv6, Ip, Port); + +%% Bad domain +mk_taddress(BadDomain, _Ip, _Port) -> + error({bad_domain, BadDomain}). + + +%% --------- + +which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 4) -> + transportDomainUdpIpv4; +which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 4) -> + transportDomainUdpIpv4; +which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 8) -> + transportDomainUdpIpv6; +which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 8) -> + transportDomainUdpIpv6. + + +%% --------- + +check_ip(X) -> + check_ip(snmpUDPDomain, X). + +check_ip(snmpUDPDomain, X) -> + check_ip(transportDomainUdpIpv4, X); +check_ip(transportDomainUdpIpv4, X) when is_list(X) andalso (length(X) =:= 4) -> case (catch all_integer(X)) of true -> ok; false -> error({invalid_ip_address, X}) end; -check_ip(X) -> - error({invalid_ip_address, X}). +check_ip(transportDomainUdpIpv4, X) -> + error({invalid_ip_address, X}); + +check_ip(transportDomainUdpIpv6, X) when is_list(X) andalso (length(X) =:= 8) -> + case (catch all_integer(X)) of + true -> + ok; + false -> + error({invalid_ip_address, X}) + end; +check_ip(transportDomainUdpIpv6, X) -> + error({invalid_ip_address, X}); + +check_ip(BadDomain, _X) -> + error({invalid_domain, BadDomain}). + %% --------- diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 25350e08cb..813942225e 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -491,6 +491,9 @@ config_agent_snmp(Dir, Vsns) -> Host = host(), AgentIP = ask("5. IP address for the agent (only used as id ~n" " when sending traps)", Host, fun verify_address/1), + %% We intentionally skip TDomain... + %% If the user wish to use IPv6, the user must create an dummy entry here + %% and then manually edit these entries later. ManagerIP = ask("6. IP address for the manager (only this manager ~n" " will have access to the agent, traps are sent ~n" " to this one)", Host, fun verify_address/1), @@ -1062,9 +1065,19 @@ verify_sec_type(ST) -> {error, "invalid security type: " ++ ST}. verify_address(A) -> - case (catch snmp_misc:ip(A)) of + verify_address(A, snmpUDPDomain). + +verify_address(A, snmpUDPDomain = _Domain) -> + do_verify_address(A, inet); +verify_address(A, transportDomainUdpIpv4 = _Domain) -> + do_verify_address(A, inet); +verify_address(A, transportDomainUdpIpv6 = _Domain) -> + do_verify_address(A, inet6). + +do_verify_address(A, Family) -> + case (catch snmp_misc:ip(A, Family)) of {ok, IP} -> - {ok, tuple_to_list(IP)}; + {ok, tuple_to_list(IP)}; {error, _} -> {error, "invalid address: " ++ A}; _E -> @@ -1721,10 +1734,12 @@ write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Hdr = header() ++ Comment, F = fun(v1 = Vsn, Acc) -> [{mk_ip(ManagerIp, Vsn), + snmp_target_mib:default_domain(), ManagerIp, UDP, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}| Acc]; (v2 = Vsn, Acc) -> [{mk_ip(ManagerIp, Vsn), + snmp_target_mib:default_domain(), ManagerIp, UDP, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, {lists:flatten(io_lib:format("~s.2",[mk_ip(ManagerIp, Vsn)])), @@ -1732,6 +1747,7 @@ write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, "std_inform", mk_param(Vsn), "", [], 2048}| Acc]; (v3 = Vsn, Acc) -> [{mk_ip(ManagerIp, Vsn), + snmp_target_mib:default_domain(), ManagerIp, UDP, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, {lists:flatten(io_lib:format("~s.3",[mk_ip(ManagerIp, Vsn)])), diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index f9aa911817..7930e37c66 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -266,9 +266,6 @@ validate_loop(eof, _Log, _Validatior, _PrevTS, _PrevSN) -> ok; validate_loop({error, _} = Error, _Log, _Validator, _PrevTS, _PrevSN) -> Error; -validate_loop({corrupt_log_file, _} = Reason, - _Log, _Validator, _PrevTS, _PrevSN) -> - {error, Reason}; validate_loop({Cont, Terms}, Log, Validator, PrevTS, PrevSN) -> ?vtrace("validate_loop -> entry with" "~n Terms: ~p" @@ -508,8 +505,6 @@ loop(eof, _Log, _Write) -> ok; loop({error, _} = Error, _Log, _Write) -> Error; -loop({corrupt_log_file, _} = Reason, _Log, _Write) -> - {error, Reason}; loop({Cont, Terms}, Log, Write) -> case (catch lists:foreach(Write, Terms)) of {'EXIT', Reason} -> diff --git a/lib/snmp/src/misc/snmp_misc.erl b/lib/snmp/src/misc/snmp_misc.erl index 1b535743a4..6adef06ab9 100644 --- a/lib/snmp/src/misc/snmp_misc.erl +++ b/lib/snmp/src/misc/snmp_misc.erl @@ -40,7 +40,7 @@ get_option/2, get_option/3, get_sec_level/1, - ip/1, + ip/1, ip/2, is_auth/1, is_BitString/1, is_oid/1, @@ -347,10 +347,15 @@ bits_to_int([Kibble|Ks],Kibbles,Res) -> %%---------------------------------------------------------------------- -%% Returns: {ok, {int(),int(),int(),int()}} | {error, Reason} +%% Returns: {ok, {int(),int(),int(),int()}} | +%% {ok, {int(),int(),int(),int()},int(),int(),int(),int()} | +%% {error, Reason} %%---------------------------------------------------------------------- ip(Host) -> - inet:getaddr(Host, inet). + ip(Host, inet). + +ip(Host, Family) -> + inet:getaddr(Host, Family). ensure_trailing_dir_delimiter([]) -> "/"; ensure_trailing_dir_delimiter(DirSuggestion) -> diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl index dc8900c8cd..82618a0b86 100644 --- a/lib/snmp/src/misc/snmp_pdus.erl +++ b/lib/snmp/src/misc/snmp_pdus.erl @@ -269,24 +269,35 @@ dec_value([64 | Bytes]) -> {Value, Rest} = dec_oct_str_notag(Bytes), {{'IpAddress', Value}, Rest}; dec_value([65 | Bytes]) -> + %% Counter32 is an unsigned 32 but is actually encoded as + %% a signed integer 32 (INTEGER). {Value, Rest} = dec_integer_notag(Bytes), - if Value >= 0, Value =< 4294967295 -> - {{'Counter32', Value}, Rest}; - true -> - exit({error, {bad_counter32, Value}}) - end; + Value2 = + if + (Value >= 0) andalso (Value =< 16#ffffffff) -> + %% We accept value above 16#7fffffff + %% in order to be backward bug-compatible + Value; + (Value < 0) -> + 16#ffffffff + Value + 1; + true -> + exit({error, {bad_counter32, Value}}) + end, + {{'Counter32', Value2}, Rest}; dec_value([66 | Bytes]) -> {Value, Rest} = dec_integer_notag(Bytes), - if Value >= 0, Value =< 4294967295 -> + if + (Value >= 0) andalso (Value =< 4294967295) -> {{'Unsigned32', Value}, Rest}; - true -> + true -> exit({error, {bad_unsigned32, Value}}) end; dec_value([67 | Bytes]) -> {Value, Rest} = dec_integer_notag(Bytes), - if Value >= 0, Value =< 4294967295 -> + if + (Value >= 0) andalso (Value =< 4294967295) -> {{'TimeTicks', Value}, Rest}; - true -> + true -> exit({error, {bad_timeticks, Value}}) end; dec_value([68 | Bytes]) -> @@ -642,6 +653,21 @@ enc_value(_Type, endOfMibView) -> [130,0]; enc_value('NULL', _Val) -> [5,0]; +enc_value('Counter32', Val) -> + Val2 = + if + Val > 16#ffffffff -> + exit({error, {bad_counter32, Val}}); + Val >= 16#80000000 -> + (Val band 16#7fffffff) - 16#80000000; + Val >= 0 -> + Val; + true -> + exit({error, {bad_counter32, Val}}) + end, + Bytes2 = enc_integer_notag(Val2), + Len2 = elength(length(Bytes2)), + lists:append([65 | Len2],Bytes2); enc_value('Counter64', Val) -> Val2 = if |