diff options
Diffstat (limited to 'lib/snmp/src/agent')
-rw-r--r-- | lib/snmp/src/agent/snmp_notification_mib.erl | 7 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmp_target_mib.erl | 168 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_acm.erl | 26 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_agent.erl | 21 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_authentication_service.erl | 9 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_conf.erl | 63 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_mpd.erl | 44 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_net_if.erl | 48 | ||||
-rw-r--r-- | lib/snmp/src/agent/snmpa_trap.erl | 40 |
9 files changed, 297 insertions, 129 deletions
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_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..d9a0438b56 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -754,8 +754,8 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) -> "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, - case catch handle_send_trap(S, Trap, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID) of + case (catch handle_send_trap(S, Trap, NotifyName, ContextName, + Recv, Varbinds, LocalEngineID)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -775,8 +775,8 @@ 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 + case (catch handle_send_trap(S, Trap, NotifyName, ContextName, + Recv, Varbinds, LocalEngineID)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -923,9 +923,9 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, ?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, @@ -1470,7 +1470,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}. @@ -1717,7 +1720,7 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) -> handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds, LocalEngineID) -> ?vtrace("handle_send_trap -> entry with" - "~n S#state.type: ~p" + "~n Agent type: ~p" "~n TrapName: ~p" "~n NotifyName: ~p" "~n ContextName: ~p" 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_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..d4bb5bdf9f 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -504,7 +504,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 +512,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 +637,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 +776,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..09ecb5228b 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -33,13 +33,14 @@ 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"). +-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). @@ -440,11 +441,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 @@ -1001,9 +1004,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 +1074,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 %%----------------------------------------------------------------- |