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