diff options
Diffstat (limited to 'lib/snmp')
25 files changed, 350 insertions, 158 deletions
diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile index 879f1b05c5..df321fc2d1 100644 --- a/lib/snmp/Makefile +++ b/lib/snmp/Makefile @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2016. All Rights Reserved. +# Copyright Ericsson AB 1996-2019. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -136,11 +136,17 @@ dclean: dialyzer_plt: $(DIA_PLT) -$(DIA_PLT): +$(DIA_PLT): Makefile @echo "Building $(APPLICATION) plt file" @dialyzer --build_plt \ --output_plt $@ \ -r ../$(APPLICATION)/ebin \ + ../../lib/kernel/ebin \ + ../../lib/stdlib/ebin \ + ../../lib/runtime_tools/ebin \ + ../../lib/crypto/ebin \ + ../../lib/mnesia/ebin \ + ../../erts/preloaded/ebin \ --output $(DIA_ANALYSIS) \ --verbose @@ -148,4 +154,4 @@ dialyzer: $(DIA_PLT) @echo "Running dialyzer on $(APPLICATION)" @dialyzer --plt $< \ ../$(APPLICATION)/ebin \ - --verbose
\ No newline at end of file + --verbose diff --git a/lib/snmp/doc/src/snmpa_mib_storage.xml b/lib/snmp/doc/src/snmpa_mib_storage.xml index ee2b009e77..6db2f178a9 100644 --- a/lib/snmp/doc/src/snmpa_mib_storage.xml +++ b/lib/snmp/doc/src/snmpa_mib_storage.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2013</year><year>2016</year> + <year>2013</year><year>2019</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -193,7 +193,7 @@ </func> <func> - <name since="OTP R16B01">Module:match_object(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name> + <name since="OTP R16B01">Module:match_object(TabId, Pattern) -> Recs | {error, Reason}</name> <fsummary>Search the mib-storage table for record matching pattern</fsummary> <type> <v>TabId = term()</v> @@ -210,7 +210,7 @@ </func> <func> - <name since="OTP R16B01">Module:match_delete(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name> + <name since="OTP R16B01">Module:match_delete(TabId, Pattern) -> Recs | {error, Reason}</name> <fsummary>Delete records in the mib-storage table matching pattern</fsummary> <type> <v>TabId = term()</v> diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index 984b0bcee1..4bd30632f5 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -545,26 +545,18 @@ snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) -> end. - get_snmpTargetAddrTDomain(RowIndex, Col) -> - case - get( - snmpTargetAddrTable, RowIndex, - [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain]) - of - [{value,?snmpTargetAddrRowStatus_active},ValueTDomain] -> - case ValueTDomain of - {value,TDomain} -> - TDomain; - _ -> - ?snmpUDPDomain - end; - _ -> + Cols = [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain], + case snmp_target_mib:snmpTargetAddrTable(get, RowIndex, Cols) of + [{value, ?snmpTargetAddrRowStatus_active}, {value, TDomain}] -> + TDomain; + [{value, ?snmpTargetAddrRowStatus_active}, _] -> + ?snmpUDPDomain; + _ -> wrongValue(Col) end. - verify_snmpTargetAddrExtTable_cols([], _TDomain, Cols) -> {ok, lists:reverse(Cols)}; verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], TDomain, Acc) -> diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl index 7ea4f0ed97..6db6f87a85 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-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -246,6 +246,7 @@ check_agent(X) -> %% Ordering function to sort intAgentTransportDomain first %% hence before intAgentIpAddress. Sort other entries on the key. +-dialyzer({nowarn_function, order_agent/2}). order_agent(EntryA, EntryB) -> snmp_conf:keyorder( 1, EntryA, EntryB, 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 56b5d96142..a5a65d9326 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -654,7 +654,7 @@ vacmAccessTable(is_set_ok, RowIndex, Cols0) -> {{Col, ?'RowStatus_createAndWait'}, _} -> %% Row already exists => inconsistentValue {inconsistentValue, Col}; - {value, {_Col, ?'RowStatus_destroy'}} -> + {{_Col, ?'RowStatus_destroy'}, _} -> %% always ok! {noError, 0}; {_, false} -> @@ -1115,9 +1115,7 @@ externalize_next(Name, Result) when is_list(Result) -> F = fun({[Col | _] = Idx, Val}) -> {Idx, externalize(Name, Col, Val)}; (Other) -> Other end, - [F(R) || R <- Result]; -externalize_next(_, Result) -> - Result. + [F(R) || R <- Result]. externalize_get(Name, Cols, Result) when is_list(Result) -> @@ -1127,9 +1125,7 @@ externalize_get(Name, Cols, Result) when is_list(Result) -> end, %% Merge column numbers and return values. there must be as much %% return values as there are columns requested. And then patch all values - [F(R) || R <- lists:zip(Cols, Result)]; -externalize_get(_, _, Result) -> - Result. + [F(R) || R <- lists:zip(Cols, Result)]. externalize(vacmViewTreeFamilyTable, ?vacmViewTreeFamilyMask, Val) -> imask2emask(Val); diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index f280260f47..7489f74223 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -525,9 +525,25 @@ unregister_subagent(Agent, SubagentOidOrPid) -> %% These subagent_ functions either return a value, or exits %% with {nodedown, Node} | Reason. %%----------------------------------------------------------------- -subagent_get(SubAgent, Varbinds, IsNotification) -> + +%% A proper spec for this would be something like this: +%% But, there is now way to spec that a process *can* exit. +%% -spec subagent_get(Agent, VBs, IsNotification) -> +%% {noError, 0, NewVBs} | +%% {ErrStatus, ErrIndex, []} | +%% erlang:exit(Reason) when +%% Agent :: pid(), +%% VBs :: [snmp:varbind()], +%% IsNotification :: boolean(), +%% NewVBs :: [snmp:varbind()], +%% ErrStatus :: snmp:error_status(), +%% ErrIndex :: snmp:error_index(), +%% Reason :: {nodedown, Node} | term(), +%% Node :: atom(). + +subagent_get(SubAgent, VBs, IsNotification) -> PduData = get_pdu_data(), - call(SubAgent, {subagent_get, Varbinds, PduData, IsNotification}). + call(SubAgent, {subagent_get, VBs, PduData, IsNotification}). subagent_get_next(SubAgent, MibView, Varbinds) -> PduData = get_pdu_data(), diff --git a/lib/snmp/src/agent/snmpa_authentication_service.erl b/lib/snmp/src/agent/snmpa_authentication_service.erl index e4238a8384..b6b9f5bd96 100644 --- a/lib/snmp/src/agent/snmpa_authentication_service.erl +++ b/lib/snmp/src/agent/snmpa_authentication_service.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,13 +19,27 @@ %% -module(snmpa_authentication_service). --export([behaviour_info/1]). - -behaviour_info(callbacks) -> - [{init_check_access, 2}]; -behaviour_info(_) -> - undefined. - +-export_type([ + acm_data/0 + ]). + +-type acm_data() :: {community, + SecModel :: 0 | 1 | 2 | 3, % any | v1 | v2c | v3 + Community :: string(), + %% Oids for either: + %% transportDomainUdpIpv4 | transportDomainUdpIpv6 + TDomain :: snmp:oid(), + TAddress :: [non_neg_integer()]} | + {v3, + MsgID :: integer(), + SecModel :: 0 | 1 | 2 | 3, % any | v1 | v2c | v3 + SecName :: string(), + %% noAuthNoPriv | authNoPriv | authPriv + SecLevel :: 1 | 2 | 3, + ContextEngineID :: string(), + ContextName :: string(), + SecData :: term()}. + %%----------------------------------------------------------------- %% init_check_access(Pdu, ACMData) @@ -46,9 +60,7 @@ behaviour_info(_) -> %% Variable = snmpInBadCommunityNames | %% snmpInBadCommunityUses | %% snmpInASNParseErrs -%% Reason = snmp_message_decoding | -%% {bad_community_name, Address, Community}} | -%% {invalid_access, Access, Op} +%% Reason = {bad_community_name, Address, Community}} %% %% Purpose: Called once for each Pdu. Returns a MibView %% which is later used for each variable in the pdu. @@ -57,3 +69,14 @@ behaviour_info(_) -> %% %% NOTE: This function is executed in the Master agents's context %%----------------------------------------------------------------- + +-callback init_check_access(Pdu, ACMData) -> + {ok, MibView, ContextName} | + {error, Reason} | + {discarded, Variable, Reason} when + Pdu :: snmp:pdu(), + ACMData :: acm_data(), + MibView :: snmp_view_based_acm_mib:mibview(), + ContextName :: string(), + Reason :: term(), + Variable :: snmpInBadCommunityNames. diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index fc5116dac9..c2e9d4025a 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-2016. All Rights Reserved. +%% Copyright Ericsson AB 2006-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -83,6 +83,34 @@ +-export_type([ + usm_entry/0 + ]). + +-type usm_entry() :: { + EngineID :: string(), + UserName :: string(), + SecName :: string(), + Clone :: zeroDotZero | [non_neg_integer()], + AuthP :: usmNoAuthProtocol | + usmHMACMD5AuthProtocol | + usmHMACSHAAuthProtocol, + AuthKeyC :: string(), + OwnAuthKeyC :: string(), + PrivP :: usmNoPrivProtocol | + usmDESPrivProtocol | + usmAesCfb128Protocol, + PrivKeyC :: string(), + OwnPrivKeyC :: string(), + Public :: string(), + %% Size 16 for usmHMACMD5AuthProtocol + %% Size 20 for usmHMACSHAAuthProtocol + AuthKey :: [non_neg_integer()], + %% Size 16 for usmDESPrivProtocol | usmAesCfb128Protocol + PrivKey :: [non_neg_integer()] + }. + + %% %% ------ agent.conf ------ %% diff --git a/lib/snmp/src/agent/snmpa_discovery_handler.erl b/lib/snmp/src/agent/snmpa_discovery_handler.erl index ffdd6aca1e..6fb1d1eb72 100644 --- a/lib/snmp/src/agent/snmpa_discovery_handler.erl +++ b/lib/snmp/src/agent/snmpa_discovery_handler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009-2016. All Rights Reserved. +%% Copyright Ericsson AB 2009-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,12 +19,17 @@ %% -module(snmpa_discovery_handler). --export([behaviour_info/1, verify/1]). - -behaviour_info(callbacks) -> - [{stage1_finish, 3}]; -behaviour_info(_) -> - undefined. +-export([verify/1]). +-callback stage1_finish(TargetName, ManagerEngineID, ExtraInfo) -> + ignore | + {ok, snmpa_conf:usm_entry() | [snmpa_conf:usm_entry()]} | + {ok, snmpa_conf:usm_entry() | [snmpa_conf:usm_entry()], NewExtraInfo} when + TargetName :: string(), + ManagerEngineID :: string(), + ExtraInfo :: term(), + NewExtraInfo :: term(). + verify(Mod) -> snmp_misc:verify_behaviour(?MODULE, Mod). + diff --git a/lib/snmp/src/agent/snmpa_error_report.erl b/lib/snmp/src/agent/snmpa_error_report.erl index 8f28eac653..6b281693e5 100644 --- a/lib/snmp/src/agent/snmpa_error_report.erl +++ b/lib/snmp/src/agent/snmpa_error_report.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,10 +19,12 @@ %% -module(snmpa_error_report). --export([behaviour_info/1]). +-callback config_err(Format, Args) -> + snmp:void() when + Format :: string(), + Args :: [term()]. -behaviour_info(callbacks) -> - [{user_err, 2}, - {config_err, 2}]; -behaviour_info(_) -> - undefined. +-callback user_err(Format, Args) -> + snmp:void() when + Format :: string(), + Args :: [term()]. diff --git a/lib/snmp/src/agent/snmpa_get.erl b/lib/snmp/src/agent/snmpa_get.erl index e67975a67d..8b16016d84 100644 --- a/lib/snmp/src/agent/snmpa_get.erl +++ b/lib/snmp/src/agent/snmpa_get.erl @@ -75,6 +75,9 @@ %% {ErrorStatus, ErrorIndex, []} %%----------------------------------------------------------------- +%% There is now to properly spec the behaviour of the ?AGENT:subagent_get/3 +%% function (it *can* exit). +-dialyzer({nowarn_function, do_get/3}). do_get(UnsortedVarbinds, IsNotification, _Extra) -> {MyVarbinds, SubagentVarbinds} = ?LIB:agent_sort_vbs(UnsortedVarbinds), case do_get_local(MyVarbinds, IsNotification) of @@ -122,6 +125,7 @@ do_get(MibView, UnsortedVarbinds, IsNotification, Extra) -> do_get_local(VBs, IsNotification) -> do_get_local(VBs, [], IsNotification). +-dialyzer({nowarn_function, do_get_local/3}). do_get_local([Vb | Vbs], Res, IsNotification) -> case try_get(Vb, IsNotification) of NewVb when is_record(NewVb, varbind) -> @@ -144,11 +148,16 @@ do_get_local([], Res, _IsNotification) -> %% Returns: {noError, 0, ListOfNewVarbinds} | %% {ErrorStatus, ErrorIndex, []} %%----------------------------------------------------------------- + +%% There is now to properly spec the behaviour of the ?AGENT:subagent_get/3 +%% function (it *can* exit). +-dialyzer({nowarn_function, do_get_subagents/3}). do_get_subagents(SubagentVarbinds, IsNotification) -> do_get_subagents(SubagentVarbinds, [], IsNotification). + do_get_subagents([{SubAgentPid, SAVbs} | Tail], Res, IsNotification) -> {_SAOids, Vbs} = ?LIB:sa_split(SAVbs), - case catch ?AGENT:subagent_get(SubAgentPid, Vbs, IsNotification) of + case (catch ?AGENT:subagent_get(SubAgentPid, Vbs, IsNotification)) of {noError, 0, NewVbs} -> do_get_subagents(Tail, lists:append(NewVbs, Res), IsNotification); {ErrorStatus, ErrorIndex, _} -> @@ -168,6 +177,8 @@ do_get_subagents([], Res, _IsNotification) -> %% #varbind | %% List of #varbind %%----------------------------------------------------------------- + +-dialyzer({nowarn_function, try_get/2}). try_get(IVb, IsNotification) when is_record(IVb, ivarbind) -> ?vtrace("try_get(ivarbind) -> entry with" "~n IVb: ~p", [IVb]), @@ -186,9 +197,12 @@ try_get({TableOid, TableVbs}, IsNotification) -> NVbs ++ NoAccessVbs end. + %%----------------------------------------------------------------- %% Make sure all requested columns are accessible. %%----------------------------------------------------------------- + +-dialyzer({nowarn_function, check_all_table_vbs/4}). check_all_table_vbs([IVb| IVbs], IsNotification, NoA, A) -> #ivarbind{mibentry = Me, varbind = Vb} = IVb, case Me#me.access of @@ -210,6 +224,7 @@ check_all_table_vbs([], _IsNotification, NoA, A) -> {NoA, A}. %% Returns: {error, ErrorStatus, OrgIndex} | %% #varbind %%----------------------------------------------------------------- +-dialyzer({nowarn_function, get_var_value_from_ivb/2}). get_var_value_from_ivb(IVb, IsNotification) when IVb#ivarbind.status =:= noError -> ?vtrace("get_var_value_from_ivb(noError) -> entry", []), @@ -242,6 +257,7 @@ get_var_value_from_ivb(#ivarbind{status = Status, varbind = Vb}, _) -> %%----------------------------------------------------------------- %% Pre: Oid is a correct instance Oid (lookup checked that). %% Returns: A correct return value (see ?AGENT:make_value_a_correct_value) +-dialyzer({nowarn_function, get_var_value_from_mib/2}). get_var_value_from_mib(#me{entrytype = variable, asn1_type = ASN1Type, mfa = {Mod, Func, Args}}, @@ -280,6 +296,7 @@ get_var_value_from_mib(#me{entrytype = table_column, %% non-existing row). %% Returns: {error, ErrorStatus, OrgIndex} | %% {value, Type, Value} +-dialyzer({nowarn_function, get_tab_value_from_mib/3}). get_tab_value_from_mib(#me{mfa = {Mod, Func, Args}}, TableOid, TableVbs) -> ?vtrace("get_tab_value_from_mib -> entry when" "~n Mod: ~p" @@ -302,12 +319,14 @@ get_tab_value_from_mib(#me{mfa = {Mod, Func, Args}}, TableOid, TableVbs) -> %% #varbind. %% The Values list comes from validate_tab_res. %%----------------------------------------------------------------- +-dialyzer({nowarn_function, merge_varbinds_and_value/2}). merge_varbinds_and_value(IVbs, [{{value, Type, Value}, Index} | Values]) -> #ivarbind{varbind = Vb} = lists:nth(Index, IVbs), [Vb#varbind{variabletype = Type, value = Value} | merge_varbinds_and_value(IVbs, Values)]; merge_varbinds_and_value(_, []) -> []. +-dialyzer({nowarn_function, get_value_all_rows/5}). get_value_all_rows([{[], OrgCols} | Rows], Mod, Func, Args, Res) -> ?vtrace("get_value_all_rows -> entry when" "~n OrgCols: ~p", [OrgCols]), @@ -352,10 +371,13 @@ delete_index([]) -> []. %% the retrieved values to reconstruct the original column list, %% but with the retrieved value for each column. %%----------------------------------------------------------------- + +-dialyzer({nowarn_function, remove_duplicates/1}). remove_duplicates(Cols) -> remove_duplicates(Cols, [], []). +-dialyzer({nowarn_function, remove_duplicates/3}). remove_duplicates([{Col, V1, OrgIdx1}, {Col, V2, OrgIdx2} | T], NCols, Dup) -> remove_duplicates([{Col, V1, OrgIdx1} | T], NCols, [{Col, V2, OrgIdx2} | Dup]); @@ -364,6 +386,7 @@ remove_duplicates([Col | T], NCols, Dup) -> remove_duplicates([], NCols, Dup) -> {lists:reverse(NCols), lists:reverse(Dup)}. +-dialyzer({nowarn_function, restore_duplicates/2}). restore_duplicates([], Cols) -> [{Val, OrgIndex} || {_Col, Val, OrgIndex} <- Cols]; restore_duplicates([{Col, _Val2, OrgIndex2} | Dup], @@ -385,6 +408,7 @@ restore_duplicates(Dup, [{_Col, Val, OrgIndex} | T]) -> %% each element in Values and OrgCols correspond to each %% other. %%----------------------------------------------------------------- +-dialyzer({nowarn_function, validate_tab_res/3}). validate_tab_res(Values, OrgCols, Mfa) when is_list(Values) -> {_Col, _ASN1Type, OneIdx} = hd(OrgCols), validate_tab_res(Values, OrgCols, Mfa, [], OneIdx); @@ -407,6 +431,7 @@ validate_tab_res(Error, [{_Col, _ASN1Type, Index} | _OrgCols], Mfa) -> ?LIB:user_err("Invalid return value ~w from ~w (get)",[Error, Mfa]), {error, genErr, Index}. +-dialyzer({nowarn_function, validate_tab_res/5}). validate_tab_res([Value | Values], [{Col, ASN1Type, Index} | OrgCols], Mfa, Res, I) -> diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl index f481641242..c9093fcdb9 100644 --- a/lib/snmp/src/agent/snmpa_local_db.erl +++ b/lib/snmp/src/agent/snmpa_local_db.erl @@ -733,16 +733,16 @@ dets_backup(close, _Cont, _D, B) -> ok; dets_backup(read, Cont1, D, B) -> case dets:bchunk(D, Cont1) of + {error, _} = ERROR -> + ERROR; + '$end_of_table' -> + dets:close(B), + end_of_input; {Cont2, Data} -> F = fun(Arg) -> dets_backup(Arg, Cont2, D, B) end, - {Data, F}; - '$end_of_table' -> - dets:close(B), - end_of_input; - Error -> - Error + {Data, F} end. diff --git a/lib/snmp/src/agent/snmpa_mib_storage.erl b/lib/snmp/src/agent/snmpa_mib_storage.erl index ed0607fb84..d46dab0be0 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -120,7 +120,7 @@ -callback match_object(TabId :: mib_storage_table_id(), Pattern :: ets:match_pattern()) -> - {ok, Recs :: [tuple()]} | {error, Reason :: term()}. + Recs :: [tuple()] | {error, Reason :: term()}. %% --------------------------------------------------------------- @@ -133,7 +133,7 @@ -callback match_delete(TabId :: mib_storage_table_id(), Pattern :: ets:match_pattern()) -> - {ok, Recs :: [tuple()]} | {error, Reason :: term()}. + Recs :: [tuple()] | {error, Reason :: term()}. %% --------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl index 2459b6bc3e..0fcb8083f5 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_dets.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_dets.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -291,16 +291,16 @@ dets_backup(close, _Cont, _ID, B) -> ok; dets_backup(read, Cont1, ID, B) -> case dets:bchunk(ID, Cont1) of + {error, _} = ERROR -> + ERROR; + '$end_of_table' -> + dets:close(B), + end_of_input; {Cont2, Data} -> F = fun(Arg) -> dets_backup(Arg, Cont2, ID, B) end, - {Data, F}; - '$end_of_table' -> - dets:close(B), - end_of_input; - Error -> - Error + {Data, F} end. diff --git a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl index 68dfa83247..173dac276e 100644 --- a/lib/snmp/src/agent/snmpa_mib_storage_ets.erl +++ b/lib/snmp/src/agent/snmpa_mib_storage_ets.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2013-2016. All Rights Reserved. +%% Copyright Ericsson AB 2013-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -189,7 +189,8 @@ read(#tab{id = ID}, Key) -> write(#tab{id = ID, rec_name = RecName}, Rec) when (is_tuple(Rec) andalso (element(1, Rec) =:= RecName)) -> ?vtrace("write to table ~p", [ID]), - ets:insert(ID, Rec). + ets:insert(ID, Rec), + ok. %% --------------------------------------------------------------- @@ -213,7 +214,9 @@ delete(#tab{id = ID, file = File}) -> %% --------------------------------------------------------------- delete(#tab{id = ID}, Key) -> ?vtrace("delete from table ~p: ~p", [ID, Key]), - ets:delete(ID, Key). + ets:delete(ID, Key), + ok. + %% --------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_network_interface.erl b/lib/snmp/src/agent/snmpa_network_interface.erl index 699fbde671..24985c113e 100644 --- a/lib/snmp/src/agent/snmpa_network_interface.erl +++ b/lib/snmp/src/agent/snmpa_network_interface.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,28 +19,56 @@ %% -module(snmpa_network_interface). --export([behaviour_info/1]). - -behaviour_info(callbacks) -> - [{start_link, 4}, - {get_log_type, 1}, - {set_log_type, 2}, - {get_request_limit, 1}, - {set_request_limit, 2}, - {info, 1}, - {verbosity, 2}]; -behaviour_info(_) -> - undefined. - - -%% behaviour_info(callbacks) -> -%% [{start_link, 4}, -%% {send_pdu, 5}, -%% {send_response_pdu, 6}, -%% {discard_pdu, 6}, -%% {send_pdu_req, 6}, -%% {verbosity, 2}, -%% {change_log_type, 2}]; -%% behaviour_info(_) -> -%% undefined. +%% Note that this behaviour is not enough! +%% There is also a set of mandatory messages which the +%% network interface entity must be able to receive and +%% be able to send. See the documentation for more info. + +-callback start_link(Prio, NoteStore, MasterAgent, Opts) -> + {ok, Pid} | {error, Reason} when + Prio :: low | normal | high, % priority_level(), + NoteStore :: pid(), + MasterAgent :: pid(), + Opts :: [Option], + Option :: {verbosity, snmp:verbosity()} | + {versions, [snmp:version()]} | + term(), + Pid :: pid(), + Reason :: term(). + +-callback info(Pid) -> + Info when + Pid :: pid(), + Info :: [{Key, Value}], + Key :: term(), + Value :: term(). + +-callback verbosity(Pid, Verbosity) -> + snmp:void() when + Pid :: pid(), + Verbosity :: snmp:verbosity(). + +-callback get_log_type(Pid) -> + {ok, LogType} | {error, Reason} when + Pid :: pid(), + LogType :: snmp:atl_type(), + Reason :: term(). + +-callback set_log_type(Pid, NewType) -> + {ok, OldType} | {error, Reason} when + Pid :: pid(), + NewType :: snmp:atl_type(), + OldType :: snmp:atl_type(), + Reason :: term(). + +-callback get_request_limit(Pid) -> + {ok, Limit} when + Pid :: pid(), + Limit :: non_neg_integer() | infinity. + +-callback set_request_limit(Pid, NewLimit) -> + {ok, OldLimit} when + Pid :: pid(), + NewLimit :: non_neg_integer() | infinity, + OldLimit :: non_neg_integer() | infinity. diff --git a/lib/snmp/src/agent/snmpa_set_mechanism.erl b/lib/snmp/src/agent/snmpa_set_mechanism.erl index 2f24f38092..4eee7d7257 100644 --- a/lib/snmp/src/agent/snmpa_set_mechanism.erl +++ b/lib/snmp/src/agent/snmpa_set_mechanism.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -19,18 +19,26 @@ %% -module(snmpa_set_mechanism). --export([behaviour_info/1]). - -behaviour_info(callbacks) -> - [{do_set, 2}, {do_subagent_set, 1}]; -behaviour_info(_) -> - undefined. +%% -export([behaviour_info/1]). +%% behaviour_info(callbacks) -> +%% [{do_set, 2}, {do_subagent_set, 1}]; +%% behaviour_info(_) -> +%% undefined. + %%----------------------------------------------------------------- %% do_set(MibView, UnsortedVarbinds) %%----------------------------------------------------------------- +-callback do_set(MibView, UnsortedVBs) -> + {noError, 0} | {ErrStatus, ErrIndex} when + MibView :: snmp_view_based_acm_mib:mibview(), + UnsortedVBs :: [snmp:varbind()], + ErrStatus :: snmp:error_status(), + ErrIndex :: snmp:error_index(). + + %%----------------------------------------------------------------- %% do_subagent_set(Args) %% @@ -41,3 +49,18 @@ behaviour_info(_) -> %% [phase_two, set, UnsortedVarbinds] %% [phase_two, undo, UnsortedVarbinds] %%----------------------------------------------------------------- + +%% -callback do_subagent_set(Args) -> +%% {noError, 0} | {ErrStatus, ErrIndex} when +%% Args :: [phase_one, UnsortedVBs] | +%% [phase_two, set, UnsortedVBs] | +%% [phase_two, undo, UnsortedVBs], +%% ErrStatus :: snmp:error_status(), +%% ErrIndex :: snmp:error_index(), +%% UnsortedVBs :: [snmp:varbind()]. + +-callback do_subagent_set(Args) -> + {noError, 0} | {ErrStatus, ErrIndex} when + Args :: list(), + ErrStatus :: snmp:error_status(), + ErrIndex :: snmp:error_index(). diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index f741c3aaa9..119207c76b 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -1115,7 +1115,7 @@ transform_taddrs(TAddrs) -> %% v2 transform_taddr({?snmpUDPDomain, Addr}) -> - transform_taddr(transportDomainIdpIpv4, Addr); + transform_taddr(transportDomainUdpIpv4, Addr); transform_taddr({?transportDomainUdpIpv4, Addr}) -> transform_taddr(transportDomainUdpIpv4, Addr); transform_taddr({?transportDomainUdpIpv6, Addr}) -> diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl index 216452afdd..7598f936c9 100644 --- a/lib/snmp/src/app/snmp.erl +++ b/lib/snmp/src/app/snmp.erl @@ -95,6 +95,9 @@ dir/0, snmp_timer/0, + atl_type/0, + verbosity/0, + engine_id/0, tdomain/0, community/0, @@ -188,6 +191,9 @@ -type dir() :: string(). -type snmp_timer() :: #snmp_incr_timer{}. +-type atl_type() :: read | write | read_write. +-type verbosity() :: info | log | debug | trace | silence. + -type engine_id() :: string(). -type tdomain() :: transportDomainUdpIpv4 | transportDomainUdpIpv6. -type community() :: string(). @@ -711,13 +717,8 @@ sys_info() -> [{arch, SysArch}, {ver, SysVer}]. os_info() -> - V = os:version(), - case os:type() of - {OsFam, OsName} -> - [{fam, OsFam}, {name, OsName}, {ver, V}]; - OsFam -> - [{fam, OsFam}, {ver, V}] - end. + {OsFam, OsName} = os:type(), + [{fam, OsFam}, {name, OsName}, {ver, os:version()}]. ms1() -> App = ?APPLICATION, diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl index 0421f49c88..d097b40438 100644 --- a/lib/snmp/src/manager/snmpm_conf.erl +++ b/lib/snmp/src/manager/snmpm_conf.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2016. All Rights Reserved. +%% Copyright Ericsson AB 2006-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -356,6 +356,7 @@ read_config_file(Dir, File, Order, Check) -> %% ---- config file utility functions ---- +-dialyzer({nowarn_function, check_ok/1}). % Future compat check_ok(ok) -> ok; check_ok({ok, _}) -> diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index cd9fecd4d4..4653d9822d 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -2738,16 +2738,16 @@ dets_backup(close, _Cont, _D, B) -> ok; dets_backup(read, Cont1, D, B) -> case dets:bchunk(D, Cont1) of + {error, _} = ERROR -> + ERROR; + '$end_of_table' -> + dets:close(B), + end_of_input; {Cont2, Data} -> F = fun(Arg) -> dets_backup(Arg, Cont2, D, B) end, - {Data, F}; - '$end_of_table' -> - dets:close(B), - end_of_input; - Error -> - Error + {Data, F} end. diff --git a/lib/snmp/src/manager/snmpm_network_interface.erl b/lib/snmp/src/manager/snmpm_network_interface.erl index d0f6f709d3..7123bb94f0 100644 --- a/lib/snmp/src/manager/snmpm_network_interface.erl +++ b/lib/snmp/src/manager/snmpm_network_interface.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2016. All Rights Reserved. +%% Copyright Ericsson AB 2004-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -20,19 +20,61 @@ -module(snmpm_network_interface). --export([behaviour_info/1]). - -behaviour_info(callbacks) -> - [{start_link, 2}, - {stop, 1}, - {send_pdu, 7}, - {inform_response, 4}, - {note_store, 2}, - {info, 1}, - {verbosity, 2}, - %% {system_info_updated, 2}, - {get_log_type, 1}, - {set_log_type, 2}]; -behaviour_info(_) -> - undefined. +-callback start_link(Server, NoteStore) -> + {ok, Pid} | {error, Reason} when + Server :: pid(), + NoteStore :: pid(), + Pid :: pid(), + Reason :: term(). + +-callback stop(Pid) -> + snmp:void() when + Pid :: pid(). + +-callback send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo) -> + snmp:void() when + Pid :: pid(), + Pdu :: snmp:pdu(), + Vsn :: 'version-1' | 'version-2' | 'version-3', + MsgData :: term(), + Domain :: snmp:tdomain(), + Addr :: {inet:ip_address(), inet:port_number()}, + ExtraInfo :: term(). + +-callback inform_response(Pid, Ref, Addr, Port) -> + snmp:void() when + Pid :: pid(), + Ref :: term(), + Addr :: inet:ip_address(), + Port :: inet:port_number(). + +-callback note_store(Pid, NoteStore) -> + snmp:void() when + Pid :: pid(), + NoteStore :: pid(). + +-callback info(Pid) -> + Info when + Pid :: pid(), + Info :: [{Key, Value}], + Key :: term(), + Value :: term(). + +-callback verbosity(Pid, Verbosity) -> + snmp:void() when + Pid :: pid(), + Verbosity :: snmp:verbosity(). + +-callback get_log_type(Pid) -> + {ok, LogType} | {error, Reason} when + Pid :: pid(), + LogType :: snmp:atl_type(), + Reason :: term(). + +-callback set_log_type(Pid, NewType) -> + {ok, OldType} | {error, Reason} when + Pid :: pid(), + NewType :: snmp:atl_type(), + OldType :: snmp:atl_type(), + Reason :: term(). diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index d73291764d..20b7af0373 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -164,6 +164,14 @@ no_filter(X) -> X. %% An ordering function (A, B) shall return true iff %% A is less than or equal to B i.e shall return %% false iff A is to be ordered after B. + +-spec keyorder(N, A, B, Keys) -> + boolean() when + N :: integer(), + A :: tuple(), + B :: tuple(), + Keys :: maybe_improper_list(). + keyorder(N, A, B, _) when element(N, A) == element(N, B) -> true; keyorder(N, A, B, [Key | _]) diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 26e85897f4..3104f2a096 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -96,17 +96,15 @@ ]). --export_type([void/0, - order_config_entry_function/0, +-export_type([ + order_config_entry_function/0, check_config_entry_function/0, - write_config_function/0]). + write_config_function/0 + ]). %%---------------------------------------------------------------------- --type void() :: term(). % Any value - ignored - - %%---------------------------------------------------------------------- %% Handy SNMP configuration %%---------------------------------------------------------------------- @@ -1106,6 +1104,7 @@ verify_sec_type(ST) -> {error, "invalid security type: " ++ ST}. verify_address(A) -> verify_address(A, snmpUDPDomain). +-dialyzer({nowarn_function, verify_address/2}). % Future compat verify_address(A, snmpUDPDomain = _Domain) -> do_verify_address(A, inet); verify_address(A, transportDomainUdpIpv4 = _Domain) -> diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index 5713c14912..8a4dfa621b 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2018. All Rights Reserved. +%% Copyright Ericsson AB 1997-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -342,9 +342,9 @@ validate_loop({Cont, Terms, BadBytes}, Log, Validator, PrevTS, PrevSN) -> ?vtrace("validate_loop -> " "~n NextTS: ~p" "~n NextSN: ~p", [NextTS, NextSN]), - validate_loop(disk_log:chunk(Log, Cont), Log, Validator, NextTS, NextSN); -validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) -> - Error. + validate_loop(disk_log:chunk(Log, Cont), Log, Validator, NextTS, NextSN). +%% validate_loop(Error, _Log, _Write, _PrevTS, _PrevSN) -> +%% Error. %% -- log --- @@ -924,14 +924,7 @@ f(TimeStamp, SeqNo, end, format_tab( "~w ~s - ~s [~s]~s ~w\n~s", - [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]); -f(TimeStamp, SeqNo, Msg, AddrStr, _Mib) -> - io:format("<ERROR> Unexpected data: " - "~n TimeStamp: ~s~s" - "~n Msg: ~p" - "~n AddrStr: ~p" - "~n", [TimeStamp, SeqNo, Msg, AddrStr]), - throw({error, 'invalid-message'}). + [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]). f(F, A) -> lists:flatten(io_lib:format(F, A)). |