snmpa_trap.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 809 行 · 第 1/3 页

ERL
809
字号
%% ``The contents of this file are subject to the Erlang Public License,%% Version 1.1, (the "License"); you may not use this file except in%% compliance with the License. You should have received a copy of the%% Erlang Public License along with this software. If not, it can be%% retrieved via the world wide web at http://www.erlang.org/.%% %% Software distributed under the License is distributed on an "AS IS"%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See%% the License for the specific language governing rights and limitations%% under the License.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id$%%-module(snmpa_trap).%%%-----------------------------------------------------------------%%% This module takes care of all trap handling.%%%-----------------------------------------------------------------%% External exports-export([construct_trap/2, try_initialise_vars/2, send_trap/6]).%% Internal exports-export([init_v2_inform/9, init_v3_inform/9]).-include("snmp_types.hrl").-include("SNMPv2-MIB.hrl").-include("SNMP-FRAMEWORK-MIB.hrl").-define(enterpriseSpecific, 6).-define(VMODULE,"TRAP").-include("snmp_verbosity.hrl").%%-----------------------------------------------------------------%% Trap mechanism%% ==============%% Distributed subagent (dSA) case%%   The MIB with the TRAP-TYPE macro is loaded in dSA.  This means%%   that dSA has info on all variables defined in the TRAP-TYPE,%%   even though some variables may be located in other SA:s (or%%   in the MA). Other variables that may be sent in the trap, %%   must be known by either the dSA, or some of its parent agents%%   (e.g. the master agent), if the variable should be referred%%   to by symbolic name. It is however possible to send other%%   variables as well, but then the entire OID must be provided.%%   The dSA locates the asn1 type, oid and value for as many%%   variables as possible. This information, together with the%%   variables for which the type, value or oid isn't known, is%%   sent to the dSA's parent. This agent performs the same%%   operation, and so on, until eventually the MA will receive the%%   info. The MA then fills in the gaps, and at this point all%%   oids and types must be known, otherwise an error is signalled,%%   and the opertaion is aborted. For the unknown values for some %%   oids, a get-operation is performed by the MA. This will%%   retreive the missing values.%%   At this point, all oid, types and values are known, so the MA%%   can distribute the traps according to the information in the%%   internal tables.%% %% Local subagent (lSA) case%%   This case is similar to the case above.%%%% Master agent (MA) case%%   This case is similar to the case above.%%%% NOTE: All trap forwarding between agents is made asynchronously.%%%% dSA: Distributed SA  (the #trap is loaded here)%% nSA: [many] SAs between dSA and MA%% MA:  Master Agent. (all trap info (destiniations is here))%% 1) application decides to send a trap.%% 2) dSA calls send_trap which initialises vars%% 3) dSA sends all to nSA%% 4) nSA tries to map symbolic names to oids and find the types%%    of all variableoids with a value (and no type).%% 5) nSA sends all to (n-1)SA%% 6) MA tries to initialise vars%% 7) MA makes a trappdu, and sends it to all destination.%%%% Problems with this implementation%% =================================%% It's ok to send {Oid, Value} but not just Oid. (it should be for%%   any Oid)%% It's ok to send {Name, Value} but not just Name. (it should be%%   for Names in the hierarchy)%% This approach might be too flexible; will people use it?%% *NOTE*%% Therefore, in this version we *do not* allow extra variables%% in traps.%% *YES* In _this_ version we do.%%-----------------------------------------------------------------%%-----------------------------------------------------------------%% Func: construct_trap/2%% Args: Trap is an atom%%       Varbinds is a list of {Variable, Value},%%         where Variable is an atom or an OID. |%%         {SymbolicTableCol, RowIndex, Value},%%         where RowIndex is the indexes for the row.%%         We don't check the RowIndex.%% Purpose: This is the initially-called function. It is called%%          by the agent that found out that a trap should be%%          sent.%%          Initialize as many variables as possible.%% Returns: {ok, TrapRecord, <list of Var>} | error%%          where Var is returned from initiate_vars.%% NOTE: Executed at the inital SA%%-----------------------------------------------------------------construct_trap(Trap, Varbinds) ->    ?vdebug("construct_trap -> entry with"	"~n   Trap: ~p", [Trap]),    case snmpa_symbolic_store:get_notification(Trap) of	undefined -> 	    user_err("send_trap got undef Trap: ~w" , [Trap]),	    error;	{value, TRec} when record(TRec, trap) ->	    ?vtrace("construct_trap -> TRec: ~n~p", [TRec]),	    ListOfVars = TRec#trap.oidobjects,	    OidVbs = [alias_to_oid(Vb) || Vb <- Varbinds],	    LV = initiate_vars(ListOfVars, OidVbs),	    InitiatedVars = try_initialise_vars(get(mibserver), LV),	    {ok, TRec, InitiatedVars};	{value, NRec} when record(NRec, notification) ->	    ?vtrace("construct_trap -> NRec: ~n~p", [NRec]),	    ListOfVars = NRec#notification.oidobjects,	    OidVbs = [alias_to_oid(Vb) || Vb <- Varbinds],	    LV = initiate_vars(ListOfVars, OidVbs),	    {ok, NRec, try_initialise_vars(get(mibserver), LV)}    end.alias_to_oid({Alias, Val}) when atom(Alias) ->    case snmpa_symbolic_store:aliasname_to_oid(Alias) of	{value, Oid} -> {lists:append(Oid, [0]), {value, Val}};	_ ->   	     {Alias, {value, Val}}    end;alias_to_oid({Alias, RowIndex, Val}) when atom(Alias) ->    case snmpa_symbolic_store:aliasname_to_oid(Alias) of	{value, Oid} -> {lists:append(Oid, RowIndex), {value, Val}};	_ ->   	     {Alias, RowIndex, {value, Val}}    end;alias_to_oid({Oid, Val}) -> {Oid, {value, Val}}.%%-----------------------------------------------------------------%% Func: initiate_vars/2%% Args: ListOfVars is a list of {Oid, #asn1_type}%%       Varbinds is a list of %%          {VariableOid, Value} | %%          {VariableAtom, Value} |%%          {TableColAtom, RowIndex, Value}%% Purpose: For each variable in specified in the TRAP-TYPE macro%%          (each in ListOfVars), check if it's got a value given%%          in the Varbinds list.%%          For each Oid:%%            1) It has corresponding VariableOid. Use Value.%%            2) No corresponding VariableOid. No value.%% Returns: A list of%%            {VariableOid, #asn1_type, Value} |%%            {VariableOid, #asn1_type} |%%            {VariableOid, Value} |%%            {VariableAtom, Value} |%%            {TableColAtom, RowIndex, Value}%% NOTE: Executed at the inital SA%%-----------------------------------------------------------------initiate_vars([{Oid, Asn1Type} | T], Varbinds) ->    case delete_oid_from_varbinds(Oid, Varbinds) of	{undefined, _, _} ->	    [{Oid, Asn1Type} | initiate_vars(T, Varbinds)];	{Value, VarOid, RestOfVarbinds} ->	    [{VarOid, Asn1Type, Value} | initiate_vars(T, RestOfVarbinds)]    end;initiate_vars([], Varbinds) ->    Varbinds.    delete_oid_from_varbinds(Oid, [{VarOid, Value} | T]) ->    case lists:prefix(Oid, VarOid) of	true -> 	    {Value, VarOid, T};	_ -> 	    {Value2, VarOid2, T2} = delete_oid_from_varbinds(Oid, T),	    {Value2, VarOid2, [{VarOid, Value} | T2]}    end;delete_oid_from_varbinds(Oid, [H | T]) ->    {Value, VarOid, T2} = delete_oid_from_varbinds(Oid, T),    {Value, VarOid, [H | T2]};delete_oid_from_varbinds(_Oid, []) -> {undefined, undefined, []}.%%-----------------------------------------------------------------%% Func: try_initialise_vars(Mib, Varbinds)%% Args: Mib is the local mib process%%       Varbinds is a list returned from initiate_vars.%% Purpose: Try to initialise uninitialised vars.%% Returns: see initiate_vars%% NOTE: Executed at the intermediate SAs%%-----------------------------------------------------------------try_initialise_vars(Mib, Varbinds) ->    V = try_map_symbolic(Varbinds),    try_find_type(V, Mib).%%-----------------------------------------------------------------%% Func: try_map_symbolic/1%% Args: Varbinds is a list returned from initiate_vars.%% Purpose: Try to map symbolic name to oid for the %%          symbolic names left in the Varbinds list.%% Returns: see initiate_vars.%% NOTE: Executed at the intermediate SAs%%-----------------------------------------------------------------try_map_symbolic([Varbind | Varbinds]) ->    [localise_oid(Varbind) | try_map_symbolic(Varbinds)];try_map_symbolic([]) -> [].localise_oid({VariableName, Value}) when atom(VariableName) ->    alias_to_oid({VariableName, Value});localise_oid({VariableName, RowIndex, Value}) when atom(VariableName) ->    alias_to_oid({VariableName, RowIndex, Value});localise_oid(X) -> X.%%-----------------------------------------------------------------%% Func: try_find_type/2%% Args: Varbinds is a list returned from initiate_vars.%%       Mib is a ref to the Mib process corresponding to%%         this agent.%% Purpose: Try to find the type for each variableoid with a value%%          but no type.%% Returns: see initiate_vars.%% NOTE: Executed at the intermediate SAs%%-----------------------------------------------------------------try_find_type([Varbind | Varbinds], Mib) ->    [localise_type(Varbind, Mib) | try_find_type(Varbinds, Mib)];try_find_type([], _) -> [].localise_type({VariableOid, Type}, _Mib)   when list(VariableOid), record(Type, asn1_type) ->    {VariableOid, Type};localise_type({VariableOid, Value}, Mib) when list(VariableOid) ->    case snmpa_mib:lookup(Mib, VariableOid) of	{variable, ME} ->	    {VariableOid, ME#me.asn1_type, Value};	{table_column, ME, _} ->	    {VariableOid, ME#me.asn1_type, Value};	_ ->	    {VariableOid, Value}    end;localise_type(X, _) -> X.%%-----------------------------------------------------------------%% Func: make_v1_trap_pdu/4%% Args: Enterprise = oid()%%       Specific = integer()%%       Varbinds is as returned from initiate_vars%%         (but only {Oid, Type[, Value} permitted)%%       SysUpTime = integer()%% 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%%          to find any missing value.%% Returns: {#trappdu, [byte()] | error%% Fails: yes%% NOTE: Executed at the MA%%-----------------------------------------------------------------make_v1_trap_pdu(Enterprise, Specific, VarbindList, SysUpTime) ->    {Enterp,Generic,Spec} = 	case Enterprise of	    ?snmp ->		{sys_object_id(),Specific,0};	    _ ->

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?