aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp/src')
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl34
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl48
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl38
-rw-r--r--lib/snmp/src/app/snmp.appup.src2
-rw-r--r--lib/snmp/src/manager/depend.mk5
-rw-r--r--lib/snmp/src/manager/snmpm_conf.erl8
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl460
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl681
-rw-r--r--lib/snmp/src/manager/snmpm_net_if_mt.erl1308
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl11
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl8
-rw-r--r--lib/snmp/src/misc/snmp_config.erl46
12 files changed, 718 insertions, 1931 deletions
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index 9d3f7ef5e7..6ff9224d34 100644
--- a/lib/snmp/src/agent/snmp_framework_mib.erl
+++ b/lib/snmp/src/agent/snmp_framework_mib.erl
@@ -207,22 +207,28 @@ check_agent({intAgentIpAddress = Tag, Ip} = Entry, {Domain, Port} = State) ->
[{Tag, FixedIp},
{intAgentTransports, [{Domain, {FixedIp, Port}}]}]
end, State};
-check_agent({intAgentTransports = Tag, Transports}, {_, Port} = State) ->
+check_agent({intAgentTransports = Tag, Transports}, {_, Port} = State)
+ when is_list(Transports) ->
CheckedTransports =
- [case
- case Port of
- undefined ->
- snmp_conf:check_address(Domain, Address);
- _ ->
- snmp_conf:check_address(Domain, Address, Port)
- end
- of
- ok ->
- Transport;
- {ok, FixedAddress} ->
- {Domain, FixedAddress}
+ [case Transport of
+ {Domain, Address} ->
+ case
+ case Port of
+ undefined ->
+ snmp_conf:check_address(Domain, Address);
+ _ ->
+ snmp_conf:check_address(Domain, Address, Port)
+ end
+ of
+ ok ->
+ Transport;
+ {ok, FixedAddress} ->
+ {Domain, FixedAddress}
+ end;
+ _ ->
+ error({bad_transport, Transport})
end
- || {Domain, Address} = Transport <- Transports],
+ || Transport <- Transports],
{{ok, {Tag, CheckedTransports}}, State};
check_agent(Entry, State) ->
{check_agent(Entry), State}.
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index e916f17d6a..ef9503cda8 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -182,6 +182,10 @@ check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId, TMask, MMS);
check_target_addr(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params,
+ _EngineId, _TMask, _MMS}) -> % Arity 10
+ error({bad_address, {Domain, Address}});
+check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId}) % Arity 8
when is_atom(Domain) ->
@@ -197,6 +201,10 @@ check_target_addr(
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params,
EngineId);
+check_target_addr(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params,
+ _EngineId}) ->% Arity 8
+ error({bad_address, {Domain, Address}});
%% Use dummy engine id if the old style is found
check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params}) % Arity 7
@@ -210,6 +218,9 @@ check_target_addr(
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params);
+check_target_addr(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params}) -> % Arity 7
+ error({bad_address, {Domain, Address}});
%% Use dummy engine id if the old style is found
check_target_addr(
{Name, Domain, Address, Timeout, RetryCount, TagList, Params,
@@ -225,6 +236,10 @@ check_target_addr(
Address = {Ip, Udp},
check_target_addr(
Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
+check_target_addr(
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList, _Params,
+ _TMask, _MMS}) -> % Arity 9
+ error({bad_address, {Domain, Address}});
check_target_addr(X) ->
error({invalid_target_addr, X}).
@@ -291,7 +306,7 @@ check_engine_id(EngineId) ->
snmp_conf:check_string(EngineId).
check_address(Domain, Address) ->
- case snmp_conf:check_address(Domain, Address) of
+ case snmp_conf:check_address(Domain, Address, 162) of
ok ->
Address;
{ok, NAddress} ->
@@ -301,7 +316,11 @@ check_address(Domain, Address) ->
check_mask(_Domain, [] = Mask) ->
Mask;
check_mask(Domain, Mask) ->
- try check_address(Domain, Mask)
+ try snmp_conf:check_address(Domain, Mask) of
+ ok ->
+ Mask;
+ {ok, NMask} ->
+ NMask
catch
{error, {bad_address, Info}} ->
error({bad_mask, Info})
@@ -365,16 +384,21 @@ table_del_row(Tab, Key) ->
snmpa_mib_lib:table_del_row(db(Tab), Key).
-add_addr(Name, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS) ->
- Domain = default_domain(),
- add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS).
-
-add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS) ->
- Addr = {Name, Domain, Ip, Port, Timeout, Retry, TagList,
- Params, EngineId, TMask, MMS},
+add_addr(
+ Name, Domain_or_Ip, Addr_or_Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS) ->
+ add_addr(
+ {Name, Domain_or_Ip, Addr_or_Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS}).
+%%
+add_addr(
+ Name, Domain, Ip, Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS) ->
+ add_addr(
+ {Name, Domain, Ip, Port, Timeout, Retry, TagList, Params,
+ EngineId, TMask, MMS}).
+%%
+add_addr(Addr) ->
case (catch check_target_addr(Addr)) of
{ok, Row} ->
Key = element(1, Row),
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index b4d32dc928..534d0e447b 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -47,7 +47,7 @@
read_standard_config/1,
%% target_addr.conf
- target_addr_entry/5, target_addr_entry/6,
+ target_addr_entry/5, target_addr_entry/6, target_addr_entry/7,
target_addr_entry/8, target_addr_entry/10, target_addr_entry/11,
write_target_addr_config/2, write_target_addr_config/3,
append_target_addr_config/2,
@@ -386,6 +386,12 @@ target_addr_entry(
target_addr_entry(Name, Ip, TagList, ParamsName, EngineId, []).
target_addr_entry(
+ Name, Domain, Addr, TagList,
+ ParamsName, EngineId) when is_atom(Domain) ->
+ target_addr_entry(
+ Name, Domain, Addr, TagList,
+ ParamsName, EngineId, []);
+target_addr_entry(
Name, Ip, TagList, ParamsName,
EngineId, TMask) ->
target_addr_entry(
@@ -394,6 +400,13 @@ target_addr_entry(
target_addr_entry(
Name, Domain_or_Ip, Addr_or_Port, TagList,
+ ParamsName, EngineId, TMask) ->
+ target_addr_entry(
+ Name, Domain_or_Ip, Addr_or_Port, TagList,
+ ParamsName, EngineId, TMask, 2048).
+
+target_addr_entry(
+ Name, Domain_or_Ip, Addr_or_Port, TagList,
ParamsName, EngineId, TMask, MaxMessageSize) ->
target_addr_entry(
Name, Domain_or_Ip, Addr_or_Port, 1500, 3, TagList,
@@ -475,6 +488,16 @@ write_target_addr_conf(Fd, Conf) ->
do_write_target_addr_conf(
Fd,
+ {Name, Domain, Address, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize})
+ when is_atom(Domain) ->
+ io:format(
+ Fd,
+ "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
+ [Name, Domain, Address, Timeout, RetryCount, TagList,
+ ParamsName, EngineId, TMask, MaxMessageSize]);
+do_write_target_addr_conf(
+ Fd,
{Name, Ip, Udp, Timeout, RetryCount, TagList,
ParamsName, EngineId, TMask, MaxMessageSize})
when is_integer(Udp) ->
@@ -485,15 +508,10 @@ do_write_target_addr_conf(
{Name, Domain, Address, Timeout, RetryCount, TagList,
ParamsName, EngineId, TMask, MaxMessageSize});
do_write_target_addr_conf(
- Fd,
- {Name, Domain, Address, Timeout, RetryCount, TagList,
- ParamsName, EngineId, TMask, MaxMessageSize})
- when is_atom(Domain) ->
- io:format(
- Fd,
- "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n",
- [Name, Domain, Address, Timeout, RetryCount, TagList,
- ParamsName, EngineId, TMask, MaxMessageSize]);
+ _Fd,
+ {_Name, Domain, Address, _Timeout, _RetryCount, _TagList,
+ _ParamsName, _EngineId, _TMask, _MaxMessageSize}) ->
+ error({bad_address, {Domain, Address}});
do_write_target_addr_conf(
Fd,
{Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index ae79e3c1d1..1cc1a17b1d 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -28,6 +28,7 @@
%% {update, snmpa_local_db, soft, soft_purge, soft_purge, []}
%% {add_module, snmpm_net_if_mt}
[
+ {"5.0", [{restart_application, snmp}]},
{"4.25.1", [{restart_application, snmp}]},
{"4.25.0.1", [{restart_application, snmp}]},
{"4.25", [{restart_application, snmp}]},
@@ -42,6 +43,7 @@
%% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
[
+ {"5.0", [{restart_application, snmp}]},
{"4.25.1", [{restart_application, snmp}]},
{"4.25.0.1", [{restart_application, snmp}]},
{"4.25", [{restart_application, snmp}]},
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_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl
index 888f19aec6..087ef6c6ea 100644
--- a/lib/snmp/src/manager/snmpm_conf.erl
+++ b/lib/snmp/src/manager/snmpm_conf.erl
@@ -114,6 +114,7 @@ do_write_manager_conf(Fd, {Tag, Val})
when Tag =:= domain;
Tag =:= address;
Tag =:= port;
+ Tag =:= transports;
Tag =:= max_message_size ->
io:format(Fd, "{~w, ~w}.~n", [Tag, Val]);
do_write_manager_conf(Fd, {Tag, Val})
@@ -199,9 +200,10 @@ do_write_users_conf(_Fd, Crap) ->
%% ------ agents.conf ------
%%
-agents_entry(UserId, TargetName, Comm, Ip, Port, EngineID, Timeout,
- MaxMessageSize, Version, SecModel, SecName, SecLevel) ->
- {UserId, TargetName, Comm, Ip, Port, EngineID, Timeout,
+agents_entry(
+ UserId, TargetName, Comm, Domain_or_Ip, Addr_or_Port, EngineID, Timeout,
+ MaxMessageSize, Version, SecModel, SecName, SecLevel) ->
+ {UserId, TargetName, Comm, Domain_or_Ip, Addr_or_Port, EngineID, Timeout,
MaxMessageSize, Version, SecModel, SecName, SecLevel}.
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index 013fefa4e2..5cab81baf6 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -442,8 +442,31 @@ agent_info(TargetName, all) ->
All ->
{ok, [{Item, Val} || {{_, Item}, Val} <- All]}
end;
+%% Begin backwards compatibility
+agent_info(TargetName, address) ->
+ case agent_info({TargetName, taddress}) of
+ {ok, Val} ->
+ {Addr, _} = Val,
+ {ok, Addr};
+ _ ->
+ %% This should be redundant since 'taddress' should exist
+ agent_info({TargetName, address})
+ end;
+agent_info(TargetName, port) ->
+ case agent_info({TargetName, taddress}) of
+ {ok, Val} ->
+ {_, Port} = Val,
+ {ok, Port};
+ _ ->
+ %% This should be redundant since 'taddress' should exist
+ agent_info({TargetName, port})
+ end;
+%% End backwards compatibility
agent_info(TargetName, Item) ->
- case ets:lookup(snmpm_agent_table, {TargetName, Item}) of
+ agent_info({TargetName, Item}).
+
+agent_info(Key) ->
+ case ets:lookup(snmpm_agent_table, Key) of
[{_, Val}] ->
{ok, Val};
[] ->
@@ -456,29 +479,29 @@ agent_info(Domain, Address, Item) when is_atom(Domain) ->
do_agent_info(Domain, NAddress, Item)
catch
_Thrown ->
- p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n"
- " ~p",
- [Domain, Address, Item, _Thrown, erlang:get_stacktrace()]),
+ %% p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n"
+ %% " ~p",
+ %% [Domain, Address, Item, _Thrown, erlang:get_stacktrace()]),
{error, not_found}
end;
-agent_info(Ip, Port, Item) ->
- p(?MODULE_STRING":agent_info(~p, ~p, ~p) entry~n",
- [Ip, Port, Item]),
+agent_info(Ip, Port, Item) when is_integer(Port) ->
+ %% p(?MODULE_STRING":agent_info(~p, ~p, ~p) entry~n",
+ %% [Ip, Port, Item]),
Domain = default_transport_domain(),
try fix_address(Domain, {Ip, Port}) of
Address ->
do_agent_info(Domain, Address, Item)
catch
_Thrown ->
- p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n"
- " ~p",
- [Ip, Port, Item, _Thrown, erlang:get_stacktrace()]),
+ %% p(?MODULE_STRING":agent_info(~p, ~p, ~p) throwed ~p at.~n"
+ %% " ~p",
+ %% [Ip, Port, Item, _Thrown, erlang:get_stacktrace()]),
{error, not_found}
end.
do_agent_info(Domain, Address, target_name = Item) ->
- p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n",
- [Domain, Address, Item]),
+ %% p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n",
+ %% [Domain, Address, Item]),
case ets:lookup(snmpm_agent_table, {Domain, Address, Item}) of
[{_, Val}] ->
{ok, Val};
@@ -486,8 +509,8 @@ do_agent_info(Domain, Address, target_name = Item) ->
{error, not_found}
end;
do_agent_info(Domain, Address, Item) ->
- p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n",
- [Domain, Address, Item]),
+ %% p(?MODULE_STRING":do_agent_info(~p, ~p, ~p) entry~n",
+ %% [Domain, Address, Item]),
case do_agent_info(Domain, Address, target_name) of
{ok, TargetName} ->
agent_info(TargetName, Item);
@@ -1287,36 +1310,6 @@ verify_options(Opts, Mandatory) ->
verify_mandatory_options(Opts, Mandatory),
verify_options(Opts).
-%% mandatory() -> [mand()]
-%% mand() -> atom() | {atom, [atom()]}
-verify_mandatory_options(_Opts, []) ->
- ok;
-verify_mandatory_options(Opts, [Mand|Mands]) ->
- verify_mandatory_option(Opts, Mand),
- verify_mandatory_options(Opts, Mands).
-
-verify_mandatory_option(Opts, {Mand, MandSubOpts}) ->
- ?d("verify_mandatory_option -> entry with"
- "~n Mand: ~p"
- "~n MandSubObjs: ~p", [Mand, MandSubOpts]),
- case lists:keysearch(Mand, 1, Opts) of
- {value, {Mand, SubOpts}} ->
- verify_mandatory_options(SubOpts, MandSubOpts);
- false ->
- ?d("missing mandatory option: ~w [~p]", [Mand, MandSubOpts]),
- error({missing_mandatory, Mand, MandSubOpts})
- end;
-verify_mandatory_option(Opts, Mand) ->
- ?d("verify_mandatory_option -> entry with"
- "~n Mand: ~p", [Mand]),
- case lists:keymember(Mand, 1, Opts) of
- true ->
- ok;
- false ->
- ?d("missing mandatory option: ~w", [Mand]),
- error({missing_mandatory, Mand})
- end.
-
verify_options([]) ->
?d("verify_options -> done", []),
ok;
@@ -1632,7 +1625,38 @@ verify_verbosity(Verbosity) ->
_ ->
error({invalid_verbosity, Verbosity})
end.
+
+%% mandatory() -> [mand()]
+%% mand() -> atom() | {atom, [atom()]}
+verify_mandatory_options(_Opts, []) ->
+ ok;
+verify_mandatory_options(Opts, [Mand|Mands]) ->
+ verify_mandatory_option(Opts, Mand),
+ verify_mandatory_options(Opts, Mands).
+
+verify_mandatory_option(Opts, {Mand, MandSubOpts}) ->
+ ?d("verify_mandatory_option -> entry with"
+ "~n Mand: ~p"
+ "~n MandSubObjs: ~p", [Mand, MandSubOpts]),
+ case lists:keysearch(Mand, 1, Opts) of
+ {value, {Mand, SubOpts}} ->
+ verify_mandatory_options(SubOpts, MandSubOpts);
+ false ->
+ ?d("missing mandatory option: ~w [~p]", [Mand, MandSubOpts]),
+ error({missing_mandatory, Mand, MandSubOpts})
+ end;
+verify_mandatory_option(Opts, Mand) ->
+ ?d("verify_mandatory_option -> entry with"
+ "~n Mand: ~p", [Mand]),
+ case lists:keymember(Mand, 1, Opts) of
+ true ->
+ ok;
+ false ->
+ ?d("missing mandatory option: ~w", [Mand]),
+ error({missing_mandatory, Mand})
+ end.
+
%% ------------------------------------------------------------------------
init_manager_config([]) ->
@@ -1654,69 +1678,10 @@ init_agent_default() ->
{version, v2}, % MPModel
{sec_model, v2c}, % SecModel
{sec_name, "initial"}, % SecName
- {sec_level, noAuthPriv}, % SecLevel
+ {sec_level, noAuthNoPriv}, % SecLevel
{community, "all-rights"}], % Community
do_update_agent_info(default_agent, AgentDefaultConfig).
-%% %% Port
-%% init_agent_default(port, ?DEFAULT_AGENT_PORT),
-
-%% %% Timeout
-%% init_agent_default(timeout, 10000),
-
-%% %% Max message (packet) size
-%% init_agent_default(max_message_size, 484),
-
-%% %% MPModel
-%% init_agent_default(version, v2),
-
-%% %% SecModel
-%% init_agent_default(sec_model, v2c),
-
-%% %% SecName
-%% init_agent_default(sec_name, "initial"),
-
-%% %% SecLevel
-%% init_agent_default(sec_level, noAuthNoPriv),
-
-%% %% Community
-%% init_agent_default(community, "all-rights"),
-%% ok.
-
-
-%% init_agent_default(Item, Val) when Item =/= user_id ->
-%% case do_update_agent_info(default_agent, Item, Val) of
-%% ok ->
-%% ok;
-%% {error, Reason} ->
-%% error(Reason)
-%% end.
-
-%% read_agents_config_file(Dir) ->
-%% Verify = fun check_agent_config2/1,
-%% case read_file(Dir, "agents.conf", Verify, []) of
-%% {ok, Conf} ->
-%% Conf;
-%% Error ->
-%% ?vlog("agent config error: ~p", [Error]),
-%% throw(Error)
-%% end.
-
-%% check_agent_config2(Agent) ->
-%% case (catch check_agent_config(Agent)) of
-%% {ok, {UserId, TargetName, Conf, Version}} ->
-%% {ok, Vsns} = system_info(versions),
-%% case lists:member(Version, Vsns) of
-%% true ->
-%% {ok, {UserId, TargetName, Conf}};
-%% false ->
-%% error({version_not_supported_by_manager,
-%% Version, Vsns})
-%% end;
-%% Err ->
-%% throw(Err)
-%% end.
-
read_agents_config_file(Dir) ->
Order = fun snmp_conf:no_order/2,
Check = fun check_agent_config/2,
@@ -1739,21 +1704,35 @@ check_agent_config(Agent, State) ->
%% For backward compatibility
check_agent_config(
+ {UserId, TargetName, Community, Domain, Addr,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) when is_atom(Domain) ->
+ check_agent_config(
+ UserId, TargetName, Community, Domain, Addr,
+ EngineId, Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel);
+check_agent_config(
{UserId, TargetName, Community, Ip, Port,
EngineId, Timeout, MaxMessageSize,
- Version, SecModel, SecName, SecLevel}) ->
+ Version, SecModel, SecName, SecLevel}) when is_integer(Port) ->
Domain = default_transport_domain(),
- Addr = fix_address(Domain, {Ip, Port}),
+ Addr = {Ip, Port},
check_agent_config(
UserId, TargetName, Community, Domain, Addr,
EngineId, Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel);
check_agent_config(
+ {_UserId, _TargetName, _Community, Domain, Addr,
+ _EngineId, _Timeout, _MaxMessageSize,
+ _Version, _SecModel, _SecName, _SecLevel}) ->
+ error({bad_address, {Domain, Addr}});
+check_agent_config(
{UserId, TargetName, Community, Domain, Ip, Port,
EngineId, Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel}) ->
+ Addr = {Ip, Port},
check_agent_config(
- UserId, TargetName, Community, Domain, {Ip, Port},
+ UserId, TargetName, Community, Domain, Addr,
EngineId, Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel);
check_agent_config(Agent) ->
@@ -1776,7 +1755,7 @@ check_agent_config(
Conf =
[{reg_type, target_name},
{tdomain, Domain},
- {taddress, Addr},
+ {taddress, fix_address(Domain, Addr)},
{community, Comm},
{engine_id, EngineId},
{timeout, Timeout},
@@ -1860,7 +1839,11 @@ verify_agent_config(
{TD, VerifiedConf};
_ ->
%% Insert tdomain since it is missing
- TD = default_transport_domain(),
+ %% Note: not default_transport_domain() since
+ %% taddress is the new format hence the application
+ %% should be tdomain aware and therefore addresses
+ %% on the Domain, Addr format should be used and understood.
+ TD = transportDomainUdpIpv4,
{TD, [{tdomain, TD}|VerifiedConf]}
end,
case snmp_conf:check_address(TDomain, Address, 0) of
@@ -1946,16 +1929,6 @@ verify_agent_entry(Item, _) ->
-%% read_users_config_file(Dir) ->
-%% Verify = fun check_user_config/1,
-%% case read_file(Dir, "users.conf", Verify, []) of
-%% {ok, Conf} ->
-%% Conf;
-%% Error ->
-%% ?vlog("failure reading users config file: ~n ~p", [Error]),
-%% throw(Error)
-%% end.
-
read_users_config_file(Dir) ->
Order = fun snmp_conf:no_order/2,
Check = fun (User, State) -> {check_user_config(User), State} end,
@@ -2074,14 +2047,6 @@ verify_default_agent_config(Conf) ->
error({bad_default_agent_config, Error})
end.
-%% read_usm_config_file(Dir) ->
-%% Verify = fun check_usm_user_config/1,
-%% case read_file(Dir, "usm.conf", Verify, []) of
-%% {ok, Conf} ->
-%% Conf;
-%% Error ->
-%% throw(Error)
-%% end.
read_usm_config_file(Dir) ->
Order = fun snmp_conf:no_order/2,
@@ -2268,24 +2233,6 @@ is_crypto_supported(Func) ->
snmp_misc:is_crypto_supported(Func).
-%% read_manager_config_file(Dir) ->
-%% Verify = fun check_manager_config/1,
-%% case read_file(Dir, "manager.conf", Verify) of
-%% {ok, Conf} ->
-%% ?d("read_manager_config_file -> ok: "
-%% "~n Conf: ~p", [Conf]),
-%% %% If the address is not specified, then we assume
-%% %% it should be the local host.
-%% %% If the address is not possible to determine
-%% %% that way, then we give up...
-%% verify_mandatory(Conf, [port,engine_id,max_message_size]),
-%% ensure_config(default_manager_config(), Conf);
-%% %% check_mandatory_manager_config(Conf),
-%% %% ensure_manager_config(Conf);
-%% Error ->
-%% throw(Error)
-%% end.
-
read_manager_config_file(Dir) ->
Order = fun order_manager_config/2,
Check = fun check_manager_config/2,
@@ -2296,13 +2243,15 @@ read_manager_config_file(Dir) ->
%% it should be the local host.
%% If the address is not possible to determine
%% that way, then we give up...
- verify_mandatory(Conf, [port,engine_id,max_message_size]),
+ verify_someof(Conf, [port, transports]),
+ verify_mandatory(Conf, [engine_id, max_message_size]),
default_manager_config(Conf).
default_manager_config(Conf) ->
- %% Ensure address of right family
- case lists:keyfind(address, 1, Conf) of
+ %% Ensure valid transports entry
+ case lists:keyfind(transports, 1, Conf) of
false ->
+ {port, Port} = lists:keyfind(port, 1, Conf),
Domain =
case lists:keyfind(domain, 1, Conf) of
false ->
@@ -2311,55 +2260,77 @@ default_manager_config(Conf) ->
D
end,
Family = snmp_conf:tdomain_to_family(Domain),
- {ok, HostName} = inet:gethostname(),
- case inet:getaddr(HostName, Family) of
+ {ok, Hostname} = inet:gethostname(),
+ case inet:getaddr(Hostname, Family) of
{ok, Address} ->
- [{address, Address} | Conf];
+ lists:sort(
+ fun order_manager_config/2,
+ [{transports, [{Domain, {Address, Port}}]} | Conf]);
{error, _Reason} ->
?d("default_manager_config -> "
"failed getting ~w address for ~s:~n"
- " _Reason: ~p", [Family, HostName, _Reason]),
+ " _Reason: ~p", [Family, Hostname, _Reason]),
Conf
end;
_ ->
Conf
end.
-default_manager_config() ->
- {ok, HostName} = inet:gethostname(),
- case inet:getaddr(HostName, inet) of
- {ok, A} ->
- [{address, tuple_to_list(A)}];
- {error, _Reason} ->
- ?d("default_manager_config -> failed getting address: "
- "~n _Reason: ~p", [_Reason]),
- []
- end.
-
order_manager_config(EntryA, EntryB) ->
- snmp_conf:keyorder(1, EntryA, EntryB, [domain]).
-
-check_manager_config({domain, D}, _Domain) ->
- {snmp_conf:check_domain(D), D};
-check_manager_config({address = Tag, Ip}, D) ->
- Domain =
- case D of
- undefined ->
- default_transport_domain();
- _ ->
- D
- end,
+ snmp_conf:keyorder(1, EntryA, EntryB, [domain, port]).
+
+check_manager_config(Entry, undefined) ->
+ check_manager_config(Entry, {default_transport_domain(), undefined});
+check_manager_config({domain, Domain}, {_, Port}) ->
+ {snmp_conf:check_domain(Domain), {Domain, Port}};
+check_manager_config({port, Port}, {Domain, _}) ->
+ {ok = snmp_conf:check_port(Port), {Domain, Port}};
+check_manager_config({address, _}, {_, undefined}) ->
+ error({missing_mandatory, port});
+check_manager_config({address = Tag, Ip} = Entry, {Domain, Port} = State) ->
{case snmp_conf:check_ip(Domain, Ip) of
ok ->
- ok;
+ [Entry,
+ {transports, [{Domain, {Ip, Port}}]}];
{ok, FixedIp} ->
- {ok, {Tag, FixedIp}}
- end, Domain};
-check_manager_config(Entry, Domain) ->
- {check_manager_config(Entry), Domain}.
+ [{Tag, FixedIp},
+ {transports, [{Domain, {FixedIp, Port}}]}]
+ end, State};
+check_manager_config({transports = Tag, Transports}, {_, Port} = State)
+ when is_list(Transports) ->
+ CheckedTransports =
+ [case Transport of
+ {Domain, Address} ->
+ case
+ case Port of
+ undefined ->
+ snmp_conf:check_address(Domain, Address);
+ _ ->
+ snmp_conf:check_address(Domain, Address, Port)
+ end
+ of
+ ok ->
+ Transport;
+ {ok, FixedAddress} ->
+ {Domain, FixedAddress}
+ end;
+ _Domain when Port =:= undefined->
+ error({missing_mandatory, port});
+ Domain ->
+ Family = snmp_conf:tdomain_to_family(Domain),
+ {ok, Hostname} = inet:gethostname(),
+ case inet:getaddr(Hostname, Family) of
+ {ok, IpAddr} ->
+ {Domain, {IpAddr, Port}};
+ {error, _} ->
+ error({bad_address, {Domain, Hostname}})
+ end
+ end
+ || Transport <- Transports],
+ {{ok, {Tag, CheckedTransports}}, State};
+check_manager_config(Entry, State) ->
+ {check_manager_config(Entry), State}.
-check_manager_config({port, Port}) ->
- snmp_conf:check_port(Port);
check_manager_config({engine_id, EngineID}) ->
snmp_conf:check_string(EngineID);
check_manager_config({max_message_size, Max}) ->
@@ -2368,45 +2339,6 @@ check_manager_config(Conf) ->
error({unknown_config, Conf}).
-%% check_mandatory_manager_config(Conf) ->
-%% Mand = [port, engine_id, max_message_size],
-%% check_mandatory_manager_config(Mand, Conf).
-
-%% check_mandatory_manager_config([], _Conf) ->
-%% ok;
-%% check_mandatory_manager_config([Item|Mand], Conf) ->
-%% case lists:keysearch(Item, 1, Conf) of
-%% false ->
-%% error({missing_mandatory_manager_config, Item});
-%% _ ->
-%% check_mandatory_manager_config(Mand, Conf)
-%% end.
-
-
-%% ensure_manager_config(Confs) ->
-%% ensure_manager_config(Confs, default_manager_config()).
-
-%% ensure_manager_config(Confs, []) ->
-%% Confs;
-%% ensure_manager_config(Confs, [{Key,_} = DefKeyVal|Defs]) ->
-%% case lists:keysearch(Key, 1, Confs) of
-%% false ->
-%% ensure_manager_config([DefKeyVal|Confs], Defs);
-%% {value, _Conf} ->
-%% ensure_manager_config(Confs, Defs)
-%% end.
-
-% ensure_manager_config([], Defs, Confs) ->
-% Confs ++ Defs;
-% ensure_manager_config(Confs0, [{Key, DefVal}|Defs], Acc) ->
-% case lists:keysearch(Key, 1, Confs0) of
-% false ->
-% ensure_manager_config(Confs0, Defs, [{Key, DefVal}|Acc]);
-% {value, Conf} ->
-% Confs = lists:keydelete(Key, 1, Confs0),
-% ensure_manager_config(Confs, Defs, [Conf|Acc])
-% end.
-
read_file(Dir, FileName, Order, Check, Default) ->
try snmp_conf:read(filename:join(Dir, FileName), Order, Check)
catch
@@ -2424,87 +2356,6 @@ read_file(Dir, FileName, Order, Check) ->
erlang:raise(throw, Error, erlang:get_stacktrace())
end.
-
-
-
-
-
-%% read_file(Dir, FileName, Verify, Default) ->
-%% File = filename:join(Dir, FileName),
-%% case file:read_file_info(File) of
-%% {ok, _} ->
-%% read_file(File, Verify);
-%% {error, Reason} ->
-%% ?vlog("failed reading config from ~s: ~p", [FileName, Reason]),
-%% {ok, Default}
-%% end.
-
-%% read_file(Dir, FileName, Verify) ->
-%% File = filename:join(Dir, FileName),
-%% case file:read_file_info(File) of
-%% {ok, _} ->
-%% read_file(File, Verify);
-%% {error, Reason} ->
-%% error_msg("failed reading config from ~s: ~p", [FileName, Reason]),
-%% {error, {failed_reading, FileName, Reason}}
-%% end.
-
-%% read_file(File, Verify) ->
-%% Check = fun (Config, State) -> {Verify(Config), State} end,
-%% try snmp_conf:read(File, Check) of
-%% Conf ->
-%% ?vtrace("read_file -> read ok"
-%% "~n Conf: ~p", [Conf]),
-%% {ok, Conf}
-%% catch
-%% Error ->
-%% ?vtrace("read_file -> read failed:"
-%% "~n Error: ~p", [Error]),
-%% Error
-%% end.
-
-%% XXX remove
-
-%% read_file(Dir, FileName, Check, Default) ->
-%% File = filename:join(Dir, FileName),
-%% case file:read_file_info(File) of
-%% {ok, _} ->
-%% case (catch do_read(File, Check)) of
-%% {ok, Conf} ->
-%% {ok, Conf};
-%% Error ->
-%% ?vtrace("read_file -> read failed:"
-%% "~n Error: ~p", [Error]),
-%% Error
-%% end;
-%% {error, Reason} ->
-%% ?vlog("failed reading config from ~s: ~p", [FileName, Reason]),
-%% {ok, Default}
-%% end.
-
-%% read_file(Dir, FileName, Check) ->
-%% File = filename:join(Dir, FileName),
-%% case file:read_file_info(File) of
-%% {ok, _} ->
-%% case (catch do_read(File, Check)) of
-%% {ok, Conf} ->
-%% ?vtrace("read_file -> read ok"
-%% "~n Conf: ~p", [Conf]),
-%% {ok, Conf};
-%% Error ->
-%% ?vtrace("read_file -> read failed:"
-%% "~n Error: ~p", [Error]),
-%% Error
-%% end;
-%% {error, Reason} ->
-%% error_msg("failed reading config from ~s: ~p", [FileName, Reason]),
-%% {error, {failed_reading, FileName, Reason}}
-%% end.
-
-%% do_read(File, Check) ->
-%% {ok, snmp_conf:read(File, Check)}.
-
-
%%--------------------------------------------------------------------
%% Func: handle_call/3
%% Returns: {reply, Reply, State} |
@@ -3580,6 +3431,5 @@ error_msg(F, A) ->
%% p(F) ->
%% p(F, []).
-p(F, A) ->
- io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
-
+%% p(F, A) ->
+%% io:format("~w:" ++ F ++ "~n", [?MODULE | A]).
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index 860b0b83dd..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).
@@ -59,8 +61,7 @@
{
server,
note_store,
- domain,
- sock,
+ transports = [],
mpd_state,
log,
irb = auto, % auto | {user, integer()}
@@ -68,6 +69,9 @@
filter
}).
+-record(transport,
+ {socket,
+ domain = snmpUDPDomain}).
-define(DEFAULT_FILTER_MODULE, snmpm_net_if_filter).
-define(DEFAULT_FILTER_OPTS, [{module, ?DEFAULT_FILTER_MODULE}]).
@@ -147,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
%%%-------------------------------------------------------------------
@@ -161,12 +223,19 @@ init([Server, NoteStore]) ->
?d("init -> entry with"
"~n Server: ~p"
"~n NoteStore: ~p", [Server, NoteStore]),
- case (catch do_init(Server, NoteStore)) of
+ try do_init(Server, NoteStore)
+ catch
{error, Reason} ->
- {stop, Reason};
- {ok, State} ->
- {ok, State}
+ {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),
@@ -176,18 +245,18 @@ 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),
- put(sname,mnif),
- put(verbosity,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),
@@ -196,21 +265,6 @@ do_init(Server, NoteStore) ->
{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),
- Domain =
- case snmpm_config:system_info(domain) of
- {ok, D} ->
- D;
- _ ->
- snmpm_config:default_transport_domain()
- end,
- {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, Domain, BindTo, NoReuse),
-
%% Flow control --
FilterOpts = get_opt(Opts, filter, []),
FilterMod = create_filter(FilterOpts),
@@ -219,83 +273,104 @@ 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]),
+ 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.
- %% -- Initiate counters ---
- init_counters(),
-
- %% -- We are done ---
- State = #state{server = Server,
- note_store = NoteStore,
- mpd_state = MpdState,
- domain = Domain,
- sock = Sock,
- log = Log,
- irb = IRB,
- irgc = IrGcRef,
- filter = FilterMod},
- ?vdebug("started", []),
- {ok, State}.
-
-
-%% Open port
-do_open_port(Port, SendSz, RecvSz, Domain, BindTo, NoReuse) ->
- ?vtrace("do_open_port -> entry with~n"
- " Port: ~p~n"
- " SendSz: ~p~n"
- " RecvSz: ~p~n"
- " Domain: ~p~n"
- " BindTo: ~p~n"
- " NoReuse: ~p",
- [Port, SendSz, RecvSz, Domain, BindTo, NoReuse]),
- IpOpts1 = bind_to(BindTo),
- IpOpts2 = no_reuse(NoReuse),
- IpOpts3 = recbuf(RecvSz),
- IpOpts4 = sndbuf(SendSz),
- IpOpts =
- [binary,
- snmp_conf:tdomain_to_family(Domain) |
- IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
- OpenRes =
- 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,
- case OpenRes of
+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 ->
- OK
+ {ok, Socket} ->
+ Socket
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}];
+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;
_ ->
- []
- end;
-bind_to(_) ->
- [].
-
-no_reuse(false) ->
- [{reuseaddr, true}];
-no_reuse(_) ->
- [].
-
-recbuf(default) ->
- [];
-recbuf(Sz) ->
- [{recbuf, Sz}].
+ case BindTo of
+ true ->
+ {IpPort, [{ip, IpAddr} | SocketOpts]};
+ _ ->
+ {IpPort, SocketOpts}
+ end
+ end.
-sndbuf(default) ->
- [];
-sndbuf(Sz) ->
- [{sndbuf, Sz}].
+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) ->
@@ -310,6 +385,10 @@ create_filter(BadOpts) ->
throw({error, {bad_filter_opts, BadOpts}}).
+%% ----------------------------------------------------------------------
+%% Audit Trail Logger
+%% ----------------------------------------------------------------------
+
%% Open log
do_init_log(false) ->
?vtrace("do_init_log(false) -> entry", []),
@@ -330,24 +409,69 @@ do_init_log(true) ->
Function = increment_counter,
Args = [atl_seqno, Initial, Max],
SeqNoGen = {Module, Function, Args},
- case snmp_log:create(Name, File,
- SeqNoGen, Size, Repair, true) of
+ case snmp_log:create(
+ 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} |
@@ -409,7 +533,7 @@ handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo},
" Vsn: ~p~n"
" MsgData: ~p~n"
" Domain: ~p~n"
- " Addr : ~p", [Pdu, Vsn, MsgData, Domain, Addr]),
+ " Addr: ~p", [Pdu, Vsn, MsgData, Domain, Addr]),
maybe_process_extra_info(ExtraInfo),
maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, State),
{noreply, State};
@@ -439,11 +563,20 @@ handle_cast(Msg, State) ->
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
handle_info(
- {udp, Sock, Ip, Port, Bytes},
- #state{sock = Sock, domain = Domain} = State) ->
- ?vlog("received ~w bytes from ~p:~p [~w]", [size(Bytes), Ip, Port, Sock]),
- maybe_handle_recv_msg(Domain, {Ip, Port}, Bytes, State),
- {noreply, State};
+ {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]),
+ maybe_handle_recv_msg(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", []),
@@ -456,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
@@ -474,68 +638,12 @@ 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
%% Returns: {ok, NewState}
%%----------------------------------------------------------------------
-code_change({down, _Vsn}, OldState, downgrade_to_pre_4_14) ->
- ?d("code_change(down, downgrade_to_pre_4_14) -> entry with"
- "~n OldState: ~p", [OldState]),
- #state{server = Server,
- note_store = NoteStore,
- sock = Sock,
- mpd_state = MpdState,
- log = {OldLog, Type},
- irb = IRB,
- irgc = IRGC} = OldState,
- NewLog = snmp_log:downgrade(OldLog),
- State =
- {state, Server, NoteStore, Sock, MpdState, {NewLog, Type}, IRB, IRGC},
- {ok, State};
-
-code_change({down, _Vsn}, OldState, downgrade_to_pre_4_16) ->
- ?d("code_change(down, downgrade_to_pre_4_16) -> entry with"
- "~n OldState: ~p", [OldState]),
- {OldLog, Type} = OldState#state.log,
- NewLog = snmp_log:downgrade(OldLog),
- State = OldState#state{log = {NewLog, Type}},
- {ok, State};
-
-% upgrade
-code_change(_Vsn, OldState, upgrade_from_pre_4_14) ->
- ?d("code_change(up, upgrade_from_pre_4_14) -> entry with"
- "~n OldState: ~p", [OldState]),
- {state, Server, NoteStore, Sock, MpdState, {OldLog, Type}, IRB, IRGC} =
- OldState,
- NewLog = snmp_log:upgrade(OldLog),
- State = #state{server = Server,
- note_store = NoteStore,
- sock = Sock,
- mpd_state = MpdState,
- log = {NewLog, Type},
- irb = IRB,
- irgc = IRGC,
- filter = ?DEFAULT_FILTER_MODULE},
- {ok, State};
-
-code_change(_Vsn, OldState, upgrade_from_pre_4_16) ->
- ?d("code_change(up, upgrade_from_pre_4_16) -> entry with"
- "~n OldState: ~p", [OldState]),
- {OldLog, Type} = OldState#state.log,
- NewLog = snmp_log:upgrade(OldLog),
- State = OldState#state{log = {NewLog, Type}},
- {ok, State};
-
code_change(_Vsn, State, _Extra) ->
?d("code_change -> entry with"
"~n Vsn: ~p"
@@ -548,80 +656,88 @@ 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, domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ #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),
- ok;
+ inc(netIfMsgInDrops);
_ ->
handle_recv_msg(Domain, Addr, Bytes, State)
- end.
+ 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},
- ok;
-
+ 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) ->
+ #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
+ 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);
+ 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),
- ok;
+ maybe_udp_send(Domain, Addr, Report, State);
{discarded, Reason} ->
?vdebug("discarded: ~p", [Reason]),
ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Domain, Addr},
- ok;
+ Pid ! {snmp_error, ErrorInfo, Domain, Addr};
Error ->
error_msg("processing of received message failed: "
- "~n ~p", [Error]),
- ok
+ "~n ~p", [Error])
end.
maybe_handle_recv_pdu(
Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger,
- #state{filter = FilterMod, domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ #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),
- ok;
+ 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, domain = ManagerDomain} = State)
+ #state{filter = FilterMod, transports = Transports} = State)
when is_record(Trap, trappdu) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ {Arg1, Arg2} = fix_filter_address(Transports, {Domain, Addr}),
case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of
false ->
- inc(netIfPduInDrops),
- ok;
+ inc(netIfPduInDrops);
_ ->
handle_recv_pdu(
Domain, Addr, Vsn, Trap, PduMS, ACM, Logger, State)
@@ -703,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}}] ->
@@ -718,10 +847,11 @@ handle_inform_response(Ref, Domain, Addr, State) ->
maybe_send_inform_response(
RePdu, Vsn, ACM, Domain, Addr, Logger,
- #state{server = Pid,
- filter = FilterMod,
- domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ #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
@@ -737,8 +867,7 @@ maybe_send_inform_response(
"~n Reason: ~p", [Reason]),
ReqId = RePdu#pdu.request_id,
ErrorInfo = {failed_generating_response, {RePdu, Reason}},
- Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr},
- ok
+ Pid ! {snmp_error, ReqId, ErrorInfo, Domain, Addr}
end
end.
@@ -771,24 +900,37 @@ 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, domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {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,
- #state{server = Pid,
- note_store = NoteStore,
- log = Log} = State) ->
+ #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
@@ -799,43 +941,58 @@ 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.
maybe_udp_send(
Domain, Addr, Msg,
- #state{sock = Sock, filter = FilterMod, domain = ManagerDomain}) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
+ #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;
_ ->
- %% XXX There should be some kind of lookup of socket
- %% from transport domain here
- {Ip, Port} = Addr,
- udp_send(Sock, Ip, Port, Msg)
+ 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, Ip, Port, Msg) ->
- case (catch gen_udp:send(Sock, Ip, Port, Msg)) of
+
+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), Ip, Port, Sock]),
+ [sz(Msg), IpAddr, IpPort, Sock]),
ok;
{error, Reason} ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Ip, Port, Reason]);
- Error ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p",[Ip, Port, Error])
+ 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) ->
- size(B);
+ byte_size(B);
sz(L) when is_list(L) ->
length(L);
sz(_) ->
@@ -1025,26 +1182,45 @@ 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(snmpUDPDomain, {Domain, Addr})
- when Domain =:= snmpUDPDomain;
- Domain =:= transportDomainUdpIpv4 ->
- Addr;
-fix_filter_address(_ManagerDomain, {Domain, _} = Address)
- when is_atom(Domain) ->
- Address;
-fix_filter_address(snmpUDPDomain, {_, Port} = Addr)
- when is_integer(Port) ->
- Addr.
+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)).
+
%% -------------------------------------------------------------------
make_response_pdu(#pdu{request_id = ReqId, varbinds = Vbs}) ->
@@ -1085,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).
@@ -1130,10 +1285,11 @@ get_opt(Opts, Key, Def) ->
%% -------------------------------------------------------------------
-get_info(#state{sock = Id}) ->
+get_info(#state{transports = Transports}) ->
ProcSize = proc_mem(self()),
- PortInfo = get_port_info(Id),
- [{process_memory, ProcSize}, {port_info, PortInfo}].
+ [{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
@@ -1248,4 +1404,3 @@ call(Pid, Req, Timeout) ->
cast(Pid, Msg) ->
gen_server:cast(Pid, Msg).
-
diff --git a/lib/snmp/src/manager/snmpm_net_if_mt.erl b/lib/snmp/src/manager/snmpm_net_if_mt.erl
index 2937f5cc87..62f6023657 100644
--- a/lib/snmp/src/manager/snmpm_net_if_mt.erl
+++ b/lib/snmp/src/manager/snmpm_net_if_mt.erl
@@ -17,1309 +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,
- domain,
- sock,
- mpd_state,
- log,
- irb = auto, % auto | {user, integer()}
- irgc,
- filter
- }).
-
-
--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]),
- 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 --
- %% 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),
-
- %% -- 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),
- Domain =
- case snmpm_config:system_info(domain) of
- {ok, D} ->
- D;
- _ ->
- snmpm_config:default_transport_domain()
- end,
- {ok, Sock} = do_open_port(Port, SndBuf, RecBuf, Domain, BindTo, NoReuse),
-
- %% 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]),
-
- %% -- Initiate counters ---
- init_counters(),
-
- %% -- We are done ---
- State = #state{server = Server,
- note_store = NoteStore,
- mpd_state = MpdState,
- domain = Domain,
- sock = Sock,
- log = Log,
- irb = IRB,
- irgc = IrGcRef,
- filter = FilterMod},
- ?vdebug("started", []),
- {ok, State}.
-
-
-%% Open port
-do_open_port(Port, SendSz, RecvSz, Domain, BindTo, NoReuse) ->
- ?vtrace("do_open_port -> entry with~n"
- " Port: ~p~n"
- " SendSz: ~p~n"
- " RecvSz: ~p~n"
- " Domain: ~p~n"
- " BindTo: ~p~n"
- " NoReuse: ~p",
- [Port, SendSz, RecvSz, Domain, BindTo, NoReuse]),
- IpOpts1 = bind_to(BindTo),
- IpOpts2 = no_reuse(NoReuse),
- IpOpts3 = recbuf(RecvSz),
- IpOpts4 = sndbuf(SendSz),
- IpOpts =
- [binary,
- snmp_conf:tdomain_to_family(Domain) |
- IpOpts1 ++ IpOpts2 ++ IpOpts3 ++ IpOpts4],
- OpenRes =
- 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,
- case OpenRes of
- {error, _} = Error ->
- throw(Error);
- OK ->
- OK
- 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}].
-
-
-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, Sock, Ip, Port, Bytes},
- #state{sock = Sock, domain = Domain} = State) ->
- ?vlog("received ~w bytes from ~p:~p", [size(Bytes), Ip, Port]),
- handle_udp(Domain, {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({'DOWN', _MRef, process, Pid, {net_if_worker, ExitStatus}},
- State) ->
- ?vdebug("received DOWN message from net_if-worker: "
- "~n ExitStatus: ~p", [ExitStatus]),
- handle_worker_exit(Pid, ExitStatus),
- {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({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) ->
- Verbosity = get(verbosity),
- spawn_opt(
- fun() ->
- Log = worker_init(State, Verbosity),
- Res =
- (catch maybe_handle_recv_msg(
- Domain, Addr, Bytes,
- State#state{log = Log})),
- worker_exit(udp, {Domain, Addr}, Res)
- end,
- [monitor]).
-
-
-maybe_handle_recv_msg(
- Domain, Addr, Bytes,
- #state{filter = FilterMod, domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
- case (catch FilterMod:accept_recv(Arg1, Arg2)) of
- false ->
- %% Drop the received packet
- inc(netIfMsgInDrops),
- ok;
- _ ->
- handle_recv_msg(Domain, Addr, Bytes, State)
- end.
-
-
-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},
- ok;
-
-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),
- ok;
- {discarded, Reason} ->
- ?vdebug("discarded: ~p", [Reason]),
- ErrorInfo = {failed_processing_message, Reason},
- Pid ! {snmp_error, ErrorInfo, Domain, Addr},
- ok;
-
- Error ->
- error_msg("processing of received message failed: "
- "~n ~p", [Error]),
- ok
- end.
-
-
-maybe_handle_recv_pdu(
- Domain, Addr, Vsn, #pdu{type = Type} = Pdu, PduMS, ACM, Logger,
- #state{filter = FilterMod, domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
- case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, Type)) of
- false ->
- inc(netIfPduInDrops),
- ok;
- _ ->
- 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, domain = ManagerDomain} = State)
- when is_record(Trap, trappdu) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
- case (catch FilterMod:accept_recv_pdu(Arg1, Arg2, trappdu)) of
- false ->
- inc(netIfPduInDrops),
- ok;
- _ ->
- 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},
- ok;
-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},
- ok;
-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},
- ok;
-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},
- ok;
-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},
- ok;
-handle_recv_pdu(
- _Domain, _Addr, _Vsn, Pdu, _PduMS, ACM, _Logger, _State) ->
- ?vlog("received unexpected pdu: "
- "~n Pdu: ~p"
- "~n ACM: ~p", [Pdu, ACM]),
- ok.
-
-
-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,
- ok.
-
-handle_inform_response(Ref, Domain, Addr, State) ->
- Verbosity = get(verbosity),
- spawn_opt(
- fun() ->
- Log = worker_init(State, Verbosity),
- Res = (catch do_handle_inform_response(
- Ref, Domain, Addr, State#state{log = Log})),
- worker_exit(inform_response, {Domain, Addr}, Res)
- end,
- [monitor]).
-
-
-
-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,
- sock = Sock,
- domain = ManagerDomain,
- filter = FilterMod}) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {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, Sock, FilterMod, ManagerDomain);
- {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},
- ok
- 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) ->
- Verbosity = get(verbosity),
- spawn_opt(
- fun() ->
- Log = worker_init(State, Verbosity),
- Res = (catch maybe_handle_send_pdu(
- Pdu, Vsn, MsgData,
- Domain, Addr,
- State#state{log = Log})),
- worker_exit(send_pdu, {Domain, Addr}, Res)
- end,
- [monitor]).
-
-maybe_handle_send_pdu(
- Pdu, Vsn, MsgData, Domain, Addr,
- #state{filter = FilterMod, domain = ManagerDomain} = State) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {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{sock = Sock, filter = FilterMod, domain = ManagerDomain}) ->
- maybe_udp_send(Domain, Addr, Msg, Sock, FilterMod, ManagerDomain).
-
-maybe_udp_send(Domain, Addr, Msg, Sock, FilterMod, ManagerDomain) ->
- {Arg1, Arg2} = fix_filter_address(ManagerDomain, {Domain, Addr}),
- case (catch FilterMod:accept_send(Arg1, Arg2)) of
- false ->
- inc(netIfMsgOutDrops),
- ok;
- _ ->
- %% XXX There should be some kind of lookup of socket
- %% from transport domain here
- {Ip, Port} = Addr,
- udp_send(Sock, Ip, Port, Msg)
- end.
-
-
-udp_send(Sock, Ip, Port, Msg) ->
- case (catch gen_udp:send(Sock, Ip, Port, Msg)) of
- ok ->
- ?vdebug("sent ~w bytes to ~w:~w [~w]",
- [sz(Msg), Ip, Port, Sock]),
- ok;
- {error, Reason} ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p", [Ip, Port, Reason]),
- ok;
- Error ->
- error_msg("failed sending message to ~p:~p: "
- "~n ~p", [Ip, Port, Error]),
- ok
- end.
-
-sz(B) when is_binary(B) ->
- 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}}.
-
-
-%% -------------------------------------------------------------------
-
-worker_init(#state{log = undefined = Log}, Verbosity) ->
- worker_init2(Log, Verbosity);
-worker_init(#state{log = {Name, Log, Type}}, Verbosity) ->
- case snmp_log:open(Name, Log) of
- {ok, NewLog} ->
- worker_init2({Name, NewLog, Type}, Verbosity);
- {error, Reason} ->
- warning_msg("NetIf worker ~p failed opening ATL: "
- "~n ~p", [self(), Reason]),
- NewLog = undefined,
- worker_init2({Name, NewLog, Type}, Verbosity)
- end;
-worker_init(State, Verbosity) ->
- ?vinfo("worker_init -> entry with invalid data: "
- "~n State: ~p"
- "~n Verbosity: ~p", [State, Verbosity]),
- exit({worker_init, State, Verbosity}).
-
-worker_init2(Log, Verbosity) ->
- put(sname, mnifw),
- put(verbosity, Verbosity),
- Log.
-
-
-worker_exit(Tag, Info, Result) ->
- exit({net_if_worker, {Tag, Info, Result}}).
-
-handle_worker_exit(_, {_, _, ok}) ->
- ok;
-handle_worker_exit(Pid, {udp, {Domain, Addr}, ExitStatus}) ->
- warning_msg(
- "Worker process (~p) terminated "
- "while processing (incomming) message from %s:~n"
- "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]),
- ok;
-handle_worker_exit(Pid, {send_pdu, {Domain, Addr}, ExitStatus}) ->
- warning_msg(
- "Worker process (~p) terminated "
- "while processing (outgoing) pdu for %s:~n"
- "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]),
- ok;
-handle_worker_exit(Pid, {inform_response, {Domain, Addr}, ExitStatus}) ->
- warning_msg(
- "Worker process (~p) terminated "
- "while processing (outgoing) inform response for %s:~n"
- "~p", [Pid, snmp_conf:mk_addr_string({Domain, Addr}), ExitStatus]),
- ok;
-handle_worker_exit(_, _) ->
- ok.
-
-
-%% 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(snmpUDPDomain, {Domain, Addr})
- when Domain =:= snmpUDPDomain;
- Domain =:= transportDomainUdpIpv4 ->
- Addr;
-fix_filter_address(_ManagerDomain, {Domain, _} = Address)
- when is_atom(Domain) ->
- Address;
-fix_filter_address(snmpUDPDomain, {_, Port} = Addr)
- when is_integer(Port) ->
- Addr.
-
-address(Domain, Addr) when is_atom(Domain) ->
- {Domain, Addr};
-address(Ip, Port) when is_integer(Port) ->
- {snmpm_config:default_transport_domain(), {Ip, Port}}.
-
-%% -------------------------------------------------------------------
-
-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, Domain, 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{sock = Id}) ->
- ProcSize = proc_mem(self()),
- PortInfo = get_port_info(Id),
- [{process_memory, ProcSize}, {port_info, PortInfo}].
-
-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").
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index ece5dad082..a75122d0bb 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -2079,7 +2079,16 @@ do_handle_agent(DefUserId, DefMod,
SnmpInfo, DefData, State) ->
?vdebug("do_handle_agent -> entry when"
"~n DefUserId: ~p", [DefUserId]),
- try DefMod:handle_agent(Domain, Addr, Type, SnmpInfo, DefData) of
+ {Domain_or_Ip, Addr_or_Port} =
+ case Domain of
+ snmpUDPDomain ->
+ Addr;
+ _ ->
+ {Domain, Addr}
+ end,
+ try DefMod:handle_agent(
+ Domain_or_Ip, Addr_or_Port, Type, SnmpInfo, DefData)
+ of
{register, UserId2, TargetName, Config} ->
?vtrace("do_handle_agent -> register: "
"~n UserId2: ~p"
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index f4483995cb..153c8070c2 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -749,8 +749,6 @@ which_domain({A0, A1, A2, A3, A4, A5, A6, A7})
%% ---------
-mk_addr_string({_IP, Port} = Addr) when is_integer(Port) ->
- mk_addr_string({snmpUDPDomain, Addr});
mk_addr_string({Domain, Addr}) when is_atom(Domain) ->
%% XXX There is only code for IP domains here
case check_address_ip(Domain, Addr) of
@@ -768,7 +766,11 @@ mk_addr_string({Domain, Addr}) when is_atom(Domain) ->
mk_addr_string_ntoa(Domain, Addr);
IP ->
mk_addr_string_ntoa(Domain, IP)
- end.
+ end;
+mk_addr_string({_IP, Port} = Addr) when is_integer(Port) ->
+ mk_addr_string({snmpUDPDomain, Addr});
+mk_addr_string(Strange) ->
+ lists:flatten(io_lib:format("~w", [Strange])).
mk_addr_string_ntoa({_, _, _, _} = IP) ->
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index 9e9865f3b5..17dfcd70b4 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -47,8 +47,8 @@
write_agent_snmp_vacm_conf/3,
write_manager_snmp_files/8,
- write_manager_snmp_conf/5,
- write_manager_snmp_users_conf/2,
+ write_manager_snmp_conf/4, write_manager_snmp_conf/5,
+ write_manager_snmp_users_conf/2,
write_manager_snmp_agents_conf/2,
write_manager_snmp_usm_conf/2
@@ -1676,7 +1676,9 @@ write_agent_snmp_conf(Dir, AgentIP, AgentUDP, EngineID, MMS)
{intAgentIpAddress, AgentIP},
{snmpEngineID, EngineID},
{snmpEngineMaxMessageSize, MMS}],
- do_write_agent_snmp_conf(Dir, Conf).
+ do_write_agent_snmp_conf(Dir, Conf);
+write_agent_snmp_conf(_Dir, Domain, AgentAddr, _EngineID, _MMS) ->
+ error({bad_address, {Domain, AgentAddr}}).
do_write_agent_snmp_conf(Dir, Conf) ->
Comment =
@@ -2116,7 +2118,24 @@ write_manager_snmp_files(Dir, IP, Port, MMS, EngineID,
%% ------ manager.conf ------
%%
-write_manager_snmp_conf(Dir, IP, Port, MMS, EngineID) ->
+write_manager_snmp_conf(Dir, Transports, MMS, EngineID) ->
+ Comment =
+"%% This file defines the Manager local configuration info\n"
+"%% Each row is a 2-tuple:\n"
+"%% {Variable, Value}.\n"
+"%% For example\n"
+"%% {transports, [{transportDomainUdpIpv4, {{127,42,17,5}, 5000}}]}.\n"
+"%% {engine_id, \"managerEngine\"}.\n"
+"%% {max_message_size, 484}.\n"
+"%%\n\n",
+ Hdr = header() ++ Comment,
+ Conf =
+ [{transports, Transports},
+ {engine_id, EngineID},
+ {max_message_size, MMS}],
+ write_manager_config(Dir, Hdr, Conf).
+
+write_manager_snmp_conf(Dir, Domain_or_IP, Addr_or_Port, MMS, EngineID) ->
Comment =
"%% This file defines the Manager local configuration info\n"
"%% Each row is a 2-tuple:\n"
@@ -2129,15 +2148,16 @@ write_manager_snmp_conf(Dir, IP, Port, MMS, EngineID) ->
"%%\n\n",
Hdr = header() ++ Comment,
Conf =
- case Port of
- {Addr, P} when is_integer(P), is_atom(IP) ->
- Domain = IP,
- [{domain, Domain},
- {port, P},
- {address, Addr}];
- _ when is_integer(Port) ->
- [{port, Port},
- {address, IP}]
+ case Addr_or_Port of
+ {IP, Port} when is_integer(Port), is_atom(Domain_or_IP) ->
+ [{domain, Domain_or_IP},
+ {port, Port},
+ {address, IP}];
+ _ when is_integer(Addr_or_Port) ->
+ [{port, Addr_or_Port},
+ {address, Domain_or_IP}];
+ _ ->
+ error({bad_address, {Domain_or_IP, Addr_or_Port}})
end ++
[{engine_id, EngineID},
{max_message_size, MMS}],