snmpm_server.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 2,152 行 · 第 1/5 页
ERL
2,152 行
"handling trap " "<~p,~p>: ~n~w", [Addr, Port, Reason]), ok end; unregister -> ?vtrace("do_handle_trap -> unregister", []), case snmpm_config:unregister_agent(UserId, Addr, Port) of ok -> ok; {error, Reason} -> error_msg("failed unregistering agent " "handling trap " "<~p,~p>: ~n~w", [Addr, Port, Reason]), ok end; _Ignore -> ?vtrace("do_handle_trap -> ignore", []), ok end.handle_snmp_inform(Ref, #pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, Addr, Port, State) -> ?vtrace("handle_snmp_inform -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n Pdu: ~p", [Addr, Port, Pdu]), SnmpInform = {EStatus, EIndex, Varbinds}, case snmpm_config:get_agent_user_id(Addr, Port) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> ?vdebug("[inform] callback handle_inform with: " "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), handle_inform(UserId, Mod, Ref, Addr, Port, SnmpInform, Data, State); Error -> %% Oh crap, use the default user ?vlog("[inform] failed retreiving user info for user ~p:" "~n ~p", [UserId, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_inform(DefUserId, DefMod, Ref, Addr, Port, SnmpInform, DefData, State); Error -> error_msg("failed retreiving the default user " "info handling inform from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end; Error -> %% Unknown agent, pass it on to the default user ?vlog("[inform] failed retreiving user id for agent <~p,~p>: " "~n ~p", [Addr, Port, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_inform(DefUserId, DefMod, Ref, Addr, Port, SnmpInform, DefData, State); Error -> error_msg("failed retreiving " "the default user info handling inform from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end, ok;handle_snmp_inform(_Ref, CrapInform, Addr, Port, _State) -> error_msg("received crap (snmp) inform from ~w:~w =>" "~p", [Addr, Port, CrapInform]), ok.handle_inform(UserId, Mod, Ref, Addr, Port, SnmpInform, Data, State) -> ?vtrace("handle_inform -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_inform(UserId, Mod, Ref, Addr, Port, SnmpInform, Data, State) end, handle_callback(F), ok.do_handle_inform(UserId, Mod, Ref, Addr, Port, SnmpInform, Data, State) -> ?vdebug("do_handle_inform -> entry with" "~n UserId: ~p", [UserId]), Rep = case (catch Mod:handle_inform(Addr, Port, SnmpInform, Data)) of {register, UserId2, Config} -> ?vtrace("do_handle_inform -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), %% The only user which would do this is the %% default user case snmpm_config:register_agent(UserId2, Addr, Port, Config) of ok -> reply; {error, Reason} -> error_msg("failed registering agent " "handling inform " "<~p,~p>: ~n~w", [Addr, Port, Reason]), reply end; unregister -> ?vtrace("do_handle_inform -> unregister", []), case snmpm_config:unregister_agent(UserId, Addr, Port) of ok -> reply; {error, Reason} -> error_msg("failed unregistering agent " "handling inform " "<~p,~p>: ~n~w", [Addr, Port, Reason]), reply end; no_reply -> ?vtrace("do_handle_inform -> no_reply", []), no_reply; _Ignore -> ?vtrace("do_handle_inform -> ignore", []), reply end, handle_inform_response(Rep, Ref, Addr, Port, State), ok.handle_inform_response(_, ignore, _Addr, _Port, _State) -> ok;handle_inform_response(no_reply, _Ref, _Addr, _Port, _State) -> ok;handle_inform_response(_, Ref, Addr, Port, #state{net_if = Pid, net_if_mod = Mod}) -> ?vdebug("handle_inform -> response", []), (catch Mod:inform_response(Pid, Ref, Addr, Port)). handle_snmp_report(#pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, Addr, Port, State) -> ?vtrace("handle_snmp_report -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n Pdu: ~p", [Addr, Port, Pdu]), SnmpReport = {EStatus, EIndex, Varbinds}, case snmpm_config:get_agent_user_id(Addr, Port) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> ?vdebug("[report] callback handle_report with: " "~n ~p" "~n ~p" "~n ~p", [UserId, Mod, SnmpReport]), handle_report(UserId, Mod, Addr, Port, SnmpReport, Data, State); Error -> %% Oh crap, use the default user ?vlog("[report] failed retreiving user info for user ~p:" " ~n ~p", [UserId, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_report(DefUserId, DefMod, Addr, Port, SnmpReport, DefData, State); Error -> error_msg("failed retreiving the default user " "info handling report from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end; Error -> %% Unknown agent, pass it on to the default user ?vlog("[report] failed retreiving user id for agent <~p,~p>: " "~n ~p", [Addr, Port, Error]), case snmpm_config:user_info() of {ok, DefUserId, DefMod, DefData} -> handle_report(DefUserId, DefMod, Addr, Port, SnmpReport, DefData, State); Error -> error_msg("failed retreiving " "the default user info handling report from " "<~p,~p>: ~n~w~n~w", [Addr, Port, Error, Pdu]) end end, ok;handle_snmp_report(CrapReport, Addr, Port, _State) -> error_msg("received crap (snmp) report from ~w:~w =>" "~p", [Addr, Port, CrapReport]), ok.%% This could be from a failed get-request, so we might have a user%% waiting for a reply here. If there is, we handle this as an failed%% get-response (except for tha data which is different). Otherwise,%% we handle it as an error (reported via the handle_error callback%% function).handle_snmp_report(ReqId, #pdu{error_status = EStatus, error_index = EIndex, varbinds = Varbinds} = Pdu, {ReportReason, Info} = Rep, Addr, Port, State) when integer(ReqId) -> ?vtrace("handle_snmp_report -> entry with" "~n Addr: ~p" "~n Port: ~p" "~n ReqId: ~p" "~n Rep: ~p" "~n Pdu: ~p", [Addr, Port, ReqId, Rep, Pdu]), SnmpReport = {EStatus, EIndex, Varbinds}, Reason = {ReportReason, Info, SnmpReport}, %% Check if there is someone waiting for this request case ets:lookup(snmpm_request_table, ReqId) of [#request{from = From, ref = Ref, mon = MonRef}] when From /= undefined, Ref /= undefined -> ?vdebug("handle_snmp_report -> " "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), Reply = {error, Reason}, ?vtrace("handle_snmp_report -> deliver reply",[]), gen_server:reply(From, Reply), ets:delete(snmpm_request_table, ReqId), ok; _ -> %% Either not a sync request or no such request. Either %% way, this is error info, so handle it as such. case snmpm_config:get_agent_user_id(Addr, Port) of {ok, UserId} -> case snmpm_config:user_info(UserId) of {ok, Mod, Data} -> ?vdebug("[report] callback handle_error with: " "~n ~p" "~n ~p" "~n ~p", [UserId, Mod, Reason]), handle_error(UserId, Mod, Reason, ReqId, Data, State); Error -> %% Oh crap, use the default user ?vlog("[report] failed retreiving user info for " "user ~p:" " ~n ~p", [UserId, 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 report from " "<~p,~p>: ~n~w~n~w~n~w", [Addr, Port, Error, ReqId, Reason]) end end; Error -> %% Unknown agent, pass it on to the default user ?vlog("[report] failed retreiving user id for " "agent <~p,~p>: " "~n ~p", [Addr, Port, 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 " "report from " "<~p,~p>: ~n~w~n~w~n~w", [Addr, Port, Error, ReqId, Reason]) end end end, ok;handle_snmp_report(CrapReqId, CrapReport, CrapInfo, Addr, Port, _State) -> error_msg("received crap (snmp) report from ~w:~w =>" "~n~p~n~p~n~p", [Addr, Port, CrapReqId, CrapReport, CrapInfo]), ok. handle_report(UserId, Mod, Addr, Port, SnmpReport, Data, State) -> ?vtrace("handle_report -> entry with" "~n UserId: ~p" "~n Mod: ~p", [UserId, Mod]), F = fun() -> do_handle_report(UserId, Mod, Addr, Port, SnmpReport, Data, State) end, handle_callback(F), ok.do_handle_report(UserId, Mod, Addr, Port, SnmpReport, Data, _State) -> ?vdebug("do_handle_report -> entry with" "~n UserId: ~p", [UserId]), case (catch Mod:handle_report(Addr, Port, SnmpReport, Data)) of {register, UserId2, Config} -> ?vtrace("do_handle_report -> register: " "~n UserId2: ~p" "~n Config: ~p", [UserId2, Config]), %% The only user which would do this is the %% default user case snmpm_config:register_agent(UserId2, Addr, Port, Config) of ok -> ok; {error, Reason} -> error_msg("failed registering agent " "handling report " "<~p,~p>: ~n~w", [Addr, Port, Reason]), ok end; unregister -> ?vtrace("do_handle_trap -> unregister", []), case snmpm_config:unregister_agent(UserId, Addr, Port) of ok -> ok; {error, Reason} -> error_msg("failed unregistering agent " "handling report " "<~p,~p>: ~n~w", [Addr, Port, Reason]), ok end; _Ignore -> ?vtrace("do_handle_report -> ignore", []), ok end.handle_callback(F) -> V = get(verbosity), erlang:spawn( fun() -> put(sname, msew), put(verbosity, V), F() end). handle_down(MonRef) -> %% Clear out all requests from this client handle_down_requests_cleanup(MonRef), %% %% Check also if this was a monitored user, and if so %% unregister all agents registered by this user, and %% finally unregister the user itself %% handle_down_user_cleanup(MonRef), ok.handle_down_requests_cleanup(MonRef) -> Pat = #request{id = '$1', ref = '$2', mon = MonRef, _ = '_'}, Match = ets:match(snmpm_request_table, Pat), Fun = fun([Id, Ref]) -> ?vtrace("delete request: ~p", [Id]), ets:delete(snmpm_request_table, Id), cancel_timer(Ref), ok end, lists:foreach(Fun, Match).handle_down_user_cleanup(MonRef) -> Pat = #monitor{id = '$1', mon = MonRef, _ = '_'}, Match = ets:match(snmpm_monitor_table, Pat), Fun = fun([Id]) -> Agents = snmpm_config:which_agents(Id), lists:foreach( fun({A,P}) -> ?vtrace("unregister agent of monitored user " "~w: <~w,~w>", [Id,A,P]), snmpm_config:unregister_agent(Id, A, P) end, Agents), ?vtrace("unregister monitored user: ~w", [Id]), ets:delete(snmpm_monitor_table, Id), snmpm_config:unregister_user(Id), ok end, lists:foreach(Fun, Match).
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?