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