aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2014-08-08 10:04:55 +0200
committerRaimo Niskanen <[email protected]>2014-08-18 15:55:01 +0200
commit215b2305cad4f1bc45fd33677198e3887d200869 (patch)
treecde84440931c002d51e22b052f5970cea2a601d2 /lib/snmp
parentc472c3f5aafc81a409d0443c4601de43bafb53cb (diff)
downloadotp-215b2305cad4f1bc45fd33677198e3887d200869.tar.gz
otp-215b2305cad4f1bc45fd33677198e3887d200869.tar.bz2
otp-215b2305cad4f1bc45fd33677198e3887d200869.zip
Rewrite manager net_if for IPv4+IPv6
Diffstat (limited to 'lib/snmp')
-rw-r--r--lib/snmp/src/manager/snmpm_conf.erl1
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl372
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl490
-rw-r--r--lib/snmp/src/misc/snmp_config.erl40
4 files changed, 412 insertions, 491 deletions
diff --git a/lib/snmp/src/manager/snmpm_conf.erl b/lib/snmp/src/manager/snmpm_conf.erl
index 888f19aec6..e03d28a3e4 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})
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index 013fefa4e2..d147aabb0b 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -1287,36 +1287,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 +1602,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 +1655,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,11 +1681,19 @@ 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,
@@ -1752,8 +1702,9 @@ 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 +1727,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},
@@ -1946,16 +1897,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 +2015,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 +2201,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 +2211,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 +2228,55 @@ 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}, State) ->
+ CheckedTransports =
+ [case snmp_conf:check_address(Domain, Address) of
+ ok ->
+ Transport;
+ {ok, FixedAddress} ->
+ {Domain, FixedAddress}
+ end
+ || {Domain, Address} = 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 +2285,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 +2302,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} |
@@ -3582,4 +3379,3 @@ error_msg(F, 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..c4716dfd21 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -59,8 +59,9 @@
{
server,
note_store,
- domain,
- sock,
+%% 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}]).
@@ -161,12 +165,17 @@ 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.
+ %% 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),
@@ -196,21 +205,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),
@@ -220,82 +214,197 @@ do_init(Server, NoteStore) ->
{ok, ATL} = snmpm_config:system_info(audit_trail_log),
Log = do_init_log(ATL),
- %% -- Initiate counters ---
- init_counters(),
+ {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.
- %% -- 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 --
+ %% 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),
+
+ %% %% -- 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.
+
+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}];
+%% 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(_) ->
+%% [].
+
+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].
+
+%% 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) ->
@@ -439,11 +548,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", []),
@@ -488,54 +606,6 @@ do_close_log(_) ->
%% 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"
@@ -550,8 +620,8 @@ code_change(_Vsn, State, _Extra) ->
maybe_handle_recv_msg(
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
@@ -569,10 +639,11 @@ handle_recv_msg(Domain, Addr, Bytes, #state{server = Pid})
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
@@ -603,8 +674,8 @@ handle_recv_msg(
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),
@@ -615,9 +686,9 @@ maybe_handle_recv_pdu(
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),
@@ -718,10 +789,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
@@ -774,8 +846,8 @@ irgc_stop(Ref) ->
maybe_handle_send_pdu(
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),
@@ -786,9 +858,10 @@ maybe_handle_send_pdu(
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
@@ -806,36 +879,52 @@ handle_send_pdu(
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 +1114,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}) ->
@@ -1130,10 +1238,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 +1357,3 @@ call(Pid, Req, Timeout) ->
cast(Pid, Msg) ->
gen_server:cast(Pid, Msg).
-
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index 9e9865f3b5..0a50174adc 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
@@ -2116,7 +2116,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 +2146,14 @@ 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}]
end ++
[{engine_id, EngineID},
{max_message_size, MMS}],