snmpm_server.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 2,152 行 · 第 1/5 页

ERL
2,152
字号
%% ``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(snmpm_server).%%----------------------------------------------------------------------%% This module implements a simple SNMP manager for Erlang.%%%% Discovery: broadcast a request for: %% %%          sysObjectID, sysDescr and sysUpTime%%%%----------------------------------------------------------------------%% User interface-export([start_link/0, stop/0, 	 is_started/0, 	 load_mib/1, unload_mib/1, 	 register_user/3, register_user_monitor/3, unregister_user/1, 	 sync_get/5,       sync_get/6,       sync_get/7, 	 async_get/5,      async_get/6,      async_get/7, 	 sync_get_next/5,  sync_get_next/6,  sync_get_next/7, 	 async_get_next/5, async_get_next/6, async_get_next/7, 	 sync_get_bulk/7,  sync_get_bulk/8,  sync_get_bulk/9, 	 async_get_bulk/7, async_get_bulk/8, async_get_bulk/9, 	 sync_set/5,       sync_set/6,       sync_set/7, 	 async_set/5,      async_set/6,      async_set/7, 	 cancel_async_request/2,	 discovery/2, discovery/3, discovery/4, discovery/5, discovery/6, 	 reconfigure/0,	 info/0, 	 verbosity/1, verbosity/2 	]).%% Internal exports-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 	 code_change/3, terminate/2]).%% GCT exports-export([gct_init/1, gct/2]).-include("snmpm_internal.hrl").-include("snmp_debug.hrl").-include("snmp_types.hrl").-include("STANDARD-MIB.hrl").-include("SNMP-FRAMEWORK-MIB.hrl").-include("snmp_verbosity.hrl").%%-----------------------------------------------------------------------define(SERVER, ?MODULE).-define(SYNC_GET_TIMEOUT,     5000).-define(SYNC_SET_TIMEOUT,     5000).-define(DEFAULT_ASYNC_EXPIRE, 5000).-define(EXTRA_INFO,           undefined).-define(SNMP_AGENT_PORT,      161).-ifdef(snmp_debug).-define(GS_START_LINK(Args),	gen_server:start_link({local, ?SERVER}, ?MODULE, Args, 			      [{debug,[trace]}])).-else.-define(GS_START_LINK(Args),	gen_server:start_link({local, ?SERVER}, ?MODULE, Args, [])).-endif.%%-----------------------------------------------------------------------record(state,	{parent,	 gct,	 note_store,	 note_store_ref,	 net_if,	 net_if_mod,	 net_if_ref,	 req,  %%  ???? Last request id in outgoing message	 oid,  %%  ???? Last oid in request outgoing message	 mini_mib	}       ).%% The active state is to ensure that nothing unpleasant happens%% during (after) a code_change. At the initial start of the%% application, this process (GCT) will make one run and then%% deactivate (unless some async request has been issued in the%% meantime).-record(gct, {parent, state = active, timeout}).-record(request, 	{id, 	 user_id,	 addr, 	 port, 	 type, 	 data, 	 ref, 	 mon, 	 from,	 discovery = false, 	 expire = infinity % When shall the request expire (time in ms)	}       ). -record(monitor,	{id, 	 mon,	 proc	}       ).%%%-------------------------------------------------------------------%%% API%%%-------------------------------------------------------------------start_link() ->    ?d("start_link -> entry", []),    Args = [],    ?GS_START_LINK(Args).stop() ->    call(stop).is_started() ->    call(is_started, 1000).load_mib(MibFile) when list(MibFile) ->    call({load_mib, MibFile}).unload_mib(Mib) when list(Mib) ->    call({unload_mib, Mib}).register_user(UserId, UserMod, UserData) ->    snmpm_config:register_user(UserId, UserMod, UserData).register_user_monitor(Id, Module, Data) ->    case register_user(Id, Module, Data) of	ok ->	    case call({monitor_user, Id, self()}) of		ok ->		    ok;		Error ->		    unregister_user(Id),		    Error	    end;	Error ->	    Error    end.unregister_user(UserId) ->    call({unregister_user, UserId}).%% -- [sync] get --sync_get(UserId, Addr, Port, CtxName, Oids) ->    sync_get(UserId, Addr, Port, CtxName, Oids, 	     ?SYNC_GET_TIMEOUT, ?EXTRA_INFO).sync_get(UserId, Addr, Port, CtxName, Oids, Timeout) ->    sync_get(UserId, Addr, Port, CtxName, Oids, Timeout, ?EXTRA_INFO).sync_get(UserId, Addr0, Port, CtxName, Oids, Timeout, ExtraInfo)   when integer(Port), list(CtxName), list(Oids), integer(Timeout) ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({sync_get, self(), UserId, Addr, Port, CtxName, Oids, Timeout, 	  ExtraInfo}).%% -- [async] get --async_get(UserId, Addr, Port, CtxName, Oids) ->    async_get(UserId, Addr, Port, CtxName, Oids, 	      ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).async_get(UserId, Addr, Port, CtxName, Oids, Expire) ->    async_get(UserId, Addr, Port, CtxName, Oids, Expire, ?EXTRA_INFO).async_get(UserId, Addr0, Port, CtxName, Oids, Expire, ExtraInfo)   when integer(Port),        list(CtxName),        list(Oids),        integer(Expire), Expire >= 0 ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({async_get, self(), UserId, Addr, Port, CtxName, Oids, Expire, 	  ExtraInfo}).%% -- [sync] get-next --sync_get_next(UserId, Addr0, Port, CtxName, Oids) ->    sync_get_next(UserId, Addr0, Port, CtxName, Oids, ?SYNC_GET_TIMEOUT, 		  ?EXTRA_INFO).sync_get_next(UserId, Addr0, Port, CtxName, Oids, Timeout) ->    sync_get_next(UserId, Addr0, Port, CtxName, Oids, Timeout, ?EXTRA_INFO).sync_get_next(UserId, Addr0, Port, CtxName, Oids, Timeout, ExtraInfo)   when integer(Port), list(CtxName), list(Oids), integer(Timeout) ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({sync_get_next, self(), UserId, Addr, Port, CtxName, Oids, Timeout, 	  ExtraInfo}).%% -- [async] get-next --async_get_next(UserId, Addr, Port, CtxName, Oids) ->    async_get_next(UserId, Addr, Port, CtxName, Oids, 		   ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).async_get_next(UserId, Addr, Port, CtxName, Oids, Expire) ->    async_get_next(UserId, Addr, Port, CtxName, Oids, Expire, ?EXTRA_INFO).async_get_next(UserId, Addr0, Port, CtxName, Oids, Expire, ExtraInfo)   when integer(Port),        list(CtxName),        list(Oids),        integer(Expire), Expire >= 0 ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({async_get_next, self(), UserId, Addr, Port, CtxName, Oids, 	  Expire, ExtraInfo}).%% -- [sync] get-bulk --sync_get_bulk(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids) ->    sync_get_bulk(UserId, Addr, Port, 		  NonRep, MaxRep, CtxName, Oids, 		  ?SYNC_GET_TIMEOUT, ?EXTRA_INFO).sync_get_bulk(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout) ->    sync_get_bulk(UserId, Addr, Port, 		  NonRep, MaxRep, CtxName, Oids, 		  Timeout, ?EXTRA_INFO).sync_get_bulk(UserId, Addr0, Port, NonRep, MaxRep, CtxName, Oids, Timeout, 	      ExtraInfo)   when integer(Port),        integer(NonRep), integer(MaxRep),        list(CtxName), list(Oids), integer(Timeout) ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({sync_get_bulk, self(), UserId, Addr, Port, 	  NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo}).%% -- [async] get-bulk --async_get_bulk(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids) ->    async_get_bulk(UserId, Addr, Port, 		   NonRep, MaxRep, CtxName, Oids, 		   ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).async_get_bulk(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Expire) ->    async_get_bulk(UserId, Addr, Port, 		   NonRep, MaxRep, CtxName, Oids, 		   Expire, ?EXTRA_INFO).async_get_bulk(UserId, Addr0, Port, NonRep, MaxRep, CtxName, Oids, Expire, 	       ExtraInfo)   when integer(Port),        integer(NonRep), integer(MaxRep),        list(CtxName), list(Oids), integer(Expire) ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({async_get_bulk, self(), UserId, Addr, Port, 	  NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo}).%% -- [sync] set --%% VarsAndValues is: {PlainOid, o|s|i, Value} (unknown mibs) | {Oid, Value} sync_set(UserId, Addr0, Port, CtxName, VarsAndVals) ->    sync_set(UserId, Addr0, Port, CtxName, VarsAndVals, 	     ?SYNC_SET_TIMEOUT, ?EXTRA_INFO).sync_set(UserId, Addr0, Port, CtxName, VarsAndVals, Timeout) ->    sync_set(UserId, Addr0, Port, CtxName, VarsAndVals, 	     Timeout, ?EXTRA_INFO).sync_set(UserId, Addr0, Port, CtxName, VarsAndVals, Timeout, ExtraInfo)   when integer(Port), list(CtxName), list(VarsAndVals), integer(Timeout) ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({sync_set, self(), UserId, Addr, Port, 	  CtxName, VarsAndVals, Timeout, ExtraInfo}).%% -- [async] set --async_set(UserId, Addr, Port, CtxName, VarsAndVals) ->    async_set(UserId, Addr, Port, CtxName, VarsAndVals, 	      ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).async_set(UserId, Addr, Port, CtxName, VarsAndVals, Expire) ->    async_set(UserId, Addr, Port, CtxName, VarsAndVals, 	      Expire, ?EXTRA_INFO).async_set(UserId, Addr0, Port, CtxName, VarsAndVals, Expire, ExtraInfo)   when integer(Port),        list(CtxName),        list(VarsAndVals),        integer(Expire), Expire >= 0 ->    {ok, Addr} = inet:getaddr(Addr0, inet),    call({async_set, self(), UserId, Addr, Port, 	  CtxName, VarsAndVals, Expire, ExtraInfo}).cancel_async_request(UserId, ReqId) ->    call({cancel_async_request, UserId, ReqId}).discovery(UserId, BAddr) ->    discovery(UserId, BAddr, ?SNMP_AGENT_PORT, [], 	      ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO).discovery(UserId, BAddr, Config) when is_list(Config) ->    discovery(UserId, BAddr, ?SNMP_AGENT_PORT, Config, 	      ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO);discovery(UserId, BAddr, Expire) when is_integer(Expire) ->    discovery(UserId, BAddr, ?SNMP_AGENT_PORT, [], Expire, ?EXTRA_INFO).discovery(UserId, BAddr, Config, Expire) ->    discovery(UserId, BAddr, ?SNMP_AGENT_PORT, Config, Expire, ?EXTRA_INFO).discovery(UserId, BAddr, Port, Config, Expire) ->    discovery(UserId, BAddr, Port, Config, Expire, ?EXTRA_INFO).discovery(UserId, BAddr, Port, Config, Expire, ExtraInfo) ->    call({discovery, self(), UserId, BAddr, Port, Config, Expire, ExtraInfo}).    verbosity(Verbosity) ->    case ?vvalidate(Verbosity) of	Verbosity ->	    call({verbosity, Verbosity});	_ ->	    {error, {invalid_verbosity, Verbosity}}    end.info() ->    call(info).verbosity(net_if = Ref, Verbosity) ->    verbosity2(Ref, Verbosity);verbosity(note_store = Ref, Verbosity) ->    verbosity2(Ref, Verbosity).verbosity2(Ref, Verbosity) ->    case ?vvalidate(Verbosity) of	Verbosity ->	    call({verbosity, Ref, Verbosity});	_ ->	    {error, {invalid_verbosity, Verbosity}}    end.reconfigure() ->    call(reconfigure).%%----------------------------------------------------------------------%% Options: List of%%  {community, String ("public" is default} %%  {mibs, List of Filenames}%%  {trap_udp, integer() (default 5000)}%%  {conf_dir, string()}%%  {log_dir,  string()}%%  {db_dir,   string()}%%  {db_repair, true | false}%%----------------------------------------------------------------------init(_) ->    ?d("init -> entry", []),    case (catch do_init()) of	{ok, State} ->	    {ok, State};	{error, Reason} ->	    {stop, Reason}    end.%% Put all config stuff in a snmpm_config module/process.%% Tables should be protected so that it is cheap to %% read. Writing has to go through the interface...do_init() ->    process_flag(trap_exit, true),    {ok, Prio} = snmpm_config:system_info(prio),    process_flag(priority, Prio),    {ok, Verbosity} = snmpm_config:system_info(server_verbosity),    put(sname, mse),    put(verbosity, Verbosity),    ?vlog("starting", []),    %% Start the garbage collector timer process    {ok, Timeout} = snmpm_config:system_info(server_timeout),    {ok, GCT} = gct_start(Timeout),    %% -- Create request table --    ets:new(snmpm_request_table, 	    [set, protected, named_table, {keypos, #request.id}]),    %% -- Create monitor table --    ets:new(snmpm_monitor_table, 	    [set, protected, named_table, {keypos, #monitor.id}]),    %% -- Start the note-store and net-if processes --    {NoteStore, NoteStoreRef} = do_init_note_store(Prio),    {NetIf, NetIfModule, NetIfRef} = do_init_net_if(NoteStore),

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?