diff options
Diffstat (limited to 'lib/snmp/src')
-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 | ||||
-rw-r--r-- | lib/snmp/src/app/snmp.appup.src | 76 | ||||
-rw-r--r-- | lib/snmp/src/misc/snmp_conf.erl | 207 | ||||
-rw-r--r-- | lib/snmp/src/misc/snmp_config.erl | 20 | ||||
-rw-r--r-- | lib/snmp/src/misc/snmp_misc.erl | 9 |
13 files changed, 592 insertions, 146 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 %%----------------------------------------------------------------- diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 4e86e12465..fd9f40caa0 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -24,14 +24,41 @@ [ {"4.19", [ - {load_module, snmpm, soft_purge, soft_purge, []} + {load_module, snmpm, 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]}, + {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_target_mib, soft_purge, soft_purge, + [snmp_conf]}, + {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, snmpm, soft_purge, soft_purge, []}, {load_module, snmp_misc, 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]}, + {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, @@ -39,6 +66,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, @@ -51,7 +80,12 @@ [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, 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]} ] } ], @@ -61,14 +95,41 @@ [ {"4.19", [ - {load_module, snmpm, soft_purge, soft_purge, []} + {load_module, snmpm, 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]}, + {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_target_mib, soft_purge, soft_purge, + [snmp_conf]}, + {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, snmpm, soft_purge, soft_purge, []}, {load_module, snmp_misc, 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]}, + {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, @@ -76,6 +137,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, @@ -88,7 +151,12 @@ [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, 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/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_misc.erl b/lib/snmp/src/misc/snmp_misc.erl index 1b535743a4..2dce76992b 100644 --- a/lib/snmp/src/misc/snmp_misc.erl +++ b/lib/snmp/src/misc/snmp_misc.erl @@ -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) -> |