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 ++++-- 9 files changed, 347 insertions(+), 170 deletions(-) (limited to 'lib/snmp/src/agent') 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. -- 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 +++++++--------- 4 files changed, 25 insertions(+), 24 deletions(-) (limited to 'lib/snmp/src/agent') 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. -- 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 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'lib/snmp/src/agent') 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} -- 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 +++-- 4 files changed, 190 insertions(+), 209 deletions(-) (limited to 'lib/snmp/src/agent') 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. -- 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 +- 4 files changed, 197 insertions(+), 164 deletions(-) (limited to 'lib/snmp/src/agent') 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. %% -- 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 +++++++- 3 files changed, 72 insertions(+), 48 deletions(-) (limited to 'lib/snmp/src/agent') 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} -> -- 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 +++++--- 5 files changed, 316 insertions(+), 102 deletions(-) (limited to 'lib/snmp/src/agent') 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) -> -- 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 +++++++++++++++++------------------- 3 files changed, 148 insertions(+), 154 deletions(-) (limited to 'lib/snmp/src/agent') 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. -- 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 +++++- 3 files changed, 33 insertions(+), 5 deletions(-) (limited to 'lib/snmp/src/agent') 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, -- 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 +++++++++++++++++++++++++++++-------- 3 files changed, 115 insertions(+), 38 deletions(-) (limited to 'lib/snmp/src/agent') 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, -- 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 +++++++++++++++------------------- 2 files changed, 31 insertions(+), 34 deletions(-) (limited to 'lib/snmp/src/agent') 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) -> -- 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 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'lib/snmp/src/agent') 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]). -- 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 ++++++++++++------------------ 2 files changed, 178 insertions(+), 269 deletions(-) (limited to 'lib/snmp/src/agent') 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}). -- 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 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'lib/snmp/src/agent') 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. %%%----------------------------------------------------------------- -- 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 ++-- 5 files changed, 881 insertions(+), 475 deletions(-) (limited to 'lib/snmp/src/agent') 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; -- 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/src/agent') 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 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/src/agent') 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 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'lib/snmp/src/agent') 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}]; _ -> -- 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/src/agent') 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/src/agent') 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