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 + -
显示快捷键?