From 768a6d38597b8bedf6551ad2e6472b2965765dd2 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 9 Apr 2014 10:29:00 +0200 Subject: Rewrite agent configuration parsing --- lib/snmp/src/agent/snmp_community_mib.erl | 71 +++-- lib/snmp/src/agent/snmp_framework_mib.erl | 55 ++-- lib/snmp/src/agent/snmp_notification_mib.erl | 24 +- lib/snmp/src/agent/snmp_standard_mib.erl | 23 +- lib/snmp/src/agent/snmp_target_mib.erl | 172 +++++++---- lib/snmp/src/agent/snmp_user_based_sm_mib.erl | 14 +- lib/snmp/src/agent/snmp_view_based_acm_mib.erl | 23 +- lib/snmp/src/agent/snmpa_conf.erl | 96 ++++-- lib/snmp/src/agent/snmpa_mpd.erl | 39 ++- lib/snmp/src/manager/snmpm_config.erl | 10 +- lib/snmp/src/misc/snmp_conf.erl | 406 +++++++++++++++++++------ lib/snmp/src/misc/snmp_config.erl | 143 ++++++--- lib/snmp/test/snmp_agent_test_lib.erl | 26 +- 13 files changed, 793 insertions(+), 309 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index 7bdd500727..12a0ec97c2 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -31,6 +31,7 @@ -include("snmpa_internal.hrl"). -include("SNMP-COMMUNITY-MIB.hrl"). -include("SNMP-TARGET-MIB.hrl"). +-include("SNMPv2-TM.hrl"). -include("SNMPv2-TC.hrl"). -include("snmp_types.hrl"). @@ -129,10 +130,11 @@ read_community_config_files(Dir) -> [FileName, D, Reason]), ok end, - Filter = fun(Comms) -> Comms end, - Check = fun(Entry) -> check_community(Entry) end, + Order = fun snmp_conf:no_order/2, + Filter = fun snmp_conf:no_filter/1, + Check = fun(Entry, State) -> {check_community(Entry), State} end, [Comms] = - snmp_conf:read_files(Dir, [{Gen, Filter, Check, "community.conf"}]), + snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]), Comms. check_community({Index, CommunityName, SecName, CtxName, TransportTag}) -> @@ -192,7 +194,7 @@ add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) -> do_add_community(Community). do_add_community(Community) -> - case (catch check_community(Community)) of + try check_community(Community) of {ok, Row} -> Key = element(1, Row), case table_cre_row(snmpCommunityTable, Key, Row) of @@ -201,11 +203,12 @@ do_add_community(Community) -> {ok, Key}; false -> {error, create_failed} - end; + end + catch {error, Reason} -> {error, Reason}; - Error -> - {error, Error} + Class:Reason -> + {error, {Class, Reason, erlang:get_stacktrace()}} end. %% FIXME: does not work with mnesia @@ -506,7 +509,12 @@ snmpTargetAddrExtTable(get_next, RowIndex, Cols) -> NCols = conv1(Cols), conv2(next(snmpTargetAddrExtTable, RowIndex, NCols)); snmpTargetAddrExtTable(set, RowIndex, Cols0) -> - case (catch verify_snmpTargetAddrExtTable_cols(Cols0, [])) of + case + (catch verify_snmpTargetAddrExtTable_cols( + Cols0, + get_snmpTargetAddrTDomain(RowIndex, Cols0), + [])) + of {ok, Cols} -> NCols = conv3(Cols), snmp_generic:table_func(set, RowIndex, NCols, @@ -515,7 +523,11 @@ snmpTargetAddrExtTable(set, RowIndex, Cols0) -> Error end; snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) -> - case (catch verify_snmpTargetAddrExtTable_cols(Cols0, [])) of + case (catch verify_snmpTargetAddrExtTable_cols( + Cols0, + get_snmpTargetAddrTDomain(RowIndex, Cols0), + [])) + of {ok, Cols} -> NCols = conv3(Cols), snmp_generic:table_func(is_set_ok, RowIndex, NCols, @@ -525,29 +537,49 @@ snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) -> end. -verify_snmpTargetAddrExtTable_cols([], Cols) -> + +get_snmpTargetAddrTDomain(RowIndex, Col) -> + case + get( + snmpTargetAddrTable, RowIndex, + [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain]) + of + [{value,?snmpTargetAddrRowStatus_active},ValueTDomain] -> + case ValueTDomain of + {value,TDomain} -> + TDomain; + _ -> + ?snmpUDPDomain + end; + _ -> + wrongValue(Col) + end. + + + +verify_snmpTargetAddrExtTable_cols([], _TDomain, Cols) -> {ok, lists:reverse(Cols)}; -verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], Acc) -> - Val = verify_snmpTargetAddrExtTable_col(Col, Val0), - verify_snmpTargetAddrExtTable_cols(Cols, [{Col, Val}|Acc]). +verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], TDomain, Acc) -> + Val = verify_snmpTargetAddrExtTable_col(Col, TDomain, Val0), + verify_snmpTargetAddrExtTable_cols(Cols, TDomain, [{Col, Val}|Acc]). -verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, []) -> +verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, _TDomain, []) -> []; -verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, TMask) -> - case (catch snmp_conf:check_taddress(TMask)) of +verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, TDomain, TMask) -> + case (catch snmp_conf:check_taddress(TDomain, TMask)) of ok -> TMask; _ -> wrongValue(?snmpTargetAddrTMask) end; -verify_snmpTargetAddrExtTable_col(?snmpTargetAddrMMS, MMS) -> +verify_snmpTargetAddrExtTable_col(?snmpTargetAddrMMS, _TDomain, MMS) -> case (catch snmp_conf:check_packet_size(MMS)) of ok -> MMS; _ -> wrongValue(?snmpTargetAddrMMS) end; -verify_snmpTargetAddrExtTable_col(_, Val) -> +verify_snmpTargetAddrExtTable_col(_, _TDomain, Val) -> Val. db(snmpTargetAddrExtTable) -> db(snmpTargetAddrTable); @@ -583,6 +615,7 @@ conv3([{Idx, Val}|T]) -> [{Idx+10, Val} | conv3(T)]; conv3([]) -> []. + get(Name, RowIndex, Cols) -> snmp_generic:handle_table_get(db(Name), RowIndex, Cols, foi(Name)). diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index cc191bd956..84f39df228 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2012. All Rights Reserved. +%% Copyright Ericsson AB 1999-2014. 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 @@ -51,7 +51,7 @@ set_engine_boots/1, set_engine_time/1, table_next/2, check_status/3]). -export([add_context/1, delete_context/1]). --export([check_agent/1, check_context/1]). +-export([check_agent/1, check_agent/2, check_context/1, order_agent/2]). %%----------------------------------------------------------------- @@ -115,23 +115,22 @@ do_configure(Dir) -> read_internal_config_files(Dir) -> ?vdebug("read context config file",[]), - Gen = fun(D, Reason) -> - convert_context(D, Reason) - end, - Filter = fun(Contexts) -> Contexts end, - Check = fun(Entry) -> check_context(Entry) end, - [Ctxs] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "context.conf"}]), + Gen = fun gen_context/2, + Order = fun snmp_conf:no_order/2, + Filter = fun snmp_conf:no_filter/1, + Check = fun(Entry, State) -> {check_context(Entry), State} end, + [Ctxs] = + snmp_conf:read_files + (Dir, [{"context.conf", Gen, Order, Check, Filter}]), Ctxs. - read_agent(Dir) -> ?vdebug("read agent config file", []), - FileName = "agent.conf", - Check = fun(Entry) -> check_agent(Entry) end, + FileName = "agent.conf", File = filename:join(Dir, FileName), - Agent = + Agent = try - snmp_conf:read(File, Check) + snmp_conf:read(File, fun order_agent/2, fun check_agent/2) catch throw:{error, Reason} -> error({failed_reading_config_file, Dir, FileName, Reason}) @@ -155,14 +154,15 @@ sort_agent(L) -> %%----------------------------------------------------------------- %% Generate a context.conf file. %%----------------------------------------------------------------- -convert_context(Dir, _Reason) -> +gen_context(Dir, _Reason) -> config_err("missing context.conf file => generating a default file", []), File = filename:join(Dir, "context.conf"), case file:open(File, [write]) of {ok, Fid} -> ok = io:format(Fid, "~s\n", [context_header()]), ok = io:format(Fid, "%% The default context\n\"\".\n", []), - file:close(Fid); + file:close(Fid), + []; {error, Reason} -> file:delete(File), error({failed_creating_file, File, Reason}) @@ -196,9 +196,21 @@ check_context(Context) -> %% Agent %% {Name, Value}. %%----------------------------------------------------------------- -check_agent({intAgentIpAddress, Value}) -> +check_agent({intAgentTransportDomain, D}, Domain) -> + case Domain of + undefined -> + {snmp_conf:check_domain(D), D}; + _ -> + error({invalid_agent_attribute, D}) + end; +check_agent({intAgentTransportAddress, Address}, Domain) -> + {snmp_conf:check_address(Domain, Address), Domain}; +check_agent(Entry, Domain) -> + {check_agent(Entry), Domain}. + +check_agent({intAgentIpAddress, Value}) -> % Obsoleted snmp_conf:check_ip(Value); -check_agent({intAgentUDPPort, Value}) -> +check_agent({intAgentUDPPort, Value}) -> % Obsoleted snmp_conf:check_integer(Value); %% This one is kept for backwards compatibility check_agent({intAgentMaxPacketSize, Value}) -> @@ -210,6 +222,15 @@ check_agent({snmpEngineID, Value}) -> check_agent(X) -> error({invalid_agent_attribute, X}). +%% Ordering function to sort intAgentTransportDomain first +%% hence before intAgentTransportAddress +order_agent({intAgentTransportDomain, _}, {intAgentTransportDomain, _}) -> + true; %% Less than or equal +order_agent(_, {intAgentTransportDomain, _}) -> + false; %% Greater than +order_agent(_, _) -> + true. %% Less than or equal + maybe_create_table(Name) -> case snmpa_local_db:table_exists(db(Name)) of diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl index 37e09f5d3e..31c7735226 100644 --- a/lib/snmp/src/agent/snmp_notification_mib.erl +++ b/lib/snmp/src/agent/snmp_notification_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2012. All Rights Reserved. +%% Copyright Ericsson AB 1998-2014. 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 @@ -106,17 +106,19 @@ do_reconfigure(Dir) -> read_notify_config_files(Dir) -> ?vdebug("read notify config file",[]), FileName = "notify.conf", - Gen = fun(D, Reason) -> - info_msg("failed reading config file ~s" - "~n Config Dir: ~s" - "~n Reason: ~p", - [FileName, D, Reason]), - ok - end, - Filter = fun(Notifs) -> Notifs end, - Check = fun(Entry) -> check_notify(Entry) end, + Gen = + fun (D, Reason) -> + info_msg("failed reading config file ~s" + "~n Config Dir: ~s" + "~n Reason: ~p", + [FileName, D, Reason]), + ok + end, + Order = fun snmp_conf:no_order/2, + Filter = fun snmp_conf:no_filter/1, + Check = fun (Entry, State) -> {check_notify(Entry), State} end, [Notifs] = - snmp_conf:read_files(Dir, [{Gen, Filter, Check, "notify.conf"}]), + snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]), Notifs. check_notify({Name, Tag, Type}) -> diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl index 766b75022b..aace3fd413 100644 --- a/lib/snmp/src/agent/snmp_standard_mib.erl +++ b/lib/snmp/src/agent/snmp_standard_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -152,16 +152,19 @@ do_reconfigure(Dir) -> %%----------------------------------------------------------------- read_standard(Dir) -> ?vdebug("check standard config file",[]), - FileName = "standard.conf", - Gen = fun(D, Reason) -> - throw({error, {failed_reading_config_file, - D, FileName, - list_dir(Dir), Reason}}) - end, - Filter = fun(Standard) -> sort_standard(Standard) end, - Check = fun(Entry) -> check_standard(Entry) end, + FileName = "standard.conf", + Gen = + fun (D, Reason) -> + throw( + {error, + {failed_reading_config_file, + D, FileName, list_dir(Dir), Reason}}) + end, + Order = fun snmp_conf:no_order/2, + Check = fun (Entry, State) -> {check_standard(Entry), State} end, + Filter = fun sort_standard/1, [Standard] = - snmp_conf:read_files(Dir, [{Gen, Filter, Check, FileName}]), + snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]), Standard. list_dir(Dir) -> diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index b01d536caa..6dd3b6e23a 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1998-2012. All Rights Reserved. +%% Copyright Ericsson AB 1998-2014. 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 @@ -133,18 +133,22 @@ do_reconfigure(Dir) -> read_target_config_files(Dir) -> ?vdebug("check target address and parameter config file(s)",[]), - TAGen = fun(_D, _Reason) -> ok end, - TAFilter = fun(Addr) -> Addr end, - TACheck = fun(Entry) -> check_target_addr(Entry) end, - TPGen = fun(_D, _Reason) -> ok end, - TPFilter = fun(Params) -> Params end, - TPCheck = fun(Entry) -> check_target_params(Entry) end, + TAName = "target_addr.conf", + TACheck = fun (Entry, State) -> {check_target_addr(Entry), State} end, + + TPName = "target_params.conf", + TPCheck = fun (Entry, State) -> {check_target_params(Entry), State} end, + + NoGen = fun snmp_conf:no_gen/2, + NoOrder = fun snmp_conf:no_order/2, + NoFilter = fun snmp_conf:no_filter/1, [Addrs, Params] = - snmp_conf:read_files(Dir, - [{TAGen, TAFilter, TACheck, "target_addr.conf"}, - {TPGen, TPFilter, TPCheck, "target_params.conf"}]), + snmp_conf:read_files( + Dir, + [{TAName, NoGen, NoOrder, TACheck, NoFilter}, + {TPName, NoGen, NoOrder, TPCheck, NoFilter}]), {Addrs, Params}. @@ -154,80 +158,142 @@ read_target_config_files(Dir) -> %% TMask, MMS} %%----------------------------------------------------------------- -check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, - Params, EngineId, TMask, MMS}) -> +check_target_addr( + {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, Params, + EngineId, TMask, MMS}) -> % Arity 11 + Address = {Ip, Udp}, + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId, TMask, MMS); +check_target_addr( + {Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId, TMask, MMS}) % Arity 10 + when is_atom(Domain) -> + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId, TMask, MMS); +check_target_addr( + {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, + EngineId, TMask, MMS}) -> % Arity 10 + Domain = default_domain(), + Address = {Ip, Udp}, + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId, TMask, MMS); +check_target_addr( + {Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId}) % Arity 8 + when is_atom(Domain) -> + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId); +check_target_addr( + {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, + EngineId}) -> % Arity 8 + Domain = default_domain(), + Address = {Ip, Udp}, + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId); +%% Use dummy engine id if the old style is found +check_target_addr( + {Name, Domain, Address, Timeout, RetryCount, TagList, Params}) % Arity 7 + when is_atom(Domain) -> + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params); +check_target_addr( + {Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) -> % Arity 7 + Domain = default_domain(), + Address = {Ip, Udp}, + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params); +%% Use dummy engine id if the old style is found +check_target_addr( + {Name, Domain, Address, Timeout, RetryCount, TagList, Params, + TMask, MMS}) % Arity 9 + when is_atom(Domain) -> + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS); +check_target_addr( + {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, + TMask, MMS}) -> % Arity 9 + Domain = default_domain(), + Address = {Ip, Udp}, + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS); +check_target_addr(X) -> + error({invalid_target_addr, X}). + +check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params) -> % Arity 7 + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + "dummy"). +%% +check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId) -> % Arity 8 + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId, [], 2048). +%% +check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + TMask, MMS) -> % Arity 9 + check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + "dummy", TMask, MMS). +%% +check_target_addr( + Name, Domain, Address, Timeout, RetryCount, TagList, Params, + EngineId, Mask, MMS) -> % Arity 10 ?vtrace("check target address with:" "~n Name: ~s" "~n Domain: ~p" - "~n Ip: ~p" - "~n Udp: ~p" + "~n Address: ~p" "~n Timeout: ~p" "~n RetryCount: ~p" "~n TagList: ~p" "~n Params: ~p" "~n EngineId: ~p" - "~n TMask: ~p" + "~n Mask: ~p" "~n MMS: ~p", - [Name, - Domain, Ip, Udp, + [Name, Domain, Address, Timeout, RetryCount, - TagList, Params, EngineId, TMask, MMS]), + TagList, Params, EngineId, Mask, MMS]), snmp_conf:check_string(Name,{gt,0}), snmp_conf:check_domain(Domain), - snmp_conf:check_ip(Domain, Ip), - snmp_conf:check_integer(Udp, {gt, 0}), + snmp_conf:check_address(Domain, Address), 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), - TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp), + check_mask(Domain, Mask), TDomain = snmp_conf:mk_tdomain(Domain), - check_tmask(TDomain, TMask, TAddress), + TAddress = snmp_conf:mk_taddress(Domain, Address), + TMask = snmp_conf:mk_taddress(Domain, Mask), snmp_conf:check_packet_size(MMS), ?vtrace("check target address done",[]), 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, - Params, EngineId, [], 2048}); -%% Use dummy engine id if the old style is found -check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) -> - check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, - Params, "dummy", [], 2048}); -%% Use dummy engine id if the old style is found -check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, - TMask, MMS}) -> - check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, - Params, "dummy", TMask, MMS}); -check_target_addr(X) -> - error({invalid_target_addr, X}). - + {ok, Addr}. check_engine_id(discovery) -> ok; check_engine_id(EngineId) -> snmp_conf:check_string(EngineId). - -check_tmask(_TDomain, [], _TAddress) -> +check_mask(_Domain, []) -> ok; -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}}). - +check_mask(Domain, Mask) -> + try snmp_conf:check_address(Domain, Mask) + catch + {error, {invalid_address, Info}} -> + {error, {invalid_mask, Info}} + end. %%----------------------------------------------------------------- %% TargetParams diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl index 223d3f7218..69dce337ba 100644 --- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl +++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2013. All Rights Reserved. +%% Copyright Ericsson AB 1999-2014. 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 @@ -137,18 +137,20 @@ do_reconfigure(Dir) -> read_usm_config_files(Dir) -> ?vdebug("read usm config file",[]), - Gen = fun(D, Reason) -> generate_usm(D, Reason) end, - Filter = fun(Usms) -> Usms end, - Check = fun(Entry) -> check_usm(Entry) end, + Gen = fun (D, Reason) -> generate_usm(D, Reason) end, + Order = fun snmp_conf:no_order/2, + Check = fun (Entry, State) -> {check_usm(Entry), State} end, + Filter = fun snmp_conf:no_filter/1, [Usms] = - snmp_conf:read_files(Dir, [{Gen, Filter, Check, "usm.conf"}]), + snmp_conf:read_files(Dir, [{"usm.conf", Gen, Order, Check, Filter}]), Usms. generate_usm(Dir, _Reason) -> info_msg("Incomplete configuration. Generating empty usm.conf.", []), USMFile = filename:join(Dir, "usm.conf"), - ok = file:write_file(USMFile, list_to_binary([])). + ok = file:write_file(USMFile, list_to_binary([])), + []. check_usm({EngineID, Name, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC, diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl index c0177b1cea..722bd7ac5b 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2013. All Rights Reserved. +%% Copyright Ericsson AB 1999-2014. 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 @@ -123,15 +123,18 @@ do_reconfigure(Dir) -> read_vacm_config_files(Dir) -> ?vdebug("read vacm config file",[]), - Gen = fun(_D, _Reason) -> ok end, - Filter = fun(Vacms) -> - Sec2Group = [X || {vacmSecurityToGroup, X} <- Vacms], - Access = [X || {vacmAccess, X} <- Vacms], - View = [X || {vacmViewTreeFamily, X} <- Vacms], - {Sec2Group, Access, View} - end, - Check = fun(Entry) -> check_vacm(Entry) end, - [Vacms] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "vacm.conf"}]), + Gen = fun snmp_conf:no_gen/2, + Order = fun snmp_conf:no_order/2, + Check = fun (Entry, State) -> {check_vacm(Entry), State} end, + Filter = + fun (Vacms) -> + Sec2Group = [X || {vacmSecurityToGroup, X} <- Vacms], + Access = [X || {vacmAccess, X} <- Vacms], + View = [X || {vacmViewTreeFamily, X} <- Vacms], + {Sec2Group, Access, View} + end, + [Vacms] = + snmp_conf:read_files(Dir, [{"vacm.conf", Gen, Order, Check, Filter}]), Vacms. %%----------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index c17a6abbd7..a405987c8a 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2011. All Rights Reserved. +%% Copyright Ericsson AB 2006-2014. 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 @@ -123,21 +123,24 @@ append_agent_config(Dir, Conf) read_agent_config(Dir) -> - Verify = fun(Entry) -> verify_agent_conf_entry(Entry) end, - read_config_file(Dir, "agent.conf", Verify). + Order = fun snmp_framework_mib:order_agent/2, + Check = fun check_agent_conf_entry/2, + read_config_file(Dir, "agent.conf", Order, Check). - -verify_agent_conf([]) -> + +verify_agent_conf(Conf) -> + verify_agent_conf(Conf, undefined). +%% +verify_agent_conf([], _) -> ok; -verify_agent_conf([H|T]) -> - verify_agent_conf_entry(H), - verify_agent_conf(T); -verify_agent_conf(X) -> +verify_agent_conf([H|T], State) -> + {_, NewState} = check_agent_conf_entry(H, State), + verify_agent_conf(T, NewState); +verify_agent_conf(X, _) -> error({bad_agent_config, X}). -verify_agent_conf_entry(Entry) -> - ok = snmp_framework_mib:check_agent(Entry), - ok. +check_agent_conf_entry(Entry, State) -> + {ok, _NewState} = snmp_framework_mib:check_agent(Entry, State). write_agent_conf(Fd, "", Conf) -> write_agent_conf(Fd, Conf); @@ -204,8 +207,12 @@ append_context_config(Dir, Conf) read_context_config(Dir) -> - Verify = fun(Entry) -> verify_context_conf_entry(Entry) end, - read_config_file(Dir, "context.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_context_conf_entry(Entry), State} + end, + read_config_file(Dir, "context.conf", Order, Verify). verify_context_conf([]) -> @@ -286,8 +293,12 @@ append_community_config(Dir, Conf) read_community_config(Dir) -> - Verify = fun(Entry) -> verify_community_conf_entry(Entry) end, - read_config_file(Dir, "community.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_community_conf_entry(Entry), State} + end, + read_config_file(Dir, "community.conf", Order, Verify). verify_community_conf([]) -> @@ -358,8 +369,12 @@ append_standard_config(Dir, Conf) read_standard_config(Dir) -> - Verify = fun(Entry) -> verify_standard_conf_entry(Entry) end, - read_config_file(Dir, "standard.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_standard_conf_entry(Entry), State} + end, + read_config_file(Dir, "standard.conf", Order, Verify). verify_standard_conf([]) -> @@ -520,8 +535,12 @@ append_target_addr_config(Dir, Conf) read_target_addr_config(Dir) -> - Verify = fun(Entry) -> verify_target_addr_conf_entry(Entry) end, - read_config_file(Dir, "target_addr.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_target_addr_conf_entry(Entry), State} + end, + read_config_file(Dir, "target_addr.conf", Order, Verify). verify_target_addr_conf([]) -> @@ -626,8 +645,12 @@ append_target_params_config(Dir, Conf) read_target_params_config(Dir) -> - Verify = fun(Entry) -> verify_target_params_conf_entry(Entry) end, - read_config_file(Dir, "target_params.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_target_params_conf_entry(Entry), State} + end, + read_config_file(Dir, "target_params.conf", Order, Verify). verify_target_params_conf([]) -> @@ -698,8 +721,12 @@ append_notify_config(Dir, Conf) read_notify_config(Dir) -> - Verify = fun(Entry) -> verify_notify_conf_entry(Entry) end, - read_config_file(Dir, "notify.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_notify_conf_entry(Entry), State} + end, + read_config_file(Dir, "notify.conf", Order, Verify). verify_notify_conf([]) -> @@ -794,8 +821,12 @@ append_usm_config(Dir, Conf) read_usm_config(Dir) -> - Verify = fun(Entry) -> verify_usm_conf_entry(Entry) end, - read_config_file(Dir, "usm.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_usm_conf_entry(Entry), State} + end, + read_config_file(Dir, "usm.conf", Order, Verify). verify_usm_conf([]) -> @@ -903,8 +934,12 @@ append_vacm_config(Dir, Conf) read_vacm_config(Dir) -> - Verify = fun(Entry) -> verify_vacm_conf_entry(Entry) end, - read_config_file(Dir, "vacm.conf", Verify). + Order = fun snmp_conf:no_order/2, + Verify = + fun (Entry, State) -> + {verify_vacm_conf_entry(Entry), State} + end, + read_config_file(Dir, "vacm.conf", Order, Verify). verify_vacm_conf([]) -> @@ -958,8 +993,8 @@ write_config_file(Dir, File, Verify, Write) -> append_config_file(Dir, File, Verify, Write) -> snmp_config:append_config_file(Dir, File, Verify, Write). -read_config_file(Dir, File, Verify) -> - snmp_config:read_config_file(Dir, File, Verify). +read_config_file(Dir, File, Order, Check) -> + snmp_config:read_config_file(Dir, File, Order, Check). %% ---- config file utility functions ---- @@ -972,6 +1007,5 @@ header() -> "~2.2.0w:~2.2.0w:~2.2.0w\n", [?MODULE, ?version, Y, Mo, D, H, Mi, S]). - error(R) -> throw({error, R}). diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index 11ae806866..9bb4556788 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2013. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. 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 @@ -183,11 +183,30 @@ discarded_pdu(Variable) -> inc(Variable). %%----------------------------------------------------------------- %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- -v1_v2c_proc(Vsn, NoteStore, Community, Domain, - {Ip, Udp}, LocalEngineID, - Data, HS, Log, Packet) -> +v1_v2c_proc( + Vsn, NoteStore, Community, Domain, Address, + LocalEngineID, Data, HS, Log, Packet) -> + try snmp_conf:check_domain(Domain) of + ok -> + try snmp_conf:check_address(Domain, Address) of + ok -> + v1_v2c_proc_dec( + Vsn, NoteStore, Community, Domain, Address, + LocalEngineID, Data, HS, Log, Packet) + catch + _ -> + {discarded, {badarg, Address}} + end + catch + _ -> + {discarded, {badarg, Domain}} + end. + +v1_v2c_proc_dec( + Vsn, NoteStore, Community, Domain, Address, + LocalEngineID, Data, HS, Log, Packet) -> TDomain = snmp_conf:mk_tdomain(Domain), - TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp), + TAddress = snmp_conf:mk_taddress(Domain, Address), AgentMS = get_engine_max_message_size(LocalEngineID), MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress), PduMS = case MgrMS of @@ -214,7 +233,7 @@ v1_v2c_proc(Vsn, NoteStore, Community, Domain, case Pdu#pdu.type of 'set-request' -> %% Check if this message has already been processed - Key = {agent, Ip, ReqId}, + Key = {agent, {Domain, Address}, ReqId}, case snmp_note_store:get_note(NoteStore, Key) of undefined -> %% Set the processed note _after_ pdu processing. @@ -236,13 +255,7 @@ v1_v2c_proc(Vsn, NoteStore, Community, Domain, {discarded, Reason}; _TrapPdu -> {discarded, trap_pdu} - end; -v1_v2c_proc(_Vsn, _NoteStore, _Community, snmpUDPDomain, TAddress, - _LocalEngineID, _Data, _HS, _Log, _Packet) -> - {discarded, {badarg, TAddress}}; -v1_v2c_proc(_Vsn, _NoteStore, _Community, TDomain, _TAddress, - _LocalEngineID, _Data, _HS, _Log, _Packet) -> - {discarded, {badarg, TDomain}}. + end. sec_model('version-1') -> ?SEC_V1; sec_model('version-2') -> ?SEC_V2C. diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 2101ad46e1..43d394e9d9 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -1666,7 +1666,7 @@ init_agent_default(Item, Val) when Item =/= user_id -> read_agents_config_file(Dir) -> - Check = fun(C) -> check_agent_config2(C) end, + Check = fun(C, S) -> {check_agent_config2(C), S} end, case read_file(Dir, "agents.conf", Check, []) of {ok, Conf} -> Conf; @@ -1837,7 +1837,7 @@ verify_agent2([Bad|_], _VerifiedConf) -> read_users_config_file(Dir) -> - Check = fun(C) -> check_user_config(C) end, + Check = fun(C, S) -> {check_user_config(C), S} end, case read_file(Dir, "users.conf", Check, []) of {ok, Conf} -> Conf; @@ -1950,7 +1950,7 @@ verify_user_agent_config(Conf) -> end. read_usm_config_file(Dir) -> - Check = fun(C) -> check_usm_user_config(C) end, + Check = fun(C, S) -> {check_usm_user_config(C), S} end, case read_file(Dir, "usm.conf", Check, []) of {ok, Conf} -> Conf; @@ -2139,7 +2139,7 @@ is_crypto_supported(Func) -> read_manager_config_file(Dir) -> - Check = fun(Conf) -> check_manager_config(Conf) end, + Check = fun(Conf, State) -> {check_manager_config(Conf), State} end, case read_file(Dir, "manager.conf", Check) of {ok, Conf} -> ?d("read_manager_config_file -> ok: " diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 46625989d5..c52b4bb6fb 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -25,7 +25,8 @@ %% External exports %% Avoid warning for local function error/1 clashing with autoimported BIF. -compile({no_auto_import,[error/1]}). --export([read_files/2, read/2]). +-export([read_files/2, no_gen/2, no_order/2, no_filter/1]). +-export([read/2, read/3]). %% Basic (type) check functions -export([check_mandatory/2, @@ -43,9 +44,10 @@ 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_ip/1, check_ip/2, + check_address/2, + check_taddress/2, + mk_taddress/2, mk_taddress/3, check_packet_size/1, @@ -70,17 +72,53 @@ -include("snmp_verbosity.hrl"). +-define(is_word(P), (((P) band (bnot 65535)) =:= 0)). +-define(is_word(P0, P1), ((((P0) bor (P1)) band (bnot 255)) =:= 0)). + +mk_word(B0, B1) -> ((B0) bsl 8) bor (B1). +mk_bytes(W) -> [(W) bsr 8,(W) band 255]. + +-define( + is_ipv4_addr(A0, A1, A2, A3), + ((((A0) bor (A1) bor (A2) bor (A3)) band (bnot 255)) =:= 0)). + +-define( + is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), + ((((A0) bor (A1) bor (A2) bor (A3) bor (A4) bor (A5) bor (A6) bor (A7)) + band (bnot 65535)) =:= 0)). +-define( + is_ipv6_addr( + A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15), + ((((A0) bor (A1) bor (A2) bor (A3) bor + (A4) bor (A5) bor (A6) bor (A7) bor + (A8) bor (A9) bor (A10) bor (A11) bor + (A12) bor (A13) bor (A14) bor (A15)) + band (bnot 65535)) =:= 0)). + + %%----------------------------------------------------------------- %% read_files(Dir, Files) -> Configs %% Dir - string() - Full path to the config dir. -%% Files - [{Gen, Filter, Check, FileName}] +%% Files - [{FileName, Gen, Order, Check, Filter}] +%% FileName - string() - Name of the config file. %% Gen - function/2 - In case of failure when reading the config file, %% this function is called to either generate a %% default file or issue the error. -%% Filter - function/1 - Filters all the config entries read from the file -%% Check - function/1 - Check each entry as they are read from the file. -%% FileName - string() - Name of the config file. +%% Returns a generated config list corresponding +%% to the written file. +%% (Dir, Error) -> Configs. +%% Order - function/2 - An ordering function that is used to process +%% the read config entries using lists:sort/2. +%% Returns true if arg 1 compares less than or +%% equal to arg 2, false otherwise. +%% Check - function/2 - Check each entry as they are read from the file. +%% (Entry, State) -> +%% {ok,NewState} | {{ok,NewEntry},NewState} | +%% throw(Error) +%% State =:= 'undefined' the first time. +%% Filter - function/1 - Process all the config entries read from the file +%% (Configs) -> [config_entry()]. %% Configs - [config_entry()] %% config_entry() - term() @@ -89,24 +127,122 @@ read_files(Dir, Files) when is_list(Dir) andalso is_list(Files) -> read_files(_Dir, [], Res) -> lists:reverse(Res); -read_files(Dir, [{Gen, Filter, Check, FileName}|Files], Res) - when is_function(Filter) andalso - is_function(Check) andalso - is_list(FileName) -> - ?vdebug("read_files -> entry with" - "~n FileName: ~p", [FileName]), +read_files(Dir, [{FileName, Gen, Order, Check, Filter}|Files], Res) + when is_list(FileName), + is_function(Gen), + is_function(Order), + is_function(Check), + is_function(Filter) -> + ?vdebug("read_files -> entry with~n" + " FileName: ~p", [FileName]), File = filename:join(Dir, FileName), - case file:read_file_info(File) of - {ok, _} -> - Confs = read(File, Check), - read_files(Dir, Files, [Filter(Confs)|Res]); - {error, R} -> - ?vlog("failed reading file info for ~s: " - "~n ~p", [FileName, R]), - Gen(Dir, R), - read_files(Dir, Files, [Filter([])|Res]) + Confs = + case file:read_file_info(File) of + {ok,_} -> + read(File, Order, Check); + {error, R} -> + ?vlog("failed reading file info for ~s: ~n" + " ~p", [FileName, R]), + Gen(Dir, R) + end, + read_files(Dir, Files, [Filter(Confs)|Res]). +%% %% +%% %% XXX remove +%% %% +%% %% read_files(Dir, Files) -> Configs +%% %% Dir - string() - Full path to the config dir. +%% %% Files - [{Gen, Filter, Check, FileName}] +%% %% Gen - function/2 - In case of failure when reading the config file, +%% %% this function is called to either generate a +%% %% default file or issue the error. +%% %% Filter - function/1 - Filters all the config entries read from the file +%% %% Check - function/1 - Check each entry as they are read from the file. +%% %% FileName - string() - Name of the config file. +%% %% Configs - [config_entry()] +%% %% config_entry() - term() +%% +%% read_files(Dir, [{Gen, Filter, Check, FileName}|Files], Res) +%% when is_function(Filter) andalso +%% is_function(Check) andalso +%% is_list(FileName) -> +%% ?vdebug("read_files -> entry with" +%% "~n FileName: ~p", [FileName]), +%% File = filename:join(Dir, FileName), +%% case file:read_file_info(File) of +%% {ok, _} -> +%% Confs = read(File, Check), +%% read_files(Dir, Files, [Filter(Confs)|Res]); +%% {error, R} -> +%% ?vlog("failed reading file info for ~s: " +%% "~n ~p", [FileName, R]), +%% Gen(Dir, R), +%% read_files(Dir, Files, [Filter([])|Res]) +%% end. + +no_gen(_Dir, _R) -> []. +no_order(_, _) -> true. +no_filter(X) -> X. + + + +%% Ret. Res | exit(Reason) +read(File, Order, Check) when is_function(Order), is_function(Check) -> + ?vdebug("read -> entry with~n" + " File: ~p", [File]), + Fd = open_file(File), + read_fd(File, Order, Check, Fd, 1, []). + +read_fd(File, Order, Check, Fd, StartLine, Res) -> + case do_read(Fd, "", StartLine) of + {ok, Row, EndLine} -> + ?vtrace("read_fd ->~n" + " Row: ~p~n" + " EndLine: ~p", [Row,EndLine]), + read_fd( + File, Order, Check, Fd, EndLine, + [{StartLine, Row, EndLine}|Res]); + {error, Error, EndLine} -> + ?vtrace("read_fd -> read failure:~n" + " Error: ~p~n" + " EndLine: ~p", [Error,EndLine]), + file:close(Fd), + error({failed_reading, File, StartLine, EndLine, Error}); + {eof, _EndLine} -> + Lines = + lists:sort( + fun ({_, RowA, _}, {_, RowB, _}) -> + Order(RowA, RowB) + end, + lists:reverse(Res)), + read_check(File, Check, Lines, undefined, []) end. +read_check(_, _, [], _, Res) -> + lists:reverse(Res); +read_check(File, Check, [{StartLine, Row, EndLine}|Lines], State, Res) -> + try Check(Row, State) of + {ok, NewState} -> + ?vtrace("read_check -> ok", []), + read_check(File, Check, Lines, NewState, [Row|Res]); + {{ok, NewRow}, NewState} -> + ?vtrace("read_check -> ok:~n" + " NewRow: ~p~n", [NewRow]), + read_check(File, Check, Lines, NewState, [NewRow|Res]) + catch + {error, Reason} -> + ?vtrace("read_check -> error:~n" + " Reason: ~p", [Reason]), + error({failed_check, File, StartLine, EndLine, Reason}); + Class:Reason -> + Error = {Class,Reason,erlang:get_stacktrace()}, + ?vtrace("read_check -> failure:~n" + " Error: ~p", [Error]), + error({failed_check, File, StartLine, EndLine, Error}) + end. + + + +%% XXX remove %% Ret. Res | exit(Reason) read(File, Check) when is_function(Check) -> @@ -155,11 +291,11 @@ loop(Fd, Res, Check, StartLine, File) -> "~n Error: ~p", [Error]), {error, {failed_check, File, StartLine, EndLine, Error}} end; - {error, EndLine, Error} -> + {error, Error, EndLine} -> ?vtrace("loop -> read failure: " "~n Error: ~p", [Error]), {error, {failed_reading, File, StartLine, EndLine, Error}}; - eof -> + {eof, _EndLine} -> {ok, Res} end. @@ -171,12 +307,8 @@ do_read(Io, Prompt, StartLine) -> {ok, Term} -> {ok, Term, EndLine}; {error, {Line, erl_parse, Error}} -> - {error, Line, {parse_error, Error}} + {error, {parse_error, Error}, Line} end; - {error,E,EndLine} -> - {error, EndLine, E}; - {eof, _EndLine} -> - eof; Other -> Other end. @@ -384,7 +516,7 @@ all_tdomains() -> check_tdomain(TDomain) -> SupportedTDomains = [ - ?snmpUDPDomain, + ?snmpUDPDomain, % Legacy ?transportDomainUdpIpv4, ?transportDomainUdpIpv6 ], @@ -416,40 +548,38 @@ mk_tdomain(BadDomain) -> %% --------- -check_taddress(X) -> - check_taddress(snmpUDPDomain, X). +%% XXX remove +%% 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 -> +check_taddress(transportDomainUdpIpv4, X) -> + case X of + [A0,A1,A2,A3,P0,P1] + when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) -> ok; - false -> + _ -> error({invalid_taddress, X}) end; -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 -> +check_taddress(transportDomainUdpIpv6, X) -> + case X of + [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1] + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), + ?is_word(P0, P1) -> ok; - false -> + _ -> error({invalid_taddress, X}) end; -check_taddress(transportDomainUdpIpv6, X) -> - error({invalid_taddress, X}); - +%% check_taddress(BadDomain, _X) -> error({invalid_tdomain, BadDomain}). @@ -512,31 +642,65 @@ all_domains() -> transportDomainSctpDns ]. +check_domain(snmpUDPDomain) -> ok; +check_domain(transportDomainUdpIpv4) -> ok; +check_domain(transportDomainUdpIpv6) -> ok; check_domain(Domain) -> - SupportedDomains = - [ - snmpUDPDomain, - transportDomainUdpIpv4, - transportDomainUdpIpv6 - ], - AllDomains = all_domains(), - case lists:member(Domain, SupportedDomains) of + case lists:member(Domain, all_domains()) of true -> - ok; + error({unsupported_domain, Domain}); false -> - case lists:member(Domain, AllDomains) of - true -> - error({unsupported_domain, Domain}); - false -> - error({unknown_domain, Domain}) - end + error({unknown_domain, Domain}) end. - + %% --------- -%% The values of Ip and Port has both been checked at this +%% The values of Domain, Ip and Port has both been checked at this %% point, so we dont need to do that again. + +mk_taddress(snmpUDPDomain, Address) -> + mk_taddress(transportDomainUdpIpv4, Address); +mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_list(Ip) -> + Ip ++ mk_bytes(Port); +mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_tuple(Ip) -> + tuple_to_list(Ip) ++ mk_bytes(Port); +mk_taddress(transportDomainUdpIpv4, IpPort) when is_list(IpPort) -> + IpPort; % Should be length 6 +mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_list(Ip) -> + Ip ++ mk_bytes(Port); +mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_tuple(Ip) -> + tuple_to_list(Ip) ++ mk_bytes(Port); +mk_taddress(transportDomainUdpIpv6, IpPort) when is_list(IpPort) -> + case IpPort of + [A0,A1,A2,A3,A4,A5,A6,A7,P] -> + [A0,A1,A2,A3,A4,A5,A6,A7] ++ mk_bytes(P); + [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] -> + [mk_word(A0, A1),mk_word(A2, A3), + mk_word(A4, A5),mk_word(A6, A7), + mk_word(A8, A9),mk_word(A10, A11), + mk_word(A12, A13),mk_word(A14, A15),P0,P1]; + _ -> + IpPort % Should already be 8 words and 2 bytes hence length 10 + end; +mk_taddress(Domain, Address) when is_atom(Domain) -> + erlang:error(badarg, [Domain,Address]); +%% +%% These are just for convenience +mk_taddress(?snmpUDPDomain, Address) -> + mk_taddress(snmpUDPDomain, Address); +mk_taddress(?transportDomainUdpIpv4, Address) -> + mk_taddress(transportDomainUdpIpv4, Address); +mk_taddress(?transportDomainUdpIpv6, Address) -> + mk_taddress(transportDomainUdpIpv6, Address); +%% Bad domain +mk_taddress(BadDomain, _) -> + error({bad_domain, BadDomain}). + + + +%% XXX remove + mk_taddress(snmpUDPDomain, Ip, Port) -> mk_taddress(transportDomainUdpIpv4, Ip, Port); mk_taddress(transportDomainUdpIpv4, Ip, Port) when is_list(Ip) -> @@ -547,7 +711,7 @@ 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); @@ -555,7 +719,7 @@ 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}). @@ -563,47 +727,113 @@ mk_taddress(BadDomain, _Ip, _Port) -> %% --------- -which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 4) -> +%% XXX remove + +which_domain([A0,A1,A2,A3]) when ?is_ipv4_addr(A0, A1, A2, A3) -> transportDomainUdpIpv4; -which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 4) -> +which_domain({A0,A1,A2,A3}) when ?is_ipv4_addr(A0, A1, A2, A3) -> transportDomainUdpIpv4; -which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 8) -> +which_domain([A0,A1,A2,A3,A4,A5,A6,A7]) + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) -> transportDomainUdpIpv6; -which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 8) -> +which_domain({A0, A1, A2, A3, A4, A5, A6, A7}) + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) -> transportDomainUdpIpv6. %% --------- +%% XXX remove + 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 -> +check_ip(transportDomainUdpIpv4, X) -> + case X of + [A,B,C,D] when ?is_ipv4_addr(A, B, C, D) -> ok; - false -> + _ -> error({invalid_ip_address, X}) end; -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 -> +check_ip(transportDomainUdpIpv6, X) -> + case X of + [A,B,C,D,E,F,G,H] + when ?is_ipv6_addr(A, B, C, D, E, F, G, H) -> ok; - false -> + [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] + when ?is_ipv6_addr( + A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> + ok; + _ -> error({invalid_ip_address, X}) end; -check_ip(transportDomainUdpIpv6, X) -> - error({invalid_ip_address, X}); - +%% check_ip(BadDomain, _X) -> error({invalid_domain, BadDomain}). +%% --------- + +%% Check a configuration term field from a file to see if it +%% can be fed to mk_taddress/2. + +check_address(Domain, Address) + when Domain =:= snmpUDPDomain; + Domain =:= transportDomainUdpIpv4 -> + case Address of + %% Erlang native format + {{A0, A1, A2, A3}, P} + when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P) -> + ok; + %% Erlangish format + {[A0,A1,A2,A3], P} + when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P) -> + ok; + %% SNMP standards format + [A0,A1,A2,A3,P0,P1] + when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) -> + ok; + _ -> + error({invalid_address, {Domain, Address}}) + end; +check_address(transportDomainUdpIpv6 = Domain, Address) -> + case Address of + %% Erlang native format + {{A0, A1, A2, A3, A4, A5, A6, A7}, P} + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), + ?is_word(P) -> + ok; + %% Erlangish format + {[A0,A1,A2,A3,A4,A5,A6,A7], P} + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), + ?is_word(P) -> + ok; + %% Erlang friendly list format + [A0,A1,A2,A3,A4,A5,A6,A7,P] + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), + ?is_word(P) -> + ok; + %% Strange hybrid format with port as bytes + [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1] + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), + ?is_word(P0, P1) -> + ok; + %% SNMP standards format + [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] + when ?is_ipv6_addr( + A0, A1, A2, A3, A4, A5, A6, A7, + A8, A9, A10, A11, A12, A13, A14, A15), + ?is_word(P0, P1) -> + ok; + _ -> + error({invalid_address, {Domain, Address}}) + end; +check_address(BadDomain, _) -> + error({invalid_domain, BadDomain}). + + %% --------- diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index a222f842e5..ec6b2ac7e4 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -26,7 +26,8 @@ -compile({no_auto_import,[error/1]}). -export([config/0]). --export([write_config_file/4, append_config_file/4, read_config_file/3]). +-export([write_config_file/4, append_config_file/4, + read_config_file/3, read_config_file/4]). -export([write_agent_snmp_files/7, write_agent_snmp_files/12, @@ -2471,7 +2472,9 @@ append_config_file(Dir, FileName, Verify, Write) throw:Error -> Error; T:E -> - {error, {failed_append, Dir, FileName, T, E}} + {error, + {failed_append, Dir, FileName, + {T, E, erlang:get_stacktrace()}}} end. do_append_config_file(Dir, FileName, Verify, Write) -> @@ -2500,59 +2503,131 @@ file_write_and_close(Write, Fd, Dir, FileName) -> end. +%% XXX remove +read_config_file(Dir, FileName, Verify) -> + read_config_file( + Dir, FileName, fun snmp_conf:no_order/2, + fun (Term, State) -> + {Verify(Term), State} + end). + -spec read_config_file(Dir :: string(), - FileName :: string(), - Verify :: verify_config_entry_function()) -> + FileName :: string(), + Order :: function(), + Verify :: function()) -> {ok, Config :: list()} | {error, Reason :: term()}. -read_config_file(Dir, FileName, Verify) - when is_list(Dir) andalso is_list(FileName) andalso is_function(Verify) -> - (catch do_read_config_file(Dir, FileName, Verify)). - -do_read_config_file(Dir, FileName, Verify) -> +read_config_file(Dir, FileName, Order, Check) + when is_list(Dir), is_list(FileName), + is_function(Order), is_function(Check) -> case file:open(filename:join(Dir, FileName), [read]) of {ok, Fd} -> - Result = read_loop(Fd, [], Verify, 1), - file:close(Fd), - Result; + try + {ok, + verify_lines( + lists:sort( + fun ({_, T1, _}, {_, T2, _}) -> + Order(T1, T2) + end, + read_lines(Fd, [], 1)), + Check, undefined, [])} + catch + Error -> + {error, Error} + after + file:close(Fd) + end; {error, Reason} -> {error, {Reason, FileName}} end. -read_loop(Fd, Acc, Check, StartLine) -> - case read_term(Fd, StartLine) of +read_lines(Fd, Acc, StartLine) -> + case read_and_parse_term(Fd, StartLine) of {ok, Term, EndLine} -> - case (catch Check(Term)) of - ok -> - read_loop(Fd, [Term | Acc], Check, EndLine); - {error, Reason} -> - {error, {failed_check, StartLine, EndLine, Reason}}; - Error -> - {error, {failed_check, StartLine, EndLine, Error}} - end; - {error, EndLine, Error} -> - {error, {failed_reading, StartLine, EndLine, Error}}; - eof -> - {ok, lists:reverse(Acc)} + read_lines(Fd, [{StartLine, Term, EndLine}|Acc], EndLine); + {error, Error, EndLine} -> + throw({failed_reading, StartLine, EndLine, Error}); + {eof, _EndLine} -> + lists:reverse(Acc) end. - -read_term(Fd, StartLine) -> + +read_and_parse_term(Fd, StartLine) -> case io:request(Fd, {get_until, "", erl_scan, tokens, [StartLine]}) of {ok, Tokens, EndLine} -> case erl_parse:parse_term(Tokens) of {ok, Term} -> {ok, Term, EndLine}; {error, {Line, erl_parse, Error}} -> - {error, Line, {parse_error, Error}} + {error, {parse_error, Error}, Line} end; - {error, E, EndLine} -> - {error, EndLine, E}; - {eof, _EndLine} -> - eof; Other -> Other end. +verify_lines([], _, Acc, _) -> + list:reverse(Acc); +verify_lines( + [{StartLine, Term, EndLine}|Lines], State, Acc, Check) -> + try Check(Term, State) of + {ok, NewState} -> + verify_lines(Lines, NewState, [Term|Acc], Check); + {{ok, NewTerm}, NewState} -> + verify_lines(Lines, NewState, [NewTerm|Acc], Check) + catch + {error, Reason} -> + throw({failed_check, StartLine, EndLine, Reason}); + C:R -> + S = erlang:get_stacktrace(), + throw({failed_check, StartLine, EndLine, {C, R, S}}) + end. + + +%% XXX remove + +%% do_read_config_file(Dir, FileName, Verify) -> +%% case file:open(filename:join(Dir, FileName), [read]) of +%% {ok, Fd} -> +%% Result = read_loop(Fd, [], Verify, 1), +%% file:close(Fd), +%% Result; +%% {error, Reason} -> +%% {error, {Reason, FileName}} +%% end. + +%% read_loop(Fd, Acc, Check, StartLine) -> +%% case read_term(Fd, StartLine) of +%% {ok, Term, EndLine} -> +%% case (catch Check(Term)) of +%% ok -> +%% read_loop(Fd, [Term | Acc], Check, EndLine); +%% {error, Reason} -> +%% {error, {failed_check, StartLine, EndLine, Reason}}; +%% Error -> +%% {error, {failed_check, StartLine, EndLine, Error}} +%% end; +%% {error, EndLine, Error} -> +%% {error, {failed_reading, StartLine, EndLine, Error}}; +%% eof -> +%% {ok, lists:reverse(Acc)} +%% end. + +%% read_term(Fd, StartLine) -> +%% case io:request(Fd, {get_until, "", erl_scan, tokens, [StartLine]}) of +%% {ok, Tokens, EndLine} -> +%% case erl_parse:parse_term(Tokens) of +%% {ok, Term} -> +%% {ok, Term, EndLine}; +%% {error, {Line, erl_parse, Error}} -> +%% {error, Line, {parse_error, Error}} +%% end; +%% {error, E, EndLine} -> +%% {error, EndLine, E}; +%% {eof, _EndLine} -> +%% eof; +%% Other -> +%% Other +%% end. + agent_snmp_mk_secret(Alg, Passwd, EngineID) -> snmp_usm:passwd2localized_key(Alg, Passwd, EngineID). diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index d7109253f7..bfedd7558c 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% Copyright Ericsson AB 2005-2014. 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 @@ -1375,9 +1375,9 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp) -> "~n MIp: ~p" "~n AIp: ~p", [Vsns, MgrDir, AgentConfDir, MIp, AIp]), - ?line snmp_config:write_agent_snmp_files(AgentConfDir, Vsns, - MIp, ?TRAP_UDP, AIp, 4000, - "test"), + ?line ok = + snmp_config:write_agent_snmp_files( + AgentConfDir, Vsns, MIp, ?TRAP_UDP, AIp, 4000, "test"), ?line case update_usm(Vsns, AgentConfDir) of true -> ?line copy_file(join(AgentConfDir, "usm.conf"), @@ -1486,7 +1486,7 @@ rewrite_usm_mgr(Dir, ShaKey, DesKey) -> {"mgrEngine", "newUser", "newUser", zeroDotZero, usmHMACSHAAuthProtocol, "", "", usmDESPrivProtocol, "", "", "", ShaKey, DesKey}], - ok = snmp_config:write_agent_usm_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_usm_config(Dir, "", Conf). reset_usm_mgr(Dir) -> ?line ok = file:rename(join(Dir,"usm.old"), @@ -1512,13 +1512,15 @@ update_vacm(_Vsn, Dir) -> write_community_conf(Dir, Conf) -> - snmp_config:write_agent_community_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_community_config(Dir, "", Conf). write_target_addr_conf(Dir, Conf) -> - snmp_config:write_agent_target_addr_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_target_addr_config(Dir, "", Conf). write_target_addr_conf(Dir, ManagerIp, UDP, Vsns) -> - snmp_config:write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Vsns). + ?line ok = + snmp_config:write_agent_snmp_target_addr_conf( + Dir, ManagerIp, UDP, Vsns). rewrite_target_addr_conf(Dir, NewPort) -> ?DBG("rewrite_target_addr_conf -> entry with" @@ -1571,14 +1573,14 @@ write_target_params_conf(Dir, Vsns) -> (v3) -> {"target_v3", v3, usm, "all-rights", noAuthNoPriv} end, Conf = [F(Vsn) || Vsn <- Vsns], - snmp_config:write_agent_target_params_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_target_params_config(Dir, "", Conf). rewrite_target_params_conf(Dir, SecName, SecLevel) when is_list(SecName) andalso is_atom(SecLevel) -> ?line ok = file:rename(join(Dir,"target_params.conf"), join(Dir,"target_params.old")), Conf = [{"target_v3", v3, usm, SecName, SecLevel}], - snmp_config:write_agent_target_params_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_target_params_config(Dir, "", Conf). reset_target_params_conf(Dir) -> ?line ok = file:rename(join(Dir,"target_params.old"), @@ -1587,12 +1589,12 @@ reset_target_params_conf(Dir) -> write_notify_conf(Dir) -> Conf = [{"standard trap", "std_trap", trap}, {"standard inform", "std_inform", inform}], - snmp_config:write_agent_notify_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_notify_config(Dir, "", Conf). write_view_conf(Dir) -> Conf = [{2, [1,3,6], included, null}, {2, ?tDescr_instance, excluded, null}], - snmp_config:write_agent_view_config(Dir, "", Conf). + ?line ok = snmp_config:write_agent_view_config(Dir, "", Conf). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -- cgit v1.2.3 From 7bc7e5821ea0614ca82467bf0349f82b61d89971 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 11 Apr 2014 16:14:00 +0200 Subject: wip --- lib/snmp/src/agent/snmp_framework_mib.erl | 9 +- lib/snmp/src/agent/snmp_target_mib.erl | 22 +- lib/snmp/src/agent/snmpa_conf.erl | 2 +- lib/snmp/src/agent/snmpa_mpd.erl | 16 +- lib/snmp/src/manager/snmpm_config.erl | 642 ++++++++++++++---------------- lib/snmp/src/manager/snmpm_mpd.erl | 69 ++-- lib/snmp/src/misc/snmp_conf.erl | 381 ++++++++++-------- 7 files changed, 560 insertions(+), 581 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 84f39df228..51f8c46d19 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -197,12 +197,7 @@ check_context(Context) -> %% {Name, Value}. %%----------------------------------------------------------------- check_agent({intAgentTransportDomain, D}, Domain) -> - case Domain of - undefined -> - {snmp_conf:check_domain(D), D}; - _ -> - error({invalid_agent_attribute, D}) - end; + {snmp_conf:check_domain(D), D}; check_agent({intAgentTransportAddress, Address}, Domain) -> {snmp_conf:check_address(Domain, Address), Domain}; check_agent(Entry, Domain) -> @@ -224,7 +219,7 @@ check_agent(X) -> %% Ordering function to sort intAgentTransportDomain first %% hence before intAgentTransportAddress -order_agent({intAgentTransportDomain, _}, {intAgentTransportDomain, _}) -> +order_agent({Name, _}, {Name, _}) -> true; %% Less than or equal order_agent(_, {intAgentTransportDomain, _}) -> false; %% Greater than diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 6dd3b6e23a..cff1e253c3 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -263,16 +263,16 @@ check_target_addr( TagList, Params, EngineId, Mask, MMS]), snmp_conf:check_string(Name,{gt,0}), snmp_conf:check_domain(Domain), - snmp_conf:check_address(Domain, Address), + NAddress = snmp_conf:check_address(Domain, Address), 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), - check_mask(Domain, Mask), + NMask = check_mask(Domain, Mask), TDomain = snmp_conf:mk_tdomain(Domain), - TAddress = snmp_conf:mk_taddress(Domain, Address), - TMask = snmp_conf:mk_taddress(Domain, Mask), + TAddress = snmp_conf:mk_taddress(Domain, NAddress), + TMask = snmp_conf:mk_taddress(Domain, NMask), snmp_conf:check_packet_size(MMS), ?vtrace("check target address done",[]), Addr = {Name, TDomain, TAddress, Timeout, @@ -286,13 +286,21 @@ check_engine_id(discovery) -> check_engine_id(EngineId) -> snmp_conf:check_string(EngineId). +check_address(Domain, Address) -> + case snmp_conf:check_address(Domain, Address) of + ok -> + Address; + {ok, FixedAddress} -> + FixedAddress + end. + check_mask(_Domain, []) -> - ok; + []; check_mask(Domain, Mask) -> - try snmp_conf:check_address(Domain, Mask) + try check_address(Domain, Mask) catch {error, {invalid_address, Info}} -> - {error, {invalid_mask, Info}} + error({invalid_mask, Info}) end. %%----------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index a405987c8a..f055f89880 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -140,7 +140,7 @@ verify_agent_conf(X, _) -> error({bad_agent_config, X}). check_agent_conf_entry(Entry, State) -> - {ok, _NewState} = snmp_framework_mib:check_agent(Entry, State). + snmp_framework_mib:check_agent(Entry, State). write_agent_conf(Fd, "", Conf) -> write_agent_conf(Fd, Conf); diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index 9bb4556788..2db98d9fc2 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -186,12 +186,12 @@ discarded_pdu(Variable) -> inc(Variable). v1_v2c_proc( Vsn, NoteStore, Community, Domain, Address, LocalEngineID, Data, HS, Log, Packet) -> - try snmp_conf:check_domain(Domain) of - ok -> - try snmp_conf:check_address(Domain, Address) of - ok -> + try snmp_conf:mk_tdomain(Domain) of + TDomain -> + try snmp_conf:mk_taddress(Domain, Address) of + TAddress -> v1_v2c_proc_dec( - Vsn, NoteStore, Community, Domain, Address, + Vsn, NoteStore, Community, TDomain, TAddress, LocalEngineID, Data, HS, Log, Packet) catch _ -> @@ -203,10 +203,8 @@ v1_v2c_proc( end. v1_v2c_proc_dec( - Vsn, NoteStore, Community, Domain, Address, + Vsn, NoteStore, Community, TDomain, TAddress, LocalEngineID, Data, HS, Log, Packet) -> - TDomain = snmp_conf:mk_tdomain(Domain), - TAddress = snmp_conf:mk_taddress(Domain, Address), AgentMS = get_engine_max_message_size(LocalEngineID), MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress), PduMS = case MgrMS of @@ -233,7 +231,7 @@ v1_v2c_proc_dec( case Pdu#pdu.type of 'set-request' -> %% Check if this message has already been processed - Key = {agent, {Domain, Address}, ReqId}, + Key = {agent, {TDomain, TAddress}, ReqId}, case snmp_note_store:get_note(NoteStore, Key) of undefined -> %% Set the processed note _after_ pdu processing. diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 43d394e9d9..af2262d988 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -335,27 +335,17 @@ register_agent(UserId, TargetName, Config0) %% is not present %% 3) Check that there are no invalid or erroneous configs %% 4) Check that the manager is capable of using the selected version - case verify_agent_config(Config0) of - {ok, Config} -> - call({register_agent, UserId, TargetName, Config}); - Error -> - Error - end. - - -verify_agent_config(Conf0) -> try - begin - verify_mandatory(Conf0, [engine_id, address, reg_type]), - verify_invalid(Conf0, [user_id]), - Conf = verify_agent_config3(Conf0), - Vsns = versions(), - Vsn = which_version(Conf), - verify_version(Vsn, Vsns), - {ok, Conf} - end + verify_mandatory(Config0, [engine_id, reg_type]), + verify_oneof(Config0, [address, taddress]), + verify_invalid(Config0, [user_id]), + Config = verify_agent(Config0), + Vsns = versions(), + Vsn = which_version(Config), + verify_version(Vsn, Vsns), + call({register_agent, UserId, TargetName, Config}) catch - throw:Error -> + Error -> Error end. @@ -381,37 +371,9 @@ verify_version(Vsn, Vsns) -> ok; false -> Reason = {version_not_supported_by_manager, Vsn, Vsns}, - throw({error, Reason}) - end. - -verify_agent_config3(Conf0) -> - %% Fix (transport) address and domain - {TDomain, Conf1} = - case lists:keysearch(tdomain, 1, Conf0) of - {value, {tdomain, Dom}} -> - {Dom, Conf0}; - false -> - Dom = default_transport_domain(), - {Dom, [{tdomain, Dom} | Conf0]} - end, - Conf2 = case lists:keysearch(address, 1, Conf1) of - {value, {address, Address}} -> - lists:keyreplace(address, 1, Conf1, - {address, {TDomain, Address}}); - false -> - %% This is a mandatory config option, - %% a later test will detect this - Conf1 - end, - case verify_agent2(Conf2) of - {ok, Conf} -> - Conf; - {error, _} = ERROR -> - throw(ERROR) + error(Reason) end. -verify_agent_config2(Conf) -> - verify_agent2(Conf). unregister_agent(UserId, TargetName) -> @@ -444,7 +406,7 @@ agent_info(TargetName, Item) -> [] -> {error, not_found} end. - + agent_info(Addr0, Port, Item) -> Addr = normalize_address(Addr0), do_agent_info(Addr, Port, Item). @@ -474,38 +436,6 @@ which_agents(UserId) -> [TargetName || [TargetName] <- Agents]. -verify_agent_info(TargetName, Info0) -> - try - begin - verify_invalid(Info0, [user_id]), - %% Check if address is part of the list and - %% if so update it with the domain info. - Info = - case lists:keysearch(address, 1, Info0) of - {value, {address, Addr}} -> - %% If domain is part of the info, then use it. - %% If not, lookup what is already stored for - %% this agent and use that. - Domain = - case lists:keysearch(tdomain, 1, Info0) of - {value, {tdomain, Dom}} -> - Dom; - false -> - {ok, Dom} = - agent_info(TargetName, tdomain), - Dom - end, - Addr2 = {Domain, Addr}, - lists:keyreplace(address, 1, Info0, {address, Addr2}); - false -> - Info0 - end, - verify_agent2(Info) - end - catch - throw:Error -> - Error - end. update_agent_info(UserId, TargetName, Info) -> call({update_agent_info, UserId, TargetName, Info}). @@ -1666,8 +1596,8 @@ init_agent_default(Item, Val) when Item =/= user_id -> read_agents_config_file(Dir) -> - Check = fun(C, S) -> {check_agent_config2(C), S} end, - case read_file(Dir, "agents.conf", Check, []) of + Verify = fun check_agent_config2/1, + case read_file(Dir, "agents.conf", Verify, []) of {ok, Conf} -> Conf; Error -> @@ -1691,119 +1621,44 @@ check_agent_config2(Agent) -> end. %% For backward compatibility -check_agent_config({UserId, - TargetName, - Community, - Ip, Port, - EngineId, - Timeout, MaxMessageSize, - Version, SecModel, SecName, SecLevel}) -> +check_agent_config( + {UserId, TargetName, Community, Ip, Port, + EngineId, Timeout, MaxMessageSize, + Version, SecModel, SecName, SecLevel}) -> TDomain = default_transport_domain(), - check_agent_config({UserId, - TargetName, - Community, - TDomain, Ip, Port, - EngineId, - Timeout, MaxMessageSize, - Version, SecModel, SecName, SecLevel}); - -check_agent_config({UserId, - TargetName, - Community, - TDomain, Ip, Port, - EngineId, - Timeout, MaxMessageSize, - Version, SecModel, SecName, SecLevel}) -> - ?vtrace("check_agent_config -> entry with" - "~n UserId: ~p" - "~n TargetName: ~p" - "~n Community: ~p" - "~n TDomain: ~p" - "~n Ip: ~p" - "~n Port: ~p" - "~n EngineId: ~p" - "~n Timeout: ~p" - "~n MaxMessageSize: ~p" - "~n Version: ~p" - "~n SecModel: ~p" - "~n SecName: ~p" - "~n SecLevel: ~p", - [UserId, TargetName, Community, - TDomain, Ip, Port, - EngineId, Timeout, MaxMessageSize, - Version, SecModel, SecName, SecLevel]), - Addr = normalize_address(TDomain, Ip), - ?vtrace("check_agent_config -> Addr: ~p", [Addr]), - Agent = {UserId, - TargetName, - Community, - TDomain, Addr, Port, - EngineId, - Timeout, MaxMessageSize, - Version, SecModel, SecName, SecLevel}, - {ok, verify_agent(Agent)}; + check_agent_config( + UserId, TargetName, Community, TDomain, {Ip, Port}, + EngineId, Timeout, MaxMessageSize, + Version, SecModel, SecName, SecLevel); +check_agent_config( + {UserId, TargetName, Community, TDomain, Ip, Port, + EngineId, Timeout, MaxMessageSize, + Version, SecModel, SecName, SecLevel}) -> + check_agent_config( + UserId, TargetName, Community, TDomain, {Ip, Port}, + EngineId, Timeout, MaxMessageSize, + Version, SecModel, SecName, SecLevel); check_agent_config(Agent) -> error({bad_agent_config, Agent}). - -init_agents_config([]) -> - ok; -init_agents_config([Agent|Agents]) -> - init_agent_config(Agent), - init_agents_config(Agents). - -init_agent_config({_UserId, ?DEFAULT_TARGETNAME = TargetName, _Config}) -> - throw({error, {invalid_target_name, TargetName}}); -init_agent_config({UserId, TargetName, Config}) -> - case handle_register_agent(UserId, TargetName, Config) of - ok -> - ok; - Error -> - throw(Error) - end. - - -%% For backward compatibility -verify_agent({UserId, - TargetName, - Comm, - Ip, Port, - EngineId, - Timeout, MMS, - Version, SecModel, SecName, SecLevel}) -> - TDomain = default_transport_domain(), - verify_agent({UserId, - TargetName, - Comm, - TDomain, Ip, Port, - EngineId, - Timeout, MMS, - Version, SecModel, SecName, SecLevel}); - -verify_agent({UserId, - TargetName, - Comm, - TDomain, Ip, Port, - EngineId, - Timeout, MMS, - Version, SecModel, SecName, SecLevel}) -> - ?vdebug("verify_agent -> entry with" +check_agent_config( + UserId, TargetName, Comm, TDomain, TAddress, + EngineId, Timeout, MMS, + Version, SecModel, SecName, SecLevel) -> + ?vdebug("check_agent_config -> entry with" "~n UserId: ~p" "~n TargetName: ~p", [UserId, TargetName]), snmp_conf:check_string(TargetName, {gt, 0}), - snmp_conf:check_integer(Port, {gt, 0}), %% Note that the order of Conf *is* important. %% Some properties may depend on others, so that %% in order to verify one property, another must %% be already verified (and present). An example - %% of this is the property 'address', for which + %% of this is the property 'taddress', for which %% the property tdomain is needed. - Conf0 = + Conf = [{reg_type, target_name}, {tdomain, TDomain}, - %% This should be taddress, but what the*... - {address, {TDomain, Ip}}, - {port, Port}, + {taddress, TAddress}, {community, Comm}, {engine_id, EngineId}, {timeout, Timeout}, @@ -1813,32 +1668,148 @@ verify_agent({UserId, {sec_name, SecName}, {sec_level, SecLevel} ], - case verify_agent2(Conf0) of - {ok, Conf} -> - {UserId, TargetName, Conf, Version}; - Err -> - throw(Err) + {ok, {UserId, TargetName, verify_agent(Conf), Version}}. + + + +init_agents_config([]) -> + ok; +init_agents_config([Agent|Agents]) -> + init_agent_config(Agent), + init_agents_config(Agents). + +init_agent_config({_UserId, ?DEFAULT_TARGETNAME = TargetName, _Config}) -> + error({invalid_target_name, TargetName}); +init_agent_config({UserId, TargetName, Config}) -> + case handle_register_agent(UserId, TargetName, Config) of + ok -> + ok; + Error -> + throw(Error) end. -verify_agent2(Conf) -> - verify_agent2(Conf, []). -verify_agent2([], VerifiedConf) -> - {ok, VerifiedConf}; -verify_agent2([{Item, Val0}|Items], VerifiedConf) -> - case verify_val(Item, Val0) of - {ok, Val} -> - verify_agent2(Items, [{Item, Val} | VerifiedConf]); - Err -> - Err + +%% Sort tdomain first +order_agent({Item, _}, {Item, _}) -> + true; %% Less than or equal +order_agent(_, {tdomain, _}) -> + false; %% Greater than +order_agent(_, _) -> + true. %% Less than or equal + +verify_agent(Conf) -> + verify_agent(lists:sort(fun order_agent/2, Conf), []). + +verify_agent([], VerifiedConf) -> + list:reverse(VerifiedConf); +verify_agent([{_Item, _} = Entry|Conf], VerifiedConf) -> +%% verify_invalid(VerifiedConf, [_Item]), % Check for duplicate + verify_agent(Conf, VerifiedConf, Entry); +verify_agent([Bad|_], _VerifiedConf) -> + error({bad_agent_config, Bad}). + +verify_agent(Conf, VerifiedConf, {taddress = Item, TAddress} = Entry) -> + verify_invalid(VerifiedConf, [address,port]), + {TDomain, VC} = + case lists:keysearch(tdomain, 1, VerifiedConf) of + {value, {tdomain,TD}} -> + {TD, VerifiedConf}; + _ -> + %% Insert tdomain since it is missing + TD = default_transport_domain(), + {TD, [{tdomain, TD}|VerifiedConf]} + end, + case snmp_conf:check_address(TDomain, TAddress) of + ok -> + verify_agent(Conf, [Entry|VC]); + {ok, NAddress} -> + verify_agent(Conf, [{Item, NAddress}|VC]) + end; +verify_agent(Conf, VerifiedConf, {address = Item, Address} = Entry) -> + verify_invalid(VerifiedConf, [taddress]), + {TDomain, VC} = + case lists:keysearch(tdomain, 1, VerifiedConf) of + {value, {tdomain,TD}} -> + {TD, VerifiedConf}; + _ -> + %% Insert tdomain since it is missing + TD = default_transport_domain(), + {TD, [{tdomain, TD}|VerifiedConf]} + end, + FakePort = make_ref(), + case snmp_conf:check_address(TDomain, Address, FakePort) of + ok -> + verify_agent(Conf, [Entry|VC]); + {ok, {NAddress,FakePort}} -> + verify_agent(Conf, [{Item, NAddress}|VC]); + {ok, _} -> + error({invalid_address, {TDomain, Address}}) + end; +verify_agent(Conf, VerifiedConf, {port, Port} = Entry) -> + verify_invalid(VerifiedConf, [taddress]), + ok = snmp_conf:check_address(snmpUDPDomain, {{0, 0, 0, 0}, Port}), + verify_agent(Conf, [Entry|VerifiedConf]); +verify_agent(Conf, VerifiedConf, {Item, Val} = Entry) -> + case verify_agent_entry(Item, Val) of + ok -> + verify_agent(Conf, [Entry|VerifiedConf]); + {ok, NewVal} -> + verify_agent(Conf, [{Item, NewVal}|VerifiedConf]) + end. + +verify_agent_entry(user_id, _UserId) -> + ok; +verify_agent_entry(reg_type, RegType) -> + if + RegType =:= addr_port; + RegType =:= target_name -> + ok; + true -> + error({bad_reg_type, RegType}) + end; +verify_agent_entry(tdomain, TDomain) -> + snmp_conf:check_domain(TDomain); +verify_agent_entry(community, Comm) -> + snmp_conf:check_string(Comm); +verify_agent_entry(engine_id, EngineId) -> + case EngineId of + discovery -> + ok; + _ -> + snmp_conf:check_string(EngineId) + end; +verify_agent_entry(timeout, Timeout) -> + snmp_conf:check_timer(Timeout); +verify_agent_entry(max_message_size, MMS) -> + snmp_conf:check_packet_size(MMS); +verify_agent_entry(version, V) -> + if + V =:= v1; + V =:= v2; + V =:= v3 -> + ok; + true -> + error({bad_version, V}) end; -verify_agent2([Bad|_], _VerifiedConf) -> - {error, {bad_agent_config, Bad}}. +verify_agent_entry(sec_model, Model) -> + snmp_conf:check_sec_model(Model); +verify_agent_entry(sec_name, Name) -> + try snmp_conf:check_string(Name) + catch + _ -> + error({bad_sec_name, Name}) + end; +verify_agent_entry(sec_level, Level) -> + snmp_conf:check_sec_level(Level); +verify_agent_entry(Item, _) -> + error({unknown_item, Item}). + read_users_config_file(Dir) -> - Check = fun(C, S) -> {check_user_config(C), S} end, - case read_file(Dir, "users.conf", Check, []) of + Verify = fun check_user_config/1, + case read_file(Dir, "users.conf", Verify, []) of {ok, Conf} -> Conf; Error -> @@ -1864,15 +1835,12 @@ check_user_config({Id, Mod, Data, DefaultAgentConfig} = _User) case (catch verify_user_behaviour(Mod)) of ok -> ?vtrace("check_user_config -> user behaviour verified", []), - case verify_user_agent_config(DefaultAgentConfig) of - {ok, DefAgentConf} -> - ?vtrace("check_user_config -> " - "user agent (default) config verified", []), - User2 = {Id, Mod, Data, DefAgentConf}, - {ok, User2}; - {error, Reason} -> - error({bad_default_agent_config, Reason}) - end; + DefAgentConf = + verify_default_agent_config(DefaultAgentConfig), + ?vtrace("check_user_config -> " + "user agent (default) config verified", []), + User2 = {Id, Mod, Data, DefAgentConf}, + {ok, User2}; Error -> throw(Error) end; @@ -1904,7 +1872,7 @@ init_user_config(User) -> error_msg("user config check failed: " "~n~w~n~w", [User, Reason]) end. - + verify_user({Id, UserMod, UserData}) -> verify_user({Id, UserMod, UserData, []}); verify_user({Id, UserMod, UserData, DefaultAgentConfig}) @@ -1917,15 +1885,19 @@ verify_user({Id, UserMod, UserData, DefaultAgentConfig}) [Id, UserMod, UserData, DefaultAgentConfig]), case (catch verify_user_behaviour(UserMod)) of ok -> - case verify_user_agent_config(DefaultAgentConfig) of - {ok, DefAgentConf} -> - Config = default_agent_config(DefAgentConf), - {ok, #user{id = Id, - mod = UserMod, - data = UserData, - default_agent_config = Config}}; - {error, Reason} -> - error({bad_default_agent_config, Reason}) + try + Config = + default_agent_config( + verify_default_agent_config(DefaultAgentConfig)), + {ok, #user{id = Id, + mod = UserMod, + data = UserData, + default_agent_config = Config}} + catch + Error -> + ?vdebug("verify_user default_agent_config -> throw" + "~n Error: ~p", [Error]), + error({bad_default_agent_config, Error}) end; Error -> throw(Error) @@ -1936,22 +1908,22 @@ verify_user({Id, _UserMod, _UserData, DefaultAgentConfig}) verify_user({Id, _, _, _}) -> {error, {bad_user_id, Id}}. -verify_user_agent_config(Conf) -> +verify_default_agent_config(Conf) -> try - begin - verify_invalid(Conf, [user_id, engine_id, address]), - verify_agent_config2(Conf) - end + verify_invalid( + Conf, + [user_id, engine_id, address, tdomain, taddress]), + verify_agent(Conf) catch - throw:Error -> - ?vdebug("verify_user_agent_config -> throw" + Error -> + ?vdebug("verify_default_agent_config -> throw" "~n Error: ~p", [Error]), - Error + error({bad_default_agent_config, Error}) end. read_usm_config_file(Dir) -> - Check = fun(C, S) -> {check_usm_user_config(C), S} end, - case read_file(Dir, "usm.conf", Check, []) of + Verify = fun check_usm_user_config/1, + case read_file(Dir, "usm.conf", Verify, []) of {ok, Conf} -> Conf; Error -> @@ -2139,8 +2111,8 @@ is_crypto_supported(Func) -> read_manager_config_file(Dir) -> - Check = fun(Conf, State) -> {check_manager_config(Conf), State} end, - case read_file(Dir, "manager.conf", Check) of + Verify = fun check_manager_config/1, + case read_file(Dir, "manager.conf", Verify) of {ok, Conf} -> ?d("read_manager_config_file -> ok: " "~n Conf: ~p", [Conf]), @@ -2218,44 +2190,80 @@ ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) -> -read_file(Dir, FileName, Check, Default) -> +read_file(Dir, FileName, Verify, Default) -> File = filename:join(Dir, FileName), case file:read_file_info(File) of {ok, _} -> - case (catch do_read(File, Check)) of - {ok, Conf} -> - {ok, Conf}; - Error -> - ?vtrace("read_file -> read failed:" - "~n Error: ~p", [Error]), - Error - end; - {error, Reason} -> + read_file(File, Verify); + {error, Reason} -> ?vlog("failed reading config from ~s: ~p", [FileName, Reason]), {ok, Default} end. -read_file(Dir, FileName, Check) -> +read_file(Dir, FileName, Verify) -> File = filename:join(Dir, FileName), case file:read_file_info(File) of {ok, _} -> - case (catch do_read(File, Check)) of - {ok, Conf} -> - ?vtrace("read_file -> read ok" - "~n Conf: ~p", [Conf]), - {ok, Conf}; - Error -> - ?vtrace("read_file -> read failed:" - "~n Error: ~p", [Error]), - Error - end; + read_file(File, Verify); {error, Reason} -> error_msg("failed reading config from ~s: ~p", [FileName, Reason]), {error, {failed_reading, FileName, Reason}} end. -do_read(File, Check) -> - {ok, snmp_conf:read(File, Check)}. +read_file(File, Verify) -> + Check = fun (Config, State) -> {Verify(Config), State} end, + try snmp_conf:read(File, Check) of + Conf -> + ?vtrace("read_file -> read ok" + "~n Conf: ~p", [Conf]), + {ok, Conf} + catch + Error -> + ?vtrace("read_file -> read failed:" + "~n Error: ~p", [Error]), + Error + end. + +%% XXX remove + +%% read_file(Dir, FileName, Check, Default) -> +%% File = filename:join(Dir, FileName), +%% case file:read_file_info(File) of +%% {ok, _} -> +%% case (catch do_read(File, Check)) of +%% {ok, Conf} -> +%% {ok, Conf}; +%% Error -> +%% ?vtrace("read_file -> read failed:" +%% "~n Error: ~p", [Error]), +%% Error +%% end; +%% {error, Reason} -> +%% ?vlog("failed reading config from ~s: ~p", [FileName, Reason]), +%% {ok, Default} +%% end. + +%% read_file(Dir, FileName, Check) -> +%% File = filename:join(Dir, FileName), +%% case file:read_file_info(File) of +%% {ok, _} -> +%% case (catch do_read(File, Check)) of +%% {ok, Conf} -> +%% ?vtrace("read_file -> read ok" +%% "~n Conf: ~p", [Conf]), +%% {ok, Conf}; +%% Error -> +%% ?vtrace("read_file -> read failed:" +%% "~n Error: ~p", [Error]), +%% Error +%% end; +%% {error, Reason} -> +%% error_msg("failed reading config from ~s: ~p", [FileName, Reason]), +%% {error, {failed_reading, FileName, Reason}} +%% end. + +%% do_read(File, Check) -> +%% {ok, snmp_conf:read(File, Check)}. %%-------------------------------------------------------------------- @@ -2795,13 +2803,24 @@ handle_update_agent_info(TargetName, Info0) -> "~n TargetName: ~p" "~n Info0: ~p", [TargetName, Info0]), %% Verify info - try verify_agent_info(TargetName, Info0) of - {ok, Info} -> - do_update_agent_info(TargetName, Info); - Error -> - Error + try + verify_invalid(Info0, [user_id]), + %% If domain is part of the info, then use it. + %% If not, lookup what is already stored for + %% this agent and use that. + Info = + case lists:keysearch(tdomain, 1, Info0) of + {value, {tdomain, _}} -> + Info0; + false -> + {ok, TDomain} = + agent_info(TargetName, tdomain), + [{tdomain, TDomain}|Info0] + end, + verify_agent(Info), + do_update_agent_info(TargetName, Info) catch - throw:Error -> + Error -> Error; T:E -> {error, {failed_info_verification, Info0, T, E}} @@ -2997,7 +3016,7 @@ verify_mandatory(Conf, [Mand|Mands]) -> true -> verify_mandatory(Conf, Mands); false -> - throw({error, {missing_mandatory_config, Mand}}) + error({missing_mandatory_config, Mand}) end. verify_invalid(_, []) -> @@ -3007,99 +3026,22 @@ verify_invalid(Conf, [Inv|Invs]) -> false -> verify_invalid(Conf, Invs); true -> - throw({error, {illegal_config, Inv}}) + error({illegal_config, Inv}) end. - -verify_val(user_id, UserId) -> - {ok, UserId}; -verify_val(reg_type, RegType) - when (RegType =:= addr_port) orelse (RegType =:= target_name) -> - {ok, RegType}; -verify_val(tdomain = Item, snmpUDPDomain = _Domain) -> - verify_val(Item, transportDomainUdpIpv4); -verify_val(tdomain, Domain) -> - case lists:member(Domain, ?SUPPORTED_DOMAINS) of +verify_oneof(Conf, [Mand|Mands]) -> + case lists:keymember(Mand, 1, Conf) of true -> - {ok, Domain}; + ok; false -> - case lists:member(Domain, snmp_conf:all_domains()) of - true -> - error({unsupported_domain, Domain}); - false -> - error({unknown_domain, Domain}) + case Mands of + [] -> + error({missing_mandatory_config, Mand}); + _ -> + verify_oneof(Conf, Mands) end - end; -verify_val(address, {Domain, Addr0}) -> - case normalize_address(Domain, Addr0) of - {_A1, _A2, _A3, _A4} = Addr -> - {ok, Addr}; - {_A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8} = Addr -> - {ok, Addr}; - _ when is_list(Addr0) -> - case (catch snmp_conf:check_ip(Addr0)) of - ok -> - {ok, list_to_tuple(Addr0)}; - Err -> - Err - end; - _ -> - error({bad_address, Addr0}) - end; -verify_val(address, BadAddress) -> - error({bad_address, BadAddress}); -verify_val(port, Port) -> - case (catch snmp_conf:check_integer(Port, {gt, 0})) of - ok -> - {ok, Port}; - Err -> - Err - end; -verify_val(community, Comm) -> - case (catch snmp_conf:check_string(Comm)) of - ok -> - {ok, Comm}; - Err -> - Err - end; -verify_val(engine_id, discovery = EngineId) -> - {ok, EngineId}; -verify_val(engine_id, EngineId) -> - case (catch snmp_conf:check_string(EngineId)) of - ok -> - {ok, EngineId}; - Err -> - Err - end; -verify_val(timeout, Timeout) -> - (catch snmp_conf:check_timer(Timeout)); -verify_val(max_message_size, MMS) -> - case (catch snmp_conf:check_packet_size(MMS)) of - ok -> - {ok, MMS}; - Err -> - Err - end; -verify_val(version, V) - when (V =:= v1) orelse (V =:= v2) orelse (V =:= v3) -> - {ok, V}; -verify_val(version, BadVersion) -> - error({bad_version, BadVersion}); -verify_val(sec_model, Model) -> - (catch snmp_conf:check_sec_model(Model)); -verify_val(sec_name, Name) when is_list(Name) -> - case (catch snmp_conf:check_string(Name)) of - ok -> - {ok, Name}; - Err -> - Err - end; -verify_val(sec_name, BadName) -> - error({bad_sec_name, BadName}); -verify_val(sec_level, Level) -> - (catch snmp_conf:check_sec_level(Level)); -verify_val(Item, _) -> - {error, {unknown_item, Item}}. + end. + %%%------------------------------------------------------------------- diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index 953c94ab54..fe5ed6b755 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2012. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -93,7 +93,9 @@ reset(#state{v3 = V3}) -> %% section 4.2.1 in rfc2272) %%----------------------------------------------------------------- process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> + process_msg(Msg, Domain, {Addr, Port}, State, NoteStore, Logger). +process_msg(Msg, Domain, Address, State, NoteStore, Logger) -> inc(snmpInPkts), case (catch snmp_pdus:dec_message_only(binary_to_list(Msg))) of @@ -102,17 +104,17 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> #message{version = 'version-1', vsn_hdr = Community, data = Data} when State#state.v1 =:= true -> HS = ?empty_msg_size + length(Community), - process_v1_v2c_msg('version-1', NoteStore, Msg, - Domain, Addr, Port, - Community, Data, HS, Logger); + process_v1_v2c_msg( + 'version-1', NoteStore, Msg, Domain, Address, + Community, Data, HS, Logger); %% Version 2 #message{version = 'version-2', vsn_hdr = Community, data = Data} when State#state.v2c =:= true -> HS = ?empty_msg_size + length(Community), - process_v1_v2c_msg('version-2', NoteStore, Msg, - Domain, Addr, Port, - Community, Data, HS, Logger); + process_v1_v2c_msg( + 'version-2', NoteStore, Msg, Domain, Address, + Community, Data, HS, Logger); %% Version 3 #message{version = 'version-3', vsn_hdr = H, data = Data} @@ -122,7 +124,7 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> "~n msgFlags: ~p" "~n msgSecModel: ~p", [H#v3_hdr.msgID,H#v3_hdr.msgFlags,H#v3_hdr.msgSecurityModel]), - process_v3_msg(NoteStore, Msg, H, Data, Addr, Port, Logger); + process_v3_msg(NoteStore, Msg, H, Data, Address, Logger); %% Crap {'EXIT', {bad_version, Vsn}} -> @@ -148,32 +150,27 @@ process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> %%----------------------------------------------------------------- %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- -process_v1_v2c_msg(Vsn, _NoteStore, Msg, Domain, - Addr, Port, - Community, Data, HS, Log) -> +process_v1_v2c_msg( + Vsn, _NoteStore, Msg, Domain, Address, Community, Data, HS, Log) -> ?vdebug("process_v1_v2c_msg -> entry with" "~n Vsn: ~p" "~n Domain: ~p" - "~n Addr: ~p" - "~n Port: ~p" + "~n Address: ~p" "~n Community: ~p" - "~n HS: ~p", [Vsn, Domain, Addr, Port, Community, HS]), - + "~n HS: ~p", [Vsn, Domain, Address, Community, HS]), + {TDomain, TAddress} = try - begin - TD = snmp_conf:mk_tdomain(Domain), - TA = snmp_conf:mk_taddress(Domain, Addr, Port), - {TD, TA} - end + {snmp_conf:mk_tdomain(Domain), + snmp_conf:mk_taddress(Domain, Address)} catch throw:{error, TReason} -> throw({discarded, {badarg, Domain, TReason}}) end, Max = get_max_message_size(), - AgentMax = get_agent_max_message_size(Addr, Port), + AgentMax = get_agent_max_message_size(Address), PduMS = pdu_ms(Max, AgentMax, HS), ?vtrace("process_v1_v2c_msg -> PduMS: ~p", [PduMS]), @@ -213,13 +210,12 @@ sec_model('version-2') -> ?SEC_V2C. %% Handles a SNMPv3 Message, following the procedures in rfc2272, %% section 4.2 and 7.2 %%----------------------------------------------------------------- -process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) -> +process_v3_msg(NoteStore, Msg, Hdr, Data, Address, Log) -> + ?vdebug( + "process_v3_msg -> entry with~n" + " Hdr: ~p~n" + " Address: ~p", [Hdr, Address]), - ?vdebug("process_v3_msg -> entry with" - "~n Hdr: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Hdr, Addr, Port]), - %% 7.2.3 #v3_hdr{msgID = MsgID, msgMaxSize = MMS, @@ -352,8 +348,8 @@ process_v3_msg(NoteStore, Msg, Hdr, Data, Addr, Port, Log) -> %% 4.2.2.1.1 - we don't handle proxys yet => we only %% handle CtxEngineID to ourselves %% Check that we actually know of an agent with this - %% CtxEngineID and Addr/Port - case is_known_engine_id(CtxEngineID, Addr, Port) of + %% CtxEngineID and Address + case is_known_engine_id(CtxEngineID, Address) of true -> ?vtrace("and the agent EngineID (~p) " "is know to us", [CtxEngineID]), @@ -866,7 +862,7 @@ get_max_message_size() -> end. %% The the MMS of the agent -get_agent_max_message_size(Addr, Port) -> +get_agent_max_message_size({Addr, Port}) -> case snmpm_config:get_agent_engine_max_message_size(Addr, Port) of {ok, MMS} -> MMS; @@ -874,6 +870,14 @@ get_agent_max_message_size(Addr, Port) -> ?vlog("unknown agent: ~w:~w", [Addr, Port]), get_max_message_size() end. +%% get_agent_max_message_size(Addr, Port) -> +%% case snmpm_config:get_agent_engine_max_message_size(Addr, Port) of +%% {ok, MMS} -> +%% MMS; +%% _Error -> +%% ?vlog("unknown agent: ~w:~w", [Addr, Port]), +%% get_max_message_size() +%% end. %% Get "our" (manager) engine id get_engine_id() -> @@ -888,9 +892,12 @@ get_engine_id() -> get_agent_engine_id(Name) -> snmpm_config:get_agent_engine_id(Name). -is_known_engine_id(EngineID, Addr, Port) -> +is_known_engine_id(EngineID, {Addr, Port}) -> snmpm_config:is_known_engine_id(EngineID, Addr, Port). +%% is_known_engine_id(EngineID, Addr, Port) -> +%% snmpm_config:is_known_engine_id(EngineID, Addr, Port). + % get_agent_engine_id(Addr, Port) -> % case snmpm_config:get_agent_engine_id(Addr, Port) of % {ok, Id} -> diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index c52b4bb6fb..f85f1d3828 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -45,9 +45,9 @@ mk_tdomain/1, which_domain/1, check_ip/1, check_ip/2, - check_address/2, + check_address/2, check_address/3, check_taddress/2, - mk_taddress/2, mk_taddress/3, + mk_taddress/2, check_packet_size/1, @@ -146,38 +146,8 @@ read_files(Dir, [{FileName, Gen, Order, Check, Filter}|Files], Res) Gen(Dir, R) end, read_files(Dir, Files, [Filter(Confs)|Res]). -%% %% -%% %% XXX remove -%% %% -%% %% read_files(Dir, Files) -> Configs -%% %% Dir - string() - Full path to the config dir. -%% %% Files - [{Gen, Filter, Check, FileName}] -%% %% Gen - function/2 - In case of failure when reading the config file, -%% %% this function is called to either generate a -%% %% default file or issue the error. -%% %% Filter - function/1 - Filters all the config entries read from the file -%% %% Check - function/1 - Check each entry as they are read from the file. -%% %% FileName - string() - Name of the config file. -%% %% Configs - [config_entry()] -%% %% config_entry() - term() -%% -%% read_files(Dir, [{Gen, Filter, Check, FileName}|Files], Res) -%% when is_function(Filter) andalso -%% is_function(Check) andalso -%% is_list(FileName) -> -%% ?vdebug("read_files -> entry with" -%% "~n FileName: ~p", [FileName]), -%% File = filename:join(Dir, FileName), -%% case file:read_file_info(File) of -%% {ok, _} -> -%% Confs = read(File, Check), -%% read_files(Dir, Files, [Filter(Confs)|Res]); -%% {error, R} -> -%% ?vlog("failed reading file info for ~s: " -%% "~n ~p", [FileName, R]), -%% Gen(Dir, R), -%% read_files(Dir, Files, [Filter([])|Res]) -%% end. + + no_gen(_Dir, _R) -> []. no_order(_, _) -> true. @@ -185,6 +155,9 @@ no_filter(X) -> X. +read(File, Check) -> + read(File, fun no_order/2, Check). + %% Ret. Res | exit(Reason) read(File, Order, Check) when is_function(Order), is_function(Check) -> ?vdebug("read -> entry with~n" @@ -240,80 +213,29 @@ read_check(File, Check, [{StartLine, Row, EndLine}|Lines], State, Res) -> error({failed_check, File, StartLine, EndLine, Error}) end. - - -%% XXX remove - -%% Ret. Res | exit(Reason) -read(File, Check) when is_function(Check) -> - ?vdebug("read -> entry with" - "~n File: ~p", [File]), - - Fd = open_file(File), - - case loop(Fd, [], Check, 1, File) of - {error, Reason} -> - file:close(Fd), - error(Reason); - {ok, Res} -> - file:close(Fd), - Res - end. - open_file(File) -> case file:open(File, [read]) of - {ok, Fd} -> - Fd; - {error, Reason} -> - error({failed_open, File, Reason}) - end. - -loop(Fd, Res, Check, StartLine, File) -> - case do_read(Fd, "", StartLine) of - {ok, Row, EndLine} -> - ?vtrace("loop -> " - "~n Row: ~p" - "~n EndLine: ~p", [Row, EndLine]), - case (catch Check(Row)) of - ok -> - ?vtrace("loop -> ok", []), - loop(Fd, [Row | Res], Check, EndLine, File); - {ok, NewRow} -> - ?vtrace("loop -> ok: " - "~n NewRow: ~p", [NewRow]), - loop(Fd, [NewRow | Res], Check, EndLine, File); - {error, Reason} -> - ?vtrace("loop -> check error: " - "~n Reason: ~p", [Reason]), - {error, {failed_check, File, StartLine, EndLine, Reason}}; - Error -> - ?vtrace("loop -> check failure: " - "~n Error: ~p", [Error]), - {error, {failed_check, File, StartLine, EndLine, Error}} - end; - {error, Error, EndLine} -> - ?vtrace("loop -> read failure: " - "~n Error: ~p", [Error]), - {error, {failed_reading, File, StartLine, EndLine, Error}}; - {eof, _EndLine} -> - {ok, Res} + {ok, Fd} -> + Fd; + {error, Reason} -> + error({failed_open, File, Reason}) end. - do_read(Io, Prompt, StartLine) -> case io:request(Io, {get_until,Prompt,erl_scan,tokens,[StartLine]}) of - {ok, Toks, EndLine} -> - case erl_parse:parse_term(Toks) of - {ok, Term} -> - {ok, Term, EndLine}; - {error, {Line, erl_parse, Error}} -> - {error, {parse_error, Error}, Line} - end; - Other -> - Other + {ok, Toks, EndLine} -> + case erl_parse:parse_term(Toks) of + {ok, Term} -> + {ok, Term, EndLine}; + {error, {Line, erl_parse, Error}} -> + {error, {parse_error, Error}, Line} + end; + Other -> + Other end. + %%----------------------------------------------------------------- @@ -657,34 +579,12 @@ check_domain(Domain) -> %% --------- %% The values of Domain, Ip and Port has both been checked at this -%% point, so we dont need to do that again. - -mk_taddress(snmpUDPDomain, Address) -> +%% point, so we dont need to do that again, but this function is +%% also used on incoming packets from net_if so a little +%% check that net_if does not supply bad arguments is in order. +%% +mk_taddress(snmpUDPDomain, Address) -> % Legacy mk_taddress(transportDomainUdpIpv4, Address); -mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_list(Ip) -> - Ip ++ mk_bytes(Port); -mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_tuple(Ip) -> - tuple_to_list(Ip) ++ mk_bytes(Port); -mk_taddress(transportDomainUdpIpv4, IpPort) when is_list(IpPort) -> - IpPort; % Should be length 6 -mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_list(Ip) -> - Ip ++ mk_bytes(Port); -mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_tuple(Ip) -> - tuple_to_list(Ip) ++ mk_bytes(Port); -mk_taddress(transportDomainUdpIpv6, IpPort) when is_list(IpPort) -> - case IpPort of - [A0,A1,A2,A3,A4,A5,A6,A7,P] -> - [A0,A1,A2,A3,A4,A5,A6,A7] ++ mk_bytes(P); - [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] -> - [mk_word(A0, A1),mk_word(A2, A3), - mk_word(A4, A5),mk_word(A6, A7), - mk_word(A8, A9),mk_word(A10, A11), - mk_word(A12, A13),mk_word(A14, A15),P0,P1]; - _ -> - IpPort % Should already be 8 words and 2 bytes hence length 10 - end; -mk_taddress(Domain, Address) when is_atom(Domain) -> - erlang:error(badarg, [Domain,Address]); %% %% These are just for convenience mk_taddress(?snmpUDPDomain, Address) -> @@ -693,36 +593,96 @@ mk_taddress(?transportDomainUdpIpv4, Address) -> mk_taddress(transportDomainUdpIpv4, Address); mk_taddress(?transportDomainUdpIpv6, Address) -> mk_taddress(transportDomainUdpIpv6, Address); +%% +mk_taddress(transportDomainUdpIpv4 = Domain, Address) -> + case Address of + {Ip, Port} when tuple_size(Ip) =:= 4, is_integer(Port) -> + tuple_to_list(Ip) ++ mk_bytes(Port); + _ -> + erlang:error(badarg, [Domain,Address]) + end; +mk_taddress(transportDomainUdpIpv6 = Domain, Address) -> + case Address of + {Ip, Port} + when tuple_size(Ip) =:= 8, is_integer(Port) -> + tuple_to_list(Ip) ++ mk_bytes(Port); + _ -> + erlang:error(badarg, [Domain,Address]) + end; %% Bad domain mk_taddress(BadDomain, _) -> error({bad_domain, BadDomain}). -%% XXX remove +%% mk_taddress(snmpUDPDomain, Address) -> +%% mk_taddress(transportDomainUdpIpv4, Address); +%% %% mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_list(Ip) -> +%% %% Ip ++ mk_bytes(Port); +%% mk_taddress(transportDomainUdpIpv4, {Ip, Port}) +%% when tuple_size(Ip) =:= 4 -> +%% tuple_to_list(Ip) ++ mk_bytes(Port); +%% %% mk_taddress(transportDomainUdpIpv4, IpPort) when is_list(IpPort) -> +%% %% IpPort; % Should be length 6 +%% %% mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_list(Ip) -> +%% %% Ip ++ mk_bytes(Port); +%% mk_taddress(transportDomainUdpIpv6, {Ip, Port}) +%% when tuple_size(Ip) == 8 -> +%% tuple_to_list(Ip) ++ mk_bytes(Port); +%% %% mk_taddress(transportDomainUdpIpv6, IpPort) when is_list(IpPort) -> +%% %% case IpPort of +%% %% [A0,A1,A2,A3,A4,A5,A6,A7,P] -> +%% %% [A0,A1,A2,A3,A4,A5,A6,A7] ++ mk_bytes(P); +%% %% [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] -> +%% %% [mk_word(A0, A1),mk_word(A2, A3), +%% %% mk_word(A4, A5),mk_word(A6, A7), +%% %% mk_word(A8, A9),mk_word(A10, A11), +%% %% mk_word(A12, A13),mk_word(A14, A15),P0,P1]; +%% %% _ -> +%% %% IpPort % Should already be 8 words and 2 bytes hence length 10 +%% %% end; +%% mk_taddress(Domain, []) -> %% Used for empty mask +%% []; +%% mk_taddress(Domain, Address) -> +%% erlang:error(badarg, [Domain,Address]); +%% %% +%% %% These are just for convenience +%% mk_taddress(?snmpUDPDomain, Address) -> +%% mk_taddress(snmpUDPDomain, Address); +%% mk_taddress(?transportDomainUdpIpv4, Address) -> +%% mk_taddress(transportDomainUdpIpv4, Address); +%% mk_taddress(?transportDomainUdpIpv6, Address) -> +%% mk_taddress(transportDomainUdpIpv6, Address); +%% %% Bad domain +%% mk_taddress(BadDomain, _) -> +%% error({bad_domain, BadDomain}). -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}). + + +%% %% XXX remove + +%% 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}). %% --------- @@ -779,59 +739,128 @@ check_ip(BadDomain, _X) -> %% Check a configuration term field from a file to see if it %% can be fed to mk_taddress/2. -check_address(Domain, Address) +check_address(Domain, Address, DefaultPort) -> + case check_address_ip(Domain, Address) of + false -> + case check_address_ip_port(Domain, Address) of + false -> + error({invalid_address, {Domain, Address}}); + true -> + {ok, Address}; + FixedAddress -> + {ok, FixedAddress} + end; + true -> + {ok, {Address, DefaultPort}}; + FixedIp -> + {ok, {FixedIp, DefaultPort}} + end. + +check_address(Domain, Address) -> + case check_address_ip_port(Domain, Address) of + false -> + error({invalid_address, {Domain, Address}}); + true -> + {ok, Address}; + FixedAddress -> + {ok, FixedAddress} + end. + +%% -> IP +check_address_ip(Domain, Address) when Domain =:= snmpUDPDomain; Domain =:= transportDomainUdpIpv4 -> case Address of %% Erlang native format - {{A0, A1, A2, A3}, P} - when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P) -> - ok; + {A0, A1, A2, A3} + when ?is_ipv4_addr(A0, A1, A2, A3) -> + true; %% Erlangish format - {[A0,A1,A2,A3], P} - when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P) -> - ok; + [A0,A1,A2,A3] + when ?is_ipv4_addr(A0, A1, A2, A3) -> + {A0, A1, A2, A3}; + _ -> + false + end; +check_address_ip(transportDomainUdpIpv6, Address) -> + case Address of + %% Erlang native format + {A0, A1, A2, A3, A4, A5, A6, A7} + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) -> + true; + %% Erlangish format + [A0,A1,A2,A3,A4,A5,A6,A7] + when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) -> + {A0, A1, A2, A3, A4, A5, A6, A7}; + %% SNMP standards format + [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15] + when ?is_ipv6_addr( + A0, A1, A2, A3, A4, A5, A6, A7, + A8, A9, A10, A11, A12, A13, A14, A15) -> + {mk_word(A0, A1), mk_word(A2, A3), + mk_word(A4, A5), mk_word(A6, A7), + mk_word(A8, A9), mk_word(A10, A11), + mk_word(A12, A13), mk_word(A14, A15)}; + _ -> + false + end. + +%% -> {IP, Port} +check_address_ip_port(Domain, Address) + when Domain =:= snmpUDPDomain; + Domain =:= transportDomainUdpIpv4 -> + case Address of + {IP, Port} when ?is_word(Port) -> + case check_address_ip(Domain, IP) of + false -> + false; + true -> + Address; + FixedIP -> + {FixedIP, Port} + end; %% SNMP standards format [A0,A1,A2,A3,P0,P1] when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) -> - ok; + {{A0, A1, A2, A3}, mk_word(P0, P1)}; _ -> - error({invalid_address, {Domain, Address}}) + false end; -check_address(transportDomainUdpIpv6 = Domain, Address) -> +check_address_ip_port(transportDomainUdpIpv6 = Domain, Address) -> case Address of - %% Erlang native format - {{A0, A1, A2, A3, A4, A5, A6, A7}, P} - when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), - ?is_word(P) -> - ok; - %% Erlangish format - {[A0,A1,A2,A3,A4,A5,A6,A7], P} - when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), - ?is_word(P) -> - ok; + {IP, Port} when ?is_word(Port) -> + case check_address_ip(Domain, IP) of + false -> + false; + true -> + Address; + FixedIP -> + {FixedIP, Port} + end; %% Erlang friendly list format [A0,A1,A2,A3,A4,A5,A6,A7,P] when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), ?is_word(P) -> - ok; + {{A0, A1, A2, A3, A4, A5, A6, A7}, P}; %% Strange hybrid format with port as bytes [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1] when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7), ?is_word(P0, P1) -> - ok; + {{A0, A1, A2, A3, A4, A5, A6, A7}, mk_word(P0, P1)}; %% SNMP standards format [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] when ?is_ipv6_addr( A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15), ?is_word(P0, P1) -> - ok; + {{mk_word(A0, A1), mk_word(A2, A3), + mk_word(A4, A5), mk_word(A6, A7), + mk_word(A8, A9), mk_word(A10, A11), + mk_word(A12, A13), mk_word(A14, A15)}, + mk_word(P0, P1)}; _ -> - error({invalid_address, {Domain, Address}}) - end; -check_address(BadDomain, _) -> - error({invalid_domain, BadDomain}). + false + end. -- cgit v1.2.3 From 373d9fa059875a2d68251c485968d3aa78e830b4 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 17 Apr 2014 16:29:51 +0200 Subject: wip-all-regression-tests-but-one-manager --- lib/snmp/src/agent/snmp_target_mib.erl | 15 ++++++++------- lib/snmp/src/manager/snmpm_config.erl | 19 +++++++++++-------- lib/snmp/src/misc/snmp_conf.erl | 16 ++++++++++------ lib/snmp/src/misc/snmp_config.erl | 4 +++- lib/snmp/test/snmp_agent_test_lib.erl | 7 +++++-- lib/snmp/test/snmp_conf_test.erl | 6 +++--- lib/snmp/test/snmp_manager_config_test.erl | 18 +++++++++--------- lib/snmp/test/snmp_manager_test.erl | 2 +- 8 files changed, 50 insertions(+), 37 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index cff1e253c3..3bcfd469e6 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -263,7 +263,7 @@ check_target_addr( TagList, Params, EngineId, Mask, MMS]), snmp_conf:check_string(Name,{gt,0}), snmp_conf:check_domain(Domain), - NAddress = snmp_conf:check_address(Domain, Address), + NAddress = check_address(Domain, Address), snmp_conf:check_integer(Timeout, {gte, 0}), snmp_conf:check_integer(RetryCount, {gte,0}), snmp_conf:check_string(TagList), @@ -290,19 +290,20 @@ check_address(Domain, Address) -> case snmp_conf:check_address(Domain, Address) of ok -> Address; - {ok, FixedAddress} -> - FixedAddress + {ok, NAddress} -> + NAddress end. -check_mask(_Domain, []) -> - []; +check_mask(_Domain, [] = Mask) -> + Mask; check_mask(Domain, Mask) -> try check_address(Domain, Mask) catch - {error, {invalid_address, Info}} -> - error({invalid_mask, Info}) + {error, {bad_address, Info}} -> + error({bad_mask, Info}) end. + %%----------------------------------------------------------------- %% TargetParams %% {Name, MPModel, SecurityModel, SecurityName, SecurityLevel} diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index af2262d988..ea962575d5 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -1702,7 +1702,10 @@ verify_agent(Conf) -> verify_agent(lists:sort(fun order_agent/2, Conf), []). verify_agent([], VerifiedConf) -> - list:reverse(VerifiedConf); + Ret = lists:reverse(VerifiedConf), + ?vdebug("verify_agent -> returns:~n" + " ~p", [Ret]), + Ret; verify_agent([{_Item, _} = Entry|Conf], VerifiedConf) -> %% verify_invalid(VerifiedConf, [_Item]), % Check for duplicate verify_agent(Conf, VerifiedConf, Entry); @@ -1744,11 +1747,11 @@ verify_agent(Conf, VerifiedConf, {address = Item, Address} = Entry) -> {ok, {NAddress,FakePort}} -> verify_agent(Conf, [{Item, NAddress}|VC]); {ok, _} -> - error({invalid_address, {TDomain, Address}}) + error({bad_address, {TDomain, Address}}) end; verify_agent(Conf, VerifiedConf, {port, Port} = Entry) -> verify_invalid(VerifiedConf, [taddress]), - ok = snmp_conf:check_address(snmpUDPDomain, {{0, 0, 0, 0}, Port}), + _ = snmp_conf:check_address(snmpUDPDomain, {{0, 0, 0, 0}, Port}), verify_agent(Conf, [Entry|VerifiedConf]); verify_agent(Conf, VerifiedConf, {Item, Val} = Entry) -> case verify_agent_entry(Item, Val) of @@ -1846,7 +1849,7 @@ check_user_config({Id, Mod, Data, DefaultAgentConfig} = _User) end; check_user_config({Id, _Mod, _Data, DefaultAgentConfig}) when (Id =/= ?DEFAULT_USER) -> - {error, {bad_default_agent_config, DefaultAgentConfig}}; + error({bad_default_agent_config, DefaultAgentConfig}); check_user_config({Id, _Mod, _Data, _DefaultAgentConfig}) -> error({bad_user_id, Id}); check_user_config(User) -> @@ -2146,7 +2149,7 @@ check_manager_config({engine_id, EngineID}) -> check_manager_config({max_message_size, Max}) -> snmp_conf:check_integer(Max, {gte, 484}); check_manager_config(Conf) -> - {error, {unknown_config, Conf}}. + error({unknown_config, Conf}). check_mandatory_manager_config(Conf) -> @@ -2709,7 +2712,7 @@ handle_register_agent(UserId, TargetName, Config) -> %% dirty crossref stuff ?vtrace("handle_register_agent -> lookup address", []), {ok, Addr} = agent_info(TargetName, address), - ?vtrace("handle_register_agent -> Addr: ~p, lookup Port", + ?vtrace("handle_register_agent -> Addr: ~p, lookup Port", [Addr]), {ok, Port} = agent_info(TargetName, port), ?vtrace("handle_register_agent -> register cross-ref fix", []), @@ -2737,7 +2740,7 @@ handle_register_agent(UserId, TargetName, Config) -> do_handle_register_agent(_TargetName, []) -> ok; do_handle_register_agent(TargetName, [{Item, Val}|Rest]) -> - ?vtrace("handle_register_agent -> entry with" + ?vtrace("do_handle_register_agent -> entry with" "~n TargetName: ~p" "~n Item: ~p" "~n Val: ~p" @@ -2746,7 +2749,7 @@ do_handle_register_agent(TargetName, [{Item, Val}|Rest]) -> ok -> do_handle_register_agent(TargetName, Rest); {error, Reason} -> - ?vtrace("handle_register_agent -> failed updating ~p" + ?vtrace("do_handle_register_agent -> failed updating ~p" "~n Item: ~p" "~n Reason: ~p", [Item, Reason]), ets:match_delete(snmpm_agent_table, {TargetName, '_'}), diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index f85f1d3828..3fefe3e8cd 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -596,6 +596,8 @@ mk_taddress(?transportDomainUdpIpv6, Address) -> %% mk_taddress(transportDomainUdpIpv4 = Domain, Address) -> case Address of + [] -> % Empty mask + []; {Ip, Port} when tuple_size(Ip) =:= 4, is_integer(Port) -> tuple_to_list(Ip) ++ mk_bytes(Port); _ -> @@ -603,6 +605,8 @@ mk_taddress(transportDomainUdpIpv4 = Domain, Address) -> end; mk_taddress(transportDomainUdpIpv6 = Domain, Address) -> case Address of + [] -> % Empty mask + []; {Ip, Port} when tuple_size(Ip) =:= 8, is_integer(Port) -> tuple_to_list(Ip) ++ mk_bytes(Port); @@ -710,14 +714,14 @@ check_ip(X) -> check_ip(snmpUDPDomain, X) -> check_ip(transportDomainUdpIpv4, X); -check_ip(transportDomainUdpIpv4, X) -> +check_ip(transportDomainUdpIpv4 = Domain, X) -> case X of [A,B,C,D] when ?is_ipv4_addr(A, B, C, D) -> ok; _ -> - error({invalid_ip_address, X}) + error({bad_address, {Domain, X}}) end; -check_ip(transportDomainUdpIpv6, X) -> +check_ip(transportDomainUdpIpv6 = Domain, X) -> case X of [A,B,C,D,E,F,G,H] when ?is_ipv6_addr(A, B, C, D, E, F, G, H) -> @@ -727,7 +731,7 @@ check_ip(transportDomainUdpIpv6, X) -> A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> ok; _ -> - error({invalid_ip_address, X}) + error({bad_address, {Domain, X}}) end; %% check_ip(BadDomain, _X) -> @@ -744,7 +748,7 @@ check_address(Domain, Address, DefaultPort) -> false -> case check_address_ip_port(Domain, Address) of false -> - error({invalid_address, {Domain, Address}}); + error({bad_address, {Domain, Address}}); true -> {ok, Address}; FixedAddress -> @@ -759,7 +763,7 @@ check_address(Domain, Address, DefaultPort) -> check_address(Domain, Address) -> case check_address_ip_port(Domain, Address) of false -> - error({invalid_address, {Domain, Address}}); + error({bad_address, {Domain, Address}}); true -> {ok, Address}; FixedAddress -> diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index ec6b2ac7e4..12467a1abf 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -2446,7 +2446,9 @@ write_config_file(Dir, FileName, Verify, Write) throw:Error -> Error; T:E -> - {error, {failed_write, Dir, FileName, T, E}} + {error, + {failed_write, Dir, FileName, + {T, E, erlang:get_stacktrace()}}} end. diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index bfedd7558c..050ae0126d 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -1536,8 +1536,11 @@ rewrite_target_addr_conf(Dir, NewPort) -> end, ?line [TrapAddr|Addrs] = - snmp_conf:read(TAFile, - fun(R) -> rewrite_target_addr_conf_check(R) end), + snmp_conf:read( + TAFile, + fun(R, S) -> + {rewrite_target_addr_conf_check(R),S} + end), ?DBG("rewrite_target_addr_conf -> TrapAddr: ~p",[TrapAddr]), diff --git a/lib/snmp/test/snmp_conf_test.erl b/lib/snmp/test/snmp_conf_test.erl index c4341d8d7e..5c8acb48a5 100644 --- a/lib/snmp/test/snmp_conf_test.erl +++ b/lib/snmp/test/snmp_conf_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% Copyright Ericsson AB 2003-2014. 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 @@ -401,7 +401,7 @@ check_taddress(Config) when is_list(Config) -> ok. verify_taddress(Val) -> - case (catch snmp_conf:check_taddress(Val)) of + case (catch snmp_conf:check_taddress(snmpUDPDomain, Val)) of {error, Reason} -> ?FAIL({verify_taddress, Val, Reason}); ok -> @@ -409,7 +409,7 @@ verify_taddress(Val) -> end. verify_not_taddress(Val) -> - case (catch snmp_conf:check_taddress(Val)) of + case (catch snmp_conf:check_taddress(snmpUDPDomain, Val)) of ok -> ?FAIL({verify_taddress, Val}); {error, _Reason} -> diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl index 7b9924b83c..3cdb2cfcbe 100644 --- a/lib/snmp/test/snmp_manager_config_test.erl +++ b/lib/snmp/test/snmp_manager_config_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -693,7 +693,7 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) -> "arne_anka", "4001", "500", "\"bmkEngine\""), ?line {error, Reason12} = config_start(Opts), p("start failed (as expected): ~p", [Reason12]), - ?line {failed_check, _, _, 2, {invalid_ip_address, _}} = Reason12, + ?line {failed_check, _, _, 2, {bad_address, _}} = Reason12, await_config_not_running(), %% -- @@ -702,7 +702,7 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) -> "9999", "4001", "500", "\"bmkEngine\""), ?line {error, Reason13} = config_start(Opts), p("start failed (as expected): ~p", [Reason13]), - ?line {failed_check, _, _, 2, {invalid_ip_address, _}} = Reason13, + ?line {failed_check, _, _, 2, {bad_address, _}} = Reason13, await_config_not_running(), %% -- @@ -1073,7 +1073,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) -> case config_start(Opts) of {error, Reason53} -> p("start failed (as expected): ~p", [Reason53]), - ?line {failed_check, _, _, _, {invalid_ip_address, _}} = Reason53, + ?line {failed_check, _, _, _, {bad_address, _}} = Reason53, await_config_not_running(); OK_53 -> exit({error, {unexpected_success, "53", OK_53}}) @@ -1086,7 +1086,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) -> case config_start(Opts) of {error, Reason54} -> p("start failed (as expected): ~p", [Reason54]), - ?line {failed_check, _, _, _, {invalid_ip_address, _}} = Reason54, + ?line {failed_check, _, _, _, {bad_address, _}} = Reason54, await_config_not_running(); OK_54 -> exit({error, {unexpected_success, "54", OK_54}}) @@ -1098,7 +1098,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) -> write_agents_conf(ConfDir, [Agent55]), ?line {error, Reason55} = config_start(Opts), p("start failed (as expected): ~p", [Reason55]), - ?line {failed_check, _, _, _, {invalid_ip_address, _}} = Reason55, + ?line {failed_check, _, _, _, {bad_address, _}} = Reason55, await_config_not_running(), %% -- @@ -1107,7 +1107,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) -> write_agents_conf(ConfDir, [Agent61]), ?line {error, Reason61} = config_start(Opts), p("start failed (as expected): ~p", [Reason61]), - ?line {failed_check, _, _, _, {invalid_integer, _}} = Reason61, + ?line {failed_check, _, _, _, {bad_address, _}} = Reason61, await_config_not_running(), %% -- @@ -1116,7 +1116,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) -> write_agents_conf(ConfDir, [Agent62]), ?line {error, Reason62} = config_start(Opts), p("start failed (as expected): ~p", [Reason62]), - ?line {failed_check, _, _, _, {invalid_integer, _}} = Reason62, + ?line {failed_check, _, _, _, {bad_address, _}} = Reason62, await_config_not_running(), %% -- @@ -1125,7 +1125,7 @@ start_with_invalid_agents_conf_file1(Conf) when is_list(Conf) -> write_agents_conf(ConfDir, [Agent63]), ?line {error, Reason63} = config_start(Opts), p("start failed (as expected): ~p", [Reason63]), - ?line {failed_check, _, _, _, {invalid_integer, _}} = Reason63, + ?line {failed_check, _, _, _, {bad_address, _}} = Reason63, await_config_not_running(), %% -- diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 3a654a2805..90f9ef2026 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -1508,7 +1508,7 @@ register_agent3(Config) when is_list(Config) -> TargetName2 = "agent3", ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName2, [{tdomain, transportDomainUdpIpv6}, - {address, LocalHost}, + {address, {0,0,0,0,0,0,0,1}}, {port, 5002}, {engine_id, "agentEngineId-2"}]), TargetName3 = "agent4", -- cgit v1.2.3 From 16b194c40f8a9ce2e12b82afd7d44bc782a80795 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 25 Apr 2014 16:26:13 +0200 Subject: wip --- lib/snmp/src/manager/snmpm_config.erl | 662 +++++++++++++++++++++------------- lib/snmp/src/misc/snmp_conf.erl | 52 ++- lib/snmp/test/snmp_agent_test_lib.erl | 6 +- 3 files changed, 449 insertions(+), 271 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index ea962575d5..61f402111e 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -190,7 +190,11 @@ register_user(UserId, UserMod, UserData, DefaultAgentConfig) when (UserId =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) -> case (catch verify_user_behaviour(UserMod)) of ok -> - Config = default_agent_config(DefaultAgentConfig), + {ok, SystemDefaultAgentConfig} = agent_info(), + Config = + ensure_config(SystemDefaultAgentConfig, + DefaultAgentConfig), +%% Config = default_agent_config(DefaultAgentConfig), call({register_user, UserId, UserMod, UserData, Config}); Error -> Error @@ -201,19 +205,19 @@ register_user(UserId, _UserMod, _UserData, DefaultAgentConfig) register_user(UserId, _, _, _) -> {error, {bad_user_id, UserId}}. -default_agent_config(DefaultAgentConfig) -> - {ok, SystemDefaultAgentConfig} = agent_info(), - default_agent_config(SystemDefaultAgentConfig, DefaultAgentConfig). - -default_agent_config([], DefaultAgentConfig) -> - DefaultAgentConfig; -default_agent_config([{Key, _} = Entry|T], DefaultAgentConfig) -> - case lists:keysearch(Key, 1, DefaultAgentConfig) of - {value, _} -> - default_agent_config(T, DefaultAgentConfig); - false -> - default_agent_config(T, [Entry|DefaultAgentConfig]) - end. +%% default_agent_config(DefaultAgentConfig) -> +%% {ok, SystemDefaultAgentConfig} = agent_info(), +%% default_agent_config(SystemDefaultAgentConfig, DefaultAgentConfig). + +%% default_agent_config([], DefaultAgentConfig) -> +%% DefaultAgentConfig; +%% default_agent_config([{Key, _} = Entry|T], DefaultAgentConfig) -> +%% case lists:keymember(Key, 1, DefaultAgentConfig) of +%% true -> +%% default_agent_config(T, DefaultAgentConfig); +%% false -> +%% default_agent_config(T, [Entry|DefaultAgentConfig]) +%% end. verify_user_behaviour(UserMod) -> @@ -282,7 +286,7 @@ do_user_info(_UserId, BadItem) -> %% :- %% This is intended for backward compatibility and therefor has %% only support for IPv4 addresses and *no* other transport domain. -mk_target_name(Addr0, Port, Config) when is_list(Config) -> +mk_target_name(Addr, Port, Config) when is_list(Config) -> Version = case lists:keysearch(version, 1, Config) of {value, {_, V}} -> @@ -290,16 +294,13 @@ mk_target_name(Addr0, Port, Config) when is_list(Config) -> false -> select_lowest_supported_version() end, - case normalize_address(Addr0) of + case normalize_address(Addr) of {A, B, C, D} -> lists:flatten( io_lib:format("~w.~w.~w.~w:~w-~w", [A, B, C, D, Port, Version])); - [A, B, C, D] -> - lists:flatten( - io_lib:format("~w.~w.~w.~w:~w-~w", [A, B, C, D, Port, Version])); _ -> lists:flatten( - io_lib:format("~p:~w-~w", [Addr0, Port, Version])) + io_lib:format("~p:~w-~w", [Addr, Port, Version])) end. select_lowest_supported_version() -> @@ -337,9 +338,9 @@ register_agent(UserId, TargetName, Config0) %% 4) Check that the manager is capable of using the selected version try verify_mandatory(Config0, [engine_id, reg_type]), - verify_oneof(Config0, [address, taddress]), - verify_invalid(Config0, [user_id]), - Config = verify_agent(Config0), + verify_someof(Config0, [address, taddress]), + verify_illegal(Config0, [user_id]), + Config = verify_agent_config(Config0), Vsns = versions(), Vsn = which_version(Config), verify_version(Vsn, Vsns), @@ -380,9 +381,8 @@ unregister_agent(UserId, TargetName) -> call({unregister_agent, UserId, TargetName}). %% This is the old style agent unregistration (using Addr and Port). -unregister_agent(UserId, Addr0, Port) -> - Addr = normalize_address(Addr0), - case do_agent_info(Addr, Port, target_name) of +unregister_agent(UserId, Addr, Port) -> + case do_agent_info(normalize_address(Addr), Port, target_name) of {ok, TargetName} -> unregister_agent(UserId, TargetName); Error -> @@ -407,9 +407,8 @@ agent_info(TargetName, Item) -> {error, not_found} end. -agent_info(Addr0, Port, Item) -> - Addr = normalize_address(Addr0), - do_agent_info(Addr, Port, Item). +agent_info(Addr, Port, Item) -> + do_agent_info(normalize_address(Addr), Port, Item). do_agent_info(Addr, Port, target_name = Item) -> case ets:lookup(snmpm_agent_table, {Addr, Port, Item}) of @@ -427,6 +426,19 @@ do_agent_info(Addr, Port, Item) -> end. +ensure_agent_info(_, [], Info) -> + Info; +ensure_agent_info(TargetName, [Item|Items], Info) -> + case lists:keymember(Item, 1, Info) of + true -> + ensure_agent_info(TargetName, Items, Info); + false -> + {ok, Value} = agent_info(TargetName, Item), + ensure_agent_info(TargetName, Items, [{Item, Value}|Info]) + end. + + + which_agents() -> which_agents('_'). @@ -670,7 +682,7 @@ verify_usm_user_config(EngineID, Name, Config) -> try begin verify_mandatory(Config, []), - verify_invalid(Config, [engine_id, name]), + verify_illegal(Config, [engine_id, name]), verify_usm_user_config2(EngineID, Name, Config) end catch @@ -1003,7 +1015,11 @@ do_init(Opts) -> %% -- Prio (optional) -- Prio = get_opt(priority, Opts, normal), ets:insert(snmpm_config_table, {prio, Prio}), - process_flag(priority, Prio), + try process_flag(priority, Prio) + catch + error:badarg -> + error({invalid_priority,Prio}) + end, %% -- Server (optional) -- ServerOpts = get_opt(server, Opts, []), @@ -1436,7 +1452,9 @@ verify_versions([]) -> ok; verify_versions([Vsn|Vsns]) -> verify_version(Vsn), - verify_versions(Vsns). + verify_versions(Vsns); +verify_versions(Vsns) -> + error({invalid_versions, Vsns}). verify_version(v1) -> ok; @@ -1559,65 +1577,94 @@ init_agent_default() -> %% The purpose of the default_agent is only to have a place %% to store system wide default values related to agents. %% + AgentDefaultConfig = + [{port, ?DEFAULT_AGENT_PORT}, % Port + {timeout, 10000}, % Timeout + {max_message_size, 484}, % Max message (packet) size + {version, v2}, % MPModel + {sec_model, v2c}, % SecModel + {sec_name, "initial"}, % SecName + {sec_level, noAuthPriv}, % SecLevel + {community, "all-rigthts"}], % Community + do_update_agent_info(default_agent, AgentDefaultConfig). - %% Port - init_agent_default(port, ?DEFAULT_AGENT_PORT), +%% %% Port +%% init_agent_default(port, ?DEFAULT_AGENT_PORT), - %% Timeout - init_agent_default(timeout, 10000), +%% %% Timeout +%% init_agent_default(timeout, 10000), - %% Max message (packet) size - init_agent_default(max_message_size, 484), +%% %% Max message (packet) size +%% init_agent_default(max_message_size, 484), - %% MPModel - init_agent_default(version, v2), +%% %% MPModel +%% init_agent_default(version, v2), - %% SecModel - init_agent_default(sec_model, v2c), +%% %% SecModel +%% init_agent_default(sec_model, v2c), - %% SecName - init_agent_default(sec_name, "initial"), +%% %% SecName +%% init_agent_default(sec_name, "initial"), - %% SecLevel - init_agent_default(sec_level, noAuthNoPriv), +%% %% SecLevel +%% init_agent_default(sec_level, noAuthNoPriv), - %% Community - init_agent_default(community, "all-rights"), - ok. +%% %% Community +%% init_agent_default(community, "all-rights"), +%% ok. -init_agent_default(Item, Val) when Item =/= user_id -> - case do_update_agent_info(default_agent, Item, Val) of - ok -> - ok; - {error, Reason} -> - error(Reason) - end. +%% init_agent_default(Item, Val) when Item =/= user_id -> +%% case do_update_agent_info(default_agent, Item, Val) of +%% ok -> +%% ok; +%% {error, Reason} -> +%% error(Reason) +%% end. +%% read_agents_config_file(Dir) -> +%% Verify = fun check_agent_config2/1, +%% case read_file(Dir, "agents.conf", Verify, []) of +%% {ok, Conf} -> +%% Conf; +%% Error -> +%% ?vlog("agent config error: ~p", [Error]), +%% throw(Error) +%% end. + +%% check_agent_config2(Agent) -> +%% case (catch check_agent_config(Agent)) of +%% {ok, {UserId, TargetName, Conf, Version}} -> +%% {ok, Vsns} = system_info(versions), +%% case lists:member(Version, Vsns) of +%% true -> +%% {ok, {UserId, TargetName, Conf}}; +%% false -> +%% error({version_not_supported_by_manager, +%% Version, Vsns}) +%% end; +%% Err -> +%% throw(Err) +%% end. read_agents_config_file(Dir) -> - Verify = fun check_agent_config2/1, - case read_file(Dir, "agents.conf", Verify, []) of - {ok, Conf} -> - Conf; - Error -> + Order = fun snmp_conf:no_order/2, + Check = fun check_agent_config/2, + try read_file(Dir, "agents.conf", Order, Check, []) + catch + throw:Error -> ?vlog("agent config error: ~p", [Error]), - throw(Error) + erlang:raise(throw, Error, erlang:get_stacktrace()) end. -check_agent_config2(Agent) -> - case (catch check_agent_config(Agent)) of - {ok, {UserId, TargetName, Conf, Version}} -> - {ok, Vsns} = system_info(versions), - case lists:member(Version, Vsns) of - true -> - {ok, {UserId, TargetName, Conf}}; - false -> - error({version_not_supported_by_manager, - Version, Vsns}) - end; - Err -> - throw(Err) +check_agent_config(Agent, State) -> + {ok, {UserId, TargetName, Conf, Version}} = check_agent_config(Agent), + {ok, Vsns} = system_info(versions), + case lists:member(Version, Vsns) of + true -> + {{ok, {UserId, TargetName, Conf}}, State}; + false -> + error({version_not_supported_by_manager, Version, Vsns}) end. %% For backward compatibility @@ -1668,7 +1715,7 @@ check_agent_config( {sec_name, SecName}, {sec_level, SecLevel} ], - {ok, {UserId, TargetName, verify_agent(Conf), Version}}. + {ok, {UserId, TargetName, verify_agent_config(Conf), Version}}. @@ -1690,30 +1737,63 @@ init_agent_config({UserId, TargetName, Config}) -> -%% Sort tdomain first -order_agent({Item, _}, {Item, _}) -> - true; %% Less than or equal -order_agent(_, {tdomain, _}) -> - false; %% Greater than -order_agent(_, _) -> - true. %% Less than or equal +%% Sort tdomain first then port to ensure both comes before taddress +order_agent({Item1, _}, {Item2, _}) -> + if Item1 == Item2 -> + true; % Item1 == Item2 + Item2 =:= tdomain -> + false; % Item1 > tdomain + Item2 =:= port -> + if Item1 =:= tdomain -> + true; % tdomain < port + true -> + false % Item1 > port + end; + true -> + true % Item1 < Item 2 + end. -verify_agent(Conf) -> - verify_agent(lists:sort(fun order_agent/2, Conf), []). +fix_agent_config(Conf) -> + ?vdebug("fix_agent_config -> entry with~n~n" + " Conf: ~p", [Conf]), + fix_agent_config(lists:sort(fun order_agent/2, Conf), []). -verify_agent([], VerifiedConf) -> +fix_agent_config([], FixedConf) -> + Ret = lists:reverse(FixedConf), + ?vdebug("fix_agent_config -> returns:~n" + " ~p", [Ret]), + Ret; +fix_agent_config([{taddress = Item, Address} = Entry|Conf], FixedConf) -> + {value, {tdomain, TDomain}} = lists:keysearch(tdomain, 1, FixedConf), + {value, {port, DefaultPort}} = lists:keysearch(port, 1, FixedConf), + case snmp_conf:check_address(TDomain, Address, DefaultPort) of + ok -> + fix_agent_config(Conf, [Entry|FixedConf]); + {ok, NAddress} -> + fix_agent_config(Conf, [{Item, NAddress}|FixedConf]) + end; +fix_agent_config([Entry|Conf], FixedConf) -> + fix_agent_config(Conf, [Entry|FixedConf]). + + + +verify_agent_config(Conf) -> + verify_agent_config(lists:sort(fun order_agent/2, Conf), []). + +verify_agent_config([], VerifiedConf) -> Ret = lists:reverse(VerifiedConf), - ?vdebug("verify_agent -> returns:~n" + ?vdebug("verify_agent_config -> returns:~n" " ~p", [Ret]), Ret; -verify_agent([{_Item, _} = Entry|Conf], VerifiedConf) -> -%% verify_invalid(VerifiedConf, [_Item]), % Check for duplicate - verify_agent(Conf, VerifiedConf, Entry); -verify_agent([Bad|_], _VerifiedConf) -> +verify_agent_config([{Item, _} = Entry|Conf], VerifiedConf) -> + verify_illegal(VerifiedConf, [Item]), % Duplicates are hereby illegal + verify_agent_config(Conf, VerifiedConf, Entry); +verify_agent_config([Bad|_], _VerifiedConf) -> error({bad_agent_config, Bad}). -verify_agent(Conf, VerifiedConf, {taddress = Item, TAddress} = Entry) -> - verify_invalid(VerifiedConf, [address,port]), +verify_agent_config( + Conf, VerifiedConf, {taddress = Item, Address} = Entry) -> + verify_illegal(VerifiedConf, [address]), {TDomain, VC} = case lists:keysearch(tdomain, 1, VerifiedConf) of {value, {tdomain,TD}} -> @@ -1723,42 +1803,36 @@ verify_agent(Conf, VerifiedConf, {taddress = Item, TAddress} = Entry) -> TD = default_transport_domain(), {TD, [{tdomain, TD}|VerifiedConf]} end, - case snmp_conf:check_address(TDomain, TAddress) of + case snmp_conf:check_address(TDomain, Address, 0) of ok -> - verify_agent(Conf, [Entry|VC]); + verify_agent_config(Conf, [Entry|VC]); {ok, NAddress} -> - verify_agent(Conf, [{Item, NAddress}|VC]) + verify_agent_config(Conf, [{Item, NAddress}|VC]) end; -verify_agent(Conf, VerifiedConf, {address = Item, Address} = Entry) -> - verify_invalid(VerifiedConf, [taddress]), +verify_agent_config(Conf, VerifiedConf, {address, Address}) -> + Item = taddress, + verify_illegal(VerifiedConf, [Item]), {TDomain, VC} = case lists:keysearch(tdomain, 1, VerifiedConf) of - {value, {tdomain,TD}} -> + {value, {tdomain, TD}} -> {TD, VerifiedConf}; _ -> %% Insert tdomain since it is missing TD = default_transport_domain(), {TD, [{tdomain, TD}|VerifiedConf]} end, - FakePort = make_ref(), - case snmp_conf:check_address(TDomain, Address, FakePort) of + case snmp_conf:check_address(TDomain, Address, 0) of ok -> - verify_agent(Conf, [Entry|VC]); - {ok, {NAddress,FakePort}} -> - verify_agent(Conf, [{Item, NAddress}|VC]); - {ok, _} -> - error({bad_address, {TDomain, Address}}) + verify_agent_config(Conf, [{Item, Address}|VC]); + {ok, NAddress} -> + verify_agent_config(Conf, [{Item, NAddress}|VC]) end; -verify_agent(Conf, VerifiedConf, {port, Port} = Entry) -> - verify_invalid(VerifiedConf, [taddress]), - _ = snmp_conf:check_address(snmpUDPDomain, {{0, 0, 0, 0}, Port}), - verify_agent(Conf, [Entry|VerifiedConf]); -verify_agent(Conf, VerifiedConf, {Item, Val} = Entry) -> +verify_agent_config(Conf, VerifiedConf, {Item, Val} = Entry) -> case verify_agent_entry(Item, Val) of ok -> - verify_agent(Conf, [Entry|VerifiedConf]); + verify_agent_config(Conf, [Entry|VerifiedConf]); {ok, NewVal} -> - verify_agent(Conf, [{Item, NewVal}|VerifiedConf]) + verify_agent_config(Conf, [{Item, NewVal}|VerifiedConf]) end. verify_agent_entry(user_id, _UserId) -> @@ -1773,6 +1847,8 @@ verify_agent_entry(reg_type, RegType) -> end; verify_agent_entry(tdomain, TDomain) -> snmp_conf:check_domain(TDomain); +verify_agent_entry(port, Port) -> + snmp_conf:check_port(Port); verify_agent_entry(community, Comm) -> snmp_conf:check_string(Comm); verify_agent_entry(engine_id, EngineId) -> @@ -1810,17 +1886,26 @@ verify_agent_entry(Item, _) -> +%% read_users_config_file(Dir) -> +%% Verify = fun check_user_config/1, +%% case read_file(Dir, "users.conf", Verify, []) of +%% {ok, Conf} -> +%% Conf; +%% Error -> +%% ?vlog("failure reading users config file: ~n ~p", [Error]), +%% throw(Error) +%% end. + read_users_config_file(Dir) -> - Verify = fun check_user_config/1, - case read_file(Dir, "users.conf", Verify, []) of - {ok, Conf} -> - Conf; - Error -> + Order = fun snmp_conf:no_order/2, + Check = fun (User, State) -> {check_user_config(User), State} end, + try read_file(Dir, "users.conf", Order, Check, []) + catch + throw:Error -> ?vlog("failure reading users config file: ~n ~p", [Error]), - throw(Error) + erlang:raise(throw, Error, erlang:get_stacktrace()) end. - check_user_config({Id, Mod, Data}) -> ?vtrace("check_user_config -> entry with" "~n Id: ~p" @@ -1889,9 +1974,14 @@ verify_user({Id, UserMod, UserData, DefaultAgentConfig}) case (catch verify_user_behaviour(UserMod)) of ok -> try + {ok, SystemDefaultAgentConfig} = agent_info(), Config = - default_agent_config( + ensure_config( + SystemDefaultAgentConfig, verify_default_agent_config(DefaultAgentConfig)), +%% Config = +%% default_agent_config( +%% verify_default_agent_config(DefaultAgentConfig)), {ok, #user{id = Id, mod = UserMod, data = UserData, @@ -1913,10 +2003,10 @@ verify_user({Id, _, _, _}) -> verify_default_agent_config(Conf) -> try - verify_invalid( + verify_illegal( Conf, [user_id, engine_id, address, tdomain, taddress]), - verify_agent(Conf) + verify_agent_config(Conf) catch Error -> ?vdebug("verify_default_agent_config -> throw" @@ -1924,14 +2014,19 @@ verify_default_agent_config(Conf) -> error({bad_default_agent_config, Error}) end. +%% read_usm_config_file(Dir) -> +%% Verify = fun check_usm_user_config/1, +%% case read_file(Dir, "usm.conf", Verify, []) of +%% {ok, Conf} -> +%% Conf; +%% Error -> +%% throw(Error) +%% end. + read_usm_config_file(Dir) -> - Verify = fun check_usm_user_config/1, - case read_file(Dir, "usm.conf", Verify, []) of - {ok, Conf} -> - Conf; - Error -> - throw(Error) - end. + Order = fun snmp_conf:no_order/2, + Check = fun (User, State) -> {check_usm_user_config(User), State} end, + read_file(Dir, "usm.conf", Order, Check, []). %% Identity-function check_usm_user_config({EngineId, Name, @@ -2113,21 +2208,38 @@ is_crypto_supported(Func) -> snmp_misc:is_crypto_supported(Func). +%% read_manager_config_file(Dir) -> +%% Verify = fun check_manager_config/1, +%% case read_file(Dir, "manager.conf", Verify) of +%% {ok, Conf} -> +%% ?d("read_manager_config_file -> ok: " +%% "~n Conf: ~p", [Conf]), +%% %% If the address is not specified, then we assume +%% %% it should be the local host. +%% %% If the address is not possible to determine +%% %% that way, then we give up... +%% verify_mandatory(Conf, [port,engine_id,max_message_size]), +%% ensure_config(default_manager_config(), Conf); +%% %% check_mandatory_manager_config(Conf), +%% %% ensure_manager_config(Conf); +%% Error -> +%% throw(Error) +%% end. + read_manager_config_file(Dir) -> - Verify = fun check_manager_config/1, - case read_file(Dir, "manager.conf", Verify) of - {ok, Conf} -> - ?d("read_manager_config_file -> ok: " - "~n Conf: ~p", [Conf]), - %% If the address is not specified, then we assume - %% it should be the local host. - %% If the address is not possible to determine - %% that way, then we give up... - check_mandatory_manager_config(Conf), - ensure_manager_config(Conf); - Error -> - throw(Error) - end. + Order = fun snmp_conf:no_order/2, + Check = fun (Entry, State) -> {check_manager_config(Entry), State} end, + Conf = read_file(Dir, "manager.conf", Order, Check), + ?d("read_manager_config_file -> ok: " + "~n Conf: ~p", [Conf]), + %% If the address is not specified, then we assume + %% it should be the local host. + %% If the address is not possible to determine + %% that way, then we give up... + verify_mandatory(Conf, [port,engine_id,max_message_size]), + ensure_config(default_manager_config(), Conf). + + default_manager_config() -> {ok, HostName} = inet:gethostname(), @@ -2152,33 +2264,33 @@ check_manager_config(Conf) -> error({unknown_config, Conf}). -check_mandatory_manager_config(Conf) -> - Mand = [port, engine_id, max_message_size], - check_mandatory_manager_config(Mand, Conf). +%% check_mandatory_manager_config(Conf) -> +%% Mand = [port, engine_id, max_message_size], +%% check_mandatory_manager_config(Mand, Conf). -check_mandatory_manager_config([], _Conf) -> - ok; -check_mandatory_manager_config([Item|Mand], Conf) -> - case lists:keysearch(Item, 1, Conf) of - false -> - error({missing_mandatory_manager_config, Item}); - _ -> - check_mandatory_manager_config(Mand, Conf) - end. +%% check_mandatory_manager_config([], _Conf) -> +%% ok; +%% check_mandatory_manager_config([Item|Mand], Conf) -> +%% case lists:keysearch(Item, 1, Conf) of +%% false -> +%% error({missing_mandatory_manager_config, Item}); +%% _ -> +%% check_mandatory_manager_config(Mand, Conf) +%% end. -ensure_manager_config(Confs) -> - ensure_manager_config(Confs, default_manager_config()). - -ensure_manager_config(Confs, []) -> - Confs; -ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) -> - case lists:keysearch(Key, 1, Confs) of - false -> - ensure_manager_config([DefKeyVal|Confs], Defs); - {value, _Conf} -> - ensure_manager_config(Confs, Defs) - end. +%% ensure_manager_config(Confs) -> +%% ensure_manager_config(Confs, default_manager_config()). + +%% ensure_manager_config(Confs, []) -> +%% Confs; +%% ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) -> +%% case lists:keysearch(Key, 1, Confs) of +%% false -> +%% ensure_manager_config([DefKeyVal|Confs], Defs); +%% {value, _Conf} -> +%% ensure_manager_config(Confs, Defs) +%% end. % ensure_manager_config([], Defs, Confs) -> % Confs ++ Defs; @@ -2191,41 +2303,61 @@ ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) -> % ensure_manager_config(Confs, Defs, [Conf|Acc]) % end. - - -read_file(Dir, FileName, Verify, Default) -> - File = filename:join(Dir, FileName), - case file:read_file_info(File) of - {ok, _} -> - read_file(File, Verify); - {error, Reason} -> +read_file(Dir, FileName, Order, Check, Default) -> + try snmp_conf:read(filename:join(Dir, FileName), Order, Check) + catch + {error, Reason} when element(1, Reason) =:= failed_open -> ?vlog("failed reading config from ~s: ~p", [FileName, Reason]), - {ok, Default} + Default end. -read_file(Dir, FileName, Verify) -> - File = filename:join(Dir, FileName), - case file:read_file_info(File) of - {ok, _} -> - read_file(File, Verify); - {error, Reason} -> +read_file(Dir, FileName, Order, Check) -> + try snmp_conf:read(filename:join(Dir, FileName), Order, Check) + catch + throw:{error, Reason} = Error + when element(1, Reason) =:= failed_open -> error_msg("failed reading config from ~s: ~p", [FileName, Reason]), - {error, {failed_reading, FileName, Reason}} + erlang:raise(throw, Error, erlang:get_stacktrace()) end. -read_file(File, Verify) -> - Check = fun (Config, State) -> {Verify(Config), State} end, - try snmp_conf:read(File, Check) of - Conf -> - ?vtrace("read_file -> read ok" - "~n Conf: ~p", [Conf]), - {ok, Conf} - catch - Error -> - ?vtrace("read_file -> read failed:" - "~n Error: ~p", [Error]), - Error - end. + + + + + +%% read_file(Dir, FileName, Verify, Default) -> +%% File = filename:join(Dir, FileName), +%% case file:read_file_info(File) of +%% {ok, _} -> +%% read_file(File, Verify); +%% {error, Reason} -> +%% ?vlog("failed reading config from ~s: ~p", [FileName, Reason]), +%% {ok, Default} +%% end. + +%% read_file(Dir, FileName, Verify) -> +%% File = filename:join(Dir, FileName), +%% case file:read_file_info(File) of +%% {ok, _} -> +%% read_file(File, Verify); +%% {error, Reason} -> +%% error_msg("failed reading config from ~s: ~p", [FileName, Reason]), +%% {error, {failed_reading, FileName, Reason}} +%% end. + +%% read_file(File, Verify) -> +%% Check = fun (Config, State) -> {Verify(Config), State} end, +%% try snmp_conf:read(File, Check) of +%% Conf -> +%% ?vtrace("read_file -> read ok" +%% "~n Conf: ~p", [Conf]), +%% {ok, Conf} +%% catch +%% Error -> +%% ?vtrace("read_file -> read failed:" +%% "~n Error: ~p", [Error]), +%% Error +%% end. %% XXX remove @@ -2695,30 +2827,48 @@ handle_register_agent(UserId, TargetName, Config) -> "~n Config: ~p", [UserId, TargetName, Config]), case (catch agent_info(TargetName, user_id)) of {error, _} -> - ?vtrace("handle_register_agent -> user_id not found in config", []), + ?vtrace( + "handle_register_agent -> user_id not found in config", []), case ets:lookup(snmpm_user_table, UserId) of [#user{default_agent_config = DefConfig}] -> - ?vtrace("handle_register_agent -> " - "~n DefConfig: ~p", [DefConfig]), - %% First, insert this users default config - ?vtrace("handle_register_agent -> store default config", []), - do_handle_register_agent(TargetName, DefConfig), - %% Second, insert the config for this agent - ?vtrace("handle_register_agent -> store config", []), - do_handle_register_agent(TargetName, - [{user_id, UserId}|Config]), + ?vtrace("handle_register_agent ->~n" + " DefConfig: ~p", [DefConfig]), + FixedConfig = + fix_agent_config(ensure_config(DefConfig, Config)), + ?vtrace("handle_register_agent ->~n" + " FixedConfig: ~p", [FixedConfig]), + do_handle_register_agent( + TargetName, [{user_id, UserId}|FixedConfig]), %% - %% And now for some (backward compatibillity) + %% And now for some (backward compatibillity) %% dirty crossref stuff - ?vtrace("handle_register_agent -> lookup address", []), - {ok, Addr} = agent_info(TargetName, address), - ?vtrace("handle_register_agent -> Addr: ~p, lookup Port", - [Addr]), - {ok, Port} = agent_info(TargetName, port), - ?vtrace("handle_register_agent -> register cross-ref fix", []), - ets:insert(snmpm_agent_table, + {value, {taddress, {Addr, Port}}} = + lists:keysearch(taddress, 1, FixedConfig), + ?vtrace( + "handle_register_agent -> register cross-ref fix", []), + ets:insert(snmpm_agent_table, {{Addr, Port, target_name}, TargetName}), %% + +%% %% First, insert this users default config +%% ?vtrace("handle_register_agent -> store default config", []), +%% do_handle_register_agent(TargetName, DefConfig), +%% %% Second, insert the config for this agent +%% ?vtrace("handle_register_agent -> store config", []), +%% do_handle_register_agent(TargetName, +%% [{user_id, UserId}|Config]), +%% %% +%% %% And now for some (backward compatibillity) +%% %% dirty crossref stuff +%% ?vtrace("handle_register_agent -> lookup taddress", []), +%% {ok, {Addr, Port} = TAddress} = +%% agent_info(TargetName, taddress), +%% ?vtrace("handle_register_agent -> taddress: ~p", +%% [TAddress]), +%% ?vtrace("handle_register_agent -> register cross-ref fix", []), +%% ets:insert(snmpm_agent_table, +%% {{Addr, Port, target_name}, TargetName}), +%% %% ok; _ -> {error, {not_found, UserId}} @@ -2773,8 +2923,7 @@ handle_unregister_agent(UserId, TargetName) -> %% %% And now for some (backward compatibillity) %% dirty crossref stuff - {ok, Addr} = agent_info(TargetName, address), - {ok, Port} = agent_info(TargetName, port), + {ok, {Addr, Port}} = agent_info(TargetName, taddress), ets:delete(snmpm_agent_table, {Addr, Port, target_name}), %% ets:match_delete(snmpm_agent_table, {{TargetName, '_'}, '_'}), @@ -2801,32 +2950,26 @@ handle_update_agent_info(UserId, TargetName, Info) -> Error end. -handle_update_agent_info(TargetName, Info0) -> +handle_update_agent_info(TargetName, Info) -> ?vtrace("handle_update_agent_info -> entry with" "~n TargetName: ~p" - "~n Info0: ~p", [TargetName, Info0]), + "~n Info: ~p", [TargetName, Info]), %% Verify info try - verify_invalid(Info0, [user_id]), - %% If domain is part of the info, then use it. + verify_illegal(Info, [user_id]), + %% If port or domain is part of the info, then use it. %% If not, lookup what is already stored for %% this agent and use that. - Info = - case lists:keysearch(tdomain, 1, Info0) of - {value, {tdomain, _}} -> - Info0; - false -> - {ok, TDomain} = - agent_info(TargetName, tdomain), - [{tdomain, TDomain}|Info0] - end, - verify_agent(Info), - do_update_agent_info(TargetName, Info) - catch + do_update_agent_info( + TargetName, + fix_agent_config( + verify_agent_config( + ensure_agent_info(TargetName, [port,tdomain], Info)))) + catch Error -> Error; T:E -> - {error, {failed_info_verification, Info0, T, E}} + {error, {failed_info_verification, Info, T, E}} end. handle_update_agent_info(UserId, TargetName, Item, Val) -> @@ -2838,6 +2981,9 @@ handle_update_agent_info(UserId, TargetName, Item, Val) -> handle_update_agent_info(TargetName, [{Item, Val}]). do_update_agent_info(TargetName, Info) -> + ?vtrace("do_update_agent_info -> entry with~n" + " TargetName: ~p~n" + " Info: ~p", [TargetName,Info]), InsertItem = fun({Item, Val}) -> ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}) @@ -3022,17 +3168,17 @@ verify_mandatory(Conf, [Mand|Mands]) -> error({missing_mandatory_config, Mand}) end. -verify_invalid(_, []) -> +verify_illegal(_, []) -> ok; -verify_invalid(Conf, [Inv|Invs]) -> +verify_illegal(Conf, [Inv|Invs]) -> case lists:member(Inv, Conf) of false -> - verify_invalid(Conf, Invs); + verify_illegal(Conf, Invs); true -> error({illegal_config, Inv}) end. -verify_oneof(Conf, [Mand|Mands]) -> +verify_someof(Conf, [Mand|Mands]) -> case lists:keymember(Mand, 1, Conf) of true -> ok; @@ -3041,10 +3187,20 @@ verify_oneof(Conf, [Mand|Mands]) -> [] -> error({missing_mandatory_config, Mand}); _ -> - verify_oneof(Conf, Mands) + verify_someof(Conf, Mands) end end. +ensure_config([], Config) -> + Config; +ensure_config([Default|Defaults], Config) -> + case lists:keymember(element(1, Default), 1, Config) of + true -> + ensure_config(Defaults, Config); + false -> + ensure_config(Defaults, [Default|Config]) + end. + %%%------------------------------------------------------------------- @@ -3203,30 +3359,16 @@ init_mini_mib_elems(MibName, [_|T], Res) -> %%---------------------------------------------------------------------- normalize_address(Addr) -> - normalize_address(snmpUDPDomain, Addr). - -normalize_address(snmpUDPDomain, Addr) -> - normalize_address(transportDomainUdpIpv4, Addr); - -normalize_address(Domain, Addr) -> - case inet:getaddr(Addr, td2fam(Domain)) of - {ok, Addr2} -> - Addr2; - _ when is_list(Addr) -> - case (catch snmp_conf:check_ip(Domain, Addr)) of - ok -> - list_to_tuple(Addr); - _ -> - Addr - end; + try snmp_conf:check_address_no_port(snmpUDPDomain, Addr) of + ok -> + Addr; + {ok, NAddr} -> + NAddr + catch _ -> - Addr + Addr end. -td2fam(transportDomainUdpIpv4) -> inet; -td2fam(transportDomainUdpIpv6) -> inet6. - - %%---------------------------------------------------------------------- call(Req) -> diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 3fefe3e8cd..d8a19c7137 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -45,6 +45,7 @@ mk_tdomain/1, which_domain/1, check_ip/1, check_ip/2, + check_address_no_port/2, check_port/1, check_address/2, check_address/3, check_taddress/2, mk_taddress/2, @@ -155,7 +156,8 @@ no_filter(X) -> X. -read(File, Check) -> +read(File, Verify) -> + Check = fun (Row, State) -> {Verify(Row), State} end, read(File, fun no_order/2, Check). %% Ret. Res | exit(Reason) @@ -740,32 +742,70 @@ check_ip(BadDomain, _X) -> %% --------- +%% check_address_default_port(Domain, Address) -> +%% case check_address_ip(Domain, Address) of +%% false -> +%% case check_address_ip_port(Domain, Address) of +%% false -> +%% error({bad_address, {Domain, Address}}); +%% _ -> +%% ok +%% end; +%% _ -> +%% ok +%% end. + +check_address_no_port(Domain, Address) -> + case check_address_ip(Domain, Address) of + false -> + error({bad_address, {Domain, Address}}); + true -> + ok; + FixedIP -> + {ok, FixedIP} + end. + +check_port(Port) when ?is_word(Port) -> + ok; +check_port(Port) -> + error({bad_port, Port}). + %% Check a configuration term field from a file to see if it -%% can be fed to mk_taddress/2. +%% can be fixed to be fed to mk_taddress/2. check_address(Domain, Address, DefaultPort) -> + %% If Address does not contain Port or contains Port =:= 0 + %% create an address containing DefaultPort case check_address_ip(Domain, Address) of false -> case check_address_ip_port(Domain, Address) of false -> error({bad_address, {Domain, Address}}); true -> - {ok, Address}; + case Address of + {IP, 0} -> + {ok, {IP, DefaultPort}}; + _ -> + ok + end; + {FixedIP, 0} -> + {ok, {FixedIP, DefaultPort}}; FixedAddress -> {ok, FixedAddress} end; true -> {ok, {Address, DefaultPort}}; - FixedIp -> - {ok, {FixedIp, DefaultPort}} + FixedIP -> + {ok, {FixedIP, DefaultPort}} end. check_address(Domain, Address) -> + %% Address has to contain Port case check_address_ip_port(Domain, Address) of false -> error({bad_address, {Domain, Address}}); true -> - {ok, Address}; + ok; FixedAddress -> {ok, FixedAddress} end. diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 050ae0126d..e12a282a34 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -1536,11 +1536,7 @@ rewrite_target_addr_conf(Dir, NewPort) -> end, ?line [TrapAddr|Addrs] = - snmp_conf:read( - TAFile, - fun(R, S) -> - {rewrite_target_addr_conf_check(R),S} - end), + snmp_conf:read(TAFile, fun rewrite_target_addr_conf_check/1), ?DBG("rewrite_target_addr_conf -> TrapAddr: ~p",[TrapAddr]), -- cgit v1.2.3 From abbd9936144da7bcff9b4819785e597455ac7f35 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 30 Apr 2014 16:47:05 +0200 Subject: wip: Rewrite manager net_if process --- lib/snmp/src/manager/snmpm.erl | 33 +- lib/snmp/src/manager/snmpm_config.erl | 116 +++-- lib/snmp/src/manager/snmpm_mpd.erl | 2 +- lib/snmp/src/manager/snmpm_net_if.erl | 291 ++++++------ lib/snmp/src/manager/snmpm_net_if_filter.erl | 52 ++- lib/snmp/src/manager/snmpm_net_if_mt.erl | 306 +++++++------ lib/snmp/src/manager/snmpm_server.erl | 660 ++++++++++++++------------- lib/snmp/src/manager/snmpm_user.erl | 23 +- lib/snmp/src/manager/snmpm_user_default.erl | 16 +- lib/snmp/src/misc/snmp_conf.erl | 59 +-- lib/snmp/test/snmp_manager_test.erl | 2 +- 11 files changed, 844 insertions(+), 716 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index c97b635fc6..cf272c5504 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -379,21 +379,26 @@ register_agent(UserId, Addr) -> register_agent(UserId, Addr, ?DEFAULT_AGENT_PORT, []). %% Backward compatibility -register_agent(UserId, Addr, Port, Config0) -> +register_agent(UserId, Domain, Address, Config0) when is_atom(Domain) -> case lists:keymember(target_name, 1, Config0) of false -> - TargetName = mk_target_name(Addr, Port, Config0), - Config = [{reg_type, addr_port}, - {address, Addr}, {port, Port} | Config0], + TargetName = mk_target_name(Domain, Address, Config0), + Config = + [{reg_type, addr_port}, + {tdomain, Domain}, {taddress, Address} | Config0], do_register_agent(UserId, TargetName, ensure_engine_id(Config)); true -> {value, {_, TargetName}} = lists:keysearch(target_name, 1, Config0), Config1 = lists:keydelete(target_name, 1, Config0), - Config2 = [{reg_type, addr_port}, - {address, Addr}, {port, Port} | Config1], + Config2 = + [{reg_type, addr_port}, + {tdomain, Domain}, {taddress, Address} | Config1], register_agent(UserId, TargetName, ensure_engine_id(Config2)) - end. + end; +register_agent(UserId, Ip, Port, Config) when is_integer(Port) -> + {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + register_agent(UserId, Domain, Address, Config). unregister_agent(UserId, TargetName) when is_list(TargetName) -> snmpm_config:unregister_agent(UserId, TargetName); @@ -402,8 +407,8 @@ unregister_agent(UserId, TargetName) when is_list(TargetName) -> unregister_agent(UserId, Addr) -> unregister_agent(UserId, Addr, ?DEFAULT_AGENT_PORT). -unregister_agent(UserId, Addr, Port) -> - case target_name(Addr, Port) of +unregister_agent(UserId, DomainIp, AddressPort) -> + case target_name(DomainIp, AddressPort) of {ok, TargetName} -> unregister_agent(UserId, TargetName); Error -> @@ -1264,11 +1269,11 @@ format_vb_value(Prefix, _Type, Val) -> %% --- Internal utility functions --- %% -target_name(Addr) -> - target_name(Addr, ?DEFAULT_AGENT_PORT). +target_name(Ip) -> + target_name(Ip, ?DEFAULT_AGENT_PORT). -target_name(Addr, Port) -> - snmpm_config:agent_info(Addr, Port, target_name). +target_name(DomainIp, AddressPort) -> + snmpm_config:agent_info(DomainIp, AddressPort, target_name). mk_target_name(Addr, Port, Config) -> snmpm_config:mk_target_name(Addr, Port, Config). diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 61f402111e..088f0c7fc8 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -286,7 +286,8 @@ do_user_info(_UserId, BadItem) -> %% :- %% This is intended for backward compatibility and therefor has %% only support for IPv4 addresses and *no* other transport domain. -mk_target_name(Addr, Port, Config) when is_list(Config) -> +mk_target_name(Domain, Address, Config) + when is_atom(Domain), is_list(Config) -> Version = case lists:keysearch(version, 1, Config) of {value, {_, V}} -> @@ -294,15 +295,27 @@ mk_target_name(Addr, Port, Config) when is_list(Config) -> false -> select_lowest_supported_version() end, - case normalize_address(Addr) of - {A, B, C, D} -> + try fix_address(Domain, Address) of + {{A, B, C, D}, P} -> lists:flatten( - io_lib:format("~w.~w.~w.~w:~w-~w", [A, B, C, D, Port, Version])); - _ -> + io_lib:format( + "~w.~w.~w.~w:~w-~w", + [A, B, C, D, P, Version])); + {{A, B, C, D, E, F, G, H}, P} -> lists:flatten( - io_lib:format("~p:~w-~w", [Addr, Port, Version])) - end. - + io_lib:format( + "[~.16b:~.16b:~.16b:~.16b:~.16b:~.16b:~.16b:~.16b]:~w-~w", + [A, B, C, D, E, F, G, H, P, Version])) + catch + _ -> + lists:flatten( + io_lib:format("~p-~w", [Address, Version])) + end; +mk_target_name(Ip, Port, Config) + when is_integer(Port), is_list(Config) -> + {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + mk_target_name(Domain, Address, Config). + select_lowest_supported_version() -> {ok, Versions} = system_info(versions), select_lowest_supported_version([v1, v2, v3], Versions). @@ -381,14 +394,33 @@ unregister_agent(UserId, TargetName) -> call({unregister_agent, UserId, TargetName}). %% This is the old style agent unregistration (using Addr and Port). -unregister_agent(UserId, Addr, Port) -> - case do_agent_info(normalize_address(Addr), Port, target_name) of +unregister_agent(UserId, Domain, Address) when is_atom(Domain) -> + try fix_address(Domain, Address) of + NAddress -> + do_unregister_agent(UserId, Domain, NAddress) + catch + _ -> + {error, not_found} + end; +unregister_agent(UserId, Ip, Port) when is_integer(Port) -> + try snmp_conf:fix_domain_address(Ip, Port) of + {Domain, Address} -> + do_unregister_agent(UserId, Domain, Address) + catch + _ -> + {error, not_found} + end. + +do_unregister_agent(UserId, Domain, Address) -> + case do_agent_info(Domain, Address, target_name) of {ok, TargetName} -> unregister_agent(UserId, TargetName); Error -> Error end. + + agent_info() -> agent_info(?DEFAULT_TARGETNAME, all). @@ -407,18 +439,32 @@ agent_info(TargetName, Item) -> {error, not_found} end. -agent_info(Addr, Port, Item) -> - do_agent_info(normalize_address(Addr), Port, Item). +agent_info(Domain, Address, Item) when is_atom(Domain) -> + try fix_address(Domain, Address) of + NAddress -> + do_agent_info(Domain, NAddress, Item) + catch + _ -> + {error, not_found} + end; +agent_info(Ip, Port, Item) -> + try snmp_conf:fix_domain_address(Ip, Port) of + {Domain, Address} -> + do_agent_info(Domain, Address, Item) + catch + _ -> + {error, not_found} + end. -do_agent_info(Addr, Port, target_name = Item) -> - case ets:lookup(snmpm_agent_table, {Addr, Port, Item}) of +do_agent_info(Domain, Address, target_name = Item) -> + case ets:lookup(snmpm_agent_table, {Domain, Address, Item}) of [{_, Val}] -> {ok, Val}; [] -> {error, not_found} end; -do_agent_info(Addr, Port, Item) -> - case do_agent_info(Addr, Port, target_name) of +do_agent_info(Domain, Address, Item) -> + case do_agent_info(Domain, Address, target_name) of {ok, TargetName} -> agent_info(TargetName, Item); Error -> @@ -1672,24 +1718,24 @@ check_agent_config( {UserId, TargetName, Community, Ip, Port, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}) -> - TDomain = default_transport_domain(), + {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), check_agent_config( - UserId, TargetName, Community, TDomain, {Ip, Port}, + UserId, TargetName, Community, Domain, Address, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel); check_agent_config( - {UserId, TargetName, Community, TDomain, Ip, Port, + {UserId, TargetName, Community, Domain, Ip, Port, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}) -> check_agent_config( - UserId, TargetName, Community, TDomain, {Ip, Port}, + UserId, TargetName, Community, Domain, {Ip, Port}, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel); check_agent_config(Agent) -> error({bad_agent_config, Agent}). check_agent_config( - UserId, TargetName, Comm, TDomain, TAddress, + UserId, TargetName, Comm, Domain, Address, EngineId, Timeout, MMS, Version, SecModel, SecName, SecLevel) -> ?vdebug("check_agent_config -> entry with" @@ -1704,8 +1750,8 @@ check_agent_config( %% the property tdomain is needed. Conf = [{reg_type, target_name}, - {tdomain, TDomain}, - {taddress, TAddress}, + {tdomain, Domain}, + {taddress, Address}, {community, Comm}, {engine_id, EngineId}, {timeout, Timeout}, @@ -2842,12 +2888,14 @@ handle_register_agent(UserId, TargetName, Config) -> %% %% And now for some (backward compatibillity) %% dirty crossref stuff - {value, {taddress, {Addr, Port}}} = + {value, {_, Domain}} = + lists:keysearch(tdomain, 1, FixedConfig), + {value, {_, Address}} = lists:keysearch(taddress, 1, FixedConfig), ?vtrace( "handle_register_agent -> register cross-ref fix", []), ets:insert(snmpm_agent_table, - {{Addr, Port, target_name}, TargetName}), + {{Domain, Address, target_name}, TargetName}), %% %% %% First, insert this users default config @@ -2923,8 +2971,9 @@ handle_unregister_agent(UserId, TargetName) -> %% %% And now for some (backward compatibillity) %% dirty crossref stuff - {ok, {Addr, Port}} = agent_info(TargetName, taddress), - ets:delete(snmpm_agent_table, {Addr, Port, target_name}), + {ok, Domain} = agent_info(TargetName, tdomain), + {ok, Address} = agent_info(TargetName, taddress), + ets:delete(snmpm_agent_table, {Domain, Address, target_name}), %% ets:match_delete(snmpm_agent_table, {{TargetName, '_'}, '_'}), ok; @@ -3358,15 +3407,12 @@ init_mini_mib_elems(MibName, [_|T], Res) -> %%---------------------------------------------------------------------- -normalize_address(Addr) -> - try snmp_conf:check_address_no_port(snmpUDPDomain, Addr) of +fix_address(Domain, Address) -> + case snmp_conf:check_address(Domain, Address) of ok -> - Addr; - {ok, NAddr} -> - NAddr - catch - _ -> - Addr + Address; + {ok, NAddress} -> + NAddress end. %%---------------------------------------------------------------------- diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index fe5ed6b755..27f0336bc1 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -21,7 +21,7 @@ -export([init/1, - process_msg/7, + process_msg/7, process_msg/6, generate_msg/5, generate_response_msg/4, next_msg_id/0, diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index 4d6bd9aa33..39e239f2a2 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -27,9 +27,9 @@ -export([ start_link/2, stop/1, - send_pdu/6, % Backward compatibillity - send_pdu/7, % Backward compatibillity - send_pdu/8, + send_pdu/6, % Backward compatibility + send_pdu/7, % Partly backward compatibility + send_pdu/8, % Backward compatibility inform_response/4, @@ -99,30 +99,31 @@ start_link(Server, NoteStore) -> stop(Pid) -> call(Pid, stop). -send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) -> - send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO). - -send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) -> +send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort) -> + send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort, ?DEFAULT_EXTRA_INFO). + +send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo) + when is_record(Pdu, pdu), is_atom(Domain) -> + ?d("send_pdu -> entry with~n" + " Pid: ~p~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain: ~p~n" + " Address: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Address]), + cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}); +send_pdu(Pid, Pdu, Vsn, MsgData, Ip, Port, ExtraInfo) -> Domain = snmpm_config:default_transport_domain(), - send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo). - -send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo) - when is_record(Pdu, pdu) -> - ?d("send_pdu -> entry with" - "~n Pid: ~p" - "~n Pdu: ~p" - "~n Vsn: ~p" - "~n MsgData: ~p" - "~n Domain: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]), - cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}). + send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo). + +send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) -> + send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo). note_store(Pid, NoteStore) -> call(Pid, {note_store, NoteStore}). -inform_response(Pid, Ref, Addr, Port) -> - cast(Pid, {inform_response, Ref, Addr, Port}). +inform_response(Pid, Ref, Domain, Address) -> + cast(Pid, {inform_response, Ref, Domain, Address}). info(Pid) -> call(Pid, info). @@ -386,25 +387,24 @@ handle_call(Req, From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}, +handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}, State) -> - ?vlog("received send_pdu message with" - "~n Pdu: ~p" - "~n Vsn: ~p" - "~n MsgData: ~p" - "~n Domain: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]), - maybe_process_extra_info(ExtraInfo), - maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State), + ?vlog("received send_pdu message with~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain: ~p~n" + " Address: ~p", [Pdu, Vsn, MsgData, Domain, Address]), + maybe_process_extra_info(ExtraInfo), + maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State), {noreply, State}; -handle_cast({inform_response, Ref, Addr, Port}, State) -> - ?vlog("received inform_response message with" - "~n Ref: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Ref, Addr, Port]), - handle_inform_response(Ref, Addr, Port, State), +handle_cast({inform_response, Ref, Domain, Address}, State) -> + ?vlog("received inform_response message with~n" + " Ref: ~p~n" + " Domain: ~p~n" + " Address: ~p", [Ref, Domain, Address]), + handle_inform_response(Ref, Domain, Address, State), {noreply, State}; handle_cast(filter_reset, State) -> @@ -425,7 +425,8 @@ handle_cast(Msg, State) -> %%-------------------------------------------------------------------- handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]), - maybe_handle_recv_msg(Ip, Port, Bytes, State), + {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + maybe_handle_recv_msg(Domain, Address, Bytes, State), {noreply, State}; handle_info(inform_response_gc, State) -> @@ -531,48 +532,49 @@ code_change(_Vsn, State, _Extra) -> %%% Internal functions %%%------------------------------------------------------------------- -maybe_handle_recv_msg(Addr, Port, Bytes, #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv(Addr, Port)) of +maybe_handle_recv_msg( + Domain, Address, Bytes, #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_recv(Domain, Address)) of false -> %% Drop the received packet inc(netIfMsgInDrops), ok; _ -> - handle_recv_msg(Addr, Port, Bytes, State) + handle_recv_msg(Domain, Address, Bytes, State) end. -handle_recv_msg(Addr, Port, Bytes, #state{server = Pid}) +handle_recv_msg(Domain, Address, Bytes, #state{server = Pid}) when is_binary(Bytes) andalso (size(Bytes) =:= 0) -> - Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port}, + Pid ! {snmp_error, {empty_message, Domain, Address}, Domain, Address}, ok; -handle_recv_msg(Addr, Port, Bytes, - #state{server = Pid, - note_store = NoteStore, - mpd_state = MpdState, - sock = Sock, - log = Log} = State) -> - Domain = snmp_conf:which_domain(Addr), % What the ****... - Logger = logger(Log, read, Addr, Port), - case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port, +handle_recv_msg( + Domain, Address, Bytes, + #state{server = Pid, + note_store = NoteStore, + mpd_state = MpdState, + sock = Sock, + log = Log} = State) -> + Logger = logger(Log, read, Domain, Address), + case (catch snmpm_mpd:process_msg(Bytes, Domain, Address, MpdState, NoteStore, Logger)) of {ok, Vsn, Pdu, MS, ACM} -> - maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, MS, ACM, + maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, MS, ACM, Logger, State); {discarded, Reason, Report} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Addr, Port}, - maybe_udp_send(State#state.filter, Sock, Addr, Port, Report), + Pid ! {snmp_error, ErrorInfo, Domain, Address}, + maybe_udp_send(State#state.filter, Sock, Domain, Address, Report), ok; {discarded, Reason} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Addr, Port}, + Pid ! {snmp_error, ErrorInfo, Domain, Address}, ok; Error -> @@ -582,88 +584,93 @@ handle_recv_msg(Addr, Port, Bytes, end. -maybe_handle_recv_pdu(Addr, Port, - Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, - Logger, - #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv_pdu(Addr, Port, Type)) of +maybe_handle_recv_pdu( + Domain, Address, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger, + #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_recv_pdu(Domain, Address, Type)) of false -> inc(netIfPduInDrops), ok; _ -> - handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) + handle_recv_pdu( + Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) end; -maybe_handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, - #state{filter = FilterMod} = State) +maybe_handle_recv_pdu( + Domain, Address, Vsn, Trap, PduMS, ACM, Logger, + #state{filter = FilterMod} = State) when is_record(Trap, trappdu) -> - case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of + case (catch FilterMod:accept_recv_pdu(Domain, Address, trappdu)) of false -> inc(netIfPduInDrops), ok; _ -> - handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, State) + handle_recv_pdu( + Domain, Address, Vsn, Trap, PduMS, ACM, Logger, State) end; -maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) -> - handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State). - - -handle_recv_pdu(Addr, Port, - Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, - Logger, #state{server = Pid, irb = IRB} = State) -> - handle_inform_request(IRB, Pid, Vsn, Pdu, ACM, - Addr, Port, Logger, State); -handle_recv_pdu(Addr, Port, - _Vsn, #pdu{type = report} = Pdu, _PduMS, ok, - _Logger, - #state{server = Pid} = _State) -> +maybe_handle_recv_pdu( + Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) -> + handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State). + + +handle_recv_pdu( + Domain, Address, Vsn, + #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger, + #state{server = Pid, irb = IRB} = State) -> + handle_inform_request( + IRB, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State); +handle_recv_pdu( + Domain, Address, _Vsn, + #pdu{type = report} = Pdu, _PduMS, ok, _Logger, + #state{server = Pid} = _State) -> ?vtrace("received report - ok", []), - Pid ! {snmp_report, {ok, Pdu}, Addr, Port}; -handle_recv_pdu(Addr, Port, - _Vsn, #pdu{type = report} = Pdu, _PduMS, - {error, ReqId, Reason}, - _Logger, - #state{server = Pid} = _State) -> + Pid ! {snmp_report, {ok, Pdu}, Domain, Address}; +handle_recv_pdu( + Domain, Address, _Vsn, + #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger, + #state{server = Pid} = _State) -> ?vtrace("received report - error", []), - Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Addr, Port}; -handle_recv_pdu(Addr, Port, - _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, - _Logger, - #state{server = Pid} = _State) -> + Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Address}; +handle_recv_pdu( + Domain, Address, _Vsn, + #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger, + #state{server = Pid} = _State) -> ?vtrace("received snmpv2-trap", []), - Pid ! {snmp_trap, Pdu, Addr, Port}; -handle_recv_pdu(Addr, Port, - _Vsn, Trap, _PduMS, _ACM, - _Logger, - #state{server = Pid} = _State) when is_record(Trap, trappdu) -> + Pid ! {snmp_trap, Pdu, Domain, Address}; +handle_recv_pdu( + Domain, Address, _Vsn, Trap, _PduMS, _ACM, _Logger, + #state{server = Pid} = _State) when is_record(Trap, trappdu) -> ?vtrace("received trappdu", []), - Pid ! {snmp_trap, Trap, Addr, Port}; -handle_recv_pdu(Addr, Port, - _Vsn, Pdu, _PduMS, _ACM, - _Logger, - #state{server = Pid} = _State) when is_record(Pdu, pdu) -> + Pid ! {snmp_trap, Trap, Domain, Address}; +handle_recv_pdu( + Domain, Address, _Vsn, Pdu, _PduMS, _ACM, _Logger, + #state{server = Pid} = _State) when is_record(Pdu, pdu) -> ?vtrace("received pdu", []), - Pid ! {snmp_pdu, Pdu, Addr, Port}; -handle_recv_pdu(_Addr, _Port, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> + Pid ! {snmp_pdu, Pdu, Domain, Address}; +handle_recv_pdu( + _Domain, _Address, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> ?vlog("received unexpected pdu: " - "~n Pdu: ~p" - "~n ACM: ~p", [Pdu, ACM]). + "~n Pdu: ~p" + "~n ACM: ~p", [Pdu, ACM]). -handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Addr, Port, Logger, State) -> +handle_inform_request( + auto, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State) -> ?vtrace("received inform-request (true)", []), - Pid ! {snmp_inform, ignore, Pdu, Addr, Port}, + Pid ! {snmp_inform, ignore, Pdu, Domain, Address}, RePdu = make_response_pdu(Pdu), - maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, State); -handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, - ACM, Addr, Port, _Logger, _State) -> + maybe_send_inform_response( + RePdu, Vsn, ACM, Domain, Address, Logger, State); +handle_inform_request( + {user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, + ACM, Domain, Address, _Logger, _State) -> ?vtrace("received inform-request (false)", []), - Pid ! {snmp_inform, ReqId, Pdu, Addr, Port}, + Pid ! {snmp_inform, ReqId, Pdu, Domain, Address}, %% Before we go any further, we need to check that we have not %% already received this message (possible resend). - Key = {ReqId, Addr, Port}, + Key = {ReqId, Domain, Address}, case ets:lookup(snmpm_inform_request_table, Key) of [_] -> %% OK, we already know about this. We assume this @@ -676,14 +683,14 @@ handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, Rec = {Key, Expire, {Vsn, ACM, RePdu}}, ets:insert(snmpm_inform_request_table, Rec) end. - -handle_inform_response(Ref, Addr, Port, State) -> - Key = {Ref, Addr, Port}, + +handle_inform_response(Ref, Domain, Address, State) -> + Key = {Ref, Domain, Address}, case ets:lookup(snmpm_inform_request_table, Key) of [{Key, _, {Vsn, ACM, RePdu}}] -> - Logger = logger(State#state.log, read, Addr, Port), + Logger = logger(State#state.log, read, Domain, Address), ets:delete(snmpm_inform_request_table, Key), - maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, + maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, State); [] -> %% Already acknowledged, or the user was to slow to reply... @@ -691,24 +698,26 @@ handle_inform_response(Ref, Addr, Port, State) -> end, ok. -maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, - #state{server = Pid, - sock = Sock, +maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, + #state{server = Pid, + sock = Sock, filter = FilterMod}) -> - case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(RePdu))) of + case (catch FilterMod:accept_send_pdu( + Domain, Address, pdu_type_of(RePdu))) + of false -> inc(netIfPduOutDrops), ok; _ -> case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of {ok, Msg} -> - maybe_udp_send(FilterMod, Sock, Addr, Port, Msg); + maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); {discarded, Reason} -> ?vlog("failed generating response message:" "~n Reason: ~p", [Reason]), ReqId = RePdu#pdu.request_id, ErrorInfo = {failed_generating_response, {RePdu, Reason}}, - Pid ! {snmp_error, ReqId, ErrorInfo, Addr, Port}, + Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Address}, ok end end. @@ -743,28 +752,28 @@ irgc_stop(Ref) -> (catch erlang:cancel_timer(Ref)). -maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, +maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of + case (catch FilterMod:accept_send_pdu(Domain, Address, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; _ -> - handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) + handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State) end. -handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port, +handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, #state{server = Pid, note_store = NoteStore, sock = Sock, log = Log, filter = FilterMod}) -> - Logger = logger(Log, write, Addr, Port), + Logger = logger(Log, write, Domain, Address), case (catch snmpm_mpd:generate_msg(Vsn, NoteStore, Pdu, MsgData, Logger)) of {ok, Msg} -> ?vtrace("handle_send_pdu -> message generated", []), - maybe_udp_send(FilterMod, Sock, Addr, Port, Msg); + maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); {discarded, Reason} -> ?vlog("PDU not sent: " "~n PDU: ~p" @@ -774,28 +783,28 @@ handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port, end. -maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) -> - case (catch FilterMod:accept_send(Addr, Port)) of +maybe_udp_send(FilterMod, Sock, Domain, {Ip, Port} = Address, Msg) -> + case (catch FilterMod:accept_send(Domain, Address)) of false -> inc(netIfMsgOutDrops), ok; _ -> - udp_send(Sock, Addr, Port, Msg) + udp_send(Sock, Ip, Port, Msg) end. -udp_send(Sock, Addr, Port, Msg) -> - case (catch gen_udp:send(Sock, Addr, Port, Msg)) of +udp_send(Sock, Ip, Port, Msg) -> + case (catch gen_udp:send(Sock, Ip, Port, Msg)) of ok -> ?vdebug("sent ~w bytes to ~w:~w [~w]", - [sz(Msg), Addr, Port, Sock]), + [sz(Msg), Ip, Port, Sock]), ok; {error, Reason} -> error_msg("failed sending message to ~p:~p: " - "~n ~p",[Addr, Port, Reason]); + "~n ~p",[Ip, Port, Reason]); Error -> error_msg("failed sending message to ~p:~p: " - "~n ~p",[Addr, Port, Error]) + "~n ~p",[Ip, Port, Error]) end. sz(B) when is_binary(B) -> @@ -1029,15 +1038,15 @@ t() -> %% ------------------------------------------------------------------- -logger(undefined, _Type, _Addr, _Port) -> +logger(undefined, _Type, _Domain, _Address) -> fun(_) -> ok end; -logger({Log, Types}, Type, Addr, Port) -> +logger({Log, Types}, Type, Domain, Address) -> case lists:member(Type, Types) of true -> fun(Msg) -> - snmp_log:log(Log, Msg, Addr, Port) + snmp_log:log(Log, Msg, Domain, Address) end; false -> fun(_) -> diff --git a/lib/snmp/src/manager/snmpm_net_if_filter.erl b/lib/snmp/src/manager/snmpm_net_if_filter.erl index eb0c6efb11..54b87a772a 100644 --- a/lib/snmp/src/manager/snmpm_net_if_filter.erl +++ b/lib/snmp/src/manager/snmpm_net_if_filter.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009. All Rights Reserved. +%% Copyright Ericsson AB 2009-2014. 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 @@ -25,29 +25,51 @@ -include("snmp_debug.hrl"). +accept_recv(Domain, _Address) when is_atom(Domain) -> + ?d("accept_recv -> entry with~n" + " Domain: ~p~n" + " Address: ~p", [Domain, _Address]), + true; accept_recv(_Addr, _Port) -> - ?d("accept_recv -> entry with" - "~n Addr: ~p" - "~n Port: ~p", [_Addr, _Port]), + ?d("accept_recv -> entry with~n" + " Addr: ~p~n" + " Port: ~p", [_Addr, _Port]), true. +accept_send(Domain, _Address) when is_atom(Domain) -> + ?d("accept_send -> entry with~n" + " Domain: ~p~n" + " Address: ~p", [Domain, _Address]), + true; accept_send(_Addr, _Port) -> - ?d("accept_send -> entry with" - "~n Addr: ~p" - "~n Port: ~p", [_Addr, _Port]), + ?d("accept_send -> entry with~n" + " Addr: ~p~n" + " Port: ~p", [_Addr, _Port]), true. +accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> + ?d("accept_recv_pdu -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " PduType: ~p", [Domain, _Address, _PduType]), + true; accept_recv_pdu(_Addr, _Port, _PduType) -> - ?d("accept_recv_pdu -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n PduType: ~p", [_Addr, _Port, _PduType]), + ?d("accept_recv_pdu -> entry with~n" + " Addr: ~p~n" + " Port: ~p~n" + " PduType: ~p", [_Addr, _Port, _PduType]), true. +accept_send_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> + ?d("accept_send_pdu -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " PduType: ~p", [Domain, _Address, _PduType]), + true; accept_send_pdu(_Addr, _Port, _PduType) -> - ?d("accept_send_pdu -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n PduType: ~p", [_Addr, _Port, _PduType]), + ?d("accept_send_pdu -> entry with~n" + " Addr: ~p~n" + " Port: ~p~n" + " PduType: ~p", [_Addr, _Port, _PduType]), true. diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl index 3e87f6a7fb..a04cfba2c1 100644 --- a/lib/snmp/src/manager/snmpm_net_if_mt.erl +++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2012. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -27,9 +27,9 @@ -export([ start_link/2, stop/1, - send_pdu/6, % Backward compatibillity - send_pdu/7, % Backward compatibillity - send_pdu/8, + send_pdu/6, % Backward compatibility + send_pdu/7, % Partly backward compatibility + send_pdu/8, % Backward compatibility inform_response/4, @@ -99,30 +99,31 @@ start_link(Server, NoteStore) -> stop(Pid) -> call(Pid, stop). -send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) -> - send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO). - -send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) -> +send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort) -> + send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort, ?DEFAULT_EXTRA_INFO). + +send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo) + when is_record(Pdu, pdu), is_atom(Domain) -> + ?d("send_pdu -> entry with~n" + " Pid: ~p~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain: ~p~n" + " Address: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Address]), + cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}); +send_pdu(Pid, Pdu, Vsn, MsgData, Ip, Port, ExtraInfo) -> Domain = snmpm_config:default_transport_domain(), - send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo). - -send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo) - when is_record(Pdu, pdu) -> - ?d("send_pdu -> entry with" - "~n Pid: ~p" - "~n Pdu: ~p" - "~n Vsn: ~p" - "~n MsgData: ~p" - "~n Domain: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]), - cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}). + send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo). + +send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) -> + send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo). note_store(Pid, NoteStore) -> call(Pid, {note_store, NoteStore}). -inform_response(Pid, Ref, Addr, Port) -> - cast(Pid, {inform_response, Ref, Addr, Port}). +inform_response(Pid, Ref, Domain, Address) -> + cast(Pid, {inform_response, Ref, Domain, Address}). info(Pid) -> call(Pid, info). @@ -396,25 +397,24 @@ handle_call(Req, From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}, +handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}, State) -> - ?vlog("received send_pdu message with" - "~n Pdu: ~p" - "~n Vsn: ~p" - "~n MsgData: ~p" - "~n Domain: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]), + ?vlog("received send_pdu message with~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain: ~p~n" + " Address: ~p", [Pdu, Vsn, MsgData, Domain, Address]), maybe_process_extra_info(ExtraInfo), - handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State), + handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State), {noreply, State}; -handle_cast({inform_response, Ref, Addr, Port}, State) -> - ?vlog("received inform_response message with" - "~n Ref: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Ref, Addr, Port]), - handle_inform_response(Ref, Addr, Port, State), +handle_cast({inform_response, Ref, Domain, Address}, State) -> + ?vlog("received inform_response message with~n" + " Ref: ~p~n" + " Domain: ~p~n" + " Address: ~p", [Ref, Domain, Address]), + handle_inform_response(Ref, Domain, Address, State), {noreply, State}; handle_cast(filter_reset, State) -> @@ -435,7 +435,8 @@ handle_cast(Msg, State) -> %%-------------------------------------------------------------------- handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]), - handle_udp(Ip, Port, Bytes, State), + {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + handle_udp(Domain, Address, Bytes, State), {noreply, State}; handle_info(inform_response_gc, State) -> @@ -500,60 +501,62 @@ code_change(_Vsn, State, _Extra) -> %%% Internal functions %%%------------------------------------------------------------------- -handle_udp(Addr, Port, Bytes, State) -> +handle_udp(Domain, Address, Bytes, State) -> Verbosity = get(verbosity), spawn_opt(fun() -> Log = worker_init(State, Verbosity), - Res = (catch maybe_handle_recv_msg( - Addr, Port, Bytes, - State#state{log = Log})), - worker_exit(udp, {Addr, Port}, Res) + Res = + (catch maybe_handle_recv_msg( + Domain, Address, Bytes, + State#state{log = Log})), + worker_exit(udp, {Domain, Address}, Res) end, [monitor]). -maybe_handle_recv_msg(Addr, Port, Bytes, #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv(Addr, Port)) of +maybe_handle_recv_msg( + Domain, Address, Bytes, #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_recv(Domain, Address)) of false -> %% Drop the received packet inc(netIfMsgInDrops), ok; _ -> - handle_recv_msg(Addr, Port, Bytes, State) + handle_recv_msg(Domain, Address, Bytes, State) end. -handle_recv_msg(Addr, Port, Bytes, #state{server = Pid}) +handle_recv_msg(Domain, Address, Bytes, #state{server = Pid}) when is_binary(Bytes) andalso (size(Bytes) =:= 0) -> - Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port}, + Pid ! {snmp_error, {empty_message, Domain, Address}, Domain, Address}, ok; -handle_recv_msg(Addr, Port, Bytes, - #state{server = Pid, - note_store = NoteStore, - mpd_state = MpdState, - sock = Sock, - log = Log} = State) -> - Domain = snmp_conf:which_domain(Addr), % What the ****... - Logger = logger(Log, read, Addr, Port), - case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port, +handle_recv_msg( + Domain, Address, Bytes, + #state{server = Pid, + note_store = NoteStore, + mpd_state = MpdState, + sock = Sock, + log = Log} = State) -> + Logger = logger(Log, read, Domain, Address), + case (catch snmpm_mpd:process_msg(Bytes, Domain, Address, MpdState, NoteStore, Logger)) of {ok, Vsn, Pdu, MS, ACM} -> - maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, MS, ACM, + maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, MS, ACM, Logger, State); {discarded, Reason, Report} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Addr, Port}, - maybe_udp_send(State#state.filter, Sock, Addr, Port, Report), + Pid ! {snmp_error, ErrorInfo, Domain, Address}, + maybe_udp_send(State#state.filter, Sock, Domain, Address, Report), ok; {discarded, Reason} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Addr, Port}, + Pid ! {snmp_error, ErrorInfo, Domain, Address}, ok; Error -> @@ -563,94 +566,98 @@ handle_recv_msg(Addr, Port, Bytes, end. -maybe_handle_recv_pdu(Addr, Port, - Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, - Logger, - #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv_pdu(Addr, Port, Type)) of +maybe_handle_recv_pdu( + Domain, Address, Vsn, + #pdu{type = Type} = Pdu, PduMS, ACM, Logger, + #state{filter = FilterMod} = State) -> + case (catch FilterMod:accept_recv_pdu(Domain, Address, Type)) of false -> inc(netIfPduInDrops), ok; _ -> - handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) + handle_recv_pdu( + Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) end; -maybe_handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, - #state{filter = FilterMod} = State) +maybe_handle_recv_pdu( + Domain, Address, Vsn, Trap, PduMS, ACM, Logger, + #state{filter = FilterMod} = State) when is_record(Trap, trappdu) -> - case (catch FilterMod:accept_recv_pdu(Addr, Port, trappdu)) of + case (catch FilterMod:accept_recv_pdu(Domain, Address, trappdu)) of false -> inc(netIfPduInDrops), ok; _ -> - handle_recv_pdu(Addr, Port, Vsn, Trap, PduMS, ACM, Logger, State) + handle_recv_pdu( + Domain, Address, Vsn, Trap, PduMS, ACM, Logger, State) end; -maybe_handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State) -> - handle_recv_pdu(Addr, Port, Vsn, Pdu, PduMS, ACM, Logger, State). - - -handle_recv_pdu(Addr, Port, - Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, - Logger, #state{server = Pid, irb = IRB} = State) -> - handle_inform_request(IRB, Pid, Vsn, Pdu, ACM, - Addr, Port, Logger, State); -handle_recv_pdu(Addr, Port, - _Vsn, #pdu{type = report} = Pdu, _PduMS, ok, - _Logger, - #state{server = Pid} = _State) -> +maybe_handle_recv_pdu( + Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) -> + handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State). + + +handle_recv_pdu( + Domain, Address, Vsn, + #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger, + #state{server = Pid, irb = IRB} = State) -> + handle_inform_request( + IRB, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State); +handle_recv_pdu( + Domain, Address, _Vsn, + #pdu{type = report} = Pdu, _PduMS, ok, _Logger, + #state{server = Pid} = _State) -> ?vtrace("received report - ok", []), - Pid ! {snmp_report, {ok, Pdu}, Addr, Port}, + Pid ! {snmp_report, {ok, Pdu}, Domain, Address}, ok; -handle_recv_pdu(Addr, Port, +handle_recv_pdu(Domain, Address, _Vsn, #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger, #state{server = Pid} = _State) -> ?vtrace("received report - error", []), - Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Addr, Port}, + Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Address}, ok; -handle_recv_pdu(Addr, Port, - _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, - _Logger, - #state{server = Pid} = _State) -> +handle_recv_pdu( + Domain, Address, _Vsn, + #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger, + #state{server = Pid} = _State) -> ?vtrace("received snmpv2-trap", []), - Pid ! {snmp_trap, Pdu, Addr, Port}, + Pid ! {snmp_trap, Pdu, Domain, Address}, ok; -handle_recv_pdu(Addr, Port, - _Vsn, Trap, _PduMS, _ACM, - _Logger, - #state{server = Pid} = _State) when is_record(Trap, trappdu) -> +handle_recv_pdu( + Domain, Address, _Vsn, Trap, _PduMS, _ACM, _Logger, + #state{server = Pid} = _State) when is_record(Trap, trappdu) -> ?vtrace("received trappdu", []), - Pid ! {snmp_trap, Trap, Addr, Port}, + Pid ! {snmp_trap, Trap, Domain, Address}, ok; -handle_recv_pdu(Addr, Port, - _Vsn, Pdu, _PduMS, _ACM, - _Logger, - #state{server = Pid} = _State) when is_record(Pdu, pdu) -> +handle_recv_pdu( + Domain, Address, _Vsn, Pdu, _PduMS, _ACM, _Logger, + #state{server = Pid} = _State) when is_record(Pdu, pdu) -> ?vtrace("received pdu", []), - Pid ! {snmp_pdu, Pdu, Addr, Port}, + Pid ! {snmp_pdu, Pdu, Domain, Address}, ok; -handle_recv_pdu(_Addr, _Port, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> +handle_recv_pdu( + _Domain, _Address, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> ?vlog("received unexpected pdu: " "~n Pdu: ~p" "~n ACM: ~p", [Pdu, ACM]), ok. -handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Addr, Port, Logger, State) -> +handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State) -> ?vtrace("received inform-request (true)", []), - Pid ! {snmp_inform, ignore, Pdu, Addr, Port}, + Pid ! {snmp_inform, ignore, Pdu, Domain, Address}, RePdu = make_response_pdu(Pdu), - maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, State); + maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, State); handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, - ACM, Addr, Port, _Logger, _State) -> + ACM, Domain, Address, _Logger, _State) -> ?vtrace("received inform-request (false)", []), - Pid ! {snmp_inform, ReqId, Pdu, Addr, Port}, + Pid ! {snmp_inform, ReqId, Pdu, Domain, Address}, %% Before we go any further, we need to check that we have not %% already received this message (possible resend). - Key = {ReqId, Addr, Port}, + Key = {ReqId, Domain, Address}, case ets:lookup(snmpm_inform_request_table, Key) of [_] -> %% OK, we already know about this. We assume this @@ -665,27 +672,27 @@ handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, end, ok. -handle_inform_response(Ref, Addr, Port, State) -> +handle_inform_response(Ref, Domain, Address, State) -> Verbosity = get(verbosity), spawn_opt(fun() -> Log = worker_init(State, Verbosity), Res = (catch do_handle_inform_response( Ref, - Addr, Port, + Domain, Address, State#state{log = Log})), - worker_exit(inform_reponse, {Addr, Port}, Res) + worker_exit(inform_response, {Domain, Address}, Res) end, [monitor]). -do_handle_inform_response(Ref, Addr, Port, State) -> - Key = {Ref, Addr, Port}, +do_handle_inform_response(Ref, Domain, Address, State) -> + Key = {Ref, Domain, Address}, case ets:lookup(snmpm_inform_request_table, Key) of [{Key, _, {Vsn, ACM, RePdu}}] -> - Logger = logger(State#state.log, read, Addr, Port), + Logger = logger(State#state.log, read, Domain, Address), ets:delete(snmpm_inform_request_table, Key), - maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, + maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, State); [] -> %% Already acknowledged, or the user was to slow to reply... @@ -693,24 +700,26 @@ do_handle_inform_response(Ref, Addr, Port, State) -> end, ok. -maybe_send_inform_response(RePdu, Vsn, ACM, Addr, Port, Logger, +maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, #state{server = Pid, sock = Sock, filter = FilterMod}) -> - case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(RePdu))) of + case (catch FilterMod:accept_send_pdu( + Domain, Address, pdu_type_of(RePdu))) + of false -> inc(netIfPduOutDrops), ok; _ -> case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of {ok, Msg} -> - maybe_udp_send(FilterMod, Sock, Addr, Port, Msg); + maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); {discarded, Reason} -> ?vlog("failed generating response message:" "~n Reason: ~p", [Reason]), ReqId = RePdu#pdu.request_id, ErrorInfo = {failed_generating_response, {RePdu, Reason}}, - Pid ! {snmp_error, ReqId, ErrorInfo, Addr, Port}, + Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Address}, ok end end. @@ -745,40 +754,40 @@ irgc_stop(Ref) -> (catch erlang:cancel_timer(Ref)). -handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) -> +handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State) -> Verbosity = get(verbosity), spawn_opt(fun() -> Log = worker_init(State, Verbosity), Res = (catch maybe_handle_send_pdu( Pdu, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, State#state{log = Log})), - worker_exit(send_pdu, {Domain, Addr, Port}, Res) + worker_exit(send_pdu, {Domain, Address}, Res) end, [monitor]). -maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, +maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of + case (catch FilterMod:accept_send_pdu(Domain, Address, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; _ -> - do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) + do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State) end. -do_handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port, +do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, #state{server = Pid, note_store = NoteStore, sock = Sock, log = Log, filter = FilterMod}) -> - Logger = logger(Log, write, Addr, Port), + Logger = logger(Log, write, Domain, Address), case (catch snmpm_mpd:generate_msg(Vsn, NoteStore, Pdu, MsgData, Logger)) of {ok, Msg} -> ?vtrace("do_handle_send_pdu -> message generated", []), - maybe_udp_send(FilterMod, Sock, Addr, Port, Msg); + maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); {discarded, Reason} -> ?vlog("PDU not sent: " "~n PDU: ~p" @@ -788,29 +797,29 @@ do_handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port, end. -maybe_udp_send(FilterMod, Sock, Addr, Port, Msg) -> - case (catch FilterMod:accept_send(Addr, Port)) of +maybe_udp_send(FilterMod, Sock, Domain, {Ip, Port} = Address, Msg) -> + case (catch FilterMod:accept_send(Domain, Address)) of false -> inc(netIfMsgOutDrops), ok; _ -> - udp_send(Sock, Addr, Port, Msg) + udp_send(Sock, Ip, Port, Msg) end. -udp_send(Sock, Addr, Port, Msg) -> - case (catch gen_udp:send(Sock, Addr, Port, Msg)) of +udp_send(Sock, Ip, Port, Msg) -> + case (catch gen_udp:send(Sock, Ip, Port, Msg)) of ok -> ?vdebug("sent ~w bytes to ~w:~w [~w]", - [sz(Msg), Addr, Port, Sock]), + [sz(Msg), Ip, Port, Sock]), ok; {error, Reason} -> error_msg("failed sending message to ~p:~p: " - "~n ~p",[Addr, Port, Reason]), + "~n ~p", [Ip, Port, Reason]), ok; Error -> error_msg("failed sending message to ~p:~p: " - "~n ~p",[Addr, Port, Error]), + "~n ~p", [Ip, Port, Error]), ok end. @@ -1036,20 +1045,20 @@ worker_exit(Tag, Info, Result) -> handle_worker_exit(_, {_, _, ok}) -> ok; -handle_worker_exit(Pid, {udp, {Addr, Port}, ExitStatus}) -> +handle_worker_exit(Pid, {udp, {Domain, Address}, ExitStatus}) -> warning_msg("Worker process (~p) terminated " "while processing (incomming) message from ~w:~w: " - "~n~p", [Pid, Addr, Port, ExitStatus]), + "~n~p", [Pid, Domain, Address, ExitStatus]), ok; -handle_worker_exit(Pid, {send_pdu, {Domain, Addr, Port}, ExitStatus}) -> +handle_worker_exit(Pid, {send_pdu, {Domain, Address}, ExitStatus}) -> warning_msg("Worker process (~p) terminated " - "while processing (outgoing) pdu for [~w] ~w:~w: " - "~n~p", [Pid, Domain, Addr, Port, ExitStatus]), + "while processing (outgoing) pdu for [~w] ~w: " + "~n~p", [Pid, Domain, Address, ExitStatus]), ok; -handle_worker_exit(Pid, {inform_response, {Addr, Port}, ExitStatus}) -> +handle_worker_exit(Pid, {inform_response, {Domain, Address}, ExitStatus}) -> warning_msg("Worker process (~p) terminated " "while processing (outgoing) inform response for ~w:~w: " - "~n~p", [Pid, Addr, Port, ExitStatus]), + "~n~p", [Pid, Domain, Address, ExitStatus]), ok; handle_worker_exit(_, _) -> ok. @@ -1095,15 +1104,15 @@ t() -> %% ------------------------------------------------------------------- -logger(undefined, _Type, _Addr, _Port) -> +logger(undefined, _Type, _Domain, _Address) -> fun(_) -> ok end; -logger({_Name, Log, Types}, Type, Addr, Port) -> +logger({_Name, Log, Types}, Type, Domain, Address) -> case lists:member(Type, Types) of true -> fun(Msg) -> - snmp_log:log(Log, Msg, Addr, Port) + snmp_log:log(Log, Msg, Domain, Address) end; false -> fun(_) -> @@ -1256,4 +1265,3 @@ call(Pid, Req, Timeout) -> cast(Pid, Msg) -> gen_server:cast(Pid, Msg). - diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl index 9c79df2748..b3389ef96c 100644 --- a/lib/snmp/src/manager/snmpm_server.erl +++ b/lib/snmp/src/manager/snmpm_server.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -163,8 +163,7 @@ reg_type, target, domain, - addr, - port, + address, type, data, ref, @@ -1033,14 +1032,14 @@ handle_info({snmp_error, Pdu, Reason}, State) -> handle_snmp_error(Pdu, Reason, State), {noreply, State}; -handle_info({snmp_error, Reason, Addr, Port}, State) -> +handle_info({snmp_error, Reason, Domain, Address}, State) -> ?vlog("received snmp_error message", []), - handle_snmp_error(Addr, Port, -1, Reason, State), + handle_snmp_error(Domain, Address, -1, Reason, State), {noreply, State}; -handle_info({snmp_error, ReqId, Reason, Addr, Port}, State) -> +handle_info({snmp_error, ReqId, Reason, Domain, Address}, State) -> ?vlog("received snmp_error message", []), - handle_snmp_error(Addr, Port, ReqId, Reason, State), + handle_snmp_error(Domain, Address, ReqId, Reason, State), {noreply, State}; %% handle_info({snmp_error, ReqId, Pdu, Reason, Addr, Port}, State) -> @@ -1049,30 +1048,30 @@ handle_info({snmp_error, ReqId, Reason, Addr, Port}, State) -> %% {noreply, State}; -handle_info({snmp_pdu, Pdu, Addr, Port}, State) -> +handle_info({snmp_pdu, Pdu, Domain, Address}, State) -> ?vlog("received snmp_pdu message", []), - handle_snmp_pdu(Pdu, Addr, Port, State), + handle_snmp_pdu(Pdu, Domain, Address, State), {noreply, State}; -handle_info({snmp_trap, Trap, Addr, Port}, State) -> +handle_info({snmp_trap, Trap, Domain, Address}, State) -> ?vlog("received snmp_trap message", []), - handle_snmp_trap(Trap, Addr, Port, State), + handle_snmp_trap(Trap, Domain, Address, State), {noreply, State}; -handle_info({snmp_inform, Ref, Pdu, Addr, Port}, State) -> +handle_info({snmp_inform, Ref, Pdu, Domain, Address}, State) -> ?vlog("received snmp_inform message", []), - handle_snmp_inform(Ref, Pdu, Addr, Port, State), + handle_snmp_inform(Ref, Pdu, Domain, Address, State), {noreply, State}; -handle_info({snmp_report, {ok, Pdu}, Addr, Port}, State) -> - handle_snmp_report(Pdu, Addr, Port, State), +handle_info({snmp_report, {ok, Pdu}, Domain, Address}, State) -> + handle_snmp_report(Pdu, Domain, Address, State), {noreply, State}; -handle_info({snmp_report, {error, ReqId, Info, Pdu}, Addr, Port}, State) -> - handle_snmp_report(ReqId, Pdu, Info, Addr, Port, State), +handle_info({snmp_report, {error, ReqId, Info, Pdu}, Domain, Address}, State) -> + handle_snmp_report(ReqId, Pdu, Info, Domain, Address, State), {noreply, State}; @@ -1176,11 +1175,11 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> "~n From: ~p", [Pid, UserId, TargetName, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_sync_get -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_request(Oids, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, Extra, State), ?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1193,8 +1192,7 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = get, data = MsgData, ref = Ref, @@ -1230,11 +1228,11 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, "~n From: ~p", [Pid, UserId, TargetName, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, Extra, State), ?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1247,12 +1245,11 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = get_next, data = MsgData, ref = Ref, - mon = MonRef, + mon = MonRef, from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -1290,11 +1287,11 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, "~n From: ~p", [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_bulk_request(Oids, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, NonRep, MaxRep, Extra, State), ?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1307,8 +1304,7 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = get_bulk, data = MsgData, ref = Ref, @@ -1346,11 +1342,11 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> "~n From: ~p", [Pid, UserId, TargetName, VarsAndVals, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_sync_set -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, Extra, State), ?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1363,8 +1359,7 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = set, data = MsgData, ref = Ref, @@ -1400,11 +1395,11 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_async_get -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_request(Oids, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, Extra, State), ?vdebug("handle_async_get -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_TIMEOUT(SendOpts), @@ -1413,8 +1408,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = get, data = MsgData, expire = t() + Expire}, @@ -1450,11 +1444,11 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_async_get_next -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, Extra, State), ?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts), @@ -1463,8 +1457,7 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = get_next, data = MsgData, expire = t() + Expire}, @@ -1507,11 +1500,11 @@ handle_async_get_bulk(Pid, "~n SendOpts: ~p", [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_bulk_request(Oids, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, NonRep, MaxRep, Extra, State), ?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts), @@ -1520,8 +1513,7 @@ handle_async_get_bulk(Pid, reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = get_bulk, data = MsgData, expire = t() + Expire}, @@ -1556,11 +1548,11 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, VarsAndVals, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Address, Vsn, MsgData} -> ?vtrace("handle_async_set -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Domain, Addr, Port, + Domain, Address, Extra, State), ?vdebug("handle_async_set -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_SET_TIMEOUT(SendOpts), @@ -1569,8 +1561,7 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> reg_type = RegType, target = TargetName, domain = Domain, - addr = Addr, - port = Port, + address = Address, type = set, data = MsgData, expire = t() + Expire}, @@ -1808,15 +1799,15 @@ handle_snmp_error(CrapError, Reason, _State) -> "~n~p~n~p", [CrapError, Reason]), ok. -handle_snmp_error(Addr, Port, ReqId, Reason, State) -> +handle_snmp_error(Domain, Address, ReqId, Reason, State) -> - ?vtrace("handle_snmp_error -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n ReqId: ~p" - "~n Reason: ~p", [Addr, Port, ReqId, Reason]), + ?vtrace("handle_snmp_error -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " ReqId: ~p~n" + " Reason: ~p", [Domain, Address, ReqId, Reason]), - case snmpm_config:get_agent_user_id(Addr, Port) of + case snmpm_config:get_agent_user_id(Domain, Address) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> @@ -1831,7 +1822,7 @@ handle_snmp_error(Addr, Port, ReqId, Reason, State) -> error_msg("failed retreiving the default user " "info handling snmp error " "<~p,~p>: ~n~w~n~w", - [Addr, Port, ReqId, Reason]) + [Domain, Address, ReqId, Reason]) end end; _Error -> @@ -1843,7 +1834,7 @@ handle_snmp_error(Addr, Port, ReqId, Reason, State) -> error_msg("failed retreiving the default user " "info handling snmp error " "<~p,~p>: ~n~w~n~w", - [Addr, Port, ReqId, Reason]) + [Domain, Address, ReqId, Reason]) end end. @@ -1867,12 +1858,12 @@ handle_error(_UserId, Mod, Reason, ReqId, Data, _State) -> handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, - Addr, Port, State) -> + Domain, Address, State) -> - ?vtrace("handle_snmp_pdu(get-response) -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n Pdu: ~p", [Addr, Port, Pdu]), + ?vtrace("handle_snmp_pdu(get-response) -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " Pdu: ~p", [Domain, Address, Pdu]), case ets:lookup(snmpm_request_table, ReqId) of @@ -1902,9 +1893,10 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, SnmpResponse = {EStatus, EIndex, Varbinds2}, case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> - handle_pdu(UserId, UserMod, - RegType, Target, Addr, Port, - ReqId, SnmpResponse, UserData, State), + handle_pdu( + UserId, UserMod, + RegType, Target, Domain, Address, + ReqId, SnmpResponse, UserData, State), maybe_delete(Disco, ReqId); _Error -> %% reply to outstanding request, for which there is no @@ -1912,15 +1904,16 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, %% Therefor send it to the default user case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> - handle_pdu(DefUserId, DefMod, - RegType, Target, Addr, Port, - ReqId, SnmpResponse, DefData, State), + handle_pdu( + DefUserId, DefMod, + RegType, Target, Domain, Address, + ReqId, SnmpResponse, DefData, State), maybe_delete(Disco, ReqId); Error -> error_msg("failed retreiving the default user " "info handling pdu from " "~p <~p,~p>: ~n~w~n~w", - [Target, Addr, Port, Error, Pdu]) + [Target, Domain, Address, Error, Pdu]) end end; @@ -1974,7 +1967,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, varbinds = Varbinds} = Pdu, Varbinds2 = fix_vbs_BITS(Varbinds), SnmpInfo = {EStatus, EIndex, Varbinds2}, - case snmpm_config:get_agent_user_id(Addr, Port) of + case snmpm_config:get_agent_user_id(Domain, Address) of {ok, UserId} -> %% A very late reply or a reply to a request %% that has been cancelled. @@ -1999,7 +1992,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, "user info handling (old) " "pdu from " "<~p,~p>: ~n~w~n~w", - [Addr, Port, Error, Pdu]) + [Domain, Address, Error, Pdu]) end end; @@ -2016,28 +2009,30 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, "no agent info found", []), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> - handle_agent(DefUserId, DefMod, - Addr, Port, - pdu, ignore, - SnmpInfo, DefData, State); + handle_agent( + DefUserId, DefMod, + Domain, Address, + pdu, ignore, + SnmpInfo, DefData, State); Error -> error_msg("failed retreiving the default user " "info handling (old) pdu when no user " "found from " "<~p,~p>: ~n~w~n~w", - [Addr, Port, Error, Pdu]) + [Domain, Address, Error, Pdu]) end end end; -handle_snmp_pdu(CrapPdu, Addr, Port, _State) -> +handle_snmp_pdu(CrapPdu, Domain, Address, _State) -> error_msg("received crap (snmp) Pdu from ~w:~w =>" - "~p", [Addr, Port, CrapPdu]), + "~p", [Domain, Address, CrapPdu]), ok. -handle_pdu(_UserId, Mod, target_name = _RegType, TargetName, _Addr, _Port, - ReqId, SnmpResponse, Data, _State) -> +handle_pdu( + _UserId, Mod, target_name = _RegType, TargetName, _Domain, _Address, + ReqId, SnmpResponse, Data, _State) -> ?vtrace("handle_pdu(target_name) -> entry when" "~n Mod: ~p", [Mod]), F = fun() -> @@ -2053,43 +2048,47 @@ handle_pdu(_UserId, Mod, target_name = _RegType, TargetName, _Addr, _Port, end, handle_callback(F), ok; -handle_pdu(_UserId, Mod, addr_port = _RegType, _TargetName, Addr, Port, - ReqId, SnmpResponse, Data, _State) -> +handle_pdu( + _UserId, Mod, addr_port = _RegType, _TargetName, _Domain, Address, + ReqId, SnmpResponse, Data, _State) -> ?vtrace("handle_pdu(addr_port) -> entry when" "~n Mod: ~p", [Mod]), F = fun() -> - (catch Mod:handle_pdu(Addr, Port, ReqId, SnmpResponse, Data)) + {Ip, Port} = Address, + (catch Mod:handle_pdu(Ip, Port, ReqId, SnmpResponse, Data)) end, handle_callback(F), ok. -handle_agent(UserId, Mod, Addr, Port, Type, Ref, SnmpInfo, Data, State) -> +handle_agent(UserId, Mod, Domain, Address, Type, Ref, SnmpInfo, Data, State) -> ?vtrace("handle_agent -> entry when" "~n UserId: ~p" "~n Type: ~p" "~n Mod: ~p", [UserId, Type, Mod]), F = fun() -> - do_handle_agent(UserId, Mod, Addr, Port, + do_handle_agent(UserId, Mod, Domain, Address, Type, Ref, SnmpInfo, Data, State) end, handle_callback(F), ok. do_handle_agent(DefUserId, DefMod, - Addr, Port, + Domain, Address, Type, Ref, SnmpInfo, DefData, State) -> ?vdebug("do_handle_agent -> entry when" "~n DefUserId: ~p", [DefUserId]), - try DefMod:handle_agent(Addr, Port, Type, SnmpInfo, DefData) of + try DefMod:handle_agent(Domain, Address, Type, SnmpInfo, DefData) of {register, UserId2, TargetName, Config} -> ?vtrace("do_handle_agent -> register: " "~n UserId2: ~p" "~n TargetName: ~p" "~n Config: ~p", [UserId2, TargetName, Config]), - Config2 = ensure_present([{address, Addr}, {port, Port}], Config), + Config2 = + ensure_present( + [{tdomain, Domain}, {taddress, Address}], Config), Config3 = [{reg_type, target_name} | Config2], case snmpm_config:register_agent(UserId2, TargetName, Config3) of @@ -2099,7 +2098,7 @@ do_handle_agent(DefUserId, DefMod, error_msg("failed registering agent - " "handling agent " "~p <~p,~p>: ~n~w", - [TargetName, Addr, Port, Reason]), + [TargetName, Domain, Address, Reason]), ok end; @@ -2108,31 +2107,33 @@ do_handle_agent(DefUserId, DefMod, ok; InvalidResult -> - CallbackArgs = [Addr, Port, Type, SnmpInfo, DefData], + CallbackArgs = [Domain, Address, Type, SnmpInfo, DefData], handle_invalid_result(handle_agent, CallbackArgs, InvalidResult) catch error:{undef, _} when Type =:= pdu -> %% Maybe, still on the old API ?vdebug("do_handle_agent -> maybe still on the old api", []), - case (catch DefMod:handle_agent(Addr, Port, SnmpInfo, DefData)) of + {Ip, Port} = Address, + case (catch DefMod:handle_agent(Ip, Port, SnmpInfo, DefData)) of {register, UserId2, Config} -> ?vtrace("do_handle_agent -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), - TargetName = mk_target_name(Addr, Port, Config), - Config2 = [{reg_type, addr_port}, - {address, Addr}, - {port, Port} | Config], - case snmpm_config:register_agent(UserId2, - TargetName, Config2) of + TargetName = mk_target_name(Domain, Address, Config), + Config2 = + ensure_present( + [{tdomain, Domain}, {taddress, Address}], Config), + Config3 = [{reg_type, addr_port} | Config2], + case snmpm_config:register_agent( + UserId2, TargetName, Config3) of ok -> ok; {error, Reason} -> error_msg("failed registering agent - " "handling agent " "~p <~p,~p>: ~n~w", - [TargetName, Addr, Port, Reason]), + [TargetName, Domain, Address, Reason]), ok end; {register, UserId2, TargetName, Config} -> @@ -2141,18 +2142,19 @@ do_handle_agent(DefUserId, DefMod, "~n TargetName: ~p" "~n Config: ~p", [UserId2, TargetName, Config]), - Config2 = ensure_present([{address, Addr}, {port, Port}], - Config), + Config2 = + ensure_present( + [{tdomain, Domain}, {taddress, Address}], Config), Config3 = [{reg_type, target_name} | Config2], - case snmpm_config:register_agent(UserId2, - TargetName, Config3) of + case snmpm_config:register_agent( + UserId2, TargetName, Config3) of ok -> ok; {error, Reason} -> error_msg("failed registering agent - " "handling agent " "~p <~p,~p>: ~n~w", - [TargetName, Addr, Port, Reason]), + [TargetName, Domain, Address, Reason]), ok end; _Ignore -> @@ -2170,34 +2172,38 @@ do_handle_agent(DefUserId, DefMod, %% Backward compatibillity crap RegType = target_name, - Target = mk_target_name(Addr, Port, default_agent_config()), + Target = mk_target_name(Domain, Address, default_agent_config()), case Type of report -> SnmpInform = SnmpInfo, - handle_report(DefUserId, DefMod, - RegType, Target, Addr, Port, - SnmpInform, DefData, State); + handle_report( + DefUserId, DefMod, + RegType, Target, Domain, Address, + SnmpInform, DefData, State); inform -> SnmpInform = SnmpInfo, - handle_inform(DefUserId, DefMod, Ref, - RegType, Target, Addr, Port, - SnmpInform, DefData, State); + handle_inform( + DefUserId, DefMod, Ref, + RegType, Target, Domain, Address, + SnmpInform, DefData, State); trap -> SnmpTrapInfo = SnmpInfo, - handle_trap(DefUserId, DefMod, - RegType, Target, Addr, Port, - SnmpTrapInfo, DefData, State); + handle_trap( + DefUserId, DefMod, + RegType, Target, Domain, Address, + SnmpTrapInfo, DefData, State); _ -> - error_msg("failed delivering ~w info to default user - " - "regarding agent " - "<~p,~p>: ~n~w", [Type, Addr, Port, SnmpInfo]) + error_msg( + "failed delivering ~w info to default user - " + "regarding agent " + "<~p,~p>: ~n~w", [Type, Domain, Address, SnmpInfo]) end; T:E -> - CallbackArgs = [Addr, Port, Type, SnmpInfo, DefData], + CallbackArgs = [Domain, Address, Type, SnmpInfo, DefData], handle_invalid_result(handle_agent, CallbackArgs, T, E) end. @@ -2215,50 +2221,51 @@ ensure_present([{Key, _Val} = Elem|Ensure], Config) -> %% Retrieve user info for this agent. %% If this is an unknown agent, then use the default user -handle_snmp_trap(#trappdu{enterprise = Enteprise, - generic_trap = Generic, - specific_trap = Spec, - time_stamp = Timestamp, - varbinds = Varbinds} = Trap, - Addr, Port, State) -> - - ?vtrace("handle_snmp_trap [trappdu] -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n Trap: ~p", [Addr, Port, Trap]), +handle_snmp_trap( + #trappdu{enterprise = Enteprise, + generic_trap = Generic, + specific_trap = Spec, + time_stamp = Timestamp, + varbinds = Varbinds} = Trap, Domain, Address, State) -> + + ?vtrace("handle_snmp_trap [trappdu] -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " Trap: ~p", [Domain, Address, Trap]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpTrapInfo = {Enteprise, Generic, Spec, Timestamp, Varbinds2}, - do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State); + do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State); handle_snmp_trap(#pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Trap, - Addr, Port, State) -> + Domain, Address, State) -> - ?vtrace("handle_snmp_trap [pdu] -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n Trap: ~p", [Addr, Port, Trap]), + ?vtrace("handle_snmp_trap [pdu] -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " Trap: ~p", [Domain, Address, Trap]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpTrapInfo = {EStatus, EIndex, Varbinds2}, - do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State); + do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State); -handle_snmp_trap(CrapTrap, Addr, Port, _State) -> +handle_snmp_trap(CrapTrap, Domain, Address, _State) -> error_msg("received crap (snmp) trap from ~w:~w =>" - "~p", [Addr, Port, CrapTrap]), + "~p", [Domain, Address, CrapTrap]), ok. -do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State) -> - case snmpm_config:get_agent_user_info(Addr, Port) of +do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> + case snmpm_config:get_agent_user_info(Domain, Address) of {ok, UserId, Target, RegType} -> ?vtrace("handle_snmp_trap -> found user: ~p", [UserId]), case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> - handle_trap(UserId, Mod, - RegType, Target, Addr, Port, - SnmpTrapInfo, Data, State); + handle_trap( + UserId, Mod, + RegType, Target, Domain, Address, + SnmpTrapInfo, Data, State); Error1 -> %% User no longer exists, unregister agent @@ -2270,66 +2277,72 @@ do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State) -> %% Try use the default user case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> - handle_agent(DefUserId, DefMod, - Addr, Port, - trap, ignore, - SnmpTrapInfo, DefData, State); + handle_agent( + DefUserId, DefMod, + Domain, Address, + trap, ignore, + SnmpTrapInfo, DefData, State); Error2 -> - error_msg("failed retreiving the default " - "user info handling report from " - "~p <~p,~p>: ~n~w~n~w", - [Target, Addr, Port, - Error2, SnmpTrapInfo]) + error_msg( + "failed retreiving the default " + "user info handling report from " + "~p <~p,~p>: ~n~w~n~w", + [Target, Domain, Address, + Error2, SnmpTrapInfo]) end; Error3 -> %% Failed unregister agent, %% now its getting messy... - warning_msg("failed unregister agent ~p <~p,~p> " - "belonging to non-existing " - "user ~p, handling trap: " - "~n Error: ~w" - "~n Trap info: ~w", - [Target, Addr, Port, UserId, - Error3, SnmpTrapInfo]) + warning_msg( + "failed unregister agent ~p <~p,~p> " + "belonging to non-existing " + "user ~p, handling trap: " + "~n Error: ~w" + "~n Trap info: ~w", + [Target, Domain, Address, UserId, + Error3, SnmpTrapInfo]) end end; Error4 -> %% Unknown agent, pass it on to the default user ?vlog("[trap] failed retreiving user id for agent <~p,~p>: " - "~n ~p", [Addr, Port, Error4]), + "~n ~p", [Domain, Address, Error4]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> - handle_agent(DefUserId, DefMod, - Addr, Port, - trap, ignore, - SnmpTrapInfo, DefData, State); + handle_agent( + DefUserId, DefMod, + Domain, Address, + trap, ignore, + SnmpTrapInfo, DefData, State); Error5 -> - error_msg("failed retreiving " - "the default user info handling trap from " - "<~p,~p>: ~n~w~n~w", - [Addr, Port, Error5, SnmpTrapInfo]) + error_msg( + "failed retreiving " + "the default user info handling trap from " + "<~p,~p>: ~n~w~n~w", + [Domain, Address, Error5, SnmpTrapInfo]) end end, ok. -handle_trap(UserId, Mod, - RegType, Target, Addr, Port, SnmpTrapInfo, Data, State) -> +handle_trap( + UserId, Mod, RegType, Target, Domain, Address, SnmpTrapInfo, Data, State) -> ?vtrace("handle_trap -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> - do_handle_trap(UserId, Mod, - RegType, Target, Addr, Port, - SnmpTrapInfo, Data, State) + do_handle_trap( + UserId, Mod, + RegType, Target, Domain, Address, + SnmpTrapInfo, Data, State) end, handle_callback(F), ok. -do_handle_trap(UserId, Mod, - RegType, Target, Addr, Port, SnmpTrapInfo, Data, _State) -> +do_handle_trap( + UserId, Mod, RegType, Target, Domain, Address, SnmpTrapInfo, Data, _State) -> ?vdebug("do_handle_trap -> entry with" "~n UserId: ~p", [UserId]), {HandleTrap, CallbackArgs} = @@ -2338,8 +2351,9 @@ do_handle_trap(UserId, Mod, {fun() -> Mod:handle_trap(Target, SnmpTrapInfo, Data) end, [Target, SnmpTrapInfo, Data]}; addr_port -> - {fun() -> Mod:handle_trap(Addr, Port, SnmpTrapInfo, Data) end, - [Addr, Port, SnmpTrapInfo, Data]} + {Ip, Port} = Address, + {fun() -> Mod:handle_trap(Ip, Port, SnmpTrapInfo, Data) end, + [Ip, Port, SnmpTrapInfo, Data]} end, try HandleTrap() of @@ -2347,9 +2361,10 @@ do_handle_trap(UserId, Mod, ?vtrace("do_handle_trap -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), - Target2 = mk_target_name(Addr, Port, Config), - Config2 = [{reg_type, target_name}, - {address, Addr}, {port, Port} | Config], + Target2 = mk_target_name(Domain, Address, Config), + Config2 = + [{reg_type, target_name}, + {tdomain, Domain}, {taddress, Address} | Config], case snmpm_config:register_agent(UserId2, Target2, Config2) of ok -> ok; @@ -2357,7 +2372,7 @@ do_handle_trap(UserId, Mod, error_msg("failed registering agent " "handling trap " "<~p,~p>: ~n~w", - [Addr, Port, Reason]), + [Domain, Address, Reason]), ok end; {register, UserId2, Target2, Config} -> @@ -2375,20 +2390,19 @@ do_handle_trap(UserId, Mod, error_msg("failed registering agent " "handling trap " "~p <~p,~p>: ~n~w", - [Target2, Addr, Port, Reason]), + [Target2, Domain, Address, Reason]), reply end; unregister -> ?vtrace("do_handle_trap -> unregister", []), - case snmpm_config:unregister_agent(UserId, - Addr, Port) of + case snmpm_config:unregister_agent(UserId, Domain, Address) of ok -> ok; {error, Reason} -> error_msg("failed unregistering agent " "handling trap " "<~p,~p>: ~n~w", - [Addr, Port, Reason]), + [Domain, Address, Reason]), ok end; ignore -> @@ -2405,28 +2419,30 @@ do_handle_trap(UserId, Mod, end. -handle_snmp_inform(Ref, - #pdu{error_status = EStatus, - error_index = EIndex, - varbinds = Varbinds} = Pdu, Addr, Port, State) -> +handle_snmp_inform( + Ref, + #pdu{error_status = EStatus, + error_index = EIndex, + varbinds = Varbinds} = Pdu, Domain, Address, State) -> - ?vtrace("handle_snmp_inform -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n Pdu: ~p", [Addr, Port, Pdu]), + ?vtrace("handle_snmp_inform -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " Pdu: ~p", [Domain, Address, Pdu]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpInform = {EStatus, EIndex, Varbinds2}, - case snmpm_config:get_agent_user_info(Addr, Port) of + case snmpm_config:get_agent_user_info(Domain, Address) of {ok, UserId, Target, RegType} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> ?vdebug("[inform] callback handle_inform with: " "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), - handle_inform(UserId, Mod, Ref, - RegType, Target, Addr, Port, - SnmpInform, Data, State); + handle_inform( + UserId, Mod, Ref, + RegType, Target, Domain, Address, + SnmpInform, Data, State); Error1 -> %% User no longer exists, unregister agent case snmpm_config:unregister_agent(UserId, Target) of @@ -2437,15 +2453,16 @@ handle_snmp_inform(Ref, "~n ~p", [UserId, Error1]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> - handle_agent(DefUserId, DefMod, - Addr, Port, - inform, Ref, - SnmpInform, DefData, State); + handle_agent( + DefUserId, DefMod, + Domain, Address, + inform, Ref, + SnmpInform, DefData, State); Error2 -> error_msg("failed retreiving the default " "user info handling inform from " "~p <~p,~p>: ~n~w~n~w", - [Target, Addr, Port, + [Target, Domain, Address, Error2, Pdu]) end; Error3 -> @@ -2456,7 +2473,7 @@ handle_snmp_inform(Ref, "user ~p, handling inform: " "~n Error: ~w" "~n Pdu: ~w", - [Target, Addr, Port, UserId, + [Target, Domain, Address, UserId, Error3, Pdu]) end end; @@ -2464,42 +2481,46 @@ handle_snmp_inform(Ref, Error4 -> %% Unknown agent, pass it on to the default user ?vlog("[inform] failed retreiving user id for agent <~p,~p>: " - "~n ~p", [Addr, Port, Error4]), + "~n ~p", [Domain, Address, Error4]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> - handle_agent(DefUserId, DefMod, - Addr, Port, - inform, Ref, - SnmpInform, DefData, State); + handle_agent( + DefUserId, DefMod, + Domain, Address, + inform, Ref, + SnmpInform, DefData, State); Error5 -> error_msg("failed retreiving " "the default user info handling inform from " "<~p,~p>: ~n~w~n~w", - [Addr, Port, Error5, Pdu]) + [Domain, Address, Error5, Pdu]) end end, ok; -handle_snmp_inform(_Ref, CrapInform, Addr, Port, _State) -> +handle_snmp_inform(_Ref, CrapInform, Domain, Address, _State) -> error_msg("received crap (snmp) inform from ~w:~w =>" - "~p", [Addr, Port, CrapInform]), + "~p", [Domain, Address, CrapInform]), ok. -handle_inform(UserId, Mod, Ref, - RegType, Target, Addr, Port, SnmpInform, Data, State) -> +handle_inform( + UserId, Mod, Ref, + RegType, Target, Domain, Address, SnmpInform, Data, State) -> ?vtrace("handle_inform -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> - do_handle_inform(UserId, Mod, Ref, - RegType, Target, Addr, Port, SnmpInform, - Data, State) + do_handle_inform( + UserId, Mod, Ref, + RegType, Target, Domain, Address, SnmpInform, + Data, State) end, handle_callback(F), ok. -do_handle_inform(UserId, Mod, Ref, - RegType, Target, Addr, Port, SnmpInform, Data, State) -> +do_handle_inform( + UserId, Mod, Ref, + RegType, Target, Domain, Address, SnmpInform, Data, State) -> ?vdebug("do_handle_inform -> entry with" "~n UserId: ~p", [UserId]), {HandleInform, CallbackArgs} = @@ -2508,8 +2529,9 @@ do_handle_inform(UserId, Mod, Ref, {fun() -> Mod:handle_inform(Target, SnmpInform, Data) end, [Target, SnmpInform, Data]}; addr_port -> - {fun() -> Mod:handle_inform(Addr, Port, SnmpInform, Data) end, - [Addr, Port, SnmpInform, Data]} + {Ip, Port} = Address, + {fun() -> Mod:handle_inform(Ip, Port, SnmpInform, Data) end, + [Ip, Port, SnmpInform, Data]} end, Rep = @@ -2520,9 +2542,11 @@ do_handle_inform(UserId, Mod, Ref, "~n Config: ~p", [UserId2, Config]), %% The only user which would do this is the %% default user - Target2 = mk_target_name(Addr, Port, Config), - Config2 = [{reg_type, target_name}, - {address, Addr}, {port, Port} | Config], + Target2 = mk_target_name(Domain, Address, Config), + Config2 = + [{reg_type, target_name} | + ensure_present( + [{tdomain, Domain}, {taddress, Address}], Config)], case snmpm_config:register_agent(UserId2, Target2, Config2) of ok -> reply; @@ -2530,7 +2554,7 @@ do_handle_inform(UserId, Mod, Ref, error_msg("failed registering agent " "handling inform " "~p <~p,~p>: ~n~w", - [Target2, Addr, Port, Reason]), + [Target2, Domain, Address, Reason]), reply end; @@ -2549,21 +2573,21 @@ do_handle_inform(UserId, Mod, Ref, error_msg("failed registering agent " "handling inform " "~p <~p,~p>: ~n~w", - [Target2, Addr, Port, Reason]), + [Target2, Domain, Address, Reason]), reply end; unregister -> ?vtrace("do_handle_inform -> unregister", []), - case snmpm_config:unregister_agent(UserId, - Addr, Port) of + case snmpm_config:unregister_agent( + UserId, Domain, Address) of ok -> reply; {error, Reason} -> error_msg("failed unregistering agent " "handling inform " "<~p,~p>: ~n~w", - [Addr, Port, Reason]), + [Domain, Address, Reason]), reply end; @@ -2576,8 +2600,8 @@ do_handle_inform(UserId, Mod, Ref, reply; InvalidResult -> - handle_invalid_result(handle_inform, CallbackArgs, - InvalidResult), + handle_invalid_result( + handle_inform, CallbackArgs, InvalidResult), reply catch @@ -2586,31 +2610,34 @@ do_handle_inform(UserId, Mod, Ref, reply end, - handle_inform_response(Rep, Ref, Addr, Port, State), + handle_inform_response(Rep, Ref, Domain, Address, State), ok. -handle_inform_response(_, ignore, _Addr, _Port, _State) -> +handle_inform_response(_, ignore, _Domain, _Address, _State) -> ignore; -handle_inform_response(no_reply, _Ref, _Addr, _Port, _State) -> +handle_inform_response(no_reply, _Ref, _Domain, _Address, _State) -> no_reply; -handle_inform_response(_, Ref, Addr, Port, - #state{net_if = Pid, net_if_mod = Mod}) -> +handle_inform_response( + _, Ref, Domain, Address, + #state{net_if = Pid, net_if_mod = Mod}) -> ?vdebug("handle_inform -> response", []), - (catch Mod:inform_response(Pid, Ref, Addr, Port)). + (catch Mod:inform_response(Pid, Ref, Domain, Address)). -handle_snmp_report(#pdu{error_status = EStatus, - error_index = EIndex, - varbinds = Varbinds} = Pdu, Addr, Port, State) -> +handle_snmp_report( + #pdu{error_status = EStatus, + error_index = EIndex, + varbinds = Varbinds} = Pdu, + Domain, Address, State) -> - ?vtrace("handle_snmp_report -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n Pdu: ~p", [Addr, Port, Pdu]), + ?vtrace("handle_snmp_report -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " Pdu: ~p", [Domain, Address, Pdu]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpReport = {EStatus, EIndex, Varbinds2}, - case snmpm_config:get_agent_user_info(Addr, Port) of + case snmpm_config:get_agent_user_info(Domain, Address) of {ok, UserId, Target, RegType} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> @@ -2620,7 +2647,7 @@ handle_snmp_report(#pdu{error_status = EStatus, "~n ~p" "~n ~p", [UserId, Mod, Target, SnmpReport]), handle_report(UserId, Mod, - RegType, Target, Addr, Port, + RegType, Target, Domain, Address, SnmpReport, Data, State); Error1 -> %% User no longer exists, unregister agent @@ -2633,7 +2660,7 @@ handle_snmp_report(#pdu{error_status = EStatus, case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent(DefUserId, DefMod, - Addr, Port, + Domain, Address, report, ignore, SnmpReport, DefData, State); @@ -2641,7 +2668,7 @@ handle_snmp_report(#pdu{error_status = EStatus, error_msg("failed retreiving the default " "user info handling report from " "~p <~p,~p>: ~n~w~n~w", - [Target, Addr, Port, + [Target, Domain, Address, Error2, Pdu]) end; Error3 -> @@ -2652,7 +2679,7 @@ handle_snmp_report(#pdu{error_status = EStatus, "user ~p, handling report: " "~n Error: ~w" "~n Report: ~w", - [Target, Addr, Port, UserId, + [Target, Domain, Address, UserId, Error3, Pdu]) end end; @@ -2660,25 +2687,25 @@ handle_snmp_report(#pdu{error_status = EStatus, Error4 -> %% Unknown agent, pass it on to the default user ?vlog("[report] failed retreiving user id for agent <~p,~p>: " - "~n ~p", [Addr, Port, Error4]), + "~n ~p", [Domain, Address, Error4]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent(DefUserId, DefMod, - Addr, Port, + Domain, Address, report, ignore, SnmpReport, DefData, State); Error5 -> error_msg("failed retreiving " "the default user info handling report from " "<~p,~p>: ~n~w~n~w", - [Addr, Port, Error5, Pdu]) + [Domain, Address, Error5, Pdu]) end end, ok; -handle_snmp_report(CrapReport, Addr, Port, _State) -> +handle_snmp_report(CrapReport, Domain, Address, _State) -> error_msg("received crap (snmp) report from ~w:~w =>" - "~p", [Addr, Port, CrapReport]), + "~p", [Domain, Address, CrapReport]), ok. %% This could be from a failed get-request, so we might have a user @@ -2686,20 +2713,20 @@ handle_snmp_report(CrapReport, Addr, Port, _State) -> %% get-response (except for tha data which is different). Otherwise, %% we handle it as an error (reported via the handle_error callback %% function). -handle_snmp_report(ReqId, - #pdu{error_status = EStatus, - error_index = EIndex, - varbinds = Varbinds} = Pdu, - {ReportReason, Info} = Rep, - Addr, Port, State) - when is_integer(ReqId) -> - - ?vtrace("handle_snmp_report -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n ReqId: ~p" - "~n Rep: ~p" - "~n Pdu: ~p", [Addr, Port, ReqId, Rep, Pdu]), +handle_snmp_report( + ReqId, + #pdu{error_status = EStatus, + error_index = EIndex, + varbinds = Varbinds} = Pdu, + {ReportReason, Info} = Rep, + Domain, Address, State) when is_integer(ReqId) -> + + ?vtrace("handle_snmp_report -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " ReqId: ~p~n" + " Rep: ~p~n" + " Pdu: ~p", [Domain, Address, ReqId, Rep, Pdu]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpReport = {EStatus, EIndex, Varbinds2}, @@ -2744,7 +2771,7 @@ handle_snmp_report(ReqId, %% Either not a sync request or no such request. Either %% way, this is error info, so handle it as such. - case snmpm_config:get_agent_user_id(Addr, Port) of + case snmpm_config:get_agent_user_id(Domain, Address) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> @@ -2768,7 +2795,7 @@ handle_snmp_report(ReqId, "default user " "info handling report from " "<~p,~p>: ~n~w~n~w~n~w", - [Addr, Port, Error, + [Domain, Address, Error, ReqId, Reason]) end end; @@ -2776,7 +2803,7 @@ handle_snmp_report(ReqId, %% Unknown agent, pass it on to the default user ?vlog("[report] failed retreiving user id for " "agent <~p,~p>: " - "~n ~p", [Addr, Port, Error]), + "~n ~p", [Domain, Address, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_error(DefUserId, DefMod, Reason, ReqId, @@ -2786,32 +2813,36 @@ handle_snmp_report(ReqId, "the default user info handling " "report from " "<~p,~p>: ~n~w~n~w~n~w", - [Addr, Port, Error, ReqId, Reason]) + [Domain, Address, Error, ReqId, Reason]) end end end, ok; -handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Addr, Port, _State) -> - error_msg("received crap (snmp) report from ~w:~w =>" - "~n~p~n~p~n~p", [Addr, Port, CrapReqId, CrapReport, CrapInfo]), +handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Domain, Address, _State) -> + error_msg( + "received crap (snmp) report from ~w:~w =>" + "~n~p~n~p~n~p", + [Domain, Address, CrapReqId, CrapReport, CrapInfo]), ok. -handle_report(UserId, Mod, RegType, Target, Addr, Port, +handle_report(UserId, Mod, RegType, Target, Domain, Address, SnmpReport, Data, State) -> ?vtrace("handle_report -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> - do_handle_report(UserId, Mod, RegType, Target, Addr, Port, - SnmpReport, Data, State) + do_handle_report( + UserId, Mod, RegType, Target, Domain, Address, + SnmpReport, Data, State) end, handle_callback(F), ok. -do_handle_report(UserId, Mod, - RegType, Target, Addr, Port, SnmpReport, Data, _State) -> +do_handle_report( + UserId, Mod, RegType, Target, Domain, Address, + SnmpReport, Data, _State) -> ?vdebug("do_handle_report -> entry with" "~n UserId: ~p", [UserId]), {HandleReport, CallbackArgs} = @@ -2820,8 +2851,9 @@ do_handle_report(UserId, Mod, {fun() -> Mod:handle_report(Target, SnmpReport, Data) end, [Target, SnmpReport, Data]}; addr_port -> - {fun() -> Mod:handle_report(Addr, Port, SnmpReport, Data) end, - [Addr, Port, SnmpReport, Data]} + {Ip, Port} = Address, + {fun() -> Mod:handle_report(Ip, Port, SnmpReport, Data) end, + [Ip, Port, SnmpReport, Data]} end, try HandleReport() of @@ -2831,17 +2863,18 @@ do_handle_report(UserId, Mod, "~n Config: ~p", [UserId2, Config]), %% The only user which would do this is the %% default user - Target2 = mk_target_name(Addr, Port, Config), - Config2 = [{reg_type, target_name}, - {address, Addr}, {port, Port} | Config], + Target2 = mk_target_name(Domain, Address, Config), + Config2 = + [{reg_type, target_name}, + {tdomain, Domain}, {taddress, Address} | Config], case snmpm_config:register_agent(UserId2, Target2, Config2) of ok -> ok; {error, Reason} -> error_msg("failed registering agent " "handling report " - "<~p,~p>: ~n~w", - [Addr, Port, Reason]), + "<~p,~p>: ~n~w", + [Domain, Address, Reason]), ok end; @@ -2860,21 +2893,20 @@ do_handle_report(UserId, Mod, error_msg("failed registering agent " "handling report " "~p <~p,~p>: ~n~w", - [Target2, Addr, Port, Reason]), + [Target2, Domain, Address, Reason]), reply end; unregister -> ?vtrace("do_handle_trap -> unregister", []), - case snmpm_config:unregister_agent(UserId, - Addr, Port) of + case snmpm_config:unregister_agent(UserId, Domain, Address) of ok -> ok; {error, Reason} -> error_msg("failed unregistering agent " "handling report " "<~p,~p>: ~n~w", - [Addr, Port, Reason]), + [Domain, Address, Reason]), ok end; @@ -3012,50 +3044,49 @@ do_gc(Key, Now) -> %% %%---------------------------------------------------------------------- -send_get_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo, +send_get_request(Oids, Vsn, MsgData, Domain, Address, ExtraInfo, #state{net_if = NetIf, net_if_mod = Mod, mini_mib = MiniMIB}) -> Pdu = make_pdu(get, Oids, MiniMIB), - ?vtrace("send_get_request -> send get-request:" - "~n Mod: ~p" - "~n NetIf: ~p" - "~n Pdu: ~p" - "~n Vsn: ~p" - "~n MsgData: ~p" - "~n Domain: ~p" - "~n Addr: ~p" - "~n Port: ~p", - [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port]), + ?vtrace("send_get_request -> send get-request:~n" + " Mod: ~p~n" + " NetIf: ~p~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain: ~p~n" + " Address: ~p~n", + [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Address]), Res = (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, - Domain, Addr, Port, ExtraInfo)), + Domain, Address, ExtraInfo)), ?vtrace("send_get_request -> send result:" "~n ~p", [Res]), Pdu#pdu.request_id. -send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo, +send_get_next_request(Oids, Vsn, MsgData, Domain, Address, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(get_next, Oids, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo), Pdu#pdu.request_id. -send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr, Port, +send_get_bulk_request(Oids, Vsn, MsgData, Domain, Address, NonRep, MaxRep, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(bulk, {NonRep, MaxRep, Oids}, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo), Pdu#pdu.request_id. -send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, Port, ExtraInfo, +send_set_request(VarsAndVals, Vsn, MsgData, Domain, Address, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(set, VarsAndVals, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo), Pdu#pdu.request_id. %% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo, @@ -3291,10 +3322,9 @@ agent_data(TargetName, SendOpts) -> {Comm, SecModel} end, Domain = agent_data_item(tdomain, TargetName), - Addr = agent_data_item(address, TargetName), - Port = agent_data_item(port, TargetName), + Address = agent_data_item(taddress, TargetName), RegType = agent_data_item(reg_type, TargetName), - {ok, RegType, Domain, Addr, Port, version(Version), MsgData}; + {ok, RegType, Domain, Address, version(Version), MsgData}; Error -> Error end. @@ -3440,9 +3470,9 @@ maybe_demonitor(MonRef) -> t() -> {A,B,C} = erlang:now(), A*1000000000+B*1000+(C div 1000). - -mk_target_name(Addr, Port, Config) -> - snmpm_config:mk_target_name(Addr, Port, Config). + +mk_target_name(Domain, Address, Config) -> + snmpm_config:mk_target_name(Domain, Address, Config). default_agent_config() -> case snmpm_config:agent_info() of diff --git a/lib/snmp/src/manager/snmpm_user.erl b/lib/snmp/src/manager/snmpm_user.erl index e6b0b6943e..8e5a874f77 100644 --- a/lib/snmp/src/manager/snmpm_user.erl +++ b/lib/snmp/src/manager/snmpm_user.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -39,20 +39,25 @@ %% *** handle_error *** %% An "asynchronous" error has been detected --callback handle_error(ReqId :: integer(), - Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} | - {invalid_sec_info, SecInfo :: term(), SnmpInfo :: snmp_gen_info()} | - {empty_message, Addr :: ip_address(), Port :: port_number()} | - term(), - UserData :: term()) -> +-callback handle_error( + ReqId :: integer(), + Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} | + {invalid_sec_info, + SecInfo :: term(), + SnmpInfo :: snmp_gen_info()} | + {empty_message, + TransportDomain :: atom(), + {Addr :: ip_address(), Port :: port_number()}} | + term(), + UserData :: term()) -> snmp:void(). %% *** handle_agent *** %% A message was received from an unknown agent --callback handle_agent(Addr :: term(), - Port :: pos_integer(), +-callback handle_agent(Domain :: atom(), + Address :: term(), Type :: pdu | trap | inform | report, SnmpInfo :: snmp_gen_info() | snmp_v1_trap_info(), UserData :: term()) -> diff --git a/lib/snmp/src/manager/snmpm_user_default.erl b/lib/snmp/src/manager/snmpm_user_default.erl index 015198cb76..b827713f27 100644 --- a/lib/snmp/src/manager/snmpm_user_default.erl +++ b/lib/snmp/src/manager/snmpm_user_default.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2013. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -36,13 +36,13 @@ handle_error(ReqId, Reason, UserData) -> ignore. -handle_agent(Addr, Port, Type, SnmpInfo, UserData) -> - info("received handle_agent:" - "~n Addr: ~p" - "~n Port: ~p" - "~n Type: ~p" - "~n SnmpInfo: ~p" - "~n UserData: ~p", [Addr, Port, Type, SnmpInfo, UserData]), +handle_agent(Domain, Address, Type, SnmpInfo, UserData) -> + info("received handle_agent:~n" + " Domain: ~p~n" + " Address: ~p~n" + " Type: ~p~n" + " SnmpInfo: ~p~n" + " UserData: ~p", [Domain, Address, Type, SnmpInfo, UserData]), ignore. diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index d8a19c7137..105652cdda 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -45,7 +45,8 @@ mk_tdomain/1, which_domain/1, check_ip/1, check_ip/2, - check_address_no_port/2, check_port/1, + check_port/1, + fix_domain_address/2, check_address/2, check_address/3, check_taddress/2, mk_taddress/2, @@ -693,19 +694,25 @@ mk_taddress(BadDomain, _) -> %% --------- -%% XXX remove +%% XXX remove, when net_if handles one socket per transport domain -which_domain([A0,A1,A2,A3]) when ?is_ipv4_addr(A0, A1, A2, A3) -> +which_domain([A0,A1,A2,A3]) + when ?is_ipv4_addr(A0, A1, A2, A3) -> transportDomainUdpIpv4; -which_domain({A0,A1,A2,A3}) when ?is_ipv4_addr(A0, A1, A2, A3) -> +which_domain({A0, A1, A2, A3}) + when ?is_ipv4_addr(A0, A1, A2, A3) -> transportDomainUdpIpv4; which_domain([A0,A1,A2,A3,A4,A5,A6,A7]) when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) -> transportDomainUdpIpv6; +which_domain([A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15]) + when ?is_ipv6_addr( + A0, A1, A2, A3, A4, A5, A6, A7, + A8, A9, A10, A11, A12, A13, A14, A15) -> + transportDomainUdpIpv6; which_domain({A0, A1, A2, A3, A4, A5, A6, A7}) when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) -> transportDomainUdpIpv6. - %% --------- @@ -742,34 +749,30 @@ check_ip(BadDomain, _X) -> %% --------- -%% check_address_default_port(Domain, Address) -> -%% case check_address_ip(Domain, Address) of -%% false -> -%% case check_address_ip_port(Domain, Address) of -%% false -> -%% error({bad_address, {Domain, Address}}); -%% _ -> -%% ok -%% end; -%% _ -> -%% ok -%% end. - -check_address_no_port(Domain, Address) -> - case check_address_ip(Domain, Address) of - false -> - error({bad_address, {Domain, Address}}); - true -> - ok; - FixedIP -> - {ok, FixedIP} - end. - check_port(Port) when ?is_word(Port) -> ok; check_port(Port) -> error({bad_port, Port}). +fix_domain_address(IP, Port) when ?is_word(Port) -> + case check_address_ip(transportDomainUdpIpv4, IP) of + false -> + case check_address_ip(transportDomainUdpIpv6, IP) of + false -> + error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}); + true -> + {transportDomainUdpIpv6, {IP, Port}}; + FixedIP -> + {transportDomainUdpIpv6, {FixedIP, Port}} + end; + true -> + {transportDomainUdpIpv4, {IP, Port}}; + FixedIP -> + {transportDomainUdpIpv4, {FixedIP, Port}} + end; +fix_domain_address(IP, Port) -> + error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}). + %% Check a configuration term field from a file to see if it %% can be fixed to be fed to mk_taddress/2. diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 90f9ef2026..52b58ecea8 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -5074,7 +5074,7 @@ inform_swarm_collector(N) -> inform_swarm_collector(N, SentAckCnt, RecvCnt, RespCnt, _) when ((N == SentAckCnt) and (N == RespCnt) and - (N >= RecvCnt)) -> + (N =< RecvCnt)) -> p("inform_swarm_collector -> done when" "~n N: ~w" "~n SentAckCnt: ~w" -- cgit v1.2.3 From 89ca2960d421a43bced0a9f228a62b8ab3089663 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 2 May 2014 16:47:52 +0200 Subject: wip: passes all regression tests --- lib/snmp/src/agent/snmpa_agent.erl | 9 +- lib/snmp/src/agent/snmpa_mpd.erl | 4 +- lib/snmp/src/agent/snmpa_net_if.erl | 336 +++++++++++++---------------- lib/snmp/src/agent/snmpa_net_if_filter.erl | 50 +++-- lib/snmp/test/klas3.erl | 12 +- lib/snmp/test/snmp_agent_test.erl | 8 +- 6 files changed, 205 insertions(+), 214 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index 9bed6e554e..dadd9d7ccd 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -2512,10 +2512,11 @@ handle_mib_of(MibServer, Oid) -> %% Func: process_msg/7 %% Returns: RePdu %%----------------------------------------------------------------- -process_msg(MibView, Vsn, Pdu, PduMS, Community, {Ip, Udp}, ContextName, - GbMaxVBs) -> +process_msg( + MibView, Vsn, Pdu, PduMS, Community, + SourceAddress, ContextName, GbMaxVBs) -> #pdu{request_id = ReqId} = Pdu, - put(snmp_address, {tuple_to_list(Ip), Udp}), + put(snmp_address, SourceAddress), put(snmp_request_id, ReqId), put(snmp_community, Community), put(snmp_context, ContextName), diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index 2db98d9fc2..c189a4eae2 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -1010,7 +1010,7 @@ generate_discovery_msg(NoteStore, {TDomain, TAddress}, InitialUserName, ContextName, Timeout) -> - {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress), + {ok, {Domain, Address}} = transform_taddr(TDomain, TAddress), %% 7.1.7 ?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]), @@ -1052,7 +1052,7 @@ generate_discovery_msg(NoteStore, {TDomain, TAddress}, %% Log(Packet), inc_snmp_out_vars(Pdu), ?vdebug("generate_discovery_msg -> done", []), - {Packet, Address}; + {Domain, Address, Packet}; Error -> throw(Error) diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 79c85a6e4e..dac172ea11 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2014. 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 @@ -129,7 +129,14 @@ init(Prio, NoteStore, MasterAgent, Parent, Opts) -> case (catch do_init(Prio, NoteStore, MasterAgent, Parent, Opts)) of {ok, State} -> proc_lib:init_ack({ok, self()}), - loop(State); + try loop(State) + catch C:E -> + S = erlang:get_stacktrace(), + error_msg( + "loop/1 EXCEPTION ~w:~w~n" + " ~p", [C,E,S]), + erlang:raise(C, E, S) + end; {error, Reason} -> config_err("failed starting net-if: ~n~p", [Reason]), proc_lib:init_ack({error, Reason}); @@ -252,24 +259,24 @@ create_filter(BadOpts) -> log({_, []}, _, _, _, _) -> ok; -log({Log, Types}, 'set-request', Packet, Addr, Port) -> +log({Log, Types}, 'set-request', Packet, Domain, Address) -> case lists:member(write, Types) of true -> - snmp_log:log(Log, Packet, Addr, Port); + snmp_log:log(Log, Packet, Domain, Address); false -> ok end; -log({Log, Types}, _, Packet, Addr, Port) -> +log({Log, Types}, _, Packet, Domain, Address) -> case lists:member(read, Types) of true -> - snmp_log:log(Log, Packet, Addr, Port); + snmp_log:log(Log, Packet, Domain, Address); false -> ok end; log(_, _, _, _, _) -> ok. - - + + gen_udp_open(Port, Opts) -> case init:get_argument(snmp_fd) of {ok, [[FdStr]]} -> @@ -290,7 +297,8 @@ loop(S) -> receive {udp, _UdpId, Ip, Port, Packet} -> ?vlog("got paket from ~w:~w",[Ip,Port]), - NewS = maybe_handle_recv(S, Ip, Port, Packet), + {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + NewS = maybe_handle_recv(S, Domain, Address, Packet), loop(NewS); {info, ReplyRef, Pid} -> @@ -510,18 +518,18 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, maybe_handle_recv(#state{usock = Sock, filter = FilterMod} = S, - Ip, Port, Packet) -> - case (catch FilterMod:accept_recv(Ip, Port)) of + Domain, Address, Packet) -> + case (catch FilterMod:accept_recv(Domain, Address)) of false -> %% Drop the received packet inc(netIfMsgInDrops), active_once(Sock), S; _ -> - handle_recv(S, Ip, Port, Packet) + handle_recv(S, Domain, Address, Packet) end. -handle_discovery_response(_Ip, _Port, #pdu{request_id = ReqId} = Pdu, +handle_discovery_response(_Domain, _Address, #pdu{request_id = ReqId} = Pdu, ManagerEngineId, #state{usock = Sock, reqs = Reqs} = S) -> case lists:keysearch(ReqId, 1, S#state.reqs) of @@ -538,26 +546,24 @@ handle_discovery_response(_Ip, _Port, #pdu{request_id = ReqId} = Pdu, handle_recv(#state{usock = Sock, mpd_state = MpdState, note_store = NS, - log = Log} = S, Ip, Port, Packet) -> + log = Log} = S, Domain, Address, Packet) -> put(n1, erlang:now()), LogF = fun(Type, Data) -> - log(Log, Type, Data, Ip, Port) + log(Log, Type, Data, Domain, Address) end, - Domain = snmp_conf:which_domain(Ip), % What the ****... - case (catch snmpa_mpd:process_packet(Packet, - Domain, {Ip, Port}, - MpdState, NS, LogF)) of + case (catch snmpa_mpd:process_packet( + Packet, Domain, Address, MpdState, NS, LogF)) of {ok, _Vsn, Pdu, _PduMS, {discovery, ManagerEngineId}} -> - handle_discovery_response(Ip, Port, Pdu, ManagerEngineId, S); + handle_discovery_response(Domain, Address, Pdu, ManagerEngineId, S); {ok, _Vsn, Pdu, _PduMS, discovery} -> - handle_discovery_response(Ip, Port, Pdu, undefined, S); + handle_discovery_response(Domain, Address, Pdu, undefined, S); {ok, Vsn, Pdu, PduMS, ACMData} -> ?vlog("got pdu ~s", [?vapply(snmp_misc, format, [256, "~w", [Pdu]])]), - %% handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S); - maybe_handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S); + %% handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S); + maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S); {discarded, Reason} -> ?vlog("packet discarded for reason: ~s", @@ -569,12 +575,14 @@ handle_recv(#state{usock = Sock, ?vlog("sending report for reason: " "~n ~s", [?vapply(snmp_misc, format, [256, "~w", [Reason]])]), + {Ip, Port} = Address, (catch udp_send(S#state.usock, Ip, Port, ReportPacket)), active_once(Sock), S; {discovery, ReportPacket} -> ?vlog("sending discovery report", []), + {Ip, Port} = Address, (catch udp_send(S#state.usock, Ip, Port, ReportPacket)), active_once(Sock), S; @@ -586,65 +594,72 @@ handle_recv(#state{usock = Sock, S end. -maybe_handle_recv_pdu(Ip, Port, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, - #state{usock = Sock, filter = FilterMod} = S) -> - case (catch FilterMod:accept_recv_pdu(Ip, Port, Type)) of +maybe_handle_recv_pdu( + Domain, Address, Vsn, + #pdu{type = Type} = Pdu, PduMS, ACMData, + #state{usock = Sock, filter = FilterMod} = S) -> + case (catch FilterMod:accept_recv_pdu(Domain, Address, Type)) of false -> inc(netIfPduInDrops), active_once(Sock), ok; _ -> - handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S) + handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S) end; -maybe_handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S) -> - handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, S). +maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S) -> + handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S). -handle_recv_pdu(Ip, Port, Vsn, #pdu{type = 'get-response'} = Pdu, - _PduMS, _ACMData, #state{usock = Sock} = S) -> +handle_recv_pdu( + Domain, Address, Vsn, + #pdu{type = 'get-response'} = Pdu, _PduMS, _ACMData, + #state{usock = Sock} = S) -> active_once(Sock), - handle_response(Vsn, Pdu, {Ip, Port}, S), + handle_response(Vsn, Pdu, {Domain, Address}, S), S; -handle_recv_pdu(Ip, Port, Vsn, #pdu{request_id = Rid, type = Type} = Pdu, +handle_recv_pdu(Domain, Address, Vsn, #pdu{request_id = Rid, type = Type} = Pdu, PduMS, ACMData, #state{master_agent = Pid} = S) when ((Type =:= 'get-request') orelse (Type =:= 'get-next-request') orelse (Type =:= 'get-bulk-request')) -> ?vtrace("handle_recv_pdu -> received get (~w)", [Type]), - Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, {Ip, Port}, []}, + SourceAddress = {Domain, Address}, + Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, SourceAddress, []}, update_req_counter_incomming(S, Rid); -handle_recv_pdu(Ip, Port, Vsn, Pdu, PduMS, ACMData, +handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, #state{usock = Sock, master_agent = Pid} = S) -> ?vtrace("handle_recv_pdu -> received other request", []), active_once(Sock), - Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, {Ip, Port}, []}, + SourceAddress = {Domain, Address}, + Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, SourceAddress, []}, S. -maybe_handle_reply_pdu(#state{filter = FilterMod} = S, Vsn, - #pdu{request_id = Rid} = Pdu, - Type, ACMData, {Ip, Port} = Dest) -> +maybe_handle_reply_pdu( + #state{filter = FilterMod} = S, Vsn, + #pdu{request_id = Rid} = Pdu, + Type, ACMData, DestinationAddress) -> S1 = update_req_counter_outgoing(S, Rid), - case (catch FilterMod:accept_send_pdu([{Ip, Port}], Type)) of + case (catch FilterMod:accept_send_pdu([DestinationAddress], Type)) of false -> inc(netIfPduOutDrops), ok; _ -> - handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, Dest) + handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, DestinationAddress) end, S1. handle_reply_pdu(#state{log = Log, usock = Sock, filter = FilterMod}, - Vsn, Pdu, Type, ACMData, {Ip, Port}) -> + Vsn, Pdu, Type, ACMData, {Domain, Address}) -> LogF = fun(Type2, Data) -> - log(Log, Type2, Data, Ip, Port) + log(Log, Type2, Data, Domain, Address) end, case (catch snmpa_mpd:generate_response_msg(Vsn, Pdu, Type, ACMData, LogF)) of {ok, Packet} -> ?vinfo("time in agent: ~w mysec", [time_in_agent()]), - maybe_udp_send(FilterMod, Sock, Ip, Port, Packet); + maybe_udp_send(FilterMod, Sock, Domain, Address, Packet); {discarded, Reason} -> ?vlog("handle_reply_pdu -> " "~n reply discarded for reason: ~s", @@ -652,79 +667,68 @@ handle_reply_pdu(#state{log = Log, ok; {'EXIT', Reason} -> user_err("failed generating response message: " - "~nPDU: ~w~n~w", [Pdu, Reason]) + "~nPDU: ~p~n~p", [Pdu, Reason]) end. - -process_taddrs(To) -> - process_taddrs(To, []). -process_taddrs([], Acc) -> - lists:reverse(Acc); -%% v3 -process_taddrs([{{_Domain, AddrAndPort}, _SecData}|T], Acc) -> - process_taddrs(T, [AddrAndPort|Acc]); -%% v1 & v2 -process_taddrs([{_Domain, AddrAndPort}|T], Acc) -> - process_taddrs(T, [AddrAndPort|Acc]). -merge_taddrs(To1, To2) -> - merge_taddrs(To1, To2, []). +maybe_handle_send_pdu( + #state{filter = FilterMod} = S, + Vsn, Pdu, MsgData, To0, From) -> -merge_taddrs([], _To2, Acc) -> - lists:reverse(Acc); -%% v3 -merge_taddrs([{{_, AddrAndPort}, _} = H|To1], To2, Acc) -> - case lists:member(AddrAndPort, To2) of - true -> - merge_taddrs(To1, To2, [H|Acc]); - false -> - merge_taddrs(To1, To2, Acc) - end; -%% v1 & v2 -merge_taddrs([{_, AddrAndPort} = H|To1], To2, Acc) -> - case lists:member(AddrAndPort, To2) of - true -> - merge_taddrs(To1, To2, [H|Acc]); - false -> - merge_taddrs(To1, To2, Acc) - end; -merge_taddrs([_Crap|To1], To2, Acc) -> - merge_taddrs(To1, To2, Acc). - - -maybe_handle_send_pdu(#state{filter = FilterMod} = S, - Vsn, Pdu, MsgData, To0, From) -> + ?vtrace("maybe_handle_send_pdu -> entry with~n" + " FilterMod: ~p~n" + " To0: ~p", [FilterMod, To0]), - ?vtrace("maybe_handle_send_pdu -> entry with" - "~n FilterMod: ~p" - "~n To0: ~p", [FilterMod, To0]), + To = snmpa_mpd:process_taddrs(To0), + Destinations = + [case T of + {{Domain, _Address} = Destination, _SecData} + when is_atom(Domain) -> % v3 + Destination; + {Domain, _Address} = Destination + when is_atom(Domain) -> % v1 & v2 + Destination + end || T <- To], - To1 = snmpa_mpd:process_taddrs(To0), - To2 = process_taddrs(To1), - - case (catch FilterMod:accept_send_pdu(To2, pdu_type_of(Pdu))) of + case (catch FilterMod:accept_send_pdu( + Destinations, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; true -> - handle_send_pdu(S, Vsn, Pdu, MsgData, To1, From); - To3 when is_list(To3) -> - To4 = merge_taddrs(To1, To3), - ?vtrace("maybe_handle_send_pdu -> To4: " - "~n ~p", [To4]), - handle_send_pdu(S, Vsn, Pdu, MsgData, To4, From); - _ -> - handle_send_pdu(S, Vsn, Pdu, MsgData, To1, From) + handle_send_pdu(S, Vsn, Pdu, MsgData, To, From); + FilteredDestinations when is_list(FilteredDestinations) -> + MergedTo = + [T || T <- To, + case T of + {{Dom, _Addr} = Dest, _SData} + when is_atom(Dom) -> % v3 + lists:member( + Dest, FilteredDestinations); + {Dom, _Addr} = Dest + when is_atom(Dom) -> % v1 & v2 + lists:member( + Dest, FilteredDestinations) + end], + ?vtrace("maybe_handle_send_pdu -> MergedTo:~n" + " ~p", [MergedTo]), + handle_send_pdu(S, Vsn, Pdu, MsgData, MergedTo, From); + Other -> + error_msg( + "FilterMod:accept_send_pdu/2 returned: ~p", [Other]), + handle_send_pdu(S, Vsn, Pdu, MsgData, To, From) end. -handle_send_pdu(#state{note_store = NS} = S, Vsn, Pdu, MsgData, To, From) -> +handle_send_pdu( + #state{note_store = NS} = S, Vsn, Pdu, MsgData, To, From) -> - ?vtrace("handle_send_pdu -> entry with" - "~n Pdu: ~p" - "~n To: ~p", [Pdu, To]), + ?vtrace("handle_send_pdu -> entry with~n" + " Pdu: ~p~n" + " To: ~p", [Pdu, To]), - case (catch snmpa_mpd:generate_msg(Vsn, NS, Pdu, MsgData, To)) of + case (catch snmpa_mpd:generate_msg( + Vsn, NS, Pdu, MsgData, To)) of {ok, Addresses} -> handle_send_pdu(S, Pdu, Addresses); {discarded, Reason} -> @@ -733,7 +737,7 @@ handle_send_pdu(#state{note_store = NS} = S, Vsn, Pdu, MsgData, To, From) -> ok; {'EXIT', Reason} -> user_err("failed generating message: " - "~nPDU: ~w~n~w", [Pdu, Reason]), + "~nPDU: ~p~n~p", [Pdu, Reason]), ok end, case From of @@ -742,15 +746,20 @@ handle_send_pdu(#state{note_store = NS} = S, Vsn, Pdu, MsgData, To, From) -> Pid -> ?vtrace("link to ~p and add to request list", [Pid]), link(Pid), - NReqs = snmp_misc:keyreplaceadd(Pid, 2, S#state.reqs, - {Pdu#pdu.request_id, From}), + NReqs = snmp_misc:keyreplaceadd( + Pid, 2, S#state.reqs, {Pdu#pdu.request_id, From}), S#state{reqs = NReqs} end. -handle_send_discovery(#state{note_store = NS} = S, - Pdu, MsgData, - To, From) -> +handle_send_discovery( + #state{note_store = NS, + log = Log, + usock = Sock, + reqs = Reqs} = S, + #pdu{type = Type, + request_id = ReqId} = Pdu, + MsgData, To, From) -> ?vtrace("handle_send_discovery -> entry with" "~n Pdu: ~p" @@ -759,32 +768,24 @@ handle_send_discovery(#state{note_store = NS} = S, "~n From: ~p", [Pdu, MsgData, To, From]), case (catch snmpa_mpd:generate_discovery_msg(NS, Pdu, MsgData, To)) of - {ok, {Packet, {Ip, Port}}} -> - handle_send_discovery(S, Pdu, Packet, Ip, Port, From); + {ok, {Domain, Address, Packet}} -> + log(Log, Type, Packet, Domain, Address), + {Ip, Port} = Address, + udp_send(Sock, Ip, Port, Packet), + ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]), + NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}), + S#state{reqs = NReqs}; {discarded, Reason} -> ?vlog("handle_send_discovery -> " "~n Discovery PDU ~p not sent due to ~p", [Pdu, Reason]), ok; {'EXIT', Reason} -> user_err("failed generating discovery message: " - "~n PDU: ~w" - "~n Reason: ~w", [Pdu, Reason]), + "~n PDU: ~p" + "~n Reason: ~p", [Pdu, Reason]), ok end. -handle_send_discovery(#state{log = Log, - usock = Sock, - reqs = Reqs} = S, - #pdu{type = Type, - request_id = ReqId}, - Packet, Ip, Port, From) - when is_binary(Packet) -> - log(Log, Type, Packet, Ip, Port), - udp_send(Sock, Ip, Port, Packet), - ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]), - NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}), - S#state{reqs = NReqs}. - handle_send_pdu(S, #pdu{type = Type} = Pdu, Addresses) -> handle_send_pdu(S, Type, Pdu, Addresses); @@ -806,61 +807,23 @@ handle_send_pdu(S, Type, Pdu, Addresses) -> handle_send_pdu1(#state{log = Log, usock = Sock, filter = FilterMod}, Type, Addresses) -> - SendFun = - 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); - - ({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]), - maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet); - - (_X) -> - ?vlog("** bad res: ~p", [_X]), - ok - end, - lists:foreach(SendFun, Addresses). - + lists:foreach( + fun ({Domain, Address, Packet}) when is_binary(Packet) -> + ?vdebug( + "[~w] sending packet:~n" + " size: ~p~n" + " to: ~p", [Domain, sz(Packet), Address]), + maybe_udp_send( + FilterMod, Log, Type, Sock, Domain, Address, Packet); + ({Domain, Address, {Packet, _LogData}}) when is_binary(Packet) -> + ?vdebug( + "[~w] sending encrypted packet:~n" + " size: ~p~n" + " to: ~p", [Domain, sz(Packet), Address]), + maybe_udp_send( + FilterMod, Log, Type, Sock, Domain, Address, Packet) + end, + Addresses). handle_response(Vsn, Pdu, From, S) -> case lists:keysearch(Pdu#pdu.request_id, 1, S#state.reqs) of @@ -873,26 +836,27 @@ handle_response(Vsn, Pdu, From, S) -> "~n No receiver available for response pdu", []) end. -maybe_udp_send(FilterMod, Sock, Ip, Port, Packet) -> - case (catch FilterMod:accept_send(Ip, Port)) of +maybe_udp_send(FilterMod, Sock, Domain, Address, Packet) -> + case (catch FilterMod:accept_send(Domain, Address)) of false -> inc(netIfMsgOutDrops), ok; _ -> + {Ip, Port} = Address, (catch udp_send(Sock, Ip, Port, Packet)) end. -maybe_udp_send(FilterMod, AtLog, Type, Sock, Ip, Port, Packet) -> - case (catch FilterMod:accept_send(Ip, Port)) of +maybe_udp_send(FilterMod, AtLog, Type, Sock, Domain, Address, Packet) -> + case (catch FilterMod:accept_send(Domain, Address)) of false -> inc(netIfMsgOutDrops), ok; _ -> - log(AtLog, Type, Packet, Ip, Port), + log(AtLog, Type, Packet, Domain, Address), + {Ip, Port} = Address, (catch udp_send(Sock, Ip, Port, Packet)) end. - udp_send(UdpId, AgentIp, UdpPort, B) -> case (catch gen_udp:send(UdpId, AgentIp, UdpPort, B)) of {error, emsgsize} -> diff --git a/lib/snmp/src/agent/snmpa_net_if_filter.erl b/lib/snmp/src/agent/snmpa_net_if_filter.erl index 989f7c95b3..871c4f05da 100644 --- a/lib/snmp/src/agent/snmpa_net_if_filter.erl +++ b/lib/snmp/src/agent/snmpa_net_if_filter.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2014. 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 @@ -25,28 +25,44 @@ -include("snmp_debug.hrl"). -accept_recv(_Addr, _Port) -> - ?d("accept_recv -> entry with" - "~n Addr: ~p" - "~n Port: ~p", [_Addr, _Port]), +accept_recv(Domain, _Address) when is_atom(Domain) -> + ?d("accept_recv -> entry with~n" + " Domain: ~p~n" + " Address: ~p", [Domain, _Address]), + true; +accept_recv(_Addr, Port) when is_integer(Port) -> + ?d("accept_recv -> entry with~n" + " Addr: ~p~n" + " Port: ~p", [_Addr, Port]), true. -accept_send(_Addr, _Port) -> - ?d("accept_send -> entry with" - "~n Addr: ~p" - "~n Port: ~p", [_Addr, _Port]), +accept_send(Domain, _Address) when is_atom(Domain) -> + ?d("accept_send -> entry with~n" + " Domain: ~p~n" + " Address: ~p", [Domain, _Address]), + true; +accept_send(_Addr, Port) when is_integer(Port) -> + ?d("accept_send -> entry with~n" + " Addr: ~p~n" + " Port: ~p", [_Addr, Port]), true. -accept_recv_pdu(_Addr, _Port, _PduType) -> - ?d("accept_recv_pdu -> entry with" - "~n Addr: ~p" - "~n Port: ~p" - "~n PduType: ~p", [_Addr, _Port, _PduType]), +accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> + ?d("accept_recv -> entry with~n" + " Domain: ~p~n" + " Address: ~p~n" + " PduType: ~p", [Domain, _Address, _PduType]), + true; +accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) -> + ?d("accept_recv_pdu -> entry with~n" + " Addr: ~p~n" + " Port: ~p~n" + " PduType: ~p", [_Addr, Port, _PduType]), true. accept_send_pdu(_Targets, _PduType) -> - ?d("accept_send_pdu -> entry with" - "~n Targets: ~p" - "~n PduType: ~p", [_Targets, _PduType]), + ?d("accept_send_pdu -> entry with~n" + " Targets: ~p~n" + " PduType: ~p", [_Targets, _PduType]), true. diff --git a/lib/snmp/test/klas3.erl b/lib/snmp/test/klas3.erl index ec78d19dbb..4c7c03e2ca 100644 --- a/lib/snmp/test/klas3.erl +++ b/lib/snmp/test/klas3.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. 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 @@ -67,8 +67,11 @@ fname(get) -> end, case snmpa:current_address() of {value, {[_A,_B,_C,_D], E}} when is_integer(E) -> ok; - {value, _} -> throw("bad_ip"); - _ -> throw("bad_adr") + {value, {D, _}} when is_atom(D) -> ok; + {value, Ip} -> + throw(format_string("bad_ip: ~p", [Ip])); + Other -> + throw(format_string("bad_adr: ~p", [Other])) end, case snmpa:current_net_if_data() of {value, []} -> ok; @@ -160,3 +163,6 @@ ftab2(get_next, [9], _Cols) -> % bad return value io:format("** Here comes Error Report get_next 3 bad return~n"), [{[1,5],1},{[2,5],3},{[2,6],3}]. + +format_string(Format, Args) -> + lists:flatten(io_lib:format(Format, Args)). diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 2a9f2e842d..bcc89b93de 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2013. All Rights Reserved. +%% Copyright Ericsson AB 2003-2014. 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 @@ -1794,7 +1794,11 @@ init_v3(Config) when is_list(Config) -> Ip = ?config(ip, Config), ?line ok = config([v3], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip)), - [{vsn, v3} | start_v3_agent(Config)]. + Opts = + [{master_agent_verbosity, trace}, + {agent_verbosity, trace}, + {net_if_verbosity, trace}], + [{vsn, v3} | start_v3_agent(Config, Opts)]. finish_v3(Config) when is_list(Config) -> delete_tables(), -- cgit v1.2.3 From 382e91a930b3d20d4e4cce14ea6c3cbc7e4397d7 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 7 May 2014 08:43:07 +0200 Subject: Rewrite agent to use {Domain,Address} tuples as far as possible --- lib/snmp/src/agent/snmpa_mpd.erl | 57 +++-- lib/snmp/src/agent/snmpa_net_if.erl | 262 +++++++++++---------- lib/snmp/src/agent/snmpa_net_if_filter.erl | 25 +- .../src/agent/snmpa_network_interface_filter.erl | 17 +- lib/snmp/src/manager/snmpm_config.erl | 6 +- lib/snmp/src/manager/snmpm_net_if.erl | 2 +- lib/snmp/src/manager/snmpm_net_if_mt.erl | 2 +- lib/snmp/src/misc/snmp_conf.erl | 6 +- 8 files changed, 205 insertions(+), 172 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index c189a4eae2..3caed27c42 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -20,7 +20,7 @@ -export([init/1, reset/0, inc/1, counters/0, discarded_pdu/1, - process_packet/6, process_packet/7, + process_packet/5, process_packet/6, process_packet/7, generate_response_msg/5, generate_response_msg/6, generate_msg/5, generate_msg/6, generate_discovery_msg/4, @@ -113,22 +113,30 @@ reset() -> % length(snmp_pdus:enc_message(M)) + 4. %%----------------------------------------------------------------- -%% Func: process_packet(Packet, TDomain, TAddress, State, Log) -> +%% Func: process_packet(Packet, Domain, Address, State, Log) -> %% {ok, SnmpVsn, Pdu, PduMS, ACMData} | {discarded, Reason} %% Types: Packet = binary() -%% TDomain = snmpUDPDomain | transportDomain() -%% TAddress = {Ip, Udp} (*but* depends on TDomain) +%% Domain = snmpUDPDomain | transportDomain() +%% Address = {Ip, Udp} (*but* depends on Domain) %% State = #state %% Purpose: This is the main Message Dispatching function. (see %% section 4.2.1 in rfc2272) %%----------------------------------------------------------------- -process_packet(Packet, TDomain, TAddress, State, NoteStore, Log) -> +process_packet(Packet, From, State, NoteStore, Log) -> LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, - process_packet(Packet, TDomain, TAddress, LocalEngineID, - State, NoteStore, Log). - -process_packet(Packet, TDomain, TAddress, LocalEngineID, - State, NoteStore, Log) -> + process_packet(Packet, From, LocalEngineID, State, NoteStore, Log). + +process_packet( + Packet, Domain, Address, LocalEngineID, State, NoteStore, Log) -> + From = {Domain, Address}, + process_packet(Packet, From, LocalEngineID, State, NoteStore, Log). + +process_packet(Packet, Domain, Address, State, NoteStore, Log) + when is_atom(Domain) -> + LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, + From = {Domain, Address}, + process_packet(Packet, From, LocalEngineID, State, NoteStore, Log); +process_packet(Packet, From, LocalEngineID, State, NoteStore, Log) -> inc(snmpInPkts), case catch snmp_pdus:dec_message_only(binary_to_list(Packet)) of @@ -136,17 +144,17 @@ process_packet(Packet, TDomain, TAddress, LocalEngineID, when State#state.v1 =:= true -> ?vlog("v1, community: ~s", [Community]), HS = ?empty_msg_size + length(Community), - v1_v2c_proc('version-1', NoteStore, Community, - TDomain, TAddress, - LocalEngineID, Data, HS, Log, Packet); + v1_v2c_proc( + 'version-1', NoteStore, Community, From, + LocalEngineID, Data, HS, Log, Packet); #message{version = 'version-2', vsn_hdr = Community, data = Data} when State#state.v2c =:= true -> ?vlog("v2c, community: ~s", [Community]), HS = ?empty_msg_size + length(Community), - v1_v2c_proc('version-2', NoteStore, Community, - TDomain, TAddress, - LocalEngineID, Data, HS, Log, Packet); + v1_v2c_proc( + 'version-2', NoteStore, Community, From, + LocalEngineID, Data, HS, Log, Packet); #message{version = 'version-3', vsn_hdr = V3Hdr, data = Data} when State#state.v3 =:= true -> @@ -154,9 +162,9 @@ process_packet(Packet, TDomain, TAddress, LocalEngineID, [V3Hdr#v3_hdr.msgID, V3Hdr#v3_hdr.msgFlags, V3Hdr#v3_hdr.msgSecurityModel]), - v3_proc(NoteStore, Packet, - TDomain, TAddress, - LocalEngineID, V3Hdr, Data, Log); + v3_proc( + NoteStore, Packet, From, + LocalEngineID, V3Hdr, Data, Log); {'EXIT', {bad_version, Vsn}} -> ?vtrace("exit: bad version: ~p",[Vsn]), @@ -184,7 +192,7 @@ discarded_pdu(Variable) -> inc(Variable). %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- v1_v2c_proc( - Vsn, NoteStore, Community, Domain, Address, + Vsn, NoteStore, Community, {Domain, Address}, LocalEngineID, Data, HS, Log, Packet) -> try snmp_conf:mk_tdomain(Domain) of TDomain -> @@ -263,8 +271,7 @@ sec_model('version-2') -> ?SEC_V2C. %% Handles a SNMPv3 Message, following the procedures in rfc2272, %% section 4.2 and 7.2 %%----------------------------------------------------------------- -v3_proc(NoteStore, Packet, _TDomain, _TAddress, LocalEngineID, - V3Hdr, Data, Log) -> +v3_proc(NoteStore, Packet, _From, LocalEngineID, V3Hdr, Data, Log) -> case (catch v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log)) of {'EXIT', Reason} -> exit(Reason); @@ -1182,6 +1189,9 @@ mk_v1_v2_packet_list([{Domain, Addr} | T], %% Sending from default UDP port inc_snmp_out_vars(Pdu), Entry = {Domain, Addr, Packet}, + %% It would be cleaner to return {To, Packet} to not + %% break the abstraction for an address on the + %% {Domain, Address} format. mk_v1_v2_packet_list(T, Packet, Len, Pdu, [Entry | Acc]). @@ -1288,6 +1298,9 @@ mk_v3_packet_entry(NoteStore, Domain, Addr, req_id = Pdu#pdu.request_id}, snmp_note_store:set_note(NoteStore, 1500, CacheKey, CacheVal), inc_snmp_out_vars(Pdu), + %% It would be cleaner to return {To, Packet} to not + %% break the abstraction for an address on the + %% {Domain, Address} format. {ok, {Domain, Addr, Data}} end. diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index dac172ea11..59d88517c9 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -257,6 +257,9 @@ create_filter(BadOpts) -> throw({error, {bad_filter_opts, BadOpts}}). +log(LogTypes, Req, Packet, {Domain, Address}) -> + log(LogTypes, Req, Packet, Domain, Address). + log({_, []}, _, _, _, _) -> ok; log({Log, Types}, 'set-request', Packet, Domain, Address) -> @@ -297,8 +300,8 @@ loop(S) -> receive {udp, _UdpId, Ip, Port, Packet} -> ?vlog("got paket from ~w:~w",[Ip,Port]), - {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), - NewS = maybe_handle_recv(S, Domain, Address, Packet), + From = snmp_conf:ip_port_to_domaddr(Ip, Port), + NewS = maybe_handle_recv(S, From, Packet), loop(NewS); {info, ReplyRef, Pid} -> @@ -307,47 +310,55 @@ loop(S) -> loop(S); %% response (to get/get_next/get_bulk/set requests) - {snmp_response, Vsn, RePdu, Type, ACMData, Dest, []} -> + {snmp_response, Vsn, RePdu, Type, ACMData, To, []} -> ?vlog("reply pdu: " "~n ~s", [?vapply(snmp_misc, format, [256, "~w", [RePdu]])]), - NewS = maybe_handle_reply_pdu(S, Vsn, RePdu, Type, ACMData, Dest), + NewS = maybe_handle_reply_pdu(S, Vsn, RePdu, Type, ACMData, To), loop(NewS); %% Traps/notification - {send_pdu, Vsn, Pdu, MsgData, To} -> - ?vdebug("send pdu: " - "~n Pdu: ~p" - "~n To: ~p", [Pdu, To]), - NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined), + {send_pdu, Vsn, Pdu, MsgData, TDomAddrs} -> + ?vdebug("send pdu:~n" + " Pdu: ~p~n" + " TDomAddrs: ~p", [Pdu, TDomAddrs]), + NewS = + maybe_handle_send_pdu( + S, Vsn, Pdu, MsgData, TDomAddrs, 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), + {send_pdu, Vsn, Pdu, MsgData, TDomAddrs, _ExtraInfo} -> + ?vdebug("send pdu:~n" + " Pdu: ~p~n" + " TDomAddrs: ~p", [Pdu, TDomAddrs]), + NewS = + maybe_handle_send_pdu( + S, Vsn, Pdu, MsgData, TDomAddrs, undefined), loop(NewS); %% Informs - {send_pdu_req, Vsn, Pdu, MsgData, To, From} -> - ?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), + {send_pdu_req, Vsn, Pdu, MsgData, TDomAddrs, From} -> + ?vdebug("send pdu request:~n" + " Pdu: ~p~n" + " TDomAddrs: ~p~n" + " From: ~p", + [Pdu, TDomAddrs, toname(From)]), + NewS = + maybe_handle_send_pdu( + S, Vsn, Pdu, MsgData, TDomAddrs, 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), + {send_pdu_req, Vsn, Pdu, MsgData, TDomAddrs, From, _ExtraInfo} -> + ?vdebug("send pdu request:~n" + " Pdu: ~p~n" + " TDomAddrs: ~p~n" + " From: ~p", + [Pdu, TDomAddrs, toname(From)]), + NewS = + maybe_handle_send_pdu( + S, Vsn, Pdu, MsgData, TDomAddrs, From), loop(NewS); %% Discovery Inform @@ -517,19 +528,19 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, S#state{rcnt = NewRCnt}. -maybe_handle_recv(#state{usock = Sock, filter = FilterMod} = S, - Domain, Address, Packet) -> - case (catch FilterMod:accept_recv(Domain, Address)) of +maybe_handle_recv( + #state{usock = Sock, filter = FilterMod} = S, From, Packet) -> + case (catch FilterMod:accept_recv(From)) of false -> %% Drop the received packet inc(netIfMsgInDrops), active_once(Sock), S; _ -> - handle_recv(S, Domain, Address, Packet) + handle_recv(S, From, Packet) end. -handle_discovery_response(_Domain, _Address, #pdu{request_id = ReqId} = Pdu, +handle_discovery_response(_From, #pdu{request_id = ReqId} = Pdu, ManagerEngineId, #state{usock = Sock, reqs = Reqs} = S) -> case lists:keysearch(ReqId, 1, S#state.reqs) of @@ -543,27 +554,29 @@ handle_discovery_response(_Domain, _Address, #pdu{request_id = ReqId} = Pdu, S end. -handle_recv(#state{usock = Sock, - mpd_state = MpdState, - note_store = NS, - log = Log} = S, Domain, Address, Packet) -> +handle_recv( + #state{usock = Sock, + mpd_state = MpdState, + note_store = NS, + log = Log} = S, From, Packet) -> put(n1, erlang:now()), - LogF = fun(Type, Data) -> - log(Log, Type, Data, Domain, Address) - end, + LogF = + fun(Type, Data) -> + log(Log, Type, Data, From) + end, case (catch snmpa_mpd:process_packet( - Packet, Domain, Address, MpdState, NS, LogF)) of + Packet, From, MpdState, NS, LogF)) of {ok, _Vsn, Pdu, _PduMS, {discovery, ManagerEngineId}} -> - handle_discovery_response(Domain, Address, Pdu, ManagerEngineId, S); + handle_discovery_response(From, Pdu, ManagerEngineId, S); {ok, _Vsn, Pdu, _PduMS, discovery} -> - handle_discovery_response(Domain, Address, Pdu, undefined, S); + handle_discovery_response(From, Pdu, undefined, S); {ok, Vsn, Pdu, PduMS, ACMData} -> ?vlog("got pdu ~s", [?vapply(snmp_misc, format, [256, "~w", [Pdu]])]), - %% handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S); - maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S); + %% handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S); + maybe_handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S); {discarded, Reason} -> ?vlog("packet discarded for reason: ~s", @@ -575,14 +588,14 @@ handle_recv(#state{usock = Sock, ?vlog("sending report for reason: " "~n ~s", [?vapply(snmp_misc, format, [256, "~w", [Reason]])]), - {Ip, Port} = Address, + {_Domain, {Ip, Port}} = From, (catch udp_send(S#state.usock, Ip, Port, ReportPacket)), active_once(Sock), S; {discovery, ReportPacket} -> ?vlog("sending discovery report", []), - {Ip, Port} = Address, + {_Domain, {Ip, Port}} = From, (catch udp_send(S#state.usock, Ip, Port, ReportPacket)), active_once(Sock), S; @@ -595,71 +608,67 @@ handle_recv(#state{usock = Sock, end. maybe_handle_recv_pdu( - Domain, Address, Vsn, + From, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, #state{usock = Sock, filter = FilterMod} = S) -> - case (catch FilterMod:accept_recv_pdu(Domain, Address, Type)) of + case (catch FilterMod:accept_recv_pdu(From, Type)) of false -> inc(netIfPduInDrops), active_once(Sock), ok; _ -> - handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S) + handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) end; -maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S) -> - handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, S). +maybe_handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) -> + handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S). handle_recv_pdu( - Domain, Address, Vsn, + From, Vsn, #pdu{type = 'get-response'} = Pdu, _PduMS, _ACMData, #state{usock = Sock} = S) -> active_once(Sock), - handle_response(Vsn, Pdu, {Domain, Address}, S), + handle_response(Vsn, Pdu, From, S), S; -handle_recv_pdu(Domain, Address, Vsn, #pdu{request_id = Rid, type = Type} = Pdu, +handle_recv_pdu(From, Vsn, #pdu{request_id = Rid, type = Type} = Pdu, PduMS, ACMData, #state{master_agent = Pid} = S) when ((Type =:= 'get-request') orelse (Type =:= 'get-next-request') orelse (Type =:= 'get-bulk-request')) -> ?vtrace("handle_recv_pdu -> received get (~w)", [Type]), - SourceAddress = {Domain, Address}, - Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, SourceAddress, []}, + Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, []}, update_req_counter_incomming(S, Rid); -handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACMData, +handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, #state{usock = Sock, master_agent = Pid} = S) -> ?vtrace("handle_recv_pdu -> received other request", []), active_once(Sock), - SourceAddress = {Domain, Address}, - Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, SourceAddress, []}, + Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, []}, S. maybe_handle_reply_pdu( #state{filter = FilterMod} = S, Vsn, #pdu{request_id = Rid} = Pdu, - Type, ACMData, DestinationAddress) -> + Type, ACMData, To) -> S1 = update_req_counter_outgoing(S, Rid), - case (catch FilterMod:accept_send_pdu([DestinationAddress], Type)) of + case (catch FilterMod:accept_send_pdu([To], Type)) of false -> inc(netIfPduOutDrops), ok; _ -> - handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, DestinationAddress) + handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, To) end, S1. -handle_reply_pdu(#state{log = Log, - usock = Sock, - filter = FilterMod}, - Vsn, Pdu, Type, ACMData, {Domain, Address}) -> - LogF = fun(Type2, Data) -> - log(Log, Type2, Data, Domain, Address) - end, +handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> + LogF = + fun(Type2, Data) -> + log(Log, Type2, Data, To) + end, case (catch snmpa_mpd:generate_response_msg(Vsn, Pdu, Type, ACMData, LogF)) of {ok, Packet} -> ?vinfo("time in agent: ~w mysec", [time_in_agent()]), - maybe_udp_send(FilterMod, Sock, Domain, Address, Packet); + maybe_udp_send(S, To, Packet); {discarded, Reason} -> ?vlog("handle_reply_pdu -> " "~n reply discarded for reason: ~s", @@ -674,63 +683,63 @@ handle_reply_pdu(#state{log = Log, maybe_handle_send_pdu( #state{filter = FilterMod} = S, - Vsn, Pdu, MsgData, To0, From) -> + Vsn, Pdu, MsgData, TDomAddrSecs, From) -> ?vtrace("maybe_handle_send_pdu -> entry with~n" " FilterMod: ~p~n" - " To0: ~p", [FilterMod, To0]), + " TDomAddrSecs: ~p", [FilterMod, TDomAddrSecs]), - To = snmpa_mpd:process_taddrs(To0), - Destinations = - [case T of - {{Domain, _Address} = Destination, _SecData} + DomAddrSecs = snmpa_mpd:process_taddrs(TDomAddrSecs), + DomAddrs = + [case DAS of + {{Domain, _Address} = DomAddr, _SecData} when is_atom(Domain) -> % v3 - Destination; - {Domain, _Address} = Destination + DomAddr; + {Domain, _Address} = DomAddr when is_atom(Domain) -> % v1 & v2 - Destination - end || T <- To], + DomAddr + end || DAS <- DomAddrSecs], case (catch FilterMod:accept_send_pdu( - Destinations, pdu_type_of(Pdu))) of + DomAddrs, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; true -> - handle_send_pdu(S, Vsn, Pdu, MsgData, To, From); - FilteredDestinations when is_list(FilteredDestinations) -> - MergedTo = - [T || T <- To, - case T of - {{Dom, _Addr} = Dest, _SData} - when is_atom(Dom) -> % v3 + handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From); + FilteredDomAddrs when is_list(FilteredDomAddrs) -> + MergedDomAddrSecs = + [DAS || DAS <- DomAddrSecs, + case DAS of + {{Domain, _Address} = DomAddr, _SData} + when is_atom(Domain) -> % v3 lists:member( - Dest, FilteredDestinations); - {Dom, _Addr} = Dest - when is_atom(Dom) -> % v1 & v2 + DomAddr, FilteredDomAddrs); + {Domain, _Address} = DomAddr + when is_atom(Domain) -> % v1 & v2 lists:member( - Dest, FilteredDestinations) + DomAddr, FilteredDomAddrs) end], - ?vtrace("maybe_handle_send_pdu -> MergedTo:~n" - " ~p", [MergedTo]), - handle_send_pdu(S, Vsn, Pdu, MsgData, MergedTo, From); + ?vtrace("maybe_handle_send_pdu -> MergedDomAddrSecs:~n" + " ~p", [MergedDomAddrSecs]), + handle_send_pdu(S, Vsn, Pdu, MsgData, MergedDomAddrSecs, From); Other -> error_msg( "FilterMod:accept_send_pdu/2 returned: ~p", [Other]), - handle_send_pdu(S, Vsn, Pdu, MsgData, To, From) + handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From) end. handle_send_pdu( - #state{note_store = NS} = S, Vsn, Pdu, MsgData, To, From) -> + #state{note_store = NS} = S, Vsn, Pdu, MsgData, DomAddrSecs, From) -> ?vtrace("handle_send_pdu -> entry with~n" - " Pdu: ~p~n" - " To: ~p", [Pdu, To]), + " Pdu: ~p~n" + " DomAddrSecs: ~p", [Pdu, DomAddrSecs]), case (catch snmpa_mpd:generate_msg( - Vsn, NS, Pdu, MsgData, To)) of + Vsn, NS, Pdu, MsgData, DomAddrSecs)) of {ok, Addresses} -> - handle_send_pdu(S, Pdu, Addresses); + do_handle_send_pdu(S, Pdu, Addresses); {discarded, Reason} -> ?vlog("handle_send_pdu -> " "~n PDU ~p not sent due to ~p", [Pdu, Reason]), @@ -787,13 +796,13 @@ handle_send_discovery( end. -handle_send_pdu(S, #pdu{type = Type} = Pdu, Addresses) -> - handle_send_pdu(S, Type, Pdu, Addresses); -handle_send_pdu(S, Trap, Addresses) -> - handle_send_pdu(S, trappdu, Trap, Addresses). +do_handle_send_pdu(S, #pdu{type = Type} = Pdu, Addresses) -> + do_handle_send_pdu(S, Type, Pdu, Addresses); +do_handle_send_pdu(S, Trap, Addresses) -> + do_handle_send_pdu(S, trappdu, Trap, Addresses). -handle_send_pdu(S, Type, Pdu, Addresses) -> - case (catch handle_send_pdu1(S, Type, Addresses)) of +do_handle_send_pdu(S, Type, Pdu, Addresses) -> + case (catch do_handle_send_pdu1(S, Type, Addresses)) of {Reason, Sz} -> error_msg("Cannot send message " "~n size: ~p" @@ -803,25 +812,23 @@ handle_send_pdu(S, Type, Pdu, Addresses) -> _ -> ok end. - -handle_send_pdu1(#state{log = Log, - usock = Sock, - filter = FilterMod}, Type, Addresses) -> + +do_handle_send_pdu1(S, Type, Addresses) -> lists:foreach( fun ({Domain, Address, Packet}) when is_binary(Packet) -> ?vdebug( "[~w] sending packet:~n" " size: ~p~n" " to: ~p", [Domain, sz(Packet), Address]), - maybe_udp_send( - FilterMod, Log, Type, Sock, Domain, Address, Packet); - ({Domain, Address, {Packet, _LogData}}) when is_binary(Packet) -> + To = {Domain, Address}, + maybe_udp_send(S, To, Packet); + ({Domain, Address, {Packet, LogData}}) when is_binary(Packet) -> ?vdebug( "[~w] sending encrypted packet:~n" " size: ~p~n" " to: ~p", [Domain, sz(Packet), Address]), - maybe_udp_send( - FilterMod, Log, Type, Sock, Domain, Address, Packet) + To = {Domain, Address}, + maybe_udp_send(S, To, Packet, Type, LogData) end, Addresses). @@ -836,24 +843,31 @@ handle_response(Vsn, Pdu, From, S) -> "~n No receiver available for response pdu", []) end. -maybe_udp_send(FilterMod, Sock, Domain, Address, Packet) -> - case (catch FilterMod:accept_send(Domain, Address)) of +maybe_udp_send( + #state{usock = Sock, + filter = FilterMod}, To, Packet) -> + case (catch FilterMod:accept_send(To)) of false -> inc(netIfMsgOutDrops), ok; _ -> - {Ip, Port} = Address, + %% XXX should be some kind of lookup of domain to socket + {_Domain, {Ip, Port}} = To, (catch udp_send(Sock, Ip, Port, Packet)) end. -maybe_udp_send(FilterMod, AtLog, Type, Sock, Domain, Address, Packet) -> - case (catch FilterMod:accept_send(Domain, Address)) of +maybe_udp_send( + #state{log = Log, + usock = Sock, + filter = FilterMod}, To, Packet, Type, _LogData) -> + case (catch FilterMod:accept_send(To)) of false -> inc(netIfMsgOutDrops), ok; _ -> - log(AtLog, Type, Packet, Domain, Address), - {Ip, Port} = Address, + log(Log, Type, Packet, To), + %% XXX should be some kind of lookup of domain to socket + {_Domain, {Ip, Port}} = To, (catch udp_send(Sock, Ip, Port, Packet)) end. diff --git a/lib/snmp/src/agent/snmpa_net_if_filter.erl b/lib/snmp/src/agent/snmpa_net_if_filter.erl index 871c4f05da..e71abc4ac6 100644 --- a/lib/snmp/src/agent/snmpa_net_if_filter.erl +++ b/lib/snmp/src/agent/snmpa_net_if_filter.erl @@ -18,41 +18,46 @@ %% -module(snmpa_net_if_filter). --export([accept_recv/2, - accept_send/2, - accept_recv_pdu/3, - accept_send_pdu/2]). +%% New behaviour +-export([accept_recv/1, accept_send/1, accept_recv_pdu/2]). +%% Common signature for both old and new behaviour +-export([accept_send_pdu/2]). +%% Old behaviour +-export([accept_recv/2, accept_send/2, accept_recv_pdu/3]). -include("snmp_debug.hrl"). -accept_recv(Domain, _Address) when is_atom(Domain) -> +accept_recv({Domain, _Address}) when is_atom(Domain) -> ?d("accept_recv -> entry with~n" " Domain: ~p~n" " Address: ~p", [Domain, _Address]), - true; + true. +%% accept_recv(_Addr, Port) when is_integer(Port) -> ?d("accept_recv -> entry with~n" " Addr: ~p~n" " Port: ~p", [_Addr, Port]), true. -accept_send(Domain, _Address) when is_atom(Domain) -> +accept_send({Domain, _Address}) when is_atom(Domain) -> ?d("accept_send -> entry with~n" " Domain: ~p~n" " Address: ~p", [Domain, _Address]), - true; + true. +%% accept_send(_Addr, Port) when is_integer(Port) -> ?d("accept_send -> entry with~n" " Addr: ~p~n" " Port: ~p", [_Addr, Port]), true. -accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> +accept_recv_pdu({Domain, _Address}, _PduType) when is_atom(Domain) -> ?d("accept_recv -> entry with~n" " Domain: ~p~n" " Address: ~p~n" " PduType: ~p", [Domain, _Address, _PduType]), - true; + true. +%% accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) -> ?d("accept_recv_pdu -> entry with~n" " Addr: ~p~n" diff --git a/lib/snmp/src/agent/snmpa_network_interface_filter.erl b/lib/snmp/src/agent/snmpa_network_interface_filter.erl index 6fa131beee..3fa83db874 100644 --- a/lib/snmp/src/agent/snmpa_network_interface_filter.erl +++ b/lib/snmp/src/agent/snmpa_network_interface_filter.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2007-2009. All Rights Reserved. +%% Copyright Ericsson AB 2007-2014. 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 @@ -23,28 +23,29 @@ behaviour_info(callbacks) -> - [{accept_recv, 2}, - {accept_send, 2}, - {accept_recv_pdu, 3}, + [{accept_recv, 1}, + {accept_send, 1}, + {accept_recv_pdu, 2}, {accept_send_pdu, 2}]; behaviour_info(_) -> undefined. -%% accept_recv(address(), port()) -> boolean() +%% accept_recv({domain(), address()}) -> boolean() %% Called at the receiption of a message %% (before *any* processing has been done). %% -%% accept_send(address(), port()) -> boolean() +%% accept_send({domain(), address()}) -> boolean() %% Called before the sending of a message %% (after *all* processing has been done). %% -%% accept_recv_pdu(Addr, Port, pdu_type()) -> boolean() +%% accept_recv_pdu({domain(), address()}, pdu_type()) -> boolean() %% Called after the basic message processing (MPD) has been done, %% but before the pdu is handed over to the master-agent for %% primary processing. %% -%% accept_send_pdu(Targets, pdu_type()) -> boolean() | NewTargets +%% accept_send_pdu([{domain(), address()}, ...] = Targets, pdu_type()) -> +%% boolean() | NewTargets %% Called before the basic message processing (MPD) is done, %% when a pdu has been received from the master-agent. %% diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 088f0c7fc8..69a6b4a3a9 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -313,7 +313,7 @@ mk_target_name(Domain, Address, Config) end; mk_target_name(Ip, Port, Config) when is_integer(Port), is_list(Config) -> - {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + {Domain, Address} = snmp_conf:ip_port_to_domaddr(Ip, Port), mk_target_name(Domain, Address, Config). select_lowest_supported_version() -> @@ -403,7 +403,7 @@ unregister_agent(UserId, Domain, Address) when is_atom(Domain) -> {error, not_found} end; unregister_agent(UserId, Ip, Port) when is_integer(Port) -> - try snmp_conf:fix_domain_address(Ip, Port) of + try snmp_conf:ip_port_to_domaddr(Ip, Port) of {Domain, Address} -> do_unregister_agent(UserId, Domain, Address) catch @@ -448,7 +448,7 @@ agent_info(Domain, Address, Item) when is_atom(Domain) -> {error, not_found} end; agent_info(Ip, Port, Item) -> - try snmp_conf:fix_domain_address(Ip, Port) of + try snmp_conf:ip_port_to_domaddr(Ip, Port) of {Domain, Address} -> do_agent_info(Domain, Address, Item) catch diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index 39e239f2a2..e7167cdb6b 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -425,7 +425,7 @@ handle_cast(Msg, State) -> %%-------------------------------------------------------------------- handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]), - {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + {Domain, Address} = snmp_conf:ip_port_to_domaddr(Ip, Port), maybe_handle_recv_msg(Domain, Address, Bytes, State), {noreply, State}; diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl index a04cfba2c1..594bc44474 100644 --- a/lib/snmp/src/manager/snmpm_net_if_mt.erl +++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl @@ -435,7 +435,7 @@ handle_cast(Msg, State) -> %%-------------------------------------------------------------------- handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]), - {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + {Domain, Address} = snmp_conf:ip_port_to_domaddr(Ip, Port), handle_udp(Domain, Address, Bytes, State), {noreply, State}; diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 105652cdda..0d17c66455 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -46,7 +46,7 @@ which_domain/1, check_ip/1, check_ip/2, check_port/1, - fix_domain_address/2, + ip_port_to_domaddr/2, check_address/2, check_address/3, check_taddress/2, mk_taddress/2, @@ -754,7 +754,7 @@ check_port(Port) when ?is_word(Port) -> check_port(Port) -> error({bad_port, Port}). -fix_domain_address(IP, Port) when ?is_word(Port) -> +ip_port_to_domaddr(IP, Port) when ?is_word(Port) -> case check_address_ip(transportDomainUdpIpv4, IP) of false -> case check_address_ip(transportDomainUdpIpv6, IP) of @@ -770,7 +770,7 @@ fix_domain_address(IP, Port) when ?is_word(Port) -> FixedIP -> {transportDomainUdpIpv4, {FixedIP, Port}} end; -fix_domain_address(IP, Port) -> +ip_port_to_domaddr(IP, Port) -> error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}). %% Check a configuration term field from a file to see if it -- cgit v1.2.3 From d2002049e348f1da8d011fe5f628484ec909ec41 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Thu, 24 Apr 2014 17:05:03 +0200 Subject: snmp: Add IPV6 tests --- lib/snmp/test/snmp_agent_test.erl | 279 +++++++++++++++++++--------------- lib/snmp/test/snmp_agent_test_lib.erl | 9 +- lib/snmp/test/snmp_manager_test.erl | 27 +++- lib/snmp/test/snmp_test_lib.erl | 7 +- lib/snmp/test/snmp_test_lib.hrl | 19 +-- 5 files changed, 202 insertions(+), 139 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index bcc89b93de..e4cac71fec 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -297,7 +297,11 @@ %% tickets2 otp8395/1, - otp9884/1 + otp9884/1, + + %% IPV6 + ipv6_processing/1, + ipv6_trap/1 ]). @@ -537,7 +541,8 @@ groups() -> {tickets1, [], tickets1_cases()}, {tickets2, [], tickets2_cases()}, {otp4394, [], [otp_4394]}, - {otp7157, [], [otp_7157]} + {otp7157, [], [otp_7157]}, + {ipv6, [], [ipv6_processing, ipv6_trap]} ]. @@ -634,6 +639,13 @@ init_per_group(mib_storage_dets = GroupName, Config) -> init_mib_storage_dets(snmp_test_lib:init_group_top_dir(GroupName, Config)); init_per_group(mib_storage_ets = GroupName, Config) -> init_mib_storage_ets(snmp_test_lib:init_group_top_dir(GroupName, Config)); +init_per_group(ipv6 = GroupName, Config) -> + case ct:require(ipv6_hosts) of + ok -> + ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config)); + _ -> + {skip, "Host does not support IPV6"} + end; init_per_group(GroupName, Config) -> snmp_test_lib:init_group_top_dir(GroupName, Config). @@ -728,6 +740,16 @@ init_per_testcase1(v3_inform_i = _Case, Config) when is_list(Config) -> "~n Config: ~p", [_Case, Config]), Dog = ?WD_START(?MINS(10)), [{watchdog, Dog} | Config ]; +init_per_testcase1(ipv6_processing = Case, Config) when is_list(Config) -> + ?DBG("init_per_testcase1 -> entry with" + "~n Case: ~p" + "~n Config: ~p", [Case, Config]), + ipv6_processing({init, init_per_testcase2(Case, Config)}); +init_per_testcase1(ipv6_trap = Case, Config) when is_list(Config) -> + ?DBG("init_per_testcase1 -> entry with" + "~n Case: ~p" + "~n Config: ~p", [Case, Config]), + ipv6_trap({init, init_per_testcase2(Case, Config)}); init_per_testcase1(_Case, Config) when is_list(Config) -> ?DBG("init_per_testcase -> entry with" "~n Case: ~p" @@ -812,7 +834,8 @@ cases() -> {group, test_v3}, {group, test_multi_threaded}, {group, mib_storage}, - {group, tickets1} + {group, tickets1}, + {group, ipv6} ]. @@ -6382,7 +6405,9 @@ otp_4394_config(AgentConfDir, MgrDir, Ip0) -> ?line write_notify_conf(AgentConfDir), ok. - +ipv6_init(Config) when is_list(Config) -> + Opts = [], + [{vsn, v1} | start_v1_agent(Config, Opts)]. otp_4394_finish(Config) when is_list(Config) -> ?DBG("finish_otp_4394 -> entry", []), @@ -6670,126 +6695,12 @@ otp8395(Config) when is_list(Config) -> otp9884({init, Config}) when is_list(Config) -> ?DBG("otp9884(init) -> entry with" "~n Config: ~p", [Config]), - - %% -- - %% Start nodes - %% - - {ok, AgentNode} = start_node(agent), - - %% We don't use a manager in this test but the (common) config - %% function takes an argument that is derived from this - {ok, ManagerNode} = start_node(manager), - - %% -- - %% Mnesia init - %% - - AgentDbDir = ?config(agent_db_dir, Config), - AgentMnesiaDir = join([AgentDbDir, "mnesia"]), - mnesia_init(AgentNode, AgentMnesiaDir), - - mnesia_create_schema(AgentNode, [AgentNode]), - - mnesia_start(AgentNode), - - %% -- - %% Host & IP - %% - - AgentHost = ?HOSTNAME(AgentNode), - ManagerHost = ?HOSTNAME(ManagerNode), - - Host = snmp_test_lib:hostname(), - Ip = ?LOCALHOST(), - {ok, AgentIP0} = snmp_misc:ip(AgentHost), - AgentIP = tuple_to_list(AgentIP0), - {ok, ManagerIP0} = snmp_misc:ip(ManagerHost), - ManagerIP = tuple_to_list(ManagerIP0), - - - %% -- - %% Write agent config - %% - - Vsns = [v1], - ManagerConfDir = ?config(manager_top_dir, Config), - AgentConfDir = ?config(agent_conf_dir, Config), - AgentTopDir = ?config(agent_top_dir, Config), - AgentBkpDir1 = join([AgentTopDir, backup1]), - AgentBkpDir2 = join([AgentTopDir, backup2]), - ok = file:make_dir(AgentBkpDir1), - ok = file:make_dir(AgentBkpDir2), - AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2], - snmp_agent_test_lib:config(Vsns, - ManagerConfDir, AgentConfDir, - ManagerIP, AgentIP), - - - %% -- - %% Start the agent - %% - - Config2 = start_agent([{host, Host}, - {ip, Ip}, - {agent_node, AgentNode}, - {agent_host, AgentHost}, - {agent_ip, AgentIP}, - {agent_backup_dirs, AgentBkpDirs}|Config]), - - %% -- - %% Create watchdog - %% - - Dog = ?WD_START(?MINS(1)), - - [{watchdog, Dog} | Config2]; + init_v1_agent([{ipfamily, inet} | Config]); otp9884({fin, Config}) when is_list(Config) -> ?DBG("otp9884(fin) -> entry with" "~n Config: ~p", [Config]), - - AgentNode = ?config(agent_node, Config), - ManagerNode = ?config(manager_node, Config), - - %% - - %% Stop agent (this is the nice way to do it, - %% so logs and files can be closed in the proper way). - %% - - AgentSup = ?config(agent_sup, Config), - ?DBG("otp9884(fin) -> stop (stand-alone) agent: ~p", [AgentSup]), - stop_stdalone_agent(AgentSup), - - %% - - %% Stop mnesia - %% - ?DBG("otp9884(fin) -> stop mnesia", []), - mnesia_stop(AgentNode), - - - %% - - %% Stop the agent node - %% - - ?DBG("otp9884(fin) -> stop agent node", []), - stop_node(AgentNode), - - - %% SubAgentNode = ?config(sub_agent_node, Config), - %% stop_node(SubAgentNode), - - - %% - - %% Stop the manager node - %% - - ?DBG("otp9884(fin) -> stop manager node", []), - stop_node(ManagerNode), - - Dog = ?config(watchdog, Config), - ?WD_STOP(Dog), - lists:keydelete(watchdog, 1, Config); + fin_v1_agent(Config); otp9884(doc) -> "OTP-9884 - Simlutaneous backup call should not work. "; @@ -6849,7 +6760,23 @@ otp9884_await_backup_completion(First, Second) end; otp9884_await_backup_completion(First, Second) -> throw({error, {bad_completion, First, Second}}). +%%----------------------------------------------------------------- +ipv6_processing({init, Config}) when is_list(Config)-> + init_v1_agent([{ipfamily, inet6} | Config]); +ipv6_processing({fin, Config}) when is_list(Config) -> + fin_v1_agent(Config); +ipv6_processing(Config) when is_list(Config) -> + v1_processing(Config). + +%%----------------------------------------------------------------- + +ipv6_trap({init, Config}) when is_list(Config)-> + init_v1_agent([{ipfamily, inet6} | Config]); +ipv6_trap({fin, Config}) when is_list(Config) -> + fin_v1_agent(Config); +ipv6_trap(Config) when is_list(Config) -> + v1_trap(Config). %%----------------------------------------------------------------- @@ -7391,3 +7318,115 @@ p(F, A) -> formated_timestamp() -> snmp_test_lib:formated_timestamp(). + +init_v1_agent(Config) -> + %% -- + %% Start nodes + %% + + {ok, AgentNode} = start_node(agent), + + %% We don't use a manager in this test but the (common) config + %% function takes an argument that is derived from this + {ok, ManagerNode} = start_node(manager), + + %% -- + %% Mnesia init + %% + + AgentDbDir = ?config(agent_db_dir, Config), + AgentMnesiaDir = join([AgentDbDir, "mnesia"]), + mnesia_init(AgentNode, AgentMnesiaDir), + + mnesia_create_schema(AgentNode, [AgentNode]), + + mnesia_start(AgentNode), + + %% -- + %% Host & IP + %% + + AgentHost = ?HOSTNAME(AgentNode), + ManagerHost = ?HOSTNAME(ManagerNode), + + Host = snmp_test_lib:hostname(), + Ip = ?LOCALHOST(?config(ipfamily, Config)), + {ok, AgentIP0} = snmp_misc:ip(AgentHost), + AgentIP = tuple_to_list(AgentIP0), + {ok, ManagerIP0} = snmp_misc:ip(ManagerHost), + ManagerIP = tuple_to_list(ManagerIP0), + + + %% -- + %% Write agent config + %% + + Vsns = [v1], + ManagerConfDir = ?config(manager_top_dir, Config), + AgentConfDir = ?config(agent_conf_dir, Config), + AgentTopDir = ?config(agent_top_dir, Config), + AgentBkpDir1 = join([AgentTopDir, backup1]), + AgentBkpDir2 = join([AgentTopDir, backup2]), + ok = file:make_dir(AgentBkpDir1), + ok = file:make_dir(AgentBkpDir2), + AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2], + snmp_agent_test_lib:config(Vsns, + ManagerConfDir, AgentConfDir, + ManagerIP, AgentIP), + + + %% -- + %% Start the agent + %% + + Config2 = start_agent([{host, Host}, + {ip, Ip}, + {agent_node, AgentNode}, + {agent_host, AgentHost}, + {agent_ip, AgentIP}, + {agent_backup_dirs, AgentBkpDirs}|Config]), + + %% -- + %% Create watchdog + %% + + Dog = ?WD_START(?MINS(1)), + + [{watchdog, Dog} | Config2]. + +fin_v1_agent(Config) -> + AgentNode = ?config(agent_node, Config), + ManagerNode = ?config(manager_node, Config), + + %% - + %% Stop agent (this is the nice way to do it, + %% so logs and files can be closed in the proper way). + %% + + AgentSup = ?config(agent_sup, Config), + stop_stdalone_agent(AgentSup), + + %% - + %% Stop mnesia + %% + mnesia_stop(AgentNode), + + + %% - + %% Stop the agent node + %% + stop_node(AgentNode), + + + %% SubAgentNode = ?config(sub_agent_node, Config), + %% stop_node(SubAgentNode), + + + %% - + %% Stop the manager node + %% + stop_node(ManagerNode), + + Dog = ?config(watchdog, Config), + ?WD_STOP(Dog), + lists:keydelete(watchdog, 1, Config). diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index e12a282a34..6061732879 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -232,13 +232,14 @@ init_case(Config) when is_list(Config) -> MgrNode = ?config(snmp_mgr, Config), MasterNode = ?config(snmp_master, Config), %% MasterNode = node(), - + IpFamily = proplists:get_value(ipfamily, Config, inet), + SaHost = ?HOSTNAME(SaNode), MgrHost = ?HOSTNAME(MgrNode), MasterHost = ?HOSTNAME(MasterNode), - {ok, MasterIP} = snmp_misc:ip(MasterHost), - {ok, MIP} = snmp_misc:ip(MgrHost), - {ok, SIP} = snmp_misc:ip(SaHost), + {ok, MasterIP} = snmp_misc:ip(MasterHost, IpFamily), + {ok, MIP} = snmp_misc:ip(MgrHost, IpFamily), + {ok, SIP} = snmp_misc:ip(SaHost, IpFamily), put(mgr_node, MgrNode), diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 52b58ecea8..3e152e6ad4 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -241,8 +241,10 @@ init_per_testcase2(Case, Config) -> AgLogDir = filename:join(AgTopDir, "log/"), ?line ok = file:make_dir(AgLogDir), + Family = proplists:get_value(ipfamily, Config, inet), + Conf = [{watchdog, ?WD_START(?MINS(5))}, - {ip, ?LOCALHOST()}, + {ip, ?LOCALHOST(Family)}, {case_top_dir, CaseTopDir}, {agent_dir, AgTopDir}, {agent_conf_dir, AgConfDir}, @@ -410,7 +412,8 @@ all() -> {group, event_tests}, {group, event_tests_mt}, discovery, - {group, tickets} + {group, tickets}, + {group, ipv6} ]. groups() -> @@ -545,7 +548,15 @@ groups() -> [ otp8395_1 ] + }, + {ipv6, [], + [ + simple_sync_get3, + inform1 + ] } + + ]. init_per_group(request_tests_mt = GroupName, Config) -> @@ -556,10 +567,16 @@ init_per_group(event_tests_mt = GroupName, Config) -> snmp_test_lib:init_group_top_dir( GroupName, [{manager_net_if_module, snmpm_net_if_mt} | Config]); +init_per_group(ipv6 = GroupName, Config) -> + case ct:require(ipv6_hosts) of + ok -> + ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config)); + _ -> + {skip, "Host does not support IPV6"} + end; init_per_group(GroupName, Config) -> snmp_test_lib:init_group_top_dir(GroupName, Config). - - + end_per_group(_GroupName, Config) -> %% Do we really need to do this? lists:keydelete(snmp_group_top_dir, 1, Config). @@ -6426,3 +6443,5 @@ formated_timestamp() -> %% p(TName, F, A) -> %% io:format("~w -> " ++ F ++ "~n", [TName|A]). +ipv6_init(Config) when is_list(Config) -> + [{ipfamily, inet6} | Config]. diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl index fbb891e40d..5e611340a3 100644 --- a/lib/snmp/test/snmp_test_lib.erl +++ b/lib/snmp/test/snmp_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2014. 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 @@ -22,7 +22,7 @@ -include_lib("kernel/include/file.hrl"). --export([hostname/0, hostname/1, localhost/0, os_type/0, sz/1, +-export([hostname/0, hostname/1, localhost/0, localhost/1, os_type/0, sz/1, display_suite_info/1]). -export([non_pc_tc_maybe_skip/4, os_based_skip/1]). -export([fix_data_dir/1, @@ -60,6 +60,9 @@ from(_H, []) -> []. localhost() -> {ok, Ip} = snmp_misc:ip(net_adm:localhost()), Ip. +localhost(Family) -> + {ok, Ip} = snmp_misc:ip(net_adm:localhost(), Family), + Ip. sz(L) when is_list(L) -> length(L); diff --git a/lib/snmp/test/snmp_test_lib.hrl b/lib/snmp/test/snmp_test_lib.hrl index 8cc3f75dc5..9b7609b831 100644 --- a/lib/snmp/test/snmp_test_lib.hrl +++ b/lib/snmp/test/snmp_test_lib.hrl @@ -1,5 +1,5 @@ %% -%% 2002-2008 +%% 2002-2014 %% Ericsson AB, All Rights Reserved %% %% @@ -32,14 +32,15 @@ -define(APPLICATION, snmp). -endif. --define(SCONF(K,D,C), snmp_test_lib:set_config(K,D,C)). --define(GCONF(K,C), snmp_test_lib:get_config(K,C)). --define(RCONF(K,C,V), snmp_test_lib:replace_config(K,C,V)). --define(HOSTNAME(N), snmp_test_lib:hostname(N)). --define(LOCALHOST(), snmp_test_lib:localhost()). --define(SZ(X), snmp_test_lib:sz(X)). --define(OSTYPE(), snmp_test_lib:os_type()). --define(DISPLAY_SUITE_INFO(), snmp_test_lib:display_suite_info(?MODULE)). +-define(SCONF(K,D,C), snmp_test_lib:set_config(K,D,C)). +-define(GCONF(K,C), snmp_test_lib:get_config(K,C)). +-define(RCONF(K,C,V), snmp_test_lib:replace_config(K,C,V)). +-define(HOSTNAME(N), snmp_test_lib:hostname(N)). +-define(LOCALHOST(), snmp_test_lib:localhost()). +-define(LOCALHOST(Family), snmp_test_lib:localhost(Family)). +-define(SZ(X), snmp_test_lib:sz(X)). +-define(OSTYPE(), snmp_test_lib:os_type()). +-define(DISPLAY_SUITE_INFO(), snmp_test_lib:display_suite_info(?MODULE)). %% - Test case macros - -- cgit v1.2.3 From 100b3345793043d50f90619c25123dc4d218e5cd Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 8 May 2014 16:16:03 +0200 Subject: fix agent configuration details --- lib/snmp/src/agent/snmp_framework_mib.erl | 51 ++++----- lib/snmp/src/agent/snmpa_conf.erl | 55 ++++++---- lib/snmp/src/agent/snmpa_net_if.erl | 14 ++- lib/snmp/src/misc/snmp_conf.erl | 111 ++++++++++++-------- lib/snmp/src/misc/snmp_config.erl | 167 ++++++++++++++++++++---------- 5 files changed, 254 insertions(+), 144 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 51f8c46d19..0b439aa5f1 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -41,6 +41,7 @@ -compile({no_auto_import,[error/1]}). -export([init/0, configure/1]). -export([intContextTable/1, intContextTable/3, + intAgentTransportDomain/1, intAgentUDPPort/1, intAgentIpAddress/1, snmpEngineID/1, snmpEngineBoots/1, @@ -128,27 +129,20 @@ read_agent(Dir) -> ?vdebug("read agent config file", []), FileName = "agent.conf", File = filename:join(Dir, FileName), - Agent = + Conf0 = try snmp_conf:read(File, fun order_agent/2, fun check_agent/2) catch throw:{error, Reason} -> error({failed_reading_config_file, Dir, FileName, Reason}) end, - sort_agent(Agent). - - -%%----------------------------------------------------------------- -%% Make sure that each mandatory agent attribute is present, and -%% provide default values for the other non-present attributes. -%%----------------------------------------------------------------- -sort_agent(L) -> - Mand = [{intAgentIpAddress, mandatory}, - {intAgentUDPPort, mandatory}, - {snmpEngineMaxMessageSize, mandatory}, - {snmpEngineID, mandatory}], - {ok, L2} = snmp_conf:check_mandatory(L, Mand), - lists:keysort(1, L2). + Mand = + [{intAgentIpAddress, mandatory}, + {intAgentUDPPort, mandatory}, + {snmpEngineMaxMessageSize, mandatory}, + {snmpEngineID, mandatory}], + {ok, Conf} = snmp_conf:check_mandatory(Conf0, Mand), + Conf. %%----------------------------------------------------------------- @@ -198,14 +192,17 @@ check_context(Context) -> %%----------------------------------------------------------------- check_agent({intAgentTransportDomain, D}, Domain) -> {snmp_conf:check_domain(D), D}; -check_agent({intAgentTransportAddress, Address}, Domain) -> - {snmp_conf:check_address(Domain, Address), Domain}; +check_agent({intAgentIpAddress, Value}, D) -> + Domain = + case D of + undefined -> snmp_target_mib:default_domain(); + _ -> D + end, + {snmp_conf:check_ip(Domain, Value), Domain}; check_agent(Entry, Domain) -> {check_agent(Entry), Domain}. -check_agent({intAgentIpAddress, Value}) -> % Obsoleted - snmp_conf:check_ip(Value); -check_agent({intAgentUDPPort, Value}) -> % Obsoleted +check_agent({intAgentUDPPort, Value}) -> snmp_conf:check_integer(Value); %% This one is kept for backwards compatibility check_agent({intAgentMaxPacketSize, Value}) -> @@ -218,13 +215,14 @@ check_agent(X) -> error({invalid_agent_attribute, X}). %% Ordering function to sort intAgentTransportDomain first -%% hence before intAgentTransportAddress +%% hence before intAgentIpAddress order_agent({Name, _}, {Name, _}) -> true; %% Less than or equal -order_agent(_, {intAgentTransportDomain, _}) -> +order_agent({_, _}, {intAgentTransportDomain, _}) -> false; %% Greater than -order_agent(_, _) -> - true. %% Less than or equal +order_agent({A, _}, {B, _}) -> + A =< B. + maybe_create_table(Name) -> @@ -398,6 +396,11 @@ intAgentUDPPort(Op) -> intAgentIpAddress(Op) -> snmp_generic:variable_func(Op, db(intAgentIpAddress)). +intAgentTransportDomain(Op) -> + snmp_generic:variable_func(Op, db(intAgentTransportDomain)). + + + snmpEngineID(print) -> VarAndValue = [{snmpEngineID, snmpEngineID(get)}], snmpa_mib_lib:print_variables(VarAndValue); diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index f055f89880..b05590a504 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -154,6 +154,8 @@ write_agent_conf(Fd, [H|T]) -> do_write_agent_conf(Fd, H), write_agent_conf(Fd, T). +do_write_agent_conf(Fd, {intAgentTransportDomain = Tag, Val}) -> + io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); do_write_agent_conf(Fd, {intAgentIpAddress = Tag, Val}) -> io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); do_write_agent_conf(Fd, {intAgentUDPPort = Tag, Val} ) -> @@ -566,29 +568,36 @@ write_target_addr_conf(Fd, Conf) -> lists:foreach(Fun, Conf), ok. -do_write_target_addr_conf(Fd, - {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, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n", - [Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, - ParamsName, EngineId, TMask, MaxMessageSize]); +do_write_target_addr_conf( + Fd, + {Name, Ip, Udp, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}) + when is_integer(Udp) -> + Domain = snmp_target_mib:default_domain(), + Address = {Ip, Udp}, + do_write_target_addr_conf( + Fd, + {Name, Domain, Address, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}); +do_write_target_addr_conf( + Fd, + {Name, Domain, Address, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}) + when is_atom(Domain) -> + io:format( + Fd, + "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n", + [Name, Domain, Address, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize]); +do_write_target_addr_conf( + Fd, + {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}) -> + Address = {Ip, Udp}, + do_write_target_addr_conf( + Fd, + {Name, Domain, Address, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}); do_write_target_addr_conf(_Fd, Crap) -> error({bad_target_addr_config, Crap}). diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 59d88517c9..96211fc5f4 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -112,6 +112,14 @@ get_address() -> {value, IPAddress} = snmp_framework_mib:intAgentIpAddress(get), IPAddress. +get_domain() -> + case snmp_framework_mib:intAgentTransportDomain(get) of + {value, Domain} -> + Domain; + genErr -> + snmpUDPDomain + end. + filter_reset(Pid) -> Pid ! filter_reset. @@ -155,6 +163,8 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> ?vlog("starting",[]), %% -- Port and address -- + Domain = get_domain(), + ?vdebug("domain: ~w",[Domain]), UDPPort = get_port(), ?vdebug("port: ~w",[UDPPort]), IPAddress = get_address(), @@ -181,7 +191,9 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> IPOpts2 = ip_opt_no_reuse_address(Opts), IPOpts3 = ip_opt_recbuf(Opts), IPOpts4 = ip_opt_sndbuf(Opts), - IPOpts = [binary | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4], + IPOpts = + [binary, snmp_conf:tdomain_to_family(Domain) + | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4], ?vdebug("open socket with options: ~w",[IPOpts]), case gen_udp_open(UDPPort, IPOpts) of {ok, Sock} -> diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 0d17c66455..0cad61e5c8 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -31,33 +31,34 @@ %% Basic (type) check functions -export([check_mandatory/2, check_integer/1, check_integer/2, - + check_string/1, check_string/2, - check_atom/2, + check_atom/2, check_timer/1, - all_domains/0, - check_domain/1, - all_tdomains/0, - check_tdomain/1, - mk_tdomain/1, - which_domain/1, + all_domains/0, + check_domain/1, + all_tdomains/0, + check_tdomain/1, + mk_tdomain/1, + tdomain_to_family/1, + which_domain/1, check_ip/1, check_ip/2, check_port/1, ip_port_to_domaddr/2, check_address/2, check_address/3, check_taddress/2, mk_taddress/2, - - check_packet_size/1, + + check_packet_size/1, check_oid/1, - check_imask/1, check_emask/1, - - check_mp_model/1, - check_sec_model/1, check_sec_model/2, check_sec_model/3, + check_imask/1, check_emask/1, + + check_mp_model/1, + check_sec_model/1, check_sec_model/2, check_sec_model/3, check_sec_level/1, all_integer/1 @@ -471,6 +472,22 @@ mk_tdomain(BadDomain) -> error({bad_domain, BadDomain}). +%% --------- + +tdomain_to_family(snmpUDPDomain) -> + inet; +tdomain_to_family(transportDomainUdpIpv4) -> + inet; +tdomain_to_family(transportDomainUdpIpv6) -> + inet6; +tdomain_to_family(?transportDomainUdpIpv4) -> + inet; +tdomain_to_family(?transportDomainUdpIpv6) -> + inet6; +tdomain_to_family(BadDomain) -> + error({bad_domain, BadDomain}). + + %% --------- %% XXX remove @@ -716,35 +733,43 @@ which_domain({A0, A1, A2, A3, A4, A5, A6, A7}) %% --------- -%% XXX remove - check_ip(X) -> check_ip(snmpUDPDomain, X). -check_ip(snmpUDPDomain, X) -> - check_ip(transportDomainUdpIpv4, X); -check_ip(transportDomainUdpIpv4 = Domain, X) -> - case X of - [A,B,C,D] when ?is_ipv4_addr(A, B, C, D) -> - ok; - _ -> - error({bad_address, {Domain, X}}) - end; -check_ip(transportDomainUdpIpv6 = Domain, X) -> - case X of - [A,B,C,D,E,F,G,H] - when ?is_ipv6_addr(A, B, C, D, E, F, G, H) -> - ok; - [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] - when ?is_ipv6_addr( - A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> +check_ip(Domain, IP) -> + case check_address_ip(Domain, IP) of + false -> + error({bad_address, {Domain, IP}}); + true -> ok; - _ -> - error({bad_address, {Domain, X}}) - end; -%% -check_ip(BadDomain, _X) -> - error({invalid_domain, BadDomain}). + FixedIP -> + {ok, FixedIP} + end. + +%% check_ip(snmpUDPDomain, X) -> +%% check_ip(transportDomainUdpIpv4, X); +%% check_ip(transportDomainUdpIpv4 = Domain, X) -> +%% case X of +%% [A,B,C,D] when ?is_ipv4_addr(A, B, C, D) -> +%% ok; +%% _ -> +%% error({bad_address, {Domain, X}}) +%% end; +%% check_ip(transportDomainUdpIpv6 = Domain, X) -> +%% case X of +%% [A,B,C,D,E,F,G,H] +%% when ?is_ipv6_addr(A, B, C, D, E, F, G, H) -> +%% ok; +%% [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] +%% when ?is_ipv6_addr( +%% A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> +%% ok; +%% _ -> +%% error({bad_address, {Domain, X}}) +%% end; +%% %% +%% check_ip(BadDomain, _X) -> +%% error({invalid_domain, BadDomain}). %% --------- @@ -850,7 +875,9 @@ check_address_ip(transportDomainUdpIpv6, Address) -> mk_word(A12, A13), mk_word(A14, A15)}; _ -> false - end. + end; +check_address_ip(BadDomain, _) -> + error({bad_domain, BadDomain}). %% -> {IP, Port} check_address_ip_port(Domain, Address) @@ -907,7 +934,9 @@ check_address_ip_port(transportDomainUdpIpv6 = Domain, Address) -> mk_word(P0, P1)}; _ -> false - end. + end; +check_address_ip_port(BadDomain, _) -> + error({bad_domain, BadDomain}). diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 12467a1abf..5dffed8068 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -30,6 +30,7 @@ read_config_file/3, read_config_file/4]). -export([write_agent_snmp_files/7, write_agent_snmp_files/12, + write_agent_snmp_files/6, write_agent_snmp_files/11, write_agent_snmp_conf/5, write_agent_snmp_context_conf/1, @@ -568,11 +569,9 @@ config_agent_snmp(Dir, Vsns) -> end, NT end, - case (catch write_agent_snmp_files(Dir, - Vsns, ManagerIP, TrapUdp, - AgentIP, AgentUDP, - SysName, NotifType, SecType, - Passwd, EngineID, MMS)) of + case (catch write_agent_snmp_files( + Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP, SysName, + NotifType, SecType, Passwd, EngineID, MMS)) of ok -> i("~n- - - - - - - - - - - - -"), i("Info: 1. SecurityName \"initial\" has noAuthNoPriv read access~n" @@ -1581,35 +1580,63 @@ remove_newline(Str) -> %% File generation %%====================================================================== +write_agent_snmp_files( + Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName) + when is_list(Dir), + is_list(Vsns), + is_atom(Domain), + is_list(SysName) -> + write_agent_snmp_files( + Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName, + "trap", none, "", "agentEngine", 484). + %%---------------------------------------------------------------------- %% Dir: string() (ex: "../conf/") %% ManagerIP, AgentIP: [int(),int(),int(),int()] %% TrapUdp, AgentUDP: integer() %% SysName: string() %%---------------------------------------------------------------------- -write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, - AgentIP, AgentUDP, SysName) - when is_list(Dir) andalso - is_list(Vsns) andalso - is_list(ManagerIP) andalso - is_integer(TrapUdp) andalso - is_list(AgentIP) andalso - is_integer(AgentUDP) andalso +write_agent_snmp_files( + Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName) + when is_list(Dir) andalso + is_list(Vsns) andalso + is_list(ManagerIP) andalso + is_integer(TrapUDP) andalso + is_list(AgentIP) andalso + is_integer(AgentUDP) andalso is_list(SysName) -> - write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP, - SysName, "trap", none, "", "agentEngine", 484). + write_agent_snmp_files( + Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName, + "trap", none, "", "agentEngine", 484). %% %% ----- Agent config files generator functions ----- %% -write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP, - SysName, NotifType, SecType, Passwd, EngineID, MMS) -> +write_agent_snmp_files( + Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName, + NotifType, SecType, Passwd, EngineID, MMS) -> + write_agent_snmp_conf(Dir, Domain, AgentAddr, EngineID, MMS), + write_agent_snmp_context_conf(Dir), + write_agent_snmp_community_conf(Dir), + write_agent_snmp_standard_conf(Dir, SysName), + write_agent_snmp_target_addr_conf(Dir, Domain, ManagerAddr, Vsns), + write_agent_snmp_target_params_conf(Dir, Vsns), + write_agent_snmp_notify_conf(Dir, NotifType), + write_agent_snmp_usm_conf(Dir, Vsns, EngineID, SecType, Passwd), + write_agent_snmp_vacm_conf(Dir, Vsns, SecType), + ok. + +write_agent_snmp_files( + Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName, + NotifType, SecType, Passwd, EngineID, MMS) -> + Domain = snmp_target_mib:default_domain(), + ManagerAddr = {ManagerIP, TrapUDP}, write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS), write_agent_snmp_context_conf(Dir), write_agent_snmp_community_conf(Dir), write_agent_snmp_standard_conf(Dir, SysName), - write_agent_snmp_target_addr_conf(Dir, ManagerIP, TrapUdp, Vsns), + write_agent_snmp_target_addr_conf(Dir, Domain, ManagerAddr, Vsns), write_agent_snmp_target_params_conf(Dir, Vsns), write_agent_snmp_notify_conf(Dir, NotifType), write_agent_snmp_usm_conf(Dir, Vsns, EngineID, SecType, Passwd), @@ -1617,11 +1644,32 @@ write_agent_snmp_files(Dir, Vsns, ManagerIP, TrapUdp, AgentIP, AgentUDP, ok. + %% %% ------ [agent] agent.conf ------ %% -write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS) -> + +write_agent_snmp_conf(Dir, Domain, AgentAddr, EngineID, MMS) + when is_atom(Domain) -> + {AgentIP, AgentUDP} = AgentAddr, + Conf = + [{intAgentTransportDomain, Domain}, + {intAgentUDPPort, AgentUDP}, + {intAgentIpAddress, AgentIP}, + {snmpEngineID, EngineID}, + {snmpEngineMaxMessageSize, MMS}], + do_write_agent_snmp_conf(Dir, Conf); +write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS) + when is_integer(AgentUDP) -> + Conf = + [{intAgentUDPPort, AgentUDP}, + {intAgentIpAddress, AgentIP}, + {snmpEngineID, EngineID}, + {snmpEngineMaxMessageSize, MMS}], + do_write_agent_snmp_conf(Dir, Conf). + +do_write_agent_snmp_conf(Dir, Conf) -> Comment = "%% This file defines the Agent local configuration info\n" "%% The data is inserted into the snmpEngine* variables defined\n" @@ -1636,11 +1684,7 @@ write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS) -> "%% {snmpEngineID, \"agentEngine\"}.\n" "%% {snmpEngineMaxMessageSize, 484}.\n" "%%\n\n", - Hdr = header() ++ Comment, - Conf = [{intAgentUDPPort, AgentUDP}, - {intAgentIpAddress, AgentIP}, - {snmpEngineID, EngineID}, - {snmpEngineMaxMessageSize, MMS}], + Hdr = header() ++ Comment, write_agent_config(Dir, Hdr, Conf). write_agent_config(Dir, Hdr, Conf) -> @@ -1746,17 +1790,22 @@ update_agent_standard_config(Dir, Conf) -> %% ------ target_addr.conf ------ %% -write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Vsns) -> +write_agent_snmp_target_addr_conf(Dir, Domain, Addr, Vsns) + when is_atom(Domain) -> Timeout = 1500, RetryCount = 3, - write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, - Timeout, RetryCount, - Vsns). - -write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, - Timeout, RetryCount, - Vsns) -> - Comment = + write_agent_snmp_target_addr_conf( + Dir, Domain, Addr, Timeout, RetryCount, Vsns); +write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Vsns) + when is_integer(UDP) -> + Domain = snmp_target_mib:default_domain(), + Addr = {ManagerIp, UDP}, + write_agent_snmp_target_addr_conf(Dir, Domain, Addr, Vsns). + +write_agent_snmp_target_addr_conf( + Dir, Domain, Addr, Timeout, RetryCount, Vsns) + when is_atom(Domain) -> + Comment = "%% This file defines the target address parameters.\n" "%% The data is inserted into the snmpTargetAddrTable defined\n" "%% in SNMP-TARGET-MIB, and in the snmpTargetAddrExtTable defined\n" @@ -1776,35 +1825,37 @@ write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, "%%\n\n", Hdr = header() ++ Comment, F = fun(v1 = Vsn, Acc) -> - [{mk_ip(ManagerIp, Vsn), - snmp_target_mib:default_domain(), - ManagerIp, UDP, Timeout, RetryCount, + [{mk_name(Addr, Vsn), Domain, Addr, 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, + [{mk_name(Addr, Vsn), Domain, Addr, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, - {lists:flatten(io_lib:format("~s.2",[mk_ip(ManagerIp, Vsn)])), - ManagerIp, UDP, Timeout, RetryCount, + {lists:flatten(io_lib:format("~s.2",[mk_name(Addr, Vsn)])), + Domain, Addr, Timeout, RetryCount, "std_inform", mk_param(Vsn), "", [], 2048}| Acc]; (v3 = Vsn, Acc) -> - [{mk_ip(ManagerIp, Vsn), - snmp_target_mib:default_domain(), - ManagerIp, UDP, Timeout, RetryCount, + [{mk_name(Addr, Vsn), Domain, Addr, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, - {lists:flatten(io_lib:format("~s.3",[mk_ip(ManagerIp, Vsn)])), - ManagerIp, UDP, Timeout, RetryCount, + {lists:flatten(io_lib:format("~s.3",[mk_name(Addr, Vsn)])), + Domain, Addr, Timeout, RetryCount, "std_inform", mk_param(Vsn), "mgrEngine", [], 2048}| Acc] end, Conf = lists:foldl(F, [], Vsns), - write_agent_target_addr_config(Dir, Hdr, Conf). + write_agent_target_addr_config(Dir, Hdr, Conf); +write_agent_snmp_target_addr_conf( + Dir, ManagerIp, UDP, Timeout, RetryCount, Vsns) when is_integer(UDP) -> + Domain = snmp_target_mib:default_domain(), + Addr = {ManagerIp, UDP}, + write_agent_snmp_target_addr_conf( + Dir, Domain, Addr, Timeout, RetryCount, Vsns). mk_param(Vsn) -> lists:flatten(io_lib:format("target_~w", [Vsn])). -mk_ip([A,B,C,D], Vsn) -> - lists:flatten(io_lib:format("~w.~w.~w.~w ~w", [A,B,C,D,Vsn])). +mk_name({[A,B,C,D], _}, Vsn) -> + lists:flatten(io_lib:format("~w.~w.~w.~w ~w", [A,B,C,D,Vsn])); +mk_name(Address, Vsn) -> + lists:flatten(io_lib:format("~w ~w", [Address,Vsn])). write_agent_target_addr_config(Dir, Hdr, Conf) -> snmpa_conf:write_target_addr_config(Dir, Hdr, Conf). @@ -2438,14 +2489,20 @@ write_config_file(Dir, FileName, Verify, Write) is_list(FileName) andalso is_function(Verify) andalso is_function(Write)) -> - try - begin - do_write_config_file(Dir, FileName, Verify, Write) - end + try do_write_config_file(Dir, FileName, Verify, Write) of + ok -> + ok; + Other -> + d("File write of ~s returned: ~p~n", [FileName,Other]) catch throw:Error -> + S = erlang:get_stacktrace(), + d("File write of ~s throwed: ~p~n ~p~n", [FileName,Error,S]), Error; T:E -> + S = erlang:get_stacktrace(), + d("File write of ~s exception: ~p:~p~n ~p~n", + [FileName,T,E,S]), {error, {failed_write, Dir, FileName, {T, E, erlang:get_stacktrace()}}} @@ -2652,8 +2709,8 @@ ensure_started(App) -> %% ------------------------------------------------------------------------- -% d(F, A) -> -% i("DBG: " ++ F, A). +d(F, A) -> + i("DBG: " ++ F, A). i(F) -> i(F, []). -- cgit v1.2.3 From 36426bcc894853dfd38a4d8db7b4971934df9692 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 9 May 2014 13:54:21 +0200 Subject: Go back to passing (Domain, Addr) to net_if filters --- lib/snmp/src/agent/snmp_framework_mib.erl | 17 +- lib/snmp/src/agent/snmpa_net_if.erl | 271 +++++++++++++++++---- lib/snmp/src/agent/snmpa_net_if_filter.erl | 23 +- .../src/agent/snmpa_network_interface_filter.erl | 6 +- lib/snmp/src/agent/snmpa_trap.erl | 101 +++++--- lib/snmp/src/misc/snmp_pdus.erl | 17 +- 6 files changed, 331 insertions(+), 104 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 0b439aa5f1..fb52f90852 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -190,15 +190,22 @@ check_context(Context) -> %% Agent %% {Name, Value}. %%----------------------------------------------------------------- -check_agent({intAgentTransportDomain, D}, Domain) -> +check_agent({intAgentTransportDomain, D}, _Domain) -> {snmp_conf:check_domain(D), D}; -check_agent({intAgentIpAddress, Value}, D) -> +check_agent({intAgentIpAddress = Tag, Value}, D) -> Domain = case D of - undefined -> snmp_target_mib:default_domain(); - _ -> D + undefined -> + snmp_target_mib:default_domain(); + _ -> + D end, - {snmp_conf:check_ip(Domain, Value), Domain}; + {case snmp_conf:check_ip(Domain, Value) of + ok -> + ok; + {ok, FixedIp} -> + {ok, {Tag, FixedIp}} + end, Domain}; check_agent(Entry, Domain) -> {check_agent(Entry), Domain}. diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 96211fc5f4..53eebb1728 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -46,7 +46,8 @@ debug = false, limit = infinity, rcnt = [], - filter}). + filter, + use_tdomain = false}). -ifndef(default_verbosity). -define(default_verbosity,silence). @@ -165,6 +166,13 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> %% -- Port and address -- Domain = get_domain(), ?vdebug("domain: ~w",[Domain]), + UseTDomain = + case Domain of + snmpUDPDomain -> + false; + _ -> + true + end, UDPPort = get_port(), ?vdebug("port: ~w",[UDPPort]), IPAddress = get_address(), @@ -208,7 +216,8 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> usock_opts = IPOpts, log = Log, limit = Limit, - filter = FilterMod}, + filter = FilterMod, + use_tdomain = UseTDomain}, ?vdebug("started with MpdState: ~p", [MpdState]), {ok, S}; {error, Reason} -> @@ -541,14 +550,39 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, maybe_handle_recv( - #state{usock = Sock, filter = FilterMod} = S, From, Packet) -> - case (catch FilterMod:accept_recv(From)) of + #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain} = S, + {Domain, Addr} = From, Packet) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_recv(Domain, Addr); + false -> + {Ip, Port} = Addr, + FilterMod:accept_recv(Ip, Port) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_recv/2 crashed for ~p: ~w:~w~n ~p", + [From,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> %% Drop the received packet inc(netIfMsgInDrops), active_once(Sock), S; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_recv/2 returned: ~p for ~p", + [Other,From]) + end, handle_recv(S, From, Packet) end. @@ -620,15 +654,40 @@ handle_recv( end. maybe_handle_recv_pdu( - From, Vsn, + {Domain, Addr} = From, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, - #state{usock = Sock, filter = FilterMod} = S) -> - case (catch FilterMod:accept_recv_pdu(From, Type)) of + #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain} = S) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_recv_pdu(Domain, Addr, Type); + false -> + {Ip, Port} = Addr, + FilterMod:accept_recv_pdu(Ip, Port, Type) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_recv_pdu/3 crashed for ~p, ~p: ~w:~w~n" + " ~p", + [From,Type,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfPduInDrops), active_once(Sock), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_recv_pdu/3 returned: ~p for ~p, ~p", + [Other,From,Type]) + end, handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) end; maybe_handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) -> @@ -658,15 +717,40 @@ handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, maybe_handle_reply_pdu( - #state{filter = FilterMod} = S, Vsn, + #state{filter = FilterMod, use_tdomain = UseTDomain} = S, Vsn, #pdu{request_id = Rid} = Pdu, - Type, ACMData, To) -> + Type, ACMData, {_Domain, Addr} = To) -> S1 = update_req_counter_outgoing(S, Rid), - case (catch FilterMod:accept_send_pdu([To], Type)) of + Addresses = + case UseTDomain of + true -> + [To]; + false -> + [Addr] + end, + case + try + FilterMod:accept_send_pdu(Addresses, Type) + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", + [Addresses,Type,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfPduOutDrops), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_send_pdu(~p, ~p) returned: ~p", + [Addresses,Type,Other]) + end, handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, To) end, S1. @@ -694,7 +778,7 @@ handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> maybe_handle_send_pdu( - #state{filter = FilterMod} = S, + #state{filter = FilterMod, use_tdomain = UseTDomain} = S, Vsn, Pdu, MsgData, TDomAddrSecs, From) -> ?vtrace("maybe_handle_send_pdu -> entry with~n" @@ -702,42 +786,77 @@ maybe_handle_send_pdu( " TDomAddrSecs: ~p", [FilterMod, TDomAddrSecs]), DomAddrSecs = snmpa_mpd:process_taddrs(TDomAddrSecs), - DomAddrs = - [case DAS of - {{Domain, _Address} = DomAddr, _SecData} - when is_atom(Domain) -> % v3 - DomAddr; - {Domain, _Address} = DomAddr - when is_atom(Domain) -> % v1 & v2 - DomAddr + AddressesToFilter = + [case UseTDomain of + true -> + case DAS of + {{Domain, _Address} = DomAddr, _SecData} + when is_atom(Domain) -> % v3 + DomAddr; + {Domain, _Address} = DomAddr + when is_atom(Domain) -> % v1 & v2 + DomAddr + end; + false -> + case DAS of + {{Domain, Address}, _SecData} + when is_atom(Domain) -> % v3 + Address; + {Domain, Address} + when is_atom(Domain) -> % v1 & v2 + Address + end end || DAS <- DomAddrSecs], - - case (catch FilterMod:accept_send_pdu( - DomAddrs, pdu_type_of(Pdu))) of + Type = pdu_type_of(Pdu), + + case + try FilterMod:accept_send_pdu(AddressesToFilter, Type) + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", + [AddressesToFilter,Type, + Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfPduOutDrops), ok; true -> handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From); - FilteredDomAddrs when is_list(FilteredDomAddrs) -> + FilteredAddresses when is_list(FilteredAddresses) -> MergedDomAddrSecs = - [DAS || DAS <- DomAddrSecs, - case DAS of - {{Domain, _Address} = DomAddr, _SData} - when is_atom(Domain) -> % v3 - lists:member( - DomAddr, FilteredDomAddrs); - {Domain, _Address} = DomAddr - when is_atom(Domain) -> % v1 & v2 - lists:member( - DomAddr, FilteredDomAddrs) - end], + [DAS || + DAS <- DomAddrSecs, + lists:member( + case UseTDomain of + true -> + case DAS of + {{Domain, _Address} = DomAddr, _SData} + when is_atom(Domain) -> % v3 + DomAddr; + {Domain, _Address} = DomAddr + when is_atom(Domain) -> % v1 & v2 + DomAddr + end; + false -> + case DAS of + {{Domain, Address}, _SData} + when is_atom(Domain) -> % v3 + Address; + {Domain, Address} + when is_atom(Domain) -> % v1 & v2 + Address + end + end, FilteredAddresses)], ?vtrace("maybe_handle_send_pdu -> MergedDomAddrSecs:~n" " ~p", [MergedDomAddrSecs]), handle_send_pdu(S, Vsn, Pdu, MsgData, MergedDomAddrSecs, From); Other -> error_msg( - "FilterMod:accept_send_pdu/2 returned: ~p", [Other]), + "FilterMod:accept_send_pdu(~p, ~p) returned: ~p", + [AddressesToFilter,Type,Other]), handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From) end. @@ -856,31 +975,81 @@ handle_response(Vsn, Pdu, From, S) -> end. maybe_udp_send( - #state{usock = Sock, - filter = FilterMod}, To, Packet) -> - case (catch FilterMod:accept_send(To)) of + #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain}, + {Domain, Addr} = To, Packet) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_send(Domain, Addr); + false -> + {Ip, Port} = Addr, + FilterMod:accept_send(Ip, Port) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send/2 crashed for ~p: ~w:~w~n ~p", + [To,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfMsgOutDrops), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_send/2 returned: ~p for ~p", + [Other,To]) + end, %% XXX should be some kind of lookup of domain to socket - {_Domain, {Ip, Port}} = To, - (catch udp_send(Sock, Ip, Port, Packet)) + {SockIp, SockPort} = Addr, + (catch udp_send(Sock, SockIp, SockPort, Packet)) end. maybe_udp_send( - #state{log = Log, - usock = Sock, - filter = FilterMod}, To, Packet, Type, _LogData) -> - case (catch FilterMod:accept_send(To)) of + #state{log = Log, + usock = Sock, + filter = FilterMod, + use_tdomain = UseTDomain}, + {Domain, Addr} = To, Packet, Type, _LogData) -> + case + try + case UseTDomain of + true -> + FilterMod:accept_send(Domain, Addr); + false -> + {Ip, Port} = Addr, + FilterMod:accept_send(Ip, Port) + end + catch + Class:Exception -> + error_msg( + "FilterMod:accept_send/2 crashed for ~p: ~w:~w~n ~p", + [To,Class,Exception,erlang:get_stacktrace()]), + true + end + of false -> inc(netIfMsgOutDrops), ok; - _ -> + Other -> + case Other of + true -> + ok; + _ -> + error_msg( + "FilterMod:accept_send/2 returned: ~p for ~p", + [Other,To]) + end, log(Log, Type, Packet, To), %% XXX should be some kind of lookup of domain to socket - {_Domain, {Ip, Port}} = To, - (catch udp_send(Sock, Ip, Port, Packet)) + {SockIp, SockPort} = Addr, + (catch udp_send(Sock, SockIp, SockPort, Packet)) end. udp_send(UdpId, AgentIp, UdpPort, B) -> diff --git a/lib/snmp/src/agent/snmpa_net_if_filter.erl b/lib/snmp/src/agent/snmpa_net_if_filter.erl index e71abc4ac6..dd77b143d0 100644 --- a/lib/snmp/src/agent/snmpa_net_if_filter.erl +++ b/lib/snmp/src/agent/snmpa_net_if_filter.erl @@ -18,46 +18,39 @@ %% -module(snmpa_net_if_filter). -%% New behaviour --export([accept_recv/1, accept_send/1, accept_recv_pdu/2]). -%% Common signature for both old and new behaviour --export([accept_send_pdu/2]). -%% Old behaviour --export([accept_recv/2, accept_send/2, accept_recv_pdu/3]). +%% Behaviour +-export([accept_recv/2, accept_send/2, accept_recv_pdu/3, accept_send_pdu/2]). -include("snmp_debug.hrl"). -accept_recv({Domain, _Address}) when is_atom(Domain) -> +accept_recv(Domain, _Address) when is_atom(Domain) -> ?d("accept_recv -> entry with~n" " Domain: ~p~n" " Address: ~p", [Domain, _Address]), - true. -%% + true; accept_recv(_Addr, Port) when is_integer(Port) -> ?d("accept_recv -> entry with~n" " Addr: ~p~n" " Port: ~p", [_Addr, Port]), true. -accept_send({Domain, _Address}) when is_atom(Domain) -> +accept_send(Domain, _Address) when is_atom(Domain) -> ?d("accept_send -> entry with~n" " Domain: ~p~n" " Address: ~p", [Domain, _Address]), - true. -%% + true; accept_send(_Addr, Port) when is_integer(Port) -> ?d("accept_send -> entry with~n" " Addr: ~p~n" " Port: ~p", [_Addr, Port]), true. -accept_recv_pdu({Domain, _Address}, _PduType) when is_atom(Domain) -> +accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> ?d("accept_recv -> entry with~n" " Domain: ~p~n" " Address: ~p~n" " PduType: ~p", [Domain, _Address, _PduType]), - true. -%% + true; accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) -> ?d("accept_recv_pdu -> entry with~n" " Addr: ~p~n" diff --git a/lib/snmp/src/agent/snmpa_network_interface_filter.erl b/lib/snmp/src/agent/snmpa_network_interface_filter.erl index 3fa83db874..90aa54a271 100644 --- a/lib/snmp/src/agent/snmpa_network_interface_filter.erl +++ b/lib/snmp/src/agent/snmpa_network_interface_filter.erl @@ -23,9 +23,9 @@ behaviour_info(callbacks) -> - [{accept_recv, 1}, - {accept_send, 1}, - {accept_recv_pdu, 2}, + [{accept_recv, 2}, + {accept_send, 2}, + {accept_recv_pdu, 3}, {accept_send_pdu, 2}]; behaviour_info(_) -> undefined. diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index b9a2496341..a2d821c099 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -1045,7 +1045,7 @@ deliver_recv(#snmpa_notification_delivery_info{tag = Tag, "~n DeliveryResult: ~p" "~n TAddr: ~p" "", [Tag, Mod, Extra, DeliveryResult, TAddr]), - Addr = transform_taddr(TAddr), + [Addr] = transform_taddrs([TAddr]), (catch Mod:delivery_info(Tag, Addr, DeliveryResult, Extra)); deliver_recv({Tag, Receiver}, MsgId, Result) -> ?vtrace("deliver_recv -> entry with" @@ -1072,35 +1072,80 @@ deliver_recv(Else, _MsgId, _Result) -> [Else]), user_err("snmpa: bad receiver, ~w\n", [Else]). -transform_taddrs(Addrs) -> - [transform_taddr(Addr) || Addr <- Addrs]. +transform_taddrs(TAddrs) -> + UseTDomain = + case snmp_framework_mib:intAgentTransportDomain(get) of + {value,snmpUDPDomain} -> + false; + {value,_} -> + true; + genErr -> + false + end, + DomAddrs = [transform_taddr(TAddr) || TAddr <- TAddrs], + case UseTDomain of + true -> + DomAddrs; + false -> + [Addr || {_Domain, Addr} <- DomAddrs] + end. -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}, +%% v2 +transform_taddr({?snmpUDPDomain, Addr}) -> + transform_taddr(transportDomainIdpIpv4, Addr); +transform_taddr({?transportDomainUdpIpv4, Addr}) -> + transform_taddr(transportDomainUdpIpv4, Addr); +transform_taddr({?transportDomainUdpIpv6, Addr}) -> + transform_taddr(transportDomainUdpIpv6, Addr); +%% v3 +transform_taddr({{?snmpUDPDomain, Addr}, _MsgData}) -> + transform_taddr(transportDomainUdpIpv4, Addr); +transform_taddr({{?transportDomainUdpIpv4, Addr}, _MsgData}) -> + transform_taddr(transportDomainUdpIpv4, Addr); +transform_taddr({{?transportDomainUdpIpv6, Addr}, _MsgData}) -> + transform_taddr(transportDomainUdpIpv6, Addr). + +transform_taddr( + transportDomainUdpIpv4 = Domain, + [A1,A2,A3,A4,P1,P2]) -> + Ip = {A1, A2, A3, A4}, Port = P1 bsl 8 + P2, - {Addr, Port}; -transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 - Addr = {A1, A2, A3, A4}, + {Domain, {Ip, Port}}; +transform_taddr( + transportDomainUdpIpv6 = Domain, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> + Ip = {A1, A2, A3, A4, A5, A6, A7, A8}, 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}. + {Domain, {Ip, Port}}. + + +%% 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}. + check_all_varbinds(#notification{oid = Oid}, Vbs, MibView) -> diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl index 15156f7467..a780fee7a3 100644 --- a/lib/snmp/src/misc/snmp_pdus.erl +++ b/lib/snmp/src/misc/snmp_pdus.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -664,7 +664,20 @@ enc_value('BITS', Val) -> enc_oct_str_tag(bits_to_str(Val)); enc_value('OBJECT IDENTIFIER', Val) -> enc_oid_tag(Val); -enc_value('IpAddress', Val) -> +enc_value('IpAddress', {A, B, C, D}) -> + enc_value('IpAddress', [A,B,C,D]); +enc_value('IpAddress', {A, B, C, D, E, F, G, H}) -> + enc_value( + 'IpAddress', + [A bsr 8, A band 255, + B bsr 8, B band 255, + C bsr 8, C band 255, + D bsr 8, D band 255, + E bsr 8, E band 255, + F bsr 8, F band 255, + G bsr 8, G band 255, + H bsr 8, H band 255]); +enc_value('IpAddress', Val) when is_list(Val) -> Bytes2 = enc_oct_str_notag(Val), Len2 = elength(length(Bytes2)), lists:append([64 | Len2],Bytes2); -- cgit v1.2.3 From 79bfddd5d49d26f45c9813738f7c29e8e3afee19 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 14 May 2014 09:26:57 +0200 Subject: Bugfix: argument order to internal function verify_lines/4 --- lib/snmp/src/misc/snmp_config.erl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 5dffed8068..b1a99accf2 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -2623,15 +2623,15 @@ read_and_parse_term(Fd, StartLine) -> Other end. -verify_lines([], _, Acc, _) -> +verify_lines([], _, _, Acc) -> list:reverse(Acc); verify_lines( - [{StartLine, Term, EndLine}|Lines], State, Acc, Check) -> + [{StartLine, Term, EndLine}|Lines], Check, State, Acc) -> try Check(Term, State) of {ok, NewState} -> - verify_lines(Lines, NewState, [Term|Acc], Check); + verify_lines(Lines, Check, NewState, [Term|Acc]); {{ok, NewTerm}, NewState} -> - verify_lines(Lines, NewState, [NewTerm|Acc], Check) + verify_lines(Lines, Check, NewState, [NewTerm|Acc]) catch {error, Reason} -> throw({failed_check, StartLine, EndLine, Reason}); -- cgit v1.2.3 From b012122510b88bd752652bbd400cc03e68c45a7e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 14 May 2014 13:17:06 +0200 Subject: bugfix: Call to non-existing module 'list' --- lib/snmp/src/misc/snmp_config.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index b1a99accf2..7e52d68fa1 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -2624,7 +2624,7 @@ read_and_parse_term(Fd, StartLine) -> end. verify_lines([], _, _, Acc) -> - list:reverse(Acc); + lists:reverse(Acc); verify_lines( [{StartLine, Term, EndLine}|Lines], Check, State, Acc) -> try Check(Term, State) of -- cgit v1.2.3 From 9a955974c52baa62ca7283f86257ddca59d4dfd3 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 14 May 2014 08:22:23 +0200 Subject: wip: Fix agent logging --- lib/snmp/src/agent/snmpa_agent.erl | 10 +- lib/snmp/src/agent/snmpa_mpd.erl | 30 +++-- lib/snmp/src/agent/snmpa_net_if.erl | 262 +++++++++++++++++------------------- lib/snmp/src/misc/snmp_conf.erl | 15 ++- lib/snmp/src/misc/snmp_config.erl | 4 +- lib/snmp/src/misc/snmp_log.erl | 187 ++++++++++++++++--------- lib/snmp/test/snmp_conf_test.erl | 2 + 7 files changed, 285 insertions(+), 225 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index dadd9d7ccd..6d3f1cca4a 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -2516,7 +2516,15 @@ process_msg( MibView, Vsn, Pdu, PduMS, Community, SourceAddress, ContextName, GbMaxVBs) -> #pdu{request_id = ReqId} = Pdu, - put(snmp_address, SourceAddress), + put( + snmp_address, + case SourceAddress of + {Domain, _} when is_atom(Domain) -> + SourceAddress; + {Ip, Port} when is_integer(Port) -> + %% Legacy transport domain + {tuple_to_list(Ip), Port} + end), put(snmp_request_id, ReqId), put(snmp_community, Community), put(snmp_context, ContextName), diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index 3caed27c42..dbd57b732c 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -192,24 +192,28 @@ discarded_pdu(Variable) -> inc(Variable). %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- v1_v2c_proc( - Vsn, NoteStore, Community, {Domain, Address}, + Vsn, NoteStore, Community, From, LocalEngineID, Data, HS, Log, Packet) -> - try snmp_conf:mk_tdomain(Domain) of - TDomain -> - try snmp_conf:mk_taddress(Domain, Address) of - TAddress -> - v1_v2c_proc_dec( - Vsn, NoteStore, Community, TDomain, TAddress, - LocalEngineID, Data, HS, Log, Packet) - catch - _ -> - {discarded, {badarg, Address}} - end + try + case From of + {D, A} when is_atom(D) -> + {snmp_conf:mk_tdomain(D), + snmp_conf:mk_taddress(D, A)}; + {_, P} = A when is_integer(P) -> + {snmp_conf:mk_tdomain(), + snmp_conf:mk_taddress(A)} + end + of + {TDomain, TAddress} -> + v1_v2c_proc_dec( + Vsn, NoteStore, Community, TDomain, TAddress, + LocalEngineID, Data, HS, Log, Packet) catch _ -> - {discarded, {badarg, Domain}} + {discarded, {badarg, From}} end. + v1_v2c_proc_dec( Vsn, NoteStore, Community, TDomain, TAddress, LocalEngineID, Data, HS, Log, Packet) -> diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 53eebb1728..42e93bff65 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -28,6 +28,7 @@ -export([system_continue/3, system_terminate/4, system_code_change/4]). -export([init/5]). -export([filter_reset/1]). +-export([format_address/1]). -include("snmp_types.hrl"). -include("snmpa_internal.hrl"). @@ -47,7 +48,7 @@ limit = infinity, rcnt = [], filter, - use_tdomain = false}). + domain = snmpUDPDomain}). -ifndef(default_verbosity). -define(default_verbosity,silence). @@ -166,13 +167,6 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> %% -- Port and address -- Domain = get_domain(), ?vdebug("domain: ~w",[Domain]), - UseTDomain = - case Domain of - snmpUDPDomain -> - false; - _ -> - true - end, UDPPort = get_port(), ?vdebug("port: ~w",[UDPPort]), IPAddress = get_address(), @@ -187,7 +181,7 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> ?vdebug("Limit: ~w", [Limit]), FilterOpts = get_filter_opts(Opts), FilterMod = create_filter(FilterOpts), - ?vdebug("FilterMod: ~w", [FilterMod]), + ?vdebug("FilterMod: ~w FilterOpts: ~p", [FilterMod,FilterOpts]), %% -- Audit trail log Log = create_log(), @@ -202,7 +196,6 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> IPOpts = [binary, snmp_conf:tdomain_to_family(Domain) | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4], - ?vdebug("open socket with options: ~w",[IPOpts]), case gen_udp_open(UDPPort, IPOpts) of {ok, Sock} -> MpdState = snmpa_mpd:init(Vsns), @@ -217,7 +210,7 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> log = Log, limit = Limit, filter = FilterMod, - use_tdomain = UseTDomain}, + domain = Domain}, ?vdebug("started with MpdState: ~p", [MpdState]), {ok, S}; {error, Reason} -> @@ -278,50 +271,69 @@ create_filter(BadOpts) -> throw({error, {bad_filter_opts, BadOpts}}). -log(LogTypes, Req, Packet, {Domain, Address}) -> - log(LogTypes, Req, Packet, Domain, Address). - -log({_, []}, _, _, _, _) -> +log({_, []}, _, _, _) -> ok; -log({Log, Types}, 'set-request', Packet, Domain, Address) -> +log({Log, Types}, 'set-request', Packet, Address) -> case lists:member(write, Types) of true -> - snmp_log:log(Log, Packet, Domain, Address); + snmp_log:log(Log, Packet, format_address(Address)); false -> ok end; -log({Log, Types}, _, Packet, Domain, Address) -> +log({Log, Types}, _, Packet, Address) -> case lists:member(read, Types) of true -> - snmp_log:log(Log, Packet, Domain, Address); + snmp_log:log(Log, Packet, format_address(Address)); false -> ok - end; -log(_, _, _, _, _) -> - ok. + end. +%% log(_, _, _, _, _) -> +%% ok. + +format_address({snmpUDPDomain, {_Ip, Port} = Addr}) when is_integer(Port) -> + format_address(Addr); +format_address({transportDomainUdpIpv4, {Ip, Port}}) -> + format_address("udpIpv4/~s:~w", [inet:ntoa(Ip), Port]); +format_address({transportDomainUdpIpv6, {Ip, Port}}) -> + format_address("udpIpv6/[~s]:~w", [inet:ntoa(Ip), Port]); +format_address({Ip, Port}) when is_integer(Port) -> + format_address("~s:~w", [inet:ntoa(Ip), Port]). + +format_address(Format, Args) -> + iolist_to_binary(io_lib:format(Format, Args)). + gen_udp_open(Port, Opts) -> case init:get_argument(snmp_fd) of {ok, [[FdStr]]} -> Fd = list_to_integer(FdStr), + ?vdebug("gen_udp_open(~p, ~p) Fd: ~p",[Port,Opts,Fd]), gen_udp:open(0, [{fd, Fd}|Opts]); error -> case init:get_argument(snmpa_fd) of {ok, [[FdStr]]} -> Fd = list_to_integer(FdStr), + ?vdebug("gen_udp_open(~p, ~p) Fd: ~p",[Port,Opts,Fd]), gen_udp:open(0, [{fd, Fd}|Opts]); error -> + ?vdebug("gen_udp_open(~p, ~p)",[Port,Opts]), gen_udp:open(Port, Opts) end end. -loop(S) -> +loop(#state{domain = Domain} = S) -> receive {udp, _UdpId, Ip, Port, Packet} -> ?vlog("got paket from ~w:~w",[Ip,Port]), - From = snmp_conf:ip_port_to_domaddr(Ip, Port), + From = + case Domain of + snmpUDPDomain -> + {Ip, Port}; + _ -> + {Domain, {Ip, Port}} + end, NewS = maybe_handle_recv(S, From, Packet), loop(NewS); @@ -550,22 +562,15 @@ update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, maybe_handle_recv( - #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain} = S, - {Domain, Addr} = From, Packet) -> + #state{usock = Sock, filter = FilterMod} = S, From, Packet) -> + {From_1, From_2} = From, case - try - case UseTDomain of - true -> - FilterMod:accept_recv(Domain, Addr); - false -> - {Ip, Port} = Addr, - FilterMod:accept_recv(Ip, Port) - end + try FilterMod:accept_recv(From_1, From_2) catch Class:Exception -> error_msg( - "FilterMod:accept_recv/2 crashed for ~p: ~w:~w~n ~p", - [From,Class,Exception,erlang:get_stacktrace()]), + "FilterMod:accept_recv(~p, ~p) crashed: ~w:~w~n ~p", + [From_1,From_2,Class,Exception,erlang:get_stacktrace()]), true end of @@ -580,8 +585,8 @@ maybe_handle_recv( ok; _ -> error_msg( - "FilterMod:accept_recv/2 returned: ~p for ~p", - [Other,From]) + "FilterMod:accept_recv(~p, ~p) returned: ~p", + [From_1,From_2,Other]) end, handle_recv(S, From, Packet) end. @@ -634,15 +639,13 @@ handle_recv( ?vlog("sending report for reason: " "~n ~s", [?vapply(snmp_misc, format, [256, "~w", [Reason]])]), - {_Domain, {Ip, Port}} = From, - (catch udp_send(S#state.usock, Ip, Port, ReportPacket)), + (catch udp_send(S#state.usock, From, ReportPacket)), active_once(Sock), S; {discovery, ReportPacket} -> ?vlog("sending discovery report", []), - {_Domain, {Ip, Port}} = From, - (catch udp_send(S#state.usock, Ip, Port, ReportPacket)), + (catch udp_send(S#state.usock, From, ReportPacket)), active_once(Sock), S; @@ -654,24 +657,19 @@ handle_recv( end. maybe_handle_recv_pdu( - {Domain, Addr} = From, Vsn, + From, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, - #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain} = S) -> + #state{usock = Sock, filter = FilterMod} = S) -> + {From_1, From_2} = From, case - try - case UseTDomain of - true -> - FilterMod:accept_recv_pdu(Domain, Addr, Type); - false -> - {Ip, Port} = Addr, - FilterMod:accept_recv_pdu(Ip, Port, Type) - end + try FilterMod:accept_recv_pdu(From_1, From_2, Type) catch Class:Exception -> error_msg( - "FilterMod:accept_recv_pdu/3 crashed for ~p, ~p: ~w:~w~n" + "FilterMod:accept_recv_pdu(~p, ~p, ~p) crashed: ~w:~w~n" " ~p", - [From,Type,Class,Exception,erlang:get_stacktrace()]), + [From_1,From_2,Type,Class,Exception, + erlang:get_stacktrace()]), true end of @@ -685,13 +683,11 @@ maybe_handle_recv_pdu( ok; _ -> error_msg( - "FilterMod:accept_recv_pdu/3 returned: ~p for ~p, ~p", - [Other,From,Type]) + "FilterMod:accept_recv_pdu(~p, ~p, ~p) returned: ~p", + [From_1,From_2,Type,Other]) end, handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) - end; -maybe_handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) -> - handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S). + end. handle_recv_pdu( From, Vsn, @@ -717,17 +713,12 @@ handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, maybe_handle_reply_pdu( - #state{filter = FilterMod, use_tdomain = UseTDomain} = S, Vsn, + #state{filter = FilterMod} = S, Vsn, #pdu{request_id = Rid} = Pdu, - Type, ACMData, {_Domain, Addr} = To) -> + Type, ACMData, To) -> + S1 = update_req_counter_outgoing(S, Rid), - Addresses = - case UseTDomain of - true -> - [To]; - false -> - [Addr] - end, + Addresses = [To], case try FilterMod:accept_send_pdu(Addresses, Type) @@ -778,7 +769,7 @@ handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> maybe_handle_send_pdu( - #state{filter = FilterMod, use_tdomain = UseTDomain} = S, + #state{filter = FilterMod, domain = Domain} = S, Vsn, Pdu, MsgData, TDomAddrSecs, From) -> ?vtrace("maybe_handle_send_pdu -> entry with~n" @@ -787,24 +778,24 @@ maybe_handle_send_pdu( DomAddrSecs = snmpa_mpd:process_taddrs(TDomAddrSecs), AddressesToFilter = - [case UseTDomain of - true -> + [case Domain of + snmpUDPDomain -> case DAS of - {{Domain, _Address} = DomAddr, _SecData} - when is_atom(Domain) -> % v3 - DomAddr; - {Domain, _Address} = DomAddr - when is_atom(Domain) -> % v1 & v2 - DomAddr + {{Dom, Addr}, _SecData} + when is_atom(Dom) -> % v3 + Addr; + {Dom, Addr} + when is_atom(Dom) -> % v1 & v2 + Addr end; - false -> + _ -> case DAS of - {{Domain, Address}, _SecData} - when is_atom(Domain) -> % v3 - Address; - {Domain, Address} - when is_atom(Domain) -> % v1 & v2 - Address + {{Dom, _Addr} = DomAddr, _SecData} + when is_atom(Dom) -> % v3 + DomAddr; + {Dom, _Addr} = DomAddr + when is_atom(Dom) -> % v1 & v2 + DomAddr end end || DAS <- DomAddrSecs], Type = pdu_type_of(Pdu), @@ -830,24 +821,24 @@ maybe_handle_send_pdu( [DAS || DAS <- DomAddrSecs, lists:member( - case UseTDomain of + case Domain of + snmpUDPDomain -> + case DAS of + {{Dom, Addr}, _SData} + when is_atom(Dom) -> % v3 + Addr; + {Dom, Addr} + when is_atom(Dom) -> % v1 & v2 + Addr + end; true -> case DAS of - {{Domain, _Address} = DomAddr, _SData} - when is_atom(Domain) -> % v3 + {{Dom, _Addr} = DomAddr, _SData} + when is_atom(Dom) -> % v3 DomAddr; - {Domain, _Address} = DomAddr - when is_atom(Domain) -> % v1 & v2 + {Dom, _Addr} = DomAddr + when is_atom(Dom) -> % v1 & v2 DomAddr - end; - false -> - case DAS of - {{Domain, Address}, _SData} - when is_atom(Domain) -> % v3 - Address; - {Domain, Address} - when is_atom(Domain) -> % v1 & v2 - Address end end, FilteredAddresses)], ?vtrace("maybe_handle_send_pdu -> MergedDomAddrSecs:~n" @@ -909,9 +900,8 @@ handle_send_discovery( case (catch snmpa_mpd:generate_discovery_msg(NS, Pdu, MsgData, To)) of {ok, {Domain, Address, Packet}} -> - log(Log, Type, Packet, Domain, Address), - {Ip, Port} = Address, - udp_send(Sock, Ip, Port, Packet), + log(Log, Type, Packet, {Domain, Address}), + udp_send(Sock, {Domain, Address}, Packet), ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]), NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}), S#state{reqs = NReqs}; @@ -975,22 +965,16 @@ handle_response(Vsn, Pdu, From, S) -> end. maybe_udp_send( - #state{usock = Sock, filter = FilterMod, use_tdomain = UseTDomain}, - {Domain, Addr} = To, Packet) -> + #state{usock = Sock, filter = FilterMod}, + To, Packet) -> + {To_1, To_2} = To, case - try - case UseTDomain of - true -> - FilterMod:accept_send(Domain, Addr); - false -> - {Ip, Port} = Addr, - FilterMod:accept_send(Ip, Port) - end + try FilterMod:accept_send(To_1, To_2) catch Class:Exception -> error_msg( - "FilterMod:accept_send/2 crashed for ~p: ~w:~w~n ~p", - [To,Class,Exception,erlang:get_stacktrace()]), + "FilterMod:accept_send(~p, ~p) crashed: ~w:~w~n ~p", + [To_1,To_2,Class,Exception,erlang:get_stacktrace()]), true end of @@ -1003,34 +987,26 @@ maybe_udp_send( ok; _ -> error_msg( - "FilterMod:accept_send/2 returned: ~p for ~p", - [Other,To]) + "FilterMod:accept_send(~p, ~p) returned: ~p", + [To_1,To_2,Other]) end, %% XXX should be some kind of lookup of domain to socket - {SockIp, SockPort} = Addr, - (catch udp_send(Sock, SockIp, SockPort, Packet)) + (catch udp_send(Sock, To, Packet)) end. maybe_udp_send( #state{log = Log, usock = Sock, - filter = FilterMod, - use_tdomain = UseTDomain}, - {Domain, Addr} = To, Packet, Type, _LogData) -> + filter = FilterMod}, + To, Packet, Type, _LogData) -> + {To_1, To_2} = To, case - try - case UseTDomain of - true -> - FilterMod:accept_send(Domain, Addr); - false -> - {Ip, Port} = Addr, - FilterMod:accept_send(Ip, Port) - end + try FilterMod:accept_send(To_1, To_2) catch Class:Exception -> error_msg( - "FilterMod:accept_send/2 crashed for ~p: ~w:~w~n ~p", - [To,Class,Exception,erlang:get_stacktrace()]), + "FilterMod:accept_send(~p, ~p) crashed for: ~w:~w~n ~p", + [To_1,To_2,Class,Exception,erlang:get_stacktrace()]), true end of @@ -1043,28 +1019,34 @@ maybe_udp_send( ok; _ -> error_msg( - "FilterMod:accept_send/2 returned: ~p for ~p", - [Other,To]) + "FilterMod:accept_send(~p, ~p) returned: ~p", + [To_1,To_2,Other]) end, log(Log, Type, Packet, To), - %% XXX should be some kind of lookup of domain to socket - {SockIp, SockPort} = Addr, - (catch udp_send(Sock, SockIp, SockPort, Packet)) + (catch udp_send(Sock, To, Packet)) end. -udp_send(UdpId, AgentIp, UdpPort, B) -> - case (catch gen_udp:send(UdpId, AgentIp, UdpPort, B)) of +udp_send(UdpId, To, B) -> + %% XXX should be some kind of lookup of domain to socket + {Ip, Port} = + case To of + {Domain, Addr} when is_atom(Domain) -> + Addr; + {_, P} = Addr when is_integer(P) -> + Addr + end, + case (catch gen_udp:send(UdpId, Ip, Port, B)) of {error, emsgsize} -> %% From this message we cannot recover, so exit sending loop throw({emsgsize, sz(B)}); {error, ErrorReason} -> error_msg("[error] cannot send message " "(destination: ~p:~p, size: ~p, reason: ~p)", - [AgentIp, UdpPort, sz(B), ErrorReason]); + [Ip, Port, sz(B), ErrorReason]); {'EXIT', ExitReason} -> error_msg("[exit] cannot send message " "(destination: ~p:~p, size: ~p, reason: ~p)", - [AgentIp, UdpPort, sz(B), ExitReason]); + [Ip, Port, sz(B), ExitReason]); _ -> ok end. @@ -1275,7 +1257,7 @@ get_counters([Counter|Counters], Acc) -> ip_opt_bind_to_ip_address(Opts, Ip) -> case get_bind_to_ip_address(Opts) of true -> - [{ip, list_to_tuple(Ip)}]; + [{ip, Ip}]; _ -> [] end. diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 0cad61e5c8..bf1a025457 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -42,7 +42,7 @@ check_domain/1, all_tdomains/0, check_tdomain/1, - mk_tdomain/1, + mk_tdomain/0, mk_tdomain/1, tdomain_to_family/1, which_domain/1, check_ip/1, check_ip/2, @@ -50,7 +50,7 @@ ip_port_to_domaddr/2, check_address/2, check_address/3, check_taddress/2, - mk_taddress/2, + mk_taddress/1, mk_taddress/2, check_packet_size/1, @@ -462,6 +462,9 @@ check_tdomain(TDomain) -> %% --------- +mk_tdomain() -> + mk_tdomain(snmpUDPDomain). + mk_tdomain(snmpUDPDomain) -> mk_tdomain(transportDomainUdpIpv4); mk_tdomain(transportDomainUdpIpv4) -> @@ -598,14 +601,14 @@ check_domain(Domain) -> %% --------- +mk_taddress(Address) -> + mk_taddress(snmpUDPDomain, Address). + %% The values of Domain, Ip and Port has both been checked at this %% point, so we dont need to do that again, but this function is %% also used on incoming packets from net_if so a little %% check that net_if does not supply bad arguments is in order. %% -mk_taddress(snmpUDPDomain, Address) -> % Legacy - mk_taddress(transportDomainUdpIpv4, Address); -%% %% These are just for convenience mk_taddress(?snmpUDPDomain, Address) -> mk_taddress(snmpUDPDomain, Address); @@ -614,6 +617,8 @@ mk_taddress(?transportDomainUdpIpv4, Address) -> mk_taddress(?transportDomainUdpIpv6, Address) -> mk_taddress(transportDomainUdpIpv6, Address); %% +mk_taddress(snmpUDPDomain, Address) -> % Legacy + mk_taddress(transportDomainUdpIpv4, Address); mk_taddress(transportDomainUdpIpv4 = Domain, Address) -> case Address of [] -> % Empty mask diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 7e52d68fa1..6d0f14237e 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -1588,7 +1588,7 @@ write_agent_snmp_files( is_list(SysName) -> write_agent_snmp_files( Dir, Vsns, Domain, ManagerAddr, AgentAddr, SysName, - "trap", none, "", "agentEngine", 484). + trap, none, "", "agentEngine", 484). %%---------------------------------------------------------------------- %% Dir: string() (ex: "../conf/") @@ -1607,7 +1607,7 @@ write_agent_snmp_files( is_list(SysName) -> write_agent_snmp_files( Dir, Vsns, ManagerIP, TrapUDP, AgentIP, AgentUDP, SysName, - "trap", none, "", "agentEngine", 484). + trap, none, "", "agentEngine", 484). %% %% ----- Agent config files generator functions ----- diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index ae28df37fa..b3596909cd 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. 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 @@ -23,7 +23,7 @@ -export([ create/4, create/5, create/6, open/1, open/2, change_size/2, close/1, sync/1, info/1, - log/4, + log/3, log/4, log_to_txt/6, log_to_txt/7, log_to_txt/8, log_to_io/5, log_to_io/6, log_to_io/7 ]). @@ -344,12 +344,20 @@ validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) -> %% log(Log, Packet, Addr, Port) %%----------------------------------------------------------------- -log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Addr, Port) -> +log(#snmp_log{id = Log, seqno = SeqNo}, Packet, AddrStr) -> + ?vtrace( + "log -> entry with~n" + " Log: ~p~n" + " AddrStr: ~s", [Log, AddrStr]), + Entry = make_entry(SeqNo, Packet, AddrStr), + disk_log:alog(Log, Entry). + +log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Ip, Port) -> ?vtrace("log -> entry with" "~n Log: ~p" - "~n Addr: ~p" - "~n Port: ~p", [Log, Addr, Port]), - Entry = make_entry(SeqNo, Packet, Addr, Port), + "~n Ip: ~p" + "~n Port: ~p", [Log, Ip, Port]), + Entry = make_entry(SeqNo, Packet, Ip, Port), %% io:format("log -> " %% "~n Entry: ~p" %% "~n Info: ~p" @@ -361,18 +369,35 @@ log(#snmp_log{id = Log, seqno = SeqNo}, Packet, Addr, Port) -> %% "~n", [Res, disk_log:info(Log)]), %% disk_log:sync(Log), Res. - -make_entry(SeqNoGen, Packet, Addr, Port) -> + +make_entry(SeqNoGen, Packet, AddrStr) + when is_integer(Packet); + is_tuple(AddrStr) -> + erlang:error(badarg, [SeqNoGen, Packet, AddrStr]); +make_entry(SeqNoGen, Packet, AddrStr) -> + try next_seqno(SeqNoGen) of + disabled -> + {timestamp(), Packet, AddrStr}; + {ok, NextSeqNo} when is_integer(NextSeqNo) -> + {timestamp(), NextSeqNo, Packet, AddrStr} + catch + _:_ -> + {timestamp(), Packet, AddrStr} + end. + +make_entry(SeqNoGen, Packet, Ip, Port) when is_integer(Packet) -> + erlang:error(badarg, [SeqNoGen, Packet, Ip, Port]); +make_entry(SeqNoGen, Packet, Ip, Port) -> try next_seqno(SeqNoGen) of disabled -> - {timestamp(), Packet, Addr, Port}; - {ok, NextSeqNo} -> - {timestamp(), NextSeqNo, Packet, Addr, Port} + {timestamp(), Packet, Ip, Port}; + {ok, NextSeqNo} when is_integer(NextSeqNo) -> + {timestamp(), NextSeqNo, Packet, Ip, Port} catch _:_ -> - {timestamp(), Packet, Addr, Port} + {timestamp(), Packet, Ip, Port} end. next_seqno({M, F, A}) -> @@ -674,60 +699,68 @@ format_msg(Entry, Mib, Start, Stop) -> end. %% This is an old-style entry, that never had the sequence-number -do_format_msg({Timestamp, Packet, {Addr, Port}}, Mib) -> - do_format_msg(Timestamp, Packet, Addr, Port, Mib); +do_format_msg({Timestamp, Packet, {Ip, Port}}, Mib) -> + do_format_msg(Timestamp, Packet, ipPort2Str(Ip, Port), Mib); +%% This is the format without sequence-number +do_format_msg({Timestamp, Packet, AddrStr}, Mib) -> + do_format_msg(Timestamp, Packet, AddrStr, Mib); +%% This is the format with sequence-number +do_format_msg({Timestamp, SeqNo, Packet, AddrStr}, Mib) + when is_integer(SeqNo) -> + do_format_msg(Timestamp, Packet, AddrStr, Mib); %% This is the format without sequence-number -do_format_msg({Timestamp, Packet, Addr, Port}, Mib) -> - do_format_msg(Timestamp, Packet, Addr, Port, Mib); +do_format_msg({Timestamp, Packet, Ip, Port}, Mib) -> + do_format_msg(Timestamp, Packet, ipPort2Str(Ip, Port), Mib); %% This is the format with sequence-number -do_format_msg({Timestamp, SeqNo, Packet, Addr, Port}, Mib) -> - do_format_msg(Timestamp, SeqNo, Packet, Addr, Port, Mib); +do_format_msg({Timestamp, SeqNo, Packet, Ip, Port}, Mib) -> + do_format_msg(Timestamp, SeqNo, Packet, ipPort2Str(Ip, Port), Mib); %% This is crap... do_format_msg(_, _) -> format_tab("** unknown entry in log file\n\n", []). -do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port, Mib) -> +do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, AddrStr, Mib) -> case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of ScopedPDU when is_record(ScopedPDU, scopedPdu) -> Msg = #message{version = 'version-3', vsn_hdr = V3Hdr, data = ScopedPDU}, - f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib); + f(ts2str(TimeStamp), "", Msg, AddrStr, Mib); {'EXIT', Reason} -> - format_tab("** error in log file at ~s from ~p:~w ~p\n\n", - [ts2str(TimeStamp), ip(Addr), Port, Reason]) + format_tab( + "** error in log file at ~s from ~s ~p\n\n", + [ts2str(TimeStamp), AddrStr, Reason]) end; -do_format_msg(TimeStamp, Packet, Addr, Port, Mib) -> +do_format_msg(TimeStamp, Packet, AddrStr, Mib) -> case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of Msg when is_record(Msg, message) -> - f(ts2str(TimeStamp), "", Msg, Addr, Port, Mib); + f(ts2str(TimeStamp), "", Msg, AddrStr, Mib); {'EXIT', Reason} -> format_tab("** error in log file ~p\n\n", [Reason]) end. -do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, Addr, Port, Mib) -> +do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, AddrStr, Mib) -> case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of ScopedPDU when is_record(ScopedPDU, scopedPdu) -> Msg = #message{version = 'version-3', vsn_hdr = V3Hdr, data = ScopedPDU}, - f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib); + f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib); {'EXIT', Reason} -> - format_tab("** error in log file at ~s from ~p:~w ~p\n\n", - [ts2str(TimeStamp), sn2str(SeqNo), - ip(Addr), Port, Reason]) + format_tab( + "** error in log file at ~s from ~s ~p\n\n", + [ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason]) end; -do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) -> +do_format_msg(TimeStamp, SeqNo, Packet, AddrStr, Mib) -> case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of Msg when is_record(Msg, message) -> - f(ts2str(TimeStamp), sn2str(SeqNo), Msg, Addr, Port, Mib); + f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib); {'EXIT', Reason} -> - format_tab("** error in log file ~s from ~p:~w ~p\n\n", - [ts2str(TimeStamp), sn2str(SeqNo), - ip(Addr), Port, Reason]) + format_tab( + "** error in log file ~s from ~s ~p\n\n", + [ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason]) end. @@ -771,44 +804,70 @@ do_format_msg(TimeStamp, SeqNo, Packet, Addr, Port, Mib) -> f(TimeStamp, SeqNo, #message{version = Vsn, vsn_hdr = VsnHdr, data = Data}, - Addr, Port, Mib) -> + AddrStr, Mib) -> Str = format_pdu(Data, Mib), HdrStr = format_header(Vsn, VsnHdr), - case get_type(Data) of - trappdu -> - f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); - 'snmpv2-trap' -> - f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); - 'inform-request' -> - f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); - 'get-response' -> - f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); - report -> - f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); - _ -> - f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) - end. + Class = + case get_type(Data) of + trappdu -> + trap; + 'snmpv2-trap' -> + trap; + 'inform-request' -> + inform; + 'get-response' -> + response; + report -> + report; + _ -> + request + end, + format_tab( + "~w ~s - ~s [~s]~s ~w\n~s", + [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]). + +%% f(TimeStamp, SeqNo, +%% #message{version = Vsn, vsn_hdr = VsnHdr, data = Data}, +%% Addr, Port, Mib) -> +%% Str = format_pdu(Data, Mib), +%% HdrStr = format_header(Vsn, VsnHdr), +%% case get_type(Data) of +%% trappdu -> +%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); +%% 'snmpv2-trap' -> +%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); +%% 'inform-request' -> +%% f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); +%% 'get-response' -> +%% f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); +%% report -> +%% f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); +%% _ -> +%% f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) +%% end. -f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> - format_tab("request ~s:~w - ~s [~s]~s ~w\n~s", - [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +%% f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> +%% format_tab("request ~s:~w - ~s [~s]~s ~w\n~s", +%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). -f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> - format_tab("response ~s:~w - ~s [~s]~s ~w\n~s", - [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +%% f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> +%% format_tab("response ~s:~w - ~s [~s]~s ~w\n~s", +%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). -f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> - format_tab("report ~s:~w - ~s [~s]~s ~w\n~s", - [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +%% f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> +%% format_tab("report ~s:~w - ~s [~s]~s ~w\n~s", +%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). -f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> - format_tab("trap ~s:~w - ~s [~s]~s ~w\n~s", - [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> +%% format_tab("trap ~s:~w - ~s [~s]~s ~w\n~s", +%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). -f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> - format_tab("inform ~s:~w - ~s [~s]~s ~w\n~s", - [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +%% f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> +%% format_tab("inform ~s:~w - ~s [~s]~s ~w\n~s", +%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +ipPort2Str(Ip, Port) -> + io_lib:format("~s:~w", [ip(Ip), Port]). %% Convert a timestamp 2-tupple to a printable string %% diff --git a/lib/snmp/test/snmp_conf_test.erl b/lib/snmp/test/snmp_conf_test.erl index 5c8acb48a5..7f5d11c0e7 100644 --- a/lib/snmp/test/snmp_conf_test.erl +++ b/lib/snmp/test/snmp_conf_test.erl @@ -373,6 +373,8 @@ verify_ip(Val) -> case (catch snmp_conf:check_ip(Val)) of {error, Reason} -> ?FAIL({verify_ip, Val, Reason}); + {ok, _} -> + ok; ok -> ok end. -- cgit v1.2.3 From c1104d6708917d7ec0b3b77340242b679ee10122 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 16 May 2014 15:11:05 +0200 Subject: wip: Testcase feedback --- lib/snmp/src/agent/snmp_framework_mib.erl | 2 ++ lib/snmp/src/agent/snmp_generic.erl | 30 ++++++++++++++++++++++++++---- lib/snmp/src/agent/snmpa_local_db.erl | 6 +++++- lib/snmp/src/misc/snmp_conf.erl | 2 ++ 4 files changed, 35 insertions(+), 5 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index fb52f90852..6589ace949 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -227,6 +227,8 @@ order_agent({Name, _}, {Name, _}) -> true; %% Less than or equal order_agent({_, _}, {intAgentTransportDomain, _}) -> false; %% Greater than +order_agent({intAgentTransportDomain, _}, {_, _}) -> + true; %% Less than or equal order_agent({A, _}, {B, _}) -> A =< B. diff --git a/lib/snmp/src/agent/snmp_generic.erl b/lib/snmp/src/agent/snmp_generic.erl index 06afa68d96..3195ca2500 100644 --- a/lib/snmp/src/agent/snmp_generic.erl +++ b/lib/snmp/src/agent/snmp_generic.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -414,7 +414,12 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndGo', RowIndex, Cols) -> % side effect free and we only use the result temporary. case catch snmpa_local_db:table_construct_row( NameDb, RowIndex, ?'RowStatus_createAndGo', Cols) of - {'EXIT', _} -> + {'EXIT', _Reason} -> + ?vtrace( + "failed construct row (createAndGo): " + " n Reason: ~p" + " n Stack: ~p", + [_Reason, erlang:get_stacktrace()]), {noCreation, Col}; % Bad RowIndex Row -> case lists:member(noinit, tuple_to_list(Row)) of @@ -431,7 +436,12 @@ table_check_status(NameDb, Col, ?'RowStatus_createAndWait', RowIndex, Cols) -> false -> case catch snmpa_local_db:table_construct_row( NameDb, RowIndex, ?'RowStatus_createAndGo', Cols) of - {'EXIT', _} -> + {'EXIT', _Reason} -> + ?vtrace( + "failed construct row (createAndWait): " + " n Reason: ~p" + " n Stack: ~p", + [_Reason, erlang:get_stacktrace()]), {noCreation, Col}; % Bad RowIndex _Row -> {noError, 0} @@ -711,7 +721,19 @@ find_col(Col, [_H | T]) -> find_col(Col, T). try_apply(nofunc, _) -> {noError, 0}; -try_apply(F, Args) -> apply(F, Args). +try_apply(F, Args) -> maybe_verbose_apply(F, Args). + +maybe_verbose_apply(M, Args) -> + case get(verbosity) of + false -> + apply(M, Args); + _ -> + ?vlog("~n apply: ~w,~p~n", [M,Args]), + Res = apply(M,Args), + ?vlog("~n returned: ~p", [Res]), + Res + end. + table_info({Name, _Db}) -> case snmpa_symbolic_store:table_info(Name) of diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl index f991244287..292c370d51 100644 --- a/lib/snmp/src/agent/snmpa_local_db.erl +++ b/lib/snmp/src/agent/snmpa_local_db.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2013. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -1011,6 +1011,10 @@ table_construct_row(Name, RowIndex, Status, Cols) -> defvals = Defs, status_col = StatusCol, first_own_index = FirstOwnIndex, not_accessible = NoAccs} = snmp_generic:table_info(Name), + ?vtrace( + "table_construct_row Indexes: ~p~n" + " RowIndex: ~p", + [Indexes, RowIndex]), Keys = snmp_generic:split_index_to_keys(Indexes, RowIndex), OwnKeys = snmp_generic:get_own_indexes(FirstOwnIndex, Keys), Row = OwnKeys ++ snmp_generic:table_create_rest(length(OwnKeys) + 1, diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index bf1a025457..594cfce705 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -191,6 +191,8 @@ read_fd(File, Order, Check, Fd, StartLine, Res) -> Order(RowA, RowB) end, lists:reverse(Res)), + ?vtrace("read_fd to read_check ->~n" + " Lines: ~p", [Lines]), read_check(File, Check, Lines, undefined, []) end. -- cgit v1.2.3 From cc1ab998ce905cd673c7ea14ee4e31ddb2412350 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 20 May 2014 15:15:43 +0200 Subject: Don't encode IPv6 address into v1 trap and fix legacy arguments to snmpa_network_interface_filter functions --- lib/snmp/src/agent/snmpa_mpd.erl | 18 +++++++- lib/snmp/src/agent/snmpa_net_if.erl | 48 ++++++++++++-------- lib/snmp/src/agent/snmpa_trap.erl | 87 +++++++++++++++++++++++++++++-------- lib/snmp/src/misc/snmp_conf.erl | 13 ++++-- lib/snmp/src/misc/snmp_pdus.erl | 13 +----- 5 files changed, 126 insertions(+), 53 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index dbd57b732c..642b1f7fc5 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -1103,8 +1103,22 @@ transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) -> {ok, {Domain, Address}}; transform_taddr(?transportDomainUdpIpv4, BadAddr) -> {error, {bad_transportDomainUdpIpv4_address, BadAddr}}; -transform_taddr(?transportDomainUdpIpv6, - [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> +transform_taddr( + ?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, + P1, P2]) -> + Domain = transportDomainUdpIpv6, + Addr = + {(A1 bsl 8) bor A2, (A3 bsl 8) bor A4, + (A5 bsl 8) bor A6, (A7 bsl 8) bor A8, + (A9 bsl 8) bor A10, (A11 bsl 8) bor A12, + (A13 bsl 8) bor A14, (A15 bsl 8) bor A16}, + Port = P1 bsl 8 + P2, + Address = {Addr, Port}, + {ok, {Domain, Address}}; +transform_taddr( + ?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> Domain = transportDomainUdpIpv6, Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, Port = P1 bsl 8 + P2, diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 42e93bff65..2c800db8b6 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -327,13 +327,7 @@ loop(#state{domain = Domain} = S) -> receive {udp, _UdpId, Ip, Port, Packet} -> ?vlog("got paket from ~w:~w",[Ip,Port]), - From = - case Domain of - snmpUDPDomain -> - {Ip, Port}; - _ -> - {Domain, {Ip, Port}} - end, + From = fix_filter_address(Domain, {Domain, {Ip, Port}}), NewS = maybe_handle_recv(S, From, Packet), loop(NewS); @@ -604,7 +598,7 @@ handle_discovery_response(_From, #pdu{request_id = ReqId} = Pdu, %% Ouch, timeout? resend? S end. - + handle_recv( #state{usock = Sock, mpd_state = MpdState, @@ -655,7 +649,7 @@ handle_recv( active_once(Sock), S end. - + maybe_handle_recv_pdu( From, Vsn, #pdu{type = Type} = Pdu, PduMS, ACMData, @@ -713,12 +707,13 @@ handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, maybe_handle_reply_pdu( - #state{filter = FilterMod} = S, Vsn, + #state{filter = FilterMod, domain = Domain} = S, Vsn, #pdu{request_id = Rid} = Pdu, Type, ACMData, To) -> S1 = update_req_counter_outgoing(S, Rid), - Addresses = [To], + %% Addresses = [To], + Addresses = [fix_filter_address(Domain, To)], case try FilterMod:accept_send_pdu(Addresses, Type) @@ -965,9 +960,10 @@ handle_response(Vsn, Pdu, From, S) -> end. maybe_udp_send( - #state{usock = Sock, filter = FilterMod}, + #state{usock = Sock, filter = FilterMod, domain = Domain}, To, Packet) -> - {To_1, To_2} = To, + %% {To_1, To_2} = To, + {To_1, To_2} = fix_filter_address(Domain, To), case try FilterMod:accept_send(To_1, To_2) catch @@ -995,11 +991,14 @@ maybe_udp_send( end. maybe_udp_send( - #state{log = Log, - usock = Sock, - filter = FilterMod}, + #state{ + log = Log, + usock = Sock, + filter = FilterMod, + domain = Domain}, To, Packet, Type, _LogData) -> - {To_1, To_2} = To, + %% {To_1, To_2} = To, + {To_1, To_2} = fix_filter_address(Domain, To), case try FilterMod:accept_send(To_1, To_2) catch @@ -1098,6 +1097,21 @@ active_once(Sock) -> inet:setopts(Sock, [{active, once}]). +%% If the agent uses legacy snmpUDPDomain e.g has not set +%% intAgentTransportDomain, then make sure +%% snmpa_network_interface_filter gets legacy arguments +%% to not break backwards compatibility. +%% +fix_filter_address(snmpUDPDomain, {Domain, Addr}) + when Domain =:= snmpUDPDomain; + Domain =:= transportDomainUdpIpv4 -> + Addr; +fix_filter_address(snmpUDPDomain, {_, Port} = Addr) + when is_integer(Port) -> + Addr; +fix_filter_address(_AgentDomain, Address) -> + Address. + %%%----------------------------------------------------------------- handle_set_log_type(#state{log = {Log, OldValue}} = State, NewType) diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index a2d821c099..ac0739860b 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -270,12 +270,13 @@ localise_type({VariableOid, Value}, Mib) when is_list(VariableOid) -> localise_type(X, _) -> X. %%----------------------------------------------------------------- -%% Func: make_v1_trap_pdu/4 +%% Func: make_v1_trap_pdu/5 %% Args: Enterprise = oid() %% Specific = integer() %% Varbinds is as returned from initiate_vars %% (but only {Oid, Type[, Value} permitted) %% SysUpTime = integer() +%% AgentIp = {A, B, C, D} %% Purpose: Make a #trappdu %% Checks the Varbinds to see that no symbolic names are %% present, and that each var has a type. Performs a get @@ -284,7 +285,7 @@ localise_type(X, _) -> X. %% Fails: yes %% NOTE: Executed at the MA %%----------------------------------------------------------------- -make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) -> +make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime, AgentIp) -> {Enterp,Generic,Spec} = case Enterprise of ?snmp -> @@ -292,7 +293,6 @@ make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) -> _ -> {Enterprise,?enterpriseSpecific,Specific} end, - {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), #trappdu{enterprise = Enterp, agent_addr = AgentIp, generic_trap = Generic, @@ -369,6 +369,7 @@ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, {tag, T}, {err, E}, {stacktrace, erlang:get_stacktrace()}], + ?vlog("snmpa_trap:send_trap exception: ~p", [Info]), {error, {failed_sending_trap, Info}} end. @@ -797,13 +798,32 @@ send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec}, "~n ~p" "~n to" "~n ~p", [Enter, Spec, V1Res]), - TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime), - AddrCommunities = mk_addr_communities(V1Res), - lists:foreach(fun({Community, Addrs}) -> - ?vtrace("send v1 trap pdu to ~p",[Addrs]), - NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs, ExtraInfo} - end, AddrCommunities); + AgentDomain = + case snmp_framework_mib:intAgentTransportDomain(get) of + {value, AD} -> + AD; + genErr -> + snmp_target_mib:default_domain() + end, + case AgentDomain of + snmpUDPDomain -> + {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), + TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime, AgentIp), + AddrCommunities = mk_addr_communities(V1Res), + lists:foreach( + fun ({Community, Addrs}) -> + ?vtrace("send v1 trap pdu to ~p",[Addrs]), + NetIf ! {send_pdu, 'version-1', TrapPdu, + {community, Community}, Addrs, ExtraInfo} + end, AddrCommunities); + _ -> + ?vtrace( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]), + user_err( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]) + end; send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) -> %% Use alg. in rfc2089 to map a v2 trap to a v1 trap @@ -822,14 +842,33 @@ send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, {lists:reverse(First),Last} end end, - TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime), - AddrCommunities = mk_addr_communities(V1Res), - lists:foreach(fun({Community, Addrs}) -> - ?vtrace("send v1 trap to ~p",[Addrs]), - NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs, ExtraInfo} - end, AddrCommunities). - + AgentDomain = + case snmp_framework_mib:intAgentTransportDomain(get) of + {value, AD} -> + AD; + genErr -> + snmp_target_mib:default_domain() + end, + case AgentDomain of + snmpUDPDomain -> + {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), + TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp), + AddrCommunities = mk_addr_communities(V1Res), + lists:foreach( + fun ({Community, Addrs}) -> + ?vtrace("send v1 trap to ~p",[Addrs]), + NetIf ! {send_pdu, 'version-1', TrapPdu, + {community, Community}, Addrs, ExtraInfo} + end, AddrCommunities); + _ -> + ?vtrace( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]), + user_err( + "snmpa_trap: can not send v1 trap with domain: ~w", + [AgentDomain]) + end. + send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) -> ok; send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime) -> @@ -1116,9 +1155,19 @@ transform_taddr( [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> Ip = {A1, A2, A3, A4, A5, A6, A7, A8}, Port = P1 bsl 8 + P2, + {Domain, {Ip, Port}}; +transform_taddr( + transportDomainUdpIpv6 = Domain, + [A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, + P1, P2]) -> + Ip = + {(A1 bsl 8) bor A2, (A3 bsl 8) bor A4, + (A5 bsl 8) bor A6, (A7 bsl 8) bor A8, + (A9 bsl 8) bor A10, (A11 bsl 8) bor A12, + (A13 bsl 8) bor A14, (A15 bsl 8) bor A16}, + Port = P1 bsl 8 + P2, {Domain, {Ip, Port}}. - %% transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2 %% Addr = {A1, A2, A3, A4}, %% Port = P1 bsl 8 + P2, diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 594cfce705..2d91cb1f55 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -634,9 +634,16 @@ mk_taddress(transportDomainUdpIpv6 = Domain, Address) -> case Address of [] -> % Empty mask []; - {Ip, Port} - when tuple_size(Ip) =:= 8, is_integer(Port) -> - tuple_to_list(Ip) ++ mk_bytes(Port); + {{A, B, C, D, E, F, G, H}, Port} -> + [A bsr 8, A band 255, + B bsr 8, B band 255, + C bsr 8, C band 255, + D bsr 8, D band 255, + E bsr 8, E band 255, + F bsr 8, F band 255, + G bsr 8, G band 255, + H bsr 8, H band 255, + Port bsr 8, Port band 255]; _ -> erlang:error(badarg, [Domain,Address]) end; diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl index a780fee7a3..90fa4c0dea 100644 --- a/lib/snmp/src/misc/snmp_pdus.erl +++ b/lib/snmp/src/misc/snmp_pdus.erl @@ -174,7 +174,7 @@ dec_pdu_tag(168) -> dec_pdu([164 | Bytes]) -> % It's a trap Bytes2 = get_data_bytes(Bytes), {Enterprise, Rest1} = dec_oid_tag(Bytes2), - {{'IpAddress', AgentAddr}, Rest2} = dec_value(Rest1), + {{'IpAddress', [_, _, _, _] = AgentAddr}, Rest2} = dec_value(Rest1), {GenericTrap, Rest3} = dec_int_tag(Rest2), {SpecificTrap, Rest4} = dec_int_tag(Rest3), {{'TimeTicks', TimeStamp}, VBBytes} = dec_value(Rest4), @@ -666,17 +666,6 @@ enc_value('OBJECT IDENTIFIER', Val) -> enc_oid_tag(Val); enc_value('IpAddress', {A, B, C, D}) -> enc_value('IpAddress', [A,B,C,D]); -enc_value('IpAddress', {A, B, C, D, E, F, G, H}) -> - enc_value( - 'IpAddress', - [A bsr 8, A band 255, - B bsr 8, B band 255, - C bsr 8, C band 255, - D bsr 8, D band 255, - E bsr 8, E band 255, - F bsr 8, F band 255, - G bsr 8, G band 255, - H bsr 8, H band 255]); enc_value('IpAddress', Val) when is_list(Val) -> Bytes2 = enc_oct_str_notag(Val), Len2 = elength(length(Bytes2)), -- cgit v1.2.3 From e3f49c557c2cf0f4e98bbe538af4142167bac6ad Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 21 May 2014 14:33:50 +0200 Subject: Rewrite string representation of addresses and stop printing an error report when snmpa_net_if gets externally killed --- lib/snmp/src/agent/snmp_target_mib.erl | 31 ++--- lib/snmp/src/agent/snmpa_net_if.erl | 34 +++--- lib/snmp/src/misc/snmp_conf.erl | 199 ++++++++++++++++----------------- lib/snmp/src/misc/snmp_config.erl | 23 ++-- lib/snmp/src/misc/snmp_log.erl | 9 +- 5 files changed, 150 insertions(+), 146 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 3bcfd469e6..932829e150 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -679,6 +679,20 @@ snmpTargetAddrTable(print) -> FOI = foi(Table), PrintRow = fun(Prefix, Row) -> + TDomain = element(?snmpTargetAddrTDomain, Row), + Domain = + try snmp_conf:tdomain_to_domain(TDomain) + catch + {error, {bad_tdomain, _}} -> + undefined + end, + TAddress = element(?snmpTargetAddrTAddress, Row), + AddrString = + try snmp_conf:mk_addr_string({Domain, TAddress}) + catch + {error, {bad_address, _}} -> + "-" + end, lists:flatten( io_lib:format("~sName: ~p" "~n~sTDomain: ~p (~w)" @@ -693,21 +707,8 @@ snmpTargetAddrTable(print) -> "~n~s[Ext] TMask: ~p" "~n~s[Ext] MMS: ~p", [Prefix, element(?snmpTargetAddrName, Row), - Prefix, element(?snmpTargetAddrTDomain, Row), - case element(?snmpTargetAddrTDomain, Row) of - ?snmpUDPDomain -> snmpUDPDomain; - ?transportDomainUdpIpv4 -> transportDomainUdpIpv4; - ?transportDomainUdpIpv6 -> transportDomainUdpIpv6; - _ -> undefined - end, - Prefix, element(?snmpTargetAddrTAddress, Row), - case element(?snmpTargetAddrTAddress, Row) of - [A,B,C,D,U1,U2] -> - lists:flatten( - io_lib:format("~w.~w.~w.~w:~w", - [A, B, C, D, U1 bsl 8 + U2])); - _ -> "-" - end, + Prefix, TDomain, Domain, + Prefix, TAddress, AddrString, Prefix, element(?snmpTargetAddrTimeout, Row), Prefix, element(?snmpTargetAddrRetryCount, Row), Prefix, element(?snmpTargetAddrTagList, Row), diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 2c800db8b6..71bb9cad2e 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -142,9 +142,16 @@ init(Prio, NoteStore, MasterAgent, Parent, Opts) -> try loop(State) catch C:E -> S = erlang:get_stacktrace(), - error_msg( - "loop/1 EXCEPTION ~w:~w~n" - " ~p", [C,E,S]), + Fmt = + "loop/1 EXCEPTION ~w:~w~n" + " ~p", + case C of + exit -> + %% Externally killed, root cause is elsewhere + info_msg(Fmt, [C, E, S]); + _ -> + error_msg(Fmt, [C, E, S]) + end, erlang:raise(C, E, S) end; {error, Reason} -> @@ -287,20 +294,9 @@ log({Log, Types}, _, Packet, Address) -> false -> ok end. -%% log(_, _, _, _, _) -> -%% ok. - -format_address({snmpUDPDomain, {_Ip, Port} = Addr}) when is_integer(Port) -> - format_address(Addr); -format_address({transportDomainUdpIpv4, {Ip, Port}}) -> - format_address("udpIpv4/~s:~w", [inet:ntoa(Ip), Port]); -format_address({transportDomainUdpIpv6, {Ip, Port}}) -> - format_address("udpIpv6/[~s]:~w", [inet:ntoa(Ip), Port]); -format_address({Ip, Port}) when is_integer(Port) -> - format_address("~s:~w", [inet:ntoa(Ip), Port]). -format_address(Format, Args) -> - iolist_to_binary(io_lib:format(Format, Args)). +format_address(Address) -> + iolist_to_binary(snmp_conf:mk_addr_string(Address)). @@ -712,7 +708,6 @@ maybe_handle_reply_pdu( Type, ACMData, To) -> S1 = update_req_counter_outgoing(S, Rid), - %% Addresses = [To], Addresses = [fix_filter_address(Domain, To)], case try @@ -962,7 +957,6 @@ handle_response(Vsn, Pdu, From, S) -> maybe_udp_send( #state{usock = Sock, filter = FilterMod, domain = Domain}, To, Packet) -> - %% {To_1, To_2} = To, {To_1, To_2} = fix_filter_address(Domain, To), case try FilterMod:accept_send(To_1, To_2) @@ -997,7 +991,6 @@ maybe_udp_send( filter = FilterMod, domain = Domain}, To, Packet, Type, _LogData) -> - %% {To_1, To_2} = To, {To_1, To_2} = fix_filter_address(Domain, To), case try FilterMod:accept_send(To_1, To_2) @@ -1358,6 +1351,9 @@ get_bind_to_ip_address(Opts) -> error_msg(F,A) -> ?snmpa_error("NET-IF server: " ++ F, A). +info_msg(F,A) -> + ?snmpa_info("NET-IF server: " ++ F, A). + %% --- user_err(F, A) -> diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 2d91cb1f55..eb71c55cf4 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -40,11 +40,13 @@ all_domains/0, check_domain/1, + domain_to_name/1, all_tdomains/0, check_tdomain/1, mk_tdomain/0, mk_tdomain/1, - tdomain_to_family/1, + tdomain_to_family/1, tdomain_to_domain/1, which_domain/1, + mk_addr_string/1, check_ip/1, check_ip/2, check_port/1, ip_port_to_domaddr/2, @@ -495,9 +497,17 @@ tdomain_to_family(BadDomain) -> %% --------- -%% XXX remove -%% check_taddress(X) -> -%% check_taddress(snmpUDPDomain, X). +tdomain_to_domain(?snmpUDPDomain) -> + snmpUDPDomain; +tdomain_to_domain(?transportDomainUdpIpv4) -> + transportDomainUdpIpv4; +tdomain_to_domain(?transportDomainUdpIpv6) -> + transportDomainUdpIpv6; +tdomain_to_domain(BadTDomain) -> + error({bad_tdomain, BadTDomain}). + + +%% --------- check_taddress(?snmpUDPDomain, X) -> check_taddress(transportDomainUdpIpv4, X); @@ -600,6 +610,42 @@ check_domain(Domain) -> error({unknown_domain, Domain}) end. +domain_to_name(snmpUDPDomain) -> + undefined; +domain_to_name(transportDomainUdpIpv4) -> + udpIpv4; +domain_to_name(transportDomainUdpIpv6) -> + udpIpv6; +domain_to_name(transportDomainUdpIpv4z) -> + udpIpv4z; +domain_to_name(transportDomainUdpIpv6z) -> + udpIpv6z; +domain_to_name(transportDomainTcpIpv4) -> + tcpIpv4; +domain_to_name(transportDomainTcpIpv6) -> + tcpIpv6; +domain_to_name(transportDomainTcpIpv4z) -> + tcpIpv4z; +domain_to_name(transportDomainTcpIpv6z) -> + tcpIpv6z; +domain_to_name(transportDomainSctpIpv4) -> + sctpIpv4; +domain_to_name(transportDomainSctpIpv6) -> + sctpIpv6; +domain_to_name(transportDomainSctpIpv4z) -> + sctpIpv4z; +domain_to_name(transportDomainSctpIpv6z) -> + sctpIpv6z; +domain_to_name(transportDomainLocal) -> + local; +domain_to_name(transportDomainUdpDns) -> + udpDns; +domain_to_name(transportDomainTcpDns) -> + tcpDns; +domain_to_name(transportDomainSctpDns) -> + sctpDns; +domain_to_name(BadDomain) -> + error({bad_domain, BadDomain}). %% --------- @@ -652,77 +698,6 @@ mk_taddress(BadDomain, _) -> error({bad_domain, BadDomain}). - -%% mk_taddress(snmpUDPDomain, Address) -> -%% mk_taddress(transportDomainUdpIpv4, Address); -%% %% mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_list(Ip) -> -%% %% Ip ++ mk_bytes(Port); -%% mk_taddress(transportDomainUdpIpv4, {Ip, Port}) -%% when tuple_size(Ip) =:= 4 -> -%% tuple_to_list(Ip) ++ mk_bytes(Port); -%% %% mk_taddress(transportDomainUdpIpv4, IpPort) when is_list(IpPort) -> -%% %% IpPort; % Should be length 6 -%% %% mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_list(Ip) -> -%% %% Ip ++ mk_bytes(Port); -%% mk_taddress(transportDomainUdpIpv6, {Ip, Port}) -%% when tuple_size(Ip) == 8 -> -%% tuple_to_list(Ip) ++ mk_bytes(Port); -%% %% mk_taddress(transportDomainUdpIpv6, IpPort) when is_list(IpPort) -> -%% %% case IpPort of -%% %% [A0,A1,A2,A3,A4,A5,A6,A7,P] -> -%% %% [A0,A1,A2,A3,A4,A5,A6,A7] ++ mk_bytes(P); -%% %% [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] -> -%% %% [mk_word(A0, A1),mk_word(A2, A3), -%% %% mk_word(A4, A5),mk_word(A6, A7), -%% %% mk_word(A8, A9),mk_word(A10, A11), -%% %% mk_word(A12, A13),mk_word(A14, A15),P0,P1]; -%% %% _ -> -%% %% IpPort % Should already be 8 words and 2 bytes hence length 10 -%% %% end; -%% mk_taddress(Domain, []) -> %% Used for empty mask -%% []; -%% mk_taddress(Domain, Address) -> -%% erlang:error(badarg, [Domain,Address]); -%% %% -%% %% These are just for convenience -%% mk_taddress(?snmpUDPDomain, Address) -> -%% mk_taddress(snmpUDPDomain, Address); -%% mk_taddress(?transportDomainUdpIpv4, Address) -> -%% mk_taddress(transportDomainUdpIpv4, Address); -%% mk_taddress(?transportDomainUdpIpv6, Address) -> -%% mk_taddress(transportDomainUdpIpv6, Address); -%% %% Bad domain -%% mk_taddress(BadDomain, _) -> -%% error({bad_domain, BadDomain}). - - - -%% %% XXX remove - -%% 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}). - - %% --------- %% XXX remove, when net_if handles one socket per transport domain @@ -747,10 +722,54 @@ which_domain({A0, A1, A2, A3, A4, A5, A6, A7}) %% --------- +mk_addr_string({_IP, Port} = Addr) when is_integer(Port) -> + mk_addr_string({snmpUDPDomain, Addr}); +mk_addr_string({Domain, Addr}) when is_atom(Domain) -> + %% XXX There is only code for IP domains here + case check_address_ip(Domain, Addr) of + false -> + case check_address_ip_port(Domain, Addr) of + false -> + error({bad_address, {Domain, Addr}}); + true -> + {IP, Port} = Addr, + mk_addr_string_ntoa(Domain, IP, Port); + {IP, Port} -> + mk_addr_string_ntoa(Domain, IP, Port) + end; + true -> + mk_addr_string_ntoa(Domain, Addr); + IP -> + mk_addr_string_ntoa(Domain, IP) + end. + + +mk_addr_string_ntoa({_, _, _, _} = IP) -> + inet:ntoa(IP); +mk_addr_string_ntoa(IP) -> + lists:flatten(io_lib:format("[~s]", [inet:ntoa(IP)])). + +mk_addr_string_ntoa(Domain, IP) -> + case domain_to_name(Domain) of + undefined -> + mk_addr_string_ntoa(IP); + Name -> + lists:flatten( + io_lib:format("~w://~s", [Name, mk_addr_string_ntoa(IP)])) + end. + +mk_addr_string_ntoa(Domain, IP, Port) -> + lists:flatten( + io_lib:format( + "~s:~w", [mk_addr_string_ntoa(Domain, IP), Port])). + +%% --------- + check_ip(X) -> check_ip(snmpUDPDomain, X). check_ip(Domain, IP) -> + %% XXX There is only code for IP domains here case check_address_ip(Domain, IP) of false -> error({bad_address, {Domain, IP}}); @@ -760,31 +779,6 @@ check_ip(Domain, IP) -> {ok, FixedIP} end. -%% check_ip(snmpUDPDomain, X) -> -%% check_ip(transportDomainUdpIpv4, X); -%% check_ip(transportDomainUdpIpv4 = Domain, X) -> -%% case X of -%% [A,B,C,D] when ?is_ipv4_addr(A, B, C, D) -> -%% ok; -%% _ -> -%% error({bad_address, {Domain, X}}) -%% end; -%% check_ip(transportDomainUdpIpv6 = Domain, X) -> -%% case X of -%% [A,B,C,D,E,F,G,H] -%% when ?is_ipv6_addr(A, B, C, D, E, F, G, H) -> -%% ok; -%% [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P] -%% when ?is_ipv6_addr( -%% A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) -> -%% ok; -%% _ -> -%% error({bad_address, {Domain, X}}) -%% end; -%% %% -%% check_ip(BadDomain, _X) -> -%% error({invalid_domain, BadDomain}). - %% --------- @@ -794,6 +788,7 @@ check_port(Port) -> error({bad_port, Port}). ip_port_to_domaddr(IP, Port) when ?is_word(Port) -> + %% XXX There is only code for IP domains here case check_address_ip(transportDomainUdpIpv4, IP) of false -> case check_address_ip(transportDomainUdpIpv6, IP) of @@ -818,6 +813,8 @@ ip_port_to_domaddr(IP, Port) -> check_address(Domain, Address, DefaultPort) -> %% If Address does not contain Port or contains Port =:= 0 %% create an address containing DefaultPort + %% + %% XXX There is only code for IP domains here case check_address_ip(Domain, Address) of false -> case check_address_ip_port(Domain, Address) of @@ -843,6 +840,8 @@ check_address(Domain, Address, DefaultPort) -> check_address(Domain, Address) -> %% Address has to contain Port + %% + %% XXX There is only code for IP domains here case check_address_ip_port(Domain, Address) of false -> error({bad_address, {Domain, Address}}); diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 6d0f14237e..ac2b7b7778 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -1825,18 +1825,23 @@ write_agent_snmp_target_addr_conf( "%%\n\n", Hdr = header() ++ Comment, F = fun(v1 = Vsn, Acc) -> - [{mk_name(Addr, Vsn), Domain, Addr, Timeout, RetryCount, + [{mk_name(Domain, Addr, Vsn), + Domain, Addr, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}| Acc]; (v2 = Vsn, Acc) -> - [{mk_name(Addr, Vsn), Domain, Addr, Timeout, RetryCount, + [{mk_name(Domain, Addr, Vsn), + Domain, Addr, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, - {lists:flatten(io_lib:format("~s.2",[mk_name(Addr, Vsn)])), + {lists:flatten( + io_lib:format("~s.2",[mk_name(Domain, Addr, Vsn)])), Domain, Addr, Timeout, RetryCount, "std_inform", mk_param(Vsn), "", [], 2048}| Acc]; (v3 = Vsn, Acc) -> - [{mk_name(Addr, Vsn), Domain, Addr, Timeout, RetryCount, + [{mk_name(Domain, Addr, Vsn), + Domain, Addr, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, - {lists:flatten(io_lib:format("~s.3",[mk_name(Addr, Vsn)])), + {lists:flatten( + io_lib:format("~s.3",[mk_name(Domain, Addr, Vsn)])), Domain, Addr, Timeout, RetryCount, "std_inform", mk_param(Vsn), "mgrEngine", [], 2048}| Acc] end, @@ -1852,10 +1857,10 @@ write_agent_snmp_target_addr_conf( mk_param(Vsn) -> lists:flatten(io_lib:format("target_~w", [Vsn])). -mk_name({[A,B,C,D], _}, Vsn) -> - lists:flatten(io_lib:format("~w.~w.~w.~w ~w", [A,B,C,D,Vsn])); -mk_name(Address, Vsn) -> - lists:flatten(io_lib:format("~w ~w", [Address,Vsn])). +mk_name(Domain, Addr, Vsn) -> + lists:flatten( + io_lib:format( + "~s ~w", [snmp_conf:mk_addr_string({Domain, Addr}), Vsn])). write_agent_target_addr_config(Dir, Hdr, Conf) -> snmpa_conf:write_target_addr_config(Dir, Hdr, Conf). diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index b3596909cd..a1fd392676 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -867,7 +867,8 @@ f(TimeStamp, SeqNo, %% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). ipPort2Str(Ip, Port) -> - io_lib:format("~s:~w", [ip(Ip), Port]). + snmp_conf:mk_addr_string({Ip, Port}). + %% io_lib:format("~s:~w", [ip(Ip), Port]). %% Convert a timestamp 2-tupple to a printable string %% @@ -968,8 +969,10 @@ get_type(#pdu{type = Type}) -> Type. -ip({A,B,C,D}) -> - io_lib:format("~w.~w.~w.~w", [A,B,C,D]). +ip(Domain, Addr) -> + snmp_conf:mk_addr_string(Domain, Addr). +%% ip({A,B,C,D}) -> +%% io_lib:format("~w.~w.~w.~w", [A,B,C,D]). -- cgit v1.2.3 From aa8f929cb3810b2c5ed67b44392d26131857f8e6 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 21 May 2014 14:37:26 +0200 Subject: Write IPv6 test cases --- lib/snmp/test/snmp_agent_test.erl | 180 ++++++++++++++++++++++++++++------ lib/snmp/test/snmp_agent_test_lib.erl | 51 +++++++--- 2 files changed, 188 insertions(+), 43 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index e4cac71fec..6b8d0802d0 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -522,9 +522,13 @@ groups() -> {mib_storage_varm_mnesia, [], varm_mib_storage_mnesia_cases()}, {misc, [], misc_cases()}, {test_v1, [], v1_cases()}, + {test_v1_ipv6, [], v1_cases_ipv6()}, {test_v2, [], v2_cases()}, + {test_v2_ipv6, [], v2_cases_ipv6()}, {test_v1_v2, [], v1_v2_cases()}, + {test_v1_v2_ipv6, [], v1_v2_cases()}, {test_v3, [], v3_cases()}, + {test_v3_ipv6, [], v3_cases_ipv6()}, {test_multi_threaded, [], mt_cases()}, {multiple_reqs, [], mul_cases()}, {multiple_reqs_2, [], mul_cases_2()}, @@ -616,6 +620,14 @@ init_per_group(test_v2 = GroupName, Config) -> init_v2(snmp_test_lib:init_group_top_dir(GroupName, Config)); init_per_group(test_v1 = GroupName, Config) -> init_v1(snmp_test_lib:init_group_top_dir(GroupName, Config)); +init_per_group(test_v1_ipv6 = GroupName, Config) -> + init_per_group_ipv6(GroupName, Config, fun init_v1/1); +init_per_group(test_v2_ipv6 = GroupName, Config) -> + init_per_group_ipv6(GroupName, Config, fun init_v2/1); +init_per_group(test_v1_v2_ipv6 = GroupName, Config) -> + init_per_group_ipv6(GroupName, Config, fun init_v1_v2/1); +init_per_group(test_v3_ipv6 = GroupName, Config) -> + init_per_group_ipv6(GroupName, Config, fun init_v3/1); init_per_group(misc = GroupName, Config) -> init_misc(snmp_test_lib:init_group_top_dir(GroupName, Config)); init_per_group(mib_storage_varm_mnesia = GroupName, Config) -> @@ -649,6 +661,16 @@ init_per_group(ipv6 = GroupName, Config) -> init_per_group(GroupName, Config) -> snmp_test_lib:init_group_top_dir(GroupName, Config). +init_per_group_ipv6(GroupName, Config, Init) -> + case ct:require(ipv6_hosts) of + ok -> + Init( + snmp_test_lib:init_group_top_dir( + GroupName, [{ipfamily, inet6}|Config])); + _ -> + {skip, "Host does not support IPV6"} + end. + end_per_group(all_tcs, Config) -> finish_all(Config); end_per_group(otp7157, Config) -> @@ -667,31 +689,39 @@ end_per_group(multiple_reqs_3, Config) -> finish_mul(Config); end_per_group(test_multi_threaded, Config) -> finish_mt(Config); -end_per_group(test_v3, Config) -> +end_per_group(test_v3_ipv6, Config) -> + finish_v3(Config); +end_per_group(test_v1_v2_ipv6, Config) -> + finish_v1_v2(Config); +end_per_group(test_v2_ipv6, Config) -> + finish_v2(Config); +end_per_group(test_v1_ipv6, Config) -> + finish_v1(Config); +end_per_group(test_v3, Config) -> finish_v3(Config); -end_per_group(test_v1_v2, Config) -> +end_per_group(test_v1_v2, Config) -> finish_v1_v2(Config); -end_per_group(test_v2, Config) -> +end_per_group(test_v2, Config) -> finish_v2(Config); -end_per_group(test_v1, Config) -> +end_per_group(test_v1, Config) -> finish_v1(Config); -end_per_group(misc, Config) -> +end_per_group(misc, Config) -> finish_misc(Config); -end_per_group(mib_storage_varm_mnesia, Config) -> +end_per_group(mib_storage_varm_mnesia, Config) -> finish_varm_mib_storage_mnesia(Config); -end_per_group(mib_storage_varm_dets, Config) -> +end_per_group(mib_storage_varm_dets, Config) -> finish_varm_mib_storage_dets(Config); -end_per_group(mib_storage_size_check_mnesia, Config) -> +end_per_group(mib_storage_size_check_mnesia, Config) -> finish_size_check_msm(Config); -end_per_group(mib_storage_size_check_dets, Config) -> +end_per_group(mib_storage_size_check_dets, Config) -> finish_size_check_msd(Config); -end_per_group(mib_storage_size_check_ets, Config) -> +end_per_group(mib_storage_size_check_ets, Config) -> finish_size_check_mse(Config); -end_per_group(mib_storage_mnesia, Config) -> +end_per_group(mib_storage_mnesia, Config) -> finish_mib_storage_mnesia(Config); -end_per_group(mib_storage_dets, Config) -> +end_per_group(mib_storage_dets, Config) -> finish_mib_storage_dets(Config); -end_per_group(mib_storage_ets, Config) -> +end_per_group(mib_storage_ets, Config) -> finish_mib_storage_ets(Config); end_per_group(_GroupName, Config) -> Config. @@ -832,6 +862,10 @@ cases() -> {group, test_v2}, {group, test_v1_v2}, {group, test_v3}, + {group, test_v1_ipv6}, + {group, test_v2_ipv6}, + {group, test_v1_v2_ipv6}, + {group, test_v3_ipv6}, {group, test_multi_threaded}, {group, mib_storage}, {group, tickets1}, @@ -1685,14 +1719,40 @@ v1_cases() -> change_target_addr_config ]. +v1_cases_ipv6() -> + [ + simple, + v1_processing, + loop_mib, +%% big, +%% big2, + api, + subagent, +%% mnesia, +%% {group, multiple_reqs}, + sa_register, + v1_trap, +%% sa_error, + next_across_sa, + undo, +%% {group, reported_bugs}, + {group, standard_mibs}, + sparse_table, + cnt_64, + opaque, + change_target_addr_config + ]. + init_v1(Config) when is_list(Config) -> ?line SaNode = ?config(snmp_sa, Config), ?line create_tables(SaNode), ?line AgentConfDir = ?config(agent_conf_dir, Config), ?line MgrDir = ?config(mgr_dir, Config), ?line Ip = ?config(ip, Config), - ?line config([v1], MgrDir, AgentConfDir, - tuple_to_list(Ip), tuple_to_list(Ip)), + ?line IpFamily = ?config(ipfamily, Config), + ?line config( + [v1], MgrDir, AgentConfDir, + tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), [{vsn, v1} | start_v1_agent(Config)]. finish_v1(Config) when is_list(Config) -> @@ -1729,14 +1789,43 @@ v2_cases() -> v2_caps ]. +v2_cases_ipv6() -> + [ + simple_2, + v2_processing, +%% big_2, +%% big2_2, + loop_mib_2, + api_2, + subagent_2, +%% mnesia_2, +%% {group, multiple_reqs_2}, + sa_register_2, + v2_trap, + {group, v2_inform}, +%% sa_error_2, + next_across_sa_2, + undo_2, +%% {group, reported_bugs_2}, + {group, standard_mibs_2}, + v2_types, + implied, + sparse_table_2, + cnt_64_2, + opaque_2, + v2_caps + ]. + init_v2(Config) when is_list(Config) -> SaNode = ?config(snmp_sa, Config), create_tables(SaNode), AgentConfDir = ?config(agent_conf_dir, Config), MgrDir = ?config(mgr_dir, Config), Ip = ?config(ip, Config), - config([v2], MgrDir, AgentConfDir, - tuple_to_list(Ip), tuple_to_list(Ip)), + IpFamily = ?config(ipfamily, Config), + config( + [v2], MgrDir, AgentConfDir, + tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), [{vsn, v2} | start_v2_agent(Config)]. finish_v2(Config) when is_list(Config) -> @@ -1755,8 +1844,9 @@ init_v1_v2(Config) when is_list(Config) -> AgentConfDir = ?config(agent_conf_dir, Config), MgrDir = ?config(mgr_dir, Config), Ip = ?config(ip, Config), + IpFamily = ?config(ipfamily, Config), config([v1,v2], MgrDir, AgentConfDir, - tuple_to_list(Ip), tuple_to_list(Ip)), + tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), [{vsn, bilingual} | start_bilingual_agent(Config)]. finish_v1_v2(Config) when is_list(Config) -> @@ -1794,6 +1884,34 @@ v3_cases() -> v2_caps_3 ]. +v3_cases_ipv6() -> + [ + simple_3, + v3_processing, +%% big_3, +%% big2_3, + api_3, + subagent_3, +%% mnesia_3, + loop_mib_3, +%% {group, multiple_reqs_3}, + sa_register_3, + v3_trap, + {group, v3_inform}, +%% sa_error_3, + next_across_sa_3, + undo_3, +%% {group, reported_bugs_3}, + {group, standard_mibs_3}, + {group, v3_security}, + v2_types_3, + implied_3, + sparse_table_3, + cnt_64_3, + opaque_3, + v2_caps_3 + ]. + init_v3(Config) when is_list(Config) -> %% Make sure crypto works, otherwise start_agent will fail %% and we will be stuck with a bunch of mnesia tables for @@ -1815,8 +1933,11 @@ init_v3(Config) when is_list(Config) -> AgentConfDir = ?config(agent_conf_dir, Config), MgrDir = ?config(mgr_dir, Config), Ip = ?config(ip, Config), - ?line ok = config([v3], MgrDir, AgentConfDir, - tuple_to_list(Ip), tuple_to_list(Ip)), + IpFamily = ?config(ipfamily, Config), + ?line ok = + config( + [v3], MgrDir, AgentConfDir, + tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), Opts = [{master_agent_verbosity, trace}, {agent_verbosity, trace}, @@ -6578,9 +6699,7 @@ otp8395({init, Config}) when is_list(Config) -> Vsns = [v1], AgentConfDir = ?config(agent_conf_dir, Config), ManagerConfDir = ?config(manager_top_dir, Config), - snmp_agent_test_lib:config(Vsns, - ManagerConfDir, AgentConfDir, - ManagerIP, AgentIP), + config(Vsns, ManagerConfDir, AgentConfDir, ManagerIP, AgentIP), %% -- @@ -7074,6 +7193,9 @@ delete_files(Config) -> config(Vsns, MgrDir, AgentDir, MIp, AIp) -> snmp_agent_test_lib:config(Vsns, MgrDir, AgentDir, MIp, AIp). +config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily) -> + snmp_agent_test_lib:config(Vsns, MgrDir, AgentDir, MIp, AIp, IpFamily). + update_usm(Vsns, Dir) -> snmp_agent_test_lib:update_usm(Vsns, Dir). @@ -7350,10 +7472,10 @@ init_v1_agent(Config) -> ManagerHost = ?HOSTNAME(ManagerNode), Host = snmp_test_lib:hostname(), - Ip = ?LOCALHOST(?config(ipfamily, Config)), - {ok, AgentIP0} = snmp_misc:ip(AgentHost), + IpFamily = ?LOCALHOST(?config(ipfamily, Config)), + {ok, AgentIP0} = snmp_misc:ip(AgentHost, IpFamily), AgentIP = tuple_to_list(AgentIP0), - {ok, ManagerIP0} = snmp_misc:ip(ManagerHost), + {ok, ManagerIP0} = snmp_misc:ip(ManagerHost, IpFamily), ManagerIP = tuple_to_list(ManagerIP0), @@ -7370,9 +7492,7 @@ init_v1_agent(Config) -> ok = file:make_dir(AgentBkpDir1), ok = file:make_dir(AgentBkpDir2), AgentBkpDirs = [AgentBkpDir1, AgentBkpDir2], - snmp_agent_test_lib:config(Vsns, - ManagerConfDir, AgentConfDir, - ManagerIP, AgentIP), + config(Vsns, ManagerConfDir, AgentConfDir, ManagerIP, AgentIP, IpFamily), %% -- @@ -7380,7 +7500,7 @@ init_v1_agent(Config) -> %% Config2 = start_agent([{host, Host}, - {ip, Ip}, + {ip, IpFamily}, {agent_node, AgentNode}, {agent_host, AgentHost}, {agent_ip, AgentIP}, diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 6061732879..6925c16ffb 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -39,7 +39,7 @@ get_req/2, get_next_req/1, - config/5, + config/5, config/6, delete_files/1, copy_file/2, update_usm/2, @@ -1369,16 +1369,38 @@ stop_node(Node) -> %%%----------------------------------------------------------------- config(Vsns, MgrDir, AgentConfDir, MIp, AIp) -> + config(Vsns, MgrDir, AgentConfDir, MIp, AIp, inet). + +config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) -> ?LOG("config -> entry with" - "~n Vsns: ~p" - "~n MgrDir: ~p" - "~n AgentConfDir: ~p" - "~n MIp: ~p" - "~n AIp: ~p", - [Vsns, MgrDir, AgentConfDir, MIp, AIp]), - ?line ok = - snmp_config:write_agent_snmp_files( - AgentConfDir, Vsns, MIp, ?TRAP_UDP, AIp, 4000, "test"), + "~n Vsns: ~p" + "~n MgrDir: ~p" + "~n AgentConfDir: ~p" + "~n MIp: ~p" + "~n AIp: ~p" + "~n IpFamily: ~p", + [Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily]), + ?line {Domain, ManagerAddr} = + case IpFamily of + inet6 -> + %% XXX Run IPv6 tests over IPv4 compatibility address + %% since the test manager needs to be rewritten to + %% handle IPv6 before we can improve this. + Ipv6Domain = transportDomainUdpIpv6, + AgentIpv6Addr = {mk_ipv6_ip(AIp), 4000}, + ManagerIpv6Addr = {mk_ipv6_ip(MIp), ?TRAP_UDP}, + ?line ok = + snmp_config:write_agent_snmp_files( + AgentConfDir, Vsns, + Ipv6Domain, ManagerIpv6Addr, AgentIpv6Addr, "test"), + {Ipv6Domain, ManagerIpv6Addr}; + _ -> + ?line ok = + snmp_config:write_agent_snmp_files( + AgentConfDir, Vsns, MIp, ?TRAP_UDP, AIp, 4000, "test"), + {snmpUDPDomain, {MIp, ?TRAP_UDP}} + end, + ?line case update_usm(Vsns, AgentConfDir) of true -> ?line copy_file(join(AgentConfDir, "usm.conf"), @@ -1389,11 +1411,14 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp) -> end, ?line update_community(Vsns, AgentConfDir), ?line update_vacm(Vsns, AgentConfDir), - ?line write_target_addr_conf(AgentConfDir, MIp, ?TRAP_UDP, Vsns), + ?line write_target_addr_conf(AgentConfDir, Domain, ManagerAddr, Vsns), ?line write_target_params_conf(AgentConfDir, Vsns), ?line write_notify_conf(AgentConfDir), ok. +mk_ipv6_ip([A,B,C,D]) -> + [0,0,0,0,0,0,0,0,0,0,255,255,A,B,C,D]. + delete_files(Config) -> AgentDir = ?config(agent_dir, Config), delete_files(AgentDir, [db, conf]). @@ -1518,10 +1543,10 @@ write_community_conf(Dir, Conf) -> write_target_addr_conf(Dir, Conf) -> ?line ok = snmp_config:write_agent_target_addr_config(Dir, "", Conf). -write_target_addr_conf(Dir, ManagerIp, UDP, Vsns) -> +write_target_addr_conf(Dir, Ip_or_Domain, Port_or_Addr, Vsns) -> ?line ok = snmp_config:write_agent_snmp_target_addr_conf( - Dir, ManagerIp, UDP, Vsns). + Dir, Ip_or_Domain, Port_or_Addr, Vsns). rewrite_target_addr_conf(Dir, NewPort) -> ?DBG("rewrite_target_addr_conf -> entry with" -- cgit v1.2.3 From 5b99573e288d3798414958975db41daf5509c0fb Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 21 May 2014 15:09:05 +0200 Subject: Fix log validation and fix some testcases --- lib/snmp/src/misc/snmp_log.erl | 19 +++++++++++++--- lib/snmp/test/snmp_agent_test.erl | 48 +++------------------------------------ 2 files changed, 19 insertions(+), 48 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index a1fd392676..4b22281b89 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -231,7 +231,20 @@ validate(Log, SeqNoReq) validate_seqno(PrevSN, SeqNo), {Timestamp, SeqNo}; - ({Timestamp, _Packet, _Addr, _Port}, {PrevTS, _PrevSN}) when SeqNoReq =:= true -> + ({Timestamp, SeqNo, _Packet, _AddrStr}, {PrevTS, PrevSN}) + when is_integer(SeqNo) -> + ?vtrace("validating log entry when" + "~n Timestamp: ~p" + "~n SeqNo: ~p" + "~n PrevTS: ~p" + "~n PrevSN: ~p", + [Timestamp, SeqNo, PrevTS, PrevSN]), + validate_timestamp(PrevTS, Timestamp), + validate_seqno(PrevSN, SeqNo), + {Timestamp, SeqNo}; + + ({Timestamp, _Packet, _Addr, _Port}, {PrevTS, _PrevSN}) + when SeqNoReq =:= true -> ?vtrace("validating log entry when" "~n Timestamp: ~p" "~n PrevTS: ~p", @@ -969,8 +982,8 @@ get_type(#pdu{type = Type}) -> Type. -ip(Domain, Addr) -> - snmp_conf:mk_addr_string(Domain, Addr). +%% ip(Domain, Addr) -> +%% snmp_conf:mk_addr_string(Domain, Addr). %% ip({A,B,C,D}) -> %% io_lib:format("~w.~w.~w.~w", [A,B,C,D]). diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 6b8d0802d0..9db2e67edd 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -297,12 +297,7 @@ %% tickets2 otp8395/1, - otp9884/1, - - %% IPV6 - ipv6_processing/1, - ipv6_trap/1 - + otp9884/1 ]). %% Internal exports @@ -545,8 +540,7 @@ groups() -> {tickets1, [], tickets1_cases()}, {tickets2, [], tickets2_cases()}, {otp4394, [], [otp_4394]}, - {otp7157, [], [otp_7157]}, - {ipv6, [], [ipv6_processing, ipv6_trap]} + {otp7157, [], [otp_7157]} ]. @@ -651,13 +645,6 @@ init_per_group(mib_storage_dets = GroupName, Config) -> init_mib_storage_dets(snmp_test_lib:init_group_top_dir(GroupName, Config)); init_per_group(mib_storage_ets = GroupName, Config) -> init_mib_storage_ets(snmp_test_lib:init_group_top_dir(GroupName, Config)); -init_per_group(ipv6 = GroupName, Config) -> - case ct:require(ipv6_hosts) of - ok -> - ipv6_init(snmp_test_lib:init_group_top_dir(GroupName, Config)); - _ -> - {skip, "Host does not support IPV6"} - end; init_per_group(GroupName, Config) -> snmp_test_lib:init_group_top_dir(GroupName, Config). @@ -770,16 +757,6 @@ init_per_testcase1(v3_inform_i = _Case, Config) when is_list(Config) -> "~n Config: ~p", [_Case, Config]), Dog = ?WD_START(?MINS(10)), [{watchdog, Dog} | Config ]; -init_per_testcase1(ipv6_processing = Case, Config) when is_list(Config) -> - ?DBG("init_per_testcase1 -> entry with" - "~n Case: ~p" - "~n Config: ~p", [Case, Config]), - ipv6_processing({init, init_per_testcase2(Case, Config)}); -init_per_testcase1(ipv6_trap = Case, Config) when is_list(Config) -> - ?DBG("init_per_testcase1 -> entry with" - "~n Case: ~p" - "~n Config: ~p", [Case, Config]), - ipv6_trap({init, init_per_testcase2(Case, Config)}); init_per_testcase1(_Case, Config) when is_list(Config) -> ?DBG("init_per_testcase -> entry with" "~n Case: ~p" @@ -868,8 +845,7 @@ cases() -> {group, test_v3_ipv6}, {group, test_multi_threaded}, {group, mib_storage}, - {group, tickets1}, - {group, ipv6} + {group, tickets1} ]. @@ -6881,24 +6857,6 @@ otp9884_await_backup_completion(First, Second) -> throw({error, {bad_completion, First, Second}}). %%----------------------------------------------------------------- -ipv6_processing({init, Config}) when is_list(Config)-> - init_v1_agent([{ipfamily, inet6} | Config]); -ipv6_processing({fin, Config}) when is_list(Config) -> - fin_v1_agent(Config); -ipv6_processing(Config) when is_list(Config) -> - v1_processing(Config). - -%%----------------------------------------------------------------- - -ipv6_trap({init, Config}) when is_list(Config)-> - init_v1_agent([{ipfamily, inet6} | Config]); -ipv6_trap({fin, Config}) when is_list(Config) -> - fin_v1_agent(Config); -ipv6_trap(Config) when is_list(Config) -> - v1_trap(Config). - -%%----------------------------------------------------------------- - agent_log_validation(Node) -> rpc:call(Node, ?MODULE, agent_log_validation, []). -- cgit v1.2.3 From 0408e4af1978177d7dee498ea3dced37aa56aefe Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 21 May 2014 16:01:49 +0200 Subject: Fix vsn.mk and clean out moot testcases --- lib/snmp/test/snmp_agent_test.erl | 10 +++++----- lib/snmp/vsn.mk | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 9db2e67edd..608a99062d 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -1707,16 +1707,16 @@ v1_cases_ipv6() -> %% mnesia, %% {group, multiple_reqs}, sa_register, - v1_trap, +%% v1_trap, % sends v1 trap %% sa_error, next_across_sa, undo, %% {group, reported_bugs}, - {group, standard_mibs}, + {group, standard_mibs}, % snmp_standard_mib still failing, sends v1 trap sparse_table, - cnt_64, - opaque, - change_target_addr_config +%% cnt_64, % sends v1 trap + opaque +%% change_target_addr_config % sends v1 trap ]. init_v1(Config) when is_list(Config) -> diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 04c3cc9392..533e313bdb 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 4.25.1 +SNMP_VSN = 4.25.0.1 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" -- cgit v1.2.3 From 827f952ce799f2051f60f0f8002d2e3908b2b5da Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 22 May 2014 10:06:51 +0200 Subject: Rewrite ordering functions for maintainability --- lib/snmp/src/agent/snmp_framework_mib.erl | 12 +++--------- lib/snmp/src/manager/snmpm_config.erl | 19 ++++--------------- lib/snmp/src/misc/snmp_conf.erl | 23 ++++++++++++++++++++++- 3 files changed, 29 insertions(+), 25 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 6589ace949..43c91bbbc8 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -222,15 +222,9 @@ check_agent(X) -> error({invalid_agent_attribute, X}). %% Ordering function to sort intAgentTransportDomain first -%% hence before intAgentIpAddress -order_agent({Name, _}, {Name, _}) -> - true; %% Less than or equal -order_agent({_, _}, {intAgentTransportDomain, _}) -> - false; %% Greater than -order_agent({intAgentTransportDomain, _}, {_, _}) -> - true; %% Less than or equal -order_agent({A, _}, {B, _}) -> - A =< B. +%% hence before intAgentIpAddress. Sort other entries on the key. +order_agent(EntryA, EntryB) -> + snmp_conf:keyorder(1, EntryA, EntryB, [intAgentTransportDomain | sort]). diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 69a6b4a3a9..36c7b914ac 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -1783,21 +1783,10 @@ init_agent_config({UserId, TargetName, Config}) -> -%% Sort tdomain first then port to ensure both comes before taddress -order_agent({Item1, _}, {Item2, _}) -> - if Item1 == Item2 -> - true; % Item1 == Item2 - Item2 =:= tdomain -> - false; % Item1 > tdomain - Item2 =:= port -> - if Item1 =:= tdomain -> - true; % tdomain < port - true -> - false % Item1 > port - end; - true -> - true % Item1 < Item 2 - end. +%% Sort 'tdomain' first then 'port' to ensure both +%% sorts before 'taddress'. Keep the order of other items. +order_agent(ItemA, ItemB) -> + snmp_conf:keyorder(1, ItemA, ItemB, [tdomain, port]). fix_agent_config(Conf) -> ?vdebug("fix_agent_config -> entry with~n~n" diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index eb71c55cf4..0c9c755bf4 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -25,7 +25,7 @@ %% External exports %% Avoid warning for local function error/1 clashing with autoimported BIF. -compile({no_auto_import,[error/1]}). --export([read_files/2, no_gen/2, no_order/2, no_filter/1]). +-export([read_files/2, no_gen/2, no_order/2, no_filter/1, keyorder/4]). -export([read/2, read/3]). %% Basic (type) check functions @@ -158,6 +158,27 @@ no_gen(_Dir, _R) -> []. no_order(_, _) -> true. no_filter(X) -> X. +%% Order tuples on element N with Keys first in appearence order. +%% +%% An ordering function (A, B) shall return true iff +%% A is less than or equal to B i.e shall return +%% false iff A is to be ordered after B. +keyorder(N, A, B, _) when element(N, A) == element(N, B) -> + true; +keyorder(N, A, B, [Key | _]) + when tuple_size(A) >= 1, element(N, B) == Key -> + false; +keyorder(N, A, B, [Key | _]) + when element(N, A) == Key, tuple_size(B) >= 1 -> + true; +keyorder(N, A, B, [_ | Keys]) -> + keyorder(N, A, B, Keys); +keyorder(_, A, B, []) when tuple_size(A) >= 1, tuple_size(B) >= 1 -> + %% Do not order other keys + true; +keyorder(N, A, B, sort) -> + %% Order other keys according to standard sort order + element(N, A) =< element(N, B). read(File, Verify) -> -- cgit v1.2.3 From f8efe4ff765e9067172d70e0d93f15fb9f8bd98b Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 23 May 2014 17:23:49 +0200 Subject: Mend manager to pass regression tests --- lib/snmp/src/manager/snmpm.erl | 28 +++++++---- lib/snmp/src/manager/snmpm_config.erl | 81 ++++++++++++++++++++------------ lib/snmp/src/manager/snmpm_net_if.erl | 4 +- lib/snmp/src/manager/snmpm_net_if_mt.erl | 4 +- lib/snmp/src/misc/snmp_conf.erl | 44 ++++++++--------- 5 files changed, 97 insertions(+), 64 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index cf272c5504..8976322c4e 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -379,13 +379,13 @@ register_agent(UserId, Addr) -> register_agent(UserId, Addr, ?DEFAULT_AGENT_PORT, []). %% Backward compatibility -register_agent(UserId, Domain, Address, Config0) when is_atom(Domain) -> +register_agent(UserId, Domain, Addr, Config0) when is_atom(Domain) -> case lists:keymember(target_name, 1, Config0) of false -> - TargetName = mk_target_name(Domain, Address, Config0), + TargetName = mk_target_name(Domain, Addr, Config0), Config = [{reg_type, addr_port}, - {tdomain, Domain}, {taddress, Address} | Config0], + {tdomain, Domain}, {taddress, Addr} | Config0], do_register_agent(UserId, TargetName, ensure_engine_id(Config)); true -> {value, {_, TargetName}} = @@ -393,12 +393,19 @@ register_agent(UserId, Domain, Address, Config0) when is_atom(Domain) -> Config1 = lists:keydelete(target_name, 1, Config0), Config2 = [{reg_type, addr_port}, - {tdomain, Domain}, {taddress, Address} | Config1], + {tdomain, Domain}, {taddress, Addr} | Config1], register_agent(UserId, TargetName, ensure_engine_id(Config2)) end; register_agent(UserId, Ip, Port, Config) when is_integer(Port) -> - {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), - register_agent(UserId, Domain, Address, Config). + Domain = snmpm_config:default_transport_domain(), + Addr = + case snmp_conf:check_address(Domain, {Ip, Port}) of + ok -> + {Ip, Port}; + {ok, FixedAddr} -> + FixedAddr + end, + register_agent(UserId, Domain, Addr, Config). unregister_agent(UserId, TargetName) when is_list(TargetName) -> snmpm_config:unregister_agent(UserId, TargetName); @@ -1276,7 +1283,10 @@ target_name(DomainIp, AddressPort) -> snmpm_config:agent_info(DomainIp, AddressPort, target_name). mk_target_name(Addr, Port, Config) -> - snmpm_config:mk_target_name(Addr, Port, Config). + R = snmpm_config:mk_target_name(Addr, Port, Config), + p(?MODULE_STRING":mk_target_name(~p, ~p, ~p) -> ~p.~n", + [Addr, Port, Config, R]), + R. ensure_engine_id(Config) -> case lists:keymember(engine_id, 1, Config) of @@ -1292,5 +1302,5 @@ ensure_engine_id(Config) -> %% p(F) -> %% p(F, []). -%% p(F, A) -> -%% io:format("~w:" ++ F ++ "~n", [?MODULE | A]). +p(F, A) -> + io:format("~w:" ++ F ++ "~n", [?MODULE | A]). diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 36c7b914ac..e938a68ab0 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -165,7 +165,7 @@ %%%------------------------------------------------------------------- default_transport_domain() -> - transportDomainUdpIpv4. + snmpUDPDomain. start_link(Opts) -> @@ -284,9 +284,9 @@ do_user_info(_UserId, BadItem) -> %% A target-name constructed in this way is a string with the following: %% :- -%% This is intended for backward compatibility and therefor has +%% This is intended for backward compatibility and therefore has %% only support for IPv4 addresses and *no* other transport domain. -mk_target_name(Domain, Address, Config) +mk_target_name(Domain, Addr, Config) when is_atom(Domain), is_list(Config) -> Version = case lists:keysearch(version, 1, Config) of @@ -295,26 +295,34 @@ mk_target_name(Domain, Address, Config) false -> select_lowest_supported_version() end, - try fix_address(Domain, Address) of - {{A, B, C, D}, P} -> - lists:flatten( - io_lib:format( - "~w.~w.~w.~w:~w-~w", - [A, B, C, D, P, Version])); - {{A, B, C, D, E, F, G, H}, P} -> - lists:flatten( - io_lib:format( - "[~.16b:~.16b:~.16b:~.16b:~.16b:~.16b:~.16b:~.16b]:~w-~w", - [A, B, C, D, E, F, G, H, P, Version])) + try + lists:flatten( + io_lib:format( + "~s-~w", [snmp_conf:mk_addr_string({Domain, Addr}), Version])) catch _ -> lists:flatten( - io_lib:format("~p-~w", [Address, Version])) + io_lib:format("~p-~w", [Addr, Version])) end; mk_target_name(Ip, Port, Config) when is_integer(Port), is_list(Config) -> - {Domain, Address} = snmp_conf:ip_port_to_domaddr(Ip, Port), - mk_target_name(Domain, Address, Config). + Domain = default_transport_domain(), + try fix_address(Domain, {Ip, Port}) of + Address -> + mk_target_name(Domain, Address, Config) + catch + _ -> + Version = + case lists:keysearch(version, 1, Config) of + {value, {_, V}} -> + V; + false -> + select_lowest_supported_version() + end, + lists:flatten( + io_lib:format("~p:~w-~w", [Ip, Port, Version])) + end. + select_lowest_supported_version() -> {ok, Versions} = system_info(versions), @@ -403,8 +411,9 @@ unregister_agent(UserId, Domain, Address) when is_atom(Domain) -> {error, not_found} end; unregister_agent(UserId, Ip, Port) when is_integer(Port) -> - try snmp_conf:ip_port_to_domaddr(Ip, Port) of - {Domain, Address} -> + Domain = default_transport_domain(), + try fix_address(Domain, {Ip, Port}) of + Address -> do_unregister_agent(UserId, Domain, Address) catch _ -> @@ -444,19 +453,30 @@ agent_info(Domain, Address, Item) when is_atom(Domain) -> NAddress -> do_agent_info(Domain, NAddress, Item) catch - _ -> + _Thrown -> + p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n" + " ~p", + [Domain, Address, Item, _Thrown, erlang:get_stacktrace()]), {error, not_found} end; agent_info(Ip, Port, Item) -> - try snmp_conf:ip_port_to_domaddr(Ip, Port) of - {Domain, Address} -> + p(?MODULE_STRING":agent_info(~p, ~p, ~p) entry~n", + [Ip, Port, Item]), + Domain = default_transport_domain(), + try fix_address(Domain, {Ip, Port}) of + Address -> do_agent_info(Domain, Address, Item) catch - _ -> + _Thrown -> + p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n" + " ~p", + [Ip, Port, Item, _Thrown, erlang:get_stacktrace()]), {error, not_found} end. do_agent_info(Domain, Address, target_name = Item) -> + p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n", + [Domain, Address, Item]), case ets:lookup(snmpm_agent_table, {Domain, Address, Item}) of [{_, Val}] -> {ok, Val}; @@ -464,6 +484,8 @@ do_agent_info(Domain, Address, target_name = Item) -> {error, not_found} end; do_agent_info(Domain, Address, Item) -> + p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n", + [Domain, Address, Item]), case do_agent_info(Domain, Address, target_name) of {ok, TargetName} -> agent_info(TargetName, Item); @@ -1718,9 +1740,10 @@ check_agent_config( {UserId, TargetName, Community, Ip, Port, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}) -> - {Domain, Address} = snmp_conf:fix_domain_address(Ip, Port), + Domain = default_transport_domain(), + Addr = fix_address(Domain, {Ip, Port}), check_agent_config( - UserId, TargetName, Community, Domain, Address, + UserId, TargetName, Community, Domain, Addr, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel); check_agent_config( @@ -1735,7 +1758,7 @@ check_agent_config(Agent) -> error({bad_agent_config, Agent}). check_agent_config( - UserId, TargetName, Comm, Domain, Address, + UserId, TargetName, Comm, Domain, Addr, EngineId, Timeout, MMS, Version, SecModel, SecName, SecLevel) -> ?vdebug("check_agent_config -> entry with" @@ -1751,7 +1774,7 @@ check_agent_config( Conf = [{reg_type, target_name}, {tdomain, Domain}, - {taddress, Address}, + {taddress, Addr}, {community, Comm}, {engine_id, EngineId}, {timeout, Timeout}, @@ -3511,6 +3534,6 @@ error_msg(F, A) -> %% p(F) -> %% p(F, []). -%% p(F, A) -> -%% io:format("~w:" ++ F ++ "~n", [?MODULE | A]). +p(F, A) -> + io:format("~w:" ++ F ++ "~n", [?MODULE | A]). diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index e7167cdb6b..d7f17e0b7f 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -425,8 +425,8 @@ handle_cast(Msg, State) -> %%-------------------------------------------------------------------- handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]), - {Domain, Address} = snmp_conf:ip_port_to_domaddr(Ip, Port), - maybe_handle_recv_msg(Domain, Address, Bytes, State), + Domain = snmpm_config:default_transport_domain(), + maybe_handle_recv_msg(Domain, {Ip, Port}, Bytes, State), {noreply, State}; handle_info(inform_response_gc, State) -> diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl index 594bc44474..8dd3ef0111 100644 --- a/lib/snmp/src/manager/snmpm_net_if_mt.erl +++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl @@ -435,8 +435,8 @@ handle_cast(Msg, State) -> %%-------------------------------------------------------------------- handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]), - {Domain, Address} = snmp_conf:ip_port_to_domaddr(Ip, Port), - handle_udp(Domain, Address, Bytes, State), + Domain = snmpm_config:default_transport_domain(), + handle_udp(Domain, {Ip, Port}, Bytes, State), {noreply, State}; handle_info(inform_response_gc, State) -> diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 0c9c755bf4..ea4686c91a 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -49,7 +49,7 @@ mk_addr_string/1, check_ip/1, check_ip/2, check_port/1, - ip_port_to_domaddr/2, +%% ip_port_to_domaddr/2, check_address/2, check_address/3, check_taddress/2, mk_taddress/1, mk_taddress/2, @@ -808,25 +808,25 @@ check_port(Port) when ?is_word(Port) -> check_port(Port) -> error({bad_port, Port}). -ip_port_to_domaddr(IP, Port) when ?is_word(Port) -> - %% XXX There is only code for IP domains here - case check_address_ip(transportDomainUdpIpv4, IP) of - false -> - case check_address_ip(transportDomainUdpIpv6, IP) of - false -> - error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}); - true -> - {transportDomainUdpIpv6, {IP, Port}}; - FixedIP -> - {transportDomainUdpIpv6, {FixedIP, Port}} - end; - true -> - {transportDomainUdpIpv4, {IP, Port}}; - FixedIP -> - {transportDomainUdpIpv4, {FixedIP, Port}} - end; -ip_port_to_domaddr(IP, Port) -> - error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}). +%% ip_port_to_domaddr(IP, Port) when ?is_word(Port) -> +%% %% XXX There is only code for IP domains here +%% case check_address_ip(transportDomainUdpIpv4, IP) of +%% false -> +%% case check_address_ip(transportDomainUdpIpv6, IP) of +%% false -> +%% error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}); +%% true -> +%% {transportDomainUdpIpv6, {IP, Port}}; +%% FixedIP -> +%% {transportDomainUdpIpv6, {FixedIP, Port}} +%% end; +%% true -> +%% {transportDomainUdpIpv4, {IP, Port}}; +%% FixedIP -> +%% {transportDomainUdpIpv4, {FixedIP, Port}} +%% end; +%% ip_port_to_domaddr(IP, Port) -> +%% error({bad_address, {transportDomainUdpIpv4, {IP, Port}}}). %% Check a configuration term field from a file to see if it %% can be fixed to be fed to mk_taddress/2. @@ -923,7 +923,7 @@ check_address_ip_port(Domain, Address) false -> false; true -> - Address; + true; FixedIP -> {FixedIP, Port} end; @@ -941,7 +941,7 @@ check_address_ip_port(transportDomainUdpIpv6 = Domain, Address) -> false -> false; true -> - Address; + true; FixedIP -> {FixedIP, Port} end; -- cgit v1.2.3 From 20bb61e48a8370a4b5913d7d8e16a260bd3e31eb Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 27 May 2014 08:09:26 +0200 Subject: Mend write_config_file and append_config_file --- lib/snmp/src/agent/snmp_framework_mib.erl | 2 +- lib/snmp/src/agent/snmpa_conf.erl | 445 ++++++++++++------------------ lib/snmp/src/manager/snmpm_conf.erl | 234 +++++++--------- lib/snmp/src/manager/snmpm_config.erl | 38 ++- lib/snmp/src/misc/snmp_config.erl | 310 +++++++++++---------- 5 files changed, 476 insertions(+), 553 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 43c91bbbc8..4599f05f47 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -52,7 +52,7 @@ set_engine_boots/1, set_engine_time/1, table_next/2, check_status/3]). -export([add_context/1, delete_context/1]). --export([check_agent/1, check_agent/2, check_context/1, order_agent/2]). +-export([check_agent/2, check_context/1, order_agent/2]). %%----------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index b05590a504..2569b01b55 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -108,40 +108,26 @@ write_agent_config(Dir, Conf) -> Hdr = header() ++ Comment, write_agent_config(Dir, Hdr, Conf). -write_agent_config(Dir, Hdr, Conf) +write_agent_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_agent_conf(Conf) end, - Write = fun(Fd) -> write_agent_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "agent.conf", Verify, Write). - + Order = fun snmp_framework_mib:order_agent/2, + Check = fun snmp_framework_mib:check_agent/2, + Write = fun (Fd, Entries) -> write_agent_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "agent.conf", Order, Check, Write, Conf). -append_agent_config(Dir, Conf) +append_agent_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_agent_conf(Conf) end, - Write = fun(Fd) -> write_agent_conf(Fd, Conf) end, - append_config_file(Dir, "agent.conf", Verify, Write). - + Order = fun snmp_framework_mib:order_agent/2, + Check = fun snmp_framework_mib:check_agent/2, + Write = fun write_agent_conf/2, + append_config_file(Dir, "agent.conf", Order, Check, Write, Conf). read_agent_config(Dir) -> Order = fun snmp_framework_mib:order_agent/2, - Check = fun check_agent_conf_entry/2, + Check = fun snmp_framework_mib:check_agent/2, read_config_file(Dir, "agent.conf", Order, Check). -verify_agent_conf(Conf) -> - verify_agent_conf(Conf, undefined). -%% -verify_agent_conf([], _) -> - ok; -verify_agent_conf([H|T], State) -> - {_, NewState} = check_agent_conf_entry(H, State), - verify_agent_conf(T, NewState); -verify_agent_conf(X, _) -> - error({bad_agent_config, X}). - -check_agent_conf_entry(Entry, State) -> - snmp_framework_mib:check_agent(Entry, State). - write_agent_conf(Fd, "", Conf) -> write_agent_conf(Fd, Conf); write_agent_conf(Fd, Hdr, Conf) -> @@ -196,38 +182,27 @@ write_context_config(Dir, Conf) -> write_context_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_context_conf(Conf) end, - Write = fun(Fd) -> write_context_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "context.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_context/2, + Write = fun (Fd, Entries) -> write_context_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "context.conf", Order, Check, Write, Conf). -append_context_config(Dir, Conf) +append_context_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_context_conf(Conf) end, - Write = fun(Fd) -> write_context_conf(Fd, Conf) end, - append_config_file(Dir, "context.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_context/2, + Write = fun write_context_conf/2, + append_config_file(Dir, "context.conf", Order, Check, Write, Conf). read_context_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_context_conf_entry(Entry), State} - end, - read_config_file(Dir, "context.conf", Order, Verify). + Check = fun check_context/2, + read_config_file(Dir, "context.conf", Order, Check). - -verify_context_conf([]) -> - ok; -verify_context_conf([H|T]) -> - verify_context_conf_entry(H), - verify_context_conf(T); -verify_context_conf(X) -> - error({error_context_config, X}). - -verify_context_conf_entry(Context) -> - {ok, _} = snmp_framework_mib:check_context(Context), - ok. + +check_context(Entry, State) -> + {check_ok(snmp_framework_mib:check_context(Entry)), + State}. write_context_conf(Fd, "", Conf) -> write_context_conf(Fd, Conf); @@ -280,40 +255,29 @@ write_community_config(Dir, Conf) -> Hdr = header() ++ Comment, write_community_config(Dir, Hdr, Conf). -write_community_config(Dir, Hdr, Conf) +write_community_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_community_conf(Conf) end, - Write = fun(Fd) -> write_community_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "community.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_community/2, + Write = fun (Fd, Entries) -> write_community_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "community.conf", Order, Check, Write, Conf). -append_community_config(Dir, Conf) +append_community_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_community_conf(Conf) end, - Write = fun(Fd) -> write_community_conf(Fd, Conf) end, - append_config_file(Dir, "community.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_community/2, + Write = fun write_community_conf/2, + append_config_file(Dir, "community.conf", Order, Check, Write, Conf). read_community_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_community_conf_entry(Entry), State} - end, - read_config_file(Dir, "community.conf", Order, Verify). + Check = fun check_community/2, + read_config_file(Dir, "community.conf", Order, Check). - -verify_community_conf([]) -> - ok; -verify_community_conf([H|T]) -> - verify_community_conf_entry(H), - verify_community_conf(T); -verify_community_conf(X) -> - error({invalid_community_config, X}). - -verify_community_conf_entry(Context) -> - {ok, _} = snmp_community_mib:check_community(Context), - ok. + +check_community(Entry, State) -> + {check_ok(snmp_community_mib:check_community(Entry)), + State}. write_community_conf(Fd, "", Conf) -> write_community_conf(Fd, Conf); @@ -322,14 +286,17 @@ write_community_conf(Fd, Hdr, Conf) -> write_community_conf(Fd, Conf). write_community_conf(Fd, Conf) -> - Fun = fun({Idx, Name, SecName, CtxName, TranspTag}) -> - io:format(Fd, "{\"~s\", \"~s\", \"~s\", \"~s\", \"~s\"}.~n", - [Idx, Name, SecName, CtxName, TranspTag]); + Fun = + fun({Idx, Name, SecName, CtxName, TranspTag}) -> + io:format( + Fd, + "{\"~s\", \"~s\", \"~s\", \"~s\", \"~s\"}.~n", + [Idx, Name, SecName, CtxName, TranspTag]); (Crap) -> - error({bad_community_config, Crap}) + error({bad_community_config, Crap}) end, lists:foreach(Fun, Conf). - + %% %% ------ standard.conf ------ @@ -356,44 +323,29 @@ write_standard_config(Dir, Conf) -> Hdr = header() ++ Comment, write_standard_config(Dir, Hdr, Conf). -write_standard_config(Dir, Hdr, Conf) +write_standard_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_standard_conf(Conf) end, - Write = fun(Fd) -> write_standard_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "standard.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_standard/2, + Write = fun (Fd, Entries) -> write_standard_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "standard.conf", Order, Check, Write, Conf). -append_standard_config(Dir, Conf) +append_standard_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_standard_conf(Conf) end, - Write = fun(Fd) -> write_standard_conf(Fd, Conf) end, - append_config_file(Dir, "standard.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_standard/2, + Write = fun write_standard_conf/2, + append_config_file(Dir, "standard.conf", Order, Check, Write, Conf). read_standard_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_standard_conf_entry(Entry), State} - end, - read_config_file(Dir, "standard.conf", Order, Verify). + Check = fun check_standard/2, + read_config_file(Dir, "standard.conf", Order, Check). - -verify_standard_conf([]) -> - ok; -verify_standard_conf([H|T]) -> - verify_standard_conf_entry(H), - verify_standard_conf(T); -verify_standard_conf(X) -> - error({bad_standard_config, X}). - -verify_standard_conf_entry(Std) -> - case snmp_standard_mib:check_standard(Std) of - ok -> - ok; - {ok, _} -> - ok - end. + +check_standard(Entry, State) -> + {check_ok(snmp_standard_mib:check_standard(Entry)), + State}. write_standard_conf(Fd, "", Conf) -> write_standard_conf(Fd, Conf); @@ -521,41 +473,29 @@ write_target_addr_config(Dir, Conf) -> Hdr = header() ++ Comment, write_target_addr_config(Dir, Hdr, Conf). -write_target_addr_config(Dir, Hdr, Conf) +write_target_addr_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_target_addr_conf(Conf) end, - Write = fun(Fd) -> write_target_addr_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "target_addr.conf", Verify, Write). - - + Order = fun snmp_conf:no_order/2, + Check = fun check_target_addr/2, + Write = fun (Fd, Entries) -> write_target_addr_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "target_addr.conf", Order, Check, Write, Conf). -append_target_addr_config(Dir, Conf) +append_target_addr_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_target_addr_conf(Conf) end, - Write = fun(Fd) -> write_target_addr_conf(Fd, Conf) end, - append_config_file(Dir, "target_addr.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_target_addr/2, + Write = fun write_target_addr_conf/2, + append_config_file(Dir, "target_addr.conf", Order, Check, Write, Conf). read_target_addr_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_target_addr_conf_entry(Entry), State} - end, - read_config_file(Dir, "target_addr.conf", Order, Verify). + Check = fun check_target_addr/2, + read_config_file(Dir, "target_addr.conf", Order, Check). - -verify_target_addr_conf([]) -> - ok; -verify_target_addr_conf([H|T]) -> - verify_target_addr_conf_entry(H), - verify_target_addr_conf(T); -verify_target_addr_conf(X) -> - error({bad_target_addr_config, X}). - -verify_target_addr_conf_entry(Entry) -> - {ok, _} = snmp_target_mib:check_target_addr(Entry), - ok. + +check_target_addr(Entry, State) -> + {check_ok(snmp_target_mib:check_target_addr(Entry)), + State}. write_target_addr_conf(Fd, "", Conf) -> write_target_addr_conf(Fd, Conf); @@ -641,38 +581,27 @@ write_target_params_config(Dir, Conf) -> write_target_params_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_target_params_conf(Conf) end, - Write = fun(Fd) -> write_target_params_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "target_params.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_target_params/2, + Write = fun (Fd, Entries) -> write_target_params_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "target_params.conf", Order, Check, Write, Conf). append_target_params_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_target_params_conf(Conf) end, - Write = fun(Fd) -> write_target_params_conf(Fd, Conf) end, - append_config_file(Dir, "target_params.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_target_params/2, + Write = fun write_target_params_conf/2, + append_config_file(Dir, "target_params.conf", Order, Check, Write, Conf). read_target_params_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_target_params_conf_entry(Entry), State} - end, - read_config_file(Dir, "target_params.conf", Order, Verify). + Check = fun check_target_params/2, + read_config_file(Dir, "target_params.conf", Order, Check). -verify_target_params_conf([]) -> - ok; -verify_target_params_conf([H|T]) -> - verify_target_params_conf_entry(H), - verify_target_params_conf(T); -verify_target_params_conf(X) -> - error({bad_target_params_config, X}). - -verify_target_params_conf_entry(Entry) -> - {ok, _} = snmp_target_mib:check_target_params(Entry), - ok. +check_target_params(Entry, State) -> + {check_ok(snmp_target_mib:check_target_params(Entry)), + State}. write_target_params_conf(Fd, "", Conf) -> write_target_params_conf(Fd, Conf); @@ -717,38 +646,27 @@ write_notify_config(Dir, Conf) -> write_notify_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_notify_conf(Conf) end, - Write = fun(Fd) -> write_notify_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "notify.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_notify/2, + Write = fun (Fd, Entries) -> write_notify_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "notify.conf", Order, Check, Write, Conf). append_notify_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_notify_conf(Conf) end, - Write = fun(Fd) -> write_notify_conf(Fd, Conf) end, - append_config_file(Dir, "notify.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_notify/2, + Write = fun write_notify_conf/2, + append_config_file(Dir, "notify.conf", Order, Check, Write, Conf). read_notify_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_notify_conf_entry(Entry), State} - end, - read_config_file(Dir, "notify.conf", Order, Verify). + Check = fun check_notify/2, + read_config_file(Dir, "notify.conf", Order, Check). -verify_notify_conf([]) -> - ok; -verify_notify_conf([H|T]) -> - verify_notify_conf_entry(H), - verify_notify_conf(T); -verify_notify_conf(X) -> - error({bad_notify_config, X}). - -verify_notify_conf_entry(Entry) -> - {ok, _} = snmp_notification_mib:check_notify(Entry), - ok. +check_notify(Entry, State) -> + {check_ok(snmp_notification_mib:check_notify(Entry)), + State}. write_notify_conf(Fd, "", Conf) -> write_notify_conf(Fd, Conf); @@ -817,38 +735,27 @@ write_usm_config(Dir, Conf) -> write_usm_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_usm_conf(Conf) end, - Write = fun(Fd) -> write_usm_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "usm.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_usm/2, + Write = fun (Fd, Entries) -> write_usm_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "usm.conf", Order, Check, Write, Conf). append_usm_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_usm_conf(Conf) end, - Write = fun(Fd) -> write_usm_conf(Fd, Conf) end, - append_config_file(Dir, "usm.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_usm/2, + Write = fun write_usm_conf/2, + append_config_file(Dir, "usm.conf", Order, Check, Write, Conf). read_usm_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_usm_conf_entry(Entry), State} - end, - read_config_file(Dir, "usm.conf", Order, Verify). + Check = fun check_usm/2, + read_config_file(Dir, "usm.conf", Order, Check). -verify_usm_conf([]) -> - ok; -verify_usm_conf([H|T]) -> - verify_usm_conf_entry(H), - verify_usm_conf(T); -verify_usm_conf(X) -> - error({bad_usm_conf, X}). - -verify_usm_conf_entry(Entry) -> - {ok, _} = snmp_user_based_sm_mib:check_usm(Entry), - ok. +check_usm(Entry, State) -> + {check_ok(snmp_user_based_sm_mib:check_usm(Entry)), + State}. write_usm_conf(Fd, "", Conf) -> write_usm_conf(Fd, Conf); @@ -860,11 +767,12 @@ write_usm_conf(Fd, Conf) -> Fun = fun(Entry) -> do_write_usm_conf(Fd, Entry) end, lists:foreach(Fun, Conf). -do_write_usm_conf(Fd, - {EngineID, UserName, SecName, Clone, - AuthP, AuthKeyC, OwnAuthKeyC, - PrivP, PrivKeyC, OwnPrivKeyC, - Public, AuthKey, PrivKey}) -> +do_write_usm_conf( + Fd, + {EngineID, UserName, SecName, Clone, + AuthP, AuthKeyC, OwnAuthKeyC, + PrivP, PrivKeyC, OwnPrivKeyC, + Public, AuthKey, PrivKey}) -> io:format(Fd, "{", []), io:format(Fd, "\"~s\", ", [EngineID]), io:format(Fd, "\"~s\", ", [UserName]), @@ -930,38 +838,27 @@ write_vacm_config(Dir, Conf) -> write_vacm_config(Dir, Hdr, Conf) when is_list(Dir) and is_list(Hdr) and is_list(Conf) -> - Verify = fun() -> verify_vacm_conf(Conf) end, - Write = fun(Fd) -> write_vacm_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, "vacm.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_vacm/2, + Write = fun (Fd, Entries) -> write_vacm_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, "vacm.conf", Order, Check, Write, Conf). append_vacm_config(Dir, Conf) when is_list(Dir) and is_list(Conf) -> - Verify = fun() -> verify_vacm_conf(Conf) end, - Write = fun(Fd) -> write_vacm_conf(Fd, Conf) end, - append_config_file(Dir, "vacm.conf", Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_vacm/2, + Write = fun write_vacm_conf/2, + append_config_file(Dir, "vacm.conf", Order, Check, Write, Conf). read_vacm_config(Dir) -> Order = fun snmp_conf:no_order/2, - Verify = - fun (Entry, State) -> - {verify_vacm_conf_entry(Entry), State} - end, - read_config_file(Dir, "vacm.conf", Order, Verify). + Check = fun check_vacm/2, + read_config_file(Dir, "vacm.conf", Order, Check). -verify_vacm_conf([]) -> - ok; -verify_vacm_conf([H|T]) -> - verify_vacm_conf_entry(H), - verify_vacm_conf(T); -verify_vacm_conf(X) -> - error({bad_vacm_conf, X}). - -verify_vacm_conf_entry(Entry) -> - {ok, _} = snmp_view_based_acm_mib:check_vacm(Entry), - ok. +check_vacm(Entry, State) -> + {check_ok(snmp_view_based_acm_mib:check_vacm(Entry)), + State}. write_vacm_conf(Fd, "", Conf) -> write_vacm_conf(Fd, Conf); @@ -973,34 +870,40 @@ write_vacm_conf(Fd, Conf) -> Fun = fun(Entry) -> do_write_vacm_conf(Fd, Entry) end, lists:foreach(Fun, Conf). -do_write_vacm_conf(Fd, - {vacmSecurityToGroup, - SecModel, SecName, GroupName}) -> - io:format(Fd, "{vacmSecurityToGroup, ~w, \"~s\", \"~s\"}.~n", - [SecModel, SecName, GroupName]); -do_write_vacm_conf(Fd, - {vacmAccess, - GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}) -> - io:format(Fd, "{vacmAccess, \"~s\", \"~s\", ~w, ~w, ~w, " - "\"~s\", \"~s\", \"~s\"}.~n", - [GroupName, Prefix, SecModel, SecLevel, - Match, RV, WV, NV]); -do_write_vacm_conf(Fd, - {vacmViewTreeFamily, - ViewIndex, ViewSubtree, ViewStatus, ViewMask}) -> - io:format(Fd, "{vacmViewTreeFamily, \"~s\", ~w, ~w, ~w}.~n", - [ViewIndex, ViewSubtree, ViewStatus, ViewMask]); +do_write_vacm_conf( + Fd, + {vacmSecurityToGroup, + SecModel, SecName, GroupName}) -> + io:format( + Fd, "{vacmSecurityToGroup, ~w, \"~s\", \"~s\"}.~n", + [SecModel, SecName, GroupName]); +do_write_vacm_conf( + Fd, + {vacmAccess, + GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV}) -> + io:format( + Fd, "{vacmAccess, \"~s\", \"~s\", ~w, ~w, ~w, " + "\"~s\", \"~s\", \"~s\"}.~n", + [GroupName, Prefix, SecModel, SecLevel, + Match, RV, WV, NV]); +do_write_vacm_conf( + Fd, + {vacmViewTreeFamily, + ViewIndex, ViewSubtree, ViewStatus, ViewMask}) -> + io:format( + Fd, "{vacmViewTreeFamily, \"~s\", ~w, ~w, ~w}.~n", + [ViewIndex, ViewSubtree, ViewStatus, ViewMask]); do_write_vacm_conf(_Fd, Crap) -> error({bad_vacm_config, Crap}). %% ---- config file wrapper functions ---- -write_config_file(Dir, File, Verify, Write) -> - snmp_config:write_config_file(Dir, File, Verify, Write). +write_config_file(Dir, File, Order, Check, Write, Conf) -> + snmp_config:write_config_file(Dir, File, Order, Check, Write, Conf). -append_config_file(Dir, File, Verify, Write) -> - snmp_config:append_config_file(Dir, File, Verify, Write). +append_config_file(Dir, File, Order, Check, Write, Conf) -> + snmp_config:append_config_file(Dir, File, Order, Check, Write, Conf). read_config_file(Dir, File, Order, Check) -> snmp_config:read_config_file(Dir, File, Order, Check). @@ -1008,13 +911,19 @@ read_config_file(Dir, File, Order, Check) -> %% ---- config file utility functions ---- +check_ok(ok) -> + ok; +check_ok({ok, _}) -> + ok. + header() -> {Y,Mo,D} = date(), {H,Mi,S} = time(), - io_lib:format("%% This file was generated by " - "~w (version-~s) ~w-~2.2.0w-~2.2.0w " - "~2.2.0w:~2.2.0w:~2.2.0w\n", - [?MODULE, ?version, Y, Mo, D, H, Mi, S]). + io_lib:format( + "%% This file was generated by " + "~w (version-~s) ~w-~2.2.0w-~2.2.0w " + "~2.2.0w:~2.2.0w:~2.2.0w\n", + [?MODULE, ?version, Y, Mo, D, H, Mi, S]). error(R) -> throw({error, R}). diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl index 5e2d9fdbf6..d2f9ba9c26 100644 --- a/lib/snmp/src/manager/snmpm_conf.erl +++ b/lib/snmp/src/manager/snmpm_conf.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2013. All Rights Reserved. +%% Copyright Ericsson AB 2006-2014. 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 @@ -78,43 +78,26 @@ write_manager_config(Dir, Conf) -> Hdr = header() ++ Comment, write_manager_config(Dir, Hdr, Conf). -write_manager_config(Dir, Hdr, Conf) - when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) -> - Verify = fun() -> verify_manager_conf(Conf) end, - Write = fun(Fid) -> write_manager_conf(Fid, Hdr, Conf) end, - write_config_file(Dir, ?MANAGER_CONF_FILE, Verify, Write). - +write_manager_config(Dir, Hdr, Conf) + when is_list(Dir), is_list(Hdr), is_list(Conf) -> + Order = fun snmpm_config:order_manager_config/2, + Check = fun snmpm_config:check_manager_config/2, + Write = fun (Fd, Entries) -> write_manager_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, ?MANAGER_CONF_FILE, Order, Check, Write, Conf). append_manager_config(Dir, Conf) - when is_list(Dir) andalso is_list(Conf) -> - Verify = fun() -> verify_manager_conf(Conf) end, - Write = fun(Fid) -> write_manager_conf(Fid, Conf) end, - append_config_file(Dir, ?MANAGER_CONF_FILE, Verify, Write). - + when is_list(Dir), is_list(Conf) -> + Order = fun snmpm_config:order_manager_config/2, + Check = fun snmpm_config:check_manager_config/2, + Write = fun write_manager_conf/2, + append_config_file(Dir, ?MANAGER_CONF_FILE, Order, Check, Write, Conf). -read_manager_config(Dir) -> - Verify = fun(Entry) -> verify_manager_conf_entry(Entry) end, - read_config_file(Dir, ?MANAGER_CONF_FILE, Verify). +read_manager_config(Dir) when is_list(Dir) -> + Order = fun snmpm_config:order_manager_config/2, + Check = fun snmpm_config:check_manager_config/2, + read_config_file(Dir, ?MANAGER_CONF_FILE, Order, Check). -verify_manager_conf([]) -> - ok; -verify_manager_conf([H|T]) -> - verify_manager_conf_entry(H), - verify_manager_conf(T); -verify_manager_conf(X) -> - error({bad_manager_config, X}). - -verify_manager_conf_entry(Entry) -> - case snmpm_config:check_manager_config(Entry) of - ok -> - ok; -%% {ok, _} -> -%% ok; - Error -> - throw(Error) - end. - write_manager_conf(Fd, "", Conf) -> write_manager_conf(Fd, Conf); write_manager_conf(Fd, Hdr, Conf) -> @@ -167,36 +150,29 @@ write_users_config(Dir, Conf) -> Hdr = header() ++ Comment, write_users_config(Dir, Hdr, Conf). -write_users_config(Dir, Hdr, Conf) +write_users_config(Dir, Hdr, Conf) when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) -> - Verify = fun() -> verify_users_conf(Conf) end, - Write = fun(Fd) -> write_users_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, ?USERS_CONF_FILE, Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_user_config/2, + Write = fun (Fd, Entries) -> write_users_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, ?USERS_CONF_FILE, Order, Check, Write, Conf). -append_users_config(Dir, Conf) +append_users_config(Dir, Conf) when is_list(Dir) andalso is_list(Conf) -> - Verify = fun() -> verify_users_conf(Conf) end, - Write = fun(Fd) -> write_users_conf(Fd, Conf) end, - append_config_file(Dir, ?USERS_CONF_FILE, Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_user_config/2, + Write = fun write_users_conf/2, + append_config_file(Dir, ?USERS_CONF_FILE, Order, Check, Write, Conf). read_users_config(Dir) when is_list(Dir) -> - Verify = fun(Entry) -> verify_users_conf_entry(Entry) end, - read_config_file(Dir, ?USERS_CONF_FILE, Verify). + Order = fun snmp_conf:no_order/2, + Check = fun check_user_config/2, + read_config_file(Dir, ?USERS_CONF_FILE, Order, Check). - -verify_users_conf([]) -> - ok; -verify_users_conf([H|T]) -> - verify_users_conf_entry(H), - verify_users_conf(T); -verify_users_conf(X) -> - error({bad_users_conf, X}). - -verify_users_conf_entry(Entry) -> - {ok, _} = snmpm_config:check_user_config(Entry), - ok. + +check_user_config(Entry, State) -> + {check_ok(snmpm_config:check_user_config(Entry)), + State}. write_users_conf(Fd, "", Conf) -> write_users_conf(Fd, Conf); @@ -239,36 +215,29 @@ write_agents_config(Dir, Conf) -> Hdr = header() ++ Comment, write_agents_config(Dir, Hdr, Conf). -write_agents_config(Dir, Hdr, Conf) +write_agents_config(Dir, Hdr, Conf) when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) -> - Verify = fun() -> verify_agents_conf(Conf) end, - Write = fun(Fd) -> write_agents_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, ?AGENTS_CONF_FILE, Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_agent_config/2, + Write = fun (Fd, Entries) -> write_agents_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, ?AGENTS_CONF_FILE, Order, Check, Write, Conf). -append_agents_config(Dir, Conf) +append_agents_config(Dir, Conf) when is_list(Dir) andalso is_list(Conf) -> - Verify = fun() -> verify_agents_conf(Conf) end, - Write = fun(Fd) -> write_agents_conf(Fd, Conf) end, - append_config_file(Dir, ?AGENTS_CONF_FILE, Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_agent_config/2, + Write = fun write_agents_conf/2, + append_config_file(Dir, ?AGENTS_CONF_FILE, Order, Check, Write, Conf). read_agents_config(Dir) -> - Verify = fun(Entry) -> verify_agents_conf_entry(Entry) end, - read_config_file(Dir, ?AGENTS_CONF_FILE, Verify). + Order = fun snmp_conf:no_order/2, + Check = fun check_agent_config/2, + read_config_file(Dir, ?AGENTS_CONF_FILE, Order, Check). -verify_agents_conf([]) -> - ok; -verify_agents_conf([H|T]) -> - verify_agents_conf_entry(H), - verify_agents_conf(T); -verify_agents_conf(X) -> - error({bad_agents_config, X}). - -verify_agents_conf_entry(Entry) -> - {ok, _} = snmpm_config:check_agent_config(Entry), - ok. +check_agent_config(Entry, State) -> + {check_ok(snmpm_config:check_agent_config(Entry)), + State}. write_agents_conf(Fd, "", Conf) -> write_agents_conf(Fd, Conf); @@ -282,13 +251,15 @@ write_agents_conf(Fd, [H|T]) -> do_write_agents_conf(Fd, H), write_agents_conf(Fd, T). -do_write_agents_conf(Fd, - {UserId, - TargetName, Comm, Ip, Port, EngineID, - Timeout, MaxMessageSize, Version, - SecModel, SecName, SecLevel} = _A) -> - io:format(Fd, - "{~w, \"~s\", \"~s\", ~w, ~w, \"~s\", ~w, ~w, ~w, ~w, \"~s\", ~w}.~n", [UserId, TargetName, Comm, Ip, Port, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel]); +do_write_agents_conf( + Fd, + {UserId, TargetName, Comm, Ip, Port, EngineID, + Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel} = _A) -> + io:format( + Fd, + "{~w, \"~s\", \"~s\", ~w, ~w, \"~s\", ~w, ~w, ~w, ~w, \"~s\", ~w}.~n", + [UserId, TargetName, Comm, Ip, Port, EngineID, + Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel]); do_write_agents_conf(_Fd, Crap) -> error({bad_agents_config, Crap}). @@ -314,37 +285,30 @@ write_usm_config(Dir, Conf) -> Hdr = header() ++ Comment, write_usm_config(Dir, Hdr, Conf). -write_usm_config(Dir, Hdr, Conf) +write_usm_config(Dir, Hdr, Conf) when is_list(Dir) andalso is_list(Hdr) andalso is_list(Conf) -> - Verify = fun() -> verify_usm_conf(Conf) end, - Write = fun(Fd) -> write_usm_conf(Fd, Hdr, Conf) end, - write_config_file(Dir, ?USM_USERS_CONF_FILE, Verify, Write). + Order = fun snmp_conf:no_order/2, + Check = fun check_usm_user_config/2, + Write = fun (Fd, Entries) -> write_usm_conf(Fd, Hdr, Entries) end, + write_config_file(Dir, ?USM_USERS_CONF_FILE, Order, Check, Write, Conf). - -append_usm_config(Dir, Conf) +append_usm_config(Dir, Conf) when is_list(Dir) andalso is_list(Conf) -> - Verify = fun() -> verify_usm_conf(Conf) end, - Write = fun(Fd) -> write_usm_conf(Fd, Conf) end, - append_config_file(Dir, ?USM_USERS_CONF_FILE, Verify, Write). - + Order = fun snmp_conf:no_order/2, + Check = fun check_usm_user_config/2, + Write = fun write_usm_conf/2, + append_config_file(Dir, ?USM_USERS_CONF_FILE, Order, Check, Write, Conf). read_usm_config(Dir) when is_list(Dir) -> - Verify = fun(Entry) -> verify_usm_conf_entry(Entry) end, - read_config_file(Dir, ?USM_USERS_CONF_FILE, Verify). + Order = fun snmp_conf:no_order/2, + Check = fun check_usm_user_config/2, + read_config_file(Dir, ?USM_USERS_CONF_FILE, Order, Check). -verify_usm_conf([]) -> - ok; -verify_usm_conf([H|T]) -> - verify_usm_conf_entry(H), - verify_usm_conf(T); -verify_usm_conf(X) -> - error({bad_usm_conf, X}). - -verify_usm_conf_entry(Entry) -> - {ok, _} = snmpm_config:check_usm_user_config(Entry), - ok. +check_usm_user_config(Entry, State) -> + {check_ok(snmpm_config:check_usrm_user_config(Entry)), + State}. write_usm_conf(Fd, "", Conf) -> write_usm_conf(Fd, Conf); @@ -358,41 +322,49 @@ write_usm_conf(Fd, [H|T]) -> do_write_usm_conf(Fd, H), write_usm_conf(Fd, T). -do_write_usm_conf(Fd, - {EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey}) -> - io:format(Fd, "{\"~s\", \"~s\", ~w, ~w, ~w, ~w}.~n", - [EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey]); -do_write_usm_conf(Fd, - {EngineID, UserName, SecName, - AuthP, AuthKey, PrivP, PrivKey}) -> - io:format(Fd, "{\"~s\", \"~s\", \"~s\", í~w, ~w, ~w, ~w}.~n", - [EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey]); +do_write_usm_conf( + Fd, + {EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey}) -> + io:format( + Fd, "{\"~s\", \"~s\", ~w, ~w, ~w, ~w}.~n", + [EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey]); +do_write_usm_conf( + Fd, + {EngineID, UserName, SecName, + AuthP, AuthKey, PrivP, PrivKey}) -> + io:format( + Fd, "{\"~s\", \"~s\", \"~s\", í~w, ~w, ~w, ~w}.~n", + [EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey]); do_write_usm_conf(_Fd, Crap) -> error({bad_usm_conf, Crap}). %% ---- config file wrapper functions ---- -write_config_file(Dir, File, Verify, Write) -> - snmp_config:write_config_file(Dir, File, Verify, Write). - -append_config_file(Dir, File, Verify, Write) -> - snmp_config:append_config_file(Dir, File, Verify, Write). +write_config_file(Dir, File, Order, Check, Write, Conf) -> + snmp_config:write_config_file(Dir, File, Order, Check, Write, Conf). -read_config_file(Dir, File, Verify) -> - snmp_config:read_config_file(Dir, File, Verify). +append_config_file(Dir, File, Order, Check, Write, Conf) -> + snmp_config:append_config_file(Dir, File, Order, Check, Write, Conf). +read_config_file(Dir, File, Order, Check) -> + snmp_config:read_config_file(Dir, File, Order, Check). %% ---- config file utility functions ---- +check_ok(ok) -> + ok; +check_ok({ok, _}) -> + ok. + header() -> {Y,Mo,D} = date(), {H,Mi,S} = time(), - io_lib:format("%% This file was generated by " - "~w (version-~s) ~w-~2.2.0w-~2.2.0w " - "~2.2.0w:~2.2.0w:~2.2.0w\n", - [?MODULE, ?version, Y, Mo, D, H, Mi, S]). - + io_lib:format( + "%% This file was generated by " + "~w (version-~s) ~w-~2.2.0w-~2.2.0w " + "~2.2.0w:~2.2.0w:~2.2.0w\n", + [?MODULE, ?version, Y, Mo, D, H, Mi, S]). error(R) -> throw({error, R}). diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index e938a68ab0..b3500d7293 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -103,8 +103,10 @@ get_agent_mp_model/2 ]). --export([check_manager_config/1, - check_user_config/1, +-export([ + order_manager_config/2, + check_manager_config/2, + check_user_config/1, check_agent_config/1, check_usm_user_config/1]). @@ -2285,8 +2287,8 @@ is_crypto_supported(Func) -> %% end. read_manager_config_file(Dir) -> - Order = fun snmp_conf:no_order/2, - Check = fun (Entry, State) -> {check_manager_config(Entry), State} end, + Order = fun order_manager_config/2, + Check = fun check_manager_config/2, Conf = read_file(Dir, "manager.conf", Order, Check), ?d("read_manager_config_file -> ok: " "~n Conf: ~p", [Conf]), @@ -2309,11 +2311,31 @@ default_manager_config() -> "~n _Reason: ~p", [_Reason]), [] end. - -check_manager_config({address, Addr}) -> - snmp_conf:check_ip(Addr); + +order_manager_config(EntryA, EntryB) -> + snmp_conf:keyorder(1, EntryA, EntryB, [domain]). + +check_manager_config({domain, D}, _Domain) -> + {snmp_conf:check_domain(D), D}; +check_manager_config({address = Tag, Ip}, D) -> + Domain = + case D of + undefined -> + default_transport_domain(); + _ -> + D + end, + {case snmp_conf:check_ip(Domain, Ip) of + ok -> + ok; + {ok, FixedIp} -> + {ok, {Tag, FixedIp}} + end, Domain}; +check_manager_config(Entry, Domain) -> + {check_manager_config(Entry), Domain}. + check_manager_config({port, Port}) -> - snmp_conf:check_integer(Port, {gt, 0}); + snmp_conf:check_port(Port); check_manager_config({engine_id, EngineID}) -> snmp_conf:check_string(EngineID); check_manager_config({max_message_size, Max}) -> diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index ac2b7b7778..68d4aee97d 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -26,8 +26,9 @@ -compile({no_auto_import,[error/1]}). -export([config/0]). --export([write_config_file/4, append_config_file/4, - read_config_file/3, read_config_file/4]). +%%-export([write_config_file/4, append_config_file/4, read_config_file/4]). + +-export([write_config_file/6, append_config_file/6, read_config_file/4]). -export([write_agent_snmp_files/7, write_agent_snmp_files/12, write_agent_snmp_files/6, write_agent_snmp_files/11, @@ -92,9 +93,9 @@ ]). --export_type([void/0, - verify_config_entry_function/0, - verify_config_function/0, +-export_type([void/0, + order_config_entry_function/0, + check_config_entry_function/0, write_config_function/0]). @@ -2467,93 +2468,90 @@ header() -> [?MODULE, ?version, Y, Mo, D, H, Mi, S]). -%% *If* these functions are successfull, they successfully return anything -%% (which is ignored), but they fail with either a throw or an exit or -%% something similar. +%% *If* these functions are successfull, they successfully return +%% (value is ignored), but they fail preferably with +%% throw({error, Reason}). Other exceptions are also handled. -%% Verification of one config entry read from a file --type(verify_config_entry_function() :: - fun((Entry :: term()) -> ok | {error, Reason :: term()})). +%% Sorting order for config entries (see lists:sort/2) +-type(order_config_entry_function() :: + fun((term(), term()) -> boolean())). -%% Verification of config to be written --type(verify_config_function() :: - fun(() -> void())). +%% Check of config entries. Initial State is 'undefined' +-type(check_config_entry_function() :: + fun((Entry :: term(), State :: undefined | term()) -> + {ok | {ok, NewEntry :: term()}, NewState :: term()})). -%% Write config to file (as defined by Fd) --type(write_config_function() :: - fun((Fd :: file:io_device()) -> void())). +%% Write configuration entries to file descriptor Fd +-type(write_config_function() :: + fun((Fd :: file:io_device(), [Entry :: term()]) -> ok)). --spec write_config_file(Dir :: string(), - FileName :: string(), - Verify :: verify_config_function(), - Write :: write_config_function()) -> - ok | {error, Reason :: term()}. +-spec write_config_file( + Dir :: string(), + FileName :: string(), + Order :: order_config_entry_function(), + Check :: check_config_entry_function(), + Write :: write_config_function(), + Entries :: [term()]) -> + ok | {error, term()}. -write_config_file(Dir, FileName, Verify, Write) - when (is_list(Dir) andalso - is_list(FileName) andalso - is_function(Verify) andalso - is_function(Write)) -> - try do_write_config_file(Dir, FileName, Verify, Write) of - ok -> - ok; - Other -> - d("File write of ~s returned: ~p~n", [FileName,Other]) +write_config_file(Dir, FileName, Order, Check, Write, Entries) + when is_list(Dir), is_list(FileName), + is_function(Order), is_function(Check), is_function(Write), + is_list(Entries) -> + try + SortedEntries = lists:sort(Order, Entries), + _ = + lists:foldl( + fun (Entry, State) -> + case Check(Entry, State) of + {ok, NewState} -> + NewState; + {{ok, _}, NewState} -> + NewState + end + end, undefined, SortedEntries), + ok + of + _ -> + case file:open(filename:join(Dir, FileName), [write]) of + {ok, Fd} -> + write_config_file(Dir, FileName, Write, Entries, Fd); + Error -> + Error + end catch - throw:Error -> + Error -> S = erlang:get_stacktrace(), - d("File write of ~s throwed: ~p~n ~p~n", [FileName,Error,S]), + d("File write of ~s throwed: ~p~n ~p~n", + [FileName, Error, S]), Error; - T:E -> + C:E -> S = erlang:get_stacktrace(), d("File write of ~s exception: ~p:~p~n ~p~n", - [FileName,T,E,S]), - {error, - {failed_write, Dir, FileName, - {T, E, erlang:get_stacktrace()}}} - end. - - -do_write_config_file(Dir, FileName, Verify, Write) -> - Verify(), - case file:open(filename:join(Dir, FileName), [write]) of - {ok, Fd} -> - file_write_and_close(Write, Fd, Dir, FileName); - Error -> - Error + [FileName,C,E,S]), + {error, {failed_write, Dir, FileName, {C, E, S}}} end. -append_config_file(Dir, FileName, Verify, Write) - when (is_list(Dir) andalso - is_list(FileName) andalso - is_function(Verify) andalso - is_function(Write)) -> - try - begin - do_append_config_file(Dir, FileName, Verify, Write) - end +write_config_file(Dir, FileName, Write, Entries, Fd) -> + try Write(Fd, Entries) of + ok -> + close_config_file(Dir, FileName, Fd) catch - throw:Error -> - Error; - T:E -> - {error, - {failed_append, Dir, FileName, - {T, E, erlang:get_stacktrace()}}} - end. - -do_append_config_file(Dir, FileName, Verify, Write) -> - Verify(), - case file:open(filename:join(Dir, FileName), [read, write]) of - {ok, Fd} -> - file:position(Fd, eof), - file_write_and_close(Write, Fd, Dir, FileName); Error -> - Error + S = erlang:get_stacktrace(), + d("File write of ~s throwed: ~p~n ~p~n", + [FileName, Error, S]), + close_config_file(Dir, FileName, Fd), + Error; + C:E -> + S = erlang:get_stacktrace(), + d("File write of ~s exception: ~p:~p~n ~p~n", + [FileName,C,E,S]), + close_config_file(Dir, FileName, Fd), + {error, {failed_write, Dir, FileName, {C, E, S}}} end. - -file_write_and_close(Write, Fd, Dir, FileName) -> - ok = Write(Fd), +close_config_file(Dir, FileName, Fd) -> case file:sync(Fd) of ok -> case file:close(Fd) of @@ -2563,23 +2561,83 @@ file_write_and_close(Write, Fd, Dir, FileName) -> {error, {failed_closing, Dir, FileName, Reason}} end; {error, Reason} -> + _ = file:close(Fd), {error, {failed_syncing, Dir, FileName, Reason}} end. -%% XXX remove -read_config_file(Dir, FileName, Verify) -> - read_config_file( - Dir, FileName, fun snmp_conf:no_order/2, - fun (Term, State) -> - {Verify(Term), State} - end). --spec read_config_file(Dir :: string(), - FileName :: string(), - Order :: function(), - Verify :: function()) -> - {ok, Config :: list()} | {error, Reason :: term()}. +-spec append_config_file( + Dir :: string(), + FileName :: string(), + Order :: order_config_entry_function(), + Check :: check_config_entry_function(), + Write :: write_config_function(), + Entries :: [term()]) -> + ok | {error, term()}. + +append_config_file(Dir, FileName, Order, Check, Write, Entries) + when is_list(Dir), is_list(FileName), + is_function(Order), is_function(Check), is_function(Write), + is_list(Entries) -> + case file:open(filename:join(Dir, FileName), [read, write]) of + {ok, Fd} -> + append_config_file( + Dir, FileName, Order, Check, Write, Entries, Fd); + Error -> + Error + end. + +append_config_file(Dir, FileName, Order, Check, Write, Entries, Fd) -> + try + %% Verify the entries together with the file content + LinesInFileR = read_lines(Fd, [], 1), + StartLine = + case LinesInFileR of + [] -> + 1; + [{_, _, EndLine} | _] -> + EndLine + end, + LinesR = prepend_lines(LinesInFileR, Entries, StartLine), + SortedLines = sort_lines(lists:reverse(LinesR), Order), + _ = verify_lines(SortedLines, Check, undefined, []), + %% Append to the file + Write(Fd, Entries) + of + ok -> + close_config_file(Dir, FileName, Fd) + catch + Error -> + S = erlang:get_stacktrace(), + d("File append of ~s throwed: ~p~n ~p~n", + [FileName, Error, S]), + close_config_file(Dir, FileName, Fd), + Error; + C:E -> + S = erlang:get_stacktrace(), + d("File append of ~s exception: ~p:~p~n ~p~n", + [FileName,C,E,S]), + close_config_file(Dir, FileName, Fd), + {error, {failed_append, Dir, FileName, {C, E, S}}} + end. + +%% Fake line numbers, one per entry +prepend_lines(Lines, [], _) -> + Lines; +prepend_lines(Lines, [Entry | Entries], StartLine) -> + EndLine = StartLine + 1, + prepend_lines([{StartLine, Entry, EndLine} | Lines], Entries, EndLine). + + + +-spec read_config_file( + Dir :: string(), + FileName :: string(), + Order :: order_config_entry_function(), + Check :: check_config_entry_function()) -> + {ok, Config :: [Entry :: term()]} | + {error, Reason :: term()}. read_config_file(Dir, FileName, Order, Check) when is_list(Dir), is_list(FileName), @@ -2587,17 +2645,20 @@ read_config_file(Dir, FileName, Order, Check) case file:open(filename:join(Dir, FileName), [read]) of {ok, Fd} -> try - {ok, - verify_lines( - lists:sort( - fun ({_, T1, _}, {_, T2, _}) -> - Order(T1, T2) - end, - read_lines(Fd, [], 1)), - Check, undefined, [])} + Lines = lists:reverse(read_lines(Fd, [], 1)), + SortedLines = sort_lines(Lines, Order), + {ok, verify_lines(SortedLines, Check, undefined, [])} catch Error -> - {error, Error} + S = erlang:get_stacktrace(), + d("File read of ~s throwed: ~p~n ~p~n", + [FileName, Error, S]), + {error, Error}; + T:E -> + S = erlang:get_stacktrace(), + d("File read of ~s exception: ~p:~p~n ~p~n", + [FileName,T,E,S]), + {error, {failed_read, Dir, FileName, {T, E, S}}} after file:close(Fd) end; @@ -2612,7 +2673,7 @@ read_lines(Fd, Acc, StartLine) -> {error, Error, EndLine} -> throw({failed_reading, StartLine, EndLine, Error}); {eof, _EndLine} -> - lists:reverse(Acc) + Acc end. read_and_parse_term(Fd, StartLine) -> @@ -2628,6 +2689,12 @@ read_and_parse_term(Fd, StartLine) -> Other end. +sort_lines(Lines, Order) -> + lists:sort( + fun ({_, T1, _}, {_, T2, _}) -> + Order(T1, T2) + end, Lines). + verify_lines([], _, _, Acc) -> lists:reverse(Acc); verify_lines( @@ -2646,53 +2713,6 @@ verify_lines( end. -%% XXX remove - -%% do_read_config_file(Dir, FileName, Verify) -> -%% case file:open(filename:join(Dir, FileName), [read]) of -%% {ok, Fd} -> -%% Result = read_loop(Fd, [], Verify, 1), -%% file:close(Fd), -%% Result; -%% {error, Reason} -> -%% {error, {Reason, FileName}} -%% end. - -%% read_loop(Fd, Acc, Check, StartLine) -> -%% case read_term(Fd, StartLine) of -%% {ok, Term, EndLine} -> -%% case (catch Check(Term)) of -%% ok -> -%% read_loop(Fd, [Term | Acc], Check, EndLine); -%% {error, Reason} -> -%% {error, {failed_check, StartLine, EndLine, Reason}}; -%% Error -> -%% {error, {failed_check, StartLine, EndLine, Error}} -%% end; -%% {error, EndLine, Error} -> -%% {error, {failed_reading, StartLine, EndLine, Error}}; -%% eof -> -%% {ok, lists:reverse(Acc)} -%% end. - -%% read_term(Fd, StartLine) -> -%% case io:request(Fd, {get_until, "", erl_scan, tokens, [StartLine]}) of -%% {ok, Tokens, EndLine} -> -%% case erl_parse:parse_term(Tokens) of -%% {ok, Term} -> -%% {ok, Term, EndLine}; -%% {error, {Line, erl_parse, Error}} -> -%% {error, Line, {parse_error, Error}} -%% end; -%% {error, E, EndLine} -> -%% {error, EndLine, E}; -%% {eof, _EndLine} -> -%% eof; -%% Other -> -%% Other -%% end. - - agent_snmp_mk_secret(Alg, Passwd, EngineID) -> snmp_usm:passwd2localized_key(Alg, Passwd, EngineID). -- cgit v1.2.3 From 4dba07b435696393adbf582933f9b539be48b943 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 28 May 2014 16:26:34 +0200 Subject: Use IPv6 config in manager --- lib/snmp/src/manager/snmpm_conf.erl | 13 +- lib/snmp/src/manager/snmpm_config.erl | 28 ++- lib/snmp/src/manager/snmpm_mpd.erl | 22 +- lib/snmp/src/manager/snmpm_net_if.erl | 271 ++++++++++++-------- lib/snmp/src/manager/snmpm_net_if_filter.erl | 16 +- lib/snmp/src/manager/snmpm_server.erl | 362 +++++++++++++-------------- lib/snmp/src/misc/snmp_conf.erl | 2 + lib/snmp/src/misc/snmp_config.erl | 17 +- lib/snmp/test/snmp_manager_test.erl | 105 +++++--- 9 files changed, 481 insertions(+), 355 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl index d2f9ba9c26..ed4cfd749e 100644 --- a/lib/snmp/src/manager/snmpm_conf.erl +++ b/lib/snmp/src/manager/snmpm_conf.erl @@ -110,14 +110,15 @@ write_manager_conf(Fd, [H|T]) -> do_write_manager_conf(Fd, H), write_manager_conf(Fd, T). -do_write_manager_conf(Fd, {address = Tag, Val}) -> +do_write_manager_conf(Fd, {Tag, Val}) + when Tag =:= domain; + Tag =:= address; + Tag =:= port; + Tag =:= max_message_size -> io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); -do_write_manager_conf(Fd, {port = Tag, Val} ) -> - io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); -do_write_manager_conf(Fd, {engine_id = Tag, Val} ) -> +do_write_manager_conf(Fd, {Tag, Val}) + when Tag =:= engine_id -> io:format(Fd, "{~w, \"~s\"}.~n", [Tag, Val]); -do_write_manager_conf(Fd, {max_message_size = Tag, Val} ) -> - io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); do_write_manager_conf(_Fd, Crap) -> error({bad_manager_config, Crap}). diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index b3500d7293..5ebd3a0662 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -2297,9 +2297,33 @@ read_manager_config_file(Dir) -> %% If the address is not possible to determine %% that way, then we give up... verify_mandatory(Conf, [port,engine_id,max_message_size]), - ensure_config(default_manager_config(), Conf). - + default_manager_config(Conf). +default_manager_config(Conf) -> + %% Ensure address of right family + case lists:keyfind(address, 1, Conf) of + false -> + Domain = + case lists:keyfind(domain, 1, Conf) of + false -> + default_transport_domain(); + {_, D} -> + D + end, + Family = snmp_conf:tdomain_to_family(Domain), + {ok, HostName} = inet:gethostname(), + case inet:getaddr(HostName, Family) of + {ok, Address} -> + [{address, Address} | Conf]; + {error, _Reason} -> + ?d("default_manager_config -> " + "failed getting ~w address for ~s:~n" + " _Reason: ~p", [Family, HostName, _Reason]), + Conf + end; + _ -> + Conf + end. default_manager_config() -> {ok, HostName} = inet:gethostname(), diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index 27f0336bc1..521c496adb 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -92,10 +92,10 @@ reset(#state{v3 = V3}) -> %% Purpose: This is the main Message Dispatching function. (see %% section 4.2.1 in rfc2272) %%----------------------------------------------------------------- -process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> - process_msg(Msg, Domain, {Addr, Port}, State, NoteStore, Logger). +process_msg(Msg, Domain, Ip, Port, State, NoteStore, Logger) -> + process_msg(Msg, Domain, {Ip, Port}, State, NoteStore, Logger). -process_msg(Msg, Domain, Address, State, NoteStore, Logger) -> +process_msg(Msg, Domain, Addr, State, NoteStore, Logger) -> inc(snmpInPkts), case (catch snmp_pdus:dec_message_only(binary_to_list(Msg))) of @@ -105,7 +105,7 @@ process_msg(Msg, Domain, Address, State, NoteStore, Logger) -> when State#state.v1 =:= true -> HS = ?empty_msg_size + length(Community), process_v1_v2c_msg( - 'version-1', NoteStore, Msg, Domain, Address, + 'version-1', NoteStore, Msg, Domain, Addr, Community, Data, HS, Logger); %% Version 2 @@ -113,7 +113,7 @@ process_msg(Msg, Domain, Address, State, NoteStore, Logger) -> when State#state.v2c =:= true -> HS = ?empty_msg_size + length(Community), process_v1_v2c_msg( - 'version-2', NoteStore, Msg, Domain, Address, + 'version-2', NoteStore, Msg, Domain, Addr, Community, Data, HS, Logger); %% Version 3 @@ -124,7 +124,7 @@ process_msg(Msg, Domain, Address, State, NoteStore, Logger) -> "~n msgFlags: ~p" "~n msgSecModel: ~p", [H#v3_hdr.msgID,H#v3_hdr.msgFlags,H#v3_hdr.msgSecurityModel]), - process_v3_msg(NoteStore, Msg, H, Data, Address, Logger); + process_v3_msg(NoteStore, Msg, H, Data, Addr, Logger); %% Crap {'EXIT', {bad_version, Vsn}} -> @@ -151,26 +151,26 @@ process_msg(Msg, Domain, Address, State, NoteStore, Logger) -> %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- process_v1_v2c_msg( - Vsn, _NoteStore, Msg, Domain, Address, Community, Data, HS, Log) -> + Vsn, _NoteStore, Msg, Domain, Addr, Community, Data, HS, Log) -> ?vdebug("process_v1_v2c_msg -> entry with" "~n Vsn: ~p" "~n Domain: ~p" - "~n Address: ~p" + "~n Addr: ~p" "~n Community: ~p" - "~n HS: ~p", [Vsn, Domain, Address, Community, HS]), + "~n HS: ~p", [Vsn, Domain, Addr, Community, HS]), {TDomain, TAddress} = try {snmp_conf:mk_tdomain(Domain), - snmp_conf:mk_taddress(Domain, Address)} + snmp_conf:mk_taddress(Domain, Addr)} catch throw:{error, TReason} -> throw({discarded, {badarg, Domain, TReason}}) end, Max = get_max_message_size(), - AgentMax = get_agent_max_message_size(Address), + AgentMax = get_agent_max_message_size(Addr), PduMS = pdu_ms(Max, AgentMax, HS), ?vtrace("process_v1_v2c_msg -> PduMS: ~p", [PduMS]), diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index d7f17e0b7f..860b0b83dd 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -55,11 +55,12 @@ %% -define(VMODULE,"NET_IF"). -include("snmp_verbosity.hrl"). --record(state, +-record(state, { server, note_store, - sock, + domain, + sock, mpd_state, log, irb = auto, % auto | {user, integer()} @@ -99,22 +100,22 @@ start_link(Server, NoteStore) -> stop(Pid) -> call(Pid, stop). -send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort) -> - send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort, ?DEFAULT_EXTRA_INFO). +send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port) -> + send_pdu( + Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ?DEFAULT_EXTRA_INFO). -send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo) - when is_record(Pdu, pdu), is_atom(Domain) -> +send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ExtraInfo) + when is_record(Pdu, pdu) -> ?d("send_pdu -> entry with~n" - " Pid: ~p~n" - " Pdu: ~p~n" - " Vsn: ~p~n" - " MsgData: ~p~n" - " Domain: ~p~n" - " Address: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Address]), - cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}); -send_pdu(Pid, Pdu, Vsn, MsgData, Ip, Port, ExtraInfo) -> - Domain = snmpm_config:default_transport_domain(), - send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo). + " Pid: ~p~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain/IP: ~p~n" + " Addr/Port: ~p", + [Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port]), + {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port), + cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}). send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) -> send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo). @@ -122,8 +123,9 @@ send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) -> note_store(Pid, NoteStore) -> call(Pid, {note_store, NoteStore}). -inform_response(Pid, Ref, Domain, Address) -> - cast(Pid, {inform_response, Ref, Domain, Address}). +inform_response(Pid, Ref, Domain_or_Ip, Addr_or_Port) -> + {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port), + cast(Pid, {inform_response, Ref, Domain, Addr}). info(Pid) -> call(Pid, info). @@ -200,7 +202,14 @@ do_init(Server, NoteStore) -> BindTo = get_opt(Opts, bind_to, false), NoReuse = get_opt(Opts, no_reuse, false), {ok, Port} = snmpm_config:system_info(port), - {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, BindTo, NoReuse), + Domain = + case snmpm_config:system_info(domain) of + {ok, D} -> + D; + _ -> + snmpm_config:default_transport_domain() + end, + {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, Domain, BindTo, NoReuse), %% Flow control -- FilterOpts = get_opt(Opts, filter, []), @@ -218,6 +227,7 @@ do_init(Server, NoteStore) -> State = #state{server = Server, note_store = NoteStore, mpd_state = MpdState, + domain = Domain, sock = Sock, log = Log, irb = IRB, @@ -228,18 +238,23 @@ do_init(Server, NoteStore) -> %% Open port -do_open_port(Port, SendSz, RecvSz, BindTo, NoReuse) -> - ?vtrace("do_open_port -> entry with" - "~n Port: ~p" - "~n SendSz: ~p" - "~n RecvSz: ~p" - "~n BindTo: ~p" - "~n NoReuse: ~p", [Port, SendSz, RecvSz, BindTo, NoReuse]), +do_open_port(Port, SendSz, RecvSz, Domain, BindTo, NoReuse) -> + ?vtrace("do_open_port -> entry with~n" + " Port: ~p~n" + " SendSz: ~p~n" + " RecvSz: ~p~n" + " Domain: ~p~n" + " BindTo: ~p~n" + " NoReuse: ~p", + [Port, SendSz, RecvSz, Domain, BindTo, NoReuse]), IpOpts1 = bind_to(BindTo), IpOpts2 = no_reuse(NoReuse), IpOpts3 = recbuf(RecvSz), IpOpts4 = sndbuf(SendSz), - IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4], + IpOpts = + [binary, + snmp_conf:tdomain_to_family(Domain) | + IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4], OpenRes = case init:get_argument(snmpm_fd) of {ok, [[FdStr]]} -> @@ -387,24 +402,24 @@ handle_call(Req, From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}, +handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}, State) -> ?vlog("received send_pdu message with~n" " Pdu: ~p~n" " Vsn: ~p~n" " MsgData: ~p~n" " Domain: ~p~n" - " Address: ~p", [Pdu, Vsn, MsgData, Domain, Address]), + " Addr : ~p", [Pdu, Vsn, MsgData, Domain, Addr]), maybe_process_extra_info(ExtraInfo), - maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State), + maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State), {noreply, State}; -handle_cast({inform_response, Ref, Domain, Address}, State) -> +handle_cast({inform_response, Ref, Domain, Addr}, State) -> ?vlog("received inform_response message with~n" - " Ref: ~p~n" - " Domain: ~p~n" - " Address: ~p", [Ref, Domain, Address]), - handle_inform_response(Ref, Domain, Address, State), + " Ref: ~p~n" + " Domain: ~p~n" + " Addr: ~p", [Ref, Domain, Addr]), + handle_inform_response(Ref, Domain, Addr, State), {noreply, State}; handle_cast(filter_reset, State) -> @@ -423,9 +438,10 @@ handle_cast(Msg, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> +handle_info( + {udp, Sock, Ip, Port, Bytes}, + #state{sock = Sock, domain = Domain} = State) -> ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]), - Domain = snmpm_config:default_transport_domain(), maybe_handle_recv_msg(Domain, {Ip, Port}, Bytes, State), {noreply, State}; @@ -533,48 +549,49 @@ code_change(_Vsn, State, _Extra) -> %%%------------------------------------------------------------------- maybe_handle_recv_msg( - Domain, Address, Bytes, #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv(Domain, Address)) of + Domain, Addr, Bytes, + #state{filter = FilterMod, domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_recv(Arg1, Arg2)) of false -> %% Drop the received packet inc(netIfMsgInDrops), ok; _ -> - handle_recv_msg(Domain, Address, Bytes, State) + handle_recv_msg(Domain, Addr, Bytes, State) end. -handle_recv_msg(Domain, Address, Bytes, #state{server = Pid}) +handle_recv_msg(Domain, Addr, Bytes, #state{server = Pid}) when is_binary(Bytes) andalso (size(Bytes) =:= 0) -> - Pid ! {snmp_error, {empty_message, Domain, Address}, Domain, Address}, + Pid ! {snmp_error, {empty_message, Domain, Addr}, Domain, Addr}, ok; handle_recv_msg( - Domain, Address, Bytes, + Domain, Addr, Bytes, #state{server = Pid, note_store = NoteStore, mpd_state = MpdState, - sock = Sock, log = Log} = State) -> - Logger = logger(Log, read, Domain, Address), - case (catch snmpm_mpd:process_msg(Bytes, Domain, Address, + Logger = logger(Log, read, Domain, Addr), + case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, MpdState, NoteStore, Logger)) of {ok, Vsn, Pdu, MS, ACM} -> - maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, MS, ACM, + maybe_handle_recv_pdu(Domain, Addr, Vsn, Pdu, MS, ACM, Logger, State); {discarded, Reason, Report} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Domain, Address}, - maybe_udp_send(State#state.filter, Sock, Domain, Address, Report), + Pid ! {snmp_error, ErrorInfo, Domain, Addr}, + maybe_udp_send(Domain, Addr, Report, State), ok; {discarded, Reason} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Domain, Address}, + Pid ! {snmp_error, ErrorInfo, Domain, Addr}, ok; Error -> @@ -585,92 +602,93 @@ handle_recv_msg( maybe_handle_recv_pdu( - Domain, Address, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger, - #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv_pdu(Domain, Address, Type)) of + Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger, + #state{filter = FilterMod, domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of false -> inc(netIfPduInDrops), ok; _ -> handle_recv_pdu( - Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) + Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) end; maybe_handle_recv_pdu( - Domain, Address, Vsn, Trap, PduMS, ACM, Logger, - #state{filter = FilterMod} = State) + Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, + #state{filter = FilterMod, domain = ManagerDomain} = State) when is_record(Trap, trappdu) -> - case (catch FilterMod:accept_recv_pdu(Domain, Address, trappdu)) of + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of false -> inc(netIfPduInDrops), ok; _ -> handle_recv_pdu( - Domain, Address, Vsn, Trap, PduMS, ACM, Logger, State) + Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, State) end; maybe_handle_recv_pdu( - Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) -> - handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State). + Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) -> + handle_recv_pdu(Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State). handle_recv_pdu( - Domain, Address, Vsn, + Domain, Addr, Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger, #state{server = Pid, irb = IRB} = State) -> handle_inform_request( - IRB, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State); + IRB, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State); handle_recv_pdu( - Domain, Address, _Vsn, + Domain, Addr, _Vsn, #pdu{type = report} = Pdu, _PduMS, ok, _Logger, #state{server = Pid} = _State) -> ?vtrace("received report - ok", []), - Pid ! {snmp_report, {ok, Pdu}, Domain, Address}; + Pid ! {snmp_report, {ok, Pdu}, Domain, Addr}; handle_recv_pdu( - Domain, Address, _Vsn, + Domain, Addr, _Vsn, #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger, #state{server = Pid} = _State) -> ?vtrace("received report - error", []), - Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Address}; + Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Addr}; handle_recv_pdu( - Domain, Address, _Vsn, + Domain, Addr, _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger, #state{server = Pid} = _State) -> ?vtrace("received snmpv2-trap", []), - Pid ! {snmp_trap, Pdu, Domain, Address}; + Pid ! {snmp_trap, Pdu, Domain, Addr}; handle_recv_pdu( - Domain, Address, _Vsn, Trap, _PduMS, _ACM, _Logger, + Domain, Addr, _Vsn, Trap, _PduMS, _ACM, _Logger, #state{server = Pid} = _State) when is_record(Trap, trappdu) -> ?vtrace("received trappdu", []), - Pid ! {snmp_trap, Trap, Domain, Address}; + Pid ! {snmp_trap, Trap, Domain, Addr}; handle_recv_pdu( - Domain, Address, _Vsn, Pdu, _PduMS, _ACM, _Logger, + Domain, Addr, _Vsn, Pdu, _PduMS, _ACM, _Logger, #state{server = Pid} = _State) when is_record(Pdu, pdu) -> ?vtrace("received pdu", []), - Pid ! {snmp_pdu, Pdu, Domain, Address}; + Pid ! {snmp_pdu, Pdu, Domain, Addr}; handle_recv_pdu( - _Domain, _Address, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> + _Domain, _Addr, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> ?vlog("received unexpected pdu: " "~n Pdu: ~p" "~n ACM: ~p", [Pdu, ACM]). handle_inform_request( - auto, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State) -> + auto, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State) -> ?vtrace("received inform-request (true)", []), - Pid ! {snmp_inform, ignore, Pdu, Domain, Address}, + Pid ! {snmp_inform, ignore, Pdu, Domain, Addr}, RePdu = make_response_pdu(Pdu), - maybe_send_inform_response( - RePdu, Vsn, ACM, Domain, Address, Logger, State); + maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Addr, Logger, State); handle_inform_request( {user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, - ACM, Domain, Address, _Logger, _State) -> + ACM, Domain, Addr, _Logger, _State) -> ?vtrace("received inform-request (false)", []), - Pid ! {snmp_inform, ReqId, Pdu, Domain, Address}, + Pid ! {snmp_inform, ReqId, Pdu, Domain, Addr}, %% Before we go any further, we need to check that we have not %% already received this message (possible resend). - Key = {ReqId, Domain, Address}, + Key = {ReqId, Domain, Addr}, case ets:lookup(snmpm_inform_request_table, Key) of [_] -> %% OK, we already know about this. We assume this @@ -684,26 +702,28 @@ handle_inform_request( ets:insert(snmpm_inform_request_table, Rec) end. -handle_inform_response(Ref, Domain, Address, State) -> - Key = {Ref, Domain, Address}, +handle_inform_response(Ref, Domain, Addr, State) -> + Key = {Ref, Domain, Addr}, case ets:lookup(snmpm_inform_request_table, Key) of [{Key, _, {Vsn, ACM, RePdu}}] -> - Logger = logger(State#state.log, read, Domain, Address), + Logger = logger(State#state.log, read, Domain, Addr), ets:delete(snmpm_inform_request_table, Key), - maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, - Logger, State); + maybe_send_inform_response( + RePdu, Vsn, ACM, Domain, Addr, Logger, State); [] -> %% Already acknowledged, or the user was to slow to reply... ok end, ok. -maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, - #state{server = Pid, - sock = Sock, - filter = FilterMod}) -> +maybe_send_inform_response( + RePdu, Vsn, ACM, Domain, Addr, Logger, + #state{server = Pid, + filter = FilterMod, + domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), case (catch FilterMod:accept_send_pdu( - Domain, Address, pdu_type_of(RePdu))) + Arg1, Arg2, pdu_type_of(RePdu))) of false -> inc(netIfPduOutDrops), @@ -711,13 +731,13 @@ maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, _ -> case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of {ok, Msg} -> - maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); + maybe_udp_send(Domain, Addr, Msg, State); {discarded, Reason} -> ?vlog("failed generating response message:" "~n Reason: ~p", [Reason]), ReqId = RePdu#pdu.request_id, ErrorInfo = {failed_generating_response, {RePdu, Reason}}, - Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Address}, + Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr}, ok end end. @@ -752,28 +772,29 @@ irgc_stop(Ref) -> (catch erlang:cancel_timer(Ref)). -maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, - #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_send_pdu(Domain, Address, pdu_type_of(Pdu))) of +maybe_handle_send_pdu( + Pdu, Vsn, MsgData, Domain, Addr, + #state{filter = FilterMod, domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; _ -> - handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State) + handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State) end. -handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, - #state{server = Pid, - note_store = NoteStore, - sock = Sock, - log = Log, - filter = FilterMod}) -> - Logger = logger(Log, write, Domain, Address), - case (catch snmpm_mpd:generate_msg(Vsn, NoteStore, - Pdu, MsgData, Logger)) of +handle_send_pdu( + Pdu, Vsn, MsgData, Domain, Addr, + #state{server = Pid, + note_store = NoteStore, + log = Log} = State) -> + Logger = logger(Log, write, Domain, Addr), + case (catch snmpm_mpd:generate_msg( + Vsn, NoteStore, Pdu, MsgData, Logger)) of {ok, Msg} -> ?vtrace("handle_send_pdu -> message generated", []), - maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); + maybe_udp_send(Domain, Addr, Msg, State); {discarded, Reason} -> ?vlog("PDU not sent: " "~n PDU: ~p" @@ -783,12 +804,18 @@ handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, end. -maybe_udp_send(FilterMod, Sock, Domain, {Ip, Port} = Address, Msg) -> - case (catch FilterMod:accept_send(Domain, Address)) of +maybe_udp_send( + Domain, Addr, Msg, + #state{sock = Sock, filter = FilterMod, domain = ManagerDomain}) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_send(Arg1, Arg2)) of false -> inc(netIfMsgOutDrops), ok; _ -> + %% XXX There should be some kind of lookup of socket + %% from transport domain here + {Ip, Port} = Addr, udp_send(Sock, Ip, Port, Msg) end. @@ -998,6 +1025,26 @@ handle_set_log_type(State, _NewType) -> {State, {error, not_enabled}}. +%% If the manager uses legacy snmpUDPDomain e.g has not set +%% {domain, _}, then make sure snmpm_network_interface_filter +%% gets legacy arguments to not break backwards compatibility. +%% +fix_filter_address(snmpUDPDomain, {Domain, Addr}) + when Domain =:= snmpUDPDomain; + Domain =:= transportDomainUdpIpv4 -> + Addr; +fix_filter_address(_ManagerDomain, {Domain, _} = Address) + when is_atom(Domain) -> + Address; +fix_filter_address(snmpUDPDomain, {_, Port} = Addr) + when is_integer(Port) -> + Addr. + +address(Domain, Addr) when is_atom(Domain) -> + {Domain, Addr}; +address(Ip, Port) when is_integer(Port) -> + {snmpm_config:default_transport_domain(), {Ip, Port}}. + %% ------------------------------------------------------------------- make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) -> @@ -1038,15 +1085,17 @@ t() -> %% ------------------------------------------------------------------- -logger(undefined, _Type, _Domain, _Address) -> +logger(undefined, _Type, _Domain, _Addr) -> fun(_) -> ok end; -logger({Log, Types}, Type, Domain, Address) -> +logger({Log, Types}, Type, Domain, Addr) -> case lists:member(Type, Types) of true -> + AddrString = + iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})), fun(Msg) -> - snmp_log:log(Log, Msg, Domain, Address) + snmp_log:log(Log, Msg, AddrString) end; false -> fun(_) -> diff --git a/lib/snmp/src/manager/snmpm_net_if_filter.erl b/lib/snmp/src/manager/snmpm_net_if_filter.erl index 54b87a772a..d96ae5c145 100644 --- a/lib/snmp/src/manager/snmpm_net_if_filter.erl +++ b/lib/snmp/src/manager/snmpm_net_if_filter.erl @@ -30,10 +30,10 @@ accept_recv(Domain, _Address) when is_atom(Domain) -> " Domain: ~p~n" " Address: ~p", [Domain, _Address]), true; -accept_recv(_Addr, _Port) -> +accept_recv(_Addr, Port) when is_integer(Port) -> ?d("accept_recv -> entry with~n" " Addr: ~p~n" - " Port: ~p", [_Addr, _Port]), + " Port: ~p", [_Addr, Port]), true. accept_send(Domain, _Address) when is_atom(Domain) -> @@ -41,10 +41,10 @@ accept_send(Domain, _Address) when is_atom(Domain) -> " Domain: ~p~n" " Address: ~p", [Domain, _Address]), true; -accept_send(_Addr, _Port) -> +accept_send(_Addr, Port) when is_integer(Port) -> ?d("accept_send -> entry with~n" " Addr: ~p~n" - " Port: ~p", [_Addr, _Port]), + " Port: ~p", [_Addr, Port]), true. accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> @@ -53,11 +53,11 @@ accept_recv_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> " Address: ~p~n" " PduType: ~p", [Domain, _Address, _PduType]), true; -accept_recv_pdu(_Addr, _Port, _PduType) -> +accept_recv_pdu(_Addr, Port, _PduType) when is_integer(Port) -> ?d("accept_recv_pdu -> entry with~n" " Addr: ~p~n" " Port: ~p~n" - " PduType: ~p", [_Addr, _Port, _PduType]), + " PduType: ~p", [_Addr, Port, _PduType]), true. accept_send_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> @@ -66,10 +66,10 @@ accept_send_pdu(Domain, _Address, _PduType) when is_atom(Domain) -> " Address: ~p~n" " PduType: ~p", [Domain, _Address, _PduType]), true; -accept_send_pdu(_Addr, _Port, _PduType) -> +accept_send_pdu(_Addr, Port, _PduType) when is_integer(Port) -> ?d("accept_send_pdu -> entry with~n" " Addr: ~p~n" " Port: ~p~n" - " PduType: ~p", [_Addr, _Port, _PduType]), + " PduType: ~p", [_Addr, Port, _PduType]), true. diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl index b3389ef96c..ece5dad082 100644 --- a/lib/snmp/src/manager/snmpm_server.erl +++ b/lib/snmp/src/manager/snmpm_server.erl @@ -1032,14 +1032,14 @@ handle_info({snmp_error, Pdu, Reason}, State) -> handle_snmp_error(Pdu, Reason, State), {noreply, State}; -handle_info({snmp_error, Reason, Domain, Address}, State) -> +handle_info({snmp_error, Reason, Domain, Addr}, State) -> ?vlog("received snmp_error message", []), - handle_snmp_error(Domain, Address, -1, Reason, State), + handle_snmp_error(Domain, Addr, -1, Reason, State), {noreply, State}; -handle_info({snmp_error, ReqId, Reason, Domain, Address}, State) -> +handle_info({snmp_error, ReqId, Reason, Domain, Addr}, State) -> ?vlog("received snmp_error message", []), - handle_snmp_error(Domain, Address, ReqId, Reason, State), + handle_snmp_error(Domain, Addr, ReqId, Reason, State), {noreply, State}; %% handle_info({snmp_error, ReqId, Pdu, Reason, Addr, Port}, State) -> @@ -1048,30 +1048,30 @@ handle_info({snmp_error, ReqId, Reason, Domain, Address}, State) -> %% {noreply, State}; -handle_info({snmp_pdu, Pdu, Domain, Address}, State) -> +handle_info({snmp_pdu, Pdu, Domain, Addr}, State) -> ?vlog("received snmp_pdu message", []), - handle_snmp_pdu(Pdu, Domain, Address, State), + handle_snmp_pdu(Pdu, Domain, Addr, State), {noreply, State}; -handle_info({snmp_trap, Trap, Domain, Address}, State) -> +handle_info({snmp_trap, Trap, Domain, Addr}, State) -> ?vlog("received snmp_trap message", []), - handle_snmp_trap(Trap, Domain, Address, State), + handle_snmp_trap(Trap, Domain, Addr, State), {noreply, State}; -handle_info({snmp_inform, Ref, Pdu, Domain, Address}, State) -> +handle_info({snmp_inform, Ref, Pdu, Domain, Addr}, State) -> ?vlog("received snmp_inform message", []), - handle_snmp_inform(Ref, Pdu, Domain, Address, State), + handle_snmp_inform(Ref, Pdu, Domain, Addr, State), {noreply, State}; -handle_info({snmp_report, {ok, Pdu}, Domain, Address}, State) -> - handle_snmp_report(Pdu, Domain, Address, State), +handle_info({snmp_report, {ok, Pdu}, Domain, Addr}, State) -> + handle_snmp_report(Pdu, Domain, Addr, State), {noreply, State}; -handle_info({snmp_report, {error, ReqId, Info, Pdu}, Domain, Address}, State) -> - handle_snmp_report(ReqId, Pdu, Info, Domain, Address, State), +handle_info({snmp_report, {error, ReqId, Info, Pdu}, Domain, Addr}, State) -> + handle_snmp_report(ReqId, Pdu, Info, Domain, Addr, State), {noreply, State}; @@ -1175,11 +1175,11 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> "~n From: ~p", [Pid, UserId, TargetName, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_sync_get -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_request(Oids, Vsn, MsgData, - Domain, Address, + Domain, Addr, Extra, State), ?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1192,7 +1192,7 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = get, data = MsgData, ref = Ref, @@ -1228,11 +1228,11 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, "~n From: ~p", [Pid, UserId, TargetName, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Domain, Address, + Domain, Addr, Extra, State), ?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1245,7 +1245,7 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = get_next, data = MsgData, ref = Ref, @@ -1287,11 +1287,11 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, "~n From: ~p", [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_bulk_request(Oids, Vsn, MsgData, - Domain, Address, + Domain, Addr, NonRep, MaxRep, Extra, State), ?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1304,7 +1304,7 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = get_bulk, data = MsgData, ref = Ref, @@ -1342,11 +1342,11 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> "~n From: ~p", [Pid, UserId, TargetName, VarsAndVals, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_sync_set -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Domain, Address, + Domain, Addr, Extra, State), ?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1359,7 +1359,7 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = set, data = MsgData, ref = Ref, @@ -1395,11 +1395,11 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_async_get -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_request(Oids, Vsn, MsgData, - Domain, Address, + Domain, Addr, Extra, State), ?vdebug("handle_async_get -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_TIMEOUT(SendOpts), @@ -1408,7 +1408,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = get, data = MsgData, expire = t() + Expire}, @@ -1444,11 +1444,11 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_async_get_next -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Domain, Address, + Domain, Addr, Extra, State), ?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts), @@ -1457,7 +1457,7 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = get_next, data = MsgData, expire = t() + Expire}, @@ -1500,11 +1500,11 @@ handle_async_get_bulk(Pid, "~n SendOpts: ~p", [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_bulk_request(Oids, Vsn, MsgData, - Domain, Address, + Domain, Addr, NonRep, MaxRep, Extra, State), ?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts), @@ -1513,7 +1513,7 @@ handle_async_get_bulk(Pid, reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = get_bulk, data = MsgData, expire = t() + Expire}, @@ -1548,11 +1548,11 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, VarsAndVals, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Domain, Address, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Vsn, MsgData} -> ?vtrace("handle_async_set -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Domain, Address, + Domain, Addr, Extra, State), ?vdebug("handle_async_set -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_SET_TIMEOUT(SendOpts), @@ -1561,7 +1561,7 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> reg_type = RegType, target = TargetName, domain = Domain, - address = Address, + address = Addr, type = set, data = MsgData, expire = t() + Expire}, @@ -1799,15 +1799,15 @@ handle_snmp_error(CrapError, Reason, _State) -> "~n~p~n~p", [CrapError, Reason]), ok. -handle_snmp_error(Domain, Address, ReqId, Reason, State) -> +handle_snmp_error(Domain, Addr, ReqId, Reason, State) -> ?vtrace("handle_snmp_error -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" + " Addr: ~p~n" " ReqId: ~p~n" - " Reason: ~p", [Domain, Address, ReqId, Reason]), + " Reason: ~p", [Domain, Addr, ReqId, Reason]), - case snmpm_config:get_agent_user_id(Domain, Address) of + case snmpm_config:get_agent_user_id(Domain, Addr) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> @@ -1822,7 +1822,7 @@ handle_snmp_error(Domain, Address, ReqId, Reason, State) -> error_msg("failed retreiving the default user " "info handling snmp error " "<~p,~p>: ~n~w~n~w", - [Domain, Address, ReqId, Reason]) + [Domain, Addr, ReqId, Reason]) end end; _Error -> @@ -1834,7 +1834,7 @@ handle_snmp_error(Domain, Address, ReqId, Reason, State) -> error_msg("failed retreiving the default user " "info handling snmp error " "<~p,~p>: ~n~w~n~w", - [Domain, Address, ReqId, Reason]) + [Domain, Addr, ReqId, Reason]) end end. @@ -1858,12 +1858,12 @@ handle_error(_UserId, Mod, Reason, ReqId, Data, _State) -> handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, - Domain, Address, State) -> + Domain, Addr, State) -> ?vtrace("handle_snmp_pdu(get-response) -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" - " Pdu: ~p", [Domain, Address, Pdu]), + " Addr: ~p~n" + " Pdu: ~p", [Domain, Addr, Pdu]), case ets:lookup(snmpm_request_table, ReqId) of @@ -1895,7 +1895,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, {ok, UserMod, UserData} -> handle_pdu( UserId, UserMod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, ReqId, SnmpResponse, UserData, State), maybe_delete(Disco, ReqId); _Error -> @@ -1906,14 +1906,14 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, {ok, DefUserId, DefMod, DefData} -> handle_pdu( DefUserId, DefMod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, ReqId, SnmpResponse, DefData, State), maybe_delete(Disco, ReqId); Error -> error_msg("failed retreiving the default user " "info handling pdu from " "~p <~p,~p>: ~n~w~n~w", - [Target, Domain, Address, Error, Pdu]) + [Target, Domain, Addr, Error, Pdu]) end end; @@ -1967,7 +1967,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, varbinds = Varbinds} = Pdu, Varbinds2 = fix_vbs_BITS(Varbinds), SnmpInfo = {EStatus, EIndex, Varbinds2}, - case snmpm_config:get_agent_user_id(Domain, Address) of + case snmpm_config:get_agent_user_id(Domain, Addr) of {ok, UserId} -> %% A very late reply or a reply to a request %% that has been cancelled. @@ -1992,7 +1992,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, "user info handling (old) " "pdu from " "<~p,~p>: ~n~w~n~w", - [Domain, Address, Error, Pdu]) + [Domain, Addr, Error, Pdu]) end end; @@ -2011,7 +2011,7 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, {ok, DefUserId, DefMod, DefData} -> handle_agent( DefUserId, DefMod, - Domain, Address, + Domain, Addr, pdu, ignore, SnmpInfo, DefData, State); Error -> @@ -2019,19 +2019,19 @@ handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, "info handling (old) pdu when no user " "found from " "<~p,~p>: ~n~w~n~w", - [Domain, Address, Error, Pdu]) + [Domain, Addr, Error, Pdu]) end end end; -handle_snmp_pdu(CrapPdu, Domain, Address, _State) -> +handle_snmp_pdu(CrapPdu, Domain, Addr, _State) -> error_msg("received crap (snmp) Pdu from ~w:~w =>" - "~p", [Domain, Address, CrapPdu]), + "~p", [Domain, Addr, CrapPdu]), ok. handle_pdu( - _UserId, Mod, target_name = _RegType, TargetName, _Domain, _Address, + _UserId, Mod, target_name = _RegType, TargetName, _Domain, _Addr, ReqId, SnmpResponse, Data, _State) -> ?vtrace("handle_pdu(target_name) -> entry when" "~n Mod: ~p", [Mod]), @@ -2049,37 +2049,37 @@ handle_pdu( handle_callback(F), ok; handle_pdu( - _UserId, Mod, addr_port = _RegType, _TargetName, _Domain, Address, + _UserId, Mod, addr_port = _RegType, _TargetName, _Domain, Addr, ReqId, SnmpResponse, Data, _State) -> ?vtrace("handle_pdu(addr_port) -> entry when" "~n Mod: ~p", [Mod]), F = fun() -> - {Ip, Port} = Address, + {Ip, Port} = Addr, (catch Mod:handle_pdu(Ip, Port, ReqId, SnmpResponse, Data)) end, handle_callback(F), ok. -handle_agent(UserId, Mod, Domain, Address, Type, Ref, SnmpInfo, Data, State) -> +handle_agent(UserId, Mod, Domain, Addr, Type, Ref, SnmpInfo, Data, State) -> ?vtrace("handle_agent -> entry when" "~n UserId: ~p" "~n Type: ~p" "~n Mod: ~p", [UserId, Type, Mod]), F = fun() -> - do_handle_agent(UserId, Mod, Domain, Address, + do_handle_agent(UserId, Mod, Domain, Addr, Type, Ref, SnmpInfo, Data, State) end, handle_callback(F), ok. do_handle_agent(DefUserId, DefMod, - Domain, Address, + Domain, Addr, Type, Ref, SnmpInfo, DefData, State) -> ?vdebug("do_handle_agent -> entry when" "~n DefUserId: ~p", [DefUserId]), - try DefMod:handle_agent(Domain, Address, Type, SnmpInfo, DefData) of + try DefMod:handle_agent(Domain, Addr, Type, SnmpInfo, DefData) of {register, UserId2, TargetName, Config} -> ?vtrace("do_handle_agent -> register: " "~n UserId2: ~p" @@ -2088,7 +2088,7 @@ do_handle_agent(DefUserId, DefMod, [UserId2, TargetName, Config]), Config2 = ensure_present( - [{tdomain, Domain}, {taddress, Address}], Config), + [{tdomain, Domain}, {taddress, Addr}], Config), Config3 = [{reg_type, target_name} | Config2], case snmpm_config:register_agent(UserId2, TargetName, Config3) of @@ -2098,7 +2098,7 @@ do_handle_agent(DefUserId, DefMod, error_msg("failed registering agent - " "handling agent " "~p <~p,~p>: ~n~w", - [TargetName, Domain, Address, Reason]), + [TargetName, Domain, Addr, Reason]), ok end; @@ -2107,23 +2107,23 @@ do_handle_agent(DefUserId, DefMod, ok; InvalidResult -> - CallbackArgs = [Domain, Address, Type, SnmpInfo, DefData], + CallbackArgs = [Domain, Addr, Type, SnmpInfo, DefData], handle_invalid_result(handle_agent, CallbackArgs, InvalidResult) catch error:{undef, _} when Type =:= pdu -> %% Maybe, still on the old API ?vdebug("do_handle_agent -> maybe still on the old api", []), - {Ip, Port} = Address, + {Ip, Port} = Addr, case (catch DefMod:handle_agent(Ip, Port, SnmpInfo, DefData)) of {register, UserId2, Config} -> ?vtrace("do_handle_agent -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), - TargetName = mk_target_name(Domain, Address, Config), + TargetName = mk_target_name(Domain, Addr, Config), Config2 = ensure_present( - [{tdomain, Domain}, {taddress, Address}], Config), + [{tdomain, Domain}, {taddress, Addr}], Config), Config3 = [{reg_type, addr_port} | Config2], case snmpm_config:register_agent( UserId2, TargetName, Config3) of @@ -2133,7 +2133,7 @@ do_handle_agent(DefUserId, DefMod, error_msg("failed registering agent - " "handling agent " "~p <~p,~p>: ~n~w", - [TargetName, Domain, Address, Reason]), + [TargetName, Domain, Addr, Reason]), ok end; {register, UserId2, TargetName, Config} -> @@ -2144,7 +2144,7 @@ do_handle_agent(DefUserId, DefMod, [UserId2, TargetName, Config]), Config2 = ensure_present( - [{tdomain, Domain}, {taddress, Address}], Config), + [{tdomain, Domain}, {taddress, Addr}], Config), Config3 = [{reg_type, target_name} | Config2], case snmpm_config:register_agent( UserId2, TargetName, Config3) of @@ -2154,7 +2154,7 @@ do_handle_agent(DefUserId, DefMod, error_msg("failed registering agent - " "handling agent " "~p <~p,~p>: ~n~w", - [TargetName, Domain, Address, Reason]), + [TargetName, Domain, Addr, Reason]), ok end; _Ignore -> @@ -2172,38 +2172,38 @@ do_handle_agent(DefUserId, DefMod, %% Backward compatibillity crap RegType = target_name, - Target = mk_target_name(Domain, Address, default_agent_config()), + Target = mk_target_name(Domain, Addr, default_agent_config()), case Type of report -> SnmpInform = SnmpInfo, handle_report( DefUserId, DefMod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpInform, DefData, State); inform -> SnmpInform = SnmpInfo, handle_inform( DefUserId, DefMod, Ref, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpInform, DefData, State); trap -> SnmpTrapInfo = SnmpInfo, handle_trap( DefUserId, DefMod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpTrapInfo, DefData, State); _ -> error_msg( "failed delivering ~w info to default user - " "regarding agent " - "<~p,~p>: ~n~w", [Type, Domain, Address, SnmpInfo]) + "<~p,~p>: ~n~w", [Type, Domain, Addr, SnmpInfo]) end; T:E -> - CallbackArgs = [Domain, Address, Type, SnmpInfo, DefData], + CallbackArgs = [Domain, Addr, Type, SnmpInfo, DefData], handle_invalid_result(handle_agent, CallbackArgs, T, E) end. @@ -2226,45 +2226,45 @@ handle_snmp_trap( generic_trap = Generic, specific_trap = Spec, time_stamp = Timestamp, - varbinds = Varbinds} = Trap, Domain, Address, State) -> + varbinds = Varbinds} = Trap, Domain, Addr, State) -> ?vtrace("handle_snmp_trap [trappdu] -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" - " Trap: ~p", [Domain, Address, Trap]), + " Addr: ~p~n" + " Trap: ~p", [Domain, Addr, Trap]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpTrapInfo = {Enteprise, Generic, Spec, Timestamp, Varbinds2}, - do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State); + do_handle_snmp_trap(SnmpTrapInfo, Domain, Addr, State); handle_snmp_trap(#pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Trap, - Domain, Address, State) -> + Domain, Addr, State) -> ?vtrace("handle_snmp_trap [pdu] -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" - " Trap: ~p", [Domain, Address, Trap]), + " Addr: ~p~n" + " Trap: ~p", [Domain, Addr, Trap]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpTrapInfo = {EStatus, EIndex, Varbinds2}, - do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State); + do_handle_snmp_trap(SnmpTrapInfo, Domain, Addr, State); -handle_snmp_trap(CrapTrap, Domain, Address, _State) -> +handle_snmp_trap(CrapTrap, Domain, Addr, _State) -> error_msg("received crap (snmp) trap from ~w:~w =>" - "~p", [Domain, Address, CrapTrap]), + "~p", [Domain, Addr, CrapTrap]), ok. -do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> - case snmpm_config:get_agent_user_info(Domain, Address) of +do_handle_snmp_trap(SnmpTrapInfo, Domain, Addr, State) -> + case snmpm_config:get_agent_user_info(Domain, Addr) of {ok, UserId, Target, RegType} -> ?vtrace("handle_snmp_trap -> found user: ~p", [UserId]), case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> handle_trap( UserId, Mod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpTrapInfo, Data, State); Error1 -> @@ -2279,7 +2279,7 @@ do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> {ok, DefUserId, DefMod, DefData} -> handle_agent( DefUserId, DefMod, - Domain, Address, + Domain, Addr, trap, ignore, SnmpTrapInfo, DefData, State); Error2 -> @@ -2287,7 +2287,7 @@ do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> "failed retreiving the default " "user info handling report from " "~p <~p,~p>: ~n~w~n~w", - [Target, Domain, Address, + [Target, Domain, Addr, Error2, SnmpTrapInfo]) end; Error3 -> @@ -2299,7 +2299,7 @@ do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> "user ~p, handling trap: " "~n Error: ~w" "~n Trap info: ~w", - [Target, Domain, Address, UserId, + [Target, Domain, Addr, UserId, Error3, SnmpTrapInfo]) end end; @@ -2307,12 +2307,12 @@ do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> Error4 -> %% Unknown agent, pass it on to the default user ?vlog("[trap] failed retreiving user id for agent <~p,~p>: " - "~n ~p", [Domain, Address, Error4]), + "~n ~p", [Domain, Addr, Error4]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent( DefUserId, DefMod, - Domain, Address, + Domain, Addr, trap, ignore, SnmpTrapInfo, DefData, State); Error5 -> @@ -2320,21 +2320,21 @@ do_handle_snmp_trap(SnmpTrapInfo, Domain, Address, State) -> "failed retreiving " "the default user info handling trap from " "<~p,~p>: ~n~w~n~w", - [Domain, Address, Error5, SnmpTrapInfo]) + [Domain, Addr, Error5, SnmpTrapInfo]) end end, ok. handle_trap( - UserId, Mod, RegType, Target, Domain, Address, SnmpTrapInfo, Data, State) -> + UserId, Mod, RegType, Target, Domain, Addr, SnmpTrapInfo, Data, State) -> ?vtrace("handle_trap -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_trap( UserId, Mod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpTrapInfo, Data, State) end, handle_callback(F), @@ -2342,7 +2342,7 @@ handle_trap( do_handle_trap( - UserId, Mod, RegType, Target, Domain, Address, SnmpTrapInfo, Data, _State) -> + UserId, Mod, RegType, Target, Domain, Addr, SnmpTrapInfo, Data, _State) -> ?vdebug("do_handle_trap -> entry with" "~n UserId: ~p", [UserId]), {HandleTrap, CallbackArgs} = @@ -2351,7 +2351,7 @@ do_handle_trap( {fun() -> Mod:handle_trap(Target, SnmpTrapInfo, Data) end, [Target, SnmpTrapInfo, Data]}; addr_port -> - {Ip, Port} = Address, + {Ip, Port} = Addr, {fun() -> Mod:handle_trap(Ip, Port, SnmpTrapInfo, Data) end, [Ip, Port, SnmpTrapInfo, Data]} end, @@ -2361,10 +2361,10 @@ do_handle_trap( ?vtrace("do_handle_trap -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), - Target2 = mk_target_name(Domain, Address, Config), + Target2 = mk_target_name(Domain, Addr, Config), Config2 = [{reg_type, target_name}, - {tdomain, Domain}, {taddress, Address} | Config], + {tdomain, Domain}, {taddress, Addr} | Config], case snmpm_config:register_agent(UserId2, Target2, Config2) of ok -> ok; @@ -2372,7 +2372,7 @@ do_handle_trap( error_msg("failed registering agent " "handling trap " "<~p,~p>: ~n~w", - [Domain, Address, Reason]), + [Domain, Addr, Reason]), ok end; {register, UserId2, Target2, Config} -> @@ -2390,19 +2390,19 @@ do_handle_trap( error_msg("failed registering agent " "handling trap " "~p <~p,~p>: ~n~w", - [Target2, Domain, Address, Reason]), + [Target2, Domain, Addr, Reason]), reply end; unregister -> ?vtrace("do_handle_trap -> unregister", []), - case snmpm_config:unregister_agent(UserId, Domain, Address) of + case snmpm_config:unregister_agent(UserId, Domain, Addr) of ok -> ok; {error, Reason} -> error_msg("failed unregistering agent " "handling trap " "<~p,~p>: ~n~w", - [Domain, Address, Reason]), + [Domain, Addr, Reason]), ok end; ignore -> @@ -2423,16 +2423,16 @@ handle_snmp_inform( Ref, #pdu{error_status = EStatus, error_index = EIndex, - varbinds = Varbinds} = Pdu, Domain, Address, State) -> + varbinds = Varbinds} = Pdu, Domain, Addr, State) -> ?vtrace("handle_snmp_inform -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" - " Pdu: ~p", [Domain, Address, Pdu]), + " Addr: ~p~n" + " Pdu: ~p", [Domain, Addr, Pdu]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpInform = {EStatus, EIndex, Varbinds2}, - case snmpm_config:get_agent_user_info(Domain, Address) of + case snmpm_config:get_agent_user_info(Domain, Addr) of {ok, UserId, Target, RegType} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> @@ -2441,7 +2441,7 @@ handle_snmp_inform( "~n Mod: ~p", [UserId, Mod]), handle_inform( UserId, Mod, Ref, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpInform, Data, State); Error1 -> %% User no longer exists, unregister agent @@ -2455,14 +2455,14 @@ handle_snmp_inform( {ok, DefUserId, DefMod, DefData} -> handle_agent( DefUserId, DefMod, - Domain, Address, + Domain, Addr, inform, Ref, SnmpInform, DefData, State); Error2 -> error_msg("failed retreiving the default " "user info handling inform from " "~p <~p,~p>: ~n~w~n~w", - [Target, Domain, Address, + [Target, Domain, Addr, Error2, Pdu]) end; Error3 -> @@ -2473,7 +2473,7 @@ handle_snmp_inform( "user ~p, handling inform: " "~n Error: ~w" "~n Pdu: ~w", - [Target, Domain, Address, UserId, + [Target, Domain, Addr, UserId, Error3, Pdu]) end end; @@ -2481,38 +2481,38 @@ handle_snmp_inform( Error4 -> %% Unknown agent, pass it on to the default user ?vlog("[inform] failed retreiving user id for agent <~p,~p>: " - "~n ~p", [Domain, Address, Error4]), + "~n ~p", [Domain, Addr, Error4]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent( DefUserId, DefMod, - Domain, Address, + Domain, Addr, inform, Ref, SnmpInform, DefData, State); Error5 -> error_msg("failed retreiving " "the default user info handling inform from " "<~p,~p>: ~n~w~n~w", - [Domain, Address, Error5, Pdu]) + [Domain, Addr, Error5, Pdu]) end end, ok; -handle_snmp_inform(_Ref, CrapInform, Domain, Address, _State) -> +handle_snmp_inform(_Ref, CrapInform, Domain, Addr, _State) -> error_msg("received crap (snmp) inform from ~w:~w =>" - "~p", [Domain, Address, CrapInform]), + "~p", [Domain, Addr, CrapInform]), ok. handle_inform( UserId, Mod, Ref, - RegType, Target, Domain, Address, SnmpInform, Data, State) -> + RegType, Target, Domain, Addr, SnmpInform, Data, State) -> ?vtrace("handle_inform -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_inform( UserId, Mod, Ref, - RegType, Target, Domain, Address, SnmpInform, + RegType, Target, Domain, Addr, SnmpInform, Data, State) end, handle_callback(F), @@ -2520,7 +2520,7 @@ handle_inform( do_handle_inform( UserId, Mod, Ref, - RegType, Target, Domain, Address, SnmpInform, Data, State) -> + RegType, Target, Domain, Addr, SnmpInform, Data, State) -> ?vdebug("do_handle_inform -> entry with" "~n UserId: ~p", [UserId]), {HandleInform, CallbackArgs} = @@ -2529,7 +2529,7 @@ do_handle_inform( {fun() -> Mod:handle_inform(Target, SnmpInform, Data) end, [Target, SnmpInform, Data]}; addr_port -> - {Ip, Port} = Address, + {Ip, Port} = Addr, {fun() -> Mod:handle_inform(Ip, Port, SnmpInform, Data) end, [Ip, Port, SnmpInform, Data]} end, @@ -2542,11 +2542,11 @@ do_handle_inform( "~n Config: ~p", [UserId2, Config]), %% The only user which would do this is the %% default user - Target2 = mk_target_name(Domain, Address, Config), + Target2 = mk_target_name(Domain, Addr, Config), Config2 = [{reg_type, target_name} | ensure_present( - [{tdomain, Domain}, {taddress, Address}], Config)], + [{tdomain, Domain}, {taddress, Addr}], Config)], case snmpm_config:register_agent(UserId2, Target2, Config2) of ok -> reply; @@ -2554,7 +2554,7 @@ do_handle_inform( error_msg("failed registering agent " "handling inform " "~p <~p,~p>: ~n~w", - [Target2, Domain, Address, Reason]), + [Target2, Domain, Addr, Reason]), reply end; @@ -2573,21 +2573,21 @@ do_handle_inform( error_msg("failed registering agent " "handling inform " "~p <~p,~p>: ~n~w", - [Target2, Domain, Address, Reason]), + [Target2, Domain, Addr, Reason]), reply end; unregister -> ?vtrace("do_handle_inform -> unregister", []), case snmpm_config:unregister_agent( - UserId, Domain, Address) of + UserId, Domain, Addr) of ok -> reply; {error, Reason} -> error_msg("failed unregistering agent " "handling inform " "<~p,~p>: ~n~w", - [Domain, Address, Reason]), + [Domain, Addr, Reason]), reply end; @@ -2610,34 +2610,34 @@ do_handle_inform( reply end, - handle_inform_response(Rep, Ref, Domain, Address, State), + handle_inform_response(Rep, Ref, Domain, Addr, State), ok. -handle_inform_response(_, ignore, _Domain, _Address, _State) -> +handle_inform_response(_, ignore, _Domain, _Addr, _State) -> ignore; -handle_inform_response(no_reply, _Ref, _Domain, _Address, _State) -> +handle_inform_response(no_reply, _Ref, _Domain, _Addr, _State) -> no_reply; handle_inform_response( - _, Ref, Domain, Address, + _, Ref, Domain, Addr, #state{net_if = Pid, net_if_mod = Mod}) -> ?vdebug("handle_inform -> response", []), - (catch Mod:inform_response(Pid, Ref, Domain, Address)). + (catch Mod:inform_response(Pid, Ref, Domain, Addr)). handle_snmp_report( #pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, - Domain, Address, State) -> + Domain, Addr, State) -> ?vtrace("handle_snmp_report -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" - " Pdu: ~p", [Domain, Address, Pdu]), + " Addr: ~p~n" + " Pdu: ~p", [Domain, Addr, Pdu]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpReport = {EStatus, EIndex, Varbinds2}, - case snmpm_config:get_agent_user_info(Domain, Address) of + case snmpm_config:get_agent_user_info(Domain, Addr) of {ok, UserId, Target, RegType} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> @@ -2647,7 +2647,7 @@ handle_snmp_report( "~n ~p" "~n ~p", [UserId, Mod, Target, SnmpReport]), handle_report(UserId, Mod, - RegType, Target, Domain, Address, + RegType, Target, Domain, Addr, SnmpReport, Data, State); Error1 -> %% User no longer exists, unregister agent @@ -2660,7 +2660,7 @@ handle_snmp_report( case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent(DefUserId, DefMod, - Domain, Address, + Domain, Addr, report, ignore, SnmpReport, DefData, State); @@ -2668,7 +2668,7 @@ handle_snmp_report( error_msg("failed retreiving the default " "user info handling report from " "~p <~p,~p>: ~n~w~n~w", - [Target, Domain, Address, + [Target, Domain, Addr, Error2, Pdu]) end; Error3 -> @@ -2679,7 +2679,7 @@ handle_snmp_report( "user ~p, handling report: " "~n Error: ~w" "~n Report: ~w", - [Target, Domain, Address, UserId, + [Target, Domain, Addr, UserId, Error3, Pdu]) end end; @@ -2687,25 +2687,25 @@ handle_snmp_report( Error4 -> %% Unknown agent, pass it on to the default user ?vlog("[report] failed retreiving user id for agent <~p,~p>: " - "~n ~p", [Domain, Address, Error4]), + "~n ~p", [Domain, Addr, Error4]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent(DefUserId, DefMod, - Domain, Address, + Domain, Addr, report, ignore, SnmpReport, DefData, State); Error5 -> error_msg("failed retreiving " "the default user info handling report from " "<~p,~p>: ~n~w~n~w", - [Domain, Address, Error5, Pdu]) + [Domain, Addr, Error5, Pdu]) end end, ok; -handle_snmp_report(CrapReport, Domain, Address, _State) -> +handle_snmp_report(CrapReport, Domain, Addr, _State) -> error_msg("received crap (snmp) report from ~w:~w =>" - "~p", [Domain, Address, CrapReport]), + "~p", [Domain, Addr, CrapReport]), ok. %% This could be from a failed get-request, so we might have a user @@ -2719,14 +2719,14 @@ handle_snmp_report( error_index = EIndex, varbinds = Varbinds} = Pdu, {ReportReason, Info} = Rep, - Domain, Address, State) when is_integer(ReqId) -> + Domain, Addr, State) when is_integer(ReqId) -> ?vtrace("handle_snmp_report -> entry with~n" " Domain: ~p~n" - " Address: ~p~n" + " Addr: ~p~n" " ReqId: ~p~n" " Rep: ~p~n" - " Pdu: ~p", [Domain, Address, ReqId, Rep, Pdu]), + " Pdu: ~p", [Domain, Addr, ReqId, Rep, Pdu]), Varbinds2 = fix_vbs_BITS(Varbinds), SnmpReport = {EStatus, EIndex, Varbinds2}, @@ -2771,7 +2771,7 @@ handle_snmp_report( %% Either not a sync request or no such request. Either %% way, this is error info, so handle it as such. - case snmpm_config:get_agent_user_id(Domain, Address) of + case snmpm_config:get_agent_user_id(Domain, Addr) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> @@ -2795,7 +2795,7 @@ handle_snmp_report( "default user " "info handling report from " "<~p,~p>: ~n~w~n~w~n~w", - [Domain, Address, Error, + [Domain, Addr, Error, ReqId, Reason]) end end; @@ -2803,7 +2803,7 @@ handle_snmp_report( %% Unknown agent, pass it on to the default user ?vlog("[report] failed retreiving user id for " "agent <~p,~p>: " - "~n ~p", [Domain, Address, Error]), + "~n ~p", [Domain, Addr, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_error(DefUserId, DefMod, Reason, ReqId, @@ -2813,35 +2813,35 @@ handle_snmp_report( "the default user info handling " "report from " "<~p,~p>: ~n~w~n~w~n~w", - [Domain, Address, Error, ReqId, Reason]) + [Domain, Addr, Error, ReqId, Reason]) end end end, ok; -handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Domain, Address, _State) -> +handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Domain, Addr, _State) -> error_msg( "received crap (snmp) report from ~w:~w =>" "~n~p~n~p~n~p", - [Domain, Address, CrapReqId, CrapReport, CrapInfo]), + [Domain, Addr, CrapReqId, CrapReport, CrapInfo]), ok. -handle_report(UserId, Mod, RegType, Target, Domain, Address, +handle_report(UserId, Mod, RegType, Target, Domain, Addr, SnmpReport, Data, State) -> ?vtrace("handle_report -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_report( - UserId, Mod, RegType, Target, Domain, Address, + UserId, Mod, RegType, Target, Domain, Addr, SnmpReport, Data, State) end, handle_callback(F), ok. do_handle_report( - UserId, Mod, RegType, Target, Domain, Address, + UserId, Mod, RegType, Target, Domain, Addr, SnmpReport, Data, _State) -> ?vdebug("do_handle_report -> entry with" "~n UserId: ~p", [UserId]), @@ -2851,7 +2851,7 @@ do_handle_report( {fun() -> Mod:handle_report(Target, SnmpReport, Data) end, [Target, SnmpReport, Data]}; addr_port -> - {Ip, Port} = Address, + {Ip, Port} = Addr, {fun() -> Mod:handle_report(Ip, Port, SnmpReport, Data) end, [Ip, Port, SnmpReport, Data]} end, @@ -2863,10 +2863,10 @@ do_handle_report( "~n Config: ~p", [UserId2, Config]), %% The only user which would do this is the %% default user - Target2 = mk_target_name(Domain, Address, Config), + Target2 = mk_target_name(Domain, Addr, Config), Config2 = [{reg_type, target_name}, - {tdomain, Domain}, {taddress, Address} | Config], + {tdomain, Domain}, {taddress, Addr} | Config], case snmpm_config:register_agent(UserId2, Target2, Config2) of ok -> ok; @@ -2874,7 +2874,7 @@ do_handle_report( error_msg("failed registering agent " "handling report " "<~p,~p>: ~n~w", - [Domain, Address, Reason]), + [Domain, Addr, Reason]), ok end; @@ -2893,20 +2893,20 @@ do_handle_report( error_msg("failed registering agent " "handling report " "~p <~p,~p>: ~n~w", - [Target2, Domain, Address, Reason]), + [Target2, Domain, Addr, Reason]), reply end; unregister -> ?vtrace("do_handle_trap -> unregister", []), - case snmpm_config:unregister_agent(UserId, Domain, Address) of + case snmpm_config:unregister_agent(UserId, Domain, Addr) of ok -> ok; {error, Reason} -> error_msg("failed unregistering agent " "handling report " "<~p,~p>: ~n~w", - [Domain, Address, Reason]), + [Domain, Addr, Reason]), ok end; @@ -3044,7 +3044,7 @@ do_gc(Key, Now) -> %% %%---------------------------------------------------------------------- -send_get_request(Oids, Vsn, MsgData, Domain, Address, ExtraInfo, +send_get_request(Oids, Vsn, MsgData, Domain, Addr, ExtraInfo, #state{net_if = NetIf, net_if_mod = Mod, mini_mib = MiniMIB}) -> @@ -3056,37 +3056,37 @@ send_get_request(Oids, Vsn, MsgData, Domain, Address, ExtraInfo, " Vsn: ~p~n" " MsgData: ~p~n" " Domain: ~p~n" - " Address: ~p~n", - [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Address]), + " Addr: ~p", + [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr]), Res = (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, - Domain, Address, ExtraInfo)), + Domain, Addr, ExtraInfo)), ?vtrace("send_get_request -> send result:" "~n ~p", [Res]), Pdu#pdu.request_id. -send_get_next_request(Oids, Vsn, MsgData, Domain, Address, ExtraInfo, +send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(get_next, Oids, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo), Pdu#pdu.request_id. -send_get_bulk_request(Oids, Vsn, MsgData, Domain, Address, +send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr, NonRep, MaxRep, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(bulk, {NonRep, MaxRep, Oids}, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo), Pdu#pdu.request_id. -send_set_request(VarsAndVals, Vsn, MsgData, Domain, Address, ExtraInfo, +send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(set, VarsAndVals, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo), Pdu#pdu.request_id. %% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo, @@ -3322,9 +3322,9 @@ agent_data(TargetName, SendOpts) -> {Comm, SecModel} end, Domain = agent_data_item(tdomain, TargetName), - Address = agent_data_item(taddress, TargetName), + Addr = agent_data_item(taddress, TargetName), RegType = agent_data_item(reg_type, TargetName), - {ok, RegType, Domain, Address, version(Version), MsgData}; + {ok, RegType, Domain, Addr, version(Version), MsgData}; Error -> Error end. @@ -3471,8 +3471,8 @@ t() -> {A,B,C} = erlang:now(), A*1000000000+B*1000+(C div 1000). -mk_target_name(Domain, Address, Config) -> - snmpm_config:mk_target_name(Domain, Address, Config). +mk_target_name(Domain, Addr, Config) -> + snmpm_config:mk_target_name(Domain, Addr, Config). default_agent_config() -> case snmpm_config:agent_info() of diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index ea4686c91a..82cbf42e35 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -508,6 +508,8 @@ tdomain_to_family(transportDomainUdpIpv4) -> inet; tdomain_to_family(transportDomainUdpIpv6) -> inet6; +tdomain_to_family(?snmpUDPDomain) -> + inet; tdomain_to_family(?transportDomainUdpIpv4) -> inet; tdomain_to_family(?transportDomainUdpIpv6) -> diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 68d4aee97d..38e248c326 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -2107,10 +2107,19 @@ write_manager_snmp_conf(Dir, IP, Port, MMS, EngineID) -> "%% {max_message_size, 484}.\n" "%%\n\n", Hdr = header() ++ Comment, - Conf = [{port, Port}, - {address, IP}, - {engine_id, EngineID}, - {max_message_size, MMS}], + Conf = + case Port of + {Addr, P} when is_integer(P), is_atom(IP) -> + Domain = IP, + [{domain, Domain}, + {port, P}, + {address, Addr}]; + _ when is_integer(Port) -> + [{port, Port}, + {address, IP}] + end ++ + [{engine_id, EngineID}, + {max_message_size, MMS}], write_manager_config(Dir, Hdr, Conf). write_manager_config(Dir, Hdr, Conf) -> diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 3e152e6ad4..685c4dc9be 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -244,6 +244,7 @@ init_per_testcase2(Case, Config) -> Family = proplists:get_value(ipfamily, Config, inet), Conf = [{watchdog, ?WD_START(?MINS(5))}, + {ipfamily, Family}, {ip, ?LOCALHOST(Family)}, {case_top_dir, CaseTopDir}, {agent_dir, AgTopDir}, @@ -413,7 +414,8 @@ all() -> {group, event_tests_mt}, discovery, {group, tickets}, - {group, ipv6} + {group, ipv6}, + {group, ipv6_mt} ]. groups() -> @@ -549,13 +551,18 @@ groups() -> otp8395_1 ] }, - {ipv6, [], + {ipv6, [], + [ + simple_sync_get3, + inform1 + ] + }, + {ipv6_mt, [], [ simple_sync_get3, inform1 ] } - ]. @@ -567,6 +574,8 @@ init_per_group(event_tests_mt = GroupName, Config) -> snmp_test_lib:init_group_top_dir( GroupName, [{manager_net_if_module, snmpm_net_if_mt} | Config]); +init_per_group(ipv6_mt, Config) -> + init_per_group(ipv6, [{manager_net_if_module, snmpm_net_if_mt} | Config]); init_per_group(ipv6 = GroupName, Config) -> case ct:require(ipv6_hosts) of ok -> @@ -5767,12 +5776,24 @@ fin_mgr_user(Conf) -> init_mgr_user_data1(Conf) -> Node = ?config(manager_node, Conf), TargetName = ?config(manager_agent_target_name, Conf), - Addr = ?config(ip, Conf), + IpFamily = ?config(ipfamily, Conf), + Ip = ?config(ip, Conf), Port = ?AGENT_PORT, - ?line ok = mgr_user_register_agent(Node, TargetName, - [{address, Addr}, - {port, Port}, - {engine_id, "agentEngine"}]), + ?line ok = + case IpFamily of + inet -> + mgr_user_register_agent( + Node, TargetName, + [{address, Ip}, + {port, Port}, + {engine_id, "agentEngine"}]); + inet6 -> + mgr_user_register_agent( + Node, TargetName, + [{tdomain, transportDomainUdpIpv6}, + {taddress, {Ip, Port}}, + {engine_id, "agentEngine"}]) + end, _Agents = mgr_user_which_own_agents(Node), ?DBG("Own agents: ~p", [_Agents]), @@ -5797,12 +5818,24 @@ init_mgr_user_data2(Conf) -> "~n Conf: ~p", [Conf]), Node = ?config(manager_node, Conf), TargetName = ?config(manager_agent_target_name, Conf), - Addr = ?config(ip, Conf), + IpFamily = ?config(ipfamily, Conf), + Ip = ?config(ip, Conf), Port = ?AGENT_PORT, - ?line ok = mgr_user_register_agent(Node, TargetName, - [{address, Addr}, - {port, Port}, - {engine_id, "agentEngine"}]), + ?line ok = + case IpFamily of + inet -> + mgr_user_register_agent( + Node, TargetName, + [{address, Ip}, + {port, Port}, + {engine_id, "agentEngine"}]); + inet6 -> + mgr_user_register_agent( + Node, TargetName, + [{tdomain, transportDomainUdpIpv6}, + {taddress, {Ip, Port}}, + {engine_id, "agentEngine"}]) + end, _Agents = mgr_user_which_own_agents(Node), ?DBG("Own agents: ~p", [_Agents]), @@ -6199,10 +6232,16 @@ await_stopped(Node, N) -> write_manager_config(Config) -> Dir = ?config(manager_conf_dir, Config), - Ip = ?config(ip, Config), - Addr = tuple_to_list(Ip), - snmp_config:write_manager_snmp_files(Dir, Addr, ?MGR_PORT, - ?MGR_MMS, ?MGR_ENGINE_ID, [], [], []). + Ip = tuple_to_list(?config(ip, Config)), + {Addr, Port} = + case ?config(ipfamily, Config) of + inet -> + {Ip, ?MGR_PORT}; + inet6 -> + {transportDomainUdpIpv6, {Ip, ?MGR_PORT}} + end, + snmp_config:write_manager_snmp_files( + Dir, Addr, Port, ?MGR_MMS, ?MGR_ENGINE_ID, [], [], []). write_manager_conf(Dir) -> Port = "5000", @@ -6231,25 +6270,27 @@ write_manager_conf(Dir, Str) -> write_agent_config(Vsns, Conf) -> Dir = ?config(agent_conf_dir, Conf), - Ip = ?config(ip, Conf), - ?line Addr = tuple_to_list(Ip), - ?line ok = write_agent_config_files(Dir, Vsns, Addr), + ?line Ip = tuple_to_list(?config(ip, Conf)), + ?line Domain = + case ?config(ipfamily, Conf) of + inet -> + snmpUDPDomain; + inet6 -> + transportDomainUdpIpv6 + end, + ?line ok = write_agent_config_files(Dir, Vsns, Domain, Ip), ?line ok = update_agent_usm(Vsns, Dir), ?line ok = update_agent_community(Vsns, Dir), ?line ok = update_agent_vacm(Vsns, Dir), - ?line ok = write_agent_target_addr_conf(Dir, Addr, Vsns), + ?line ok = write_agent_target_addr_conf(Dir, Domain, Ip, Vsns), ?line ok = write_agent_target_params_conf(Dir, Vsns), ?line ok = write_agent_notify_conf(Dir), ok. -write_agent_config_files(Dir, Vsns, Addr) -> - snmp_config:write_agent_snmp_files(Dir, Vsns, - Addr, ?MGR_PORT, - Addr, ?AGENT_PORT, - "mgr-test", "trap", - none, "", - ?AGENT_ENGINE_ID, - ?AGENT_MMS). +write_agent_config_files(Dir, Vsns, Domain, Ip) -> + snmp_config:write_agent_snmp_files( + Dir, Vsns, Domain, {Ip, ?MGR_PORT}, {Ip, ?AGENT_PORT}, "mgr-test", + trap, none, "", ?AGENT_ENGINE_ID, ?AGENT_MMS). update_agent_usm(Vsns, Dir) -> case lists:member(v3, Vsns) of @@ -6317,9 +6358,9 @@ update_agent_vacm(_Vsns, Dir) -> excluded, null}], snmp_config:update_agent_vacm_config(Dir, Conf). -write_agent_target_addr_conf(Dir, Addr, Vsns) -> - snmp_config:write_agent_snmp_target_addr_conf(Dir, Addr, ?MGR_PORT, - 300, 3, Vsns). +write_agent_target_addr_conf(Dir, Domain, Ip, Vsns) -> + snmp_config:write_agent_snmp_target_addr_conf( + Dir, Domain, {Ip, ?MGR_PORT}, 300, 3, Vsns). write_agent_target_params_conf(Dir, Vsns) -> F = fun(v1) -> {"target_v1", v1, v1, "all-rights", noAuthNoPriv}; -- cgit v1.2.3 From 41fe52bd9540307cdb6e2e4ba06d36b11c9fd6bd Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 19 Jun 2014 16:08:28 +0200 Subject: Add testcases and do related fixes --- lib/snmp/src/agent/snmpa_net_if.erl | 8 +- lib/snmp/src/manager/snmpm_mpd.erl | 9 +- lib/snmp/src/manager/snmpm_net_if_mt.erl | 398 ++++++++++++++++++------------- lib/snmp/test/snmp_manager_test.erl | 31 ++- 4 files changed, 256 insertions(+), 190 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 71bb9cad2e..875ea19097 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -28,7 +28,6 @@ -export([system_continue/3, system_terminate/4, system_code_change/4]). -export([init/5]). -export([filter_reset/1]). --export([format_address/1]). -include("snmp_types.hrl"). -include("snmpa_internal.hrl"). @@ -1099,11 +1098,12 @@ fix_filter_address(snmpUDPDomain, {Domain, Addr}) when Domain =:= snmpUDPDomain; Domain =:= transportDomainUdpIpv4 -> Addr; +fix_filter_address(_AgentDomain, {Domain, _} = Address) + when is_atom(Domain) -> + Address; fix_filter_address(snmpUDPDomain, {_, Port} = Addr) when is_integer(Port) -> - Addr; -fix_filter_address(_AgentDomain, Address) -> - Address. + Addr. %%%----------------------------------------------------------------- diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index 521c496adb..f8a7441c0a 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -170,7 +170,7 @@ process_v1_v2c_msg( end, Max = get_max_message_size(), - AgentMax = get_agent_max_message_size(Addr), + AgentMax = get_agent_max_message_size(Domain, Addr), PduMS = pdu_ms(Max, AgentMax, HS), ?vtrace("process_v1_v2c_msg -> PduMS: ~p", [PduMS]), @@ -862,12 +862,13 @@ get_max_message_size() -> end. %% The the MMS of the agent -get_agent_max_message_size({Addr, Port}) -> - case snmpm_config:get_agent_engine_max_message_size(Addr, Port) of +get_agent_max_message_size(Domain, Addr) -> + case snmpm_config:get_agent_engine_max_message_size(Domain, Addr) of {ok, MMS} -> MMS; _Error -> - ?vlog("unknown agent: ~w:~w", [Addr, Port]), + ?vlog("unknown agent: ~s", + [snmp_conf:mk_addr_string({Domain, Addr})]), get_max_message_size() end. %% get_agent_max_message_size(Addr, Port) -> diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl index 8dd3ef0111..2937f5cc87 100644 --- a/lib/snmp/src/manager/snmpm_net_if_mt.erl +++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl @@ -55,13 +55,14 @@ %% -define(VMODULE,"NET_IF"). -include("snmp_verbosity.hrl"). --record(state, +-record(state, { server, note_store, - sock, + domain, + sock, mpd_state, - log, + log, irb = auto, % auto | {user, integer()} irgc, filter @@ -99,22 +100,22 @@ start_link(Server, NoteStore) -> stop(Pid) -> call(Pid, stop). -send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort) -> - send_pdu(Pid, Pdu, Vsn, MsgData, DomainIp, AddrPort, ?DEFAULT_EXTRA_INFO). +send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port) -> + send_pdu( + Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ?DEFAULT_EXTRA_INFO). -send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo) - when is_record(Pdu, pdu), is_atom(Domain) -> +send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ExtraInfo) + when is_record(Pdu, pdu) -> ?d("send_pdu -> entry with~n" - " Pid: ~p~n" - " Pdu: ~p~n" - " Vsn: ~p~n" - " MsgData: ~p~n" - " Domain: ~p~n" - " Address: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Address]), - cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}); -send_pdu(Pid, Pdu, Vsn, MsgData, Ip, Port, ExtraInfo) -> - Domain = snmpm_config:default_transport_domain(), - send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo). + " Pid: ~p~n" + " Pdu: ~p~n" + " Vsn: ~p~n" + " MsgData: ~p~n" + " Domain/IP: ~p~n" + " Addr/Port : ~p", + [Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port]), + {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port), + cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}). send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) -> send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo). @@ -122,8 +123,9 @@ send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) -> note_store(Pid, NoteStore) -> call(Pid, {note_store, NoteStore}). -inform_response(Pid, Ref, Domain, Address) -> - cast(Pid, {inform_response, Ref, Domain, Address}). +inform_response(Pid, Ref, Domain_or_Ip, Addr_or_Port) -> + {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port), + cast(Pid, {inform_response, Ref, Domain, Addr}). info(Pid) -> call(Pid, info). @@ -203,7 +205,14 @@ do_init(Server, NoteStore) -> BindTo = get_opt(Opts, bind_to, false), NoReuse = get_opt(Opts, no_reuse, false), {ok, Port} = snmpm_config:system_info(port), - {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, BindTo, NoReuse), + Domain = + case snmpm_config:system_info(domain) of + {ok, D} -> + D; + _ -> + snmpm_config:default_transport_domain() + end, + {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, Domain, BindTo, NoReuse), %% Flow control -- FilterOpts = get_opt(Opts, filter, []), @@ -219,10 +228,11 @@ do_init(Server, NoteStore) -> init_counters(), %% -- We are done --- - State = #state{server = Server, - note_store = NoteStore, + State = #state{server = Server, + note_store = NoteStore, mpd_state = MpdState, - sock = Sock, + domain = Domain, + sock = Sock, log = Log, irb = IRB, irgc = IrGcRef, @@ -232,19 +242,24 @@ do_init(Server, NoteStore) -> %% Open port -do_open_port(Port, SendSz, RecvSz, BindTo, NoReuse) -> - ?vtrace("do_open_port -> entry with" - "~n Port: ~p" - "~n SendSz: ~p" - "~n RecvSz: ~p" - "~n BindTo: ~p" - "~n NoReuse: ~p", [Port, SendSz, RecvSz, BindTo, NoReuse]), +do_open_port(Port, SendSz, RecvSz, Domain, BindTo, NoReuse) -> + ?vtrace("do_open_port -> entry with~n" + " Port: ~p~n" + " SendSz: ~p~n" + " RecvSz: ~p~n" + " Domain: ~p~n" + " BindTo: ~p~n" + " NoReuse: ~p", + [Port, SendSz, RecvSz, Domain, BindTo, NoReuse]), IpOpts1 = bind_to(BindTo), IpOpts2 = no_reuse(NoReuse), IpOpts3 = recbuf(RecvSz), IpOpts4 = sndbuf(SendSz), - IpOpts = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4], - OpenRes = + IpOpts = + [binary, + snmp_conf:tdomain_to_family(Domain) | + IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4], + OpenRes = case init:get_argument(snmpm_fd) of {ok, [[FdStr]]} -> Fd = list_to_integer(FdStr), @@ -397,24 +412,24 @@ handle_call(Req, From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Address, ExtraInfo}, +handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}, State) -> ?vlog("received send_pdu message with~n" " Pdu: ~p~n" " Vsn: ~p~n" " MsgData: ~p~n" " Domain: ~p~n" - " Address: ~p", [Pdu, Vsn, MsgData, Domain, Address]), - maybe_process_extra_info(ExtraInfo), - handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State), + " Addr: ~p", [Pdu, Vsn, MsgData, Domain, Addr]), + maybe_process_extra_info(ExtraInfo), + handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State), {noreply, State}; -handle_cast({inform_response, Ref, Domain, Address}, State) -> +handle_cast({inform_response, Ref, Domain, Addr}, State) -> ?vlog("received inform_response message with~n" " Ref: ~p~n" " Domain: ~p~n" - " Address: ~p", [Ref, Domain, Address]), - handle_inform_response(Ref, Domain, Address, State), + " Addr: ~p", [Ref, Domain, Addr]), + handle_inform_response(Ref, Domain, Addr, State), {noreply, State}; handle_cast(filter_reset, State) -> @@ -433,9 +448,10 @@ handle_cast(Msg, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) -> +handle_info( + {udp, Sock, Ip, Port, Bytes}, + #state{sock = Sock, domain = Domain} = State) -> ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]), - Domain = snmpm_config:default_transport_domain(), handle_udp(Domain, {Ip, Port}, Bytes, State), {noreply, State}; @@ -501,62 +517,64 @@ code_change(_Vsn, State, _Extra) -> %%% Internal functions %%%------------------------------------------------------------------- -handle_udp(Domain, Address, Bytes, State) -> - Verbosity = get(verbosity), - spawn_opt(fun() -> - Log = worker_init(State, Verbosity), - Res = - (catch maybe_handle_recv_msg( - Domain, Address, Bytes, - State#state{log = Log})), - worker_exit(udp, {Domain, Address}, Res) - end, - [monitor]). - +handle_udp(Domain, Addr, Bytes, State) -> + Verbosity = get(verbosity), + spawn_opt( + fun() -> + Log = worker_init(State, Verbosity), + Res = + (catch maybe_handle_recv_msg( + Domain, Addr, Bytes, + State#state{log = Log})), + worker_exit(udp, {Domain, Addr}, Res) + end, + [monitor]). + maybe_handle_recv_msg( - Domain, Address, Bytes, #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv(Domain, Address)) of + Domain, Addr, Bytes, + #state{filter = FilterMod, domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_recv(Arg1, Arg2)) of false -> - %% Drop the received packet + %% Drop the received packet inc(netIfMsgInDrops), ok; _ -> - handle_recv_msg(Domain, Address, Bytes, State) + handle_recv_msg(Domain, Addr, Bytes, State) end. -handle_recv_msg(Domain, Address, Bytes, #state{server = Pid}) +handle_recv_msg(Domain, Addr, Bytes, #state{server = Pid}) when is_binary(Bytes) andalso (size(Bytes) =:= 0) -> - Pid ! {snmp_error, {empty_message, Domain, Address}, Domain, Address}, + Pid ! {snmp_error, {empty_message, Domain, Addr}, Domain, Addr}, ok; handle_recv_msg( - Domain, Address, Bytes, + Domain, Addr, Bytes, #state{server = Pid, note_store = NoteStore, mpd_state = MpdState, - sock = Sock, log = Log} = State) -> - Logger = logger(Log, read, Domain, Address), - case (catch snmpm_mpd:process_msg(Bytes, Domain, Address, + Logger = logger(Log, read, Domain, Addr), + case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, MpdState, NoteStore, Logger)) of {ok, Vsn, Pdu, MS, ACM} -> - maybe_handle_recv_pdu(Domain, Address, Vsn, Pdu, MS, ACM, + maybe_handle_recv_pdu(Domain, Addr, Vsn, Pdu, MS, ACM, Logger, State); {discarded, Reason, Report} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Domain, Address}, - maybe_udp_send(State#state.filter, Sock, Domain, Address, Report), + Pid ! {snmp_error, ErrorInfo, Domain, Addr}, + maybe_udp_send(Domain, Addr, Report, State), ok; {discarded, Reason} -> ?vdebug("discarded: ~p", [Reason]), ErrorInfo = {failed_processing_message, Reason}, - Pid ! {snmp_error, ErrorInfo, Domain, Address}, + Pid ! {snmp_error, ErrorInfo, Domain, Addr}, ok; Error -> @@ -567,97 +585,99 @@ handle_recv_msg( maybe_handle_recv_pdu( - Domain, Address, Vsn, - #pdu{type = Type} = Pdu, PduMS, ACM, Logger, - #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_recv_pdu(Domain, Address, Type)) of + Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger, + #state{filter = FilterMod, domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of false -> inc(netIfPduInDrops), ok; _ -> handle_recv_pdu( - Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) + Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) end; maybe_handle_recv_pdu( - Domain, Address, Vsn, Trap, PduMS, ACM, Logger, - #state{filter = FilterMod} = State) + Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, + #state{filter = FilterMod, domain = ManagerDomain} = State) when is_record(Trap, trappdu) -> - case (catch FilterMod:accept_recv_pdu(Domain, Address, trappdu)) of + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of false -> inc(netIfPduInDrops), ok; _ -> handle_recv_pdu( - Domain, Address, Vsn, Trap, PduMS, ACM, Logger, State) + Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, State) end; maybe_handle_recv_pdu( - Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State) -> - handle_recv_pdu(Domain, Address, Vsn, Pdu, PduMS, ACM, Logger, State). + Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) -> + handle_recv_pdu(Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State). handle_recv_pdu( - Domain, Address, Vsn, + Domain, Addr, Vsn, #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger, #state{server = Pid, irb = IRB} = State) -> handle_inform_request( - IRB, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State); + IRB, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State); handle_recv_pdu( - Domain, Address, _Vsn, + Domain, Addr, _Vsn, #pdu{type = report} = Pdu, _PduMS, ok, _Logger, #state{server = Pid} = _State) -> ?vtrace("received report - ok", []), - Pid ! {snmp_report, {ok, Pdu}, Domain, Address}, + Pid ! {snmp_report, {ok, Pdu}, Domain, Addr}, ok; -handle_recv_pdu(Domain, Address, - _Vsn, #pdu{type = report} = Pdu, _PduMS, - {error, ReqId, Reason}, - _Logger, - #state{server = Pid} = _State) -> +handle_recv_pdu( + Domain, Addr, _Vsn, + #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger, + #state{server = Pid} = _State) -> ?vtrace("received report - error", []), - Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Address}, + Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Addr}, ok; handle_recv_pdu( - Domain, Address, _Vsn, + Domain, Addr, _Vsn, #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger, #state{server = Pid} = _State) -> ?vtrace("received snmpv2-trap", []), - Pid ! {snmp_trap, Pdu, Domain, Address}, + Pid ! {snmp_trap, Pdu, Domain, Addr}, ok; handle_recv_pdu( - Domain, Address, _Vsn, Trap, _PduMS, _ACM, _Logger, + Domain, Addr, _Vsn, Trap, _PduMS, _ACM, _Logger, #state{server = Pid} = _State) when is_record(Trap, trappdu) -> ?vtrace("received trappdu", []), - Pid ! {snmp_trap, Trap, Domain, Address}, + Pid ! {snmp_trap, Trap, Domain, Addr}, ok; handle_recv_pdu( - Domain, Address, _Vsn, Pdu, _PduMS, _ACM, _Logger, + Domain, Addr, _Vsn, Pdu, _PduMS, _ACM, _Logger, #state{server = Pid} = _State) when is_record(Pdu, pdu) -> ?vtrace("received pdu", []), - Pid ! {snmp_pdu, Pdu, Domain, Address}, + Pid ! {snmp_pdu, Pdu, Domain, Addr}, ok; handle_recv_pdu( - _Domain, _Address, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> + _Domain, _Addr, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) -> ?vlog("received unexpected pdu: " "~n Pdu: ~p" "~n ACM: ~p", [Pdu, ACM]), ok. -handle_inform_request(auto, Pid, Vsn, Pdu, ACM, Domain, Address, Logger, State) -> +handle_inform_request( + auto, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State) -> ?vtrace("received inform-request (true)", []), - Pid ! {snmp_inform, ignore, Pdu, Domain, Address}, + Pid ! {snmp_inform, ignore, Pdu, Domain, Addr}, RePdu = make_response_pdu(Pdu), - maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, State); -handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, - ACM, Domain, Address, _Logger, _State) -> + maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Addr, Logger, State); +handle_inform_request( + {user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, + ACM, Domain, Addr, _Logger, _State) -> ?vtrace("received inform-request (false)", []), - Pid ! {snmp_inform, ReqId, Pdu, Domain, Address}, + Pid ! {snmp_inform, ReqId, Pdu, Domain, Addr}, %% Before we go any further, we need to check that we have not %% already received this message (possible resend). - Key = {ReqId, Domain, Address}, + Key = {ReqId, Domain, Addr}, case ets:lookup(snmpm_inform_request_table, Key) of [_] -> %% OK, we already know about this. We assume this @@ -671,41 +691,43 @@ handle_inform_request({user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu, ets:insert(snmpm_inform_request_table, Rec) end, ok. - -handle_inform_response(Ref, Domain, Address, State) -> - Verbosity = get(verbosity), - spawn_opt(fun() -> - Log = worker_init(State, Verbosity), - Res = (catch do_handle_inform_response( - Ref, - Domain, Address, - State#state{log = Log})), - worker_exit(inform_response, {Domain, Address}, Res) - end, - [monitor]). - +handle_inform_response(Ref, Domain, Addr, State) -> + Verbosity = get(verbosity), + spawn_opt( + fun() -> + Log = worker_init(State, Verbosity), + Res = (catch do_handle_inform_response( + Ref, Domain, Addr, State#state{log = Log})), + worker_exit(inform_response, {Domain, Addr}, Res) + end, + [monitor]). -do_handle_inform_response(Ref, Domain, Address, State) -> - Key = {Ref, Domain, Address}, + + +do_handle_inform_response(Ref, Domain, Addr, State) -> + Key = {Ref, Domain, Addr}, case ets:lookup(snmpm_inform_request_table, Key) of [{Key, _, {Vsn, ACM, RePdu}}] -> - Logger = logger(State#state.log, read, Domain, Address), + Logger = logger(State#state.log, read, Domain, Addr), ets:delete(snmpm_inform_request_table, Key), - maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, - Logger, State); + maybe_send_inform_response( + RePdu, Vsn, ACM, Domain, Addr, Logger, State); [] -> %% Already acknowledged, or the user was to slow to reply... ok end, ok. -maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, - #state{server = Pid, - sock = Sock, - filter = FilterMod}) -> +maybe_send_inform_response( + RePdu, Vsn, ACM, Domain, Addr, Logger, + #state{server = Pid, + sock = Sock, + domain = ManagerDomain, + filter = FilterMod}) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), case (catch FilterMod:accept_send_pdu( - Domain, Address, pdu_type_of(RePdu))) + Arg1, Arg2, pdu_type_of(RePdu))) of false -> inc(netIfPduOutDrops), @@ -713,13 +735,14 @@ maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Address, Logger, _ -> case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of {ok, Msg} -> - maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); + maybe_udp_send( + Domain, Addr, Msg, Sock, FilterMod, ManagerDomain); {discarded, Reason} -> ?vlog("failed generating response message:" "~n Reason: ~p", [Reason]), ReqId = RePdu#pdu.request_id, ErrorInfo = {failed_generating_response, {RePdu, Reason}}, - Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Address}, + Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr}, ok end end. @@ -754,40 +777,42 @@ irgc_stop(Ref) -> (catch erlang:cancel_timer(Ref)). -handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State) -> - Verbosity = get(verbosity), - spawn_opt(fun() -> - Log = worker_init(State, Verbosity), - Res = (catch maybe_handle_send_pdu( - Pdu, Vsn, MsgData, - Domain, Address, - State#state{log = Log})), - worker_exit(send_pdu, {Domain, Address}, Res) - end, - [monitor]). - -maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, - #state{filter = FilterMod} = State) -> - case (catch FilterMod:accept_send_pdu(Domain, Address, pdu_type_of(Pdu))) of +handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State) -> + Verbosity = get(verbosity), + spawn_opt( + fun() -> + Log = worker_init(State, Verbosity), + Res = (catch maybe_handle_send_pdu( + Pdu, Vsn, MsgData, + Domain, Addr, + State#state{log = Log})), + worker_exit(send_pdu, {Domain, Addr}, Res) + end, + [monitor]). + +maybe_handle_send_pdu( + Pdu, Vsn, MsgData, Domain, Addr, + #state{filter = FilterMod, domain = ManagerDomain} = State) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; _ -> - do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, State) + do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State) end. -do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, - #state{server = Pid, - note_store = NoteStore, - sock = Sock, - log = Log, - filter = FilterMod}) -> - Logger = logger(Log, write, Domain, Address), - case (catch snmpm_mpd:generate_msg(Vsn, NoteStore, - Pdu, MsgData, Logger)) of +do_handle_send_pdu( + Pdu, Vsn, MsgData, Domain, Addr, + #state{server = Pid, + note_store = NoteStore, + log = Log} = State) -> + Logger = logger(Log, write, Domain, Addr), + case (catch snmpm_mpd:generate_msg( + Vsn, NoteStore, Pdu, MsgData, Logger)) of {ok, Msg} -> ?vtrace("do_handle_send_pdu -> message generated", []), - maybe_udp_send(FilterMod, Sock, Domain, Address, Msg); + maybe_udp_send(Domain, Addr, Msg, State); {discarded, Reason} -> ?vlog("PDU not sent: " "~n PDU: ~p" @@ -796,13 +821,21 @@ do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Address, ok end. +maybe_udp_send( + Domain, Addr, Msg, + #state{sock = Sock, filter = FilterMod, domain = ManagerDomain}) -> + maybe_udp_send(Domain, Addr, Msg, Sock, FilterMod, ManagerDomain). -maybe_udp_send(FilterMod, Sock, Domain, {Ip, Port} = Address, Msg) -> - case (catch FilterMod:accept_send(Domain, Address)) of +maybe_udp_send(Domain, Addr, Msg, Sock, FilterMod, ManagerDomain) -> + {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}), + case (catch FilterMod:accept_send(Arg1, Arg2)) of false -> inc(netIfMsgOutDrops), ok; _ -> + %% XXX There should be some kind of lookup of socket + %% from transport domain here + {Ip, Port} = Addr, udp_send(Sock, Ip, Port, Msg) end. @@ -1045,25 +1078,48 @@ worker_exit(Tag, Info, Result) -> handle_worker_exit(_, {_, _, ok}) -> ok; -handle_worker_exit(Pid, {udp, {Domain, Address}, ExitStatus}) -> - warning_msg("Worker process (~p) terminated " - "while processing (incomming) message from ~w:~w: " - "~n~p", [Pid, Domain, Address, ExitStatus]), +handle_worker_exit(Pid, {udp, {Domain, Addr}, ExitStatus}) -> + warning_msg( + "Worker process (~p) terminated " + "while processing (incomming) message from %s:~n" + "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]), ok; -handle_worker_exit(Pid, {send_pdu, {Domain, Address}, ExitStatus}) -> - warning_msg("Worker process (~p) terminated " - "while processing (outgoing) pdu for [~w] ~w: " - "~n~p", [Pid, Domain, Address, ExitStatus]), +handle_worker_exit(Pid, {send_pdu, {Domain, Addr}, ExitStatus}) -> + warning_msg( + "Worker process (~p) terminated " + "while processing (outgoing) pdu for %s:~n" + "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]), ok; -handle_worker_exit(Pid, {inform_response, {Domain, Address}, ExitStatus}) -> - warning_msg("Worker process (~p) terminated " - "while processing (outgoing) inform response for ~w:~w: " - "~n~p", [Pid, Domain, Address, ExitStatus]), +handle_worker_exit(Pid, {inform_response, {Domain, Addr}, ExitStatus}) -> + warning_msg( + "Worker process (~p) terminated " + "while processing (outgoing) inform response for %s:~n" + "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]), ok; handle_worker_exit(_, _) -> ok. +%% If the manager uses legacy snmpUDPDomain e.g has not set +%% {domain, _}, then make sure snmpm_network_interface_filter +%% gets legacy arguments to not break backwards compatibility. +%% +fix_filter_address(snmpUDPDomain, {Domain, Addr}) + when Domain =:= snmpUDPDomain; + Domain =:= transportDomainUdpIpv4 -> + Addr; +fix_filter_address(_ManagerDomain, {Domain, _} = Address) + when is_atom(Domain) -> + Address; +fix_filter_address(snmpUDPDomain, {_, Port} = Addr) + when is_integer(Port) -> + Addr. + +address(Domain, Addr) when is_atom(Domain) -> + {Domain, Addr}; +address(Ip, Port) when is_integer(Port) -> + {snmpm_config:default_transport_domain(), {Ip, Port}}. + %% ------------------------------------------------------------------- make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) -> @@ -1104,15 +1160,17 @@ t() -> %% ------------------------------------------------------------------- -logger(undefined, _Type, _Domain, _Address) -> +logger(undefined, _Type, _Domain, _Addr) -> fun(_) -> ok end; -logger({_Name, Log, Types}, Type, Domain, Address) -> +logger({_Name, Log, Types}, Type, Domain, Addr) -> case lists:member(Type, Types) of true -> + AddrString = + iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})), fun(Msg) -> - snmp_log:log(Log, Msg, Domain, Address) + snmp_log:log(Log, Msg, Domain, AddrString) end; false -> fun(_) -> diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 685c4dc9be..75560f8958 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -551,21 +551,28 @@ groups() -> otp8395_1 ] }, - {ipv6, [], - [ - simple_sync_get3, - inform1 - ] - }, - {ipv6_mt, [], - [ - simple_sync_get3, - inform1 - ] - } + {ipv6, [], ipv6_tests()}, + {ipv6_mt, [], ipv6_tests()} ]. +ipv6_tests() -> + [ + register_agent1, + simple_sync_get_next3, + simple_async_get2, + simple_sync_get3, + simple_async_get_next2, + simple_sync_set3, + simple_async_set2, + simple_sync_get_bulk2, + simple_async_get_bulk3, + misc_async2, + inform1, + inform_swarm + ]. + + init_per_group(request_tests_mt = GroupName, Config) -> snmp_test_lib:init_group_top_dir( GroupName, -- cgit v1.2.3 From 666559111508b65ab1379476b0d8c76c15e5700e Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 24 Jun 2014 15:54:48 +0200 Subject: Mend regression tests --- lib/snmp/test/snmp_agent_test.erl | 23 +++++++++++++++++------ lib/snmp/test/snmp_manager_config_test.erl | 5 +++-- lib/snmp/test/snmp_manager_test.erl | 12 ++++++++++-- 3 files changed, 30 insertions(+), 10 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 608a99062d..c13b64e8da 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -1725,7 +1725,7 @@ init_v1(Config) when is_list(Config) -> ?line AgentConfDir = ?config(agent_conf_dir, Config), ?line MgrDir = ?config(mgr_dir, Config), ?line Ip = ?config(ip, Config), - ?line IpFamily = ?config(ipfamily, Config), + ?line IpFamily = config_ipfamily(Config), ?line config( [v1], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), @@ -1798,7 +1798,7 @@ init_v2(Config) when is_list(Config) -> AgentConfDir = ?config(agent_conf_dir, Config), MgrDir = ?config(mgr_dir, Config), Ip = ?config(ip, Config), - IpFamily = ?config(ipfamily, Config), + IpFamily = config_ipfamily(Config), config( [v2], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), @@ -1820,7 +1820,7 @@ init_v1_v2(Config) when is_list(Config) -> AgentConfDir = ?config(agent_conf_dir, Config), MgrDir = ?config(mgr_dir, Config), Ip = ?config(ip, Config), - IpFamily = ?config(ipfamily, Config), + IpFamily = config_ipfamily(Config), config([v1,v2], MgrDir, AgentConfDir, tuple_to_list(Ip), tuple_to_list(Ip), IpFamily), [{vsn, bilingual} | start_bilingual_agent(Config)]. @@ -1909,7 +1909,7 @@ init_v3(Config) when is_list(Config) -> AgentConfDir = ?config(agent_conf_dir, Config), MgrDir = ?config(mgr_dir, Config), Ip = ?config(ip, Config), - IpFamily = ?config(ipfamily, Config), + IpFamily = config_ipfamily(Config), ?line ok = config( [v3], MgrDir, AgentConfDir, @@ -7430,7 +7430,8 @@ init_v1_agent(Config) -> ManagerHost = ?HOSTNAME(ManagerNode), Host = snmp_test_lib:hostname(), - IpFamily = ?LOCALHOST(?config(ipfamily, Config)), + IpFamily = config_ipfamily(Config), + Ip = ?LOCALHOST(IpFamily), {ok, AgentIP0} = snmp_misc:ip(AgentHost, IpFamily), AgentIP = tuple_to_list(AgentIP0), {ok, ManagerIP0} = snmp_misc:ip(ManagerHost, IpFamily), @@ -7458,7 +7459,7 @@ init_v1_agent(Config) -> %% Config2 = start_agent([{host, Host}, - {ip, IpFamily}, + {ip, Ip}, {agent_node, AgentNode}, {agent_host, AgentHost}, {agent_ip, AgentIP}, @@ -7508,3 +7509,13 @@ fin_v1_agent(Config) -> Dog = ?config(watchdog, Config), ?WD_STOP(Dog), lists:keydelete(watchdog, 1, Config). + + + +config_ipfamily(Config) -> + case ?config(ipfamily, Config) of + undefined -> + inet; + Value -> + Value + end. diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl index 3cdb2cfcbe..2f5c68d14d 100644 --- a/lib/snmp/test/snmp_manager_config_test.erl +++ b/lib/snmp/test/snmp_manager_config_test.erl @@ -720,7 +720,8 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) -> "[134,138,177,189]", "-1", "500", "\"bmkEngine\""), ?line {error, Reason22} = config_start(Opts), p("start failed (as expected): ~p", [Reason22]), - ?line {failed_check, _, _, 3, {invalid_integer, _}} = Reason22, + io:format("Reason22: ~p~n", [Reason22]), + ?line {failed_check, _, _, 3, {bad_port, _}} = Reason22, await_config_not_running(), %% -- @@ -729,7 +730,7 @@ start_with_invalid_manager_conf_file1(Conf) when is_list(Conf) -> "[134,138,177,189]", "\"kalle-anka\"", "500", "\"bmkEngine\""), ?line {error, Reason23} = config_start(Opts), p("start failed (as expected): ~p", [Reason23]), - ?line {failed_check, _, _, 3, {invalid_integer, _}} = Reason23, + ?line {failed_check, _, _, 3, {bad_port, _}} = Reason23, await_config_not_running(), %% -- diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 75560f8958..78352e59cf 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -581,8 +581,16 @@ init_per_group(event_tests_mt = GroupName, Config) -> snmp_test_lib:init_group_top_dir( GroupName, [{manager_net_if_module, snmpm_net_if_mt} | Config]); -init_per_group(ipv6_mt, Config) -> - init_per_group(ipv6, [{manager_net_if_module, snmpm_net_if_mt} | Config]); +init_per_group(ipv6_mt = GroupName, Config) -> + case ct:require(ipv6_hosts) of + ok -> + ipv6_init( + snmp_test_lib:init_group_top_dir( + GroupName, + [{manager_net_if_module, snmpm_net_if_mt} | Config])); + _ -> + {skip, "Host does not support IPV6"} + end; init_per_group(ipv6 = GroupName, Config) -> case ct:require(ipv6_hosts) of ok -> -- cgit v1.2.3 From f9a9d8e0dff57317e097dca852155de1c7c09142 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 24 Jun 2014 17:48:03 +0200 Subject: Mend loop_mib_* testcases --- lib/snmp/test/snmp_agent_test.erl | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index c13b64e8da..b181bf957d 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -37,7 +37,7 @@ v1_processing/1, big/1, big2/1, - loop_mib_1/1, + loop_mib_1/1, api/1, subagent/1, mnesia/1, @@ -389,9 +389,9 @@ usm_read/0, usm_del_user/0, usm_bad/0, - loop_mib_1_test/0, - loop_mib_2_test/0, - loop_mib_3_test/0, + loop_mib_1_test/0, + loop_mib_2_test/0, + loop_mib_3_test/0, otp_1129_i/1, otp_1162_test/0, otp_1131_test/0, @@ -898,8 +898,8 @@ start_v2_agent(Config) -> start_v2_agent(Config, Opts) -> snmp_agent_test_lib:start_v2_agent(Config, Opts). -start_v3_agent(Config) -> - snmp_agent_test_lib:start_v3_agent(Config). +%% start_v3_agent(Config) -> +%% snmp_agent_test_lib:start_v3_agent(Config). start_v3_agent(Config, Opts) -> snmp_agent_test_lib:start_v3_agent(Config, Opts). @@ -1669,7 +1669,7 @@ del_dir(Dir, Depth) -> ok end. -%v1_cases() -> [loop_mib]; +%v1_cases() -> [loop_mib_1]; v1_cases() -> [ simple, @@ -1677,7 +1677,7 @@ v1_cases() -> v1_processing, big, big2, - loop_mib_1, + loop_mib_1, api, subagent, mnesia, @@ -1699,7 +1699,7 @@ v1_cases_ipv6() -> [ simple, v1_processing, - loop_mib, + loop_mib_1, %% big, %% big2, api, @@ -5670,7 +5670,7 @@ usm_bad() -> %%----------------------------------------------------------------- loop_mib_1(suite) -> []; loop_mib_1(Config) when is_list(Config) -> - ?P(loop_mib_1), + ?P(loop_mib_1), ?LOG("loop_mib_1 -> initiate case",[]), %% snmpa:verbosity(master_agent,debug), %% snmpa:verbosity(mib_server,info), @@ -5678,7 +5678,7 @@ loop_mib_1(Config) when is_list(Config) -> ?DBG("loop_mib_1 -> ~n" "\tSaNode: ~p~n" "\tMgrNode: ~p~n" - "\tMibDir: ~p", [_SaNode, _MgrNode, _MibDir]), + "\tMibDir: ~p",[_SaNode, _MgrNode, _MibDir]), ?DBG("loop_mib_1 -> load mib SNMP-COMMUNITY-MIB",[]), ?line load_master_std("SNMP-COMMUNITY-MIB"), ?DBG("loop_mib_1 -> load mib SNMP-MPD-MIB",[]), @@ -6502,10 +6502,6 @@ otp_4394_config(AgentConfDir, MgrDir, Ip0) -> ?line write_notify_conf(AgentConfDir), ok. -ipv6_init(Config) when is_list(Config) -> - Opts = [], - [{vsn, v1} | start_v1_agent(Config, Opts)]. - otp_4394_finish(Config) when is_list(Config) -> ?DBG("finish_otp_4394 -> entry", []), C1 = stop_agent(Config), -- cgit v1.2.3 From c7d97f4d7a27bd6aca3b6335c90e6a51e28e6719 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Wed, 25 Jun 2014 08:55:53 +0200 Subject: snmp: Add new test suite --- lib/snmp/test/Makefile | 4 +- lib/snmp/test/modules.mk | 1 + lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 235 ++++++++++++++++++++++++++++++++ 3 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 lib/snmp/test/snmp_to_snmpnet_SUITE.erl (limited to 'lib/snmp') diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile index 7bc9dd07d4..d2eca0b250 100644 --- a/lib/snmp/test/Makefile +++ b/lib/snmp/test/Makefile @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2012. All Rights Reserved. +# Copyright Ericsson AB 1997-2014. 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 @@ -36,7 +36,7 @@ VSN = $(SNMP_VSN) include modules.mk SNMP_ROOT = .. -SNMP_SUITE = snmp_SUITE +SNMP_SUITE = snmp_SUITE ERL_FILES = $(MODULES:%=%.erl) diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk index fd8315ec4d..1bf08a9729 100644 --- a/lib/snmp/test/modules.mk +++ b/lib/snmp/test/modules.mk @@ -19,6 +19,7 @@ SUITE_MODULES = \ snmp_SUITE \ + snmp_to_snmpnet_SUITE \ snmp_app_test \ snmp_appup_test \ snmp_compiler_test \ diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl new file mode 100644 index 0000000000..4584ad75c2 --- /dev/null +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -0,0 +1,235 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2014-2014. All Rights Reserved. +%% +%% The contents of this file are subject to the Erlang Public License, +%% Version 1.1, (the "License"); you may not use this file except in +%% compliance with the License. You should have received a copy of the +%% Erlang Public License along with this software. If not, it can be +%% retrieved online at http://www.erlang.org/. +%% +%% Software distributed under the License is distributed on an "AS IS" +%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +%% the License for the specific language governing rights and limitations +%% under the License. +%% +%% %CopyrightEnd% +%% +%% + +-module(snmp_to_snmpnet_SUITE). + +%% Note: This directive should only be used in test suites. +-compile(export_all). + +-include_lib("common_test/include/ct.hrl"). +-include_lib("snmp/include/STANDARD-MIB.hrl"). + +-define(AGENT_ENGIN_ID, "ErlangSnmpAgent"). +-define(AGENT_PORT, 4000). +-define(DEFAULT_MAX_MESSAGE_SIZE, 484). +-define(SYS_DESC, "iso.3.6.1.2.1.1.1.0 = STRING: \"Erlang SNMP agent\"\n"). + +%%-------------------------------------------------------------------- +%% Common Test interface functions ----------------------------------- +%%-------------------------------------------------------------------- + +suite() -> [{ct_hooks,[ts_install_cth]}]. + +all() -> + [ + {group, ipv4}, + {group, ipv6} + ]. + +groups() -> + [{ipv4, [], ipv4_tests()}, + {ipv6, [], ipv6_tests()}, + {get, [], get_tests()}, + %%{trap, [], trap_tests()}, + {dual_ip, [], dual_ip_tests()}]. + +get_tests() -> + [erlang_agent_netsnmp_get]. +trap_tests() -> + [erlang_agent_netsnmp_trap]. +dual_ip_tests() -> + [erlang_agent_dual_ip_get]. +ipv4_tests() -> + [{group, get}]. +ipv6_tests() -> + [{group, get}, + {group, dual_ip} + ]. + +init_per_suite(Config) -> + case os:find_executable("snmpget") of + false -> + {skip, "snmpget not found"}; + _ -> + Config + end. + +end_per_suite(_Config) -> + ok. + +init_per_group(ipv6, Config) -> + case ct:require(ipv6_hosts) of + ok -> + Dir = ?config(priv_dir, Config), + Domain = transportDomainUdpIpv6, + {ok, Host} = inet:gethostname(), + {ok, IpAddr} = inet:getaddr(Host, inet6), + Versions = [v2], + agent_config(Dir, Domain, IpAddr, IpAddr, ?AGENT_PORT, Versions), + [{host, Host}, {port, ?AGENT_PORT}, + {snmp_versions, Versions}, {ip_version, ipv6} | Config]; + _ -> + {skip, "Host does not support IPV6"} + end; + +init_per_group(ipv4, Config) -> + Dir = ?config(priv_dir, Config), + Domain = transportDomainUdpIpv4, + {ok, Host} = inet:gethostname(), + {ok, IpAddr} = inet:getaddr(Host, inet), + Versions = [v2], + agent_config(Dir, Domain, IpAddr, IpAddr, ?AGENT_PORT, Versions), + [{host, Host}, {port, ?AGENT_PORT}, {snmp_versions, Versions}, + {ip_version, ipv4} | Config]; + +init_per_group(get, Config) -> + case os:find_executable("snmpget") of + false -> + {skip, "snmpget not found"}; + _ -> + Config + end; + +init_per_group(trap, Config) -> + case os:find_executable("snmptrapd") of + false -> + {skip, "snmptrapd not found"}; + _ -> + Config + end; +init_per_group(_, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +init_per_testcase(Case, Config) -> + end_per_testcase(Case, Config), + application:start(snmp), + application:load(snmp), + application:set_env(snmp, agent, app_env(Case, Config)), + snmp:start_agent(normal), + Config. + +end_per_testcase(_, Config) -> + application:stop(snmp), + Config. + +%%-------------------------------------------------------------------- +%% Test Cases -------------------------------------------------------- +%%-------------------------------------------------------------------- +erlang_agent_netsnmp_get() -> + [{doc,"Test that we can access erlang snmp agent " + "from snmpnet manager"}]. + +erlang_agent_netsnmp_get(Config) when is_list(Config) -> + Host = ?config(host, Config), + Port = ?config(port, Config), + IPVersion = ?config(ip_version, Config), + Versions = ?config(snmp_versions, Config), + + Cmd = "snmpget -c public " ++ net_snmp_version(Versions) ++ " " ++ + net_snmp_ip_version(IPVersion) ++ + Host ++ ":" ++ integer_to_list(Port) ++ + " " ++ oid_str(?sysDescr_instance), + net_snmp(Cmd, ?SYS_DESC). + +%%-------------------------------------------------------------------- +erlang_agent_dual_ip_get() -> + [{doc,"Test that we can access erlang snmp agent from both " + "snmpnet ipv4 and snmpnet ipv6 manager at the same time"}]. +erlang_agent_dual_ip_get(Config) when is_list(Config) -> + erlang_agent_netsnmp_get([{ip_version, ipv4}]), + erlang_agent_netsnmp_get([{ip_version, ipv6}]). +%%-------------------------------------------------------------------- +erlang_agent_netsnmp_trap() -> + %% Host = ?config(host, Config), + %% Port = ?config(port, Config), + %% IPVersion = ?config(ip_version, Config), + %% Versions = ?config(snmp_versions, Config), + + Cmd = "", + net_snmp(Cmd, ""). + +%%-------------------------------------------------------------------- +%% Internal functions ------------------------------------------------ +%%-------------------------------------------------------------------- +net_snmp(Cmd, Expect) -> + SnmpNetPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + receive + {SnmpNetPort, {data, Expect}} -> + ok; + Msg -> + ct:fail({{expected, {SnmpNetPort, {data, Expect}}}, + {got, Msg}}) + end. + +app_env(_Case, Config) -> + Dir = ?config(priv_dir, Config), + Vsns = ?config(snmp_versions, Config), + [{versions, Vsns}, + {agent_type, master}, + {agent_verbosity, trace}, + {db_dir, Dir}, + {audit_trail_log, [{type, read_write}, + {dir, Dir}, + {size, {10240, 10}}]}, + {config, [{dir, Dir}, + {force_load, false}, + {verbosity, trace}]}, + {local_db, [{repair, true}, + {verbosity, silence}]}, + {mib_server, [{verbosity, silence}]}, + {symbolic_store, [{verbosity, silence}]}, + {note_store, [{verbosity, silence}]}, + {net_if, [{verbosity, trace}]}]. + +oid_str([Int | Rest]) -> + oid_str(Rest, integer_to_list(Int)). + +oid_str([], Acc) -> + Acc; +oid_str([Int | Rest], Acc) -> + oid_str(Rest, Acc ++ "." ++ integer_to_list(Int)). + +agent_config(Dir, Domain, IpA, IpM, Port, Versions) -> + EngineID = ?AGENT_ENGIN_ID, + MMS = ?DEFAULT_MAX_MESSAGE_SIZE, + snmp_config:write_agent_snmp_conf(Dir, Domain, {IpA, Port}, + EngineID, MMS), + snmp_config:write_agent_snmp_context_conf(Dir), + snmp_config:write_agent_snmp_community_conf(Dir), + snmp_config:write_agent_snmp_standard_conf(Dir, "snmp_to_snmpnet_SUITE"), + snmp_config:write_agent_snmp_target_addr_conf(Dir, Domain, + IpM, Versions), + snmp_config:write_agent_snmp_target_params_conf(Dir, Versions), + snmp_config:write_agent_snmp_notify_conf(Dir, inform), + snmp_config:write_agent_snmp_vacm_conf(Dir, Versions, none). + +net_snmp_version([v3 | _]) -> + "-v3"; +net_snmp_version([v2 | _]) -> + "-v2c"; +net_snmp_version([v1 | _]) -> + "-v1". +net_snmp_ip_version(ipv4) -> + "udp:"; +net_snmp_ip_version(ipv6) -> + "udp6:". -- cgit v1.2.3 From 1ebfcb6f1f013e62aabc9935c878a55b788967a9 Mon Sep 17 00:00:00 2001 From: Ingela Anderton Andin Date: Fri, 27 Jun 2014 15:41:18 +0200 Subject: snmp: Add inform test --- lib/snmp/test/Makefile | 1 + lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 127 ++++++++++++--------- .../test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin | Bin 0 -> 3640 bytes .../test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib | 71 ++++++++++++ 4 files changed, 148 insertions(+), 51 deletions(-) create mode 100644 lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin create mode 100644 lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib (limited to 'lib/snmp') diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile index d2eca0b250..a9bbe7fe62 100644 --- a/lib/snmp/test/Makefile +++ b/lib/snmp/test/Makefile @@ -239,6 +239,7 @@ release_tests_spec: opt $(INSTALL_DATA) $(RELTEST_FILES) $(COVER_SPEC_FILE) "$(RELSYSDIR)" chmod -R u+w "$(RELSYSDIR)" tar cf - snmp_test_data | (cd "$(RELSYSDIR)"; tar xf -) + tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) release_docs_spec: diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index 4584ad75c2..e8dcffd361 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -27,7 +27,8 @@ -include_lib("snmp/include/STANDARD-MIB.hrl"). -define(AGENT_ENGIN_ID, "ErlangSnmpAgent"). --define(AGENT_PORT, 4000). +-define(AGENT_PORT, 4000). +-define(MANAGER_PORT, 8989). -define(DEFAULT_MAX_MESSAGE_SIZE, 484). -define(SYS_DESC, "iso.3.6.1.2.1.1.1.0 = STRING: \"Erlang SNMP agent\"\n"). @@ -44,33 +45,21 @@ all() -> ]. groups() -> - [{ipv4, [], ipv4_tests()}, - {ipv6, [], ipv6_tests()}, - {get, [], get_tests()}, - %%{trap, [], trap_tests()}, - {dual_ip, [], dual_ip_tests()}]. - -get_tests() -> - [erlang_agent_netsnmp_get]. -trap_tests() -> - [erlang_agent_netsnmp_trap]. -dual_ip_tests() -> - [erlang_agent_dual_ip_get]. -ipv4_tests() -> - [{group, get}]. -ipv6_tests() -> - [{group, get}, - {group, dual_ip} + [{ipv4, [], [{group, get}, + {group, inform} + ]}, + {ipv6, [], [{group, get}, + {group, inform}, + {group, dual_ip} + ]}, + {get, [], [erlang_agent_netsnmp_get]}, + {inform, [], [erlang_agent_netsnmp_inform]}, + {dual_ip, [], [erlang_agent_dual_ip_get]} ]. init_per_suite(Config) -> - case os:find_executable("snmpget") of - false -> - {skip, "snmpget not found"}; - _ -> - Config - end. - + [{agent_port, ?AGENT_PORT}, {manager_port, ?MANAGER_PORT} | Config]. + end_per_suite(_Config) -> ok. @@ -82,8 +71,8 @@ init_per_group(ipv6, Config) -> {ok, Host} = inet:gethostname(), {ok, IpAddr} = inet:getaddr(Host, inet6), Versions = [v2], - agent_config(Dir, Domain, IpAddr, IpAddr, ?AGENT_PORT, Versions), - [{host, Host}, {port, ?AGENT_PORT}, + agent_config(Dir, Domain, IpAddr, IpAddr, ?config(agent_port, Config), Versions), + [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv6} | Config]; _ -> {skip, "Host does not support IPV6"} @@ -95,11 +84,13 @@ init_per_group(ipv4, Config) -> {ok, Host} = inet:gethostname(), {ok, IpAddr} = inet:getaddr(Host, inet), Versions = [v2], - agent_config(Dir, Domain, IpAddr, IpAddr, ?AGENT_PORT, Versions), - [{host, Host}, {port, ?AGENT_PORT}, {snmp_versions, Versions}, + agent_config(Dir, Domain, IpAddr, {IpAddr, ?config(manager_port, Config)}, + ?config(agent_port, Config), Versions), + [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv4} | Config]; init_per_group(get, Config) -> + %% From Ubuntu package snmp case os:find_executable("snmpget") of false -> {skip, "snmpget not found"}; @@ -107,7 +98,8 @@ init_per_group(get, Config) -> Config end; -init_per_group(trap, Config) -> +init_per_group(inform, Config) -> + %% From Ubuntu package snmptrapfmt case os:find_executable("snmptrapd") of false -> {skip, "snmptrapd not found"}; @@ -121,12 +113,13 @@ end_per_group(_GroupName, Config) -> Config. init_per_testcase(Case, Config) -> + Dog = ct:timetrap(10000), end_per_testcase(Case, Config), application:start(snmp), application:load(snmp), application:set_env(snmp, agent, app_env(Case, Config)), snmp:start_agent(normal), - Config. + [{watchdog, Dog} | Config]. end_per_testcase(_, Config) -> application:stop(snmp), @@ -141,10 +134,10 @@ erlang_agent_netsnmp_get() -> erlang_agent_netsnmp_get(Config) when is_list(Config) -> Host = ?config(host, Config), - Port = ?config(port, Config), + Port = ?config(agent_port, Config), IPVersion = ?config(ip_version, Config), Versions = ?config(snmp_versions, Config), - + Cmd = "snmpget -c public " ++ net_snmp_version(Versions) ++ " " ++ net_snmp_ip_version(IPVersion) ++ Host ++ ":" ++ integer_to_list(Port) ++ @@ -159,26 +152,58 @@ erlang_agent_dual_ip_get(Config) when is_list(Config) -> erlang_agent_netsnmp_get([{ip_version, ipv4}]), erlang_agent_netsnmp_get([{ip_version, ipv6}]). %%-------------------------------------------------------------------- -erlang_agent_netsnmp_trap() -> - %% Host = ?config(host, Config), - %% Port = ?config(port, Config), - %% IPVersion = ?config(ip_version, Config), - %% Versions = ?config(snmp_versions, Config), +erlang_agent_netsnmp_inform(Config) when is_list(Config) -> + Host = ?config(host, Config), + IPVersion = ?config(ip_version, Config), + DataDir = ?config(data_dir, Config), + ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, "TestTrapv2")), - Cmd = "", - net_snmp(Cmd, ""). + Cmd = "snmptrapd -L o -M " ++ DataDir ++ + " --disableAuthorization=yes" ++ + " --snmpTrapdAddr=" ++ net_snmp_ip_version(IPVersion) ++ + Host ++ ":" ++ integer_to_list(?config(manager_port, Config)), + NetSnmpPort = net_snmp_trapd(Cmd), + snmpa:send_notification(snmp_master_agent, testTrapv22, + {erlang_agent_test, self()}), + net_snmp_log(NetSnmpPort), + receive + {snmp_targets, erlang_agent_test, Addresses} -> + ct:pal("Notification sent to: ~p~n", [Addresses]) + end, + receive + {snmp_notification, erlang_agent_test, {got_response, Address}} -> + ct:pal("Got respons from: ~p~n", [Address]), + ok; + {snmp_notification, erlang_agent_test, {no_response, _} = + NoResponse} -> + ct:fail(NoResponse) + end. + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- net_snmp(Cmd, Expect) -> - SnmpNetPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + NetSnmpPort = open_port({spawn, Cmd}, [stderr_to_stdout]), receive - {SnmpNetPort, {data, Expect}} -> + {NetSnmpPort, {data, Expect}} -> ok; Msg -> - ct:fail({{expected, {SnmpNetPort, {data, Expect}}}, + ct:fail({{expected, {NetSnmpPort, {data, Expect}}}, {got, Msg}}) + end, + catch erlang:port_close(NetSnmpPort). + +net_snmp_trapd(Cmd) -> + open_port({spawn, Cmd}, [stderr_to_stdout]). + +net_snmp_log(NetSnmpPort) -> + receive + {NetSnmpPort, {data, Data}} -> + ct:pal("Received from netsnmp: ~p~n", [Data]), + net_snmp_log(NetSnmpPort) + after 500 -> + catch erlang:port_close(NetSnmpPort) end. app_env(_Case, Config) -> @@ -212,16 +237,16 @@ oid_str([Int | Rest], Acc) -> agent_config(Dir, Domain, IpA, IpM, Port, Versions) -> EngineID = ?AGENT_ENGIN_ID, MMS = ?DEFAULT_MAX_MESSAGE_SIZE, - snmp_config:write_agent_snmp_conf(Dir, Domain, {IpA, Port}, + ok = snmp_config:write_agent_snmp_conf(Dir, Domain, {IpA, Port}, EngineID, MMS), - snmp_config:write_agent_snmp_context_conf(Dir), - snmp_config:write_agent_snmp_community_conf(Dir), - snmp_config:write_agent_snmp_standard_conf(Dir, "snmp_to_snmpnet_SUITE"), - snmp_config:write_agent_snmp_target_addr_conf(Dir, Domain, + ok = snmp_config:write_agent_snmp_context_conf(Dir), + ok = snmp_config:write_agent_snmp_community_conf(Dir), + ok = snmp_config:write_agent_snmp_standard_conf(Dir, "snmp_to_snmpnet_SUITE"), + ok = snmp_config:write_agent_snmp_target_addr_conf(Dir, Domain, IpM, Versions), - snmp_config:write_agent_snmp_target_params_conf(Dir, Versions), - snmp_config:write_agent_snmp_notify_conf(Dir, inform), - snmp_config:write_agent_snmp_vacm_conf(Dir, Versions, none). + ok = snmp_config:write_agent_snmp_target_params_conf(Dir, Versions), + ok = snmp_config:write_agent_snmp_notify_conf(Dir, inform), + ok = snmp_config:write_agent_snmp_vacm_conf(Dir, Versions, none). net_snmp_version([v3 | _]) -> "-v3"; diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin new file mode 100644 index 0000000000..9d0790498d Binary files /dev/null and b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.bin differ diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib new file mode 100644 index 0000000000..679ddc14b0 --- /dev/null +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/TestTrapv2.mib @@ -0,0 +1,71 @@ +TestTrapv2 DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, + TimeTicks, Counter32, snmpModules, mib-2, enterprises, IpAddress, + Integer32 + FROM SNMPv2-SMI + DisplayString, TestAndIncr, TimeStamp, RowStatus, TruthValue, + TEXTUAL-CONVENTION + FROM SNMPv2-TC + MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP + FROM SNMPv2-CONF + + system, snmp, ifIndex, ifAdminStatus, ifOperStatus + FROM RFC1213-MIB + snmpTraps + FROM SNMPv2-MIB; + +testTrapv2 MODULE-IDENTITY + LAST-UPDATED "9511090000Z" + ORGANIZATION "IETF SNMPv2 Working Group" + CONTACT-INFO + " Marshall T. Rose + + Postal: Dover Beach Consulting, Inc. + 420 Whisman Court + Mountain View, CA 94043-2186 + US + + Tel: +1 415 968 1052 + + E-mail: mrose@dbc.mtview.ca.us" + DESCRIPTION + "The MIB module for SNMPv2 entities." + REVISION "9304010000Z" + DESCRIPTION + "The initial revision of this MIB module was published as + RFC 1450." + ::= { system 100 } + + +tst OBJECT IDENTIFIER ::= { system 0 } + +testTrapv21 NOTIFICATION-TYPE + STATUS current + DESCRIPTION + "This trap is exactly the v2 correspondance of testTrap1 in + TestTrap mib." + ::= { snmp 1 } + +testTrapv22 NOTIFICATION-TYPE + STATUS current + DESCRIPTION + "This trap is exactly the v2 correspondance of testTrap2 in + TestTrap mib." + ::= { system 0 1 } + +linkUp NOTIFICATION-TYPE + OBJECTS { ifIndex, ifAdminStatus, ifOperStatus } + STATUS current + DESCRIPTION + "A linkUp trap signifies that the SNMPv2 entity, + acting in an agent role, has detected that the + ifOperStatus object for one of its communication links + has transitioned out of the down state." + ::= { snmpTraps 4 } + + + + +END -- cgit v1.2.3 From dfb5cf6e2406486eeb7fbd89bf9118a6411bd5f2 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 26 Jun 2014 10:50:24 +0200 Subject: Rewrite agent for IPv4 + IPv6 --- lib/snmp/src/agent/snmp_framework_mib.erl | 86 ++- lib/snmp/src/agent/snmp_target_mib.erl | 12 +- lib/snmp/src/agent/snmpa_conf.erl | 93 +-- lib/snmp/src/agent/snmpa_net_if.erl | 1020 +++++++++++++++++++---------- lib/snmp/src/agent/snmpa_trap.erl | 145 ++-- lib/snmp/src/misc/snmp_conf.erl | 8 +- lib/snmp/src/misc/snmp_config.erl | 12 +- lib/snmp/test/klas3.erl | 1 + 8 files changed, 899 insertions(+), 478 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 4599f05f47..3b33cae3ec 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -41,7 +41,7 @@ -compile({no_auto_import,[error/1]}). -export([init/0, configure/1]). -export([intContextTable/1, intContextTable/3, - intAgentTransportDomain/1, + intAgentTransportDomain/1, intAgentTransports/1, intAgentUDPPort/1, intAgentIpAddress/1, snmpEngineID/1, snmpEngineBoots/1, @@ -137,8 +137,9 @@ read_agent(Dir) -> error({failed_reading_config_file, Dir, FileName, Reason}) end, Mand = - [{intAgentIpAddress, mandatory}, - {intAgentUDPPort, mandatory}, + [{intAgentTransports, mandatory}, +%%% {intAgentIpAddress, mandatory}, +%%% {intAgentUDPPort, mandatory}, {snmpEngineMaxMessageSize, mandatory}, {snmpEngineID, mandatory}], {ok, Conf} = snmp_conf:check_mandatory(Conf0, Mand), @@ -190,27 +191,63 @@ check_context(Context) -> %% Agent %% {Name, Value}. %%----------------------------------------------------------------- -check_agent({intAgentTransportDomain, D}, _Domain) -> - {snmp_conf:check_domain(D), D}; -check_agent({intAgentIpAddress = Tag, Value}, D) -> - Domain = - case D of - undefined -> - snmp_target_mib:default_domain(); - _ -> - D - end, - {case snmp_conf:check_ip(Domain, Value) of +check_agent(Entry, undefined) -> + check_agent(Entry, {snmp_target_mib:default_domain(), undefined}); +check_agent({intAgentTransportDomain, Domain}, {_, Port}) -> + {snmp_conf:check_domain(Domain), {Domain, Port}}; +check_agent({intAgentUDPPort, Port}, {Domain, _}) -> + ok = snmp_conf:check_port(Port), + {ok, {Domain, Port}}; +check_agent({intAgentIpAddress, _}, {_, undefined}) -> + error({missing_mandatory, intAgentUDPPort}); +check_agent({intAgentIpAddress = Tag, Ip} = Entry, {Domain, Port} = State) -> + {case snmp_conf:check_ip(Domain, Ip) of ok -> - ok; + [Entry, {intAgentTransports, [{Domain, {Ip, Port}}]}]; {ok, FixedIp} -> - {ok, {Tag, FixedIp}} - end, Domain}; -check_agent(Entry, Domain) -> - {check_agent(Entry), Domain}. + [{Tag, Ip}, {intAgentTransports, [{Domain, {FixedIp, Port}}]}] + end, State}; +check_agent({intAgentTransports = Tag, Transports}, {_, Port} = State) -> + CheckedTransports = + [case + case Port of + undefined -> + snmp_conf:check_address(Domain, Address); + _ -> + snmp_conf:check_address(Domain, Address, Port) + end + of + ok -> + Transport; + {ok, FixedAddress} -> + {Domain, FixedAddress} + end + || {Domain, Address} = Transport <- Transports], + {{ok, {Tag, CheckedTransports}}, State}; +check_agent(Entry, State) -> + {check_agent(Entry), State}. + +%%% XXX remove +%%% +%%% check_agent({intAgentTransportDomain, D}, _Domain) -> +%%% {snmp_conf:check_domain(D), D}; +%%% check_agent({intAgentIpAddress = Tag, Value}, D) -> +%%% Domain = +%%% case D of +%%% undefined -> +%%% snmp_target_mib:default_domain(); +%%% _ -> +%%% D +%%% end, +%%% {case snmp_conf:check_ip(Domain, Value) of +%%% ok -> +%%% ok; +%%% {ok, FixedIp} -> +%%% {ok, {Tag, FixedIp}} +%%% end, Domain}; +%%% check_agent(Entry, Domain) -> +%%% {check_agent(Entry), Domain}. -check_agent({intAgentUDPPort, Value}) -> - snmp_conf:check_integer(Value); %% This one is kept for backwards compatibility check_agent({intAgentMaxPacketSize, Value}) -> snmp_conf:check_packet_size(Value); @@ -224,7 +261,9 @@ check_agent(X) -> %% Ordering function to sort intAgentTransportDomain first %% hence before intAgentIpAddress. Sort other entries on the key. order_agent(EntryA, EntryB) -> - snmp_conf:keyorder(1, EntryA, EntryB, [intAgentTransportDomain | sort]). + snmp_conf:keyorder( + 1, EntryA, EntryB, + [intAgentTransportDomain, intAgentUDPPort | sort]). @@ -402,6 +441,9 @@ intAgentIpAddress(Op) -> intAgentTransportDomain(Op) -> snmp_generic:variable_func(Op, db(intAgentTransportDomain)). +intAgentTransports(Op) -> + snmp_generic:variable_func(Op, db(intAgentTransports)). + snmpEngineID(print) -> diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 932829e150..e916f17d6a 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -174,7 +174,8 @@ check_target_addr( EngineId, TMask, MMS); check_target_addr( {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, - EngineId, TMask, MMS}) -> % Arity 10 + EngineId, TMask, MMS}) + when is_integer(Udp) -> % Arity 10 Domain = default_domain(), Address = {Ip, Udp}, check_target_addr( @@ -189,7 +190,8 @@ check_target_addr( EngineId); check_target_addr( {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, - EngineId}) -> % Arity 8 + EngineId}) % Arity 8 + when is_integer(Udp) -> Domain = default_domain(), Address = {Ip, Udp}, check_target_addr( @@ -202,7 +204,8 @@ check_target_addr( check_target_addr( Name, Domain, Address, Timeout, RetryCount, TagList, Params); check_target_addr( - {Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) -> % Arity 7 + {Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) % Arity 7 + when is_integer(Udp) -> Domain = default_domain(), Address = {Ip, Udp}, check_target_addr( @@ -216,7 +219,8 @@ check_target_addr( Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS); check_target_addr( {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, - TMask, MMS}) -> % Arity 9 + TMask, MMS}) % Arity 9 + when is_integer(Udp) -> Domain = default_domain(), Address = {Ip, Udp}, check_target_addr( diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index 2569b01b55..b4d32dc928 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -140,6 +140,8 @@ write_agent_conf(Fd, [H|T]) -> do_write_agent_conf(Fd, H), write_agent_conf(Fd, T). +do_write_agent_conf(Fd, {intAgentTransports = Tag, Val}) -> + io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); do_write_agent_conf(Fd, {intAgentTransportDomain = Tag, Val}) -> io:format(Fd, "{~w, ~w}.~n", [Tag, Val]); do_write_agent_conf(Fd, {intAgentIpAddress = Tag, Val}) -> @@ -379,72 +381,35 @@ do_write_standard_conf(_Fd, Tag, Val) -> %% ------ target_addr.conf ------ %% -target_addr_entry(Name, - Ip, - TagList, - ParamsName, - EngineId) -> +target_addr_entry( + Name, Ip, TagList, ParamsName, EngineId) -> target_addr_entry(Name, Ip, TagList, ParamsName, EngineId, []). -target_addr_entry(Name, - Ip, - TagList, - ParamsName, - EngineId, - TMask) -> - target_addr_entry(Name, Ip, 162, TagList, - ParamsName, EngineId, - TMask, 2048). - -target_addr_entry(Name, - Ip, - Udp, - TagList, - ParamsName, - EngineId, - TMask, - MaxMessageSize) -> - target_addr_entry(Name, Ip, Udp, 1500, 3, TagList, - ParamsName, EngineId, - TMask, MaxMessageSize). - -target_addr_entry(Name, - Ip, - Udp, - Timeout, - RetryCount, - TagList, - ParamsName, - EngineId, - TMask, - MaxMessageSize) -> - target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp, - Timeout, RetryCount, TagList, - ParamsName, EngineId, - TMask, MaxMessageSize). - -target_addr_entry(Name, - Domain, - Ip, - Udp, - Timeout, - RetryCount, - TagList, - ParamsName, - EngineId, - TMask, - MaxMessageSize) -> - {Name, - Domain, - Ip, - Udp, - Timeout, - RetryCount, - TagList, - ParamsName, - EngineId, - TMask, - MaxMessageSize}. +target_addr_entry( + Name, Ip, TagList, ParamsName, + EngineId, TMask) -> + target_addr_entry( + Name, Ip, 162, TagList, ParamsName, + EngineId, TMask, 2048). + +target_addr_entry( + Name, Domain_or_Ip, Addr_or_Port, TagList, + ParamsName, EngineId, TMask, MaxMessageSize) -> + target_addr_entry( + Name, Domain_or_Ip, Addr_or_Port, 1500, 3, TagList, + ParamsName, EngineId, TMask, MaxMessageSize). + +target_addr_entry( + Name, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize) -> + {Name, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}. + +target_addr_entry( + Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, + ParamsName, EngineId,TMask, MaxMessageSize) -> + {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize}. write_target_addr_config(Dir, Conf) -> diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 875ea19097..f5fd377341 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -35,19 +35,27 @@ -include("snmp_debug.hrl"). -include("snmp_verbosity.hrl"). --record(state, {parent, - note_store, - master_agent, - usock, - usock_opts, - mpd_state, - log, - reqs = [], - debug = false, - limit = infinity, - rcnt = [], - filter, - domain = snmpUDPDomain}). +-record(state, + {parent, + note_store, + master_agent, + transports = [], +%% usock, +%% usock_opts, + mpd_state, + log, + reqs = [], + debug = false, + limit = infinity, +%% rcnt = [], + filter}). +%% domain = snmpUDPDomain}). + +-record(transport, + {socket, + domain = snmpUDPDomain, + opts = [], + req_refs = []}). -ifndef(default_verbosity). -define(default_verbosity,silence). @@ -105,21 +113,27 @@ get_request_limit(Pid) -> set_request_limit(Pid, NewLimit) -> call(Pid, {set_request_limit, NewLimit}). -get_port() -> - {value, UDPPort} = snmp_framework_mib:intAgentUDPPort(get), - UDPPort. +get_transports() -> + {value, Transports} = snmp_framework_mib:intAgentTransports(get), + Transports. -get_address() -> - {value, IPAddress} = snmp_framework_mib:intAgentIpAddress(get), - IPAddress. - -get_domain() -> - case snmp_framework_mib:intAgentTransportDomain(get) of - {value, Domain} -> - Domain; - genErr -> - snmpUDPDomain - end. +%%% XXX remove +%%% +%%% get_ip_port() -> +%%% {value, UDPPort} = snmp_framework_mib:intAgentUDPPort(get), +%%% UDPPort. +%%% +%%% get_address() -> +%%% {value, IPAddress} = snmp_framework_mib:intAgentIpAddress(get), +%%% IPAddress. +%%% +%%% get_domain() -> +%%% case snmp_framework_mib:intAgentTransportDomain(get) of +%%% {value, Domain} -> +%%% Domain; +%%% genErr -> +%%% snmpUDPDomain +%%% end. filter_reset(Pid) -> Pid ! filter_reset. @@ -170,13 +184,15 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> put(verbosity,get_verbosity(Opts)), ?vlog("starting",[]), - %% -- Port and address -- - Domain = get_domain(), - ?vdebug("domain: ~w",[Domain]), - UDPPort = get_port(), - ?vdebug("port: ~w",[UDPPort]), - IPAddress = get_address(), - ?vdebug("addr: ~w",[IPAddress]), +%%% XXX remove +%%% +%%% %% -- Port and address -- +%%% Domain = get_domain(), +%%% ?vdebug("domain: ~w",[Domain]), +%%% UDPPort = get_ip_port(), +%%% ?vdebug("port: ~w",[UDPPort]), +%%% IPAddress = get_address(), +%%% ?vdebug("addr: ~w",[IPAddress]), %% -- Versions -- Vsns = get_vsns(Opts), @@ -193,37 +209,73 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> Log = create_log(), ?vdebug("Log: ~w",[Log]), - - %% -- Socket -- - IPOpts1 = ip_opt_bind_to_ip_address(Opts, IPAddress), - IPOpts2 = ip_opt_no_reuse_address(Opts), - IPOpts3 = ip_opt_recbuf(Opts), - IPOpts4 = ip_opt_sndbuf(Opts), - IPOpts = - [binary, snmp_conf:tdomain_to_family(Domain) - | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4], - case gen_udp_open(UDPPort, IPOpts) of - {ok, Sock} -> + DomainAddresses = get_transports(), + ?vdebug("DomainAddresses: ~w",[DomainAddresses]), + try + [begin + SocketOpts = socket_opts(Domain, Address, Opts), + Socket = socket_open(Domain, SocketOpts), + active_once(Socket), + #transport{ + socket = Socket, + domain = Domain, + opts = SocketOpts} + end || {Domain, Address} <- DomainAddresses] + of + [] -> + ?vinfo("No transports configured: ~p", [DomainAddresses]), + {error, {no_transports,DomainAddresses}}; + Transports -> MpdState = snmpa_mpd:init(Vsns), - init_counters(), - active_once(Sock), + init_counters(), S = #state{parent = Parent, note_store = NoteStore, master_agent = MasterAgent, mpd_state = MpdState, - usock = Sock, - usock_opts = IPOpts, + transports = Transports, log = Log, limit = Limit, - filter = FilterMod, - domain = Domain}, + filter = FilterMod}, ?vdebug("started with MpdState: ~p", [MpdState]), - {ok, S}; - {error, Reason} -> - ?vinfo("Failed to open UDP socket: ~p", [Reason]), - {error, {udp_open, UDPPort, Reason}} + {ok, S} + catch + Error -> + ?vinfo("Failed to initialize socket(s): ~p", [Error]), + {error, Error} end. +%%% XXX remove +%%% +%%% %% -- Socket -- +%%% IPOpts1 = ip_opt_bind_to_ip_address(Opts, IPAddress), +%%% IPOpts2 = ip_opt_no_reuse_address(Opts), +%%% IPOpts3 = ip_opt_recbuf(Opts), +%%% IPOpts4 = ip_opt_sndbuf(Opts), +%%% IPOpts = +%%% [binary, snmp_conf:tdomain_to_family(Domain) +%%% | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4], +%%% case gen_udp_open(UDPPort, IPOpts) of +%%% {ok, Sock} -> +%%% MpdState = snmpa_mpd:init(Vsns), +%%% init_counters(), +%%% active_once(Sock), +%%% S = #state{parent = Parent, +%%% note_store = NoteStore, +%%% master_agent = MasterAgent, +%%% mpd_state = MpdState, +%%% usock = Sock, +%%% usock_opts = IPOpts, +%%% log = Log, +%%% limit = Limit, +%%% filter = FilterMod, +%%% domain = Domain}, +%%% ?vdebug("started with MpdState: ~p", [MpdState]), +%%% {ok, S}; +%%% {error, Reason} -> +%%% ?vinfo("Failed to open UDP socket: ~p", [Reason]), +%%% {error, {udp_open, UDPPort, Reason}} +%%% end. + create_log() -> case ets:lookup(snmp_agent_table, audit_trail_log) of @@ -298,33 +350,63 @@ format_address(Address) -> iolist_to_binary(snmp_conf:mk_addr_string(Address)). - -gen_udp_open(Port, Opts) -> +socket_open(snmpUDPDomain = Domain, [IpPort | Opts]) -> case init:get_argument(snmp_fd) of {ok, [[FdStr]]} -> Fd = list_to_integer(FdStr), - ?vdebug("gen_udp_open(~p, ~p) Fd: ~p",[Port,Opts,Fd]), - gen_udp:open(0, [{fd, Fd}|Opts]); + ?vdebug("socket_open(~p, [~p | ~p]) Fd: ~p", + [Domain, IpPort, Opts, Fd]), + gen_udp_open(IpPort, [{fd, Fd} | Opts]); error -> case init:get_argument(snmpa_fd) of {ok, [[FdStr]]} -> Fd = list_to_integer(FdStr), - ?vdebug("gen_udp_open(~p, ~p) Fd: ~p",[Port,Opts,Fd]), - gen_udp:open(0, [{fd, Fd}|Opts]); + ?vdebug("socket_open(~p, [~p | ~p]) Fd: ~p", + [Domain, IpPort, Opts, Fd]), + gen_udp_open(IpPort, [{fd, Fd} | Opts]); error -> - ?vdebug("gen_udp_open(~p, ~p)",[Port,Opts]), - gen_udp:open(Port, Opts) + ?vdebug("socket_open(~p, [~p | ~p])", + [Domain, IpPort, Opts]), + gen_udp_open(IpPort, Opts) end + end; +socket_open(Domain, [IpPort | Opts]) + when Domain =:= transportDomainUdpIpv4; + Domain =:= transportDomainUdpIpv6 -> + ?vdebug("socket_open(~p, [~p | ~p])", [Domain, IpPort, Opts]), + gen_udp_open(IpPort, Opts); +socket_open(Domain, Opts) -> + throw({socket_open, Domain, Opts}). + +gen_udp_open(IpPort, Opts) -> + case gen_udp:open(IpPort, Opts) of + {ok, Socket} -> + Socket; + {error, Reason} -> + throw({udp_open, IpPort, Reason}) end. -loop(#state{domain = Domain} = S) -> + +loop(#state{transports = Transports, limit = Limit, parent = Parent} = S) -> + ?vdebug("loop(~p)", [S]), receive - {udp, _UdpId, Ip, Port, Packet} -> - ?vlog("got paket from ~w:~w",[Ip,Port]), - From = fix_filter_address(Domain, {Domain, {Ip, Port}}), - NewS = maybe_handle_recv(S, From, Packet), - loop(NewS); + {udp, Socket, IpAddr, IpPort, Packet} = Msg when is_port(Socket) -> + ?vlog("got paket from ~w:~w on ~w", [IpAddr, IpPort, Socket]), + case lists:keyfind(Socket, #transport.socket, Transports) of + #transport{socket = Socket, domain = Domain} = Transport -> + From = + case Domain of + snmpUDPDomain -> + {IpAddr, IpPort}; + _ -> + {Domain, {IpAddr, IpPort}} + end, + loop(maybe_handle_recv(S, Transport, From, Packet)); + false -> + error_msg("Packet on unknown port: ~p", [Msg]), + loop(S) + end; {info, ReplyRef, Pid} -> Info = get_info(S), @@ -332,12 +414,35 @@ loop(#state{domain = Domain} = S) -> loop(S); %% response (to get/get_next/get_bulk/set requests) - {snmp_response, Vsn, RePdu, Type, ACMData, To, []} -> + {snmp_response, Vsn, RePdu, Type, ACMData, To, Extra} -> ?vlog("reply pdu: " "~n ~s", [?vapply(snmp_misc, format, [256, "~w", [RePdu]])]), - NewS = maybe_handle_reply_pdu(S, Vsn, RePdu, Type, ACMData, To), - loop(NewS); + {_, ReqRef} = lists:keyfind(request_ref, 1, Extra), + case + case + (Limit =/= infinity) andalso + select_transport_from_req_ref(ReqRef, Transports) + of + false -> + select_transport_from_domain( + address_to_domain(To), + Transports); + T -> + T + end + of + false -> + error_msg( + "Can not find transport for response PDU to: ~s", + [format_address(To)]), + loop(S); + Transport -> + NewS = update_req_counter_outgoing(S, Transport, ReqRef), + maybe_handle_reply_pdu( + NewS, Transport, Vsn, RePdu, Type, ACMData, To), + loop(NewS) + end; %% Traps/notification {send_pdu, Vsn, Pdu, MsgData, TDomAddrs} -> @@ -406,15 +511,34 @@ loop(#state{domain = Domain} = S) -> NewS = handle_send_discovery(S, Pdu, MsgData, To, From), loop(NewS); - {discarded_pdu, _Vsn, ReqId, _ACMData, Variable, _Extra} -> - ?vdebug("discard PDU: ~p", [Variable]), + {discarded_pdu, _Vsn, ReqId, _ACMData, Variable, Extra} -> + ?vdebug("discard PDU: ~p - ~p - ~p", + [Variable, Extra, Transports]), snmpa_mpd:discarded_pdu(Variable), - NewS = update_req_counter_outgoing(S, ReqId), - loop(NewS); + {_, ReqRef} = lists:keyfind(request_ref, 1, Extra), + if + Limit =:= infinity -> + %% The incoming PDU was not registered + loop(update_req_counter_outgoing(S, false, ReqRef)); + true -> + case + select_transport_from_req_ref(ReqRef, Transports) + of + false -> + error_msg( + "Can not find transport for discarded PDU: ~p", + [ReqId]), + loop(S); + Transport -> + loop( + update_req_counter_outgoing( + S, Transport, ReqRef)) + end + end; {get_log_type, ReplyRef, Pid} -> ?vdebug("get log type: ~p", []), - #state{log = {_, LogType}} = S, + {_, LogType} = S#state.log, Pid ! {ReplyRef, {ok, LogType}, self()}, loop(S); @@ -426,7 +550,6 @@ loop(#state{domain = Domain} = S) -> {get_request_limit, ReplyRef, Pid} -> ?vdebug("get request limit: ~p", []), - #state{limit = Limit} = S, Pid ! {ReplyRef, {ok, Limit}, self()}, loop(S); @@ -450,36 +573,50 @@ loop(#state{domain = Domain} = S) -> reset_counters(), loop(S); - {'EXIT', Parent, Reason} when Parent == S#state.parent -> + {'EXIT', Parent, Reason} -> ?vlog("parent (~p) exited: " "~n ~p", [Parent, Reason]), exit(Reason); - {'EXIT', Port, Reason} when Port == S#state.usock -> - UDPPort = get_port(), - NewS = - case gen_udp_open(UDPPort, S#state.usock_opts) of - {ok, Id} -> - error_msg("Port ~p exited for reason" - "~n ~p" - "~n Re-opened (~p)", [Port, Reason, Id]), - S#state{usock = Id}; - {error, ReopenReason} -> - error_msg("Port ~p exited for reason" - "~n ~p" - "~n Re-open failed with reason" - "~n ~p", - [Port, Reason, ReopenReason]), - ok - end, - loop(NewS); - - {'EXIT', Port, Reason} when is_port(Port) -> - error_msg("Exit message from port ~p for reason ~p~n", - [Port, Reason]), - loop(S); + {'EXIT', Socket, Reason} when is_port(Socket) -> + case lists:keyfind(Socket, #transport.socket, Transports) of + #transport{ + socket = Socket, + domain = Domain, + opts = SocketOpts, + req_refs = ReqRefs} = Transport -> + try socket_open(Domain, SocketOpts) of + NewSocket -> + error_msg( + "Socket ~p exited for reason" + "~n ~p" + "~n Re-opened (~p)", + [Socket, Reason, NewSocket]), + (length(ReqRefs) < Limit) andalso + active_once(NewSocket), + S#state{ + transports = + lists:keyreplace( + Socket, #transport.socket, Transports, + Transport#transport{socket = NewSocket})} + catch + ReopenReason -> + error_msg( + "Socket ~p exited for reason" + "~n ~p" + "~n Re-open failed with reason" + "~n ~p", + [Socket, Reason, ReopenReason]), + exit(ReopenReason) + end; + false -> + error_msg( + "Exit message from port ~p for reason ~p~n", + [Socket, Reason]), + loop(S) + end; - {'EXIT', Pid, Reason} -> + {'EXIT', Pid, Reason} when is_pid(Pid) -> ?vlog("~p exited: " "~n ~p", [Pid, Reason]), NewS = clear_reqs(Pid, S), @@ -487,71 +624,144 @@ loop(#state{domain = Domain} = S) -> {system, From, Msg} -> ?vdebug("system event ~p from ~p", [Msg, From]), - sys:handle_system_msg(Msg, From, S#state.parent, ?MODULE, [], S); + sys:handle_system_msg(Msg, From, Parent, ?MODULE, [], S); _ -> loop(S) end. -update_req_counter_incomming(#state{limit = infinity, usock = Sock} = S, _) -> - active_once(Sock), %% No limit so activate directly +update_req_counter_incoming( + #state{limit = infinity} = S, + #transport{socket = Socket}, + _ReqRef) -> + active_once(Socket), %% No limit so activate directly S; -update_req_counter_incomming(#state{limit = Limit, - rcnt = RCnt, - usock = Sock} = S, Rid) - when length(RCnt) + 1 == Limit -> +update_req_counter_incoming( + #state{limit = Limit} = S, + #transport{socket = Socket, req_refs = ReqRefs} = T, + ReqRef) when length(ReqRefs) + 1 >= Limit -> %% Ok, one more and we are at the limit. %% Just make sure we are not already processing this one... - case lists:member(Rid, RCnt) of + case lists:member(ReqRef, ReqRefs) of false -> %% We are at the limit, do _not_ activate socket - S#state{rcnt = [Rid|RCnt]}; + update_transport_req_refs(S, T, [ReqRef | ReqRefs]); true -> - active_once(Sock), + active_once(Socket), S end; -update_req_counter_incomming(#state{rcnt = RCnt, - usock = Sock} = S, Rid) -> - active_once(Sock), - case lists:member(Rid, RCnt) of +update_req_counter_incoming( + #state{} = S, + #transport{socket = Socket, req_refs = ReqRefs} = T, + ReqRef) -> + active_once(Socket), + case lists:member(ReqRef, ReqRefs) of false -> - S#state{rcnt = [Rid|RCnt]}; + update_transport_req_refs(S, T, [ReqRef | ReqRefs]); true -> S end. - -update_req_counter_outgoing(#state{limit = infinity} = S, _Rid) -> +update_transport_req_refs( + #state{transports = Transports} = S, + #transport{socket = Socket} = T, + ReqRefs) -> + S#state{ + transports = + lists:keyreplace( + Socket, #transport.socket, Transports, + T#transport{req_refs = ReqRefs})}. + +%%% XXX remove +%%% +%%% update_req_counter_incoming(#state{limit = infinity, usock = Sock} = S, _) -> +%%% active_once(Sock), %% No limit so activate directly +%%% S; +%%% update_req_counter_incoming(#state{limit = Limit, +%%% rcnt = RCnt, +%%% usock = Sock} = S, Rid) +%%% when length(RCnt) + 1 >= Limit -> +%%% %% Ok, one more and we are at the limit. +%%% %% Just make sure we are not already processing this one... +%%% case lists:member(Rid, RCnt) of +%%% false -> +%%% %% We are at the limit, do _not_ activate socket +%%% S#state{rcnt = [Rid|RCnt]}; +%%% true -> +%%% active_once(Sock), +%%% S +%%% end; +%%% update_req_counter_incoming(#state{rcnt = RCnt, +%%% usock = Sock} = S, Rid) -> +%%% active_once(Sock), +%%% case lists:member(Rid, RCnt) of +%%% false -> +%%% S#state{rcnt = [Rid|RCnt]}; +%%% true -> +%%% S +%%% end. + + +update_req_counter_outgoing( + #state{limit = infinity} = S, + _Transport, _ReqRef) -> %% Already activated (in the incoming function) S; -update_req_counter_outgoing(#state{limit = Limit, - rcnt = RCnt, - usock = Sock} = S, Rid) - when length(RCnt) == Limit -> - ?vtrace("handle_req_counter_outgoing(~w) -> entry with" - "~n Rid: ~w" - "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]), - case lists:delete(Rid, RCnt) of - NewRCnt when length(NewRCnt) < Limit -> +update_req_counter_outgoing( + #state{limit = Limit, transports = Transports} = S, + #transport{socket = Socket, req_refs = ReqRefs} = Transport, + ReqRef) -> + LengthReqRefs = length(ReqRefs), + ?vtrace("update_req_counter_outgoing() -> entry with~n" + " Limit: ~w~n" + " ReqRef: ~w~n" + " length(ReqRefs): ~w", [Limit, ReqRef, LengthReqRefs]), + NewReqRefs = lists:delete(ReqRef, ReqRefs), + (LengthReqRefs >= Limit) andalso (length(NewReqRefs) < Limit) andalso + begin ?vtrace("update_req_counter_outgoing -> " - "passed below limit: activate", []), - active_once(Sock), - S#state{rcnt = NewRCnt}; - _ -> - S - end; -update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, - Rid) -> - ?vtrace("handle_req_counter_outgoing(~w) -> entry with" - "~n Rid: ~w" - "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]), - NewRCnt = lists:delete(Rid, RCnt), - S#state{rcnt = NewRCnt}. + "passed below limit: activate", []), + active_once(Socket) + end, + S#state{ + transports = + snmp_misc:keyreplace( + Socket, #transport.socket, Transports, + Transport#transport{req_refs = NewReqRefs})}. + +%%% XXX remove +%%% +%%% update_req_counter_outgoing( +%%% #state{limit = Limit, +%%% rcnt = RCnt, +%%% usock = Sock} = S, Rid) +%%% when length(RCnt) >= Limit -> +%%% ?vtrace("handle_req_counter_outgoing(~w) -> entry with" +%%% "~n Rid: ~w" +%%% "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]), +%%% case lists:delete(Rid, RCnt) of +%%% NewRCnt when length(NewRCnt) < Limit -> +%%% ?vtrace("update_req_counter_outgoing -> " +%%% "passed below limit: activate", []), +%%% active_once(Sock), +%%% S#state{rcnt = NewRCnt}; +%%% _ -> +%%% S +%%% end; +%%% update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, +%%% Rid) -> +%%% ?vtrace("handle_req_counter_outgoing(~w) -> entry with" +%%% "~n Rid: ~w" +%%% "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]), +%%% NewRCnt = lists:delete(Rid, RCnt), +%%% S#state{rcnt = NewRCnt}. maybe_handle_recv( - #state{usock = Sock, filter = FilterMod} = S, From, Packet) -> + #state{filter = FilterMod} = S, + #transport{socket = Socket} = Transport, + From, Packet) -> {From_1, From_2} = From, case try FilterMod:accept_recv(From_1, From_2) @@ -566,7 +776,7 @@ maybe_handle_recv( false -> %% Drop the received packet inc(netIfMsgInDrops), - active_once(Sock), + active_once(Socket), S; Other -> case Other of @@ -577,28 +787,13 @@ maybe_handle_recv( "FilterMod:accept_recv(~p, ~p) returned: ~p", [From_1,From_2,Other]) end, - handle_recv(S, From, Packet) - end. - -handle_discovery_response(_From, #pdu{request_id = ReqId} = Pdu, - ManagerEngineId, - #state{usock = Sock, reqs = Reqs} = S) -> - case lists:keysearch(ReqId, 1, S#state.reqs) of - {value, {_, Pid}} -> - active_once(Sock), - Pid ! {snmp_discovery_response_received, Pdu, ManagerEngineId}, - NReqs = lists:keydelete(ReqId, 1, Reqs), - S#state{reqs = NReqs}; - _ -> - %% Ouch, timeout? resend? - S + handle_recv(S, Transport, From, Packet) end. handle_recv( - #state{usock = Sock, - mpd_state = MpdState, - note_store = NS, - log = Log} = S, From, Packet) -> + #state{mpd_state = MpdState, note_store = NS, log = Log} = S, + #transport{socket = Socket} = Transport, + From, Packet) -> put(n1, erlang:now()), LogF = fun(Type, Data) -> @@ -607,48 +802,72 @@ handle_recv( case (catch snmpa_mpd:process_packet( Packet, From, MpdState, NS, LogF)) of {ok, _Vsn, Pdu, _PduMS, {discovery, ManagerEngineId}} -> - handle_discovery_response(From, Pdu, ManagerEngineId, S); + handle_discovery_response( + S, Transport, From, Pdu, ManagerEngineId); {ok, _Vsn, Pdu, _PduMS, discovery} -> - handle_discovery_response(From, Pdu, undefined, S); + handle_discovery_response( + S, Transport, From, Pdu, undefined); {ok, Vsn, Pdu, PduMS, ACMData} -> ?vlog("got pdu ~s", [?vapply(snmp_misc, format, [256, "~w", [Pdu]])]), - %% handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S); - maybe_handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S); + %% handle_recv_pdu(S, Transport, From, Vsn, Pdu, PduMS, ACMData); + maybe_handle_recv_pdu( + S, Transport, From, Vsn, Pdu, PduMS, ACMData); {discarded, Reason} -> ?vlog("packet discarded for reason: ~s", [?vapply(snmp_misc, format, [256, "~w", [Reason]])]), - active_once(Sock), + active_once(Socket), S; {discarded, Reason, ReportPacket} -> ?vlog("sending report for reason: " "~n ~s", [?vapply(snmp_misc, format, [256, "~w", [Reason]])]), - (catch udp_send(S#state.usock, From, ReportPacket)), - active_once(Sock), + (catch udp_send(Socket, From, ReportPacket)), + active_once(Socket), S; {discovery, ReportPacket} -> ?vlog("sending discovery report", []), - (catch udp_send(S#state.usock, From, ReportPacket)), - active_once(Sock), + (catch udp_send(Socket, From, ReportPacket)), + active_once(Socket), S; Error -> error_msg("processing of received message failed: " "~n ~p", [Error]), - active_once(Sock), + active_once(Socket), + S + end. + +handle_discovery_response( + #state{reqs = Reqs} = S, + #transport{socket = Socket}, + _From, + #pdu{request_id = ReqId} = Pdu, + ManagerEngineId) -> + case lists:keyfind(ReqId, 1, S#state.reqs) of + {ReqId, Pid} -> + active_once(Socket), + Pid ! {snmp_discovery_response_received, Pdu, ManagerEngineId}, + %% XXX Strange... Reqs from this Pid should be reaped + %% at process exit by clear_reqs/2 so the following + %% should be redundant. + NReqs = lists:keydelete(ReqId, 1, Reqs), + S#state{reqs = NReqs}; + false -> + %% Ouch, timeout? resend? S end. maybe_handle_recv_pdu( + #state{filter = FilterMod} = S, + #transport{socket = Socket} = Transport, From, Vsn, - #pdu{type = Type} = Pdu, PduMS, ACMData, - #state{usock = Sock, filter = FilterMod} = S) -> + #pdu{type = Type} = Pdu, PduMS, ACMData) -> {From_1, From_2} = From, case try FilterMod:accept_recv_pdu(From_1, From_2, Type) @@ -664,8 +883,8 @@ maybe_handle_recv_pdu( of false -> inc(netIfPduInDrops), - active_once(Sock), - ok; + active_once(Socket), + S; Other -> case Other of true -> @@ -675,39 +894,72 @@ maybe_handle_recv_pdu( "FilterMod:accept_recv_pdu(~p, ~p, ~p) returned: ~p", [From_1,From_2,Type,Other]) end, - handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, S) + handle_recv_pdu(S, Transport, From, Vsn, Pdu, PduMS, ACMData) end. handle_recv_pdu( + #state{reqs = Reqs} = S, + #transport{socket = Socket}, From, Vsn, - #pdu{type = 'get-response'} = Pdu, _PduMS, _ACMData, - #state{usock = Sock} = S) -> - active_once(Sock), - handle_response(Vsn, Pdu, From, S), + #pdu{type = 'get-response', request_id = ReqId} = Pdu, + _PduMS, _ACMData) -> + active_once(Socket), + case lists:keyfind(ReqId, 1, Reqs) of + {ReqId, Pid} -> + ?vdebug("handle_recv_pdu -> " + "~n send response to receiver ~p", [Pid]), + Pid ! {snmp_response_received, Vsn, Pdu, From}; + false -> + ?vdebug("handle_recv_pdu -> " + "~n No receiver available for response pdu", []) + end, S; -handle_recv_pdu(From, Vsn, #pdu{request_id = Rid, type = Type} = Pdu, - PduMS, ACMData, #state{master_agent = Pid} = S) - when ((Type =:= 'get-request') orelse - (Type =:= 'get-next-request') orelse - (Type =:= 'get-bulk-request')) -> - ?vtrace("handle_recv_pdu -> received get (~w)", [Type]), - Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, []}, - update_req_counter_incomming(S, Rid); -handle_recv_pdu(From, Vsn, Pdu, PduMS, ACMData, - #state{usock = Sock, master_agent = Pid} = S) -> +%%% XXX remove +%%% +%%% handle_recv_pdu( +%%% #state{} = S, +%%% #transport{socket = Socket} = Transport, +%%% From, Vsn, +%%% #pdu{type = 'get-response'} = Pdu, +%%% _PduMS, _ACMData) -> +%%% active_once(Socket), +%%% handle_response(S, Pdu, From, Vsn), +%%% S; +handle_recv_pdu( + #state{master_agent = Pid} = S, + #transport{} = Transport, + From, Vsn, + #pdu{type = Type} = Pdu, + PduMS, ACMData) + when Type =:= 'set-request'; + Type =:= 'get-request'; + Type =:= 'get-next-request'; + Type =:= 'get-bulk-request' -> + ?vtrace("handle_recv_pdu -> received request (~w)", [Type]), + ReqRef = make_ref(), + Extra = [{request_ref, ReqRef}], + Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, Extra}, + NewS = update_req_counter_incoming(S, Transport, ReqRef), + ?vdebug("handle_recv_pdu -> ~p", [NewS]), + NewS; +handle_recv_pdu( + #state{master_agent = Pid} = S, + #transport{socket = Socket}, + From, Vsn, Pdu, PduMS, ACMData) -> ?vtrace("handle_recv_pdu -> received other request", []), - active_once(Sock), + active_once(Socket), Pid ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, []}, S. maybe_handle_reply_pdu( - #state{filter = FilterMod, domain = Domain} = S, Vsn, - #pdu{request_id = Rid} = Pdu, + #state{filter = FilterMod, transports = Transports} = S, + #transport{} = Transport, + Vsn, + #pdu{} = Pdu, Type, ACMData, To) -> - - S1 = update_req_counter_outgoing(S, Rid), - Addresses = [fix_filter_address(Domain, To)], + %% + Addresses = [fix_filter_address(Transports, To)], case try FilterMod:accept_send_pdu(Addresses, Type) @@ -715,7 +967,8 @@ maybe_handle_reply_pdu( Class:Exception -> error_msg( "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", - [Addresses,Type,Class,Exception,erlang:get_stacktrace()]), + [Addresses, Type, Class, Exception, + erlang:get_stacktrace()]), true end of @@ -731,11 +984,16 @@ maybe_handle_reply_pdu( "FilterMod:accept_send_pdu(~p, ~p) returned: ~p", [Addresses,Type,Other]) end, - handle_reply_pdu(S1, Vsn, Pdu, Type, ACMData, To) - end, - S1. + handle_reply_pdu(S, Transport, Vsn, Pdu, Type, ACMData, To) + end. -handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> +handle_reply_pdu( + #state{log = Log} = S, + #transport{} = Transport, + Vsn, + #pdu{} = Pdu, + Type, ACMData, To) -> + %% LogF = fun(Type2, Data) -> log(Log, Type2, Data, To) @@ -744,7 +1002,15 @@ handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> ACMData, LogF)) of {ok, Packet} -> ?vinfo("time in agent: ~w mysec", [time_in_agent()]), - maybe_udp_send(S, To, Packet); + try maybe_udp_send(S, Transport, To, Packet) + catch + {Reason, Sz} -> + error_msg("Cannot send message " + "~n size: ~p" + "~n reason: ~p" + "~n pdu: ~p", + [Sz, Reason, Pdu]) + end; {discarded, Reason} -> ?vlog("handle_reply_pdu -> " "~n reply discarded for reason: ~s", @@ -758,7 +1024,7 @@ handle_reply_pdu(#state{log = Log} = S, Vsn, Pdu, Type, ACMData, To) -> maybe_handle_send_pdu( - #state{filter = FilterMod, domain = Domain} = S, + #state{filter = FilterMod, transports = Transports} = S, Vsn, Pdu, MsgData, TDomAddrSecs, From) -> ?vtrace("maybe_handle_send_pdu -> entry with~n" @@ -767,26 +1033,15 @@ maybe_handle_send_pdu( DomAddrSecs = snmpa_mpd:process_taddrs(TDomAddrSecs), AddressesToFilter = - [case Domain of - snmpUDPDomain -> - case DAS of - {{Dom, Addr}, _SecData} - when is_atom(Dom) -> % v3 - Addr; - {Dom, Addr} - when is_atom(Dom) -> % v1 & v2 - Addr - end; - _ -> - case DAS of - {{Dom, _Addr} = DomAddr, _SecData} - when is_atom(Dom) -> % v3 - DomAddr; - {Dom, _Addr} = DomAddr - when is_atom(Dom) -> % v1 & v2 - DomAddr - end - end || DAS <- DomAddrSecs], + case is_legacy_transports(Transports) of + true -> + [fix_filter_legacy_mpd_address(DAS) + || DAS <- DomAddrSecs]; + false -> + [fix_filter_mpd_address(DAS) + || DAS <- DomAddrSecs] + end, + Type = pdu_type_of(Pdu), case @@ -806,33 +1061,24 @@ maybe_handle_send_pdu( true -> handle_send_pdu(S, Vsn, Pdu, MsgData, DomAddrSecs, From); FilteredAddresses when is_list(FilteredAddresses) -> - MergedDomAddrSecs = - [DAS || - DAS <- DomAddrSecs, - lists:member( - case Domain of - snmpUDPDomain -> - case DAS of - {{Dom, Addr}, _SData} - when is_atom(Dom) -> % v3 - Addr; - {Dom, Addr} - when is_atom(Dom) -> % v1 & v2 - Addr - end; - true -> - case DAS of - {{Dom, _Addr} = DomAddr, _SData} - when is_atom(Dom) -> % v3 - DomAddr; - {Dom, _Addr} = DomAddr - when is_atom(Dom) -> % v1 & v2 - DomAddr - end - end, FilteredAddresses)], - ?vtrace("maybe_handle_send_pdu -> MergedDomAddrSecs:~n" - " ~p", [MergedDomAddrSecs]), - handle_send_pdu(S, Vsn, Pdu, MsgData, MergedDomAddrSecs, From); + FilteredDomAddrSecs = + case is_legacy_transports(Transports) of + true -> + [DAS || + DAS <- DomAddrSecs, + lists:member( + fix_filter_legacy_mpd_address(DAS), + FilteredAddresses)]; + false -> + [DAS || + DAS <- DomAddrSecs, + lists:member( + fix_filter_mpd_address(DAS), + FilteredAddresses)] + end, + ?vtrace("maybe_handle_send_pdu -> FilteredDomAddrSecs:~n" + " ~p", [FilteredDomAddrSecs]), + handle_send_pdu(S, Vsn, Pdu, MsgData, FilteredDomAddrSecs, From); Other -> error_msg( "FilterMod:accept_send_pdu(~p, ~p) returned: ~p", @@ -841,8 +1087,9 @@ maybe_handle_send_pdu( end. handle_send_pdu( - #state{note_store = NS} = S, Vsn, Pdu, MsgData, DomAddrSecs, From) -> - + #state{note_store = NS} = S, + Vsn, Pdu, MsgData, DomAddrSecs, From) -> + %% ?vtrace("handle_send_pdu -> entry with~n" " Pdu: ~p~n" " DomAddrSecs: ~p", [Pdu, DomAddrSecs]), @@ -863,23 +1110,24 @@ handle_send_pdu( case From of undefined -> S; - Pid -> + Pid when is_pid(Pid) -> ?vtrace("link to ~p and add to request list", [Pid]), link(Pid), - NReqs = snmp_misc:keyreplaceadd( - Pid, 2, S#state.reqs, {Pdu#pdu.request_id, From}), + NReqs = + snmp_misc:keyreplaceadd( + Pid, 2, S#state.reqs, {Pdu#pdu.request_id, From}), S#state{reqs = NReqs} end. handle_send_discovery( - #state{note_store = NS, - log = Log, - usock = Sock, - reqs = Reqs} = S, - #pdu{type = Type, - request_id = ReqId} = Pdu, - MsgData, To, From) -> + #state{ + note_store = NS, + log = Log, + reqs = Reqs, + transports = Transports} = S, + #pdu{type = Type, request_id = ReqId} = Pdu, + MsgData, To, From) when is_pid(From) -> ?vtrace("handle_send_discovery -> entry with" "~n Pdu: ~p" @@ -889,20 +1137,28 @@ handle_send_discovery( case (catch snmpa_mpd:generate_discovery_msg(NS, Pdu, MsgData, To)) of {ok, {Domain, Address, Packet}} -> - log(Log, Type, Packet, {Domain, Address}), - udp_send(Sock, {Domain, Address}, Packet), - ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]), - NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}), - S#state{reqs = NReqs}; + case select_transport_from_domain(Domain, Transports) of + false -> + error_msg( + "Can not find transport to: ~s", + [format_address(To)]), + S; + #transport{socket = Socket} -> + log(Log, Type, Packet, {Domain, Address}), + udp_send(Socket, {Domain, Address}, Packet), + ?vtrace("handle_send_discovery -> sent (~w)", [ReqId]), + NReqs = snmp_misc:keyreplaceadd(From, 2, Reqs, {ReqId, From}), + S#state{reqs = NReqs} + end; {discarded, Reason} -> ?vlog("handle_send_discovery -> " "~n Discovery PDU ~p not sent due to ~p", [Pdu, Reason]), - ok; + S; {'EXIT', Reason} -> user_err("failed generating discovery message: " "~n PDU: ~p" "~n Reason: ~p", [Pdu, Reason]), - ok + S end. @@ -912,18 +1168,20 @@ do_handle_send_pdu(S, Trap, Addresses) -> do_handle_send_pdu(S, trappdu, Trap, Addresses). do_handle_send_pdu(S, Type, Pdu, Addresses) -> - case (catch do_handle_send_pdu1(S, Type, Addresses)) of + try do_handle_send_pdu1(S, Type, Addresses) + catch {Reason, Sz} -> - error_msg("Cannot send message " - "~n size: ~p" - "~n reason: ~p" - "~n pdu: ~p", - [Sz, Reason, Pdu]); - _ -> - ok + error_msg( + "Can not send message~n" + " size: ~p~n" + " reason: ~p~n" + " pdu: ~p", + [Sz, Reason, Pdu]) end. -do_handle_send_pdu1(S, Type, Addresses) -> +do_handle_send_pdu1( + #state{transports = Transports} = S, + Type, Addresses) -> lists:foreach( fun ({Domain, Address, Packet}) when is_binary(Packet) -> ?vdebug( @@ -931,32 +1189,55 @@ do_handle_send_pdu1(S, Type, Addresses) -> " size: ~p~n" " to: ~p", [Domain, sz(Packet), Address]), To = {Domain, Address}, - maybe_udp_send(S, To, Packet); + case select_transport_from_domain(Domain, Transports) of + false -> + error_msg( + "Can not find transport~n" + " size: ~p~n" + " to: ~s", + [sz(Packet), To]); + Transport -> + maybe_udp_send(S, Transport, To, Packet) + end; ({Domain, Address, {Packet, LogData}}) when is_binary(Packet) -> ?vdebug( "[~w] sending encrypted packet:~n" " size: ~p~n" " to: ~p", [Domain, sz(Packet), Address]), To = {Domain, Address}, - maybe_udp_send(S, To, Packet, Type, LogData) + case select_transport_from_domain(Domain, Transports) of + false -> + error_msg( + "Can not find transport~n" + " size: ~p~n" + " to: ~s", + [sz(Packet), To]); + Transport -> + maybe_udp_send(S, Transport, To, Packet, Type, LogData) + end end, Addresses). -handle_response(Vsn, Pdu, From, S) -> - case lists:keysearch(Pdu#pdu.request_id, 1, S#state.reqs) of - {value, {_, Pid}} -> - ?vdebug("handle_response -> " - "~n send response to receiver ~p", [Pid]), - Pid ! {snmp_response_received, Vsn, Pdu, From}; - _ -> - ?vdebug("handle_response -> " - "~n No receiver available for response pdu", []) - end. +%%% XXX remove +%%% +%%% handle_response( +%%% #state{reqs = Reqs} = S, Pdu#pdu{request_id = ReqId}, From, Vsn) +%%% when is_pid(From) -> +%%% case lists:keyfind(ReqId, 1, S#state.reqs) of +%%% {ReqId, Pid} -> +%%% ?vdebug("handle_response -> " +%%% "~n send response to receiver ~p", [Pid]), +%%% Pid ! {snmp_response_received, Vsn, Pdu, From}; +%%% false -> +%%% ?vdebug("handle_response -> " +%%% "~n No receiver available for response pdu", []) +%%% end. maybe_udp_send( - #state{usock = Sock, filter = FilterMod, domain = Domain}, + #state{filter = FilterMod, transports = Transports}, + #transport{socket = Socket}, To, Packet) -> - {To_1, To_2} = fix_filter_address(Domain, To), + {To_1, To_2} = fix_filter_address(Transports, To), case try FilterMod:accept_send(To_1, To_2) catch @@ -979,25 +1260,21 @@ maybe_udp_send( "FilterMod:accept_send(~p, ~p) returned: ~p", [To_1,To_2,Other]) end, - %% XXX should be some kind of lookup of domain to socket - (catch udp_send(Sock, To, Packet)) + udp_send(Socket, To, Packet) end. maybe_udp_send( - #state{ - log = Log, - usock = Sock, - filter = FilterMod, - domain = Domain}, + #state{log = Log, filter = FilterMod, transports = Transports}, + #transport{socket = Socket}, To, Packet, Type, _LogData) -> - {To_1, To_2} = fix_filter_address(Domain, To), + {To_1, To_2} = fix_filter_address(Transports, To), case try FilterMod:accept_send(To_1, To_2) catch Class:Exception -> error_msg( "FilterMod:accept_send(~p, ~p) crashed for: ~w:~w~n ~p", - [To_1,To_2,Class,Exception,erlang:get_stacktrace()]), + [To_1, To_2, Class, Exception, erlang:get_stacktrace()]), true end of @@ -1014,32 +1291,33 @@ maybe_udp_send( [To_1,To_2,Other]) end, log(Log, Type, Packet, To), - (catch udp_send(Sock, To, Packet)) + udp_send(Socket, To, Packet) end. -udp_send(UdpId, To, B) -> - %% XXX should be some kind of lookup of domain to socket - {Ip, Port} = +udp_send(Socket, To, B) -> + {IpAddr, IpPort} = case To of {Domain, Addr} when is_atom(Domain) -> Addr; {_, P} = Addr when is_integer(P) -> Addr end, - case (catch gen_udp:send(UdpId, Ip, Port, B)) of + try gen_udp:send(Socket, IpAddr, IpPort, B) of {error, emsgsize} -> %% From this message we cannot recover, so exit sending loop throw({emsgsize, sz(B)}); {error, ErrorReason} -> error_msg("[error] cannot send message " "(destination: ~p:~p, size: ~p, reason: ~p)", - [Ip, Port, sz(B), ErrorReason]); - {'EXIT', ExitReason} -> - error_msg("[exit] cannot send message " - "(destination: ~p:~p, size: ~p, reason: ~p)", - [Ip, Port, sz(B), ExitReason]); - _ -> + [IpAddr, IpPort, sz(B), ErrorReason]); + ok -> ok + catch + error:ExitReason -> + error_msg("[exit] cannot send message " + "(destination: ~p:~p, size: ~p, reason: ~p, at: ~p)", + [IpAddr, IpPort, sz(B), ExitReason, + erlang:get_stacktrace()]) end. sz(L) when is_list(L) -> length(L); @@ -1089,21 +1367,74 @@ active_once(Sock) -> inet:setopts(Sock, [{active, once}]). +select_transport_from_req_ref(_, []) -> + false; +select_transport_from_req_ref( + ReqRef, + [#transport{req_refs = ReqRefs} = Transport | Transports]) -> + case lists:member(ReqRef, ReqRefs) of + true -> + Transport; + false -> + select_transport_from_req_ref(ReqRef, Transports) + end. + +select_transport_from_domain(Domain, Transports) when is_atom(Domain) -> + Pos = #transport.domain, + case lists:keyfind(Domain, Pos, Transports) of + #transport{domain = Domain} = Transport -> + Transport; + false when Domain == snmpUDPDomain -> + lists:keyfind(transportDomainUdpIpv4, Pos, Transports); + false when Domain == transportDomainUdpIpv4 -> + lists:keyfind(snmpUDPDomain, Pos, Transports); + false -> + false + end. + +address_to_domain({Domain, _Addr}) when is_atom(Domain) -> + Domain; +address_to_domain({_Ip, Port}) when is_integer(Port) -> + snmpUDPDomain. + %% If the agent uses legacy snmpUDPDomain e.g has not set %% intAgentTransportDomain, then make sure %% snmpa_network_interface_filter gets legacy arguments %% to not break backwards compatibility. %% -fix_filter_address(snmpUDPDomain, {Domain, Addr}) - when Domain =:= snmpUDPDomain; - Domain =:= transportDomainUdpIpv4 -> - Addr; -fix_filter_address(_AgentDomain, {Domain, _} = Address) - when is_atom(Domain) -> - Address; -fix_filter_address(snmpUDPDomain, {_, Port} = Addr) - when is_integer(Port) -> - Addr. +fix_filter_address(Transports, Address) -> + case is_legacy_transports(Transports) of + true -> + case Address of + {Domain, Addr} when is_atom(Domain) -> + Addr; + {_, IpPort} = Addr when is_integer(IpPort) -> + Addr + end; + false -> + Address + end. + +is_legacy_transports([#transport{domain = snmpUDPDomain}]) -> + true; +is_legacy_transports([#transport{} | _]) -> + false. + +fix_filter_legacy_mpd_address(Domain_Address_SecData) -> + case Domain_Address_SecData of + {{Domain, Addr}, _SecData} when is_atom(Domain) -> % v3 + Addr; + {Domain, Addr} when is_atom(Domain) -> % v1 & v2 + Addr + end. + +fix_filter_mpd_address(Domain_Address_SecData) -> + case Domain_Address_SecData of + {{Domain, _Addr} = Address, _SecData} when is_atom(Domain) -> % v3 + Address; + {Domain, _Addr} = Address when is_atom(Domain) -> % v1 & v2 + Address + end. %%%----------------------------------------------------------------- @@ -1261,6 +1592,35 @@ get_counters([Counter|Counters], Acc) -> %% ---------------------------------------------------------------- +socket_opts(Domain, {IpAddr, IpPort}, Opts) -> + [IpPort, % Picked off at socket open, separate argument + binary, + snmp_conf:tdomain_to_family(Domain) + | case get_bind_to_ip_address(Opts) of + true -> + [{ip, IpAddr}]; + _ -> + [] + end ++ + case get_no_reuse_address(Opts) of + false -> + [{reuseaddr, true}]; + _ -> + [] + end ++ + case get_recbuf(Opts) of + use_default -> + []; + Sz -> + [{recbuf, Sz}] + end ++ + case get_sndbuf(Opts) of + use_default -> + []; + Sz -> + [{sndbuf, Sz}] + end]. + ip_opt_bind_to_ip_address(Opts, Ip) -> case get_bind_to_ip_address(Opts) of true -> @@ -1378,14 +1738,14 @@ call(Pid, Req) -> %% ---------------------------------------------------------------- -get_info(#state{usock = Id, reqs = Reqs}) -> +get_info(#state{transports = Transports, reqs = Reqs}) -> ProcSize = proc_mem(self()), - PortInfo = get_port_info(Id), Counters = get_counters(), - [{reqs, Reqs}, - {counters, Counters}, - {process_memory, ProcSize}, - {port_info, PortInfo}]. + [{reqs, Reqs}, + {counters, Counters}, + {process_memory, ProcSize} + | [{port_info, get_port_info(Socket)} + || #transport{socket = Socket} <- Transports]]. proc_mem(P) when is_pid(P) -> case (catch erlang:process_info(P, memory)) of diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index ac0739860b..40956c40fb 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -790,42 +790,45 @@ send_trap_pdus([], ContextName, {TrapRec, Vbs}, send_v1_trap(_TrapRec, [], _Vbs, _ExtraInfo, _NetIf, _SysUpTime) -> ok; -send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec}, - V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) -> +send_v1_trap( + #trap{enterpriseoid = Enter, specificcode = Spec}, + V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) -> ?vdebug("prepare to send v1 trap " "~n '~p'" "~n with" "~n ~p" "~n to" "~n ~p", [Enter, Spec, V1Res]), - AgentDomain = - case snmp_framework_mib:intAgentTransportDomain(get) of - {value, AD} -> - AD; - genErr -> - snmp_target_mib:default_domain() - end, - case AgentDomain of - snmpUDPDomain -> - {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), - TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime, AgentIp), - AddrCommunities = mk_addr_communities(V1Res), - lists:foreach( - fun ({Community, Addrs}) -> - ?vtrace("send v1 trap pdu to ~p",[Addrs]), - NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs, ExtraInfo} - end, AddrCommunities); - _ -> - ?vtrace( - "snmpa_trap: can not send v1 trap with domain: ~w", - [AgentDomain]), - user_err( - "snmpa_trap: can not send v1 trap with domain: ~w", - [AgentDomain]) - end; -send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, - SysUpTime) -> + do_send_v1_trap(Enter, Spec, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime); +%%% AgentDomain = +%%% case snmp_framework_mib:intAgentTransportDomain(get) of +%%% {value, AD} -> +%%% AD; +%%% genErr -> +%%% snmp_target_mib:default_domain() +%%% end, +%%% case AgentDomain of +%%% snmpUDPDomain -> +%%% {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), +%%% TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime, AgentIp), +%%% AddrCommunities = mk_addr_communities(V1Res), +%%% lists:foreach( +%%% fun ({Community, Addrs}) -> +%%% ?vtrace("send v1 trap pdu to ~p",[Addrs]), +%%% NetIf ! {send_pdu, 'version-1', TrapPdu, +%%% {community, Community}, Addrs, ExtraInfo} +%%% end, AddrCommunities); +%%% _ -> +%%% ?vtrace( +%%% "snmpa_trap: can not send v1 trap with domain: ~w", +%%% [AgentDomain]), +%%% user_err( +%%% "snmpa_trap: can not send v1 trap with domain: ~w", +%%% [AgentDomain]) +%%% end; +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]), @@ -842,32 +845,64 @@ send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, {lists:reverse(First),Last} end end, - AgentDomain = - case snmp_framework_mib:intAgentTransportDomain(get) of - {value, AD} -> - AD; - genErr -> - snmp_target_mib:default_domain() + do_send_v1_trap(Enter, Spec, V1Res, NVbs, ExtraInfo, NetIf, SysUpTime). + +do_send_v1_trap(Enter, Spec, V1Res, NVbs, ExtraInfo, NetIf, SysUpTime) -> + {value, Transports} = snmp_framework_mib:intAgentTransports(get), + {_Domain, {AgentIp, _AgentPort}} = + case lists:keyfind(snmpUDPDomain, 1, Transports) of + false -> + case lists:keyfind(transportDomainUdpIpv4, 1, Transports) of + false -> + ?vtrace( + "snmpa_trap: can not send v1 trap " + "without IPv4 domain: ~p", + [Transports]), + user_err( + "snmpa_trap: can not send v1 trap " + "without IPv4 domain: ~p", + [Transports]); + DomainAddr -> + DomainAddr + end; + DomainAddr -> + DomainAddr end, - case AgentDomain of - snmpUDPDomain -> - {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), - TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp), - AddrCommunities = mk_addr_communities(V1Res), - lists:foreach( - fun ({Community, Addrs}) -> - ?vtrace("send v1 trap to ~p",[Addrs]), - NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs, ExtraInfo} - end, AddrCommunities); - _ -> - ?vtrace( - "snmpa_trap: can not send v1 trap with domain: ~w", - [AgentDomain]), - user_err( - "snmpa_trap: can not send v1 trap with domain: ~w", - [AgentDomain]) - end. + TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp), + AddrCommunities = mk_addr_communities(V1Res), + lists:foreach( + fun ({Community, Addrs}) -> + ?vtrace("send v1 trap to ~p",[Addrs]), + NetIf ! {send_pdu, 'version-1', TrapPdu, + {community, Community}, Addrs, ExtraInfo} + end, AddrCommunities). + +%%% AgentDomain = +%%% case snmp_framework_mib:intAgentTransportDomain(get) of +%%% {value, AD} -> +%%% AD; +%%% genErr -> +%%% snmp_target_mib:default_domain() +%%% end, +%%% case AgentDomain of +%%% snmpUDPDomain -> +%%% {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), +%%% TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp), +%%% AddrCommunities = mk_addr_communities(V1Res), +%%% lists:foreach( +%%% fun ({Community, Addrs}) -> +%%% ?vtrace("send v1 trap to ~p",[Addrs]), +%%% NetIf ! {send_pdu, 'version-1', TrapPdu, +%%% {community, Community}, Addrs, ExtraInfo} +%%% end, AddrCommunities); +%%% _ -> +%%% ?vtrace( +%%% "snmpa_trap: can not send v1 trap with domain: ~w", +%%% [AgentDomain]), +%%% user_err( +%%% "snmpa_trap: can not send v1 trap with domain: ~w", +%%% [AgentDomain]) +%%% end. send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) -> ok; diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 82cbf42e35..f4483995cb 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -223,13 +223,17 @@ read_check(_, _, [], _, Res) -> lists:reverse(Res); read_check(File, Check, [{StartLine, Row, EndLine}|Lines], State, Res) -> try Check(Row, State) of + {Rows, NewState} when is_list(Rows) -> + ?vtrace("read_check -> ok:~n" + " Rows: ~p~n", [Rows]), + read_check(File, Check, Lines, NewState, Rows ++ Res); {ok, NewState} -> ?vtrace("read_check -> ok", []), - read_check(File, Check, Lines, NewState, [Row|Res]); + read_check(File, Check, Lines, NewState, [Row | Res]); {{ok, NewRow}, NewState} -> ?vtrace("read_check -> ok:~n" " NewRow: ~p~n", [NewRow]), - read_check(File, Check, Lines, NewState, [NewRow|Res]) + read_check(File, Check, Lines, NewState, [NewRow | Res]) catch {error, Reason} -> ?vtrace("read_check -> error:~n" diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 38e248c326..91240082f1 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -33,7 +33,7 @@ -export([write_agent_snmp_files/7, write_agent_snmp_files/12, write_agent_snmp_files/6, write_agent_snmp_files/11, - write_agent_snmp_conf/5, + write_agent_snmp_conf/4, write_agent_snmp_conf/5, write_agent_snmp_context_conf/1, write_agent_snmp_community_conf/1, write_agent_snmp_standard_conf/2, @@ -1650,6 +1650,12 @@ write_agent_snmp_files( %% ------ [agent] agent.conf ------ %% +write_agent_snmp_conf(Dir, Transports, EngineID, MMS) -> + Conf = + [{intAgentTransports, Transports}, + {snmpEngineID, EngineID}, + {snmpEngineMaxMessageSize, MMS}], + do_write_agent_snmp_conf(Dir, Conf). write_agent_snmp_conf(Dir, Domain, AgentAddr, EngineID, MMS) when is_atom(Domain) -> @@ -2513,6 +2519,8 @@ write_config_file(Dir, FileName, Order, Check, Write, Entries) lists:foldl( fun (Entry, State) -> case Check(Entry, State) of + {Ok, NewState} when is_list(Ok) -> + NewState; {ok, NewState} -> NewState; {{ok, _}, NewState} -> @@ -2709,6 +2717,8 @@ verify_lines([], _, _, Acc) -> verify_lines( [{StartLine, Term, EndLine}|Lines], Check, State, Acc) -> try Check(Term, State) of + {Terms, NewState} when is_list(Terms) -> + verify_lines(Lines, Check, NewState, Terms ++ Acc); {ok, NewState} -> verify_lines(Lines, Check, NewState, [Term|Acc]); {{ok, NewTerm}, NewState} -> diff --git a/lib/snmp/test/klas3.erl b/lib/snmp/test/klas3.erl index 4c7c03e2ca..4cbd852b2d 100644 --- a/lib/snmp/test/klas3.erl +++ b/lib/snmp/test/klas3.erl @@ -75,6 +75,7 @@ fname(get) -> end, case snmpa:current_net_if_data() of {value, []} -> ok; + {value, [{request_ref, R}]} when is_reference(R) -> ok; {value, _} -> throw("bad_nil"); _ -> throw("bad_nid") end, -- cgit v1.2.3 From 09451fa20a51ca198e6043505b033a9d24b497f6 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Mon, 30 Jun 2014 17:22:13 +0200 Subject: Silence logging from agent net_if at shutdown --- lib/snmp/src/agent/snmpa_net_if.erl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index f5fd377341..66964faed7 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -153,11 +153,12 @@ init(Prio, NoteStore, MasterAgent, Parent, Opts) -> {ok, State} -> proc_lib:init_ack({ok, self()}), try loop(State) - catch C:E -> - S = erlang:get_stacktrace(), + catch + C:E when C =/= exit, E =/= shutdown -> Fmt = "loop/1 EXCEPTION ~w:~w~n" " ~p", + S = erlang:get_stacktrace(), case C of exit -> %% Externally killed, root cause is elsewhere -- cgit v1.2.3 From d38674e8dd8224da8a66d77ca4f5a8073e01f794 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 1 Jul 2014 10:17:50 +0200 Subject: Add dual_ip tests in snmp_to_snmpnet_SUITE --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 70 ++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 18 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index e8dcffd361..3271b98ec3 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -68,12 +68,16 @@ init_per_group(ipv6, Config) -> ok -> Dir = ?config(priv_dir, Config), Domain = transportDomainUdpIpv6, + AgentPort = ?config(agent_port, Config), + ManagerPort = ?config(manager_port, Config), {ok, Host} = inet:gethostname(), {ok, IpAddr} = inet:getaddr(Host, inet6), + Transports = [{Domain, {IpAddr, AgentPort}}], + TrapAddr = {IpAddr, ManagerPort}, Versions = [v2], - agent_config(Dir, Domain, IpAddr, IpAddr, ?config(agent_port, Config), Versions), - [{host, Host}, - {snmp_versions, Versions}, {ip_version, ipv6} | Config]; + agent_config(Dir, Transports, Domain, TrapAddr, Versions), + [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv6} + | Config]; _ -> {skip, "Host does not support IPV6"} end; @@ -81,13 +85,36 @@ init_per_group(ipv6, Config) -> init_per_group(ipv4, Config) -> Dir = ?config(priv_dir, Config), Domain = transportDomainUdpIpv4, + AgentPort = ?config(agent_port, Config), + ManagerPort = ?config(manager_port, Config), {ok, Host} = inet:gethostname(), {ok, IpAddr} = inet:getaddr(Host, inet), + Transports = [{Domain, {IpAddr, AgentPort}}], + TrapAddr = {IpAddr, ManagerPort}, Versions = [v2], - agent_config(Dir, Domain, IpAddr, {IpAddr, ?config(manager_port, Config)}, - ?config(agent_port, Config), Versions), - [{host, Host}, {snmp_versions, Versions}, - {ip_version, ipv4} | Config]; + agent_config(Dir, Transports, Domain, TrapAddr, Versions), + [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv4} + | Config]; + +init_per_group(dual_ip, Config) -> + case ct:require(ipv6_hosts) of + ok -> + Dir = ?config(priv_dir, Config), + {ok, Host} = inet:gethostname(), + {ok, IPv4Addr} = inet:getaddr(Host, inet), + {ok, IPv6Addr} = inet:getaddr(Host, inet6), + Domain = snmpUDPDomain, + Transports = + [{Domain, {IPv4Addr, ?AGENT_PORT}}, + {transportDomainUdpIpv6, {IPv6Addr, ?AGENT_PORT}}], + TrapAddr = {IPv4Addr, 0}, + Versions = [v2], + agent_config(Dir, Transports, Domain, TrapAddr, Versions), + [{host, Host}, {port, ?AGENT_PORT}, {snmp_versions, Versions} + | Config]; + _ -> + {skip, "Host does not support IPV6"} + end; init_per_group(get, Config) -> %% From Ubuntu package snmp @@ -149,14 +176,16 @@ erlang_agent_dual_ip_get() -> [{doc,"Test that we can access erlang snmp agent from both " "snmpnet ipv4 and snmpnet ipv6 manager at the same time"}]. erlang_agent_dual_ip_get(Config) when is_list(Config) -> - erlang_agent_netsnmp_get([{ip_version, ipv4}]), - erlang_agent_netsnmp_get([{ip_version, ipv6}]). + erlang_agent_netsnmp_get([{ip_version, ipv4} | Config]), + erlang_agent_netsnmp_get([{ip_version, ipv6} | Config]). %%-------------------------------------------------------------------- erlang_agent_netsnmp_inform(Config) when is_list(Config) -> Host = ?config(host, Config), IPVersion = ?config(ip_version, Config), DataDir = ?config(data_dir, Config), - ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, "TestTrapv2")), + ok = + snmpa:load_mib( + snmp_master_agent, filename:join(DataDir, "TestTrapv2")), Cmd = "snmptrapd -L o -M " ++ DataDir ++ " --disableAuthorization=yes" ++ @@ -173,7 +202,7 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> end, receive {snmp_notification, erlang_agent_test, {got_response, Address}} -> - ct:pal("Got respons from: ~p~n", [Address]), + ct:pal("Got response from: ~p~n", [Address]), ok; {snmp_notification, erlang_agent_test, {no_response, _} = NoResponse} -> @@ -185,6 +214,7 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> %%-------------------------------------------------------------------- net_snmp(Cmd, Expect) -> NetSnmpPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + ct:pal("net_snmp started: ~s~n", [Cmd]), receive {NetSnmpPort, {data, Expect}} -> ok; @@ -195,7 +225,9 @@ net_snmp(Cmd, Expect) -> catch erlang:port_close(NetSnmpPort). net_snmp_trapd(Cmd) -> - open_port({spawn, Cmd}, [stderr_to_stdout]). + NetSnmpTrapdPort = open_port({spawn, Cmd}, [stderr_to_stdout]), + ct:pal("net_snmp_trapd started: ~s~n", [Cmd]), + NetSnmpTrapdPort. net_snmp_log(NetSnmpPort) -> receive @@ -234,16 +266,18 @@ oid_str([], Acc) -> oid_str([Int | Rest], Acc) -> oid_str(Rest, Acc ++ "." ++ integer_to_list(Int)). -agent_config(Dir, Domain, IpA, IpM, Port, Versions) -> +agent_config(Dir, Transports, TargetDomain, TargetAddr, Versions) -> EngineID = ?AGENT_ENGIN_ID, MMS = ?DEFAULT_MAX_MESSAGE_SIZE, - ok = snmp_config:write_agent_snmp_conf(Dir, Domain, {IpA, Port}, - EngineID, MMS), + ok = snmp_config:write_agent_snmp_conf(Dir, Transports, EngineID, MMS), ok = snmp_config:write_agent_snmp_context_conf(Dir), ok = snmp_config:write_agent_snmp_community_conf(Dir), - ok = snmp_config:write_agent_snmp_standard_conf(Dir, "snmp_to_snmpnet_SUITE"), - ok = snmp_config:write_agent_snmp_target_addr_conf(Dir, Domain, - IpM, Versions), + ok = + snmp_config:write_agent_snmp_standard_conf( + Dir, "snmp_to_snmpnet_SUITE"), + ok = + snmp_config:write_agent_snmp_target_addr_conf( + Dir, TargetDomain, TargetAddr, Versions), ok = snmp_config:write_agent_snmp_target_params_conf(Dir, Versions), ok = snmp_config:write_agent_snmp_notify_conf(Dir, inform), ok = snmp_config:write_agent_snmp_vacm_conf(Dir, Versions, none). -- cgit v1.2.3 From 81d2a6e1b13e944893377d93505523b8e7995e53 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 2 Jul 2014 15:38:01 +0200 Subject: Remove commented out code --- lib/snmp/src/agent/snmp_framework_mib.erl | 23 ---- lib/snmp/src/agent/snmpa_net_if.erl | 197 ++---------------------------- lib/snmp/src/agent/snmpa_trap.erl | 53 -------- 3 files changed, 9 insertions(+), 264 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 3b33cae3ec..922215ff00 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -138,8 +138,6 @@ read_agent(Dir) -> end, Mand = [{intAgentTransports, mandatory}, -%%% {intAgentIpAddress, mandatory}, -%%% {intAgentUDPPort, mandatory}, {snmpEngineMaxMessageSize, mandatory}, {snmpEngineID, mandatory}], {ok, Conf} = snmp_conf:check_mandatory(Conf0, Mand), @@ -227,27 +225,6 @@ check_agent({intAgentTransports = Tag, Transports}, {_, Port} = State) -> check_agent(Entry, State) -> {check_agent(Entry), State}. -%%% XXX remove -%%% -%%% check_agent({intAgentTransportDomain, D}, _Domain) -> -%%% {snmp_conf:check_domain(D), D}; -%%% check_agent({intAgentIpAddress = Tag, Value}, D) -> -%%% Domain = -%%% case D of -%%% undefined -> -%%% snmp_target_mib:default_domain(); -%%% _ -> -%%% D -%%% end, -%%% {case snmp_conf:check_ip(Domain, Value) of -%%% ok -> -%%% ok; -%%% {ok, FixedIp} -> -%%% {ok, {Tag, FixedIp}} -%%% end, Domain}; -%%% check_agent(Entry, Domain) -> -%%% {check_agent(Entry), Domain}. - %% This one is kept for backwards compatibility check_agent({intAgentMaxPacketSize, Value}) -> snmp_conf:check_packet_size(Value); diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 66964faed7..8f6706166b 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -117,24 +117,6 @@ get_transports() -> {value, Transports} = snmp_framework_mib:intAgentTransports(get), Transports. -%%% XXX remove -%%% -%%% get_ip_port() -> -%%% {value, UDPPort} = snmp_framework_mib:intAgentUDPPort(get), -%%% UDPPort. -%%% -%%% get_address() -> -%%% {value, IPAddress} = snmp_framework_mib:intAgentIpAddress(get), -%%% IPAddress. -%%% -%%% get_domain() -> -%%% case snmp_framework_mib:intAgentTransportDomain(get) of -%%% {value, Domain} -> -%%% Domain; -%%% genErr -> -%%% snmpUDPDomain -%%% end. - filter_reset(Pid) -> Pid ! filter_reset. @@ -185,16 +167,6 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> put(verbosity,get_verbosity(Opts)), ?vlog("starting",[]), -%%% XXX remove -%%% -%%% %% -- Port and address -- -%%% Domain = get_domain(), -%%% ?vdebug("domain: ~w",[Domain]), -%%% UDPPort = get_ip_port(), -%%% ?vdebug("port: ~w",[UDPPort]), -%%% IPAddress = get_address(), -%%% ?vdebug("addr: ~w",[IPAddress]), - %% -- Versions -- Vsns = get_vsns(Opts), ?vdebug("vsns: ~w",[Vsns]), @@ -245,38 +217,6 @@ do_init(Prio, NoteStore, MasterAgent, Parent, Opts) -> {error, Error} end. -%%% XXX remove -%%% -%%% %% -- Socket -- -%%% IPOpts1 = ip_opt_bind_to_ip_address(Opts, IPAddress), -%%% IPOpts2 = ip_opt_no_reuse_address(Opts), -%%% IPOpts3 = ip_opt_recbuf(Opts), -%%% IPOpts4 = ip_opt_sndbuf(Opts), -%%% IPOpts = -%%% [binary, snmp_conf:tdomain_to_family(Domain) -%%% | IPOpts1 ++ IPOpts2 ++ IPOpts3 ++ IPOpts4], -%%% case gen_udp_open(UDPPort, IPOpts) of -%%% {ok, Sock} -> -%%% MpdState = snmpa_mpd:init(Vsns), -%%% init_counters(), -%%% active_once(Sock), -%%% S = #state{parent = Parent, -%%% note_store = NoteStore, -%%% master_agent = MasterAgent, -%%% mpd_state = MpdState, -%%% usock = Sock, -%%% usock_opts = IPOpts, -%%% log = Log, -%%% limit = Limit, -%%% filter = FilterMod, -%%% domain = Domain}, -%%% ?vdebug("started with MpdState: ~p", [MpdState]), -%%% {ok, S}; -%%% {error, Reason} -> -%%% ?vinfo("Failed to open UDP socket: ~p", [Reason]), -%%% {error, {udp_open, UDPPort, Reason}} -%%% end. - create_log() -> case ets:lookup(snmp_agent_table, audit_trail_log) of @@ -664,53 +604,13 @@ update_req_counter_incoming( S end. -update_transport_req_refs( - #state{transports = Transports} = S, - #transport{socket = Socket} = T, - ReqRefs) -> - S#state{ - transports = - lists:keyreplace( - Socket, #transport.socket, Transports, - T#transport{req_refs = ReqRefs})}. - -%%% XXX remove -%%% -%%% update_req_counter_incoming(#state{limit = infinity, usock = Sock} = S, _) -> -%%% active_once(Sock), %% No limit so activate directly -%%% S; -%%% update_req_counter_incoming(#state{limit = Limit, -%%% rcnt = RCnt, -%%% usock = Sock} = S, Rid) -%%% when length(RCnt) + 1 >= Limit -> -%%% %% Ok, one more and we are at the limit. -%%% %% Just make sure we are not already processing this one... -%%% case lists:member(Rid, RCnt) of -%%% false -> -%%% %% We are at the limit, do _not_ activate socket -%%% S#state{rcnt = [Rid|RCnt]}; -%%% true -> -%%% active_once(Sock), -%%% S -%%% end; -%%% update_req_counter_incoming(#state{rcnt = RCnt, -%%% usock = Sock} = S, Rid) -> -%%% active_once(Sock), -%%% case lists:member(Rid, RCnt) of -%%% false -> -%%% S#state{rcnt = [Rid|RCnt]}; -%%% true -> -%%% S -%%% end. - - update_req_counter_outgoing( #state{limit = infinity} = S, _Transport, _ReqRef) -> %% Already activated (in the incoming function) S; update_req_counter_outgoing( - #state{limit = Limit, transports = Transports} = S, + #state{limit = Limit} = S, #transport{socket = Socket, req_refs = ReqRefs} = Transport, ReqRef) -> LengthReqRefs = length(ReqRefs), @@ -725,39 +625,18 @@ update_req_counter_outgoing( "passed below limit: activate", []), active_once(Socket) end, + update_transport_req_refs(S, Transport, NewReqRefs). + +update_transport_req_refs( + #state{transports = Transports} = S, + #transport{socket = Socket} = T, + ReqRefs) -> S#state{ transports = - snmp_misc:keyreplace( + lists:keyreplace( Socket, #transport.socket, Transports, - Transport#transport{req_refs = NewReqRefs})}. + T#transport{req_refs = ReqRefs})}. -%%% XXX remove -%%% -%%% update_req_counter_outgoing( -%%% #state{limit = Limit, -%%% rcnt = RCnt, -%%% usock = Sock} = S, Rid) -%%% when length(RCnt) >= Limit -> -%%% ?vtrace("handle_req_counter_outgoing(~w) -> entry with" -%%% "~n Rid: ~w" -%%% "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]), -%%% case lists:delete(Rid, RCnt) of -%%% NewRCnt when length(NewRCnt) < Limit -> -%%% ?vtrace("update_req_counter_outgoing -> " -%%% "passed below limit: activate", []), -%%% active_once(Sock), -%%% S#state{rcnt = NewRCnt}; -%%% _ -> -%%% S -%%% end; -%%% update_req_counter_outgoing(#state{limit = Limit, rcnt = RCnt} = S, -%%% Rid) -> -%%% ?vtrace("handle_req_counter_outgoing(~w) -> entry with" -%%% "~n Rid: ~w" -%%% "~n length(RCnt): ~w", [Limit, Rid, length(RCnt)]), -%%% NewRCnt = lists:delete(Rid, RCnt), -%%% S#state{rcnt = NewRCnt}. - maybe_handle_recv( #state{filter = FilterMod} = S, @@ -915,17 +794,6 @@ handle_recv_pdu( "~n No receiver available for response pdu", []) end, S; -%%% XXX remove -%%% -%%% handle_recv_pdu( -%%% #state{} = S, -%%% #transport{socket = Socket} = Transport, -%%% From, Vsn, -%%% #pdu{type = 'get-response'} = Pdu, -%%% _PduMS, _ACMData) -> -%%% active_once(Socket), -%%% handle_response(S, Pdu, From, Vsn), -%%% S; handle_recv_pdu( #state{master_agent = Pid} = S, #transport{} = Transport, @@ -1219,21 +1087,6 @@ do_handle_send_pdu1( end, Addresses). -%%% XXX remove -%%% -%%% handle_response( -%%% #state{reqs = Reqs} = S, Pdu#pdu{request_id = ReqId}, From, Vsn) -%%% when is_pid(From) -> -%%% case lists:keyfind(ReqId, 1, S#state.reqs) of -%%% {ReqId, Pid} -> -%%% ?vdebug("handle_response -> " -%%% "~n send response to receiver ~p", [Pid]), -%%% Pid ! {snmp_response_received, Vsn, Pdu, From}; -%%% false -> -%%% ?vdebug("handle_response -> " -%%% "~n No receiver available for response pdu", []) -%%% end. - maybe_udp_send( #state{filter = FilterMod, transports = Transports}, #transport{socket = Socket}, @@ -1622,38 +1475,6 @@ socket_opts(Domain, {IpAddr, IpPort}, Opts) -> [{sndbuf, Sz}] end]. -ip_opt_bind_to_ip_address(Opts, Ip) -> - case get_bind_to_ip_address(Opts) of - true -> - [{ip, Ip}]; - _ -> - [] - end. - -ip_opt_no_reuse_address(Opts) -> - case get_no_reuse_address(Opts) of - false -> - [{reuseaddr, true}]; - _ -> - [] - end. - -ip_opt_recbuf(Opts) -> - case get_recbuf(Opts) of - use_default -> - []; - Sz -> - [{recbuf, Sz}] - end. - -ip_opt_sndbuf(Opts) -> - case get_sndbuf(Opts) of - use_default -> - []; - Sz -> - [{sndbuf, Sz}] - end. - %% ---------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index 40956c40fb..a79b150f57 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -800,32 +800,6 @@ send_v1_trap( "~n to" "~n ~p", [Enter, Spec, V1Res]), do_send_v1_trap(Enter, Spec, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime); -%%% AgentDomain = -%%% case snmp_framework_mib:intAgentTransportDomain(get) of -%%% {value, AD} -> -%%% AD; -%%% genErr -> -%%% snmp_target_mib:default_domain() -%%% end, -%%% case AgentDomain of -%%% snmpUDPDomain -> -%%% {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), -%%% TrapPdu = make_v1_trap_pdu(Enter, Spec, Vbs, SysUpTime, AgentIp), -%%% AddrCommunities = mk_addr_communities(V1Res), -%%% lists:foreach( -%%% fun ({Community, Addrs}) -> -%%% ?vtrace("send v1 trap pdu to ~p",[Addrs]), -%%% NetIf ! {send_pdu, 'version-1', TrapPdu, -%%% {community, Community}, Addrs, ExtraInfo} -%%% end, AddrCommunities); -%%% _ -> -%%% ?vtrace( -%%% "snmpa_trap: can not send v1 trap with domain: ~w", -%%% [AgentDomain]), -%%% user_err( -%%% "snmpa_trap: can not send v1 trap with domain: ~w", -%%% [AgentDomain]) -%%% end; send_v1_trap( #notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) -> @@ -877,33 +851,6 @@ do_send_v1_trap(Enter, Spec, V1Res, NVbs, ExtraInfo, NetIf, SysUpTime) -> {community, Community}, Addrs, ExtraInfo} end, AddrCommunities). -%%% AgentDomain = -%%% case snmp_framework_mib:intAgentTransportDomain(get) of -%%% {value, AD} -> -%%% AD; -%%% genErr -> -%%% snmp_target_mib:default_domain() -%%% end, -%%% case AgentDomain of -%%% snmpUDPDomain -> -%%% {value, AgentIp} = snmp_framework_mib:intAgentIpAddress(get), -%%% TrapPdu = make_v1_trap_pdu(Enter, Spec, NVbs, SysUpTime, AgentIp), -%%% AddrCommunities = mk_addr_communities(V1Res), -%%% lists:foreach( -%%% fun ({Community, Addrs}) -> -%%% ?vtrace("send v1 trap to ~p",[Addrs]), -%%% NetIf ! {send_pdu, 'version-1', TrapPdu, -%%% {community, Community}, Addrs, ExtraInfo} -%%% end, AddrCommunities); -%%% _ -> -%%% ?vtrace( -%%% "snmpa_trap: can not send v1 trap with domain: ~w", -%%% [AgentDomain]), -%%% user_err( -%%% "snmpa_trap: can not send v1 trap with domain: ~w", -%%% [AgentDomain]) -%%% end. - send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) -> ok; send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime) -> -- cgit v1.2.3 From 1e67db678ea40e4b8a125da425c86fdfe7f1b986 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 2 Jul 2014 15:37:41 +0200 Subject: Use {ipv6_v6only, true} --- lib/snmp/src/agent/snmpa_net_if.erl | 11 ++++++++--- lib/snmp/src/app/snmp.appup.src | 4 ++++ lib/snmp/vsn.mk | 2 +- 3 files changed, 13 insertions(+), 4 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 8f6706166b..389c26834d 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -1448,9 +1448,14 @@ get_counters([Counter|Counters], Acc) -> socket_opts(Domain, {IpAddr, IpPort}, Opts) -> [IpPort, % Picked off at socket open, separate argument - binary, - snmp_conf:tdomain_to_family(Domain) - | case get_bind_to_ip_address(Opts) of + binary + | case snmp_conf:tdomain_to_family(Domain) of + inet6 = Family -> + [Family, {ipv6_v6only, true}]; + Family -> + [Family] + end ++ + case get_bind_to_ip_address(Opts) of true -> [{ip, IpAddr}]; _ -> diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index babc33e6a5..ae79e3c1d1 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -28,6 +28,8 @@ %% {update, snmpa_local_db, soft, soft_purge, soft_purge, []} %% {add_module, snmpm_net_if_mt} [ + {"4.25.1", [{restart_application, snmp}]}, + {"4.25.0.1", [{restart_application, snmp}]}, {"4.25", [{restart_application, snmp}]}, {"4.24.2", [{restart_application, snmp}]}, {"4.24.1", [{restart_application, snmp}]}, @@ -40,6 +42,8 @@ %% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}} [ + {"4.25.1", [{restart_application, snmp}]}, + {"4.25.0.1", [{restart_application, snmp}]}, {"4.25", [{restart_application, snmp}]}, {"4.24.2", [{restart_application, snmp}]}, {"4.24.1", [{restart_application, snmp}]}, diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 533e313bdb..fd10244386 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -18,6 +18,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 4.25.0.1 +SNMP_VSN = 5.0 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" -- cgit v1.2.3 From 7e775edac0a5fa736046940d6b1776e238978804 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 3 Jul 2014 18:07:30 +0200 Subject: Improve dual stack test suite --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 261 ++++++++++++++------- .../snmp_to_snmpnet_SUITE_data/start_stop_wrapper | 47 ++++ 2 files changed, 229 insertions(+), 79 deletions(-) create mode 100755 lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index 3271b98ec3..fa92beb6b1 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -30,7 +30,7 @@ -define(AGENT_PORT, 4000). -define(MANAGER_PORT, 8989). -define(DEFAULT_MAX_MESSAGE_SIZE, 484). --define(SYS_DESC, "iso.3.6.1.2.1.1.1.0 = STRING: \"Erlang SNMP agent\"\n"). +-define(SYS_DESC, <<"iso.3.6.1.2.1.1.1.0 = STRING: \"Erlang SNMP agent\"">>). %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- @@ -97,23 +97,30 @@ init_per_group(ipv4, Config) -> | Config]; init_per_group(dual_ip, Config) -> - case ct:require(ipv6_hosts) of - ok -> - Dir = ?config(priv_dir, Config), - {ok, Host} = inet:gethostname(), - {ok, IPv4Addr} = inet:getaddr(Host, inet), - {ok, IPv6Addr} = inet:getaddr(Host, inet6), - Domain = snmpUDPDomain, - Transports = - [{Domain, {IPv4Addr, ?AGENT_PORT}}, - {transportDomainUdpIpv6, {IPv6Addr, ?AGENT_PORT}}], - TrapAddr = {IPv4Addr, 0}, - Versions = [v2], - agent_config(Dir, Transports, Domain, TrapAddr, Versions), - [{host, Host}, {port, ?AGENT_PORT}, {snmp_versions, Versions} - | Config]; - _ -> - {skip, "Host does not support IPV6"} + case os:find_executable("snmpget") of + false -> + {skip, "snmpget not found"}; + Path -> + case ct:require(ipv6_hosts) of + ok -> + Dir = ?config(priv_dir, Config), + {ok, Host} = inet:gethostname(), + {ok, IPv4Addr} = inet:getaddr(Host, inet), + {ok, IPv6Addr} = inet:getaddr(Host, inet6), + Domain = snmpUDPDomain, + Transports = + [{Domain, {IPv4Addr, ?AGENT_PORT}}, + {transportDomainUdpIpv6, {IPv6Addr, ?AGENT_PORT}}], + TrapAddr = {IPv4Addr, 0}, + Versions = [v2], + agent_config( + Dir, Transports, Domain, TrapAddr, Versions), + [{host, Host}, {port, ?AGENT_PORT}, + {snmp_versions, Versions}, + {snmpget, Path} | Config]; + _ -> + {skip, "Host does not support IPV6"} + end end; init_per_group(get, Config) -> @@ -121,8 +128,8 @@ init_per_group(get, Config) -> case os:find_executable("snmpget") of false -> {skip, "snmpget not found"}; - _ -> - Config + Path -> + [{snmpget, Path} | Config] end; init_per_group(inform, Config) -> @@ -130,8 +137,8 @@ init_per_group(inform, Config) -> case os:find_executable("snmptrapd") of false -> {skip, "snmptrapd not found"}; - _ -> - Config + Path -> + [{snmptrapd, Path} | Config] end; init_per_group(_, Config) -> Config. @@ -139,19 +146,32 @@ init_per_group(_, Config) -> end_per_group(_GroupName, Config) -> Config. -init_per_testcase(Case, Config) -> +init_per_testcase(_Case, Config) -> Dog = ct:timetrap(10000), - end_per_testcase(Case, Config), - application:start(snmp), - application:load(snmp), - application:set_env(snmp, agent, app_env(Case, Config)), - snmp:start_agent(normal), + application:stop(snmp), + application:unload(snmp), [{watchdog, Dog} | Config]. end_per_testcase(_, Config) -> - application:stop(snmp), + case application:stop(snmp) of + ok -> + ok; + E1 -> + ct:pal("application:stop(snmp) -> ~p", [E1]) + end, + case application:unload(snmp) of + ok -> + ok; + E2 -> + ct:pal("application:unload(snmp) -> ~p", [E2]) + end, Config. +start_agent(Config) -> + ok = application:load(snmp), + ok = application:set_env(snmp, agent, app_env(Config)), + ok = application:start(snmp). + %%-------------------------------------------------------------------- %% Test Cases -------------------------------------------------------- %%-------------------------------------------------------------------- @@ -160,42 +180,46 @@ erlang_agent_netsnmp_get() -> "from snmpnet manager"}]. erlang_agent_netsnmp_get(Config) when is_list(Config) -> - Host = ?config(host, Config), - Port = ?config(agent_port, Config), - IPVersion = ?config(ip_version, Config), - Versions = ?config(snmp_versions, Config), - - Cmd = "snmpget -c public " ++ net_snmp_version(Versions) ++ " " ++ - net_snmp_ip_version(IPVersion) ++ - Host ++ ":" ++ integer_to_list(Port) ++ - " " ++ oid_str(?sysDescr_instance), - net_snmp(Cmd, ?SYS_DESC). + start_agent(Config), + ?SYS_DESC = snmpget(oid_str(?sysDescr_instance), Config), + ok. %%-------------------------------------------------------------------- erlang_agent_dual_ip_get() -> [{doc,"Test that we can access erlang snmp agent from both " "snmpnet ipv4 and snmpnet ipv6 manager at the same time"}]. erlang_agent_dual_ip_get(Config) when is_list(Config) -> - erlang_agent_netsnmp_get([{ip_version, ipv4} | Config]), - erlang_agent_netsnmp_get([{ip_version, ipv6} | Config]). + start_agent(Config), + + OidStr = oid_str(?sysDescr_instance), + ?SYS_DESC = snmpget(OidStr, [{ip_version, ipv4} | Config]), + ?SYS_DESC = snmpget(OidStr, [{ip_version, ipv6} | Config]), + ok. + %%-------------------------------------------------------------------- erlang_agent_netsnmp_inform(Config) when is_list(Config) -> Host = ?config(host, Config), IPVersion = ?config(ip_version, Config), DataDir = ?config(data_dir, Config), + + start_agent(Config), ok = snmpa:load_mib( snmp_master_agent, filename:join(DataDir, "TestTrapv2")), - Cmd = "snmptrapd -L o -M " ++ DataDir ++ - " --disableAuthorization=yes" ++ - " --snmpTrapdAddr=" ++ net_snmp_ip_version(IPVersion) ++ - Host ++ ":" ++ integer_to_list(?config(manager_port, Config)), - - NetSnmpPort = net_snmp_trapd(Cmd), - snmpa:send_notification(snmp_master_agent, testTrapv22, - {erlang_agent_test, self()}), - net_snmp_log(NetSnmpPort), + SnmptrapdArgs = + ["-f", "-Lo", + "-M", DataDir, + "--disableAuthorization=yes", + "--snmpTrapdAddr=" ++ net_snmp_transport(IPVersion) ++ + Host ++ ":" ++ integer_to_list(?config(manager_port, Config))], + {ok, CheckMP} = re:compile("NET-SNMP version ", [anchored]), + ProgHandle = + start_program(snmptrapd, SnmptrapdArgs, CheckMP, Config), + + snmpa:send_notification( + snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), + receive {snmp_targets, erlang_agent_test, Addresses} -> ct:pal("Notification sent to: ~p~n", [Addresses]) @@ -207,38 +231,116 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> {snmp_notification, erlang_agent_test, {no_response, _} = NoResponse} -> ct:fail(NoResponse) - end. + end, + + stop_program(ProgHandle). %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- -net_snmp(Cmd, Expect) -> - NetSnmpPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - ct:pal("net_snmp started: ~s~n", [Cmd]), - receive - {NetSnmpPort, {data, Expect}} -> - ok; - Msg -> - ct:fail({{expected, {NetSnmpPort, {data, Expect}}}, - {got, Msg}}) - end, - catch erlang:port_close(NetSnmpPort). - -net_snmp_trapd(Cmd) -> - NetSnmpTrapdPort = open_port({spawn, Cmd}, [stderr_to_stdout]), - ct:pal("net_snmp_trapd started: ~s~n", [Cmd]), - NetSnmpTrapdPort. - -net_snmp_log(NetSnmpPort) -> - receive - {NetSnmpPort, {data, Data}} -> - ct:pal("Received from netsnmp: ~p~n", [Data]), - net_snmp_log(NetSnmpPort) - after 500 -> - catch erlang:port_close(NetSnmpPort) +snmpget(OidStr, Config) -> + Versions = ?config(snmp_versions, Config), + IPVersion = ?config(ip_version, Config), + Host = ?config(host, Config), + Port = ?config(agent_port, Config), + + Args = + ["-c", "public", net_snmp_version(Versions), + net_snmp_transport(IPVersion) ++ + Host ++ ":" ++ integer_to_list(Port), + OidStr], + ProgHandle = start_program(snmpget, Args, none, Config), + {_, line, Line} = get_program_output(ProgHandle), + stop_program(ProgHandle), + Line. + + +start_program(Prog, Args, StartCheckMP, Config) -> + Path = ?config(Prog, Config), + DataDir = ?config(data_dir, Config), + StartWrapper = filename:join(DataDir, "start_stop_wrapper"), + Parent = self(), + Pid = + spawn_link( + fun () -> + run_program(Parent, StartWrapper, [Path | Args]) + end), + start_check(Pid, erlang:monitor(process, Pid), StartCheckMP). + +start_check(Pid, Mon, none) -> + {Pid, Mon}; +start_check(Pid, Mon, StartCheckMP) -> + receive + {Pid, line, Line} -> + case re:run(Line, StartCheckMP, [{capture, none}]) of + match -> + {Pid, Mon}; + nomatch -> + start_check(Pid, Mon, StartCheckMP) + end; + {'DOWN', Mon, _, _, Reason} -> + ct:fail("Prog ~p start failed: ~p", [Pid, Reason]) + end. + +get_program_output({Pid, Mon}) -> + receive + {Pid, _, _} = Msg -> + Msg; + {'DOWN', Mon, _, _, Reason} -> + ct:fail("Prog ~p crashed: ~p", [Pid, Reason]) end. -app_env(_Case, Config) -> +stop_program({Pid, _} = Handle) -> + Pid ! {self(), stop}, + wait_program_stop(Handle). + +wait_program_stop({Pid, Mon}) -> + receive + {Pid, exit, ExitStatus} -> + receive + {'DOWN', Mon, _, _, _} -> + ExitStatus + end; + {'DOWN', Mon, _, _, Reason} -> + ct:fail("Prog stop: ~p", [Reason]) + end. + +run_program(Parent, StartWrapper, ProgAndArgs) -> + Port = + open_port( + {spawn_executable, StartWrapper}, + [{args, ProgAndArgs}, binary, stderr_to_stdout, {line, 80}, + exit_status]), + ct:pal("Prog ~p started: ~p", [Port, ProgAndArgs]), + run_program_loop(Parent, Port, []). + +run_program_loop(Parent, Port, Buf) -> + receive + {Parent, stop} -> + true = port_command(Port, <<"stop\n">>), + ct:pal("Prog ~p stop", [Port]), + run_program_loop(Parent, Port, Buf); + {Port, {data, {Flag, Data}}} -> + case Flag of + eol -> + Line = iolist_to_binary(lists:reverse(Buf, Data)), + ct:pal("Prog ~p output: ~s", [Port, Line]), + Parent ! {self(), line, Line}, + run_program_loop(Parent, Port, []); + noeol -> + run_program_loop(Parent, Port, [Data | Buf]) + end; + {Port, {exit_status,ExitStatus}} -> + ct:pal("Prog ~p exit: ~p", [Port, ExitStatus]), + catch port_close(Port), + Parent ! {self(), exit, ExitStatus}; + Unexpected -> + ct:pal("run_program_loop Unexpected: ~p", [Unexpected]), + run_program_loop(Parent, Port, Buf) + end. + + +app_env(Config) -> Dir = ?config(priv_dir, Config), Vsns = ?config(snmp_versions, Config), [{versions, Vsns}, @@ -249,7 +351,7 @@ app_env(_Case, Config) -> {dir, Dir}, {size, {10240, 10}}]}, {config, [{dir, Dir}, - {force_load, false}, + {force_load, true}, {verbosity, trace}]}, {local_db, [{repair, true}, {verbosity, silence}]}, @@ -288,7 +390,8 @@ net_snmp_version([v2 | _]) -> "-v2c"; net_snmp_version([v1 | _]) -> "-v1". -net_snmp_ip_version(ipv4) -> + +net_snmp_transport(ipv4) -> "udp:"; -net_snmp_ip_version(ipv6) -> +net_snmp_transport(ipv6) -> "udp6:". diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper new file mode 100755 index 0000000000..f806ab5c12 --- /dev/null +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE_data/start_stop_wrapper @@ -0,0 +1,47 @@ +#! /bin/sh +## +## %CopyrightBegin% +## +## Copyright Ericsson AB 2014-2014. All Rights Reserved. +## +## The contents of this file are subject to the Erlang Public License, +## Version 1.1, (the "License"); you may not use this file except in +## compliance with the License. You should have received a copy of the +## Erlang Public License along with this software. If not, it can be +## retrieved online at http://www.erlang.org/. +## +## Software distributed under the License is distributed on an "AS IS" +## basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See +## the License for the specific language governing rights and limitations +## under the License. +## +## %CopyrightEnd% +## +# + +## Start the given executable, wait for stop command, +## stop the running executable and wait for exit. + +die () { + r=$? + echo "$0:" "$*" 1>&2 + exit $r +} + +test -x "$1" || die "Not Executable: $1" + +# Redirect stdin to make sure the stop command is read by us below +# and does not go to the executable +"$@" 0< /dev/null & +PID=$! + +# Wait for stop command +while read LINE; do + case :"$LINE" in + :"stop") + break;; + esac +done + +kill $PID +wait $PID -- cgit v1.2.3 From 3fe74b2d7d150078faed977ca79ddf96e3b2c000 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 4 Jul 2014 15:37:56 +0200 Subject: Write list of trap targets --- lib/snmp/src/misc/snmp_config.erl | 101 ++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 43 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 91240082f1..9e9865f3b5 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -37,8 +37,10 @@ write_agent_snmp_context_conf/1, write_agent_snmp_community_conf/1, write_agent_snmp_standard_conf/2, - write_agent_snmp_target_addr_conf/4, - write_agent_snmp_target_addr_conf/6, + write_agent_snmp_target_addr_conf/3, + write_agent_snmp_target_addr_conf/4, + write_agent_snmp_target_addr_conf/5, + write_agent_snmp_target_addr_conf/6, write_agent_snmp_target_params_conf/2, write_agent_snmp_notify_conf/2, write_agent_snmp_usm_conf/5, @@ -1797,21 +1799,18 @@ update_agent_standard_config(Dir, Conf) -> %% ------ target_addr.conf ------ %% -write_agent_snmp_target_addr_conf(Dir, Domain, Addr, Vsns) - when is_atom(Domain) -> - Timeout = 1500, - RetryCount = 3, +write_agent_snmp_target_addr_conf(Dir, Addresses, Vsns) -> + Timeout = 1500, + RetryCount = 3, write_agent_snmp_target_addr_conf( - Dir, Domain, Addr, Timeout, RetryCount, Vsns); -write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Vsns) - when is_integer(UDP) -> - Domain = snmp_target_mib:default_domain(), - Addr = {ManagerIp, UDP}, - write_agent_snmp_target_addr_conf(Dir, Domain, Addr, Vsns). + Dir, Addresses, Timeout, RetryCount, Vsns). + +write_agent_snmp_target_addr_conf(Dir, Domain_or_Ip, Addr_or_Port, Vsns) -> + Addresses = [{Domain_or_Ip, Addr_or_Port}], + write_agent_snmp_target_addr_conf(Dir, Addresses, Vsns). write_agent_snmp_target_addr_conf( - Dir, Domain, Addr, Timeout, RetryCount, Vsns) - when is_atom(Domain) -> + Dir, Addresses, Timeout, RetryCount, Vsns) -> Comment = "%% This file defines the target address parameters.\n" "%% The data is inserted into the snmpTargetAddrTable defined\n" @@ -1831,43 +1830,59 @@ write_agent_snmp_target_addr_conf( "%% [127,0,0,0], 2048}.\n" "%%\n\n", Hdr = header() ++ Comment, - F = fun(v1 = Vsn, Acc) -> - [{mk_name(Domain, Addr, Vsn), - Domain, Addr, Timeout, RetryCount, - "std_trap", mk_param(Vsn), "", [], 2048}| Acc]; - (v2 = Vsn, Acc) -> - [{mk_name(Domain, Addr, Vsn), - Domain, Addr, Timeout, RetryCount, - "std_trap", mk_param(Vsn), "", [], 2048}, - {lists:flatten( - io_lib:format("~s.2",[mk_name(Domain, Addr, Vsn)])), - Domain, Addr, Timeout, RetryCount, - "std_inform", mk_param(Vsn), "", [], 2048}| Acc]; - (v3 = Vsn, Acc) -> - [{mk_name(Domain, Addr, Vsn), - Domain, Addr, Timeout, RetryCount, - "std_trap", mk_param(Vsn), "", [], 2048}, - {lists:flatten( - io_lib:format("~s.3",[mk_name(Domain, Addr, Vsn)])), - Domain, Addr, Timeout, RetryCount, - "std_inform", mk_param(Vsn), "mgrEngine", [], 2048}| Acc] - end, - Conf = lists:foldl(F, [], Vsns), - write_agent_target_addr_config(Dir, Hdr, Conf); + Conf = + lists:foldl( + fun ({Domain_or_Ip, Addr_or_Port} = Address, OuterAcc) -> + lists:foldl( + fun(v1 = Vsn, Acc) -> + [{mk_name(Address, Vsn), + Domain_or_Ip, Addr_or_Port, + Timeout, RetryCount, + "std_trap", mk_param(Vsn), "", + [], 2048}| Acc]; + (v2 = Vsn, Acc) -> + [{mk_name(Address, Vsn), + Domain_or_Ip, Addr_or_Port, + Timeout, RetryCount, + "std_trap", mk_param(Vsn), "", + [], 2048}, + {lists:flatten( + io_lib:format( + "~s.2", [mk_name(Address, Vsn)])), + Domain_or_Ip, Addr_or_Port, + Timeout, RetryCount, + "std_inform", mk_param(Vsn), "", + [], 2048}| Acc]; + (v3 = Vsn, Acc) -> + [{mk_name(Address, Vsn), + Domain_or_Ip, Addr_or_Port, + Timeout, RetryCount, + "std_trap", mk_param(Vsn), "", + [], 2048}, + {lists:flatten( + io_lib:format( + "~s.3", [mk_name(Address, Vsn)])), + Domain_or_Ip, Addr_or_Port, + Timeout, RetryCount, + "std_inform", mk_param(Vsn), "mgrEngine", + [], 2048} | Acc] + end, OuterAcc, Vsns) + end, [], Addresses), + write_agent_target_addr_config(Dir, Hdr, Conf). + write_agent_snmp_target_addr_conf( - Dir, ManagerIp, UDP, Timeout, RetryCount, Vsns) when is_integer(UDP) -> - Domain = snmp_target_mib:default_domain(), - Addr = {ManagerIp, UDP}, + Dir, Domain_or_Ip, Addr_or_Port, Timeout, RetryCount, Vsns) -> + Addresses = [{Domain_or_Ip, Addr_or_Port}], write_agent_snmp_target_addr_conf( - Dir, Domain, Addr, Timeout, RetryCount, Vsns). + Dir, Addresses, Timeout, RetryCount, Vsns). mk_param(Vsn) -> lists:flatten(io_lib:format("target_~w", [Vsn])). -mk_name(Domain, Addr, Vsn) -> +mk_name(Address, Vsn) -> lists:flatten( io_lib:format( - "~s ~w", [snmp_conf:mk_addr_string({Domain, Addr}), Vsn])). + "~s ~w", [snmp_conf:mk_addr_string(Address), Vsn])). write_agent_target_addr_config(Dir, Hdr, Conf) -> snmpa_conf:write_target_addr_config(Dir, Hdr, Conf). -- cgit v1.2.3 From 06c3bbdcff4af11aba54309bb09ecc3eed96d754 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 4 Jul 2014 15:38:53 +0200 Subject: Test inform to dual transports --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 148 +++++++++++++++++++++++--------- 1 file changed, 106 insertions(+), 42 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index fa92beb6b1..7a2b05c048 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -45,16 +45,22 @@ all() -> ]. groups() -> - [{ipv4, [], [{group, get}, - {group, inform} - ]}, - {ipv6, [], [{group, get}, - {group, inform}, - {group, dual_ip} - ]}, - {get, [], [erlang_agent_netsnmp_get]}, - {inform, [], [erlang_agent_netsnmp_inform]}, - {dual_ip, [], [erlang_agent_dual_ip_get]} + [{ipv4, [], + [{group, get}, + {group, inform} + ]}, + {ipv6, [], + [{group, get}, + {group, inform}, + {group, dual_ip} + ]}, + {get, [], + [erlang_agent_netsnmp_get]}, + {inform, [], + [erlang_agent_netsnmp_inform]}, + {dual_ip, [], + [erlang_agent_dual_ip_get, + erlang_agent_dual_ip_inform]} ]. init_per_suite(Config) -> @@ -81,7 +87,7 @@ init_per_group(ipv6, Config) -> _ -> {skip, "Host does not support IPV6"} end; - +%% init_per_group(ipv4, Config) -> Dir = ?config(priv_dir, Config), Domain = transportDomainUdpIpv4, @@ -95,51 +101,44 @@ init_per_group(ipv4, Config) -> agent_config(Dir, Transports, Domain, TrapAddr, Versions), [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv4} | Config]; - +%% init_per_group(dual_ip, Config) -> - case os:find_executable("snmpget") of - false -> - {skip, "snmpget not found"}; - Path -> + case find_executables([snmpget, snmptrapd], Config) of + NewConfig when is_list(NewConfig) -> case ct:require(ipv6_hosts) of ok -> Dir = ?config(priv_dir, Config), + Domain = transportDomainUdpIpv4, + AgentPort = ?config(agent_port, Config), + ManagerPort = ?config(manager_port, Config), {ok, Host} = inet:gethostname(), {ok, IPv4Addr} = inet:getaddr(Host, inet), {ok, IPv6Addr} = inet:getaddr(Host, inet6), - Domain = snmpUDPDomain, Transports = - [{Domain, {IPv4Addr, ?AGENT_PORT}}, - {transportDomainUdpIpv6, {IPv6Addr, ?AGENT_PORT}}], - TrapAddr = {IPv4Addr, 0}, + [{Domain, {IPv4Addr, AgentPort}}, + {transportDomainUdpIpv6, {IPv6Addr, AgentPort}}], + Targets = + [{Domain, {IPv4Addr, ManagerPort}}, + {transportDomainUdpIpv6, {IPv6Addr, ManagerPort}}], Versions = [v2], - agent_config( - Dir, Transports, Domain, TrapAddr, Versions), + agent_config(Dir, Transports, Targets, Versions), [{host, Host}, {port, ?AGENT_PORT}, - {snmp_versions, Versions}, - {snmpget, Path} | Config]; + {snmp_versions, Versions} + | NewConfig]; _ -> {skip, "Host does not support IPV6"} - end + end; + Other -> + Other end; - +%% init_per_group(get, Config) -> %% From Ubuntu package snmp - case os:find_executable("snmpget") of - false -> - {skip, "snmpget not found"}; - Path -> - [{snmpget, Path} | Config] - end; - + find_executables([snmpget], Config); +%% init_per_group(inform, Config) -> %% From Ubuntu package snmptrapfmt - case os:find_executable("snmptrapd") of - false -> - {skip, "snmptrapd not found"}; - Path -> - [{snmptrapd, Path} | Config] - end; + find_executables([snmptrapd], Config); init_per_group(_, Config) -> Config. @@ -167,6 +166,18 @@ end_per_testcase(_, Config) -> end, Config. +find_executables([], Config) -> + Config; +find_executables([Exec | Execs], Config) -> + case os:find_executable(atom_to_list(Exec)) of + false -> + {skip, Exec ++ " not found"}; + Path -> + find_executables( + Execs, + [{Exec, Path} | Config]) + end. + start_agent(Config) -> ok = application:load(snmp), ok = application:set_env(snmp, agent, app_env(Config)), @@ -213,9 +224,9 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> "--disableAuthorization=yes", "--snmpTrapdAddr=" ++ net_snmp_transport(IPVersion) ++ Host ++ ":" ++ integer_to_list(?config(manager_port, Config))], - {ok, CheckMP} = re:compile("NET-SNMP version ", [anchored]), + {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]), ProgHandle = - start_program(snmptrapd, SnmptrapdArgs, CheckMP, Config), + start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config), snmpa:send_notification( snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), @@ -235,6 +246,56 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> stop_program(ProgHandle). +%%-------------------------------------------------------------------- +erlang_agent_dual_ip_inform(Config) when is_list(Config) -> + Host = ?config(host, Config), + ManagerPort = ?config(manager_port, Config), + DataDir = ?config(data_dir, Config), + + start_agent(Config), + ok = + snmpa:load_mib( + snmp_master_agent, filename:join(DataDir, "TestTrapv2")), + + ManagerPortStr = integer_to_list(ManagerPort), + SnmptrapdArgs = + ["-f", "-Lo", + "-M", DataDir, + "--disableAuthorization=yes", + "--snmpTrapdAddr=" ++ + net_snmp_transport(ipv4) ++ Host ++ ":" ++ ManagerPortStr ++ + "," ++ + net_snmp_transport(ipv6) ++ Host ++ ":" ++ ManagerPortStr], + {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]), + ProgHandle = + start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config), + + snmpa:send_notification( + snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), + + receive + {snmp_targets, erlang_agent_test, Addresses} -> + ct:pal("Notification sent to: ~p~n", [Addresses]), + erlang_agent_dual_ip_inform_responses(Addresses) + end, + stop_program(ProgHandle). + +erlang_agent_dual_ip_inform_responses([]) -> + ok; +erlang_agent_dual_ip_inform_responses([Address | Addresses] = AAs) -> + receive + {snmp_notification, erlang_agent_test, + {got_response, Address}} -> + ct:pal("Got response from: ~p~n", [Address]), + erlang_agent_dual_ip_inform_responses(Addresses); + {snmp_notification, erlang_agent_test, + {no_response, _} = NoResponse} -> + ct:fail(NoResponse); + {snmp_notification, erlang_agent_test, _} = Unexpected -> + ct:pal("Unexpected response: ~p", [Unexpected]), + erlang_agent_dual_ip_inform_responses(AAs) + end. + %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- @@ -369,6 +430,9 @@ oid_str([Int | Rest], Acc) -> oid_str(Rest, Acc ++ "." ++ integer_to_list(Int)). agent_config(Dir, Transports, TargetDomain, TargetAddr, Versions) -> + agent_config(Dir, Transports, [{TargetDomain, TargetAddr}], Versions). +%% +agent_config(Dir, Transports, Targets, Versions) -> EngineID = ?AGENT_ENGIN_ID, MMS = ?DEFAULT_MAX_MESSAGE_SIZE, ok = snmp_config:write_agent_snmp_conf(Dir, Transports, EngineID, MMS), @@ -379,7 +443,7 @@ agent_config(Dir, Transports, TargetDomain, TargetAddr, Versions) -> Dir, "snmp_to_snmpnet_SUITE"), ok = snmp_config:write_agent_snmp_target_addr_conf( - Dir, TargetDomain, TargetAddr, Versions), + Dir, Targets, Versions), ok = snmp_config:write_agent_snmp_target_params_conf(Dir, Versions), ok = snmp_config:write_agent_snmp_notify_conf(Dir, inform), ok = snmp_config:write_agent_snmp_vacm_conf(Dir, Versions, none). -- cgit v1.2.3 From 8547d1fe580c714e15ab205d6b2635333ea380f8 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 23 Jul 2014 15:42:20 +0200 Subject: Improve external snmp commands args --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 120 ++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 52 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index 7a2b05c048..78c3a53f89 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -16,7 +16,13 @@ %% %% %CopyrightEnd% %% -%% +%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% This test suite uses the following external programs: +%% snmpget From packet 'snmp' (in Ubuntu 12.04) +%% snmptrapd From packet 'snmpd' (in Ubuntu 12.04) +%% They originate from the Net-SNMP applications, see: +%% http://net-snmp.sourceforge.net/ + -module(snmp_to_snmpnet_SUITE). @@ -26,11 +32,14 @@ -include_lib("common_test/include/ct.hrl"). -include_lib("snmp/include/STANDARD-MIB.hrl"). --define(AGENT_ENGIN_ID, "ErlangSnmpAgent"). +-define(AGENT_ENGINE_ID, "ErlangSnmpAgent"). -define(AGENT_PORT, 4000). -define(MANAGER_PORT, 8989). -define(DEFAULT_MAX_MESSAGE_SIZE, 484). --define(SYS_DESC, <<"iso.3.6.1.2.1.1.1.0 = STRING: \"Erlang SNMP agent\"">>). + +expected(?sysDescr_instance = Oid, get) -> + OidStr = oid_str(Oid), + iolist_to_binary([OidStr | " = STRING: \"Erlang SNMP agent\""]). %%-------------------------------------------------------------------- %% Common Test interface functions ----------------------------------- @@ -192,7 +201,9 @@ erlang_agent_netsnmp_get() -> erlang_agent_netsnmp_get(Config) when is_list(Config) -> start_agent(Config), - ?SYS_DESC = snmpget(oid_str(?sysDescr_instance), Config), + Oid = ?sysDescr_instance, + Expected = expected(Oid, get), + Expected = snmpget(Oid, Config), ok. %%-------------------------------------------------------------------- @@ -201,10 +212,10 @@ erlang_agent_dual_ip_get() -> "snmpnet ipv4 and snmpnet ipv6 manager at the same time"}]. erlang_agent_dual_ip_get(Config) when is_list(Config) -> start_agent(Config), - - OidStr = oid_str(?sysDescr_instance), - ?SYS_DESC = snmpget(OidStr, [{ip_version, ipv4} | Config]), - ?SYS_DESC = snmpget(OidStr, [{ip_version, ipv6} | Config]), + Oid = ?sysDescr_instance, + Expected = expected(Oid, get), + Expected = snmpget(Oid, [{ip_version, ipv4} | Config]), + Expected = snmpget(Oid, [{ip_version, ipv6} | Config]), ok. %%-------------------------------------------------------------------- @@ -212,21 +223,14 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> Host = ?config(host, Config), IPVersion = ?config(ip_version, Config), DataDir = ?config(data_dir, Config), + Mib = "TestTrapv2", start_agent(Config), - ok = - snmpa:load_mib( - snmp_master_agent, filename:join(DataDir, "TestTrapv2")), - - SnmptrapdArgs = - ["-f", "-Lo", - "-M", DataDir, - "--disableAuthorization=yes", - "--snmpTrapdAddr=" ++ net_snmp_transport(IPVersion) ++ - Host ++ ":" ++ integer_to_list(?config(manager_port, Config))], - {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]), - ProgHandle = - start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config), + ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), + + TrapAddr = net_snmp_transport(IPVersion) ++ Host ++ + ":" ++ integer_to_list(?config(manager_port, Config)), + ProgHandle = start_snmptrapd(Mib, TrapAddr, Config), snmpa:send_notification( snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), @@ -251,24 +255,17 @@ erlang_agent_dual_ip_inform(Config) when is_list(Config) -> Host = ?config(host, Config), ManagerPort = ?config(manager_port, Config), DataDir = ?config(data_dir, Config), + Mib = "TestTrapv2", start_agent(Config), - ok = - snmpa:load_mib( - snmp_master_agent, filename:join(DataDir, "TestTrapv2")), + ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), ManagerPortStr = integer_to_list(ManagerPort), - SnmptrapdArgs = - ["-f", "-Lo", - "-M", DataDir, - "--disableAuthorization=yes", - "--snmpTrapdAddr=" ++ - net_snmp_transport(ipv4) ++ Host ++ ":" ++ ManagerPortStr ++ - "," ++ - net_snmp_transport(ipv6) ++ Host ++ ":" ++ ManagerPortStr], - {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]), - ProgHandle = - start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config), + TrapAddrs = + net_snmp_transport(ipv4) ++ Host ++ ":" ++ ManagerPortStr ++ + "," ++ + net_snmp_transport(ipv6) ++ Host ++ ":" ++ ManagerPortStr, + ProgHandle = start_snmptrapd(Mib, TrapAddrs, Config), snmpa:send_notification( snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), @@ -281,8 +278,14 @@ erlang_agent_dual_ip_inform(Config) when is_list(Config) -> stop_program(ProgHandle). erlang_agent_dual_ip_inform_responses([]) -> - ok; -erlang_agent_dual_ip_inform_responses([Address | Addresses] = AAs) -> + receive + {snmp_notification, erlang_agent_test, _} = Unexpected -> + ct:pal("Unexpected response: ~p", [Unexpected]), + erlang_agent_dual_ip_inform_responses([]) + after 0 -> + ok + end; +erlang_agent_dual_ip_inform_responses([Address | Addresses]) -> receive {snmp_notification, erlang_agent_test, {got_response, Address}} -> @@ -290,16 +293,13 @@ erlang_agent_dual_ip_inform_responses([Address | Addresses] = AAs) -> erlang_agent_dual_ip_inform_responses(Addresses); {snmp_notification, erlang_agent_test, {no_response, _} = NoResponse} -> - ct:fail(NoResponse); - {snmp_notification, erlang_agent_test, _} = Unexpected -> - ct:pal("Unexpected response: ~p", [Unexpected]), - erlang_agent_dual_ip_inform_responses(AAs) + ct:fail(NoResponse) end. %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- -snmpget(OidStr, Config) -> +snmpget(Oid, Config) -> Versions = ?config(snmp_versions, Config), IPVersion = ?config(ip_version, Config), Host = ?config(host, Config), @@ -307,14 +307,26 @@ snmpget(OidStr, Config) -> Args = ["-c", "public", net_snmp_version(Versions), - net_snmp_transport(IPVersion) ++ - Host ++ ":" ++ integer_to_list(Port), - OidStr], + "-m", "", + "-Cf", + net_snmp_transport(IPVersion)++Host++":"++ integer_to_list(Port), + oid_str(Oid)], ProgHandle = start_program(snmpget, Args, none, Config), {_, line, Line} = get_program_output(ProgHandle), stop_program(ProgHandle), Line. +start_snmptrapd(Mibs, TrapAddrs, Config) -> + DataDir = ?config(data_dir, Config), + MibDir = filename:join(code:lib_dir(snmp), "mibs"), + SnmptrapdArgs = + ["-f", "-Lo", "-C", + "-m", Mibs, + "-M", MibDir++":"++DataDir, + "--disableAuthorization=yes", + "--snmpTrapdAddr="++TrapAddrs], + {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]), + start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config). start_program(Prog, Args, StartCheckMP, Config) -> Path = ?config(Prog, Config), @@ -421,19 +433,23 @@ app_env(Config) -> {note_store, [{verbosity, silence}]}, {net_if, [{verbosity, trace}]}]. -oid_str([Int | Rest]) -> - oid_str(Rest, integer_to_list(Int)). +oid_str([1 | Ints]) -> + "iso." ++ oid_str_tl(Ints); +oid_str(Ints) -> + oid_str_tl(Ints). -oid_str([], Acc) -> - Acc; -oid_str([Int | Rest], Acc) -> - oid_str(Rest, Acc ++ "." ++ integer_to_list(Int)). +oid_str_tl([]) -> + ""; +oid_str_tl([Int]) -> + integer_to_list(Int); +oid_str_tl([Int | Ints]) -> + integer_to_list(Int) ++ "." ++ oid_str_tl(Ints). agent_config(Dir, Transports, TargetDomain, TargetAddr, Versions) -> agent_config(Dir, Transports, [{TargetDomain, TargetAddr}], Versions). %% agent_config(Dir, Transports, Targets, Versions) -> - EngineID = ?AGENT_ENGIN_ID, + EngineID = ?AGENT_ENGINE_ID, MMS = ?DEFAULT_MAX_MESSAGE_SIZE, ok = snmp_config:write_agent_snmp_conf(Dir, Transports, EngineID, MMS), ok = snmp_config:write_agent_snmp_context_conf(Dir), -- cgit v1.2.3 From 99c1ea078124faac8062df3deb9a98d2be495a12 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 23 Jul 2014 17:27:47 +0200 Subject: Call new Net-SNMP test suite from top suite --- lib/snmp/test/snmp_SUITE.erl | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_SUITE.erl b/lib/snmp/test/snmp_SUITE.erl index 22b9c64588..6fabf6410f 100644 --- a/lib/snmp/test/snmp_SUITE.erl +++ b/lib/snmp/test/snmp_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2012. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. 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 @@ -80,7 +80,8 @@ groups() -> {group, note_store_test}]}, {agent, [], [{group, mibs_test}, {group, nfilter_test}, - {group, agent_test}]}, + {group, agent_test}, + {group, snmpnet_test}]}, {manager, [], [{group, manager_config_test}, {group, manager_user_test}, {group, manager_test}]}, @@ -95,6 +96,7 @@ groups() -> {mibs_test, [], [{snmp_agent_mibs_test, all}]}, {nfilter_test, [], [{snmp_agent_nfilter_test, all}]}, {agent_test, [], [{snmp_agent_test, all}]}, + {snmpnet_test, [], [{snmp_to_snmpnet_SUITE, all}]}, {manager_config_test, [], [{snmp_manager_config_test, all}]}, {manager_user_test, [], [{snmp_manager_user_test, all}]}, {manager_test, [], [{snmp_manager_test, all}]} @@ -107,15 +109,18 @@ init_per_group(GroupName, Config0) -> "~n GroupName: ~p" "~n Config0: ~p", [GroupName, Config0]), - %% Group name is not really the suite name - %% (but it is a good enough approximation), - %% but it does not matter since we only need - %% it to be unique. - snmp_test_lib:init_suite_top_dir(GroupName, Config0). - - + case GroupName of + snmpnet_test -> + Config0; + _ -> + %% Group name is not really the suite name + %% (but it is a good enough approximation), + %% but it does not matter since we only need + %% it to be unique. + snmp_test_lib:init_suite_top_dir(GroupName, Config0) + end. + +end_per_group(snmpnet_test, Config) -> + Config; end_per_group(_GroupName, Config) -> lists:keydelete(snmp_suite_top_dir, 1, Config). - - - -- cgit v1.2.3 From ad00eb19928f7056386a37e633a0b4e3d1f9442b Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 24 Jul 2014 13:52:10 +0200 Subject: Fix test manager in agent tests for IPv6 --- lib/snmp/test/snmp_agent_test.erl | 9 ++++-- lib/snmp/test/snmp_agent_test_lib.erl | 12 +++----- lib/snmp/test/snmp_test_mgr.erl | 36 +++++++++++++----------- lib/snmp/test/snmp_test_mgr_misc.erl | 52 +++++++++++++++++++---------------- 4 files changed, 60 insertions(+), 49 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index b181bf957d..9a9258aa91 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -653,7 +653,9 @@ init_per_group_ipv6(GroupName, Config, Init) -> ok -> Init( snmp_test_lib:init_group_top_dir( - GroupName, [{ipfamily, inet6}|Config])); + GroupName, + [{ipfamily, inet6}, + {ip, ?LOCALHOST(inet6)} | lists:keydelete(ip, 1, Config)])); _ -> {skip, "Host does not support IPV6"} end. @@ -6654,6 +6656,7 @@ otp8395({init, Config}) when is_list(Config) -> %% SubAgentHost = ?HPSTNAME(SubAgentNode), ManagerHost = ?HOSTNAME(ManagerNode), + IpFamily = inet, Host = snmp_test_lib:hostname(), Ip = ?LOCALHOST(), {ok, AgentIP0} = snmp_misc:ip(AgentHost), @@ -6671,7 +6674,7 @@ otp8395({init, Config}) when is_list(Config) -> Vsns = [v1], AgentConfDir = ?config(agent_conf_dir, Config), ManagerConfDir = ?config(manager_top_dir, Config), - config(Vsns, ManagerConfDir, AgentConfDir, ManagerIP, AgentIP), + config(Vsns, ManagerConfDir, AgentConfDir, ManagerIP, AgentIP, IpFamily), %% -- @@ -6680,6 +6683,7 @@ otp8395({init, Config}) when is_list(Config) -> Config2 = start_agent([{host, Host}, {ip, Ip}, + {ipfamily, IpFamily}, {agent_node, AgentNode}, {agent_host, AgentHost}, {agent_ip, AgentIP}, @@ -6759,6 +6763,7 @@ otp8395(Config) when is_list(Config) -> put(mib_dir, ?config(mib_dir, Config)), put(vsn, v1), put(master_host, ?config(agent_host, Config)), + put(ipfamily, ?config(ipfamily, Config)), try_test(simple_standard_test), ?SLEEP(1000), diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 6925c16ffb..333fe6eb66 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -251,6 +251,7 @@ init_case(Config) when is_list(Config) -> put(mip, tuple_to_list(MIP)), put(masterip, tuple_to_list(MasterIP)), put(sip, tuple_to_list(SIP)), + put(ipfamily, IpFamily), MibDir = ?config(mib_dir, Config), put(mib_dir, MibDir), @@ -359,6 +360,7 @@ run(Mod, Func, Args, Opts) -> {packet_server_debug,true}, {debug,true}, {agent, get(master_host)}, + {ipfamily, get(ipfamily)}, {agent_udp, 4000}, {trap_udp, 5000}, {recbuf,65535}, @@ -1383,12 +1385,9 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) -> ?line {Domain, ManagerAddr} = case IpFamily of inet6 -> - %% XXX Run IPv6 tests over IPv4 compatibility address - %% since the test manager needs to be rewritten to - %% handle IPv6 before we can improve this. Ipv6Domain = transportDomainUdpIpv6, - AgentIpv6Addr = {mk_ipv6_ip(AIp), 4000}, - ManagerIpv6Addr = {mk_ipv6_ip(MIp), ?TRAP_UDP}, + AgentIpv6Addr = {AIp, 4000}, + ManagerIpv6Addr = {MIp, ?TRAP_UDP}, ?line ok = snmp_config:write_agent_snmp_files( AgentConfDir, Vsns, @@ -1416,9 +1415,6 @@ config(Vsns, MgrDir, AgentConfDir, MIp, AIp, IpFamily) -> ?line write_notify_conf(AgentConfDir), ok. -mk_ipv6_ip([A,B,C,D]) -> - [0,0,0,0,0,0,0,0,0,0,255,255,A,B,C,D]. - delete_files(Config) -> AgentDir = ?config(agent_dir, Config), delete_files(AgentDir, [db, conf]). diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl index d4eb00ff91..cf62edba1c 100644 --- a/lib/snmp/test/snmp_test_mgr.erl +++ b/lib/snmp/test/snmp_test_mgr.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -235,21 +235,23 @@ init({Options, CallerPid}) -> VsnHdrD = {Com, User, EngineId, CtxEngineId, mk_seclevel(SecLevel)}, io:format("[~w] ~p -> VsnHdrD: ~p~n", [?MODULE, self(), VsnHdrD]), + IpFamily = get_value(ipfamily, Options, inet), + io:format("[~w] ~p -> IpFamily: ~p~n", [?MODULE, self(), IpFamily]), AgIp = case snmp_misc:assq(agent, Options) of {value, Tuple4} when is_tuple(Tuple4) andalso (size(Tuple4) =:= 4) -> Tuple4; {value, Host} when is_list(Host) -> - {ok, Ip} = snmp_misc:ip(Host), + {ok, Ip} = snmp_misc:ip(Host, IpFamily), Ip end, io:format("[~w] ~p -> AgIp: ~p~n", [?MODULE, self(), AgIp]), Quiet = lists:member(quiet, Options), io:format("[~w] ~p -> Quiet: ~p~n", [?MODULE, self(), Quiet]), - PackServ = start_packet_server(Quiet, Options, CallerPid, - AgIp, Udp, TrapUdp, - VsnHdrD, Version, Dir, RecBufSz, - PacksDbg), + PackServ = + start_packet_server( + Quiet, Options, CallerPid, AgIp, Udp, TrapUdp, + VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily), d("init -> packet server: ~p",[PackServ]), State = #state{parent = CallerPid, quiet = Quiet, @@ -263,23 +265,21 @@ init({Options, CallerPid}) -> end. start_packet_server(false, _Options, _CallerPid, AgIp, Udp, TrapUdp, - VsnHdrD, Version, Dir, RecBufSz, PacksDbg) -> + VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily) -> d("start_packet_server -> entry", []), - ?PACK_SERV:start_link_packet({msg, self()}, - AgIp, Udp, TrapUdp, - VsnHdrD, Version, Dir, RecBufSz, - PacksDbg); + ?PACK_SERV:start_link_packet( + {msg, self()}, AgIp, Udp, TrapUdp, + VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily); start_packet_server(true, Options, CallerPid, AgIp, Udp, TrapUdp, - VsnHdrD, Version, Dir, RecBufSz, PacksDbg) -> + VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily) -> Type = get_value(receive_type, Options, pdu), d("start_packet_server -> entry with" "~n CallerPid: ~p" "~n when" "~n Type: ~p",[CallerPid, Type]), - ?PACK_SERV:start_link_packet({Type, CallerPid}, - AgIp, Udp, TrapUdp, - VsnHdrD, Version, Dir, RecBufSz, - PacksDbg). + ?PACK_SERV:start_link_packet( + {Type, CallerPid}, AgIp, Udp, TrapUdp, + VsnHdrD, Version, Dir, RecBufSz, PacksDbg, IpFamily). is_options_ok([{mibs,List}|Opts]) when is_list(List) -> is_options_ok(Opts); @@ -287,6 +287,10 @@ is_options_ok([quiet|Opts]) -> is_options_ok(Opts); is_options_ok([{agent,_}|Opts]) -> is_options_ok(Opts); +is_options_ok([{ipfamily,IpFamily}|Opts]) + when IpFamily =:= inet; + IpFamily =:= inet6 -> + is_options_ok(Opts); is_options_ok([{agent_udp,Int}|Opts]) when is_integer(Int) -> is_options_ok(Opts); is_options_ok([{trap_udp,Int}|Opts]) when is_integer(Int) -> diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl index 5525c5c3ec..5274dcacd9 100644 --- a/lib/snmp/test/snmp_test_mgr_misc.erl +++ b/lib/snmp/test/snmp_test_mgr_misc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2012. All Rights Reserved. +%% Copyright Ericsson AB 1996-2014. 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 @@ -23,7 +23,7 @@ -module(snmp_test_mgr_misc). %% API --export([start_link_packet/8, start_link_packet/9, +-export([start_link_packet/8, start_link_packet/9, start_link_packet/10, stop/1, send_discovery_pdu/2, send_pdu/2, send_msg/4, send_bytes/2, @@ -31,7 +31,7 @@ get_pdu/1, set_pdu/2, format_hdr/1]). %% internal exports --export([init_packet/10]). +-export([init_packet/11]). -compile({no_auto_import, [error/2]}). @@ -42,22 +42,26 @@ %%---------------------------------------------------------------------- %% The InHandler process will receive messages on the form {snmp_pdu, Pdu}. %%---------------------------------------------------------------------- -start_link_packet(InHandler, - AgentIp, UdpPort, TrapUdp, - VsnHdr, Version, Dir, BufSz) -> - start_link_packet(InHandler, - AgentIp, UdpPort, TrapUdp, - VsnHdr, Version, Dir, BufSz, - false). - -start_link_packet(InHandler, - AgentIp, UdpPort, TrapUdp, - VsnHdr, Version, Dir, BufSz, - Dbg) when is_integer(UdpPort) -> - Args = [self(), InHandler, - AgentIp, UdpPort, TrapUdp, - VsnHdr, Version, Dir, BufSz, - Dbg], +start_link_packet( + InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz) -> + start_link_packet( + InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz, + false). + +start_link_packet( + InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz, + Dbg) -> + start_link_packet( + InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz, + Dbg, inet). + +start_link_packet( + InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz, + Dbg, IpFamily) when is_integer(UdpPort) -> + Args = + [self(), + InHandler, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz, + Dbg, IpFamily], proc_lib:start_link(?MODULE, init_packet, Args). stop(Pid) -> @@ -90,12 +94,14 @@ send_bytes(Bytes, PacketPid) -> %%-------------------------------------------------- %% The SNMP encode/decode process %%-------------------------------------------------- -init_packet(Parent, SnmpMgr, - AgentIp, UdpPort, TrapUdp, - VsnHdr, Version, Dir, BufSz, DbgOptions) -> +init_packet( + Parent, + SnmpMgr, AgentIp, UdpPort, TrapUdp, VsnHdr, Version, Dir, BufSz, + DbgOptions, IpFamily) -> put(sname, mgr_misc), init_debug(DbgOptions), - {ok, UdpId} = gen_udp:open(TrapUdp, [{recbuf,BufSz},{reuseaddr, true}]), + {ok, UdpId} = + gen_udp:open(TrapUdp, [{recbuf,BufSz}, {reuseaddr, true}, IpFamily]), put(msg_id, 1), proc_lib:init_ack(Parent, self()), init_usm(Version, Dir), -- cgit v1.2.3 From c5d0122795f8294478f0bafce53ef72c369fd2cc Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Mon, 28 Jul 2014 15:41:06 +0200 Subject: Fix call to non-existent function --- lib/snmp/src/manager/snmpm_conf.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl index ed4cfd749e..888f19aec6 100644 --- a/lib/snmp/src/manager/snmpm_conf.erl +++ b/lib/snmp/src/manager/snmpm_conf.erl @@ -308,7 +308,7 @@ read_usm_config(Dir) check_usm_user_config(Entry, State) -> - {check_ok(snmpm_config:check_usrm_user_config(Entry)), + {check_ok(snmpm_config:check_usm_user_config(Entry)), State}. write_usm_conf(Fd, "", Conf) -> -- cgit v1.2.3 From 87301df2f4d22153364f11d1c07a5be1e9423c13 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Mon, 28 Jul 2014 16:32:55 +0200 Subject: Adjust test cases for daily builds --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 65 +++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 23 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index 78c3a53f89..a54fb58117 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -91,7 +91,8 @@ init_per_group(ipv6, Config) -> TrapAddr = {IpAddr, ManagerPort}, Versions = [v2], agent_config(Dir, Transports, Domain, TrapAddr, Versions), - [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv6} + [{snmp_versions, Versions}, {ip_version, ipv6}, + {trapaddrs, [IpAddr]} | Config]; _ -> {skip, "Host does not support IPV6"} @@ -108,7 +109,8 @@ init_per_group(ipv4, Config) -> TrapAddr = {IpAddr, ManagerPort}, Versions = [v2], agent_config(Dir, Transports, Domain, TrapAddr, Versions), - [{host, Host}, {snmp_versions, Versions}, {ip_version, ipv4} + [{snmp_versions, Versions}, {ip_version, ipv4}, + {trapaddrs, [IpAddr]} | Config]; %% init_per_group(dual_ip, Config) -> @@ -131,8 +133,8 @@ init_per_group(dual_ip, Config) -> {transportDomainUdpIpv6, {IPv6Addr, ManagerPort}}], Versions = [v2], agent_config(Dir, Transports, Targets, Versions), - [{host, Host}, {port, ?AGENT_PORT}, - {snmp_versions, Versions} + [{port, ?AGENT_PORT}, {snmp_versions, Versions}, + {trapaddrs, [IPv4Addr, IPv6Addr]} | NewConfig]; _ -> {skip, "Host does not support IPV6"} @@ -178,9 +180,26 @@ end_per_testcase(_, Config) -> find_executables([], Config) -> Config; find_executables([Exec | Execs], Config) -> - case os:find_executable(atom_to_list(Exec)) of + ExecStr = atom_to_list(Exec), + case os:find_executable(ExecStr) of false -> - {skip, Exec ++ " not found"}; + find_sys_executables( + Execs, Config, Exec, ExecStr, + [["usr", "local", "sbin"], + ["usr", "sbin"], + ["sbin"]]); + Path -> + find_executables( + Execs, + [{Exec, Path} | Config]) + end. + +find_sys_executables(_Execs, _Config, _Exec, ExecStr, []) -> + {skip, ExecStr ++ " not found"}; +find_sys_executables(Execs, Config, Exec, ExecStr, [Dir | Dirs]) -> + case os:find_executable(filename:join(["/" | Dir] ++ [ExecStr])) of + false -> + find_sys_executables(Execs, Config, Exec, ExecStr, Dirs); Path -> find_executables( Execs, @@ -220,17 +239,15 @@ erlang_agent_dual_ip_get(Config) when is_list(Config) -> %%-------------------------------------------------------------------- erlang_agent_netsnmp_inform(Config) when is_list(Config) -> - Host = ?config(host, Config), - IPVersion = ?config(ip_version, Config), - DataDir = ?config(data_dir, Config), + [TrapAddr | _] = ?config(trapaddrs, Config), + DataDir = ?config(data_dir, Config), Mib = "TestTrapv2", start_agent(Config), ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), - TrapAddr = net_snmp_transport(IPVersion) ++ Host ++ - ":" ++ integer_to_list(?config(manager_port, Config)), - ProgHandle = start_snmptrapd(Mib, TrapAddr, Config), + TrapAddrStr = net_snmp_addr_str(TrapAddr, ?config(manager_port, Config)), + ProgHandle = start_snmptrapd(Mib, TrapAddrStr, Config), snmpa:send_notification( snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), @@ -252,7 +269,7 @@ erlang_agent_netsnmp_inform(Config) when is_list(Config) -> %%-------------------------------------------------------------------- erlang_agent_dual_ip_inform(Config) when is_list(Config) -> - Host = ?config(host, Config), + [TrapAddr1, TrapAddr2 | _] = ?config(trapaddrs, Config), ManagerPort = ?config(manager_port, Config), DataDir = ?config(data_dir, Config), Mib = "TestTrapv2", @@ -260,11 +277,10 @@ erlang_agent_dual_ip_inform(Config) when is_list(Config) -> start_agent(Config), ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), - ManagerPortStr = integer_to_list(ManagerPort), TrapAddrs = - net_snmp_transport(ipv4) ++ Host ++ ":" ++ ManagerPortStr ++ + net_snmp_addr_str(TrapAddr1, ManagerPort) ++ "," ++ - net_snmp_transport(ipv6) ++ Host ++ ":" ++ ManagerPortStr, + net_snmp_addr_str(TrapAddr2, ManagerPort), ProgHandle = start_snmptrapd(Mib, TrapAddrs, Config), snmpa:send_notification( @@ -301,15 +317,14 @@ erlang_agent_dual_ip_inform_responses([Address | Addresses]) -> %%-------------------------------------------------------------------- snmpget(Oid, Config) -> Versions = ?config(snmp_versions, Config), - IPVersion = ?config(ip_version, Config), - Host = ?config(host, Config), + [TrapAddr | _] = ?config(trapaddrs, Config), Port = ?config(agent_port, Config), Args = ["-c", "public", net_snmp_version(Versions), "-m", "", "-Cf", - net_snmp_transport(IPVersion)++Host++":"++ integer_to_list(Port), + net_snmp_addr_str(TrapAddr, Port), oid_str(Oid)], ProgHandle = start_program(snmpget, Args, none, Config), {_, line, Line} = get_program_output(ProgHandle), @@ -471,7 +486,11 @@ net_snmp_version([v2 | _]) -> net_snmp_version([v1 | _]) -> "-v1". -net_snmp_transport(ipv4) -> - "udp:"; -net_snmp_transport(ipv6) -> - "udp6:". +net_snmp_addr_str(IPv4Addr, Port) when tuple_size(IPv4Addr) =:= 4 -> + "udp:" ++ + inet_parse:ntoa(IPv4Addr) ++ ":" ++ + integer_to_list(Port); +net_snmp_addr_str(IPv6Addr, Port) when tuple_size(IPv6Addr) =:= 8 -> + "udp6:[" ++ + inet_parse:ntoa(IPv6Addr) ++ "]:" ++ + integer_to_list(Port). -- cgit v1.2.3 From fbc5e6a9a58e6d923442e260003e0c6d554749d0 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 29 Jul 2014 11:11:10 +0200 Subject: Fix testcase for really dual ip --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 170 +++++++++++--------------------- 1 file changed, 59 insertions(+), 111 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index a54fb58117..69d54570ea 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -68,8 +68,8 @@ groups() -> {inform, [], [erlang_agent_netsnmp_inform]}, {dual_ip, [], - [erlang_agent_dual_ip_get, - erlang_agent_dual_ip_inform]} + [erlang_agent_netsnmp_get, + erlang_agent_netsnmp_inform]} ]. init_per_suite(Config) -> @@ -81,61 +81,20 @@ end_per_suite(_Config) -> init_per_group(ipv6, Config) -> case ct:require(ipv6_hosts) of ok -> - Dir = ?config(priv_dir, Config), - Domain = transportDomainUdpIpv6, - AgentPort = ?config(agent_port, Config), - ManagerPort = ?config(manager_port, Config), - {ok, Host} = inet:gethostname(), - {ok, IpAddr} = inet:getaddr(Host, inet6), - Transports = [{Domain, {IpAddr, AgentPort}}], - TrapAddr = {IpAddr, ManagerPort}, - Versions = [v2], - agent_config(Dir, Transports, Domain, TrapAddr, Versions), - [{snmp_versions, Versions}, {ip_version, ipv6}, - {trapaddrs, [IpAddr]} - | Config]; + init_per_group_ip([inet6], Config); _ -> {skip, "Host does not support IPV6"} end; %% init_per_group(ipv4, Config) -> - Dir = ?config(priv_dir, Config), - Domain = transportDomainUdpIpv4, - AgentPort = ?config(agent_port, Config), - ManagerPort = ?config(manager_port, Config), - {ok, Host} = inet:gethostname(), - {ok, IpAddr} = inet:getaddr(Host, inet), - Transports = [{Domain, {IpAddr, AgentPort}}], - TrapAddr = {IpAddr, ManagerPort}, - Versions = [v2], - agent_config(Dir, Transports, Domain, TrapAddr, Versions), - [{snmp_versions, Versions}, {ip_version, ipv4}, - {trapaddrs, [IpAddr]} - | Config]; + init_per_group_ip([inet], Config); %% init_per_group(dual_ip, Config) -> case find_executables([snmpget, snmptrapd], Config) of NewConfig when is_list(NewConfig) -> case ct:require(ipv6_hosts) of ok -> - Dir = ?config(priv_dir, Config), - Domain = transportDomainUdpIpv4, - AgentPort = ?config(agent_port, Config), - ManagerPort = ?config(manager_port, Config), - {ok, Host} = inet:gethostname(), - {ok, IPv4Addr} = inet:getaddr(Host, inet), - {ok, IPv6Addr} = inet:getaddr(Host, inet6), - Transports = - [{Domain, {IPv4Addr, AgentPort}}, - {transportDomainUdpIpv6, {IPv6Addr, AgentPort}}], - Targets = - [{Domain, {IPv4Addr, ManagerPort}}, - {transportDomainUdpIpv6, {IPv6Addr, ManagerPort}}], - Versions = [v2], - agent_config(Dir, Transports, Targets, Versions), - [{port, ?AGENT_PORT}, {snmp_versions, Versions}, - {trapaddrs, [IPv4Addr, IPv6Addr]} - | NewConfig]; + init_per_group_ip([inet, inet6], NewConfig); _ -> {skip, "Host does not support IPV6"} end; @@ -153,6 +112,29 @@ init_per_group(inform, Config) -> init_per_group(_, Config) -> Config. +init_per_group_ip(Families, Config) -> + Dir = ?config(priv_dir, Config), + AgentPort = ?config(agent_port, Config), + ManagerPort = ?config(manager_port, Config), + Versions = [v2], + {ok, Host} = inet:gethostname(), + Transports = + [begin + {ok, Addr} = inet:getaddr(Host, Family), + {domain(Family), {Addr, AgentPort}} + end || Family <- Families], + Targets = + [begin + {ok, Addr} = inet:getaddr(Host, Family), + {domain(Family), {Addr, ManagerPort}} + end || Family <- Families], + agent_config(Dir, Transports, Targets, Versions), + [{port, ?AGENT_PORT}, {snmp_versions, Versions}, + {transports, Transports}, {targets, Targets} + | Config]. + + + end_per_group(_GroupName, Config) -> Config. @@ -219,69 +201,23 @@ erlang_agent_netsnmp_get() -> "from snmpnet manager"}]. erlang_agent_netsnmp_get(Config) when is_list(Config) -> + Transports = ?config(transports, Config), start_agent(Config), Oid = ?sysDescr_instance, Expected = expected(Oid, get), - Expected = snmpget(Oid, Config), - ok. - -%%-------------------------------------------------------------------- -erlang_agent_dual_ip_get() -> - [{doc,"Test that we can access erlang snmp agent from both " - "snmpnet ipv4 and snmpnet ipv6 manager at the same time"}]. -erlang_agent_dual_ip_get(Config) when is_list(Config) -> - start_agent(Config), - Oid = ?sysDescr_instance, - Expected = expected(Oid, get), - Expected = snmpget(Oid, [{ip_version, ipv4} | Config]), - Expected = snmpget(Oid, [{ip_version, ipv6} | Config]), + [Expected = snmpget(Oid, Transport, Config) + || Transport <- Transports], ok. %%-------------------------------------------------------------------- erlang_agent_netsnmp_inform(Config) when is_list(Config) -> - [TrapAddr | _] = ?config(trapaddrs, Config), - DataDir = ?config(data_dir, Config), - Mib = "TestTrapv2", - - start_agent(Config), - ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), - - TrapAddrStr = net_snmp_addr_str(TrapAddr, ?config(manager_port, Config)), - ProgHandle = start_snmptrapd(Mib, TrapAddrStr, Config), - - snmpa:send_notification( - snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), - - receive - {snmp_targets, erlang_agent_test, Addresses} -> - ct:pal("Notification sent to: ~p~n", [Addresses]) - end, - receive - {snmp_notification, erlang_agent_test, {got_response, Address}} -> - ct:pal("Got response from: ~p~n", [Address]), - ok; - {snmp_notification, erlang_agent_test, {no_response, _} = - NoResponse} -> - ct:fail(NoResponse) - end, - - stop_program(ProgHandle). - -%%-------------------------------------------------------------------- -erlang_agent_dual_ip_inform(Config) when is_list(Config) -> - [TrapAddr1, TrapAddr2 | _] = ?config(trapaddrs, Config), - ManagerPort = ?config(manager_port, Config), DataDir = ?config(data_dir, Config), Mib = "TestTrapv2", start_agent(Config), ok = snmpa:load_mib(snmp_master_agent, filename:join(DataDir, Mib)), - TrapAddrs = - net_snmp_addr_str(TrapAddr1, ManagerPort) ++ - "," ++ - net_snmp_addr_str(TrapAddr2, ManagerPort), - ProgHandle = start_snmptrapd(Mib, TrapAddrs, Config), + ProgHandle = start_snmptrapd(Mib, Config), snmpa:send_notification( snmp_master_agent, testTrapv22, {erlang_agent_test, self()}), @@ -289,24 +225,24 @@ erlang_agent_dual_ip_inform(Config) when is_list(Config) -> receive {snmp_targets, erlang_agent_test, Addresses} -> ct:pal("Notification sent to: ~p~n", [Addresses]), - erlang_agent_dual_ip_inform_responses(Addresses) + erlang_agent_netsnmp_inform_responses(Addresses) end, stop_program(ProgHandle). -erlang_agent_dual_ip_inform_responses([]) -> +erlang_agent_netsnmp_inform_responses([]) -> receive {snmp_notification, erlang_agent_test, _} = Unexpected -> ct:pal("Unexpected response: ~p", [Unexpected]), - erlang_agent_dual_ip_inform_responses([]) + erlang_agent_netsnmp_inform_responses([]) after 0 -> ok end; -erlang_agent_dual_ip_inform_responses([Address | Addresses]) -> +erlang_agent_netsnmp_inform_responses([Address | Addresses]) -> receive {snmp_notification, erlang_agent_test, {got_response, Address}} -> ct:pal("Got response from: ~p~n", [Address]), - erlang_agent_dual_ip_inform_responses(Addresses); + erlang_agent_netsnmp_inform_responses(Addresses); {snmp_notification, erlang_agent_test, {no_response, _} = NoResponse} -> ct:fail(NoResponse) @@ -315,31 +251,30 @@ erlang_agent_dual_ip_inform_responses([Address | Addresses]) -> %%-------------------------------------------------------------------- %% Internal functions ------------------------------------------------ %%-------------------------------------------------------------------- -snmpget(Oid, Config) -> +snmpget(Oid, Transport, Config) -> Versions = ?config(snmp_versions, Config), - [TrapAddr | _] = ?config(trapaddrs, Config), - Port = ?config(agent_port, Config), Args = ["-c", "public", net_snmp_version(Versions), "-m", "", "-Cf", - net_snmp_addr_str(TrapAddr, Port), + net_snmp_addr_str(Transport), oid_str(Oid)], ProgHandle = start_program(snmpget, Args, none, Config), {_, line, Line} = get_program_output(ProgHandle), stop_program(ProgHandle), Line. -start_snmptrapd(Mibs, TrapAddrs, Config) -> +start_snmptrapd(Mibs, Config) -> DataDir = ?config(data_dir, Config), MibDir = filename:join(code:lib_dir(snmp), "mibs"), + Targets = ?config(targets, Config), SnmptrapdArgs = ["-f", "-Lo", "-C", "-m", Mibs, "-M", MibDir++":"++DataDir, "--disableAuthorization=yes", - "--snmpTrapdAddr="++TrapAddrs], + "--snmpTrapdAddr=" ++ net_snmp_addr_str(Targets)], {ok, StartCheckMP} = re:compile("NET-SNMP version ", [anchored]), start_program(snmptrapd, SnmptrapdArgs, StartCheckMP, Config). @@ -486,11 +421,24 @@ net_snmp_version([v2 | _]) -> net_snmp_version([v1 | _]) -> "-v1". -net_snmp_addr_str(IPv4Addr, Port) when tuple_size(IPv4Addr) =:= 4 -> +domain(inet) -> + transportDomainUdpIpv4; +domain(inet6) -> + transportDomainUdpIpv6. + +net_snmp_addr_str([Target | Targets]) -> + net_snmp_addr_str(Target) ++ + case Targets of + [] -> + []; + [_ | _] -> + "," ++ net_snmp_addr_str(Targets) + end; +net_snmp_addr_str({transportDomainUdpIpv4, {Addr, Port}}) -> "udp:" ++ - inet_parse:ntoa(IPv4Addr) ++ ":" ++ + inet_parse:ntoa(Addr) ++ ":" ++ integer_to_list(Port); -net_snmp_addr_str(IPv6Addr, Port) when tuple_size(IPv6Addr) =:= 8 -> +net_snmp_addr_str({transportDomainUdpIpv6, {Addr, Port}}) -> "udp6:[" ++ - inet_parse:ntoa(IPv6Addr) ++ "]:" ++ + inet_parse:ntoa(Addr) ++ "]:" ++ integer_to_list(Port). -- cgit v1.2.3 From 010bbdacbab4d4bfff7a7c59968aa333f081e7c5 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Wed, 30 Jul 2014 10:10:38 +0200 Subject: Rearrange test suite group structure --- lib/snmp/test/snmp_to_snmpnet_SUITE.erl | 83 ++++++++++++++------------------- 1 file changed, 36 insertions(+), 47 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index 69d54570ea..6e9c57bce9 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -50,7 +50,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [ {group, ipv4}, - {group, ipv6} + {group, ipv6}, + {group, ipv4_ipv6} ]. groups() -> @@ -60,16 +61,17 @@ groups() -> ]}, {ipv6, [], [{group, get}, - {group, inform}, - {group, dual_ip} + {group, inform} + ]}, + {ipv4_ipv6, [], + [{group, get}, + {group, inform} ]}, + %% {get, [], [erlang_agent_netsnmp_get]}, {inform, [], - [erlang_agent_netsnmp_inform]}, - {dual_ip, [], - [erlang_agent_netsnmp_get, - erlang_agent_netsnmp_inform]} + [erlang_agent_netsnmp_inform]} ]. init_per_suite(Config) -> @@ -78,40 +80,31 @@ init_per_suite(Config) -> end_per_suite(_Config) -> ok. -init_per_group(ipv6, Config) -> - case ct:require(ipv6_hosts) of - ok -> - init_per_group_ip([inet6], Config); - _ -> - {skip, "Host does not support IPV6"} - end; -%% init_per_group(ipv4, Config) -> init_per_group_ip([inet], Config); -%% -init_per_group(dual_ip, Config) -> - case find_executables([snmpget, snmptrapd], Config) of - NewConfig when is_list(NewConfig) -> - case ct:require(ipv6_hosts) of - ok -> - init_per_group_ip([inet, inet6], NewConfig); - _ -> - {skip, "Host does not support IPV6"} - end; - Other -> - Other - end; +init_per_group(ipv6, Config) -> + init_per_group_ipv6([inet6], Config); +init_per_group(ipv4_ipv6, Config) -> + init_per_group_ipv6([inet, inet6], Config); %% init_per_group(get, Config) -> %% From Ubuntu package snmp - find_executables([snmpget], Config); -%% + find_executable(snmpget, Config); init_per_group(inform, Config) -> - %% From Ubuntu package snmptrapfmt - find_executables([snmptrapd], Config); + %% From Ubuntu package snmpd + find_executable(snmptrapd, Config); +%% init_per_group(_, Config) -> Config. +init_per_group_ipv6(Families, Config) -> + case ct:require(ipv6_hosts) of + ok -> + init_per_group_ip(Families, Config); + _ -> + {skip, "Host does not support IPV6"} + end. + init_per_group_ip(Families, Config) -> Dir = ?config(priv_dir, Config), AgentPort = ?config(agent_port, Config), @@ -159,33 +152,29 @@ end_per_testcase(_, Config) -> end, Config. -find_executables([], Config) -> - Config; -find_executables([Exec | Execs], Config) -> +find_executable(Exec, Config) -> ExecStr = atom_to_list(Exec), case os:find_executable(ExecStr) of false -> - find_sys_executables( - Execs, Config, Exec, ExecStr, + %% The sbin dirs are not in the PATH on all platforms... + find_sys_executable( + Exec, ExecStr, [["usr", "local", "sbin"], ["usr", "sbin"], - ["sbin"]]); + ["sbin"]], + Config); Path -> - find_executables( - Execs, - [{Exec, Path} | Config]) + [{Exec, Path} | Config] end. -find_sys_executables(_Execs, _Config, _Exec, ExecStr, []) -> +find_sys_executable(_Exec, ExecStr, [], _Config) -> {skip, ExecStr ++ " not found"}; -find_sys_executables(Execs, Config, Exec, ExecStr, [Dir | Dirs]) -> +find_sys_executable(Exec, ExecStr, [Dir | Dirs], Config) -> case os:find_executable(filename:join(["/" | Dir] ++ [ExecStr])) of false -> - find_sys_executables(Execs, Config, Exec, ExecStr, Dirs); + find_sys_executable(Exec, ExecStr, Dirs, Config); Path -> - find_executables( - Execs, - [{Exec, Path} | Config]) + [{Exec, Path} | Config] end. start_agent(Config) -> -- cgit v1.2.3 From 3cdb20acd5577fd37a10ac96f6ab37dd0952413f Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 5 Aug 2014 15:07:03 +0200 Subject: Fix misspelled community in manager --- lib/snmp/src/manager/snmpm_config.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index 5ebd3a0662..013fefa4e2 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -1655,7 +1655,7 @@ init_agent_default() -> {sec_model, v2c}, % SecModel {sec_name, "initial"}, % SecName {sec_level, noAuthPriv}, % SecLevel - {community, "all-rigthts"}], % Community + {community, "all-rights"}], % Community do_update_agent_info(default_agent, AgentDefaultConfig). %% %% Port -- cgit v1.2.3 From 948705328504ca78bce684ded56ce47d35a0068f Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Tue, 5 Aug 2014 15:08:12 +0200 Subject: Improve ct_snmp test cases --- lib/snmp/src/agent/snmp_community_mib.erl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index 12a0ec97c2..4546c343b7 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -246,6 +246,10 @@ gc_tabs() -> %%----------------------------------------------------------------- community2vacm(Community, Addr) -> Idxs = ets:lookup(snmp_community_cache, Community), + ?vtrace("community2vacm ->~n" + " Community: ~p~n" + " Addr: ~p~n" + " Idxs: ~p", [Community, Addr, Idxs]), loop_c2v_rows(lists:keysort(2, Idxs), Addr). loop_c2v_rows([{_, CommunityIndex} | T], Addr) -> @@ -253,6 +257,9 @@ loop_c2v_rows([{_, CommunityIndex} | T], Addr) -> "~n CommunityIndex: ~p", [CommunityIndex]), case get_row(CommunityIndex) of {_Community, VacmParams, Tag} -> + ?vtrace("loop_c2v_rows ->~n" + " VacmParams: ~p~n" + " Tag: ~p", [VacmParams, Tag]), {TDomain, TAddr} = Addr, case snmp_target_mib:is_valid_tag(Tag, TDomain, TAddr) of true -> -- cgit v1.2.3 From e910f8568a4d19093f7ea8c6865367c3e73703f0 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Thu, 7 Aug 2014 17:31:10 +0200 Subject: Fix error printouts to not crash --- lib/snmp/src/agent/snmp_framework_mib.erl | 6 ++++-- lib/snmp/src/agent/snmpa_net_if.erl | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'lib/snmp') diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 922215ff00..9d3f7ef5e7 100644 --- a/lib/snmp/src/agent/snmp_framework_mib.erl +++ b/lib/snmp/src/agent/snmp_framework_mib.erl @@ -201,9 +201,11 @@ check_agent({intAgentIpAddress, _}, {_, undefined}) -> check_agent({intAgentIpAddress = Tag, Ip} = Entry, {Domain, Port} = State) -> {case snmp_conf:check_ip(Domain, Ip) of ok -> - [Entry, {intAgentTransports, [{Domain, {Ip, Port}}]}]; + [Entry, + {intAgentTransports, [{Domain, {Ip, Port}}]}]; {ok, FixedIp} -> - [{Tag, Ip}, {intAgentTransports, [{Domain, {FixedIp, Port}}]}] + [{Tag, FixedIp}, + {intAgentTransports, [{Domain, {FixedIp, Port}}]}] end, State}; check_agent({intAgentTransports = Tag, Transports}, {_, Port} = State) -> CheckedTransports = diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 389c26834d..840d56d563 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -1064,7 +1064,7 @@ do_handle_send_pdu1( "Can not find transport~n" " size: ~p~n" " to: ~s", - [sz(Packet), To]); + [sz(Packet), format_address(To)]); Transport -> maybe_udp_send(S, Transport, To, Packet) end; @@ -1080,7 +1080,7 @@ do_handle_send_pdu1( "Can not find transport~n" " size: ~p~n" " to: ~s", - [sz(Packet), To]); + [sz(Packet), format_address(To)]); Transport -> maybe_udp_send(S, Transport, To, Packet, Type, LogData) end -- cgit v1.2.3 From 3e871d69871fd30b4a3f97766bdaf6ea6b3cc092 Mon Sep 17 00:00:00 2001 From: Erlang/OTP Date: Thu, 7 Aug 2014 17:36:36 +0200 Subject: Update release notes --- lib/snmp/doc/src/notes.xml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'lib/snmp') diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 06674095f2..15efd47a1c 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -33,7 +33,29 @@ -
SNMP 4.25.1 +
SNMP 5.0 + +
Improvements and New Features + + +

+ SNMP has been improved to handle IPv6. The agent can + handle dual stack IPv4 + IPv6, but not yet the manager. + The documentation also still lags behind... If you do + such advanced stuff like writing a custom net_if module, + the interface for it has changed, but other than that + SNMP is backwards compatible.

+

+ *** POTENTIAL INCOMPATIBILITY ***

+

+ Own Id: OTP-12020 Aux Id: OTP-11518

+
+
+
+ +
+ +
SNMP 4.25.1
Fixed Bugs and Malfunctions -- cgit v1.2.3