aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp/src
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2014-04-09 10:29:00 +0200
committerRaimo Niskanen <[email protected]>2014-07-22 09:59:15 +0200
commit768a6d38597b8bedf6551ad2e6472b2965765dd2 (patch)
treee4eb4fb767d2c83954bdf63f1191497589e267b9 /lib/snmp/src
parent934b6de4d2ab6c31c5217e1ba4779ade9e37cc83 (diff)
downloadotp-768a6d38597b8bedf6551ad2e6472b2965765dd2.tar.gz
otp-768a6d38597b8bedf6551ad2e6472b2965765dd2.tar.bz2
otp-768a6d38597b8bedf6551ad2e6472b2965765dd2.zip
Rewrite agent configuration parsing
Diffstat (limited to 'lib/snmp/src')
-rw-r--r--lib/snmp/src/agent/snmp_community_mib.erl71
-rw-r--r--lib/snmp/src/agent/snmp_framework_mib.erl55
-rw-r--r--lib/snmp/src/agent/snmp_notification_mib.erl24
-rw-r--r--lib/snmp/src/agent/snmp_standard_mib.erl23
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl172
-rw-r--r--lib/snmp/src/agent/snmp_user_based_sm_mib.erl14
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl23
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl96
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl39
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl10
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl406
-rw-r--r--lib/snmp/src/misc/snmp_config.erl143
12 files changed, 779 insertions, 297 deletions
diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl
index 7bdd500727..12a0ec97c2 100644
--- a/lib/snmp/src/agent/snmp_community_mib.erl
+++ b/lib/snmp/src/agent/snmp_community_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -31,6 +31,7 @@
-include("snmpa_internal.hrl").
-include("SNMP-COMMUNITY-MIB.hrl").
-include("SNMP-TARGET-MIB.hrl").
+-include("SNMPv2-TM.hrl").
-include("SNMPv2-TC.hrl").
-include("snmp_types.hrl").
@@ -129,10 +130,11 @@ read_community_config_files(Dir) ->
[FileName, D, Reason]),
ok
end,
- Filter = fun(Comms) -> Comms end,
- Check = fun(Entry) -> check_community(Entry) end,
+ Order = fun snmp_conf:no_order/2,
+ Filter = fun snmp_conf:no_filter/1,
+ Check = fun(Entry, State) -> {check_community(Entry), State} end,
[Comms] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, "community.conf"}]),
+ snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]),
Comms.
check_community({Index, CommunityName, SecName, CtxName, TransportTag}) ->
@@ -192,7 +194,7 @@ add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) ->
do_add_community(Community).
do_add_community(Community) ->
- case (catch check_community(Community)) of
+ try check_community(Community) of
{ok, Row} ->
Key = element(1, Row),
case table_cre_row(snmpCommunityTable, Key, Row) of
@@ -201,11 +203,12 @@ do_add_community(Community) ->
{ok, Key};
false ->
{error, create_failed}
- end;
+ end
+ catch
{error, Reason} ->
{error, Reason};
- Error ->
- {error, Error}
+ Class:Reason ->
+ {error, {Class, Reason, erlang:get_stacktrace()}}
end.
%% FIXME: does not work with mnesia
@@ -506,7 +509,12 @@ snmpTargetAddrExtTable(get_next, RowIndex, Cols) ->
NCols = conv1(Cols),
conv2(next(snmpTargetAddrExtTable, RowIndex, NCols));
snmpTargetAddrExtTable(set, RowIndex, Cols0) ->
- case (catch verify_snmpTargetAddrExtTable_cols(Cols0, [])) of
+ case
+ (catch verify_snmpTargetAddrExtTable_cols(
+ Cols0,
+ get_snmpTargetAddrTDomain(RowIndex, Cols0),
+ []))
+ of
{ok, Cols} ->
NCols = conv3(Cols),
snmp_generic:table_func(set, RowIndex, NCols,
@@ -515,7 +523,11 @@ snmpTargetAddrExtTable(set, RowIndex, Cols0) ->
Error
end;
snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) ->
- case (catch verify_snmpTargetAddrExtTable_cols(Cols0, [])) of
+ case (catch verify_snmpTargetAddrExtTable_cols(
+ Cols0,
+ get_snmpTargetAddrTDomain(RowIndex, Cols0),
+ []))
+ of
{ok, Cols} ->
NCols = conv3(Cols),
snmp_generic:table_func(is_set_ok, RowIndex, NCols,
@@ -525,29 +537,49 @@ snmpTargetAddrExtTable(is_set_ok, RowIndex, Cols0) ->
end.
-verify_snmpTargetAddrExtTable_cols([], Cols) ->
+
+get_snmpTargetAddrTDomain(RowIndex, Col) ->
+ case
+ get(
+ snmpTargetAddrTable, RowIndex,
+ [?snmpTargetAddrRowStatus,?snmpTargetAddrTDomain])
+ of
+ [{value,?snmpTargetAddrRowStatus_active},ValueTDomain] ->
+ case ValueTDomain of
+ {value,TDomain} ->
+ TDomain;
+ _ ->
+ ?snmpUDPDomain
+ end;
+ _ ->
+ wrongValue(Col)
+ end.
+
+
+
+verify_snmpTargetAddrExtTable_cols([], _TDomain, Cols) ->
{ok, lists:reverse(Cols)};
-verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], Acc) ->
- Val = verify_snmpTargetAddrExtTable_col(Col, Val0),
- verify_snmpTargetAddrExtTable_cols(Cols, [{Col, Val}|Acc]).
+verify_snmpTargetAddrExtTable_cols([{Col, Val0}|Cols], TDomain, Acc) ->
+ Val = verify_snmpTargetAddrExtTable_col(Col, TDomain, Val0),
+ verify_snmpTargetAddrExtTable_cols(Cols, TDomain, [{Col, Val}|Acc]).
-verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, []) ->
+verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, _TDomain, []) ->
[];
-verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, TMask) ->
- case (catch snmp_conf:check_taddress(TMask)) of
+verify_snmpTargetAddrExtTable_col(?snmpTargetAddrTMask, TDomain, TMask) ->
+ case (catch snmp_conf:check_taddress(TDomain, TMask)) of
ok ->
TMask;
_ ->
wrongValue(?snmpTargetAddrTMask)
end;
-verify_snmpTargetAddrExtTable_col(?snmpTargetAddrMMS, MMS) ->
+verify_snmpTargetAddrExtTable_col(?snmpTargetAddrMMS, _TDomain, MMS) ->
case (catch snmp_conf:check_packet_size(MMS)) of
ok ->
MMS;
_ ->
wrongValue(?snmpTargetAddrMMS)
end;
-verify_snmpTargetAddrExtTable_col(_, Val) ->
+verify_snmpTargetAddrExtTable_col(_, _TDomain, Val) ->
Val.
db(snmpTargetAddrExtTable) -> db(snmpTargetAddrTable);
@@ -583,6 +615,7 @@ conv3([{Idx, Val}|T]) -> [{Idx+10, Val} | conv3(T)];
conv3([]) -> [].
+
get(Name, RowIndex, Cols) ->
snmp_generic:handle_table_get(db(Name), RowIndex, Cols, foi(Name)).
diff --git a/lib/snmp/src/agent/snmp_framework_mib.erl b/lib/snmp/src/agent/snmp_framework_mib.erl
index cc191bd956..84f39df228 100644
--- a/lib/snmp/src/agent/snmp_framework_mib.erl
+++ b/lib/snmp/src/agent/snmp_framework_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -51,7 +51,7 @@
set_engine_boots/1, set_engine_time/1,
table_next/2, check_status/3]).
-export([add_context/1, delete_context/1]).
--export([check_agent/1, check_context/1]).
+-export([check_agent/1, check_agent/2, check_context/1, order_agent/2]).
%%-----------------------------------------------------------------
@@ -115,23 +115,22 @@ do_configure(Dir) ->
read_internal_config_files(Dir) ->
?vdebug("read context config file",[]),
- Gen = fun(D, Reason) ->
- convert_context(D, Reason)
- end,
- Filter = fun(Contexts) -> Contexts end,
- Check = fun(Entry) -> check_context(Entry) end,
- [Ctxs] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "context.conf"}]),
+ Gen = fun gen_context/2,
+ Order = fun snmp_conf:no_order/2,
+ Filter = fun snmp_conf:no_filter/1,
+ Check = fun(Entry, State) -> {check_context(Entry), State} end,
+ [Ctxs] =
+ snmp_conf:read_files
+ (Dir, [{"context.conf", Gen, Order, Check, Filter}]),
Ctxs.
-
read_agent(Dir) ->
?vdebug("read agent config file", []),
- FileName = "agent.conf",
- Check = fun(Entry) -> check_agent(Entry) end,
+ FileName = "agent.conf",
File = filename:join(Dir, FileName),
- Agent =
+ Agent =
try
- snmp_conf:read(File, Check)
+ snmp_conf:read(File, fun order_agent/2, fun check_agent/2)
catch
throw:{error, Reason} ->
error({failed_reading_config_file, Dir, FileName, Reason})
@@ -155,14 +154,15 @@ sort_agent(L) ->
%%-----------------------------------------------------------------
%% Generate a context.conf file.
%%-----------------------------------------------------------------
-convert_context(Dir, _Reason) ->
+gen_context(Dir, _Reason) ->
config_err("missing context.conf file => generating a default file", []),
File = filename:join(Dir, "context.conf"),
case file:open(File, [write]) of
{ok, Fid} ->
ok = io:format(Fid, "~s\n", [context_header()]),
ok = io:format(Fid, "%% The default context\n\"\".\n", []),
- file:close(Fid);
+ file:close(Fid),
+ [];
{error, Reason} ->
file:delete(File),
error({failed_creating_file, File, Reason})
@@ -196,9 +196,21 @@ check_context(Context) ->
%% Agent
%% {Name, Value}.
%%-----------------------------------------------------------------
-check_agent({intAgentIpAddress, Value}) ->
+check_agent({intAgentTransportDomain, D}, Domain) ->
+ case Domain of
+ undefined ->
+ {snmp_conf:check_domain(D), D};
+ _ ->
+ error({invalid_agent_attribute, D})
+ end;
+check_agent({intAgentTransportAddress, Address}, Domain) ->
+ {snmp_conf:check_address(Domain, Address), Domain};
+check_agent(Entry, Domain) ->
+ {check_agent(Entry), Domain}.
+
+check_agent({intAgentIpAddress, Value}) -> % Obsoleted
snmp_conf:check_ip(Value);
-check_agent({intAgentUDPPort, Value}) ->
+check_agent({intAgentUDPPort, Value}) -> % Obsoleted
snmp_conf:check_integer(Value);
%% This one is kept for backwards compatibility
check_agent({intAgentMaxPacketSize, Value}) ->
@@ -210,6 +222,15 @@ check_agent({snmpEngineID, Value}) ->
check_agent(X) ->
error({invalid_agent_attribute, X}).
+%% Ordering function to sort intAgentTransportDomain first
+%% hence before intAgentTransportAddress
+order_agent({intAgentTransportDomain, _}, {intAgentTransportDomain, _}) ->
+ true; %% Less than or equal
+order_agent(_, {intAgentTransportDomain, _}) ->
+ false; %% Greater than
+order_agent(_, _) ->
+ true. %% Less than or equal
+
maybe_create_table(Name) ->
case snmpa_local_db:table_exists(db(Name)) of
diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl
index 37e09f5d3e..31c7735226 100644
--- a/lib/snmp/src/agent/snmp_notification_mib.erl
+++ b/lib/snmp/src/agent/snmp_notification_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -106,17 +106,19 @@ do_reconfigure(Dir) ->
read_notify_config_files(Dir) ->
?vdebug("read notify config file",[]),
FileName = "notify.conf",
- Gen = fun(D, Reason) ->
- info_msg("failed reading config file ~s"
- "~n Config Dir: ~s"
- "~n Reason: ~p",
- [FileName, D, Reason]),
- ok
- end,
- Filter = fun(Notifs) -> Notifs end,
- Check = fun(Entry) -> check_notify(Entry) end,
+ Gen =
+ fun (D, Reason) ->
+ info_msg("failed reading config file ~s"
+ "~n Config Dir: ~s"
+ "~n Reason: ~p",
+ [FileName, D, Reason]),
+ ok
+ end,
+ Order = fun snmp_conf:no_order/2,
+ Filter = fun snmp_conf:no_filter/1,
+ Check = fun (Entry, State) -> {check_notify(Entry), State} end,
[Notifs] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, "notify.conf"}]),
+ snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]),
Notifs.
check_notify({Name, Tag, Type}) ->
diff --git a/lib/snmp/src/agent/snmp_standard_mib.erl b/lib/snmp/src/agent/snmp_standard_mib.erl
index 766b75022b..aace3fd413 100644
--- a/lib/snmp/src/agent/snmp_standard_mib.erl
+++ b/lib/snmp/src/agent/snmp_standard_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -152,16 +152,19 @@ do_reconfigure(Dir) ->
%%-----------------------------------------------------------------
read_standard(Dir) ->
?vdebug("check standard config file",[]),
- FileName = "standard.conf",
- Gen = fun(D, Reason) ->
- throw({error, {failed_reading_config_file,
- D, FileName,
- list_dir(Dir), Reason}})
- end,
- Filter = fun(Standard) -> sort_standard(Standard) end,
- Check = fun(Entry) -> check_standard(Entry) end,
+ FileName = "standard.conf",
+ Gen =
+ fun (D, Reason) ->
+ throw(
+ {error,
+ {failed_reading_config_file,
+ D, FileName, list_dir(Dir), Reason}})
+ end,
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (Entry, State) -> {check_standard(Entry), State} end,
+ Filter = fun sort_standard/1,
[Standard] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, FileName}]),
+ snmp_conf:read_files(Dir, [{FileName, Gen, Order, Check, Filter}]),
Standard.
list_dir(Dir) ->
diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl
index b01d536caa..6dd3b6e23a 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2012. All Rights Reserved.
+%% Copyright Ericsson AB 1998-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
@@ -133,18 +133,22 @@ do_reconfigure(Dir) ->
read_target_config_files(Dir) ->
?vdebug("check target address and parameter config file(s)",[]),
- TAGen = fun(_D, _Reason) -> ok end,
- TAFilter = fun(Addr) -> Addr end,
- TACheck = fun(Entry) -> check_target_addr(Entry) end,
- TPGen = fun(_D, _Reason) -> ok end,
- TPFilter = fun(Params) -> Params end,
- TPCheck = fun(Entry) -> check_target_params(Entry) end,
+ TAName = "target_addr.conf",
+ TACheck = fun (Entry, State) -> {check_target_addr(Entry), State} end,
+
+ TPName = "target_params.conf",
+ TPCheck = fun (Entry, State) -> {check_target_params(Entry), State} end,
+
+ NoGen = fun snmp_conf:no_gen/2,
+ NoOrder = fun snmp_conf:no_order/2,
+ NoFilter = fun snmp_conf:no_filter/1,
[Addrs, Params] =
- snmp_conf:read_files(Dir,
- [{TAGen, TAFilter, TACheck, "target_addr.conf"},
- {TPGen, TPFilter, TPCheck, "target_params.conf"}]),
+ snmp_conf:read_files(
+ Dir,
+ [{TAName, NoGen, NoOrder, TACheck, NoFilter},
+ {TPName, NoGen, NoOrder, TPCheck, NoFilter}]),
{Addrs, Params}.
@@ -154,80 +158,142 @@ read_target_config_files(Dir) ->
%% TMask, MMS}
%%-----------------------------------------------------------------
-check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS}) ->
+check_target_addr(
+ {Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS}) -> % Arity 11
+ Address = {Ip, Udp},
+ 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
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS}) -> % Arity 10
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, TMask, MMS);
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId}) % Arity 8
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ EngineId}) -> % Arity 8
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId);
+%% Use dummy engine id if the old style is found
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params}) % Arity 7
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) -> % Arity 7
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params);
+%% Use dummy engine id if the old style is found
+check_target_addr(
+ {Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ TMask, MMS}) % Arity 9
+ when is_atom(Domain) ->
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
+check_target_addr(
+ {Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
+ TMask, MMS}) -> % Arity 9
+ Domain = default_domain(),
+ Address = {Ip, Udp},
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params, TMask, MMS);
+check_target_addr(X) ->
+ error({invalid_target_addr, X}).
+
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params) -> % Arity 7
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ "dummy").
+%%
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId) -> % Arity 8
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, [], 2048).
+%%
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ TMask, MMS) -> % Arity 9
+ check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ "dummy", TMask, MMS).
+%%
+check_target_addr(
+ Name, Domain, Address, Timeout, RetryCount, TagList, Params,
+ EngineId, Mask, MMS) -> % Arity 10
?vtrace("check target address with:"
"~n Name: ~s"
"~n Domain: ~p"
- "~n Ip: ~p"
- "~n Udp: ~p"
+ "~n Address: ~p"
"~n Timeout: ~p"
"~n RetryCount: ~p"
"~n TagList: ~p"
"~n Params: ~p"
"~n EngineId: ~p"
- "~n TMask: ~p"
+ "~n Mask: ~p"
"~n MMS: ~p",
- [Name,
- Domain, Ip, Udp,
+ [Name, Domain, Address,
Timeout, RetryCount,
- TagList, Params, EngineId, TMask, MMS]),
+ TagList, Params, EngineId, Mask, MMS]),
snmp_conf:check_string(Name,{gt,0}),
snmp_conf:check_domain(Domain),
- snmp_conf:check_ip(Domain, Ip),
- snmp_conf:check_integer(Udp, {gt, 0}),
+ snmp_conf:check_address(Domain, Address),
snmp_conf:check_integer(Timeout, {gte, 0}),
snmp_conf:check_integer(RetryCount, {gte,0}),
snmp_conf:check_string(TagList),
snmp_conf:check_string(Params),
check_engine_id(EngineId),
- TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp),
+ check_mask(Domain, Mask),
TDomain = snmp_conf:mk_tdomain(Domain),
- check_tmask(TDomain, TMask, TAddress),
+ TAddress = snmp_conf:mk_taddress(Domain, Address),
+ TMask = snmp_conf:mk_taddress(Domain, Mask),
snmp_conf:check_packet_size(MMS),
?vtrace("check target address done",[]),
Addr = {Name, TDomain, TAddress, Timeout,
RetryCount, TagList, Params,
?'StorageType_nonVolatile', ?'RowStatus_active', EngineId,
TMask, MMS}, % Values for Augmenting table in SNMP-COMMUNITY-MIB
- {ok, Addr};
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS}) ->
- Domain = default_domain(),
- check_target_addr({Name,
- Domain, Ip, Udp,
- Timeout, RetryCount, TagList,
- Params, EngineId, TMask, MMS});
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
- EngineId}) ->
- check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, EngineId, [], 2048});
-%% Use dummy engine id if the old style is found
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params}) ->
- check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, "dummy", [], 2048});
-%% Use dummy engine id if the old style is found
-check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params,
- TMask, MMS}) ->
- check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList,
- Params, "dummy", TMask, MMS});
-check_target_addr(X) ->
- error({invalid_target_addr, X}).
-
+ {ok, Addr}.
check_engine_id(discovery) ->
ok;
check_engine_id(EngineId) ->
snmp_conf:check_string(EngineId).
-
-check_tmask(_TDomain, [], _TAddress) ->
+check_mask(_Domain, []) ->
ok;
-check_tmask(TDomain, TMask, TAddress) when length(TMask) =:= length(TAddress) ->
- snmp_conf:check_taddress(TDomain, TMask);
-check_tmask(_TDomain, TMask, _TAddr) ->
- throw({error, {invalid_tmask, TMask}}).
-
+check_mask(Domain, Mask) ->
+ try snmp_conf:check_address(Domain, Mask)
+ catch
+ {error, {invalid_address, Info}} ->
+ {error, {invalid_mask, Info}}
+ end.
%%-----------------------------------------------------------------
%% TargetParams
diff --git a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
index 223d3f7218..69dce337ba 100644
--- a/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
+++ b/lib/snmp/src/agent/snmp_user_based_sm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -137,18 +137,20 @@ do_reconfigure(Dir) ->
read_usm_config_files(Dir) ->
?vdebug("read usm config file",[]),
- Gen = fun(D, Reason) -> generate_usm(D, Reason) end,
- Filter = fun(Usms) -> Usms end,
- Check = fun(Entry) -> check_usm(Entry) end,
+ Gen = fun (D, Reason) -> generate_usm(D, Reason) end,
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (Entry, State) -> {check_usm(Entry), State} end,
+ Filter = fun snmp_conf:no_filter/1,
[Usms] =
- snmp_conf:read_files(Dir, [{Gen, Filter, Check, "usm.conf"}]),
+ snmp_conf:read_files(Dir, [{"usm.conf", Gen, Order, Check, Filter}]),
Usms.
generate_usm(Dir, _Reason) ->
info_msg("Incomplete configuration. Generating empty usm.conf.", []),
USMFile = filename:join(Dir, "usm.conf"),
- ok = file:write_file(USMFile, list_to_binary([])).
+ ok = file:write_file(USMFile, list_to_binary([])),
+ [].
check_usm({EngineID, Name, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC,
diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
index c0177b1cea..722bd7ac5b 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1999-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
@@ -123,15 +123,18 @@ do_reconfigure(Dir) ->
read_vacm_config_files(Dir) ->
?vdebug("read vacm config file",[]),
- Gen = fun(_D, _Reason) -> ok end,
- Filter = fun(Vacms) ->
- Sec2Group = [X || {vacmSecurityToGroup, X} <- Vacms],
- Access = [X || {vacmAccess, X} <- Vacms],
- View = [X || {vacmViewTreeFamily, X} <- Vacms],
- {Sec2Group, Access, View}
- end,
- Check = fun(Entry) -> check_vacm(Entry) end,
- [Vacms] = snmp_conf:read_files(Dir, [{Gen, Filter, Check, "vacm.conf"}]),
+ Gen = fun snmp_conf:no_gen/2,
+ Order = fun snmp_conf:no_order/2,
+ Check = fun (Entry, State) -> {check_vacm(Entry), State} end,
+ Filter =
+ fun (Vacms) ->
+ Sec2Group = [X || {vacmSecurityToGroup, X} <- Vacms],
+ Access = [X || {vacmAccess, X} <- Vacms],
+ View = [X || {vacmViewTreeFamily, X} <- Vacms],
+ {Sec2Group, Access, View}
+ end,
+ [Vacms] =
+ snmp_conf:read_files(Dir, [{"vacm.conf", Gen, Order, Check, Filter}]),
Vacms.
%%-----------------------------------------------------------------
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index c17a6abbd7..a405987c8a 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2006-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
@@ -123,21 +123,24 @@ append_agent_config(Dir, Conf)
read_agent_config(Dir) ->
- Verify = fun(Entry) -> verify_agent_conf_entry(Entry) end,
- read_config_file(Dir, "agent.conf", Verify).
+ Order = fun snmp_framework_mib:order_agent/2,
+ Check = fun check_agent_conf_entry/2,
+ read_config_file(Dir, "agent.conf", Order, Check).
-
-verify_agent_conf([]) ->
+
+verify_agent_conf(Conf) ->
+ verify_agent_conf(Conf, undefined).
+%%
+verify_agent_conf([], _) ->
ok;
-verify_agent_conf([H|T]) ->
- verify_agent_conf_entry(H),
- verify_agent_conf(T);
-verify_agent_conf(X) ->
+verify_agent_conf([H|T], State) ->
+ {_, NewState} = check_agent_conf_entry(H, State),
+ verify_agent_conf(T, NewState);
+verify_agent_conf(X, _) ->
error({bad_agent_config, X}).
-verify_agent_conf_entry(Entry) ->
- ok = snmp_framework_mib:check_agent(Entry),
- ok.
+check_agent_conf_entry(Entry, State) ->
+ {ok, _NewState} = snmp_framework_mib:check_agent(Entry, State).
write_agent_conf(Fd, "", Conf) ->
write_agent_conf(Fd, Conf);
@@ -204,8 +207,12 @@ append_context_config(Dir, Conf)
read_context_config(Dir) ->
- Verify = fun(Entry) -> verify_context_conf_entry(Entry) end,
- read_config_file(Dir, "context.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_context_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "context.conf", Order, Verify).
verify_context_conf([]) ->
@@ -286,8 +293,12 @@ append_community_config(Dir, Conf)
read_community_config(Dir) ->
- Verify = fun(Entry) -> verify_community_conf_entry(Entry) end,
- read_config_file(Dir, "community.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_community_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "community.conf", Order, Verify).
verify_community_conf([]) ->
@@ -358,8 +369,12 @@ append_standard_config(Dir, Conf)
read_standard_config(Dir) ->
- Verify = fun(Entry) -> verify_standard_conf_entry(Entry) end,
- read_config_file(Dir, "standard.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_standard_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "standard.conf", Order, Verify).
verify_standard_conf([]) ->
@@ -520,8 +535,12 @@ append_target_addr_config(Dir, Conf)
read_target_addr_config(Dir) ->
- Verify = fun(Entry) -> verify_target_addr_conf_entry(Entry) end,
- read_config_file(Dir, "target_addr.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_target_addr_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "target_addr.conf", Order, Verify).
verify_target_addr_conf([]) ->
@@ -626,8 +645,12 @@ append_target_params_config(Dir, Conf)
read_target_params_config(Dir) ->
- Verify = fun(Entry) -> verify_target_params_conf_entry(Entry) end,
- read_config_file(Dir, "target_params.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_target_params_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "target_params.conf", Order, Verify).
verify_target_params_conf([]) ->
@@ -698,8 +721,12 @@ append_notify_config(Dir, Conf)
read_notify_config(Dir) ->
- Verify = fun(Entry) -> verify_notify_conf_entry(Entry) end,
- read_config_file(Dir, "notify.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_notify_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "notify.conf", Order, Verify).
verify_notify_conf([]) ->
@@ -794,8 +821,12 @@ append_usm_config(Dir, Conf)
read_usm_config(Dir) ->
- Verify = fun(Entry) -> verify_usm_conf_entry(Entry) end,
- read_config_file(Dir, "usm.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_usm_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "usm.conf", Order, Verify).
verify_usm_conf([]) ->
@@ -903,8 +934,12 @@ append_vacm_config(Dir, Conf)
read_vacm_config(Dir) ->
- Verify = fun(Entry) -> verify_vacm_conf_entry(Entry) end,
- read_config_file(Dir, "vacm.conf", Verify).
+ Order = fun snmp_conf:no_order/2,
+ Verify =
+ fun (Entry, State) ->
+ {verify_vacm_conf_entry(Entry), State}
+ end,
+ read_config_file(Dir, "vacm.conf", Order, Verify).
verify_vacm_conf([]) ->
@@ -958,8 +993,8 @@ write_config_file(Dir, File, Verify, Write) ->
append_config_file(Dir, File, Verify, Write) ->
snmp_config:append_config_file(Dir, File, Verify, Write).
-read_config_file(Dir, File, Verify) ->
- snmp_config:read_config_file(Dir, File, Verify).
+read_config_file(Dir, File, Order, Check) ->
+ snmp_config:read_config_file(Dir, File, Order, Check).
%% ---- config file utility functions ----
@@ -972,6 +1007,5 @@ header() ->
"~2.2.0w:~2.2.0w:~2.2.0w\n",
[?MODULE, ?version, Y, Mo, D, H, Mi, S]).
-
error(R) ->
throw({error, R}).
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 11ae806866..9bb4556788 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1997-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1997-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
@@ -183,11 +183,30 @@ discarded_pdu(Variable) -> inc(Variable).
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-v1_v2c_proc(Vsn, NoteStore, Community, Domain,
- {Ip, Udp}, LocalEngineID,
- Data, HS, Log, Packet) ->
+v1_v2c_proc(
+ Vsn, NoteStore, Community, Domain, Address,
+ LocalEngineID, Data, HS, Log, Packet) ->
+ try snmp_conf:check_domain(Domain) of
+ ok ->
+ try snmp_conf:check_address(Domain, Address) of
+ ok ->
+ v1_v2c_proc_dec(
+ Vsn, NoteStore, Community, Domain, Address,
+ LocalEngineID, Data, HS, Log, Packet)
+ catch
+ _ ->
+ {discarded, {badarg, Address}}
+ end
+ catch
+ _ ->
+ {discarded, {badarg, Domain}}
+ end.
+
+v1_v2c_proc_dec(
+ Vsn, NoteStore, Community, Domain, Address,
+ LocalEngineID, Data, HS, Log, Packet) ->
TDomain = snmp_conf:mk_tdomain(Domain),
- TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp),
+ TAddress = snmp_conf:mk_taddress(Domain, Address),
AgentMS = get_engine_max_message_size(LocalEngineID),
MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress),
PduMS = case MgrMS of
@@ -214,7 +233,7 @@ v1_v2c_proc(Vsn, NoteStore, Community, Domain,
case Pdu#pdu.type of
'set-request' ->
%% Check if this message has already been processed
- Key = {agent, Ip, ReqId},
+ Key = {agent, {Domain, Address}, ReqId},
case snmp_note_store:get_note(NoteStore, Key) of
undefined ->
%% Set the processed note _after_ pdu processing.
@@ -236,13 +255,7 @@ v1_v2c_proc(Vsn, NoteStore, Community, Domain,
{discarded, Reason};
_TrapPdu ->
{discarded, trap_pdu}
- end;
-v1_v2c_proc(_Vsn, _NoteStore, _Community, snmpUDPDomain, TAddress,
- _LocalEngineID, _Data, _HS, _Log, _Packet) ->
- {discarded, {badarg, TAddress}};
-v1_v2c_proc(_Vsn, _NoteStore, _Community, TDomain, _TAddress,
- _LocalEngineID, _Data, _HS, _Log, _Packet) ->
- {discarded, {badarg, TDomain}}.
+ end.
sec_model('version-1') -> ?SEC_V1;
sec_model('version-2') -> ?SEC_V2C.
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index 2101ad46e1..43d394e9d9 100644
--- a/lib/snmp/src/manager/snmpm_config.erl
+++ b/lib/snmp/src/manager/snmpm_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2013. 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
@@ -1666,7 +1666,7 @@ init_agent_default(Item, Val) when Item =/= user_id ->
read_agents_config_file(Dir) ->
- Check = fun(C) -> check_agent_config2(C) end,
+ Check = fun(C, S) -> {check_agent_config2(C), S} end,
case read_file(Dir, "agents.conf", Check, []) of
{ok, Conf} ->
Conf;
@@ -1837,7 +1837,7 @@ verify_agent2([Bad|_], _VerifiedConf) ->
read_users_config_file(Dir) ->
- Check = fun(C) -> check_user_config(C) end,
+ Check = fun(C, S) -> {check_user_config(C), S} end,
case read_file(Dir, "users.conf", Check, []) of
{ok, Conf} ->
Conf;
@@ -1950,7 +1950,7 @@ verify_user_agent_config(Conf) ->
end.
read_usm_config_file(Dir) ->
- Check = fun(C) -> check_usm_user_config(C) end,
+ Check = fun(C, S) -> {check_usm_user_config(C), S} end,
case read_file(Dir, "usm.conf", Check, []) of
{ok, Conf} ->
Conf;
@@ -2139,7 +2139,7 @@ is_crypto_supported(Func) ->
read_manager_config_file(Dir) ->
- Check = fun(Conf) -> check_manager_config(Conf) end,
+ Check = fun(Conf, State) -> {check_manager_config(Conf), State} end,
case read_file(Dir, "manager.conf", Check) of
{ok, Conf} ->
?d("read_manager_config_file -> ok: "
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index 46625989d5..c52b4bb6fb 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -25,7 +25,8 @@
%% External exports
%% Avoid warning for local function error/1 clashing with autoimported BIF.
-compile({no_auto_import,[error/1]}).
--export([read_files/2, read/2]).
+-export([read_files/2, no_gen/2, no_order/2, no_filter/1]).
+-export([read/2, read/3]).
%% Basic (type) check functions
-export([check_mandatory/2,
@@ -43,9 +44,10 @@
check_tdomain/1,
mk_tdomain/1,
which_domain/1,
- check_ip/1, check_ip/2,
- check_taddress/1, check_taddress/2,
- mk_taddress/3,
+ check_ip/1, check_ip/2,
+ check_address/2,
+ check_taddress/2,
+ mk_taddress/2, mk_taddress/3,
check_packet_size/1,
@@ -70,17 +72,53 @@
-include("snmp_verbosity.hrl").
+-define(is_word(P), (((P) band (bnot 65535)) =:= 0)).
+-define(is_word(P0, P1), ((((P0) bor (P1)) band (bnot 255)) =:= 0)).
+
+mk_word(B0, B1) -> ((B0) bsl 8) bor (B1).
+mk_bytes(W) -> [(W) bsr 8,(W) band 255].
+
+-define(
+ is_ipv4_addr(A0, A1, A2, A3),
+ ((((A0) bor (A1) bor (A2) bor (A3)) band (bnot 255)) =:= 0)).
+
+-define(
+ is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ((((A0) bor (A1) bor (A2) bor (A3) bor (A4) bor (A5) bor (A6) bor (A7))
+ band (bnot 65535)) =:= 0)).
+-define(
+ is_ipv6_addr(
+ A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15),
+ ((((A0) bor (A1) bor (A2) bor (A3) bor
+ (A4) bor (A5) bor (A6) bor (A7) bor
+ (A8) bor (A9) bor (A10) bor (A11) bor
+ (A12) bor (A13) bor (A14) bor (A15))
+ band (bnot 65535)) =:= 0)).
+
+
%%-----------------------------------------------------------------
%% read_files(Dir, Files) -> Configs
%% Dir - string() - Full path to the config dir.
-%% Files - [{Gen, Filter, Check, FileName}]
+%% Files - [{FileName, Gen, Order, Check, Filter}]
+%% FileName - string() - Name of the config file.
%% Gen - function/2 - In case of failure when reading the config file,
%% this function is called to either generate a
%% default file or issue the error.
-%% Filter - function/1 - Filters all the config entries read from the file
-%% Check - function/1 - Check each entry as they are read from the file.
-%% FileName - string() - Name of the config file.
+%% Returns a generated config list corresponding
+%% to the written file.
+%% (Dir, Error) -> Configs.
+%% Order - function/2 - An ordering function that is used to process
+%% the read config entries using lists:sort/2.
+%% Returns true if arg 1 compares less than or
+%% equal to arg 2, false otherwise.
+%% Check - function/2 - Check each entry as they are read from the file.
+%% (Entry, State) ->
+%% {ok,NewState} | {{ok,NewEntry},NewState} |
+%% throw(Error)
+%% State =:= 'undefined' the first time.
+%% Filter - function/1 - Process all the config entries read from the file
+%% (Configs) -> [config_entry()].
%% Configs - [config_entry()]
%% config_entry() - term()
@@ -89,24 +127,122 @@ read_files(Dir, Files) when is_list(Dir) andalso is_list(Files) ->
read_files(_Dir, [], Res) ->
lists:reverse(Res);
-read_files(Dir, [{Gen, Filter, Check, FileName}|Files], Res)
- when is_function(Filter) andalso
- is_function(Check) andalso
- is_list(FileName) ->
- ?vdebug("read_files -> entry with"
- "~n FileName: ~p", [FileName]),
+read_files(Dir, [{FileName, Gen, Order, Check, Filter}|Files], Res)
+ when is_list(FileName),
+ is_function(Gen),
+ is_function(Order),
+ is_function(Check),
+ is_function(Filter) ->
+ ?vdebug("read_files -> entry with~n"
+ " FileName: ~p", [FileName]),
File = filename:join(Dir, FileName),
- case file:read_file_info(File) of
- {ok, _} ->
- Confs = read(File, Check),
- read_files(Dir, Files, [Filter(Confs)|Res]);
- {error, R} ->
- ?vlog("failed reading file info for ~s: "
- "~n ~p", [FileName, R]),
- Gen(Dir, R),
- read_files(Dir, Files, [Filter([])|Res])
+ Confs =
+ case file:read_file_info(File) of
+ {ok,_} ->
+ read(File, Order, Check);
+ {error, R} ->
+ ?vlog("failed reading file info for ~s: ~n"
+ " ~p", [FileName, R]),
+ Gen(Dir, R)
+ end,
+ read_files(Dir, Files, [Filter(Confs)|Res]).
+%% %%
+%% %% XXX remove
+%% %%
+%% %% read_files(Dir, Files) -> Configs
+%% %% Dir - string() - Full path to the config dir.
+%% %% Files - [{Gen, Filter, Check, FileName}]
+%% %% Gen - function/2 - In case of failure when reading the config file,
+%% %% this function is called to either generate a
+%% %% default file or issue the error.
+%% %% Filter - function/1 - Filters all the config entries read from the file
+%% %% Check - function/1 - Check each entry as they are read from the file.
+%% %% FileName - string() - Name of the config file.
+%% %% Configs - [config_entry()]
+%% %% config_entry() - term()
+%%
+%% read_files(Dir, [{Gen, Filter, Check, FileName}|Files], Res)
+%% when is_function(Filter) andalso
+%% is_function(Check) andalso
+%% is_list(FileName) ->
+%% ?vdebug("read_files -> entry with"
+%% "~n FileName: ~p", [FileName]),
+%% File = filename:join(Dir, FileName),
+%% case file:read_file_info(File) of
+%% {ok, _} ->
+%% Confs = read(File, Check),
+%% read_files(Dir, Files, [Filter(Confs)|Res]);
+%% {error, R} ->
+%% ?vlog("failed reading file info for ~s: "
+%% "~n ~p", [FileName, R]),
+%% Gen(Dir, R),
+%% read_files(Dir, Files, [Filter([])|Res])
+%% end.
+
+no_gen(_Dir, _R) -> [].
+no_order(_, _) -> true.
+no_filter(X) -> X.
+
+
+
+%% Ret. Res | exit(Reason)
+read(File, Order, Check) when is_function(Order), is_function(Check) ->
+ ?vdebug("read -> entry with~n"
+ " File: ~p", [File]),
+ Fd = open_file(File),
+ read_fd(File, Order, Check, Fd, 1, []).
+
+read_fd(File, Order, Check, Fd, StartLine, Res) ->
+ case do_read(Fd, "", StartLine) of
+ {ok, Row, EndLine} ->
+ ?vtrace("read_fd ->~n"
+ " Row: ~p~n"
+ " EndLine: ~p", [Row,EndLine]),
+ read_fd(
+ File, Order, Check, Fd, EndLine,
+ [{StartLine, Row, EndLine}|Res]);
+ {error, Error, EndLine} ->
+ ?vtrace("read_fd -> read failure:~n"
+ " Error: ~p~n"
+ " EndLine: ~p", [Error,EndLine]),
+ file:close(Fd),
+ error({failed_reading, File, StartLine, EndLine, Error});
+ {eof, _EndLine} ->
+ Lines =
+ lists:sort(
+ fun ({_, RowA, _}, {_, RowB, _}) ->
+ Order(RowA, RowB)
+ end,
+ lists:reverse(Res)),
+ read_check(File, Check, Lines, undefined, [])
end.
+read_check(_, _, [], _, Res) ->
+ lists:reverse(Res);
+read_check(File, Check, [{StartLine, Row, EndLine}|Lines], State, Res) ->
+ try Check(Row, State) of
+ {ok, NewState} ->
+ ?vtrace("read_check -> ok", []),
+ read_check(File, Check, Lines, NewState, [Row|Res]);
+ {{ok, NewRow}, NewState} ->
+ ?vtrace("read_check -> ok:~n"
+ " NewRow: ~p~n", [NewRow]),
+ read_check(File, Check, Lines, NewState, [NewRow|Res])
+ catch
+ {error, Reason} ->
+ ?vtrace("read_check -> error:~n"
+ " Reason: ~p", [Reason]),
+ error({failed_check, File, StartLine, EndLine, Reason});
+ Class:Reason ->
+ Error = {Class,Reason,erlang:get_stacktrace()},
+ ?vtrace("read_check -> failure:~n"
+ " Error: ~p", [Error]),
+ error({failed_check, File, StartLine, EndLine, Error})
+ end.
+
+
+
+%% XXX remove
%% Ret. Res | exit(Reason)
read(File, Check) when is_function(Check) ->
@@ -155,11 +291,11 @@ loop(Fd, Res, Check, StartLine, File) ->
"~n Error: ~p", [Error]),
{error, {failed_check, File, StartLine, EndLine, Error}}
end;
- {error, EndLine, Error} ->
+ {error, Error, EndLine} ->
?vtrace("loop -> read failure: "
"~n Error: ~p", [Error]),
{error, {failed_reading, File, StartLine, EndLine, Error}};
- eof ->
+ {eof, _EndLine} ->
{ok, Res}
end.
@@ -171,12 +307,8 @@ do_read(Io, Prompt, StartLine) ->
{ok, Term} ->
{ok, Term, EndLine};
{error, {Line, erl_parse, Error}} ->
- {error, Line, {parse_error, Error}}
+ {error, {parse_error, Error}, Line}
end;
- {error,E,EndLine} ->
- {error, EndLine, E};
- {eof, _EndLine} ->
- eof;
Other ->
Other
end.
@@ -384,7 +516,7 @@ all_tdomains() ->
check_tdomain(TDomain) ->
SupportedTDomains =
[
- ?snmpUDPDomain,
+ ?snmpUDPDomain, % Legacy
?transportDomainUdpIpv4,
?transportDomainUdpIpv6
],
@@ -416,40 +548,38 @@ mk_tdomain(BadDomain) ->
%% ---------
-check_taddress(X) ->
- check_taddress(snmpUDPDomain, X).
+%% XXX remove
+%% check_taddress(X) ->
+%% check_taddress(snmpUDPDomain, X).
check_taddress(?snmpUDPDomain, X) ->
check_taddress(transportDomainUdpIpv4, X);
check_taddress(snmpUDPDomain, X) ->
check_taddress(transportDomainUdpIpv4, X);
-
+%%
check_taddress(?transportDomainUdpIpv4, X) ->
check_taddress(transportDomainUdpIpv4, X);
-check_taddress(transportDomainUdpIpv4, X)
- when is_list(X) andalso (length(X) =:= 6) ->
- case (catch all_integer(X)) of
- true ->
+check_taddress(transportDomainUdpIpv4, X) ->
+ case X of
+ [A0,A1,A2,A3,P0,P1]
+ when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) ->
ok;
- false ->
+ _ ->
error({invalid_taddress, X})
end;
-check_taddress(transportDomainUdpIpv4, X) ->
- error({invalid_taddress, X});
-
+%%
check_taddress(?transportDomainUdpIpv6, X) ->
check_taddress(transportDomainUdpIpv6, X);
-check_taddress(transportDomainUdpIpv6, X)
- when is_list(X) andalso (length(X) =:= 10) ->
- case (catch all_integer(X)) of
- true ->
+check_taddress(transportDomainUdpIpv6, X) ->
+ case X of
+ [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P0, P1) ->
ok;
- false ->
+ _ ->
error({invalid_taddress, X})
end;
-check_taddress(transportDomainUdpIpv6, X) ->
- error({invalid_taddress, X});
-
+%%
check_taddress(BadDomain, _X) ->
error({invalid_tdomain, BadDomain}).
@@ -512,31 +642,65 @@ all_domains() ->
transportDomainSctpDns
].
+check_domain(snmpUDPDomain) -> ok;
+check_domain(transportDomainUdpIpv4) -> ok;
+check_domain(transportDomainUdpIpv6) -> ok;
check_domain(Domain) ->
- SupportedDomains =
- [
- snmpUDPDomain,
- transportDomainUdpIpv4,
- transportDomainUdpIpv6
- ],
- AllDomains = all_domains(),
- case lists:member(Domain, SupportedDomains) of
+ case lists:member(Domain, all_domains()) of
true ->
- ok;
+ error({unsupported_domain, Domain});
false ->
- case lists:member(Domain, AllDomains) of
- true ->
- error({unsupported_domain, Domain});
- false ->
- error({unknown_domain, Domain})
- end
+ error({unknown_domain, Domain})
end.
-
+
%% ---------
-%% The values of Ip and Port has both been checked at this
+%% The values of Domain, Ip and Port has both been checked at this
%% point, so we dont need to do that again.
+
+mk_taddress(snmpUDPDomain, Address) ->
+ mk_taddress(transportDomainUdpIpv4, Address);
+mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_list(Ip) ->
+ Ip ++ mk_bytes(Port);
+mk_taddress(transportDomainUdpIpv4, {Ip, Port}) when is_tuple(Ip) ->
+ tuple_to_list(Ip) ++ mk_bytes(Port);
+mk_taddress(transportDomainUdpIpv4, IpPort) when is_list(IpPort) ->
+ IpPort; % Should be length 6
+mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_list(Ip) ->
+ Ip ++ mk_bytes(Port);
+mk_taddress(transportDomainUdpIpv6, {Ip, Port}) when is_tuple(Ip) ->
+ tuple_to_list(Ip) ++ mk_bytes(Port);
+mk_taddress(transportDomainUdpIpv6, IpPort) when is_list(IpPort) ->
+ case IpPort of
+ [A0,A1,A2,A3,A4,A5,A6,A7,P] ->
+ [A0,A1,A2,A3,A4,A5,A6,A7] ++ mk_bytes(P);
+ [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1] ->
+ [mk_word(A0, A1),mk_word(A2, A3),
+ mk_word(A4, A5),mk_word(A6, A7),
+ mk_word(A8, A9),mk_word(A10, A11),
+ mk_word(A12, A13),mk_word(A14, A15),P0,P1];
+ _ ->
+ IpPort % Should already be 8 words and 2 bytes hence length 10
+ end;
+mk_taddress(Domain, Address) when is_atom(Domain) ->
+ erlang:error(badarg, [Domain,Address]);
+%%
+%% These are just for convenience
+mk_taddress(?snmpUDPDomain, Address) ->
+ mk_taddress(snmpUDPDomain, Address);
+mk_taddress(?transportDomainUdpIpv4, Address) ->
+ mk_taddress(transportDomainUdpIpv4, Address);
+mk_taddress(?transportDomainUdpIpv6, Address) ->
+ mk_taddress(transportDomainUdpIpv6, Address);
+%% Bad domain
+mk_taddress(BadDomain, _) ->
+ error({bad_domain, BadDomain}).
+
+
+
+%% XXX remove
+
mk_taddress(snmpUDPDomain, Ip, Port) ->
mk_taddress(transportDomainUdpIpv4, Ip, Port);
mk_taddress(transportDomainUdpIpv4, Ip, Port) when is_list(Ip) ->
@@ -547,7 +711,7 @@ mk_taddress(transportDomainUdpIpv6, Ip, Port) when is_list(Ip) ->
Ip ++ [Port div 256, Port rem 256];
mk_taddress(transportDomainUdpIpv6 = Domain, Ip, Port) when is_tuple(Ip) ->
mk_taddress(Domain, tuple_to_list(Ip), Port);
-
+%%
%% These are just for convenience
mk_taddress(?snmpUDPDomain, Ip, Port) ->
mk_taddress(snmpUDPDomain, Ip, Port);
@@ -555,7 +719,7 @@ mk_taddress(?transportDomainUdpIpv4, Ip, Port) ->
mk_taddress(transportDomainUdpIpv4, Ip, Port);
mk_taddress(?transportDomainUdpIpv6, Ip, Port) ->
mk_taddress(transportDomainUdpIpv6, Ip, Port);
-
+%%
%% Bad domain
mk_taddress(BadDomain, _Ip, _Port) ->
error({bad_domain, BadDomain}).
@@ -563,47 +727,113 @@ mk_taddress(BadDomain, _Ip, _Port) ->
%% ---------
-which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 4) ->
+%% XXX remove
+
+which_domain([A0,A1,A2,A3]) when ?is_ipv4_addr(A0, A1, A2, A3) ->
transportDomainUdpIpv4;
-which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 4) ->
+which_domain({A0,A1,A2,A3}) when ?is_ipv4_addr(A0, A1, A2, A3) ->
transportDomainUdpIpv4;
-which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 8) ->
+which_domain([A0,A1,A2,A3,A4,A5,A6,A7])
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) ->
transportDomainUdpIpv6;
-which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 8) ->
+which_domain({A0, A1, A2, A3, A4, A5, A6, A7})
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7) ->
transportDomainUdpIpv6.
%% ---------
+%% XXX remove
+
check_ip(X) ->
check_ip(snmpUDPDomain, X).
check_ip(snmpUDPDomain, X) ->
check_ip(transportDomainUdpIpv4, X);
-check_ip(transportDomainUdpIpv4, X) when is_list(X) andalso (length(X) =:= 4) ->
- case (catch all_integer(X)) of
- true ->
+check_ip(transportDomainUdpIpv4, X) ->
+ case X of
+ [A,B,C,D] when ?is_ipv4_addr(A, B, C, D) ->
ok;
- false ->
+ _ ->
error({invalid_ip_address, X})
end;
-check_ip(transportDomainUdpIpv4, X) ->
- error({invalid_ip_address, X});
-
-check_ip(transportDomainUdpIpv6, X) when is_list(X) andalso (length(X) =:= 8) ->
- case (catch all_integer(X)) of
- true ->
+check_ip(transportDomainUdpIpv6, X) ->
+ case X of
+ [A,B,C,D,E,F,G,H]
+ when ?is_ipv6_addr(A, B, C, D, E, F, G, H) ->
ok;
- false ->
+ [A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P]
+ when ?is_ipv6_addr(
+ A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P) ->
+ ok;
+ _ ->
error({invalid_ip_address, X})
end;
-check_ip(transportDomainUdpIpv6, X) ->
- error({invalid_ip_address, X});
-
+%%
check_ip(BadDomain, _X) ->
error({invalid_domain, BadDomain}).
+%% ---------
+
+%% Check a configuration term field from a file to see if it
+%% can be fed to mk_taddress/2.
+
+check_address(Domain, Address)
+ when Domain =:= snmpUDPDomain;
+ Domain =:= transportDomainUdpIpv4 ->
+ case Address of
+ %% Erlang native format
+ {{A0, A1, A2, A3}, P}
+ when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P) ->
+ ok;
+ %% Erlangish format
+ {[A0,A1,A2,A3], P}
+ when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P) ->
+ ok;
+ %% SNMP standards format
+ [A0,A1,A2,A3,P0,P1]
+ when ?is_ipv4_addr(A0, A1, A2, A3), ?is_word(P0, P1) ->
+ ok;
+ _ ->
+ error({invalid_address, {Domain, Address}})
+ end;
+check_address(transportDomainUdpIpv6 = Domain, Address) ->
+ case Address of
+ %% Erlang native format
+ {{A0, A1, A2, A3, A4, A5, A6, A7}, P}
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P) ->
+ ok;
+ %% Erlangish format
+ {[A0,A1,A2,A3,A4,A5,A6,A7], P}
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P) ->
+ ok;
+ %% Erlang friendly list format
+ [A0,A1,A2,A3,A4,A5,A6,A7,P]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P) ->
+ ok;
+ %% Strange hybrid format with port as bytes
+ [A0,A1,A2,A3,A4,A5,A6,A7,P0,P1]
+ when ?is_ipv6_addr(A0, A1, A2, A3, A4, A5, A6, A7),
+ ?is_word(P0, P1) ->
+ ok;
+ %% SNMP standards format
+ [A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,P0,P1]
+ when ?is_ipv6_addr(
+ A0, A1, A2, A3, A4, A5, A6, A7,
+ A8, A9, A10, A11, A12, A13, A14, A15),
+ ?is_word(P0, P1) ->
+ ok;
+ _ ->
+ error({invalid_address, {Domain, Address}})
+ end;
+check_address(BadDomain, _) ->
+ error({invalid_domain, BadDomain}).
+
+
%% ---------
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index a222f842e5..ec6b2ac7e4 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2013. All Rights Reserved.
+%% Copyright Ericsson AB 1996-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
@@ -26,7 +26,8 @@
-compile({no_auto_import,[error/1]}).
-export([config/0]).
--export([write_config_file/4, append_config_file/4, read_config_file/3]).
+-export([write_config_file/4, append_config_file/4,
+ read_config_file/3, read_config_file/4]).
-export([write_agent_snmp_files/7, write_agent_snmp_files/12,
@@ -2471,7 +2472,9 @@ append_config_file(Dir, FileName, Verify, Write)
throw:Error ->
Error;
T:E ->
- {error, {failed_append, Dir, FileName, T, E}}
+ {error,
+ {failed_append, Dir, FileName,
+ {T, E, erlang:get_stacktrace()}}}
end.
do_append_config_file(Dir, FileName, Verify, Write) ->
@@ -2500,59 +2503,131 @@ file_write_and_close(Write, Fd, Dir, FileName) ->
end.
+%% XXX remove
+read_config_file(Dir, FileName, Verify) ->
+ read_config_file(
+ Dir, FileName, fun snmp_conf:no_order/2,
+ fun (Term, State) ->
+ {Verify(Term), State}
+ end).
+
-spec read_config_file(Dir :: string(),
- FileName :: string(),
- Verify :: verify_config_entry_function()) ->
+ FileName :: string(),
+ Order :: function(),
+ Verify :: function()) ->
{ok, Config :: list()} | {error, Reason :: term()}.
-read_config_file(Dir, FileName, Verify)
- when is_list(Dir) andalso is_list(FileName) andalso is_function(Verify) ->
- (catch do_read_config_file(Dir, FileName, Verify)).
-
-do_read_config_file(Dir, FileName, Verify) ->
+read_config_file(Dir, FileName, Order, Check)
+ when is_list(Dir), is_list(FileName),
+ is_function(Order), is_function(Check) ->
case file:open(filename:join(Dir, FileName), [read]) of
{ok, Fd} ->
- Result = read_loop(Fd, [], Verify, 1),
- file:close(Fd),
- Result;
+ try
+ {ok,
+ verify_lines(
+ lists:sort(
+ fun ({_, T1, _}, {_, T2, _}) ->
+ Order(T1, T2)
+ end,
+ read_lines(Fd, [], 1)),
+ Check, undefined, [])}
+ catch
+ Error ->
+ {error, Error}
+ after
+ file:close(Fd)
+ end;
{error, Reason} ->
{error, {Reason, FileName}}
end.
-read_loop(Fd, Acc, Check, StartLine) ->
- case read_term(Fd, StartLine) of
+read_lines(Fd, Acc, StartLine) ->
+ case read_and_parse_term(Fd, StartLine) of
{ok, Term, EndLine} ->
- case (catch Check(Term)) of
- ok ->
- read_loop(Fd, [Term | Acc], Check, EndLine);
- {error, Reason} ->
- {error, {failed_check, StartLine, EndLine, Reason}};
- Error ->
- {error, {failed_check, StartLine, EndLine, Error}}
- end;
- {error, EndLine, Error} ->
- {error, {failed_reading, StartLine, EndLine, Error}};
- eof ->
- {ok, lists:reverse(Acc)}
+ read_lines(Fd, [{StartLine, Term, EndLine}|Acc], EndLine);
+ {error, Error, EndLine} ->
+ throw({failed_reading, StartLine, EndLine, Error});
+ {eof, _EndLine} ->
+ lists:reverse(Acc)
end.
-
-read_term(Fd, StartLine) ->
+
+read_and_parse_term(Fd, StartLine) ->
case io:request(Fd, {get_until, "", erl_scan, tokens, [StartLine]}) of
{ok, Tokens, EndLine} ->
case erl_parse:parse_term(Tokens) of
{ok, Term} ->
{ok, Term, EndLine};
{error, {Line, erl_parse, Error}} ->
- {error, Line, {parse_error, Error}}
+ {error, {parse_error, Error}, Line}
end;
- {error, E, EndLine} ->
- {error, EndLine, E};
- {eof, _EndLine} ->
- eof;
Other ->
Other
end.
+verify_lines([], _, Acc, _) ->
+ list:reverse(Acc);
+verify_lines(
+ [{StartLine, Term, EndLine}|Lines], State, Acc, Check) ->
+ try Check(Term, State) of
+ {ok, NewState} ->
+ verify_lines(Lines, NewState, [Term|Acc], Check);
+ {{ok, NewTerm}, NewState} ->
+ verify_lines(Lines, NewState, [NewTerm|Acc], Check)
+ catch
+ {error, Reason} ->
+ throw({failed_check, StartLine, EndLine, Reason});
+ C:R ->
+ S = erlang:get_stacktrace(),
+ throw({failed_check, StartLine, EndLine, {C, R, S}})
+ end.
+
+
+%% XXX remove
+
+%% do_read_config_file(Dir, FileName, Verify) ->
+%% case file:open(filename:join(Dir, FileName), [read]) of
+%% {ok, Fd} ->
+%% Result = read_loop(Fd, [], Verify, 1),
+%% file:close(Fd),
+%% Result;
+%% {error, Reason} ->
+%% {error, {Reason, FileName}}
+%% end.
+
+%% read_loop(Fd, Acc, Check, StartLine) ->
+%% case read_term(Fd, StartLine) of
+%% {ok, Term, EndLine} ->
+%% case (catch Check(Term)) of
+%% ok ->
+%% read_loop(Fd, [Term | Acc], Check, EndLine);
+%% {error, Reason} ->
+%% {error, {failed_check, StartLine, EndLine, Reason}};
+%% Error ->
+%% {error, {failed_check, StartLine, EndLine, Error}}
+%% end;
+%% {error, EndLine, Error} ->
+%% {error, {failed_reading, StartLine, EndLine, Error}};
+%% eof ->
+%% {ok, lists:reverse(Acc)}
+%% end.
+
+%% read_term(Fd, StartLine) ->
+%% case io:request(Fd, {get_until, "", erl_scan, tokens, [StartLine]}) of
+%% {ok, Tokens, EndLine} ->
+%% case erl_parse:parse_term(Tokens) of
+%% {ok, Term} ->
+%% {ok, Term, EndLine};
+%% {error, {Line, erl_parse, Error}} ->
+%% {error, Line, {parse_error, Error}}
+%% end;
+%% {error, E, EndLine} ->
+%% {error, EndLine, E};
+%% {eof, _EndLine} ->
+%% eof;
+%% Other ->
+%% Other
+%% end.
+
agent_snmp_mk_secret(Alg, Passwd, EngineID) ->
snmp_usm:passwd2localized_key(Alg, Passwd, EngineID).