snmpm_net_if.erl

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

ERL
855
字号
%% ``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_net_if).-behaviour(gen_server).-behaviour(snmpm_network_interface).%% Network Interface callback functions-export([	 start_link/2, 	 stop/1, 	 send_pdu/6, % Backward compatibillity	 send_pdu/7,	 inform_response/4, 	 note_store/2, 	 info/1,  	 verbosity/2	]).%% gen_server callbacks-export([init/1, handle_call/3, handle_cast/2, handle_info/2, 	 code_change/3, terminate/2]).-define(SNMP_USE_V3, true).-include("snmp_types.hrl").-include("snmpm_internal.hrl").-include("snmpm_atl.hrl").-include("snmp_debug.hrl").%% -define(VMODULE,"NET_IF").-include("snmp_verbosity.hrl").-record(state, 	{	  server,	  note_store,	  sock, 	  mpd_state,	  log,	  irb = auto, % auto | {user, integer()}	  irgc	 }).-ifdef(snmp_debug).-define(GS_START_LINK(Args),	gen_server:start_link(?MODULE, Args, [{debug,[trace]}])).-else.-define(GS_START_LINK(Args),	gen_server:start_link(?MODULE, Args, [])).-endif.-define(IRGC_TIMEOUT, timer:minutes(5)).%%%-------------------------------------------------------------------%%% API%%%-------------------------------------------------------------------start_link(Server, NoteStore) ->    ?d("start_link -> entry with"       "~n   Server:    ~p"       "~n   NoteStore: ~p", [Server, NoteStore]),    Args = [Server, NoteStore],     ?GS_START_LINK(Args).stop(Pid) ->    call(Pid, stop).send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) ->    send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, undefined).send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo)   when record(Pdu, pdu) ->    ?d("send_pdu -> entry with"       "~n   Pid:     ~p"       "~n   Pdu:     ~p"       "~n   Vsn:     ~p"       "~n   MsgData: ~p"       "~n   Addr:    ~p"       "~n   Port:    ~p", [Pid, Pdu, Vsn, MsgData, Addr, Port]),    cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}).note_store(Pid, NoteStore) ->    call(Pid, {note_store, NoteStore}).inform_response(Pid, Ref, Addr, Port) ->    cast(Pid, {inform_response, Ref, Addr, Port}).info(Pid) ->    call(Pid, info).verbosity(Pid, V) ->    call(Pid, {verbosity, V}).%%%-------------------------------------------------------------------%%% Callback functions from gen_server%%%-------------------------------------------------------------------%%--------------------------------------------------------------------%% Func: init/1%% Returns: {ok, State}          |%%          {ok, State, Timeout} |%%          ignore               |%%          {stop, Reason}%%--------------------------------------------------------------------init([Server, NoteStore]) ->     ?d("init -> entry with"       "~n   Server:    ~p"       "~n   NoteStore: ~p", [Server, NoteStore]),    case (catch do_init(Server, NoteStore)) of	{error, Reason} ->	    {stop, Reason};	{ok, State} ->	    {ok, State}    end.	    do_init(Server, NoteStore) ->    process_flag(trap_exit, true),    %% -- Prio --    {ok, Prio} = snmpm_config:system_info(prio),    process_flag(priority, Prio),    %% -- Create inform request table --    ets:new(snmpm_inform_request_table,	    [set, protected, named_table, {keypos, 1}]),    %% -- Verbosity --     {ok, Verbosity} = snmpm_config:system_info(net_if_verbosity),    put(sname,mnif),    put(verbosity,Verbosity),    ?vlog("starting", []),    %% -- MPD --    {ok, Vsns} = snmpm_config:system_info(versions),    MpdState   = snmpm_mpd:init(Vsns),    %% -- Module dependent options --    {ok, Opts} = snmpm_config:system_info(net_if_options),    %% -- Inform response behaviour --    {ok, IRB}  = snmpm_config:system_info(net_if_irb),     IrGcRef    = irgc_start(IRB),     %% -- Socket --    SndBuf  = get_opt(Opts, sndbuf,   default),    RecBuf  = get_opt(Opts, recbuf,   default),    BindTo  = get_opt(Opts, bind_to,  false),    NoReuse = get_opt(Opts, no_reuse, false),    {ok, Port} = snmpm_config:system_info(port),    {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, BindTo, NoReuse),    %% -- Audit trail log ---    {ok, ATL} = snmpm_config:system_info(audit_trail_log),    Log = do_init_log(ATL),        %% -- We are done ---    State = #state{server     = Server, 		   note_store = NoteStore, 		   mpd_state  = MpdState,		   sock       = Sock, 		   log        = Log,		   irb        = IRB,		   irgc       = IrGcRef},    ?vdebug("started", []),    {ok, State}.%% Open port do_open_port(Port, SendSz, RecvSz, BindTo, NoReuse) ->    ?vtrace("do_open_port -> entry with"	    "~n   Port:    ~p"	    "~n   SendSz:  ~p"	    "~n   RecvSz:  ~p"	    "~n   BindTo:  ~p"	    "~n   NoReuse: ~p", [Port, SendSz, RecvSz, BindTo, NoReuse]),    IpOpts1 = bind_to(BindTo),    IpOpts2 = no_reuse(NoReuse),    IpOpts3 = recbuf(RecvSz),    IpOpts4 = sndbuf(SendSz),    IpOpts  = [binary | IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],    case init:get_argument(snmpm_fd) of	{ok, [[FdStr]]} ->	    Fd = list_to_integer(FdStr),	    gen_udp:open(0, [{fd, Fd}|IpOpts]);	error ->	    gen_udp:open(Port, IpOpts)    end.bind_to(true) ->    case snmpm_config:system_info(address) of	{ok, Addr} when is_list(Addr) ->	    [{ip, list_to_tuple(Addr)}];	{ok, Addr} ->	    [{ip, Addr}];	_ ->	    []    end;bind_to(_) ->    [].no_reuse(false) ->    [{reuseaddr, true}];no_reuse(_) ->    [].recbuf(default) ->    [];recbuf(Sz) ->    [{recbuf, Sz}].sndbuf(default) ->    [];sndbuf(Sz) ->    [{sndbuf, Sz}].%% Open logdo_init_log(false) ->    ?vtrace("do_init_log(false) -> entry", []),    undefined;do_init_log(true) ->    ?vtrace("do_init_log(true) -> entry", []),    {ok, Type}   = snmpm_config:system_info(audit_trail_log_type),    {ok, Dir}    = snmpm_config:system_info(audit_trail_log_dir),    {ok, Size}   = snmpm_config:system_info(audit_trail_log_size),    {ok, Repair} = snmpm_config:system_info(audit_trail_log_repair),    Name = ?audit_trail_log_name,     File = filename:absname(?audit_trail_log_file, Dir),    case snmp_log:create(Name, File, Size, Repair, true) of	{ok, Log} ->	    {Log, Type};	{error, Reason} ->	    throw({error, {failed_create_audit_log, Reason}})    end.    %%--------------------------------------------------------------------%% Func: handle_call/3%% Returns: {reply, Reply, State}          |%%          {reply, Reply, State, Timeout} |%%          {noreply, State}               |%%          {noreply, State, Timeout}      |%%          {stop, Reason, Reply, State}   | (terminate/2 is called)%%          {stop, Reason, State}            (terminate/2 is called)%%--------------------------------------------------------------------handle_call({verbosity, Verbosity}, _From, State) ->    ?vlog("received verbosity request", []),    put(verbosity, Verbosity),    {reply, ok, State};handle_call({note_store, Pid}, _From, State) ->    ?vlog("received new note_store: ~w", [Pid]),    {reply, ok, State#state{note_store = Pid}};handle_call(stop, _From, State) ->    ?vlog("received stop request", []),    Reply = ok,    {stop, normal, Reply, State};handle_call(info, _From, State) ->    ?vlog("received info request", []),    Reply = get_info(State),    {reply, Reply, State};handle_call(Req, From, State) ->    warning_msg("received unknown request (from ~p): ~n~p", [Req, From]),    {reply, {error, {invalid_request, Req}}, State}.%%--------------------------------------------------------------------%% Func: handle_cast/2%% Returns: {noreply, State}          |%%          {noreply, State, Timeout} |%%          {stop, Reason, State}            (terminate/2 is called)%%--------------------------------------------------------------------handle_cast({send_pdu, Pdu, Vsn, MsgData, Addr, Port, _ExtraInfo}, State) ->    ?vlog("received send_pdu message with"	  "~n   Pdu:     ~p"	  "~n   Vsn:     ~p"	  "~n   MsgData: ~p"	  "~n   Addr:    ~p"	  "~n   Port:    ~p", [Pdu, Vsn, MsgData, Addr, Port]),    handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State),     {noreply, State};handle_cast({inform_response, Ref, Addr, Port}, State) ->    ?vlog("received inform_response message with"	  "~n   Ref:  ~p"	  "~n   Addr: ~p"	  "~n   Port: ~p", [Ref, Addr, Port]),    handle_inform_response(Ref, Addr, Port, State),     {noreply, State};handle_cast(Msg, State) ->    warning_msg("received unknown message: ~n~p", [Msg]),    {noreply, State}.%%--------------------------------------------------------------------%% Func: handle_info/2%% Returns: {noreply, State}          |%%          {noreply, State, Timeout} |%%          {stop, Reason, State}            (terminate/2 is called)%%--------------------------------------------------------------------handle_info({udp, Sock, Ip, Port, Bytes}, #state{sock = Sock} = State) ->    ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]),    handle_recv_msg(Ip, Port, Bytes, State),    {noreply, State};handle_info(inform_response_gc, State) ->    ?vlog("received inform_response_gc message", []),    State2 = handle_inform_response_gc(State),    {noreply, State2};handle_info({disk_log, _Node, Log, Info}, State) ->    ?vlog("received disk_log message: "	  "~n   Info: ~p", [Info]),    State2 = handle_disk_log(Log, Info, State),    {noreply, State2};handle_info(Info, State) ->    warning_msg("received unknown info: ~n~p", [Info]),    {noreply, State}.%%--------------------------------------------------------------------%% Func: terminate/2%% Purpose: Shutdown the server%% Returns: any (ignored by gen_server)%%--------------------------------------------------------------------terminate(Reason, #state{log = Log, irgc = IrGcRef}) ->    ?vdebug("terminate: ~p",[Reason]),    irgc_stop(IrGcRef),    %% Close logs    do_close_log(Log),    ok.do_close_log({Log, _Type}) ->    (catch snmp_log:sync(Log)),    (catch snmp_log:close(Log)),    ok;do_close_log(_) ->    ok.%%----------------------------------------------------------------------%% Func: code_change/3%% Purpose: Convert process state when code is changed%% Returns: {ok, NewState}%%---------------------------------------------------------------------- code_change({down, _Vsn}, OldState, downgrade_to_pre45) ->    ?d("code_change(down) -> entry", []),    #state{server     = Server, 	   note_store = NoteStore, 	   sock       = Sock, 	   mpd_state  = MpdState, 	   log        = Log, 	   irgc       = IrGcRef} = OldState,    irgc_stop(IrGcRef),    (catch ets:delete(snmpm_inform_request_table)),    State = {state, Server, NoteStore, Sock, MpdState, Log},    {ok, State};% upgradecode_change(_Vsn, OldState, upgrade_from_pre45) ->    ?d("code_change(up) -> entry", []),    {state, Server, NoteStore, Sock, MpdState, Log} = OldState,    State = #state{server     = Server, 		   note_store = NoteStore, 		   sock       = Sock, 		   mpd_state  = MpdState, 		   log        = Log, 		   irb        = auto,		   irgc       = undefined},    ets:new(snmpm_inform_request_table,	    [set, protected, named_table, {keypos, 1}]),    {ok, State};code_change(_Vsn, State, _Extra) ->    {ok, State}. %%%-------------------------------------------------------------------%%% Internal functions%%%-------------------------------------------------------------------handle_recv_msg(Addr, Port, Bytes, #state{server = Pid})   when is_binary(Bytes) and (size(Bytes) == 0) ->    Pid ! {snmp_error, {empty_message, Addr, Port}, Addr, Port},    ok;handle_recv_msg(Addr, Port, Bytes, 		#state{server     = Pid, 		       note_store = NoteStore, 		       mpd_state  = MpdState, 		       sock       = Sock,		       log        = Log,		       irb        = IRB}) ->    Logger = logger(Log, read, Addr, Port),    case (catch snmpm_mpd:process_msg(Bytes, snmpUDPDomain, Addr, Port, 				      MpdState, NoteStore, Logger)) of	%% BMK BMK BMK	%% Do we really need message size here??

⌨️ 快捷键说明

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