aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src/manager
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2014-08-22 12:12:29 +0200
committerRaimo Niskanen <[email protected]>2014-08-22 12:12:29 +0200
commitcc9fbe12c3e7c0c99462d72fe99ee9f29051353a (patch)
tree7fe0974c711ceb34112734b8d7ff0fb58fe1f15c /lib/snmp/src/manager
parentbdbd6849aa811faf20d5ce7d577a49612266209a (diff)
downloadotp-cc9fbe12c3e7c0c99462d72fe99ee9f29051353a.tar.gz
otp-cc9fbe12c3e7c0c99462d72fe99ee9f29051353a.tar.bz2
otp-cc9fbe12c3e7c0c99462d72fe99ee9f29051353a.zip
Merge manager net_if_mt into net_if
Diffstat (limited to 'lib/snmp/src/manager')
-rw-r--r--lib/snmp/src/manager/depend.mk5
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl237
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_mt.erl1340
3 files changed, 201 insertions, 1381 deletions
diff --git a/lib/snmp/src/manager/depend.mk b/lib/snmp/src/manager/depend.mk
index 2e7783c8ed..60f61b0d3b 100644
--- a/lib/snmp/src/manager/depend.mk
+++ b/lib/snmp/src/manager/depend.mk
@@ -2,7 +2,7 @@
# %CopyrightBegin%
#
-# Copyright Ericsson AB 2004-2012. All Rights Reserved.
+# Copyright Ericsson AB 2004-2014. All Rights Reserved.
#
# 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
@@ -50,10 +50,11 @@ $(EBIN)/snmpm_net_if.$(EMULATOR): \
snmpm_network_interface.erl
$(EBIN)/snmpm_net_if_mt.$(EMULATOR): \
+ snmpm_net_if_mt.erl \
../../include/snmp_types.hrl \
../misc/snmp_debug.hrl \
../misc/snmp_verbosity.hrl \
- snmpm_net_if_mt.erl \
+ snmpm_net_if.erl \
snmpm_network_interface.erl
$(EBIN)/snmpm_server.$(EMULATOR): \
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index bdde8a5623..cb72871177 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -17,7 +17,9 @@
%% %CopyrightEnd%
%%
+-ifndef(snmpm_net_if_mt).
-module(snmpm_net_if).
+-endif.
-behaviour(gen_server).
-behaviour(snmpm_network_interface).
@@ -149,6 +151,64 @@ filter_reset(Pid) ->
%%%-------------------------------------------------------------------
+%%% Multi-thread manager
+%%%-------------------------------------------------------------------
+
+-ifdef(snmpm_net_if_mt).
+
+%% This function is called through the macro below to
+%% (in the not multithreaded case) avoid creating the
+%% Failer/4 fun, and to avoid calling the Worker through a fun
+%% (now it shall not be a fun, just a code snippet).
+
+worker(Worker, Failer, #state{log = Log} = State) ->
+ Verbosity = get(verbosity),
+ spawn_opt(
+ fun () ->
+ try
+ put(sname, mnifw),
+ put(verbosity, Verbosity),
+ NewState =
+ case do_reopen_log(Log) of
+ Log ->
+ State;
+ NewLog ->
+ State#state{log = NewLog}
+ end,
+ Worker(NewState)
+ of
+ Result ->
+ %% Winds up in handle_info {'DOWN', ...}
+ erlang:exit({net_if_worker, Result})
+ catch
+ Class:Reason ->
+ %% Winds up in handle_info {'DOWN', ...}
+ erlang:exit(
+ {net_if_worker, Failer,
+ Class, Reason, erlang:get_stacktrace()})
+ end
+ end,
+ [monitor]).
+-define(
+ worker(S, Worker, Failer, State),
+ begin
+ worker(
+ fun (S) -> begin Worker end end,
+ begin Failer end,
+ (State))
+ end).
+
+-else.
+
+-define(
+ worker(S, Worker, _Failer, State),
+ begin (S) = (State), begin Worker end end).
+
+-endif.
+
+
+
+%%%-------------------------------------------------------------------
%%% Callback functions from gen_server
%%%-------------------------------------------------------------------
@@ -168,6 +228,14 @@ init([Server, NoteStore]) ->
{error, Reason} ->
{stop, Reason}
end.
+
+-ifdef(snmpm_net_if_mt).
+%% This should really be protected, but it also needs to
+%% be writable for the worker processes, so...
+-define(inform_table_opts, [set, public, named_table, {keypos, 1}]).
+-else.
+-define(inform_table_opts, [set, protected, named_table, {keypos, 1}]).
+-endif.
do_init(Server, NoteStore) ->
process_flag(trap_exit, true),
@@ -177,8 +245,7 @@ do_init(Server, NoteStore) ->
process_flag(priority, Prio),
%% -- Create inform request table --
- ets:new(snmpm_inform_request_table,
- [set, protected, named_table, {keypos, 1}]),
+ ets:new(snmpm_inform_request_table, ?inform_table_opts),
%% -- Verbosity --
{ok, Verbosity} = snmpm_config:system_info(net_if_verbosity),
@@ -189,6 +256,7 @@ do_init(Server, NoteStore) ->
%% -- MPD --
{ok, Vsns} = snmpm_config:system_info(versions),
MpdState = snmpm_mpd:init(Vsns),
+ ?vdebug("MpdState: ~w", [MpdState]),
%% -- Module dependent options --
{ok, Opts} = snmpm_config:system_info(net_if_options),
@@ -205,6 +273,7 @@ do_init(Server, NoteStore) ->
%% -- Audit trail log ---
{ok, ATL} = snmpm_config:system_info(audit_trail_log),
Log = do_init_log(ATL),
+ ?vdebug("Log: ~w", [Log]),
{ok, DomainAddresses} = snmpm_config:system_info(transports),
?vdebug("DomainAddresses: ~w",[DomainAddresses]),
@@ -344,20 +413,65 @@ do_init_log(true) ->
Name, File, SeqNoGen, Size, Repair, true) of
{ok, Log} ->
?vdebug("log created: ~w", [Log]),
- {Log, Type};
+ {Name, Log, Type};
{error, Reason} ->
throw({error, {failed_create_audit_log, Reason}})
end;
_ ->
case snmp_log:create(Name, File, Size, Repair, true) of
{ok, Log} ->
- {Log, Type};
+ ?vdebug("log created: ~w", [Log]),
+ {Name, Log, Type};
{error, Reason} ->
throw({error, {failed_create_audit_log, Reason}})
end
end.
-
+-ifdef(snmpm_net_if_mt).
+do_reopen_log(undefined) ->
+ undefined;
+do_reopen_log({Name, Log, Type}) ->
+ case snmp_log:open(Name, Log) of
+ {ok, NewLog} ->
+ {Name, NewLog, Type};
+ {error, Reason} ->
+ warning_msg(
+ "NetIf worker ~p failed to open ATL:~n"
+ " ~p", [self(), Reason]),
+ undefined
+ end.
+-endif.
+
+%% Close log
+do_close_log(undefined) ->
+ ok;
+do_close_log({_Name, Log, _Type}) ->
+ (catch snmp_log:sync(Log)),
+ (catch snmp_log:close(Log)),
+ ok;
+do_close_log(_) ->
+ ok.
+
+%% Log
+logger(undefined, _Type, _Domain, _Addr) ->
+ fun(_) ->
+ ok
+ end;
+logger({_Name, Log, Types}, Type, Domain, Addr) ->
+ case lists:member(Type, Types) of
+ true ->
+ AddrString =
+ iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})),
+ fun(Msg) ->
+ snmp_log:log(Log, Msg, AddrString)
+ end;
+ false ->
+ fun(_) ->
+ ok
+ end
+ end.
+
+
%%--------------------------------------------------------------------
%% Func: handle_call/3
%% Returns: {reply, Reply, State} |
@@ -475,11 +589,42 @@ handle_info({disk_log, _Node, Log, Info}, State) ->
State2 = handle_disk_log(Log, Info, State),
{noreply, State2};
+handle_info({'DOWN', _, _, _, _} = Info, State) ->
+ handle_info_down(Info, State);
+
handle_info(Info, State) ->
+ handle_info_unknown(Info, State).
+
+
+handle_info_unknown(Info, State) ->
warning_msg("received unknown info: ~n~p", [Info]),
{noreply, State}.
+-ifdef(snmpm_net_if_mt).
+handle_info_down(
+ {'DOWN', _MRef, process, _Pid,
+ {net_if_worker, _Result}},
+ State) ->
+ ?vdebug("received DOWN message from net_if worker [~w]: "
+ "~n Result: ~p", [_Pid, _Result]),
+ {noreply, State};
+handle_info_down(
+ {'DOWN', _MRef, process, Pid,
+ {net_if_worker, Failer, Class, Reason, Stacktrace} = _ExitStatus},
+ State) ->
+ ?vdebug("received DOWN message from net_if worker [~w]: "
+ "~n ExitStatus: ~p", [Pid, _ExitStatus]),
+ Failer(Pid, Class, Reason, Stacktrace),
+ {noreply, State};
+handle_info_down(Info, State) ->
+ handle_info_unknown(Info, State).
+-else.
+handle_info_down(Info, State) ->
+ handle_info_unknown(Info, State).
+-endif.
+
+
%%--------------------------------------------------------------------
%% Func: terminate/2
%% Purpose: Shutdown the server
@@ -493,14 +638,6 @@ terminate(Reason, #state{log = Log, irgc = IrGcRef}) ->
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
@@ -519,7 +656,20 @@ code_change(_Vsn, State, _Extra) ->
%%% Internal functions
%%%-------------------------------------------------------------------
-maybe_handle_recv_msg(
+maybe_handle_recv_msg(Domain, Addr, Bytes, State) ->
+ ?worker(
+ S, maybe_handle_recv_msg_mt(Domain, Addr, Bytes, S),
+ fun (Pid, Class, Reason, Stacktrace) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (incomming) message from %s:~n"
+ "~w:~w at ~p",
+ [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
+ Class, Reason, Stacktrace])
+ end,
+ State).
+
+maybe_handle_recv_msg_mt(
Domain, Addr, Bytes,
#state{filter = FilterMod, transports = Transports} = State) ->
{Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
@@ -669,6 +819,19 @@ handle_inform_request(
end.
handle_inform_response(Ref, Domain, Addr, State) ->
+ ?worker(
+ S, handle_inform_response_mt(Ref, Domain, Addr, S),
+ fun (Pid, Class, Reason, Stacktrace) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (outgoing) inform response for %s:~n"
+ "~w:~w at ~p",
+ [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
+ Class, Reason, Stacktrace])
+ end,
+ State).
+
+handle_inform_response_mt(Ref, Domain, Addr, State) ->
Key = {Ref, Domain, Addr},
case ets:lookup(snmpm_inform_request_table, Key) of
[{Key, _, {Vsn, ACM, RePdu}}] ->
@@ -737,18 +900,30 @@ irgc_stop(undefined) ->
irgc_stop(Ref) ->
(catch erlang:cancel_timer(Ref)).
-
-maybe_handle_send_pdu(
+maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State) ->
+ ?worker(
+ S, maybe_handle_send_pdu_mt(Pdu, Vsn, MsgData, Domain, Addr, S),
+ fun (Pid, Class, Reason, Stacktrace) ->
+ warning_msg(
+ "Worker process (~p) terminated "
+ "while processing (outgoing) pdu for %s:~n"
+ "~w:~w at ~p",
+ [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
+ Class, Reason, Stacktrace])
+ end,
+ State).
+
+maybe_handle_send_pdu_mt(
Pdu, Vsn, MsgData, Domain, Addr,
#state{filter = FilterMod, transports = Transports} = State) ->
{Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of
false ->
- inc(netIfPduOutDrops),
- ok;
+ inc(netIfPduOutDrops);
_ ->
handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State)
- end.
+ end,
+ ok.
handle_send_pdu(
Pdu, Vsn, MsgData, Domain, Addr,
@@ -766,8 +941,7 @@ handle_send_pdu(
?vlog("PDU not sent: "
"~n PDU: ~p"
"~n Reason: ~p", [Pdu, Reason]),
- Pid ! {snmp_error, Pdu, Reason},
- ok
+ Pid ! {snmp_error, Pdu, Reason}
end.
@@ -1087,27 +1261,6 @@ t() ->
%% -------------------------------------------------------------------
-logger(undefined, _Type, _Domain, _Addr) ->
- fun(_) ->
- ok
- end;
-logger({Log, Types}, Type, Domain, Addr) ->
- case lists:member(Type, Types) of
- true ->
- AddrString =
- iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})),
- fun(Msg) ->
- snmp_log:log(Log, Msg, AddrString)
- end;
- false ->
- fun(_) ->
- ok
- end
- end.
-
-
-%% -------------------------------------------------------------------
-
%% info_msg(F, A) ->
%% ?snmpm_info("NET-IF server: " ++ F, A).
diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl
index 8f2ed6d8cd..62f6023657 100644
--- a/lib/snmp/src/manager/snmpm_net_if_mt.erl
+++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl
@@ -17,1341 +17,7 @@
%% %CopyrightEnd%
%%
--module(snmpm_net_if_mt).
-
--behaviour(gen_server).
--behaviour(snmpm_network_interface).
-
-
-%% Network Interface callback functions
--export([
- start_link/2,
- stop/1,
- send_pdu/6, % Backward compatibility
- send_pdu/7, % Partly backward compatibility
- send_pdu/8, % Backward compatibility
-
- inform_response/4,
-
- note_store/2,
-
- info/1,
- verbosity/2,
- %% system_info_updated/2,
- get_log_type/1, set_log_type/2,
- filter_reset/1
- ]).
-
-%% 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,
- transports = [],
- mpd_state,
- log,
- irb = auto, % auto | {user, integer()}
- irgc,
- filter
- }).
-
--record(transport,
- {socket,
- domain = snmpUDPDomain}).
-
--define(DEFAULT_FILTER_MODULE, snmpm_net_if_filter).
--define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]).
-
--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)).
-
--define(ATL_SEQNO_INITIAL, 1).
--define(ATL_SEQNO_MAX, 2147483647).
-
-
-%%%-------------------------------------------------------------------
-%%% 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, Domain_or_Ip, Addr_or_Port) ->
- send_pdu(
- Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ?DEFAULT_EXTRA_INFO).
-
-send_pdu(Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port, ExtraInfo)
- when is_record(Pdu, pdu) ->
- ?d("send_pdu -> entry with~n"
- " Pid: ~p~n"
- " Pdu: ~p~n"
- " Vsn: ~p~n"
- " MsgData: ~p~n"
- " Domain/IP: ~p~n"
- " Addr/Port: ~p",
- [Pid, Pdu, Vsn, MsgData, Domain_or_Ip, Addr_or_Port]),
- {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port),
- cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo}).
-
-send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Ip, Port, ExtraInfo) ->
- send_pdu(Pid, Pdu, Vsn, MsgData, Domain, {Ip, Port}, ExtraInfo).
-
-note_store(Pid, NoteStore) ->
- call(Pid, {note_store, NoteStore}).
-
-inform_response(Pid, Ref, Domain_or_Ip, Addr_or_Port) ->
- {Domain, Addr} = address(Domain_or_Ip, Addr_or_Port),
- cast(Pid, {inform_response, Ref, Domain, Addr}).
-
-info(Pid) ->
- call(Pid, info).
-
-verbosity(Pid, V) ->
- call(Pid, {verbosity, V}).
-
-%% system_info_updated(Pid, What) ->
-%% call(Pid, {system_info_updated, What}).
-
-get_log_type(Pid) ->
- call(Pid, get_log_type).
-
-set_log_type(Pid, NewType) ->
- call(Pid, {set_log_type, NewType}).
-
-filter_reset(Pid) ->
- cast(Pid, filter_reset).
-
-
-%%%-------------------------------------------------------------------
-%%% 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]),
- try do_init(Server, NoteStore)
- catch
- {error, Reason} ->
- {stop, Reason}
- 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 --
- %% This should really be protected, but it also needs to
- %% be writable for the worker processes, so...
- ets:new(snmpm_inform_request_table,
- [set, public, 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),
- ?vdebug("MpdState: ~w", [MpdState]),
-
- %% -- 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),
-
- %% Flow control --
- FilterOpts = get_opt(Opts, filter, []),
- FilterMod = create_filter(FilterOpts),
- ?vdebug("FilterMod: ~w", [FilterMod]),
-
- %% -- Audit trail log ---
- {ok, ATL} = snmpm_config:system_info(audit_trail_log),
- Log = do_init_log(ATL),
- ?vdebug("Log: ~w", [Log]),
-
- {ok, DomainAddresses} = snmpm_config:system_info(transports),
- ?vdebug("DomainAddresses: ~w",[DomainAddresses]),
- CommonSocketOpts = common_socket_opts(Opts),
- BindTo = get_opt(Opts, bind_to, false),
- case
- [begin
- {IpPort, SocketOpts} =
- socket_params(Domain, Address, BindTo, CommonSocketOpts),
- Socket = socket_open(IpPort, SocketOpts),
- #transport{socket = Socket, domain = Domain}
- end || {Domain, Address} <- DomainAddresses]
- of
- [] ->
- ?vinfo("No transports configured: ~p", [DomainAddresses]),
- throw({error, {no_transports,DomainAddresses}});
- Transports ->
- %% -- Initiate counters ---
- init_counters(),
-
- %% -- We are done ---
- State = #state{
- server = Server,
- note_store = NoteStore,
- mpd_state = MpdState,
- transports = Transports,
- log = Log,
- irb = IRB,
- irgc = IrGcRef,
- filter = FilterMod},
- ?vdebug("started", []),
- {ok, State}
- end.
-
-socket_open(IpPort, SocketOpts) ->
- ?vtrace("socket_open -> entry with~n"
- " IpPort: ~p~n"
- " SocketOpts: ~p", [IpPort, SocketOpts]),
- case gen_udp:open(IpPort, SocketOpts) of
- {error, _} = Error ->
- throw(Error);
- {ok, Socket} ->
- Socket
- end.
-
-socket_params(Domain, {IpAddr, IpPort}, BindTo, CommonSocketOpts) ->
- Family = snmp_conf:tdomain_to_family(Domain),
- SocketOpts =
- case Family of
- inet6 ->
- [Family, {ipv6_v6only, true} | CommonSocketOpts];
- Family ->
- [Family | CommonSocketOpts]
- end,
- case Family of
- inet ->
- case init:get_argument(snmp_fd) of
- {ok, [[FdStr]]} ->
- Fd = list_to_integer(FdStr),
- case BindTo of
- true ->
- {IpPort, [{ip, IpAddr}, {fd, Fd} | SocketOpts]};
- _ ->
- {0, [{fd, Fd} | SocketOpts]}
- end;
- error ->
- {IpPort, [{ip, IpAddr} | SocketOpts]}
- end;
- _ ->
- case BindTo of
- true ->
- {IpPort, [{ip, IpAddr} | SocketOpts]};
- _ ->
- {IpPort, SocketOpts}
- end
- end.
-
-common_socket_opts(Opts) ->
- [binary
- | case get_opt(Opts, sndbuf, default) of
- default ->
- [];
- Sz ->
- [{sndbuf, Sz}]
- end ++
- case get_opt(Opts, recbuf, default) of
- default ->
- [];
- Sz ->
- [{sndbuf, Sz}]
- end ++
- case get_opt(Opts, no_reuse, false) of
- false ->
- [{reuseaddr, true}];
- _ ->
- []
- end].
-
-
-create_filter(Opts) when is_list(Opts) ->
- case get_opt(Opts, module, ?DEFAULT_FILTER_MODULE) of
- ?DEFAULT_FILTER_MODULE = Mod ->
- Mod;
- Module ->
- snmpm_network_interface_filter:verify(Module),
- Module
- end;
-create_filter(BadOpts) ->
- throw({error, {bad_filter_opts, BadOpts}}).
-
-
-%% ----------------------------------------------------------------------
-%% Audit Trail Logger
-%% ----------------------------------------------------------------------
-
-%% Open log
-do_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 snmpm_config:system_info(audit_trail_log_seqno) of
- {ok, true} ->
- Initial = ?ATL_SEQNO_INITIAL,
- Max = ?ATL_SEQNO_MAX,
- Module = snmpm_config,
- Function = increment_counter,
- Args = [atl_seqno, Initial, Max],
- SeqNoGen = {Module, Function, Args},
- case snmp_log:create(
- Name, File, SeqNoGen, Size, Repair, true) of
- {ok, Log} ->
- ?vdebug("log created: ~w", [Log]),
- {Name, Log, Type};
- {error, Reason} ->
- throw({error, {failed_create_audit_log, Reason}})
- end;
- _ ->
- case snmp_log:create(Name, File, Size, Repair, true) of
- {ok, Log} ->
- ?vdebug("log created: ~w", [Log]),
- {Name, Log, Type};
- {error, Reason} ->
- throw({error, {failed_create_audit_log, Reason}})
- end
- 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({system_info_updated, What}, _From, State) ->
-%% ?vlog("received system_info_updated request with What = ~p", [What]),
-%% {NewState, Reply} = handle_system_info_updated(State, What),
-%% {reply, Reply, NewState};
-
-handle_call(get_log_type, _From, State) ->
- ?vlog("received get-log-type request", []),
- Reply = (catch handle_get_log_type(State)),
- {reply, Reply, State};
-
-handle_call({set_log_type, NewType}, _From, State) ->
- ?vlog("received set-log-type request with NewType = ~p", [NewType]),
- {NewState, Reply} = (catch handle_set_log_type(State, NewType)),
- {reply, Reply, NewState};
-
-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, Domain, Addr, ExtraInfo},
- State) ->
- ?vlog("received send_pdu message with~n"
- " Pdu: ~p~n"
- " Vsn: ~p~n"
- " MsgData: ~p~n"
- " Domain: ~p~n"
- " Addr: ~p", [Pdu, Vsn, MsgData, Domain, Addr]),
- maybe_process_extra_info(ExtraInfo),
- handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State),
- {noreply, State};
-
-handle_cast({inform_response, Ref, Domain, Addr}, State) ->
- ?vlog("received inform_response message with~n"
- " Ref: ~p~n"
- " Domain: ~p~n"
- " Addr: ~p", [Ref, Domain, Addr]),
- handle_inform_response(Ref, Domain, Addr, State),
- {noreply, State};
-
-handle_cast(filter_reset, State) ->
- ?vlog("received filter_reset message", []),
- reset_counters(),
- {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, Socket, IpAddr, IpPort, Bytes},
- #state{transports = Transports} = State) ->
- Size = byte_size(Bytes),
- case lists:keyfind(Socket, #transport.socket, Transports) of
- #transport{socket = Socket, domain = Domain} ->
- ?vlog("received ~w bytes from ~p:~p [~w]",
- [Size, IpAddr, IpPort, Socket]),
- handle_udp(Domain, {IpAddr, IpPort}, Bytes, State),
- {noreply, State};
- false ->
- warning_msg("Received ~w bytes on unknown port: ~p from ~s",
- [Size, Socket, format_address({IpAddr, IpPort})]),
- {noreply, State}
- end;
-
-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({'DOWN', _MRef, process, _Pid, {net_if_worker, _Result}},
- State) ->
- ?vdebug("received DOWN message from net_if worker [~w]: "
- "~n Result: ~p", [_Pid, _Result]),
- {noreply, State};
-handle_info(
- {'DOWN', _MRef, process, Pid,
- {net_if_worker, Failer, Class, Reason, Stacktrace} = _ExitStatus},
- State) ->
- ?vdebug("received DOWN message from net_if worker [~w]: "
- "~n ExitStatus: ~p", [Pid, _ExitStatus]),
- Failer(Pid, Class, Reason, Stacktrace),
- {noreply, State};
-
-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({_Name, 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(_Vsn, State, _Extra) ->
- ?d("code_change -> entry with"
- "~n Vsn: ~p"
- "~n State: ~p"
- "~n Extra: ~p", [_Vsn, State, _Extra]),
- {ok, State}.
-
-
-%%%-------------------------------------------------------------------
-%%% Internal functions
-%%%-------------------------------------------------------------------
-
-handle_udp(Domain, Addr, Bytes, State) ->
- worker(
- fun (S) ->
- maybe_handle_recv_msg(Domain, Addr, Bytes, S)
- end,
- fun (Pid, Class, Reason, Stacktrace) ->
- warning_msg(
- "Worker process (~p) terminated "
- "while processing (incomming) message from %s:~n"
- "~w:~w at ~p",
- [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
- Class, Reason, Stacktrace])
- end,
- State).
-
-maybe_handle_recv_msg(
- Domain, Addr, Bytes,
- #state{filter = FilterMod, transports = Transports} = State) ->
- {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
- case (catch FilterMod:accept_recv(Arg1, Arg2)) of
- false ->
- %% Drop the received packet
- inc(netIfMsgInDrops);
- _ ->
- handle_recv_msg(Domain, Addr, Bytes, State)
- end,
- ok.
-
-
-handle_recv_msg(Domain, Addr, Bytes, #state{server = Pid})
- when is_binary(Bytes) andalso (size(Bytes) =:= 0) ->
- Pid ! {snmp_error, {empty_message, Domain, Addr}, Domain, Addr};
-%%
-handle_recv_msg(
- Domain, Addr, Bytes,
- #state{
- server = Pid,
- note_store = NoteStore,
- mpd_state = MpdState,
- log = Log} = State) ->
- Logger = logger(Log, read, Domain, Addr),
- case (catch snmpm_mpd:process_msg(
- Bytes, Domain, Addr, MpdState, NoteStore, Logger)) of
-
- {ok, Vsn, Pdu, MS, ACM} ->
- maybe_handle_recv_pdu(
- Domain, Addr, Vsn, Pdu, MS, ACM, Logger, State);
-
- {discarded, Reason, Report} ->
- ?vdebug("discarded: ~p", [Reason]),
- ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Domain, Addr},
- maybe_udp_send(Domain, Addr, Report, State);
- {discarded, Reason} ->
- ?vdebug("discarded: ~p", [Reason]),
- ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Domain, Addr};
-
- Error ->
- error_msg("processing of received message failed: "
- "~n ~p", [Error])
- end.
-
-
-maybe_handle_recv_pdu(
- Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger,
- #state{filter = FilterMod, transports = Transports} = State) ->
- {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
- case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of
- false ->
- inc(netIfPduInDrops);
- _ ->
- handle_recv_pdu(
- Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State)
- end;
-maybe_handle_recv_pdu(
- Domain, Addr, Vsn, Trap, PduMS, ACM, Logger,
- #state{filter = FilterMod, transports = Transports} = State)
- when is_record(Trap, trappdu) ->
- {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
- case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of
- false ->
- inc(netIfPduInDrops);
- _ ->
- handle_recv_pdu(
- Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, State)
- end;
-maybe_handle_recv_pdu(
- Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State) ->
- handle_recv_pdu(Domain, Addr, Vsn, Pdu, PduMS, ACM, Logger, State).
-
-
-handle_recv_pdu(
- Domain, Addr, Vsn,
- #pdu{type = 'inform-request'} = Pdu, _PduMS, ACM, Logger,
- #state{server = Pid, irb = IRB} = State) ->
- handle_inform_request(
- IRB, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State);
-handle_recv_pdu(
- Domain, Addr, _Vsn,
- #pdu{type = report} = Pdu, _PduMS, ok, _Logger,
- #state{server = Pid} = _State) ->
- ?vtrace("received report - ok", []),
- Pid ! {snmp_report, {ok, Pdu}, Domain, Addr};
-handle_recv_pdu(
- Domain, Addr, _Vsn,
- #pdu{type = report} = Pdu, _PduMS, {error, ReqId, Reason}, _Logger,
- #state{server = Pid} = _State) ->
- ?vtrace("received report - error", []),
- Pid ! {snmp_report, {error, ReqId, Reason, Pdu}, Domain, Addr};
-handle_recv_pdu(
- Domain, Addr, _Vsn,
- #pdu{type = 'snmpv2-trap'} = Pdu, _PduMS, _ACM, _Logger,
- #state{server = Pid} = _State) ->
- ?vtrace("received snmpv2-trap", []),
- Pid ! {snmp_trap, Pdu, Domain, Addr};
-handle_recv_pdu(
- Domain, Addr, _Vsn, Trap, _PduMS, _ACM, _Logger,
- #state{server = Pid} = _State) when is_record(Trap, trappdu) ->
- ?vtrace("received trappdu", []),
- Pid ! {snmp_trap, Trap, Domain, Addr};
-handle_recv_pdu(
- Domain, Addr, _Vsn, Pdu, _PduMS, _ACM, _Logger,
- #state{server = Pid} = _State) when is_record(Pdu, pdu) ->
- ?vtrace("received pdu", []),
- Pid ! {snmp_pdu, Pdu, Domain, Addr};
-handle_recv_pdu(
- _Domain, _Addr, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) ->
- ?vlog("received unexpected pdu: "
- "~n Pdu: ~p"
- "~n ACM: ~p", [Pdu, ACM]).
-
-
-handle_inform_request(
- auto, Pid, Vsn, Pdu, ACM, Domain, Addr, Logger, State) ->
- ?vtrace("received inform-request (true)", []),
- Pid ! {snmp_inform, ignore, Pdu, Domain, Addr},
- RePdu = make_response_pdu(Pdu),
- maybe_send_inform_response(RePdu, Vsn, ACM, Domain, Addr, Logger, State);
-handle_inform_request(
- {user, To}, Pid, Vsn, #pdu{request_id = ReqId} = Pdu,
- ACM, Domain, Addr, _Logger, _State) ->
- ?vtrace("received inform-request (false)", []),
-
- Pid ! {snmp_inform, ReqId, Pdu, Domain, Addr},
-
- %% Before we go any further, we need to check that we have not
- %% already received this message (possible resend).
-
- Key = {ReqId, Domain, Addr},
- case ets:lookup(snmpm_inform_request_table, Key) of
- [_] ->
- %% OK, we already know about this. We assume this
- %% is a resend. Either the agent is really eager or
- %% the user has not answered yet. Bad user!
- ok;
- [] ->
- RePdu = make_response_pdu(Pdu),
- Expire = t() + To,
- Rec = {Key, Expire, {Vsn, ACM, RePdu}},
- ets:insert(snmpm_inform_request_table, Rec)
- end.
-
-handle_inform_response(Ref, Domain, Addr, State) ->
- worker(
- fun (S) ->
- do_handle_inform_response(Ref, Domain, Addr, S)
- end,
- fun (Pid, Class, Reason, Stacktrace) ->
- warning_msg(
- "Worker process (~p) terminated "
- "while processing (outgoing) inform response for %s:~n"
- "~w:~w at ~p",
- [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
- Class, Reason, Stacktrace])
- end,
- State).
-
-do_handle_inform_response(Ref, Domain, Addr, State) ->
- Key = {Ref, Domain, Addr},
- case ets:lookup(snmpm_inform_request_table, Key) of
- [{Key, _, {Vsn, ACM, RePdu}}] ->
- Logger = logger(State#state.log, read, Domain, Addr),
- ets:delete(snmpm_inform_request_table, Key),
- maybe_send_inform_response(
- RePdu, Vsn, ACM, Domain, Addr, Logger, State);
- [] ->
- %% Already acknowledged, or the user was to slow to reply...
- ok
- end,
- ok.
-
-maybe_send_inform_response(
- RePdu, Vsn, ACM, Domain, Addr, Logger,
- #state{
- server = Pid,
- filter = FilterMod,
- transports = Transports} = State) ->
- {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
- case (catch FilterMod:accept_send_pdu(
- Arg1, Arg2, pdu_type_of(RePdu)))
- of
- false ->
- inc(netIfPduOutDrops),
- ok;
- _ ->
- case snmpm_mpd:generate_response_msg(Vsn, RePdu, ACM, Logger) of
- {ok, Msg} ->
- maybe_udp_send(Domain, Addr, Msg, State);
- {discarded, Reason} ->
- ?vlog("failed generating response message:"
- "~n Reason: ~p", [Reason]),
- ReqId = RePdu#pdu.request_id,
- ErrorInfo = {failed_generating_response, {RePdu, Reason}},
- Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr}
- end
- end.
-
-handle_inform_response_gc(#state{irb = IRB} = State) ->
- ets:safe_fixtable(snmpm_inform_request_table, true),
- do_irgc(ets:first(snmpm_inform_request_table), t()),
- ets:safe_fixtable(snmpm_inform_request_table, false),
- State#state{irgc = irgc_start(IRB)}.
-
-%% We are deleting at the same time as we are traversing the table!!!
-do_irgc('$end_of_table', _) ->
- ok;
-do_irgc(Key, Now) ->
- Next = ets:next(snmpm_inform_request_table, Key),
- case ets:lookup(snmpm_inform_request_table, Key) of
- [{Key, BestBefore, _}] when BestBefore < Now ->
- ets:delete(snmpm_inform_request_table, Key);
- _ ->
- ok
- end,
- do_irgc(Next, Now).
-
-irgc_start(auto) ->
- undefined;
-irgc_start(_) ->
- erlang:send_after(?IRGC_TIMEOUT, self(), inform_response_gc).
-
-irgc_stop(undefined) ->
- ok;
-irgc_stop(Ref) ->
- (catch erlang:cancel_timer(Ref)).
-
-
-handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State) ->
- worker(
- fun (S) ->
- maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, S)
- end,
- fun (Pid, Class, Reason, Stacktrace) ->
- warning_msg(
- "Worker process (~p) terminated "
- "while processing (outgoing) pdu for %s:~n"
- "~w:~w at ~p",
- [Pid, snmp_conf:mk_addr_string({Domain, Addr}),
- Class, Reason, Stacktrace])
- end,
- State).
-
-maybe_handle_send_pdu(
- Pdu, Vsn, MsgData, Domain, Addr,
- #state{filter = FilterMod, transports = Transports} = State) ->
- {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
- case (catch FilterMod:accept_send_pdu(Arg1, Arg2, pdu_type_of(Pdu))) of
- false ->
- inc(netIfPduOutDrops),
- ok;
- _ ->
- do_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State)
- end.
-
-do_handle_send_pdu(
- Pdu, Vsn, MsgData, Domain, Addr,
- #state{
- server = Pid,
- note_store = NoteStore,
- log = Log} = State) ->
- Logger = logger(Log, write, Domain, Addr),
- case (catch snmpm_mpd:generate_msg(
- Vsn, NoteStore, Pdu, MsgData, Logger)) of
- {ok, Msg} ->
- ?vtrace("do_handle_send_pdu -> message generated", []),
- maybe_udp_send(Domain, Addr, Msg, State);
- {discarded, Reason} ->
- ?vlog("PDU not sent: "
- "~n PDU: ~p"
- "~n Reason: ~p", [Pdu, Reason]),
- Pid ! {snmp_error, Pdu, Reason},
- ok
- end.
-
-
-maybe_udp_send(
- Domain, Addr, Msg,
- #state{filter = FilterMod, transports = Transports}) ->
- To = {Domain, Addr},
- {Arg1, Arg2} = fix_filter_address(Transports, To),
- case (catch FilterMod:accept_send(Arg1, Arg2)) of
- false ->
- inc(netIfMsgOutDrops),
- ok;
- _ ->
- case select_transport_from_domain(Domain, Transports) of
- false ->
- error_msg(
- "Can not find transport~n"
- " size: ~p~n"
- " to: ~s",
- [sz(Msg), format_address(To)]);
- #transport{socket = Socket} ->
- udp_send(Socket, Addr, Msg)
- end
- end.
-
-udp_send(Sock, To, Msg) ->
- {IpAddr, IpPort} =
- case To of
- {Domain, Addr} when is_atom(Domain) ->
- Addr;
- {_, P} = Addr when is_integer(P) ->
- Addr
- end,
- try gen_udp:send(Sock, IpAddr, IpPort, Msg) of
- ok ->
- ?vdebug("sent ~w bytes to ~w:~w [~w]",
- [sz(Msg), IpAddr, IpPort, Sock]),
- ok;
- {error, Reason} ->
- error_msg("failed sending message to ~p:~p:~n"
- " ~p",[IpAddr, IpPort, Reason])
- catch
- error:Error ->
- error_msg("failed sending message to ~p:~p:~n"
- " error:~p~n"
- " ~p",
- [IpAddr, IpPort, Error, erlang:get_stacktrace()])
- end.
-
-sz(B) when is_binary(B) ->
- byte_size(B);
-sz(L) when is_list(L) ->
- length(L);
-sz(_) ->
- undefined.
-
-
-handle_disk_log(_Log, {wrap, NoLostItems}, State) ->
- ?vlog("Audit Trail Log - wrapped: ~w previously logged items where lost",
- [NoLostItems]),
- State;
-handle_disk_log(_Log, {truncated, NoLostItems}, State) ->
- ?vlog("Audit Trail Log - truncated: ~w items where lost when truncating",
- [NoLostItems]),
- State;
-handle_disk_log(_Log, full, State) ->
- error_msg("Failed to write to Audit Trail Log (full)", []),
- State;
-handle_disk_log(_Log, {error_status, ok}, State) ->
- State;
-handle_disk_log(_Log, {error_status, {error, Reason}}, State) ->
- error_msg("Error status received from Audit Trail Log: "
- "~n~p", [Reason]),
- State;
-handle_disk_log(_Log, _Info, State) ->
- State.
-
-
-%% mk_discovery_msg('version-3', Pdu, _VsnHdr, UserName) ->
-%% ScopedPDU = #scopedPdu{contextEngineID = "",
-%% contextName = "",
-%% data = Pdu},
-%% Bytes = snmp_pdus:enc_scoped_pdu(ScopedPDU),
-%% MsgID = get(msg_id),
-%% put(msg_id,MsgID+1),
-%% UsmSecParams =
-%% #usmSecurityParameters{msgAuthoritativeEngineID = "",
-%% msgAuthoritativeEngineBoots = 0,
-%% msgAuthoritativeEngineTime = 0,
-%% msgUserName = UserName,
-%% msgPrivacyParameters = "",
-%% msgAuthenticationParameters = ""},
-%% SecBytes = snmp_pdus:enc_usm_security_parameters(UsmSecParams),
-%% PduType = Pdu#pdu.type,
-%% Hdr = #v3_hdr{msgID = MsgID,
-%% msgMaxSize = 1000,
-%% msgFlags = snmp_misc:mk_msg_flags(PduType, 0),
-%% msgSecurityModel = ?SEC_USM,
-%% msgSecurityParameters = SecBytes},
-%% Msg = #message{version = 'version-3', vsn_hdr = Hdr, data = Bytes},
-%% case (catch snmp_pdus:enc_message_only(Msg)) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% L when list(L) ->
-%% {Msg, L}
-%% end;
-%% mk_discovery_msg(Version, Pdu, {Com, _, _, _, _}, UserName) ->
-%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu},
-%% case catch snmp_pdus:enc_message(Msg) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% L when list(L) ->
-%% {Msg, L}
-%% end.
-
-
-%% mk_msg('version-3', Pdu, {Context, User, EngineID, CtxEngineId, SecLevel},
-%% MsgData) ->
-%% %% Code copied from snmp_mpd.erl
-%% {MsgId, SecName, SecData} =
-%% if
-%% tuple(MsgData), Pdu#pdu.type == 'get-response' ->
-%% MsgData;
-%% true ->
-%% Md = get(msg_id),
-%% put(msg_id, Md + 1),
-%% {Md, User, []}
-%% end,
-%% ScopedPDU = #scopedPdu{contextEngineID = CtxEngineId,
-%% contextName = Context,
-%% data = Pdu},
-%% ScopedPDUBytes = snmp_pdus:enc_scoped_pdu(ScopedPDU),
-
-%% PduType = Pdu#pdu.type,
-%% V3Hdr = #v3_hdr{msgID = MsgId,
-%% msgMaxSize = 1000,
-%% msgFlags = snmp_misc:mk_msg_flags(PduType, SecLevel),
-%% msgSecurityModel = ?SEC_USM},
-%% Message = #message{version = 'version-3', vsn_hdr = V3Hdr,
-%% data = ScopedPDUBytes},
-%% SecEngineID = case PduType of
-%% 'get-response' -> snmp_framework_mib:get_engine_id();
-%% _ -> EngineID
-%% end,
-%% case catch snmp_usm:generate_outgoing_msg(Message, SecEngineID,
-%% SecName, SecData, SecLevel) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% {error, Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% Packet ->
-%% Packet
-%% end;
-%% mk_msg(Version, Pdu, {Com, _User, _EngineID, _Ctx, _SecLevel}, _SecData) ->
-%% Msg = #message{version = Version, vsn_hdr = Com, data = Pdu},
-%% case catch snmp_pdus:enc_message(Msg) of
-%% {'EXIT', Reason} ->
-%% error("Encoding error. Pdu: ~w. Reason: ~w",[Pdu, Reason]),
-%% error;
-%% B when list(B) ->
-%% B
-%% end.
-
-
-%% handle_system_info_updated(#state{log = {Log, _OldType}} = State,
-%% audit_trail_log_type = _What) ->
-%% %% Just to make sure, check that ATL is actually enabled
-%% case snmpm_config:system_info(audit_trail_log) of
-%% {ok, true} ->
-%% {ok, Type} = snmpm_config:system_info(audit_trail_log_type),
-%% NewState = State#state{log = {Log, Type}},
-%% {NewState, ok};
-%% _ ->
-%% {State, {error, {adt_not_enabled}}}
-%% end;
-%% handle_system_info_updated(_State, _What) ->
-%% ok.
-
-handle_get_log_type(#state{log = {_Log, Value}} = State) ->
- %% Just to make sure, check that ATL is actually enabled
- case snmpm_config:system_info(audit_trail_log) of
- {ok, true} ->
- Type =
- case {lists:member(read, Value), lists:member(write, Value)} of
- {true, true} ->
- read_write;
- {true, false} ->
- read;
- {false, true} ->
- write;
- {false, false} ->
- throw({State, {error, {bad_atl_type, Value}}})
- end,
- {ok, Type};
- _ ->
- {error, not_enabled}
- end;
-handle_get_log_type(_State) ->
- {error, not_enabled}.
-
-handle_set_log_type(#state{log = {Log, OldValue}} = State, NewType) ->
- %% Just to make sure, check that ATL is actually enabled
- case snmpm_config:system_info(audit_trail_log) of
- {ok, true} ->
- NewValue =
- case NewType of
- read ->
- [read];
- write ->
- [write];
- read_write ->
- [read,write];
- _ ->
- throw({State, {error, {bad_atl_type, NewType}}})
- end,
- NewState = State#state{log = {Log, NewValue}},
- OldType =
- case {lists:member(read, OldValue),
- lists:member(write, OldValue)} of
- {true, true} ->
- read_write;
- {true, false} ->
- read;
- {false, true} ->
- write;
- {false, false} ->
- throw({State, {error, {bad_atl_type, OldValue}}})
- end,
- {NewState, {ok, OldType}};
- _ ->
- {State, {error, not_enabled}}
- end;
-handle_set_log_type(State, _NewType) ->
- {State, {error, not_enabled}}.
-
-
-select_transport_from_domain(Domain, Transports) when is_atom(Domain) ->
- Pos = #transport.domain,
- case lists:keyfind(Domain, Pos, Transports) of
- #transport{domain = Domain} = Transport ->
- Transport;
- false when Domain == snmpUDPDomain ->
- lists:keyfind(transportDomainUdpIpv4, Pos, Transports);
- false when Domain == transportDomainUdpIpv4 ->
- lists:keyfind(snmpUDPDomain, Pos, Transports);
- false ->
- false
- end.
-
-%% If the manager uses legacy snmpUDPDomain e.g has not set
-%% {domain, _}, then make sure snmpm_network_interface_filter
-%% gets legacy arguments to not break backwards compatibility.
-%%
-fix_filter_address(Transports, Address) ->
- DefaultDomain = snmpm_config:default_transport_domain(),
- case Transports of
- [#transport{domain = DefaultDomain}, DefaultDomain] ->
- case Address of
- {Domain, Addr} when is_atom(Domain) ->
- Addr;
- {_, IpPort} = Addr when is_integer(IpPort) ->
- Addr
- end;
- _ ->
- Address
- end.
-
-address(Domain, Addr) when is_atom(Domain) ->
- {Domain, Addr};
-address(Ip, Port) when is_integer(Port) ->
- {snmpm_config:default_transport_domain(), {Ip, Port}}.
-
-format_address(Address) ->
- iolist_to_binary(snmp_conf:mk_addr_string(Address)).
-
-%% -------------------------------------------------------------------
-
-worker(Worker, Failer, State) ->
- Verbosity = get(verbosity),
- spawn_opt(
- fun () ->
- try
- put(sname, mnifw),
- put(verbosity, Verbosity),
- Worker(worker_init(State))
- of
- Result ->
- %% Winds up in handle_info {'DOWN', ...}
- erlang:exit({net_if_worker, Result})
- catch
- Class:Reason ->
- %% Winds up in handle_info {'DOWN', ...}
- erlang:exit(
- {net_if_worker, Failer,
- Class, Reason, erlang:get_stacktrace()})
- end
- end,
- [monitor]).
-
-worker_init(#state{log = undefined} = State) ->
- State;
-worker_init(#state{log = {Name, Log, Type}} = State) ->
- case snmp_log:open(Name, Log) of
- {ok, NewLog} ->
- State#state{log = {Name, NewLog, Type}};
- {error, Reason} ->
- warning_msg("NetIf worker ~p failed opening ATL: "
- "~n ~p", [self(), Reason]),
- State#state{log = {Name, undefined, Type}}
- end;
-worker_init(State) ->
- ?vinfo("worker_init -> entry with invalid data: "
- "~n State: ~p", [State]),
- erlang:error({worker_init, State}).
-
-%% -------------------------------------------------------------------
-
-make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) ->
- #pdu{type = 'get-response',
- request_id = ReqId,
- error_status = noError,
- error_index = 0,
- varbinds = Vbs}.
-
-
-%% ----------------------------------------------------------------
-
-pdu_type_of(#pdu{type = Type}) ->
- Type;
-pdu_type_of(TrapPdu) when is_record(TrapPdu, trappdu) ->
- trap.
-
-
-%% -------------------------------------------------------------------
-
-%% At this point this function is used during testing
-maybe_process_extra_info(?DEFAULT_EXTRA_INFO) ->
- ok;
-maybe_process_extra_info({?SNMPM_EXTRA_INFO_TAG, Fun})
- when is_function(Fun, 0) ->
- (catch Fun()),
- ok;
-maybe_process_extra_info(_ExtraInfo) ->
- ok.
-
-
-%% -------------------------------------------------------------------
-
-t() ->
- {A,B,C} = erlang:now(),
- A*1000000000+B*1000+(C div 1000).
-
-
-%% -------------------------------------------------------------------
-
-logger(undefined, _Type, _Domain, _Addr) ->
- fun(_) ->
- ok
- end;
-logger({_Name, Log, Types}, Type, Domain, Addr) ->
- case lists:member(Type, Types) of
- true ->
- AddrString =
- iolist_to_binary(snmp_conf:mk_addr_string({Domain, Addr})),
- fun(Msg) ->
- snmp_log:log(Log, Msg, AddrString)
- end;
- false ->
- fun(_) ->
- ok
- end
- end.
-
-
-%% -------------------------------------------------------------------
-
-%% info_msg(F, A) ->
-%% ?snmpm_info("NET-IF server: " ++ F, A).
-
-warning_msg(F, A) ->
- ?snmpm_warning("NET-IF server: " ++ F, A).
-
-error_msg(F, A) ->
- ?snmpm_error("NET-IF server: " ++ F, A).
-
-
-
-%%%-------------------------------------------------------------------
-
-% get_opt(Key, Opts) ->
-% ?vtrace("get option ~w", [Key]),
-% snmp_misc:get_option(Key, Opts).
-
-get_opt(Opts, Key, Def) ->
- ?vtrace("get option ~w with default ~p", [Key, Def]),
- snmp_misc:get_option(Key, Opts, Def).
-
-
-%% -------------------------------------------------------------------
-
-get_info(#state{transports = Transports}) ->
- ProcSize = proc_mem(self()),
- [{process_memory, ProcSize}
- | [{port_info, get_port_info(Socket)}
- || #transport{socket = Socket} <- Transports]].
-
-proc_mem(P) when is_pid(P) ->
- case (catch erlang:process_info(P, memory)) of
- {memory, Sz} when is_integer(Sz) ->
- Sz;
- _ ->
- undefined
- end.
-%% proc_mem(_) ->
-%% undefined.
-
-
-get_port_info(Id) ->
- PortInfo =
- case (catch erlang:port_info(Id)) of
- PI when is_list(PI) ->
- [{port_info, PI}];
- _ ->
- []
- end,
- PortStatus =
- case (catch prim_inet:getstatus(Id)) of
- {ok, PS} ->
- [{port_status, PS}];
- _ ->
- []
- end,
- PortAct =
- case (catch inet:getopts(Id, [active])) of
- {ok, PA} ->
- [{port_act, PA}];
- _ ->
- []
- end,
- PortStats =
- case (catch inet:getstat(Id)) of
- {ok, Stat} ->
- [{port_stats, Stat}];
- _ ->
- []
- end,
- IfList =
- case (catch inet:getif(Id)) of
- {ok, IFs} ->
- [{interfaces, IFs}];
- _ ->
- []
- end,
- BufSz =
- case (catch inet:getopts(Id, [recbuf, sndbuf, buffer])) of
- {ok, Sz} ->
- [{buffer_size, Sz}];
- _ ->
- []
- end,
- [{socket, Id}] ++
- IfList ++
- PortStats ++
- PortInfo ++
- PortStatus ++
- PortAct ++
- BufSz.
-
-
-%%-----------------------------------------------------------------
-%% Counter functions
-%%-----------------------------------------------------------------
-init_counters() ->
- F = fun(Counter) -> maybe_create_counter(Counter) end,
- lists:map(F, counters()).
-
-reset_counters() ->
- F = fun(Counter) -> snmpm_config:reset_stats_counter(Counter) end,
- lists:map(F, counters()).
-
-maybe_create_counter(Counter) ->
- snmpm_config:maybe_cre_stats_counter(Counter, 0).
-
-counters() ->
- [
- netIfMsgOutDrops,
- netIfMsgInDrops,
- netIfPduOutDrops,
- netIfPduInDrops
- ].
-
-inc(Name) -> inc(Name, 1).
-inc(Name, N) -> snmpm_config:incr_stats_counter(Name, N).
-
-%% get_counters() ->
-%% Counters = counters(),
-%% get_counters(Counters, []).
-
-%% get_counters([], Acc) ->
-%% lists:reverse(Acc);
-%% get_counters([Counter|Counters], Acc) ->
-%% case snmpm_config:get_stats_counter(Counter) of
-%% {ok, CounterVal} ->
-%% get_counters(Counters, [{Counter, CounterVal}|Acc]);
-%% _ ->
-%% get_counters(Counters, Acc)
-%% end.
-
-
-%% ----------------------------------------------------------------
-
-call(Pid, Req) ->
- call(Pid, Req, infinity).
-
-call(Pid, Req, Timeout) ->
- gen_server:call(Pid, Req, Timeout).
-
-cast(Pid, Msg) ->
- gen_server:cast(Pid, Msg).
+-define(snmpm_net_if_mt, true).
+-module(snmpm_net_if_mt).
+-include("snmpm_net_if.erl").