snmpm_server.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 2,152 行 · 第 1/5 页
ERL
2,152 行
maybe_demonitor(MonRef), case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> handle_error(UserId, UserMod, Reason, ReqId, UserData, State), maybe_delete(Disco, ReqId); _ -> %% reply to outstanding request, for which there is no %% longer any owner (the user has unregistered). %% Therefor send it to the default user case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_error(DefUserId, DefMod, Reason, ReqId, DefData, State), maybe_delete(Disco, ReqId); _ -> error_msg("failed retreiving the default user " "info handling error [~w]: " "~n~w", [ReqId, Reason]) end end; %% Failed sync request %% [#request{ref = Ref, mon = MonRef, from = From}] -> ?vdebug("handle_snmp_error -> " "found corresponding request: " "~n failed sync request" "~n Ref: ~p" "~n ModRef: ~p" "~n From: ~p", [Ref, MonRef, From]), Remaining = case (catch cancel_timer(Ref)) of Rem when integer(Rem) -> Rem; _ -> 0 end, ?vtrace("handle_snmp_error -> Remaining: ~p", [Remaining]), maybe_demonitor(MonRef), Reply = {error, {send_failed, ReqId, Reason}}, ?vtrace("handle_snmp_error -> deliver (error-) reply",[]), gen_server:reply(From, Reply), ets:delete(snmpm_request_table, ReqId), ok; %% A very old reply, see if this agent is handled by %% a user. In that case send it there, else to the %% default user. _ -> ?vdebug("handle_snmp_error -> no request?", []), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_error(DefUserId, DefMod, Reason, ReqId, DefData, State); _ -> error_msg("failed retreiving the default " "user info handling error [~w]: " "~n~w",[ReqId, Reason]) end end;handle_snmp_error(CrapError, Reason, _State) -> error_msg("received crap (snmp) error =>" "~n~p~n~p", [CrapError, Reason]), ok.handle_snmp_error(Addr, Port, ReqId, Reason, State) -> ?vtrace("handle_snmp_error -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n ReqId: ~p" "~n Reason: ~p", [Addr, Port, ReqId, Reason]), case snmpm_config:get_agent_user_id(Addr, Port) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> handle_error(UserId, UserMod, Reason, ReqId, UserData, State); _Error -> case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_error(DefUserId, DefMod, Reason, ReqId, DefData, State); _Error -> error_msg("failed retreiving the default user " "info handling snmp error " "<~p,~p>: ~n~w~n~w", [Addr, Port, ReqId, Reason]) end end; _Error -> case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_error(DefUserId, DefMod, Reason, ReqId, DefData, State); _Error -> error_msg("failed retreiving the default user " "info handling snmp error " "<~p,~p>: ~n~w~n~w", [Addr, Port, ReqId, Reason]) end end.handle_error(_UserId, Mod, Reason, ReqId, Data, _State) -> ?vtrace("handle_error -> entry when" "~n Mod: ~p", [Mod]), F = fun() -> (catch Mod:handle_error(ReqId, Reason, Data)) end, handle_callback(F), ok.handle_snmp_pdu(#pdu{type = 'get-response', request_id = ReqId} = Pdu, Addr, Port, State) -> ?vtrace("handle_snmp_pdu(get-response) -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n Pdu: ~p", [Addr, Port, Pdu]), case ets:lookup(snmpm_request_table, ReqId) of %% Reply to a async request or %% possibly a late reply to a sync request %% (ref is also undefined) [#request{user_id = UserId, from = undefined, ref = undefined, mon = MonRef, discovery = Disco}] -> ?vdebug("handle_snmp_pdu(get-response) -> " "found corresponding request: " "~n reply to async request or late reply to sync request" "~n UserId: ~p" "~n ModRef: ~p" "~n Disco: ~p", [UserId, MonRef, Disco]), maybe_demonitor(MonRef), #pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, SnmpResponse = {EStatus, EIndex, Varbinds}, case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> handle_pdu(UserId, UserMod, Addr, Port, ReqId, SnmpResponse, UserData, State), maybe_delete(Disco, ReqId); _Error -> %% reply to outstanding request, for which there is no %% longer any owner (the user has unregistered). %% Therefor send it to the default user case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_pdu(DefUserId, DefMod, Addr, Port, ReqId, SnmpResponse, DefData, State), maybe_delete(Disco, ReqId); Error -> error_msg("failed retreiving the default user " "info handling pdu from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end; %% Reply to a sync request %% [#request{ref = Ref, mon = MonRef, from = From}] -> ?vdebug("handle_snmp_pdu(get-response) -> " "found corresponding request: " "~n reply to sync request" "~n Ref: ~p" "~n ModRef: ~p" "~n From: ~p", [Ref, MonRef, From]), Remaining = case (catch cancel_timer(Ref)) of Rem when integer(Rem) -> Rem; _ -> 0 end, ?vtrace("handle_snmp_pdu(get-response) -> Remaining: ~p", [Remaining]), maybe_demonitor(MonRef), #pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, SnmpReply = {EStatus, EIndex, Varbinds}, Reply = {ok, SnmpReply, Remaining}, ?vtrace("handle_snmp_pdu(get-response) -> deliver reply",[]), gen_server:reply(From, Reply), ets:delete(snmpm_request_table, ReqId), ok; %% A very old reply, see if this agent is handled by %% a user. In that case send it there, else to the %% default user. _ -> ?vdebug("handle_snmp_pdu(get-response) -> " "no corresponding request: " "~n a very old reply", []), #pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, SnmpInfo = {EStatus, EIndex, Varbinds}, case snmpm_config:get_agent_user_id(Addr, Port) of {ok, UserId} -> %% A very late reply or a reply to a request %% that has been cancelled. %% ?vtrace("handle_snmp_pdu(get-response) -> " "a very late reply:" "~n UserId: ~p",[UserId]), case snmpm_config:user_info(UserId) of {ok, UserMod, UserData} -> Reason = {unexpected_pdu, SnmpInfo}, handle_error(UserId, UserMod, Reason, ReqId, UserData, State); _Error -> %% Ouch, found an agent but not it's user!! case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> Reason = {unexpected_pdu, SnmpInfo}, handle_error(DefUserId, DefMod, Reason, ReqId, DefData, State); Error -> error_msg("failed retreiving the default " "user info handling (old) " "pdu from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end; {error, _} -> %% No agent, so either this agent has been %% unregistered, or this is a very late reply %% to a request (possibly a discovery), which %% has since been cancelled (either because of %% a timeout or that the user has unregistered %% itself (and with it all it's requests)). %% No way to know which. %% ?vtrace("handle_snmp_pdu(get-response) -> " "no agent info found", []), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_agent(DefUserId, DefMod, Addr, Port, SnmpInfo, DefData, State); Error -> error_msg("failed retreiving the default user " "info handling (old) pdu when no user " "found from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end end;handle_snmp_pdu(CrapPdu, Addr, Port, _State) -> error_msg("received crap (snmp) Pdu from ~w:~w =>" "~p", [Addr, Port, CrapPdu]), ok.handle_pdu(_UserId, Mod, Addr, Port, ReqId, SnmpResponse, Data, _State) -> ?vtrace("handle_pdu -> entry when" "~n Mod: ~p", [Mod]), F = fun() -> (catch Mod:handle_pdu(Addr, Port, ReqId, SnmpResponse, Data)) end, handle_callback(F), ok.handle_agent(UserId, Mod, Addr, Port, SnmpInfo, Data, State) -> ?vtrace("handle_agent -> entry when" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_agent(UserId, Mod, Addr, Port, SnmpInfo, Data, State) end, handle_callback(F), ok.do_handle_agent(UserId, Mod, Addr, Port, SnmpInfo, Data, _State) -> ?vdebug("do_handle_agent -> entry when" "~n UserId: ~p", [UserId]), case (catch Mod:handle_agent(Addr, Port, SnmpInfo, Data)) of {register, UserId2, Config} -> ?vtrace("do_handle_agent -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), case snmpm_config:register_agent(UserId2, Addr, Port, Config) of ok -> ok; {error, Reason} -> error_msg("failed registering agent " "handling agent " "<~p,~p>: ~n~w", [Addr, Port, Reason]), ok end; _Ignore -> ?vtrace("do_handle_agent -> ignore", []), ok end. %% Retrieve user info for this agent.%% If this is an unknown agent, then use the default userhandle_snmp_trap(#trappdu{enterprise = Enteprise, generic_trap = Generic, specific_trap = Spec, time_stamp = Timestamp, varbinds = Varbinds} = Trap, Addr, Port, State) -> ?vtrace("handle_snmp_trap [trappdu] -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n Trap: ~p", [Addr, Port, Trap]), SnmpTrapInfo = {Enteprise, Generic, Spec, Timestamp, Varbinds}, do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State);handle_snmp_trap(#pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Trap, Addr, Port, State) -> ?vtrace("handle_snmp_trap [pdu] -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n Trap: ~p", [Addr, Port, Trap]), SnmpTrapInfo = {EStatus, EIndex, Varbinds}, do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State);handle_snmp_trap(CrapTrap, Addr, Port, _State) -> error_msg("received crap (snmp) trap from ~w:~w =>" "~p", [Addr, Port, CrapTrap]), ok.do_handle_snmp_trap(SnmpTrapInfo, Addr, Port, State) -> case snmpm_config:get_agent_user_id(Addr, Port) of {ok, UserId} -> ?vtrace("handle_snmp_trap -> found user: ~p",[UserId]), case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> handle_trap(UserId, Mod, Addr, Port, SnmpTrapInfo, Data, State); Error -> %% Oh crap, use the default user ?vlog("[trap] failed retreiving user info for user ~p: " "~n ~p", [UserId, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_trap(DefUserId, DefMod, Addr, Port, SnmpTrapInfo, DefData, State); Error -> error_msg("failed retreiving the default user " "info handling report from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, SnmpTrapInfo]) end end; Error -> %% Unknown agent, pass it on to the default user ?vlog("[trap] failed retreiving user id for agent <~p,~p>: " "~n ~p", [Addr, Port, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_trap(DefUserId, DefMod, Addr, Port, SnmpTrapInfo, DefData, State); Error -> error_msg("failed retreiving " "the default user info handling trap from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, SnmpTrapInfo]) end end, ok.handle_trap(UserId, Mod, Addr, Port, SnmpTrapInfo, Data, State) -> ?vtrace("handle_trap -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_trap(UserId, Mod, Addr, Port, SnmpTrapInfo, Data, State) end, handle_callback(F), ok. do_handle_trap(UserId, Mod, Addr, Port, SnmpTrapInfo, Data, _State) -> ?vdebug("do_handle_trap -> entry with" "~n UserId: ~p", [UserId]), case (catch Mod:handle_trap(Addr, Port, SnmpTrapInfo, Data)) of {register, UserId2, Config} -> ?vtrace("do_handle_trap -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), case snmpm_config:register_agent(UserId2, Addr, Port, Config) of ok -> ok; {error, Reason} -> error_msg("failed registering agent "
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?