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