aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/snmp/Makefile5
-rw-r--r--lib/snmp/doc/src/Makefile4
-rw-r--r--lib/snmp/doc/src/notes.xml130
-rw-r--r--lib/snmp/doc/src/snmpc.xml15
-rw-r--r--lib/snmp/doc/src/snmpc_cmd.xml28
-rw-r--r--lib/snmp/doc/src/snmpm.xml40
-rw-r--r--lib/snmp/src/agent/snmp_view_based_acm_mib.erl6
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl2
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl9
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl104
-rw-r--r--lib/snmp/src/app/snmp.appup.src226
-rw-r--r--lib/snmp/src/compile/Makefile11
-rw-r--r--lib/snmp/src/compile/snmpc.erl9
-rw-r--r--lib/snmp/src/compile/snmpc.src14
-rw-r--r--lib/snmp/src/compile/snmpc_lib.hrl15
-rw-r--r--lib/snmp/src/manager/snmpm.erl8
-rw-r--r--lib/snmp/src/manager/snmpm_config.erl515
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl47
-rw-r--r--lib/snmp/src/manager/snmpm_net_if.erl31
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl77
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl83
-rw-r--r--lib/snmp/src/misc/snmp_config.erl10
-rw-r--r--lib/snmp/test/snmp_compiler_test.erl47
-rw-r--r--lib/snmp/test/snmp_manager_test.erl185
-rw-r--r--lib/snmp/vsn.mk2
-rw-r--r--lib/stdlib/src/io_lib_fread.erl64
-rw-r--r--lib/stdlib/test/ets_SUITE.erl57
-rw-r--r--lib/stdlib/test/io_SUITE.erl30
28 files changed, 1271 insertions, 503 deletions
diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile
index 20e3d4692a..c55eff04c6 100644
--- a/lib/snmp/Makefile
+++ b/lib/snmp/Makefile
@@ -67,7 +67,7 @@ do_configure: configure
configure: configure.in
autoconf
-.PHONY: info
+.PHONY: info gclean
info:
@echo "OS: $(OS)"
@@ -76,6 +76,9 @@ info:
@echo "SNMP_VSN: $(SNMP_VSN)"
@echo "APP_VSN: $(APP_VSN)"
+gclean:
+ git clean -fXd
+
# ----------------------------------------------------
# Application (source) release targets
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile
index 35ed63e103..aa9431477c 100644
--- a/lib/snmp/doc/src/Makefile
+++ b/lib/snmp/doc/src/Makefile
@@ -152,6 +152,7 @@ $(TOP_PDF_FILE): $(XML_FILES)
pdf: $(TOP_PDF_FILE)
html: gifs $(HTML_REF_MAN_FILE)
+html2: html $(INDEX_TARGET)
clean clean_docs: clean_html clean_man clean_pdf
rm -f errs core *~
@@ -228,6 +229,7 @@ clean_man:
clean_html:
@echo "cleaning html:"
rm -rf $(HTMLDIR)/*
+ rm -f $(INDEX_TARGET)
$(MAN7DIR)/%.7: $(MIBSDIR)/%.mib
@echo "processing $*"
@@ -286,7 +288,7 @@ release_docs_spec: docs
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
$(INSTALL_DIR) $(RELEASE_PATH)/man/man1
$(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1
- $(INSTALL_DIR) $(RELEASE_PATH)/man/man
+ $(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3
$(INSTALL_DIR) $(RELEASE_PATH)/man/man6
$(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 6a20d8ee3a..4178192120 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,6 +33,136 @@
</header>
<section>
+ <title>SNMP Development Toolkit 4.21</title>
+ <p>Version 4.21 supports code replacement in runtime from/to
+ version 4.20.1, 4.20 and 4.19. </p>
+
+ <section>
+ <title>Improvements and new features</title>
+<!--
+ <p>-</p>
+-->
+ <list type="bulleted">
+ <item>
+ <p>[manager] There was no way to specify transport domain.
+ The transport domains was assumed to be IPv4 (transportDomainUdpIpv4).
+ This has now been changed so that it can also be IPv6
+ (transportDomainUdpIpv6).
+ To facilitate this, the transport domain, <c>tdomain</c>,
+ is now a (new) valid option when
+ <seealso marker="snmpm#register_agent">registering</seealso>
+ a new agent (and
+ <seealso marker="snmpm#update_agent_info">updating</seealso>
+ agent info). </p>
+ <p>This also mean that the transport behaviour has changed. </p>
+ <p>Own Id: OTP-9305</p>
+ <p>Aux Id: Seq 11847</p>
+ </item>
+
+ <item>
+ <p>[compiler] Added the option
+ <seealso marker="snmpc#compile">warnings_as_errors</seealso>
+ (for the SNMP MIB compiler (escript) frontend, the option
+ <seealso marker="snmpc(command)#option_wae">--wae</seealso> is used)
+ which specifies whether warnings should be treated as errors. </p>
+ <p>Tuncer Ayaz</p>
+ <p>Own Id: OTP-9437</p>
+ </item>
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>The snmp config tool could not handle (manager) audit trail config
+ because the option seqno was not handled. </p>
+ <p>Own Id: OTP-9354</p>
+ </item>
+
+ <item>
+ <p>[agent] The SNMP ACM cache was not properly updated when
+ changes where made to the VACM security-to-group, access and
+ view-tree-family tables. </p>
+ <p>Own Id: OTP-9367</p>
+ <p>Aux Id: Seq 11858</p>
+ </item>
+
+ <item>
+ <p>Fixed install directory typo for man3. </p>
+ <p>Peter Lemenkov</p>
+ <p>Hans Ulrich Niedermann</p>
+ <p>Own Id: OTP-9442</p>
+ </item>
+
+ </list>
+ </section>
+
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.21 -->
+
+
+ <section>
+ <title>SNMP Development Toolkit 4.20.1</title>
+ <p>Version 4.20.1 supports code replacement in runtime from/to
+ version 4.20, 4.19 and 4.18.</p>
+
+ <section>
+ <title>Improvements and new features</title>
+ <p>-</p>
+<!--
+ <list type="bulleted">
+ <item>
+ <p>Added type specs for functions that do not return. </p>
+ <p>Kostis Sagonas</p>
+ <p>Own Id: OTP-9208</p>
+ </item>
+ </list>
+-->
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+<!--
+ <p>-</p>
+-->
+ <list type="bulleted">
+ <item>
+ <p>[agent] Did not handle transport domains properly in some cases,
+ for instance trap sending. </p>
+ <p>Own Id: OTP-9400</p>
+ </item>
+
+ <item>
+ <p>[agent] Wrong default transport domain, snmpUDPDomain, instead
+ of transportDomainUdpIpv4. </p>
+ <p>Own Id: OTP-9425</p>
+ <p>Aux Id: Seq 11874</p>
+ </item>
+
+ </list>
+ </section>
+
+
+ <section>
+ <title>Incompatibilities</title>
+ <p>-</p>
+ </section>
+
+ </section> <!-- 4.20.1 -->
+
+
+ <section>
<title>SNMP Development Toolkit 4.20</title>
<p>Version 4.20 supports code replacement in runtime from/to
version 4.19 and 4.18.</p>
diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml
index 771629492d..61d19251c5 100644
--- a/lib/snmp/doc/src/snmpc.xml
+++ b/lib/snmp/doc/src/snmpc.xml
@@ -48,7 +48,11 @@
<type>
<v>File = string()</v>
<v>Options = [opt()]</v>
- <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | module_compliance() | agent_capabilities() | outdir() | no_defs() | verbosity() | warnings()</v>
+ <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() |
+ description() | reference() | group_check() | i() | il() |
+ imports() | module() | module_identity() | module_compliance() |
+ agent_capabilities() | outdir() | no_defs() | verbosity() |
+ warnings() | warnings_as_errors()</v>
<v>db() = {db, volatile|persistent|mnesia}</v>
<v>deprecated() = {deprecated, bool()}</v>
<v>relaxed_row_name_assign_check() = relaxed_row_name_assign_check</v>
@@ -66,6 +70,7 @@
<v>outdir() = {outdir, dir()}</v>
<v>verbosity() = {verbosity, silence|warning|info|log|debug|trace}</v>
<v>warnings() = {warnings, bool()}</v>
+ <v>warnings_as_errors() = warnings_as_errors</v>
<v>dir() = string()</v>
<v>BinFileName = string()</v>
</type>
@@ -200,11 +205,17 @@
<item>
<p>The option <c>warnings</c> specifies whether warning
- messages should be shown. </p>
+ messages should be shown. </p>
<p>Default is <c>true</c>. </p>
</item>
+ <item>
+ <p>The option <c>warnings_as_errors</c>, if present, specifies
+ whether warnings should be treated as errors.</p>
+ </item>
+
</list>
+
<p>The MIB compiler understands both SMIv1 and SMIv2 MIBs. It
uses the <c>MODULE-IDENTITY</c> statement to determine if the MIB is
version 1 or 2.
diff --git a/lib/snmp/doc/src/snmpc_cmd.xml b/lib/snmp/doc/src/snmpc_cmd.xml
index 9358382a10..72116f8981 100644
--- a/lib/snmp/doc/src/snmpc_cmd.xml
+++ b/lib/snmp/doc/src/snmpc_cmd.xml
@@ -50,6 +50,8 @@
with definitions of Erlang constants for the objects in
the MIB, see
<seealso marker="snmpc#mib_to_hrl">mib_to_hrl/1</seealso>. </p>
+
+ <marker id="options"></marker>
</desc>
</func>
</funcs>
@@ -58,15 +60,18 @@
<title>Compiler options</title>
<p>The following options are supported (note that most of these relate
to the compilation of the MIB file):</p>
+ <marker id="option_help"></marker>
<taglist>
<tag>--help</tag>
<item>
<p>Prints help info.</p>
+ <marker id="option_version"></marker>
</item>
<tag>--version</tag>
<item>
<p>Prints application and mib format version.</p>
+ <marker id="option_verbosity"></marker>
</item>
<tag>--verbosity <em>verbosity</em></tag>
@@ -74,11 +79,20 @@
<p>Print debug info. </p>
<p><c>verbosity</c> = <c>trace</c> | <c>debug</c> | <c>log</c> | <c>info</c> | <c>silence</c></p>
<p>Defaults to <c>silence</c>.</p>
+ <marker id="option_warnings"></marker>
</item>
<tag>--warnings</tag>
<item>
<p>Print warning messages. </p>
+ <marker id="option_wae"></marker>
+ </item>
+
+ <tag>--wae</tag>
+ <item>
+ <p>Warnings as errors.
+ Indicates that warnings shall be treated as errors. </p>
+ <marker id="option_odir"></marker>
</item>
<tag>--o <em>directory</em></tag>
@@ -86,6 +100,7 @@
<p>The directory where the compiler should place the output files.
If not specified, output files will be placed in the current working
directory.</p>
+ <marker id="option_idir"></marker>
</item>
<tag>--i <em>Directory</em></tag>
@@ -94,6 +109,7 @@
By default, the current working directory is always included. </p>
<p>This option can be present several times, each time specifying
<em>one</em> path. </p>
+ <marker id="option_ildir"></marker>
</item>
<tag>--il <em>Directory</em></tag>
@@ -106,6 +122,7 @@
the current version may be in the system). The current directory
and the "snmp-home"/priv/mibs/ are always listed last in the
include path. </p>
+ <marker id="option_sgc"></marker>
</item>
<tag>--sgc</tag>
@@ -114,42 +131,50 @@
group check of the mib compiler.
That is, should the OBJECT-GROUP and the NOTIFICATION-GROUP
macro(s) be checked for correctness or not. </p>
+ <marker id="option_dep"></marker>
</item>
<tag>--dep</tag>
<item>
<p>Keep deprecated definition(s).
If not specified the compiler will ignore deprecated definitions. </p>
+ <marker id="option_desc"></marker>
</item>
<tag>--desc</tag>
<item>
<p>The DESCRIPTION field will be included. </p>
+ <marker id="option_ref"></marker>
</item>
<tag>--ref</tag>
<item>
<p>The REFERENCE field will be included. </p>
+ <marker id="option_imp"></marker>
</item>
<tag>--imp</tag>
<item>
<p>The IMPORTS field will be included. </p>
+ <marker id="option_mi"></marker>
</item>
<tag>--mi</tag>
<item>
<p>The MODULE-IDENTITY field will be included. </p>
+ <marker id="option_mc"></marker>
</item>
<tag>--mc</tag>
<item>
<p>The MODULE-COMPLIANCE field will be included. </p>
+ <marker id="option_ac"></marker>
</item>
<tag>--ac</tag>
<item>
<p>The AGENT-CAPABILITIES field will be included. </p>
+ <marker id="option_mod"></marker>
</item>
<tag>--mod <em>module</em></tag>
@@ -157,6 +182,7 @@
<p>The module which implements all the instrumentation functions. </p>
<p>The name of all instrumentation functions must be the
same as the corresponding managed object it implements. </p>
+ <marker id="option_nd"></marker>
</item>
<tag>--nd</tag>
@@ -165,6 +191,7 @@
used if a managed object have no instrumentation function.
Instead this will be reported as an error, and the compilation
aborts. </p>
+ <marker id="option_rrnac"></marker>
</item>
<tag>--rrnac</tag>
@@ -176,6 +203,7 @@
This means that the error will be converted to a warning. </p>
<p>By default it is not included, but if this option is present
it will be. </p>
+ <marker id="see_also"></marker>
</item>
</taglist>
diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml
index b527d171b0..c36a1b2a24 100644
--- a/lib/snmp/doc/src/snmpm.xml
+++ b/lib/snmp/doc/src/snmpm.xml
@@ -283,27 +283,27 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
<v>TargetName = target_name()</v>
<v>Config = [agent_config()]</v>
<v>agent_config() = {Item, Val}</v>
- <v>Item = engine_id | address | port | community | timeout | max_message_size | version | sec_model | sec_name | sec_level</v>
+ <v>Item = engine_id | address | port | community | timeout | max_message_size | version | sec_model | sec_name | sec_level | tdomain</v>
<v>Val = term()</v>
<v>Reason = term()</v>
</type>
<desc>
<p>Explicitly instruct the manager to handle this agent, with
- <c>UserId</c> as the responsible user. </p>
- <p>Called to instruct the manager that this agent
- shall be handled. This function is used when
- the user knows in advance which agents the
- manager shall handle.
- Note that there is an alternate way to do the same thing:
- Add the agent to the manager config files (see
- <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>).</p>
+ <c>UserId</c> as the responsible user. </p>
+ <p>Called to instruct the manager that this agent shall be handled.
+ This function is used when the user knows in advance which agents
+ the manager shall handle.
+ Note that there is an alternate way to do the same thing:
+ Add the agent to the manager config files (see
+ <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>).</p>
<p><c>TargetName</c> is a non-empty string,
- uniquely identifying the agent. </p>
- <p>The type of <c>Val</c> depends on <c>Item</c>: </p>
+ uniquely identifying the agent. </p>
+ <p>The type of <c>Val</c> depends on <c>Item</c>: </p>
<code type="none"><![CDATA[
[mandatory] engine_id = string()
[mandatory] address = ip_address()
[optional] port = integer()
+[optional] tdomain = transportDomainUdpIpv4 | transportDomainUdpIpv6
[optional] community = string()
[optional] timeout = integer() | snmp_timer()
[optional] max_message_size = integer()
@@ -312,7 +312,9 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
[optional] sec_name = string()
[optional] sec_level = noAuthNoPriv | authNoPriv | authPriv
]]></code>
- <p>Note that if no <c>Port</c> is given, the default value is used.</p>
+ <p>Note that if no <c>tdomain</c> is given, the default value,
+ <c>transportDomainUdpIpv4</c>, is used.</p>
+ <p>Note that if no <c>port</c> is given, the default value is used.</p>
<marker id="unregister_agent"></marker>
</desc>
@@ -348,17 +350,25 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv
</func>
<func>
+ <name>update_agent_info(UserId, TargetName, Info) -> ok | {error, Reason}</name>
<name>update_agent_info(UserId, TargetName, Item, Val) -> ok | {error, Reason}</name>
<fsummary>Update agent config</fsummary>
<type>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>Item = atom()</v>
- <v>Val = term()</v>
+ <v>Info = [{item(), item_value()}]</v>
+ <v>Item = item()</v>
+ <v>item() = atom()</v>
+ <v>Val = item_value()</v>
+ <v>item_value() = term()</v>
<v>Reason = term()</v>
</type>
<desc>
- <p>Update agent config.</p>
+ <p>Update agent config. The function <c>update_agent_info/3</c>
+ should be used when several values needs to be updated atomically. </p>
+ <p>See function
+ <seealso marker="#register_agent">register_agent</seealso>)
+ for more info about what kind of items are allowed. </p>
<marker id="which_agents"></marker>
</desc>
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 28469a7b4e..37f6dd3f26 100644
--- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
+++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl
@@ -247,6 +247,7 @@ add_sec2group(SecModel, SecName, GroupName) ->
Key = [Key1, length(Key2) | Key2],
case table_cre_row(vacmSecurityToGroupTable, Key, Row) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
false ->
{error, create_failed}
@@ -260,6 +261,7 @@ add_sec2group(SecModel, SecName, GroupName) ->
delete_sec2group(Key) ->
case table_del_row(vacmSecurityToGroupTable, Key) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
ok;
false ->
{error, delete_failed}
@@ -279,6 +281,7 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
Key3 = [SM, SL],
Key = Key1 ++ Key2 ++ Key3,
snmpa_vacm:insert([{Key, Row}], false),
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
{error, Reason} ->
{error, Reason};
@@ -287,6 +290,7 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) ->
end.
delete_access(Key) ->
+ snmpa_agent:invalidate_ca_cache(),
snmpa_vacm:delete(Key).
@@ -299,6 +303,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) ->
Key = [length(Key1) | Key1] ++ [length(Key2) | Key2],
case table_cre_row(vacmViewTreeFamilyTable, Key, Row) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
{ok, Key};
false ->
{error, create_failed}
@@ -312,6 +317,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) ->
delete_view_tree_fam(Key) ->
case table_del_row(vacmViewTreeFamilyTable, Key) of
true ->
+ snmpa_agent:invalidate_ca_cache(),
ok;
false ->
{error, delete_failed}
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index 82a7ec647b..6322f0f21d 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -1626,7 +1626,7 @@ invalidate_ca_cache() ->
MasterAgent ! invalidate_ca_cache;
false ->
%% This is running on a sub-agent node,
- %% so sent skip it
+ %% so skip it
ok
end;
_ -> % Not on this node
diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl
index 4b88eb69f7..c17a6abbd7 100644
--- a/lib/snmp/src/agent/snmpa_conf.erl
+++ b/lib/snmp/src/agent/snmpa_conf.erl
@@ -424,7 +424,8 @@ target_addr_entry(Name,
EngineId,
TMask) ->
target_addr_entry(Name, Ip, 162, TagList,
- ParamsName, EngineId, TMask, 2048).
+ ParamsName, EngineId,
+ TMask, 2048).
target_addr_entry(Name,
Ip,
@@ -435,7 +436,8 @@ target_addr_entry(Name,
TMask,
MaxMessageSize) ->
target_addr_entry(Name, Ip, Udp, 1500, 3, TagList,
- ParamsName, EngineId, TMask, MaxMessageSize).
+ ParamsName, EngineId,
+ TMask, MaxMessageSize).
target_addr_entry(Name,
Ip,
@@ -448,7 +450,8 @@ target_addr_entry(Name,
TMask,
MaxMessageSize) ->
target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp,
- Timeout, RetryCount, TagList, ParamsName,
+ Timeout, RetryCount, TagList,
+ ParamsName, EngineId,
TMask, MaxMessageSize).
target_addr_entry(Name,
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 14f62b12f3..4f50b1a674 100644
--- a/lib/snmp/src/agent/snmpa_mpd.erl
+++ b/lib/snmp/src/agent/snmpa_mpd.erl
@@ -32,6 +32,7 @@
-include("SNMP-MPD-MIB.hrl").
-include("SNMPv2-TM.hrl").
-include("SNMP-FRAMEWORK-MIB.hrl").
+-include("TRANSPORT-ADDRESS-MIB.hrl").
-define(VMODULE,"MPD").
-include("snmp_verbosity.hrl").
@@ -981,12 +982,15 @@ generate_discovery_msg2(NoteStore, Pdu,
discovery_note_timeout(Timeout) ->
(Timeout div 100) + 1.
-generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]},
+generate_discovery_msg(NoteStore, {TDomain, TAddress},
Pdu, ScopedPduBytes,
ContextEngineID, ManagerEngineID,
SecModel, SecName, SecLevelFlag,
InitialUserName,
ContextName, Timeout) ->
+
+ {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress),
+
%% 7.1.7
?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]),
MsgID = generate_msg_id(),
@@ -1027,7 +1031,7 @@ generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]},
%% Log(Packet),
inc_snmp_out_vars(Pdu),
?vdebug("generate_discovery_msg -> done", []),
- {Packet, {{A,B,C,D}, U1 bsl 8 + U2}};
+ {Packet, Address};
Error ->
throw(Error)
@@ -1057,6 +1061,34 @@ generate_sec_discovery_msg(Message, SecModule,
end.
+transform_taddr(?snmpUDPDomain, TAddress) ->
+ transform_taddr(?transportDomainUdpIpv4, TAddress);
+transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) ->
+ Domain = transportDomainUdpIpv4,
+ Addr = {A,B,C,D},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(?transportDomainUdpIpv4, BadAddr) ->
+ {error, {bad_transportDomainUdpIpv4_address, BadAddr}};
+transform_taddr(?transportDomainUdpIpv6,
+ [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) ->
+ Domain = transportDomainUdpIpv6,
+ Addr = {A1, A2, A3, A4, A5, A6, A7, A8},
+ Port = P1 bsl 8 + P2,
+ Address = {Addr, Port},
+ {ok, {Domain, Address}};
+transform_taddr(?transportDomainUdpIpv6, BadAddr) ->
+ {error, {bad_transportDomainUdpIpv6_address, BadAddr}};
+transform_taddr(BadTDomain, TAddress) ->
+ case lists:member(BadTDomain, snmp_conf:all_tdomains()) of
+ true ->
+ {error, {unsupported_tdomain, BadTDomain, TAddress}};
+ false ->
+ {error, {unknown_tdomain, BadTDomain, TAddress}}
+ end.
+
+
process_taddrs(Dests) ->
?vtrace("process_taddrs -> entry with"
"~n Dests: ~p", [Dests]),
@@ -1066,46 +1098,44 @@ process_taddrs([], Acc) ->
?vtrace("process_taddrs -> entry when done with"
"~n Acc: ~p", [Acc]),
lists:reverse(Acc);
-
+
%% v3
-process_taddrs([{{?snmpUDPDomain, [A,B,C,D,U1,U2]}, SecData} | T], Acc) ->
+process_taddrs([{{TDomain, TAddress}, SecData} | T], Acc) ->
?vtrace("process_taddrs -> entry when v3 with"
- "~n A: ~p"
- "~n B: ~p"
- "~n C: ~p"
- "~n D: ~p"
- "~n U1: ~p"
- "~n U2: ~p"
- "~n SecData: ~p", [A, B, C, D, U1, U2, SecData]),
- Entry = {{snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, SecData},
- process_taddrs(T, [Entry | Acc]);
-%% Bad v3
-process_taddrs([{{TDomain, TAddr}, _SecData} | T], Acc) ->
- ?vtrace("process_taddrs -> entry when bad v3 with"
- "~n TDomain: ~p"
- "~n TAddr: ~p", [TDomain, TAddr]),
- user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]),
- process_taddrs(T, Acc);
+ "~n TDomain: ~p"
+ "~n TAddress: ~p"
+ "~n SecData: ~p", [TDomain, TAddress, SecData]),
+ case transform_taddr(TDomain, TAddress) of
+ {ok, DestAddr} ->
+ ?vtrace("process_taddrs -> transformed: "
+ "~n DestAddr: ~p", [DestAddr]),
+ Entry = {DestAddr, SecData},
+ process_taddrs(T, [Entry | Acc]);
+ {error, Reason} ->
+ ?vinfo("Failed transforming v3 domain and address"
+ "~n Reason: ~p", [Reason]),
+ user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]),
+ process_taddrs(T, Acc)
+ end;
%% v1 & v2
-process_taddrs([{?snmpUDPDomain, [A,B,C,D,U1,U2]} | T], Acc) ->
+process_taddrs([{TDomain, TAddress} | T], Acc) ->
?vtrace("process_taddrs -> entry when v1/v2 with"
- "~n A: ~p"
- "~n B: ~p"
- "~n C: ~p"
- "~n D: ~p"
- "~n U1: ~p"
- "~n U2: ~p", [A, B, C, D, U1, U2]),
- Entry = {snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}},
- process_taddrs(T, [Entry | Acc]);
-%% Bad v1 or v2
-process_taddrs([{TDomain, TAddr} | T], Acc) ->
- ?vtrace("process_taddrs -> entry when bad v1/v2 with"
- "~n TDomain: ~p"
- "~n TAddr: ~p", [TDomain, TAddr]),
- user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]),
- process_taddrs(T, Acc);
+ "~n TDomain: ~p"
+ "~n TAddress: ~p", [TDomain, TAddress]),
+ case transform_taddr(TDomain, TAddress) of
+ {ok, DestAddr} ->
+ ?vtrace("process_taddrs -> transformed: "
+ "~n DestAddr: ~p", [DestAddr]),
+ Entry = DestAddr,
+ process_taddrs(T, [Entry | Acc]);
+ {error, Reason} ->
+ ?vinfo("Failed transforming v1/v2 domain and address: "
+ "~n Reason: ~p", [Reason]),
+ user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]),
+ process_taddrs(T, Acc)
+ end;
process_taddrs(Crap, Acc) ->
- throw({error, {taddrs_crap, Crap, Acc}}).
+ throw({error, {bad_taddrs, Crap, Acc}}).
mk_v1_v2_packet_list(To, Packet, Len, Pdu) ->
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 5deb40be0f..8e1855b4df 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -22,82 +22,82 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.20.1",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
+ {"4.20",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
{"4.19",
[
{load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
{load_module, snmpa_usm, soft_purge, soft_purge, []},
{load_module, snmpm_usm, soft_purge, soft_purge, []},
{load_module, snmp_log, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_conf, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
{load_module, snmp_misc, soft_purge, soft_purge, []},
{load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
{load_module, snmpa_trap, soft_purge, soft_purge,
[snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
{load_module, snmpa_acm, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd, snmp_target_mib]},
{load_module, snmpa_conf, soft_purge, soft_purge,
- [snmp_notification_mib]},
+ [snmp_config, snmp_notification_mib]},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
{load_module, snmp_notification_mib, soft_purge, soft_purge,
[snmp_conf, snmp_target_mib]},
{load_module, snmp_community_mib, soft_purge, soft_purge, []},
{load_module, snmp_target_mib, soft_purge, soft_purge,
[snmp_conf]},
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
- {update, snmpa_net_if, soft, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd]},
- {update, snmpa_agent, soft, soft_purge, soft_purge,
- [snmpa_acm, snmpa_mpd, snmpa_trap]}
- ]
- },
- {"4.18",
- [
- {load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []},
- {load_module, snmp_misc, soft_purge, soft_purge, []},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmp_config, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmpa_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge,
- [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
- {load_module, snmpa_acm, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd, snmp_target_mib]},
- {load_module, snmpa, soft_purge, soft_purge,
- [snmp_community_mib,
- snmp_framework_mib,
- snmp_standard_mib,
- snmp_target_mib,
- snmp_user_based_sm_mib,
- snmp_view_based_acm_mib]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge,
- [snmp_conf, snmp_target_mib, snmpa_mib_lib]},
- {load_module, snmp_community_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib, snmpa_vacm]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
-
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
-
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
{update, snmpa_net_if, soft, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd]},
{update, snmpa_agent, soft, soft_purge, soft_purge,
@@ -109,84 +109,82 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.20.1",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
+ {"4.20",
+ [
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
+ {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
+ {load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmp_config, soft_purge, soft_purge, []},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]}
+ ]
+ },
{"4.19",
[
{load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
+ {load_module, snmpm, soft_purge, soft_purge,
+ [snmpm_server, snmpm_config, snmp_config]},
{load_module, snmpa_usm, soft_purge, soft_purge, []},
{load_module, snmpm_usm, soft_purge, soft_purge, []},
{load_module, snmp_log, soft_purge, soft_purge, []},
{load_module, snmp_pdus, soft_purge, soft_purge, []},
{load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_conf, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
{load_module, snmp_misc, soft_purge, soft_purge, []},
{load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
+ {load_module, snmpa_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge,
+ [snmp_conf, snmp_config, snmpm_config]},
{load_module, snmpa_trap, soft_purge, soft_purge,
[snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
{load_module, snmpa_acm, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd, snmp_target_mib]},
{load_module, snmpa_conf, soft_purge, soft_purge,
- [snmp_notification_mib]},
+ [snmp_config, snmp_notification_mib]},
+ {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []},
{load_module, snmp_notification_mib, soft_purge, soft_purge,
[snmp_conf, snmp_target_mib]},
{load_module, snmp_community_mib, soft_purge, soft_purge, []},
{load_module, snmp_target_mib, soft_purge, soft_purge,
[snmp_conf]},
-
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
-
- {update, snmpa_net_if, soft, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd]},
- {update, snmpa_agent, soft, soft_purge, soft_purge,
- [snmpa_acm, snmpa_mpd, snmpa_trap]}
- ]
- },
- {"4.18",
- [
- {load_module, snmpa, soft_purge, soft_purge, []},
- {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]},
- {load_module, snmpa_usm, soft_purge, soft_purge, []},
- {load_module, snmpm_usm, soft_purge, soft_purge, []},
- {load_module, snmp_misc, soft_purge, soft_purge, []},
- {load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmp_conf, soft_purge, soft_purge, []},
- {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]},
- {load_module, snmpa_vacm, soft_purge, soft_purge, []},
- {load_module, snmpa_trap, soft_purge, soft_purge,
- [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]},
- {load_module, snmpa_acm, soft_purge, soft_purge,
- [snmp_conf, snmpa_mpd, snmp_target_mib]},
- {load_module, snmpa, soft_purge, soft_purge,
- [snmp_community_mib,
- snmp_framework_mib,
- snmp_standard_mib,
- snmp_target_mib,
- snmp_user_based_sm_mib,
- snmp_view_based_acm_mib]},
- {load_module, snmp_notification_mib, soft_purge, soft_purge,
- [snmp_conf, snmp_target_mib, snmpa_mib_lib]},
- {load_module, snmp_community_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_framework_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_standard_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_target_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib]},
- {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
- [snmpa_mib_lib, snmpa_vacm]},
- {load_module, snmpa_mib_lib, soft_purge, soft_purge, []},
-
- {update, snmpm_net_if, soft, soft_purge, soft_purge, []},
- {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]},
-
+ {update, snmpm_net_if, soft, soft_purge, soft_purge,
+ [snmp_conf, snmpm_mpd, snmpm_config]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge,
+ [snmpm_net_if, snmpm_mpd, snmpm_config]},
{update, snmpa_net_if, soft, soft_purge, soft_purge,
[snmp_conf, snmpa_mpd]},
{update, snmpa_agent, soft, soft_purge, soft_purge,
diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile
index 0ceaf276a6..627af6f185 100644
--- a/lib/snmp/src/compile/Makefile
+++ b/lib/snmp/src/compile/Makefile
@@ -45,11 +45,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN)
include modules.mk
-ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%)
-
-ERL_FILES = $(MODULES:%=%.erl)
-
-TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(ESCRIPT_BIN)
+ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%)
+ERL_FILES = $(MODULES:%=%.erl)
+EBIN_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+TARGET_FILES = $(EBIN_FILES) $(ESCRIPT_BIN)
GENERATED_PARSER = $(PARSER_MODULE:%=%.erl)
@@ -125,7 +124,7 @@ release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/src/compiler
$(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler
$(INSTALL_DIR) $(RELSYSDIR)/ebin
- $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin
+ $(INSTALL_DATA) $(EBIN_FILES) $(RELSYSDIR)/ebin
$(INSTALL_DIR) $(RELSYSDIR)/bin
$(INSTALL_SCRIPT) $(ESCRIPT_BIN) $(RELSYSDIR)/bin
diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl
index 195c238184..5e6b81f1ec 100644
--- a/lib/snmp/src/compile/snmpc.erl
+++ b/lib/snmp/src/compile/snmpc.erl
@@ -108,6 +108,7 @@ compile(FileName) ->
%% {i, [import_dir_string()]} ["./"]
%% {il, [import_lib_dir_string()]} []
%% {warnings, bool()} true
+%% warnings_as_errors
%% {outdir, string()} "./"
%% description
%% reference
@@ -199,6 +200,8 @@ get_options([reference|Opts], Formats, Args) ->
get_options(Opts, ["~n reference"|Formats], Args);
get_options([{warnings, Val}|Opts], Formats, Args) ->
get_options(Opts, ["~n warnings: ~w"|Formats], [Val|Args]);
+get_options([warnings_as_errors|Opts], Formats, Args) ->
+ get_options(Opts, ["~n warnings_as_errors"|Formats], Args);
get_options([{verbosity, Val}|Opts], Formats, Args) ->
get_options(Opts, ["~n verbosity: ~w"|Formats], [Val|Args]);
get_options([imports|Opts], Formats, Args) ->
@@ -261,6 +264,8 @@ check_options([{group_check, Atom} | T]) when is_atom(Atom) ->
check_options([{warnings, Bool} | T]) ->
check_bool(warnings, Bool),
check_options(T);
+check_options([warnings_as_errors | T]) ->
+ check_options(T);
check_options([{db, volatile} | T]) ->
check_options(T);
check_options([{db, persistent} | T]) ->
@@ -331,6 +336,9 @@ get_agent_capabilities(Options) ->
get_module_compliance(Options) ->
get_bool_option(module_compliance, Options).
+get_warnings_as_errors(Options) ->
+ lists:member(warnings_as_errors, Options).
+
get_relaxed_row_name_assign_check(Options) ->
lists:member(relaxed_row_name_assign_check, Options).
@@ -409,6 +417,7 @@ init(From, MibFileName, Options) ->
put(reference, get_reference(Options)),
put(agent_capabilities, get_agent_capabilities(Options)),
put(module_compliance, get_module_compliance(Options)),
+ put(warnings_as_errors, get_warnings_as_errors(Options)),
File = filename:rootname(MibFileName, ".mib"),
put(filename, filename:basename(File ++ ".mib")),
R = case catch c_impl(File) of
diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src
index 5f9b154bfa..4e91ae9a03 100644
--- a/lib/snmp/src/compile/snmpc.src
+++ b/lib/snmp/src/compile/snmpc.src
@@ -50,7 +50,8 @@
%% The default verbosity (silence) will be filled in
%% during argument processing.
verbosity,
- warnings = false
+ warnings = false,
+ warnings_as_errors = false
}).
@@ -74,6 +75,7 @@
%% --version
%% --verbosity V
%% --warnings
+%% --wae
main(Args) when is_list(Args) ->
case (catch process_args(Args)) of
ok ->
@@ -156,7 +158,8 @@ mk_mib_options(#state{outdir = OutDir,
%% The default verbosity (silence) will be filled in
%% during argument processing.
verbosity = V,
- warnings = W}) ->
+ warnings = W,
+ warnings_as_errors = WAE}) ->
[{outdir, OutDir},
{db, DB},
{i, IDs},
@@ -178,7 +181,8 @@ mk_mib_options(#state{outdir = OutDir,
maybe_option(Imp, imports) ++
maybe_option(MI, module_identity) ++
maybe_option(MC, module_compliance) ++
- maybe_option(AC, agent_capabilities).
+ maybe_option(AC, agent_capabilities) ++
+ maybe_option(WE, warnings_as_errors).
maybe_option(true, Opt) -> [Opt];
maybe_option(_, _) -> [].
@@ -292,6 +296,8 @@ process_args(["--nd"|Args], State) ->
process_args(Args, State#state{no_defaults = true});
process_args(["--rrnac"|Args], State) ->
process_args(Args, State#state{relaxed_row_name_assigne_check = true});
+process_args(["--wae"|Args], State) ->
+ process_args(Args, State#state{warnings_as_errors = true});
process_args([MIB], State) ->
Ext = filename:extension(MIB),
if
@@ -371,6 +377,8 @@ usage() ->
"~n a warning. "
"~n By default it is not included, but if this option is "
"~n present it will be. "
+ "~n --wae - Warnings as errors. "
+ "~n Indicates that warnings shall be treated as errors. "
"~n "
"~n", []),
halt(1).
diff --git a/lib/snmp/src/compile/snmpc_lib.hrl b/lib/snmp/src/compile/snmpc_lib.hrl
index 000486e728..35ec9abd03 100644
--- a/lib/snmp/src/compile/snmpc_lib.hrl
+++ b/lib/snmp/src/compile/snmpc_lib.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2009. All Rights Reserved.
+%% Copyright Ericsson AB 2009-2011. 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
@@ -20,8 +20,17 @@
-ifndef(snmpc_lib).
-define(snmpc_lib, true).
--define(vwarning(F, A), ?verbosity(warning, F, A, ignore)).
--define(vwarning2(F, A, MibLine), ?verbosity(warning, F, A, MibLine)).
+-define(vwarning(F, A),
+ case get(warnings_as_errors) of
+ true -> snmpc_lib:error(F, A);
+ _ -> ?verbosity(warning, F, A, ignore)
+ end).
+
+-define(vwarning2(F, A, MibLine),
+ case get(warnings_as_errors) of
+ true -> snmpc_lib:error(F, A, MibLine);
+ _ -> ?verbosity(warning, F, A, MibLine)
+ end).
-define(vinfo(F, A), ?verbosity(info, F, A, ignore)).
-define(vinfo2(F, A, MibLine), ?verbosity(info, F, A, MibLine)).
-define(vlog(F, A), ?verbosity(log, F, A, ignore)).
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index 0d084332de..6d2ac8d747 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -50,7 +50,7 @@
register_agent/2, register_agent/3, register_agent/4,
unregister_agent/2, unregister_agent/3,
which_agents/0, which_agents/1,
- agent_info/2, update_agent_info/4,
+ agent_info/2, update_agent_info/3, update_agent_info/4,
register_usm_user/3, unregister_usm_user/2,
which_usm_users/0, which_usm_users/1,
@@ -167,6 +167,7 @@
-include_lib("snmp/include/snmp_types.hrl").
-include("snmpm_atl.hrl").
-include("snmpm_internal.hrl").
+-include("snmp_verbosity.hrl").
-define(DEFAULT_AGENT_PORT, 161).
@@ -447,8 +448,11 @@ agent_info(Addr, Port, Item) ->
Error
end.
+update_agent_info(UserId, TargetName, Info) when is_list(Info) ->
+ snmpm_config:update_agent_info(UserId, TargetName, Info).
+
update_agent_info(UserId, TargetName, Item, Val) ->
- snmpm_config:update_agent_info(UserId, TargetName, Item, Val).
+ update_agent_info(UserId, TargetName, [{Item, Val}]).
%% Backward compatibility functions
update_agent_info(UserId, Addr, Port, Item, Val) ->
diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl
index fd6da3e71a..c2e57abddb 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-2010. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2011. 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
@@ -36,7 +36,8 @@
user_info/0, user_info/1, user_info/2,
register_agent/3, unregister_agent/2,
- agent_info/0, agent_info/2, agent_info/3, update_agent_info/4,
+ agent_info/0, agent_info/2, agent_info/3,
+ update_agent_info/3, update_agent_info/4,
which_agents/0, which_agents/1,
is_known_engine_id/2,
@@ -84,7 +85,9 @@
backup/1,
- mk_target_name/3
+ mk_target_name/3,
+
+ default_transport_domain/0
]).
@@ -127,23 +130,24 @@
%% Macros and Constants:
--define(SERVER, ?MODULE).
--define(BACKUP_DB, snmpm_config_backup).
--define(CONFIG_DB, snmpm_config_db).
+-define(SERVER, ?MODULE).
+-define(BACKUP_DB, snmpm_config_backup).
+-define(CONFIG_DB, snmpm_config_db).
-define(DEFAULT_USER, default_user).
-define(DEFAULT_AGENT_PORT, 161).
--define(IRB_DEFAULT, auto).
-%% -define(IRB_DEFAULT, {user, timer:seconds(15)}).
+-define(IRB_DEFAULT, auto).
+%% -define(IRB_DEFAULT, {user, timer:seconds(15)}).
--define(USER_MOD_DEFAULT, snmpm_user_default).
--define(USER_DATA_DEFAULT, undefined).
+-define(USER_MOD_DEFAULT, snmpm_user_default).
+-define(USER_DATA_DEFAULT, undefined).
%% -define(DEF_ADDR_TAG, default_addr_tag).
-define(DEFAULT_TARGETNAME, default_agent).
--define(DEF_PORT_TAG, default_port_tag).
+-define(DEF_PORT_TAG, default_port_tag).
+-define(SUPPORTED_DOMAINS, [transportDomainUdpIpv4, transportDomainUdpIpv6]).
-ifdef(snmp_debug).
-define(GS_START_LINK(Opts),
@@ -159,6 +163,11 @@
%%%-------------------------------------------------------------------
%%% API
%%%-------------------------------------------------------------------
+
+default_transport_domain() ->
+ transportDomainUdpIpv4.
+
+
start_link(Opts) ->
?d("start_link -> entry with"
"~n Opts: ~p", [Opts]),
@@ -269,9 +278,10 @@ do_user_info(_UserId, BadItem) ->
error({not_found, BadItem}).
-%% A target-name constructed in this way is a string with the following
+%% A target-name constructed in this way is a string with the following:
%% <IP-address>:<Port>-<Version>
-%%
+%% This is intended for backward compatibility and therefor has
+%% only support for IPv4 addresses and *no* other transport domain.
mk_target_name(Addr0, Port, Config) when is_list(Config) ->
Version =
case lists:keysearch(version, 1, Config) of
@@ -280,7 +290,6 @@ mk_target_name(Addr0, Port, Config) when is_list(Config) ->
false ->
select_lowest_supported_version()
end,
-%% p("mk_target_name -> Version: ~p", [Version]),
case normalize_address(Addr0) of
{A, B, C, D} ->
lists:flatten(
@@ -308,57 +317,99 @@ select_lowest_supported_version([H|T], Versions) ->
end.
-register_agent(UserId, _TargetName, _Config) when (UserId =:= user_id) ->
+register_agent(UserId, _TargetName, _Config0) when (UserId =:= user_id) ->
{error, {bad_user_id, UserId}};
-register_agent(UserId, TargetName, Config)
+register_agent(UserId, TargetName, Config0)
when (is_list(TargetName) andalso
(length(TargetName) > 0) andalso
- is_list(Config)) ->
+ is_list(Config0)) ->
-%% p("register_agent -> entry with"
-%% "~n UserId: ~p"
-%% "~n TargetName: ~p"
-%% "~n Config: ~p", [UserId, TargetName, Config]),
+ ?vtrace("register_agent -> entry with"
+ "~n UserId: ~p"
+ "~n TargetName: ~p"
+ "~n Config0: ~p", [UserId, TargetName, Config0]),
%% Check:
%% 1) That the mandatory configs are present
- %% 2) That the illegal config user_id (used internally) is
- %% not present
+ %% 2) That no illegal config, e.g. user_id (used internally),
+ %% is not present
%% 3) Check that there are no invalid or erroneous configs
- %% 4) Chack that the manager is capable to use the selected version
- case verify_agent_config(Config) of
- ok ->
+ %% 4) Check that the manager is capable of using the selected version
+ case verify_agent_config(Config0) of
+ {ok, Config} ->
call({register_agent, UserId, TargetName, Config});
Error ->
Error
end.
-verify_agent_config(Conf) ->
- ok = verify_mandatory(Conf, [engine_id, address, reg_type]),
- case verify_invalid(Conf, [user_id]) of
- ok ->
- case verify_agent_config2(Conf) of
- ok ->
- {ok, Vsns} = system_info(versions),
- Vsn =
- case lists:keysearch(version, 1, Conf) of
- {value, {version, V}} ->
- V;
- false ->
- v1
- end,
- case lists:member(Vsn, Vsns) of
- true ->
- ok;
- false ->
- {error, {version_not_supported_by_manager, Vsn, Vsns}}
- end
- end;
- Error ->
+verify_agent_config(Conf0) ->
+ try
+ begin
+ verify_mandatory(Conf0, [engine_id, address, reg_type]),
+ verify_invalid(Conf0, [user_id]),
+ Conf = verify_agent_config3(Conf0),
+ Vsns = versions(),
+ Vsn = which_version(Conf),
+ verify_version(Vsn, Vsns),
+ {ok, Conf}
+ end
+ catch
+ throw:Error ->
Error
end.
+versions() ->
+ case system_info(versions) of
+ {ok, Vsns} ->
+ Vsns;
+ {error, _} = ERROR ->
+ throw(ERROR)
+ end.
+
+which_version(Conf) ->
+ case lists:keysearch(version, 1, Conf) of
+ {value, {version, V}} ->
+ V;
+ false ->
+ v1
+ end.
+
+verify_version(Vsn, Vsns) ->
+ case lists:member(Vsn, Vsns) of
+ true ->
+ ok;
+ false ->
+ Reason = {version_not_supported_by_manager, Vsn, Vsns},
+ throw({error, Reason})
+ end.
+
+verify_agent_config3(Conf0) ->
+ %% Fix (transport) address and domain
+ {TDomain, Conf1} =
+ case lists:keysearch(tdomain, 1, Conf0) of
+ {value, {tdomain, Dom}} ->
+ {Dom, Conf0};
+ false ->
+ Dom = default_transport_domain(),
+ {Dom, [{tdomain, Dom} | Conf0]}
+ end,
+ Conf2 = case lists:keysearch(address, 1, Conf1) of
+ {value, {address, Address}} ->
+ lists:keyreplace(address, 1, Conf1,
+ {address, {TDomain, Address}});
+ false ->
+ %% This is a mandatory config option,
+ %% a later test will detect this
+ Conf1
+ end,
+ case verify_agent2(Conf2) of
+ {ok, Conf} ->
+ Conf;
+ {error, _} = ERROR ->
+ throw(ERROR)
+ end.
+
verify_agent_config2(Conf) ->
verify_agent2(Conf).
@@ -366,6 +417,7 @@ verify_agent_config2(Conf) ->
unregister_agent(UserId, TargetName) ->
call({unregister_agent, UserId, TargetName}).
+%% This is the old style agent unregistration (using Addr and Port).
unregister_agent(UserId, Addr0, Port) ->
Addr = normalize_address(Addr0),
case do_agent_info(Addr, Port, target_name) of
@@ -421,17 +473,51 @@ which_agents(UserId) ->
Agents = ets:match(snmpm_agent_table, Pat),
[TargetName || [TargetName] <- Agents].
-
-update_agent_info(UserId, TargetName, Item, Val0)
- when (Item =/= user_id) ->
- case (catch verify_val(Item, Val0)) of
- {ok, Val} ->
- call({update_agent_info, UserId, TargetName, Item, Val});
- Error ->
+
+verify_agent_info(TargetName, Info0) ->
+ try
+ begin
+ verify_invalid(Info0, [user_id]),
+ %% Check if address is part of the list and
+ %% if so update it with the domain info.
+ Info =
+ case lists:keysearch(address, 1, Info0) of
+ {value, {address, Addr}} ->
+ %% If domain is part of the info, then use it.
+ %% If not, lookup what is already stored for
+ %% this agent and use that.
+ Domain =
+ case lists:keysearch(tdomain, 1, Info0) of
+ {value, {tdomain, Dom}} ->
+ Dom;
+ false ->
+ {ok, Dom} =
+ agent_info(TargetName, tdomain),
+ Dom
+ end,
+ Addr2 = {Domain, Addr},
+ lists:keyreplace(address, 1, Info0, {address, Addr2});
+ false ->
+ Info0
+ end,
+ verify_agent2(Info)
+ end
+ catch
+ throw:Error ->
Error
end.
-%% Backward compatibillity
+update_agent_info(UserId, TargetName, Info) ->
+ call({update_agent_info, UserId, TargetName, Info}).
+
+%% <BACKWARD-COMPAT-2>
+%% This is wrapped in the interface module, so this function is
+%% only here to catch code-upgrade problems.
+update_agent_info(UserId, TargetName, Item, Val) ->
+ update_agent_info(UserId, TargetName, [{Item, Val}]).
+%% </BACKWARD-COMPAT-2>
+
+%% <BACKWARD-COMPAT-1>
update_agent_info(UserId, Addr, Port, Item, Val) ->
case agent_info(Addr, Port, target_name) of
{ok, TargetName} ->
@@ -439,6 +525,7 @@ update_agent_info(UserId, Addr, Port, Item, Val) ->
Error ->
Error
end.
+%% </BACKWARD-COMPAT-1>
is_known_engine_id(EngineID, TargetName) ->
case agent_info(TargetName, engine_id) of
@@ -650,22 +737,14 @@ unregister_usm_user(EngineID, Name)
call({unregister_usm_user, EngineID, Name}).
verify_usm_user_config(EngineID, Name, Config) ->
- %% case verify_mandatory(Config, []) of
- %% ok ->
- %% case verify_invalid(Config, [engine_id, name]) of
- %% ok ->
- %% verify_usm_user_config2(EngineID, Name, Config);
- %% Error ->
- %% Error
- %% end;
- %% Error ->
- %% Error
- %% end.
- ok = verify_mandatory(Config, []),
- case verify_invalid(Config, [engine_id, name]) of
- ok ->
- verify_usm_user_config2(EngineID, Name, Config);
- Error ->
+ try
+ begin
+ verify_mandatory(Config, []),
+ verify_invalid(Config, [engine_id, name]),
+ verify_usm_user_config2(EngineID, Name, Config)
+ end
+ catch
+ throw:Error ->
Error
end.
@@ -1590,6 +1669,7 @@ check_agent_config2(Agent) ->
throw(Err)
end.
+%% For backward compatibility
check_agent_config({UserId,
TargetName,
Community,
@@ -1597,10 +1677,27 @@ check_agent_config({UserId,
EngineId,
Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel}) ->
+ TDomain = default_transport_domain(),
+ check_agent_config({UserId,
+ TargetName,
+ Community,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel});
+
+check_agent_config({UserId,
+ TargetName,
+ Community,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MaxMessageSize,
+ Version, SecModel, SecName, SecLevel}) ->
?vtrace("check_agent_config -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p"
"~n Community: ~p"
+ "~n TDomain: ~p"
"~n Ip: ~p"
"~n Port: ~p"
"~n EngineId: ~p"
@@ -1610,15 +1707,16 @@ check_agent_config({UserId,
"~n SecModel: ~p"
"~n SecName: ~p"
"~n SecLevel: ~p",
- [UserId, TargetName, Community, Ip, Port,
+ [UserId, TargetName, Community,
+ TDomain, Ip, Port,
EngineId, Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel]),
- Addr = normalize_address(Ip),
+ Addr = normalize_address(TDomain, Ip),
?vtrace("check_agent_config -> Addr: ~p", [Addr]),
Agent = {UserId,
TargetName,
Community,
- Addr, Port,
+ TDomain, Addr, Port,
EngineId,
Timeout, MaxMessageSize,
Version, SecModel, SecName, SecLevel},
@@ -1644,6 +1742,7 @@ init_agent_config({UserId, TargetName, Config}) ->
end.
+%% For backward compatibility
verify_agent({UserId,
TargetName,
Comm,
@@ -1651,48 +1750,68 @@ verify_agent({UserId,
EngineId,
Timeout, MMS,
Version, SecModel, SecName, SecLevel}) ->
- ?vtrace("verify_agent -> entry with"
+ TDomain = default_transport_domain(),
+ verify_agent({UserId,
+ TargetName,
+ Comm,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MMS,
+ Version, SecModel, SecName, SecLevel});
+
+verify_agent({UserId,
+ TargetName,
+ Comm,
+ TDomain, Ip, Port,
+ EngineId,
+ Timeout, MMS,
+ Version, SecModel, SecName, SecLevel}) ->
+ ?vdebug("verify_agent -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p", [UserId, TargetName]),
snmp_conf:check_string(TargetName, {gt, 0}),
- case verify_val(address, Ip) of
- {ok, Addr} ->
- snmp_conf:check_integer(Port, {gt, 0}),
- Conf =
- [{reg_type, target_name},
- {address, Addr},
- {port, Port},
- {community, Comm},
- {engine_id, EngineId},
- {timeout, Timeout},
- {max_message_size, MMS},
- {version, Version},
- {sec_model, SecModel},
- {sec_name, SecName},
- {sec_level, SecLevel}
- ],
- case verify_agent2(Conf) of
- ok ->
- {UserId, TargetName, Conf, Version};
- Err ->
- throw(Err)
- end;
-
- Error ->
- ?vlog("verify_agent -> failed: ~n ~p", [Error]),
- throw(Error)
+ snmp_conf:check_integer(Port, {gt, 0}),
+ %% Note that the order of Conf *is* important.
+ %% Some properties may depend on others, so that
+ %% in order to verify one property, another must
+ %% be already verified (and present). An example
+ %% of this is the property 'address', for which
+ %% the property tdomain is needed.
+ Conf0 =
+ [{reg_type, target_name},
+ {tdomain, TDomain},
+ %% This should be taddress, but what the*...
+ {address, {TDomain, Ip}},
+ {port, Port},
+ {community, Comm},
+ {engine_id, EngineId},
+ {timeout, Timeout},
+ {max_message_size, MMS},
+ {version, Version},
+ {sec_model, SecModel},
+ {sec_name, SecName},
+ {sec_level, SecLevel}
+ ],
+ case verify_agent2(Conf0) of
+ {ok, Conf} ->
+ {UserId, TargetName, Conf, Version};
+ Err ->
+ throw(Err)
end.
-verify_agent2([]) ->
- ok;
-verify_agent2([{Item, Val}|Items]) ->
- case verify_val(Item, Val) of
- {ok, _Val} ->
- verify_agent2(Items);
+verify_agent2(Conf) ->
+ verify_agent2(Conf, []).
+
+verify_agent2([], VerifiedConf) ->
+ {ok, VerifiedConf};
+verify_agent2([{Item, Val0}|Items], VerifiedConf) ->
+ case verify_val(Item, Val0) of
+ {ok, Val} ->
+ verify_agent2(Items, [{Item, Val} | VerifiedConf]);
Err ->
Err
end;
-verify_agent2([Bad|_]) ->
+verify_agent2([Bad|_], _VerifiedConf) ->
{error, {bad_agent_config, Bad}}.
@@ -1708,14 +1827,28 @@ read_users_config_file(Dir) ->
check_user_config({Id, Mod, Data}) ->
+ ?vtrace("check_user_config -> entry with"
+ "~n Id: ~p"
+ "~n Mod: ~p"
+ "~n Data: ~p", [Id, Mod, Data]),
check_user_config({Id, Mod, Data, []});
-check_user_config({Id, Mod, _Data, DefaultAgentConfig} = User)
+check_user_config({Id, Mod, Data, DefaultAgentConfig} = _User)
when (Id =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) ->
+ ?vtrace("check_user_config -> entry with"
+ "~n Id: ~p"
+ "~n Mod: ~p"
+ "~n Data: ~p"
+ "~n DefaultAgentConfig: ~p",
+ [Id, Mod, Data, DefaultAgentConfig]),
case (catch verify_user_behaviour(Mod)) of
ok ->
+ ?vtrace("check_user_config -> user behaviour verified", []),
case verify_user_agent_config(DefaultAgentConfig) of
- ok ->
- {ok, User};
+ {ok, DefAgentConf} ->
+ ?vtrace("check_user_config -> "
+ "user agent (default) config verified", []),
+ User2 = {Id, Mod, Data, DefAgentConf},
+ {ok, User2};
{error, Reason} ->
error({bad_default_agent_config, Reason})
end;
@@ -1756,16 +1889,16 @@ verify_user({Id, UserMod, UserData}) ->
verify_user({Id, UserMod, UserData, DefaultAgentConfig})
when (Id =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) ->
?d("verify_user -> entry with"
- "~n Id: ~p"
- "~n UserMod: ~p"
- "~n UserData: ~p"
+ "~n Id: ~p"
+ "~n UserMod: ~p"
+ "~n UserData: ~p"
"~n DefaultAgentConfig: ~p",
[Id, UserMod, UserData, DefaultAgentConfig]),
case (catch verify_user_behaviour(UserMod)) of
ok ->
case verify_user_agent_config(DefaultAgentConfig) of
- ok ->
- Config = default_agent_config(DefaultAgentConfig),
+ {ok, DefAgentConf} ->
+ Config = default_agent_config(DefAgentConf),
{ok, #user{id = Id,
mod = UserMod,
data = UserData,
@@ -1783,10 +1916,15 @@ verify_user({Id, _, _, _}) ->
{error, {bad_user_id, Id}}.
verify_user_agent_config(Conf) ->
- case verify_invalid(Conf, [user_id, engine_id, address]) of
- ok ->
- verify_agent_config2(Conf);
- Error ->
+ try
+ begin
+ verify_invalid(Conf, [user_id, engine_id, address]),
+ verify_agent_config2(Conf)
+ end
+ catch
+ throw:Error ->
+ ?vdebug("verify_user_agent_config -> throw"
+ "~n Error: ~p", [Error]),
Error
end.
@@ -2147,6 +2285,16 @@ handle_call({unregister_agent, UserId, TargetName}, _From, State) ->
Reply = handle_unregister_agent(UserId, TargetName),
{reply, Reply, State};
+handle_call({update_agent_info, UserId, TargetName, Info},
+ _From, State) ->
+ ?vlog("received update_agent_info request: "
+ "~n UserId: ~p"
+ "~n TargetName: ~p"
+ "~n Info: ~p", [UserId, TargetName, Info]),
+ Reply = handle_update_agent_info(UserId, TargetName, Info),
+ {reply, Reply, State};
+
+%% <BACKWARD-COMPAT>
handle_call({update_agent_info, UserId, TargetName, Item, Val},
_From, State) ->
?vlog("received update_agent_info request: "
@@ -2156,6 +2304,7 @@ handle_call({update_agent_info, UserId, TargetName, Item, Val},
"~n Val: ~p", [UserId, TargetName, Item, Val]),
Reply = handle_update_agent_info(UserId, TargetName, Item, Val),
{reply, Reply, State};
+%% </BACKWARD-COMPAT>
handle_call({register_usm_user, User}, _From, State) ->
?vlog("received register_usm_user request: "
@@ -2517,16 +2666,27 @@ handle_register_agent(UserId, TargetName, Config) ->
"~n Config: ~p", [UserId, TargetName, Config]),
case (catch agent_info(TargetName, user_id)) of
{error, _} ->
+ ?vtrace("handle_register_agent -> user_id not found in config", []),
case ets:lookup(snmpm_user_table, UserId) of
[#user{default_agent_config = DefConfig}] ->
+ ?vtrace("handle_register_agent -> "
+ "~n DefConfig: ~p", [DefConfig]),
+ %% First, insert this users default config
+ ?vtrace("handle_register_agent -> store default config", []),
do_handle_register_agent(TargetName, DefConfig),
+ %% Second, insert the config for this agent
+ ?vtrace("handle_register_agent -> store config", []),
do_handle_register_agent(TargetName,
[{user_id, UserId}|Config]),
%% <DIRTY-BACKWARD-COMPATIBILLITY>
%% And now for some (backward compatibillity)
%% dirty crossref stuff
+ ?vtrace("handle_register_agent -> lookup address", []),
{ok, Addr} = agent_info(TargetName, address),
+ ?vtrace("handle_register_agent -> Addr: ~p, lookup Port",
+ [Addr]),
{ok, Port} = agent_info(TargetName, port),
+ ?vtrace("handle_register_agent -> register cross-ref fix", []),
ets:insert(snmpm_agent_table,
{{Addr, Port, target_name}, TargetName}),
%% </DIRTY-BACKWARD-COMPATIBILLITY>
@@ -2551,10 +2711,18 @@ handle_register_agent(UserId, TargetName, Config) ->
do_handle_register_agent(_TargetName, []) ->
ok;
do_handle_register_agent(TargetName, [{Item, Val}|Rest]) ->
+ ?vtrace("handle_register_agent -> entry with"
+ "~n TargetName: ~p"
+ "~n Item: ~p"
+ "~n Val: ~p"
+ "~n Rest: ~p", [TargetName, Item, Val, Rest]),
case (catch do_update_agent_info(TargetName, Item, Val)) of
ok ->
do_handle_register_agent(TargetName, Rest);
{error, Reason} ->
+ ?vtrace("handle_register_agent -> failed updating ~p"
+ "~n Item: ~p"
+ "~n Reason: ~p", [Item, Reason]),
ets:match_delete(snmpm_agent_table, {TargetName, '_'}),
{error, Reason}
end;
@@ -2589,41 +2757,61 @@ handle_unregister_agent(UserId, TargetName) ->
end.
-handle_update_agent_info(UserId, TargetName, Item, Val) ->
+handle_update_agent_info(UserId, TargetName, Info) ->
?vdebug("handle_update_agent_info -> entry with"
"~n UserId: ~p"
"~n TargetName: ~p"
- "~n Item: ~p"
- "~n Val: ~p", [UserId, TargetName, Item, Val]),
+ "~n Info: ~p", [UserId, TargetName, Info]),
+ %% Verify ownership
case (catch agent_info(TargetName, user_id)) of
- {ok, UserId} ->
- do_update_agent_info(TargetName, Item, Val);
+ {ok, UserId} ->
+ handle_update_agent_info(TargetName, Info);
{ok, OtherUserId} ->
{error, {not_owner, OtherUserId}};
Error ->
Error
end.
-do_update_agent_info(TargetName, Item, Val0) ->
-%% p("do_update_agent_info -> entry with"
-%% "~n TargetName: ~p"
-%% "~n Item: ~p"
-%% "~n Val0: ~p", [TargetName, Item, Val0]),
- case verify_val(Item, Val0) of
- {ok, Val} ->
-%% p("do_update_agent_info -> verified value"
-%% "~n Val: ~p", [Val]),
- ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}),
- ok;
+handle_update_agent_info(TargetName, Info0) ->
+ ?vtrace("handle_update_agent_info -> entry with"
+ "~n TargetName: ~p"
+ "~n Info0: ~p", [TargetName, Info0]),
+ %% Verify info
+ try verify_agent_info(TargetName, Info0) of
+ {ok, Info} ->
+ do_update_agent_info(TargetName, Info);
Error ->
- ?vlog("do_update_agent_info -> verify value failed: "
- "~n TargetName: ~p"
- "~n Item: ~p"
- "~n Val0: ~p"
- "~n Error: ~p", [TargetName, Item, Val0, Error]),
- {error, {bad_agent_val, TargetName, Item, Val0}}
+ Error
+ catch
+ throw:Error ->
+ Error;
+ T:E ->
+ {error, {failed_info_verification, Info0, T, E}}
end.
+handle_update_agent_info(UserId, TargetName, Item, Val) ->
+ ?vdebug("handle_update_agent_info -> entry with"
+ "~n UserId: ~p"
+ "~n TargetName: ~p"
+ "~n Item: ~p"
+ "~n Val: ~p", [UserId, TargetName, Item, Val]),
+ handle_update_agent_info(TargetName, [{Item, Val}]).
+
+do_update_agent_info(TargetName, Info) ->
+ InsertItem =
+ fun({Item, Val}) ->
+ ets:insert(snmpm_agent_table, {{TargetName, Item}, Val})
+ end,
+ lists:foreach(InsertItem, Info).
+
+do_update_agent_info(TargetName, Item, Val) ->
+ ?vtrace("do_update_agent_info -> entry with"
+ "~n TargetName: ~p"
+ "~n Item: ~p"
+ "~n Val: ~p", [TargetName, Item, Val]),
+ ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}),
+ ok.
+
handle_register_usm_user(#usm_user{engine_id = EngineID,
name = Name} = User) ->
@@ -2791,7 +2979,7 @@ verify_mandatory(Conf, [Mand|Mands]) ->
true ->
verify_mandatory(Conf, Mands);
false ->
- {error, {missing_mandatory_config, Mand}}
+ throw({error, {missing_mandatory_config, Mand}})
end.
verify_invalid(_, []) ->
@@ -2801,7 +2989,7 @@ verify_invalid(Conf, [Inv|Invs]) ->
false ->
verify_invalid(Conf, Invs);
true ->
- {error, {illegal_config, Inv}}
+ throw({error, {illegal_config, Inv}})
end.
@@ -2810,10 +2998,26 @@ verify_val(user_id, UserId) ->
verify_val(reg_type, RegType)
when (RegType =:= addr_port) orelse (RegType =:= target_name) ->
{ok, RegType};
-verify_val(address, Addr0) ->
- case normalize_address(Addr0) of
+verify_val(tdomain = Item, snmpUDPDomain = _Domain) ->
+ verify_val(Item, transportDomainUdpIpv4);
+verify_val(tdomain, Domain) ->
+ case lists:member(Domain, ?SUPPORTED_DOMAINS) of
+ true ->
+ {ok, Domain};
+ false ->
+ case lists:member(Domain, snmp_conf:all_domains()) of
+ true ->
+ error({unsupported_domain, Domain});
+ false ->
+ error({unknown_domain, Domain})
+ end
+ end;
+verify_val(address, {Domain, Addr0}) ->
+ case normalize_address(Domain, Addr0) of
{_A1, _A2, _A3, _A4} = Addr ->
{ok, Addr};
+ {_A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8} = Addr ->
+ {ok, Addr};
_ when is_list(Addr0) ->
case (catch snmp_conf:check_ip(Addr0)) of
ok ->
@@ -2824,6 +3028,8 @@ verify_val(address, Addr0) ->
_ ->
error({bad_address, Addr0})
end;
+verify_val(address, BadAddress) ->
+ error({bad_address, BadAddress});
verify_val(port, Port) ->
case (catch snmp_conf:check_integer(Port, {gt, 0})) of
ok ->
@@ -2875,7 +3081,7 @@ verify_val(sec_name, BadName) ->
verify_val(sec_level, Level) ->
(catch snmp_conf:check_sec_level(Level));
verify_val(Item, _) ->
- {error, {no_such_item, Item}}.
+ {error, {unknown_item, Item}}.
%%%-------------------------------------------------------------------
@@ -3034,11 +3240,17 @@ init_mini_mib_elems(MibName, [_|T], Res) ->
%%----------------------------------------------------------------------
normalize_address(Addr) ->
- case inet:getaddr(Addr, inet) of
+ normalize_address(snmpUDPDomain, Addr).
+
+normalize_address(snmpUDPDomain, Addr) ->
+ normalize_address(transportDomainUdpIpv4, Addr);
+
+normalize_address(Domain, Addr) ->
+ case inet:getaddr(Addr, td2fam(Domain)) of
{ok, Addr2} ->
Addr2;
_ when is_list(Addr) ->
- case (catch snmp_conf:check_ip(Addr)) of
+ case (catch snmp_conf:check_ip(Domain, Addr)) of
ok ->
list_to_tuple(Addr);
_ ->
@@ -3048,6 +3260,9 @@ normalize_address(Addr) ->
Addr
end.
+td2fam(transportDomainUdpIpv4) -> inet;
+td2fam(transportDomainUdpIpv6) -> inet6.
+
%%----------------------------------------------------------------------
diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl
index 7712370d28..627838e3d4 100644
--- a/lib/snmp/src/manager/snmpm_mpd.erl
+++ b/lib/snmp/src/manager/snmpm_mpd.erl
@@ -92,7 +92,7 @@ reset(#state{v3 = V3}) ->
%% Purpose: This is the main Message Dispatching function. (see
%% section 4.2.1 in rfc2272)
%%-----------------------------------------------------------------
-process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) ->
+process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) ->
inc(snmpInPkts),
@@ -102,18 +102,18 @@ process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) ->
#message{version = 'version-1', vsn_hdr = Community, data = Data}
when State#state.v1 =:= true ->
HS = ?empty_msg_size + length(Community),
- process_v1_v2c_msg('version-1', NoteStore, Msg, TDomain,
- Addr, Port,
+ process_v1_v2c_msg('version-1', NoteStore, Msg,
+ Domain, Addr, Port,
Community, Data, HS, Logger);
%% Version 2
#message{version = 'version-2', vsn_hdr = Community, data = Data}
when State#state.v2c =:= true ->
HS = ?empty_msg_size + length(Community),
- process_v1_v2c_msg('version-2', NoteStore, Msg, TDomain,
- Addr, Port,
- Community, Data, HS, Logger);
-
+ (catch process_v1_v2c_msg('version-2', NoteStore, Msg,
+ Domain, Addr, Port,
+ Community, Data, HS, Logger));
+
%% Version 3
#message{version = 'version-3', vsn_hdr = H, data = Data}
when State#state.v3 =:= true ->
@@ -148,17 +148,30 @@ process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) ->
%%-----------------------------------------------------------------
%% Handles a Community based message (v1 or v2c).
%%-----------------------------------------------------------------
-process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain,
+process_v1_v2c_msg(Vsn, _NoteStore, Msg, Domain,
Addr, Port,
Community, Data, HS, Log) ->
?vdebug("process_v1_v2c_msg -> entry with"
"~n Vsn: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
"~n Port: ~p"
"~n Community: ~p"
- "~n HS: ~p", [Vsn, Addr, Port, Community, HS]),
+ "~n HS: ~p", [Vsn, Domain, Addr, Port, Community, HS]),
+ {TDomain, TAddress} =
+ try
+ begin
+ TD = snmp_conf:mk_tdomain(Domain),
+ TA = snmp_conf:mk_taddress(Domain, Addr, Port),
+ {TD, TA}
+ end
+ catch
+ throw:{error, TReason} ->
+ throw({discarded, {badarg, Domain, TReason}})
+ end,
+
Max = get_max_message_size(),
AgentMax = get_agent_max_message_size(Addr, Port),
PduMS = pdu_ms(Max, AgentMax, HS),
@@ -170,14 +183,14 @@ process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain,
?vtrace("process_v1_v2c_msg -> was a pdu", []),
Log(Msg),
inc_snmp_in(Pdu),
- MsgData = {Community, sec_model(Vsn)},
+ MsgData = {Community, sec_model(Vsn), TDomain, TAddress},
{ok, Vsn, Pdu, PduMS, MsgData};
Trap when is_record(Trap, trappdu) ->
?vtrace("process_v1_v2c_msg -> was a trap", []),
Log(Msg),
inc_snmp_in(Trap),
- MsgData = {Community, sec_model(Vsn)},
+ MsgData = {Community, sec_model(Vsn), TDomain, TAddress},
{ok, Vsn, Trap, PduMS, MsgData};
{'EXIT', Reason} ->
@@ -185,11 +198,7 @@ process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain,
"~n Reason: ~p", [Reason]),
inc(snmpInASNParseErrs),
{discarded, Reason}
- end;
-process_v1_v2c_msg(_Vsn, _NoteStore, _Msg, TDomain,
- _Addr, _Port,
- _Comm, _HS, _Data, _Log) ->
- {discarded, {badarg, TDomain}}.
+ end.
pdu_ms(MgrMMS, AgentMMS, HS) when AgentMMS < MgrMMS ->
AgentMMS - HS;
@@ -482,8 +491,8 @@ generate_msg('version-3', NoteStore, Pdu,
generate_v3_msg(NoteStore, Pdu,
SecModel, SecName, SecLevel, CtxEngineID, CtxName,
TargetName, Log);
-generate_msg(Vsn, _NoteStore, Pdu, {Community, _SecModel}, Log) ->
- generate_v1_v2c_msg(Vsn, Pdu, Community, Log).
+generate_msg(Vsn, _NoteStore, Pdu, {Comm, _SecModel}, Log) ->
+ generate_v1_v2c_msg(Vsn, Pdu, Comm, Log).
generate_v3_msg(NoteStore, Pdu,
@@ -627,6 +636,8 @@ generate_response_msg('version-3', Pdu,
generate_v3_response_msg(Pdu, MsgID, SecModel, SecName, SecLevel,
CtxEngineID, CtxName, SecData, Log);
generate_response_msg(Vsn, Pdu, {Comm, _SecModel}, Log) ->
+ generate_v1_v2c_response_msg(Vsn, Pdu, Comm, Log);
+generate_response_msg(Vsn, Pdu, {Comm, _SecModel, _TDomain, _TAddress}, Log) ->
generate_v1_v2c_response_msg(Vsn, Pdu, Comm, Log).
diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl
index a116c9f26b..4d6bd9aa33 100644
--- a/lib/snmp/src/manager/snmpm_net_if.erl
+++ b/lib/snmp/src/manager/snmpm_net_if.erl
@@ -28,7 +28,8 @@
start_link/2,
stop/1,
send_pdu/6, % Backward compatibillity
- send_pdu/7,
+ send_pdu/7, % Backward compatibillity
+ send_pdu/8,
inform_response/4,
@@ -101,16 +102,21 @@ stop(Pid) ->
send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) ->
send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO).
-send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo)
+send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) ->
+ Domain = snmpm_config:default_transport_domain(),
+ send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo).
+
+send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, 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: ~p"
"~n Addr: ~p"
- "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Addr, Port]),
- cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}).
+ "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]),
+ cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}).
note_store(Pid, NoteStore) ->
call(Pid, {note_store, NoteStore}).
@@ -380,15 +386,17 @@ handle_call(Req, From, State) ->
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%%--------------------------------------------------------------------
-handle_cast({send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}, State) ->
+handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo},
+ State) ->
?vlog("received send_pdu message with"
"~n Pdu: ~p"
"~n Vsn: ~p"
"~n MsgData: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
- "~n Port: ~p", [Pdu, Vsn, MsgData, Addr, Port]),
+ "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]),
maybe_process_extra_info(ExtraInfo),
- maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State),
+ maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State),
{noreply, State};
handle_cast({inform_response, Ref, Addr, Port}, State) ->
@@ -545,8 +553,9 @@ handle_recv_msg(Addr, Port, Bytes,
mpd_state = MpdState,
sock = Sock,
log = Log} = State) ->
+ Domain = snmp_conf:which_domain(Addr), % What the ****...
Logger = logger(Log, read, Addr, Port),
- case (catch snmpm_mpd:process_msg(Bytes, snmpUDPDomain, Addr, Port,
+ case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port,
MpdState, NoteStore, Logger)) of
{ok, Vsn, Pdu, MS, ACM} ->
@@ -734,17 +743,17 @@ irgc_stop(Ref) ->
(catch erlang:cancel_timer(Ref)).
-maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port,
+maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port,
#state{filter = FilterMod} = State) ->
case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of
false ->
inc(netIfPduOutDrops),
ok;
_ ->
- handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State)
+ handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State)
end.
-handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port,
+handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port,
#state{server = Pid,
note_store = NoteStore,
sock = Sock,
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 58a58507d6..484954addb 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -161,7 +161,8 @@
{id,
user_id,
reg_type,
- target,
+ target,
+ domain,
addr,
port,
type,
@@ -1175,11 +1176,12 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) ->
"~n From: ~p",
[Pid, UserId, TargetName, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_request(Oids, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
Timeout = ?SYNC_GET_TIMEOUT(SendOpts),
@@ -1190,6 +1192,7 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) ->
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get,
@@ -1227,11 +1230,12 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts,
"~n From: ~p",
[Pid, UserId, TargetName, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
Timeout = ?SYNC_GET_NEXT_TIMEOUT(SendOpts),
@@ -1242,6 +1246,7 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_next,
@@ -1285,10 +1290,11 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts,
"~n From: ~p",
[Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
- ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
+ ReqId = send_get_bulk_request(Oids, Vsn, MsgData,
+ Domain, Addr, Port,
NonRep, MaxRep, Extra, State),
?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
@@ -1300,6 +1306,7 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_bulk,
@@ -1339,11 +1346,12 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) ->
"~n From: ~p",
[Pid, UserId, TargetName, VarsAndVals, From]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_sync_set -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]),
Msg = {sync_timeout, ReqId, From},
Timeout = ?SYNC_SET_TIMEOUT(SendOpts),
@@ -1354,6 +1362,7 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) ->
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = set,
@@ -1391,10 +1400,11 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
- ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port,
+ ReqId = send_get_request(Oids, Vsn, MsgData,
+ Domain, Addr, Port,
Extra, State),
?vdebug("handle_async_get -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_TIMEOUT(SendOpts),
@@ -1402,6 +1412,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) ->
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get,
@@ -1439,17 +1450,19 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get_next -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_get_next_request(Oids, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts),
Req = #request{id = ReqId,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_next,
@@ -1494,10 +1507,11 @@ handle_async_get_bulk(Pid,
"~n SendOpts: ~p",
[Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
- ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
+ ReqId = send_get_bulk_request(Oids, Vsn, MsgData,
+ Domain, Addr, Port,
NonRep, MaxRep, Extra, State),
?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts),
@@ -1505,6 +1519,7 @@ handle_async_get_bulk(Pid,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = get_bulk,
@@ -1541,17 +1556,19 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) ->
"~n SendOpts: ~p",
[Pid, UserId, TargetName, VarsAndVals, SendOpts]),
case agent_data(TargetName, SendOpts) of
- {ok, RegType, Addr, Port, Vsn, MsgData} ->
+ {ok, RegType, Domain, Addr, Port, Vsn, MsgData} ->
?vtrace("handle_async_set -> send a ~p message", [Vsn]),
Extra = ?GET_EXTRA(SendOpts),
ReqId = send_set_request(VarsAndVals, Vsn, MsgData,
- Addr, Port, Extra, State),
+ Domain, Addr, Port,
+ Extra, State),
?vdebug("handle_async_set -> ReqId: ~p", [ReqId]),
Expire = ?ASYNC_SET_TIMEOUT(SendOpts),
Req = #request{id = ReqId,
user_id = UserId,
reg_type = RegType,
target = TargetName,
+ domain = Domain,
addr = Addr,
port = Port,
type = set,
@@ -2907,7 +2924,7 @@ do_gc(Key, Now) ->
%%
%%----------------------------------------------------------------------
-send_get_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo,
+send_get_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
#state{net_if = NetIf,
net_if_mod = Mod,
mini_mib = MiniMIB}) ->
@@ -2918,34 +2935,39 @@ send_get_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo,
"~n Pdu: ~p"
"~n Vsn: ~p"
"~n MsgData: ~p"
+ "~n Domain: ~p"
"~n Addr: ~p"
- "~n Port: ~p", [Mod, NetIf, Pdu, Vsn, MsgData, Addr, Port]),
- (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo)),
+ "~n Port: ~p",
+ [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port]),
+ Res = (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData,
+ Domain, Addr, Port, ExtraInfo)),
+ ?vtrace("send_get_request -> send result:"
+ "~n ~p", [Res]),
Pdu#pdu.request_id.
-send_get_next_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo,
+send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(get_next, Oids, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
Pdu#pdu.request_id.
-send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port,
+send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr, Port,
NonRep, MaxRep, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(bulk, {NonRep, MaxRep, Oids}, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
Pdu#pdu.request_id.
-send_set_request(VarsAndVals, Vsn, MsgData, Addr, Port, ExtraInfo,
+send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, Port, ExtraInfo,
#state{mini_mib = MiniMIB,
net_if = NetIf,
net_if_mod = Mod}) ->
Pdu = make_pdu(set, VarsAndVals, MiniMIB),
- Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo),
+ Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo),
Pdu#pdu.request_id.
%% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo,
@@ -3181,10 +3203,11 @@ agent_data(TargetName, SendOpts) ->
{Comm, SecModel}
end,
+ Domain = agent_data_item(tdomain, Info),
Addr = agent_data_item(address, Info),
Port = agent_data_item(port, Info),
RegType = agent_data_item(reg_type, Info),
- {ok, RegType, Addr, Port, version(Version), MsgData};
+ {ok, RegType, Domain, Addr, Port, version(Version), MsgData};
Error ->
Error
end.
diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index 20f4455d10..7249def24e 100644
--- a/lib/snmp/src/misc/snmp_conf.erl
+++ b/lib/snmp/src/misc/snmp_conf.erl
@@ -37,7 +37,9 @@
check_timer/1,
+ all_domains/0,
check_domain/1,
+ all_tdomains/0,
check_tdomain/1,
mk_tdomain/1,
which_domain/1,
@@ -345,6 +347,25 @@ check_sec_level(BadSecLevel) ->
%% ---------
+all_tdomains() ->
+ [
+ ?transportDomainUdpIpv4,
+ ?transportDomainUdpIpv6,
+ ?transportDomainUdpIpv4z,
+ ?transportDomainUdpIpv6z,
+ ?transportDomainTcpIpv4,
+ ?transportDomainTcpIpv6,
+ ?transportDomainTcpIpv4z,
+ ?transportDomainTcpIpv6z,
+ ?transportDomainSctpIpv4,
+ ?transportDomainSctpIpv6,
+ ?transportDomainSctpIpv4z,
+ ?transportDomainSctpIpv6z,
+ ?transportDomainLocal,
+ ?transportDomainUdpDns,
+ ?transportDomainTcpDns,
+ ?transportDomainSctpDns
+ ].
check_tdomain(TDomain) ->
SupportedTDomains =
@@ -353,25 +374,7 @@ check_tdomain(TDomain) ->
?transportDomainUdpIpv4,
?transportDomainUdpIpv6
],
- AllTDomains =
- [
- ?transportDomainUdpIpv4,
- ?transportDomainUdpIpv6,
- ?transportDomainUdpIpv4z,
- ?transportDomainUdpIpv6z,
- ?transportDomainTcpIpv4,
- ?transportDomainTcpIpv6,
- ?transportDomainTcpIpv4z,
- ?transportDomainTcpIpv6z,
- ?transportDomainSctpIpv4,
- ?transportDomainSctpIpv6,
- ?transportDomainSctpIpv4z,
- ?transportDomainSctpIpv6z,
- ?transportDomainLocal,
- ?transportDomainUdpDns,
- ?transportDomainTcpDns,
- ?transportDomainSctpDns
- ],
+ AllTDomains = all_tdomains(),
case lists:member(TDomain, SupportedTDomains) of
true ->
ok;
@@ -388,7 +391,7 @@ check_tdomain(TDomain) ->
%% ---------
mk_tdomain(snmpUDPDomain) ->
- ?snmpUDPDomain;
+ mk_tdomain(transportDomainUdpIpv4);
mk_tdomain(transportDomainUdpIpv4) ->
?transportDomainUdpIpv4;
mk_tdomain(transportDomainUdpIpv6) ->
@@ -474,6 +477,26 @@ do_check_timer(WaitFor, Factor, Incr, Retry) ->
%% ---------
+all_domains() ->
+ [
+ transportDomainUdpIpv4,
+ transportDomainUdpIpv6,
+ transportDomainUdpIpv4z,
+ transportDomainUdpIpv6z,
+ transportDomainTcpIpv4,
+ transportDomainTcpIpv6,
+ transportDomainTcpIpv4z,
+ transportDomainTcpIpv6z,
+ transportDomainSctpIpv4,
+ transportDomainSctpIpv6,
+ transportDomainSctpIpv4z,
+ transportDomainSctpIpv6z,
+ transportDomainLocal,
+ transportDomainUdpDns,
+ transportDomainTcpDns,
+ transportDomainSctpDns
+ ].
+
check_domain(Domain) ->
SupportedDomains =
[
@@ -481,25 +504,7 @@ check_domain(Domain) ->
transportDomainUdpIpv4,
transportDomainUdpIpv6
],
- AllDomains =
- [
- transportDomainUdpIpv4,
- transportDomainUdpIpv6,
- transportDomainUdpIpv4z,
- transportDomainUdpIpv6z,
- transportDomainTcpIpv4,
- transportDomainTcpIpv6,
- transportDomainTcpIpv4z,
- transportDomainTcpIpv6z,
- transportDomainSctpIpv4,
- transportDomainSctpIpv6,
- transportDomainSctpIpv4z,
- transportDomainSctpIpv6z,
- transportDomainLocal,
- transportDomainUdpDns,
- transportDomainTcpDns,
- transportDomainSctpDns
- ],
+ AllDomains = all_domains(),
case lists:member(Domain, SupportedDomains) of
true ->
ok;
diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl
index fcbc6a88c9..6ab20e3e48 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -337,7 +337,7 @@ config_agent_sys() ->
{dir, ATLDir},
{size, ATLSize},
{repair, ATLRepair},
- {seqno, ATLSeqNo}]}];
+ {seqno, ATLSeqNo}]}];
no ->
[]
end,
@@ -568,7 +568,7 @@ config_agent_snmp(Dir, Vsns) ->
false ->
ok
end,
- i("The following agent files were written: agent.conf, "
+ i("The following agent files where written: agent.conf, "
"community.conf,~n"
"standard.conf, target_addr.conf, "
"target_params.conf, ~n"
@@ -776,7 +776,7 @@ config_manager_snmp(Dir, Vsns) ->
Users, Agents, Usms)) of
ok ->
i("~n- - - - - - - - - - - - -"),
- i("The following manager files were written: "
+ i("The following manager files where written: "
"manager.conf, agents.conf " ++
case lists:member(v3, Vsns) of
true ->
@@ -2350,7 +2350,9 @@ write_sys_config_file_manager_atl_opt(Fid, {type, Type}) ->
write_sys_config_file_manager_atl_opt(Fid, {size, Size}) ->
ok = io:format(Fid, "{size, ~w}", [Size]);
write_sys_config_file_manager_atl_opt(Fid, {repair, Rep}) ->
- ok = io:format(Fid, "{repair, ~w}", [Rep]).
+ ok = io:format(Fid, "{repair, ~w}", [Rep]);
+write_sys_config_file_manager_atl_opt(Fid, {seqno, SeqNo}) ->
+ ok = io:format(Fid, "{seqno, ~w}", [SeqNo]).
header() ->
diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl
index 2e6020ae7a..cee11ba97a 100644
--- a/lib/snmp/test/snmp_compiler_test.erl
+++ b/lib/snmp/test/snmp_compiler_test.erl
@@ -47,6 +47,7 @@
module_identity/1,
agent_capabilities/1,
module_compliance/1,
+ warnings_as_errors/1,
otp_6150/1,
otp_8574/1,
@@ -97,9 +98,10 @@ all() ->
description,
oid_conflicts,
imports,
- module_identity,
- agent_capabilities,
- module_compliance,
+ module_identity,
+ agent_capabilities,
+ module_compliance,
+ warnings_as_errors,
{group, tickets}
].
@@ -152,6 +154,8 @@ description(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
oid_conflicts(suite) -> [];
oid_conflicts(Config) when is_list(Config) ->
put(tname,oid_conflicts),
@@ -165,18 +169,24 @@ oid_conflicts(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
imports(suite) ->
[];
imports(Config) when is_list(Config) ->
?SKIP(not_yet_implemented).
+%%======================================================================
+
module_identity(suite) ->
[];
module_identity(Config) when is_list(Config) ->
?SKIP(not_yet_implemented).
+%%======================================================================
+
agent_capabilities(suite) ->
[];
agent_capabilities(Config) when is_list(Config) ->
@@ -218,6 +228,8 @@ agent_capabilities(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
module_compliance(suite) ->
[];
module_compliance(Config) when is_list(Config) ->
@@ -259,6 +271,31 @@ module_compliance(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
+warnings_as_errors(suite) ->
+ ["OTP-9437"];
+warnings_as_errors(Config) when is_list(Config) ->
+ put(tname,warnings_as_errors),
+ p("starting with Config: ~p~n", [Config]),
+ Dir = ?config(comp_dir, Config),
+ MibDir = ?config(mib_dir, Config),
+ MibFile = join(MibDir, "OTP8574-MIB.mib"),
+ OutFile = join(Dir, "OTP8574-MIB.bin"),
+ Opts = [{group_check, false},
+ {outdir, Dir},
+ {verbosity, trace},
+ relaxed_row_name_assign_check],
+ {error, compilation_failed} =
+ snmpc:compile(MibFile, [warnings_as_errors|Opts]),
+ false = filelib:is_regular(OutFile),
+ {ok, _} = snmpc:compile(MibFile, Opts),
+ true = filelib:is_regular(OutFile),
+ ok.
+
+
+%%======================================================================
+
otp_6150(suite) ->
[];
otp_6150(Config) when is_list(Config) ->
@@ -273,6 +310,8 @@ otp_6150(Config) when is_list(Config) ->
ok.
+%%======================================================================
+
otp_8574(suite) ->
[];
otp_8574(Config) when is_list(Config) ->
@@ -304,6 +343,8 @@ otp_8574(Config) when is_list(Config) ->
end.
+%%======================================================================
+
otp_8595(suite) ->
[];
otp_8595(Config) when is_list(Config) ->
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index 0b536748fb..d18f20d359 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -61,6 +61,7 @@
register_agent1/1,
register_agent2/1,
+ register_agent3/1,
info/1,
@@ -383,12 +384,12 @@ end_per_testcase2(Case, Config) ->
all() ->
[
{group, start_and_stop_tests},
- {group, misc_tests},
+ {group, misc_tests},
{group, user_tests},
- {group, agent_tests},
+ {group, agent_tests},
{group, request_tests},
{group, event_tests},
- discovery,
+ discovery,
{group, tickets}
].
@@ -417,7 +418,8 @@ groups() ->
{agent_tests, [],
[
register_agent1,
- register_agent2
+ register_agent2,
+ register_agent3
]
},
{request_tests, [],
@@ -477,14 +479,14 @@ groups() ->
},
{event_tests, [],
[
- trap1,
- trap2,
- inform1,
- inform2,
- inform3,
- inform4,
- inform_swarm,
- report
+ trap1%% ,
+ %% trap2,
+ %% inform1,
+ %% inform2,
+ %% inform3,
+ %% inform4,
+ %% inform_swarm,
+ %% report
]
},
{tickets, [],
@@ -1134,6 +1136,7 @@ register_agent1(suite) ->
register_agent1(Config) when is_list(Config) ->
process_flag(trap_exit, true),
put(tname,ra1),
+
p("starting with Config: ~p~n", [Config]),
ManagerNode = start_manager_node(),
@@ -1164,7 +1167,7 @@ register_agent1(Config) when is_list(Config) ->
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) calvin & hobbe"),
+ p("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
@@ -1293,7 +1296,7 @@ register_agent2(Config) when is_list(Config) ->
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("register user(s) calvin & hobbe"),
+ p("register user(s) user_alfa & user_beta"),
?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
@@ -1348,7 +1351,7 @@ register_agent2(Config) when is_list(Config) ->
end,
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
-
+
p("unregister user user_alfa"),
?line ok = mgr_unregister_user(ManagerNode, user_alfa),
@@ -1377,7 +1380,157 @@ register_agent2(Config) when is_list(Config) ->
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
- p("unregister user hobbe"),
+ p("unregister user user_beta"),
+ ?line ok = mgr_unregister_user(ManagerNode, user_beta),
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ ?SLEEP(1000),
+
+ p("stop snmp application (with only manager)"),
+ ?line ok = stop_snmp(ManagerNode),
+
+ ?SLEEP(1000),
+
+ stop_node(ManagerNode),
+
+ ?SLEEP(1000),
+
+ p("end"),
+ ok.
+
+
+%%======================================================================
+
+register_agent3(doc) ->
+ ["Test registration of agents with the NEW interface functions "
+ "and specifying transport domain"];
+register_agent3(suite) ->
+ [];
+register_agent3(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ put(tname, ra3),
+ p("starting with Config: ~p~n", [Config]),
+
+ ManagerNode = start_manager_node(),
+
+ ConfDir = ?config(manager_conf_dir, Config),
+ DbDir = ?config(manager_db_dir, Config),
+ LocalHost = snmp_test_lib:localhost(),
+
+
+ write_manager_conf(ConfDir),
+
+ Opts = [{server, [{verbosity, trace}]},
+ {net_if, [{verbosity, trace}]},
+ {note_store, [{verbosity, trace}]},
+ {config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}],
+
+
+ p("load snmp application"),
+ ?line ok = load_snmp(ManagerNode),
+
+ p("set manager env for the snmp application"),
+ ?line ok = set_mgr_env(ManagerNode, Opts),
+
+ p("starting snmp application (with only manager)"),
+ ?line ok = start_snmp(ManagerNode),
+
+ p("started"),
+
+ ?SLEEP(1000),
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("register user(s) user_alfa & user_beta"),
+ ?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []),
+ ?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []),
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("register agent(s)"),
+ TargetName1 = "agent2",
+ ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName1,
+ [{tdomain, transportDomainUdpIpv4},
+ {address, LocalHost},
+ {port, 5001},
+ {engine_id, "agentEngineId-1"}]),
+ TargetName2 = "agent3",
+ ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName2,
+ [{tdomain, transportDomainUdpIpv6},
+ {address, LocalHost},
+ {port, 5002},
+ {engine_id, "agentEngineId-2"}]),
+ TargetName3 = "agent4",
+ ?line {error, {unsupported_domain, _} = Reason4} =
+ mgr_register_agent(ManagerNode, user_beta, TargetName3,
+ [{tdomain, transportDomainTcpIpv4},
+ {address, LocalHost},
+ {port, 5003},
+ {engine_id, "agentEngineId-3"}]),
+ p("Expected registration failure: ~p", [Reason4]),
+ TargetName4 = "agent5",
+ ?line {error, {unknown_domain, _} = Reason5} =
+ mgr_register_agent(ManagerNode, user_beta, TargetName4,
+ [{tdomain, transportDomainUdpIpv4_bad},
+ {address, LocalHost},
+ {port, 5004},
+ {engine_id, "agentEngineId-4"}]),
+ p("Expected registration failure: ~p", [Reason5]),
+
+ p("verify all agent(s): expect 2"),
+ case mgr_which_agents(ManagerNode) of
+ Agents1 when length(Agents1) =:= 2 ->
+ p("all agents: ~p~n", [Agents1]),
+ ok;
+ Agents1 ->
+ ?FAIL({agent_registration_failure, Agents1})
+ end,
+
+ p("verify user_alfa agent(s)"),
+ case mgr_which_agents(ManagerNode, user_alfa) of
+ Agents2 when length(Agents2) =:= 2 ->
+ p("calvin agents: ~p~n", [Agents2]),
+ ok;
+ Agents2 ->
+ ?FAIL({agent_registration_failure, Agents2})
+ end,
+
+ p("verify user_beta agent(s)"),
+ case mgr_which_agents(ManagerNode, user_beta) of
+ Agents3 when length(Agents3) =:= 0 ->
+ p("hobbe agents: ~p~n", [Agents3]),
+ ok;
+ Agents3 ->
+ ?FAIL({agent_registration_failure, Agents3})
+ end,
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("unregister user user_alfa"),
+ ?line ok = mgr_unregister_user(ManagerNode, user_alfa),
+
+ p("verify all agent(s): expect 0"),
+ case mgr_which_agents(ManagerNode) of
+ Agents4 when length(Agents4) =:= 0 ->
+ p("all agents: ~p~n", [Agents4]),
+ ok;
+ Agents4 ->
+ ?FAIL({agent_unregistration_failure, Agents4})
+ end,
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("verify all agent(s): expect 0"),
+ case mgr_which_agents(ManagerNode) of
+ [] ->
+ ok;
+ Agents5 ->
+ p("all agents: ~p~n", [Agents5]),
+ ?FAIL({agent_unregistration_failure, Agents5})
+ end,
+
+ p("manager info: ~p~n", [mgr_info(ManagerNode)]),
+
+ p("unregister user user_beta"),
?line ok = mgr_unregister_user(ManagerNode, user_beta),
p("manager info: ~p~n", [mgr_info(ManagerNode)]),
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 29228fc59b..08251ab9ea 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -17,6 +17,6 @@
#
# %CopyrightEnd%
-SNMP_VSN = 4.20
+SNMP_VSN = 4.21
PRE_VSN =
APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)"
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 52aa4d073c..ded1346097 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.erl
@@ -24,6 +24,10 @@
-import(lists, [reverse/1,reverse/2]).
+-define(is_whitespace(C),
+ ((C) =:= $\s orelse (C) =:= $\t
+ orelse (C) =:= $\r orelse (C) =:= $\n)).
+
%%-----------------------------------------------------------------------
%% fread(Continuation, CharList, FormatString)
@@ -106,31 +110,27 @@ fread_line(Format0, Line, N0, Results0, More, Newline) ->
fread(Format, Line) ->
fread(Format, Line, 0, []).
-fread([$~|Format0], Line, N, Results) ->
+fread([$~|Format0]=AllFormat, Line, N, Results) ->
{Format,F,Sup,Unicode} = fread_field(Format0),
- fread1(Format, F, Sup, Unicode, Line, N, Results, Format0);
-fread([$\s|Format], Line, N, Results) ->
- fread_skip_white(Format, Line, N, Results);
-fread([$\t|Format], Line, N, Results) ->
- fread_skip_white(Format, Line, N, Results);
-fread([$\r|Format], Line, N, Results) ->
- fread_skip_white(Format, Line, N, Results);
-fread([$\n|Format], Line, N, Results) ->
+ fread1(Format, F, Sup, Unicode, Line, N, Results, AllFormat);
+fread([C|Format], Line, N, Results) when ?is_whitespace(C) ->
fread_skip_white(Format, Line, N, Results);
fread([C|Format], [C|Line], N, Results) ->
fread(Format, Line, N+1, Results);
fread([_F|_Format], [_C|_Line], _N, _Results) ->
fread_error(input);
+fread([_|_]=Format, [], N, Results) ->
+ {more,Format,N,Results};
+fread([_|_], eof, 0, []) ->
+ %% This is at start of input so no error.
+ eof;
+fread([_|_], eof, _N, _Results) ->
+ %% This is an error as there is no more input.
+ fread_error(input);
fread([], Line, _N, Results) ->
{ok,reverse(Results),Line}.
-fread_skip_white(Format, [$\s|Line], N, Results) ->
- fread_skip_white(Format, Line, N+1, Results);
-fread_skip_white(Format, [$\t|Line], N, Results) ->
- fread_skip_white(Format, Line, N+1, Results);
-fread_skip_white(Format, [$\r|Line], N, Results) ->
- fread_skip_white(Format, Line, N+1, Results);
-fread_skip_white(Format, [$\n|Line], N, Results) ->
+fread_skip_white(Format, [C|Line], N, Results) when ?is_whitespace(C) ->
fread_skip_white(Format, Line, N+1, Results);
fread_skip_white(Format, Line, N, Results) ->
fread(Format, Line, N, Results).
@@ -166,9 +166,9 @@ fread1([$l|Format], _F, Sup, _U, Line, N, Res, _AllFormat) ->
fread(Format, Line, N, fread_result(Sup, N, Res));
fread1(_Format, _F, _Sup, _U, [], N, Res, AllFormat) ->
%% Need more input here.
- {more,[$~|AllFormat],N,Res};
-fread1(_Format, _F, _Sup, _U, eof, _N, [], _AllFormat) ->
- %% This is at start of format string so no error.
+ {more,AllFormat,N,Res};
+fread1(_Format, _F, _Sup, _U, eof, 0, [], _AllFormat) ->
+ %% This is at start of input so no error.
eof;
fread1(_Format, _F, _Sup, _U, eof, _N, _Res, _AllFormat) ->
%% This is an error as there is no more input.
@@ -386,26 +386,16 @@ fread_string_cs(Line0, N0, true) ->
%% fread_digits(Line, N, Base, Characters)
%% Read segments of things, return "thing" characters in reverse order.
-fread_skip_white([$\s|Line]) -> fread_skip_white(Line);
-fread_skip_white([$\t|Line]) -> fread_skip_white(Line);
-fread_skip_white([$\r|Line]) -> fread_skip_white(Line);
-fread_skip_white([$\n|Line]) -> fread_skip_white(Line);
+fread_skip_white([C|Line]) when ?is_whitespace(C) ->
+ fread_skip_white(Line);
fread_skip_white(Line) -> Line.
-fread_skip_white([$\s|Line], N) ->
- fread_skip_white(Line, N+1);
-fread_skip_white([$\t|Line], N) ->
- fread_skip_white(Line, N+1);
-fread_skip_white([$\r|Line], N) ->
- fread_skip_white(Line, N+1);
-fread_skip_white([$\n|Line], N) ->
+fread_skip_white([C|Line], N) when ?is_whitespace(C) ->
fread_skip_white(Line, N+1);
fread_skip_white(Line, N) -> {Line,N}.
-fread_skip_latin1_nonwhite([$\s|Line], N, Cs) -> {[$\s|Line],N,Cs};
-fread_skip_latin1_nonwhite([$\t|Line], N, Cs) -> {[$\t|Line],N,Cs};
-fread_skip_latin1_nonwhite([$\r|Line], N, Cs) -> {[$\r|Line],N,Cs};
-fread_skip_latin1_nonwhite([$\n|Line], N, Cs) -> {[$\n|Line],N,Cs};
+fread_skip_latin1_nonwhite([C|Line], N, Cs) when ?is_whitespace(C) ->
+ {[C|Line],N,Cs};
fread_skip_latin1_nonwhite([C|Line], N, []) when C > 255 ->
{[C|Line],N,error};
fread_skip_latin1_nonwhite([C|Line], N, Cs) when C > 255 ->
@@ -414,10 +404,8 @@ fread_skip_latin1_nonwhite([C|Line], N, Cs) ->
fread_skip_latin1_nonwhite(Line, N+1, [C|Cs]);
fread_skip_latin1_nonwhite([], N, Cs) -> {[],N,Cs}.
-fread_skip_nonwhite([$\s|Line], N, Cs) -> {[$\s|Line],N,Cs};
-fread_skip_nonwhite([$\t|Line], N, Cs) -> {[$\t|Line],N,Cs};
-fread_skip_nonwhite([$\r|Line], N, Cs) -> {[$\r|Line],N,Cs};
-fread_skip_nonwhite([$\n|Line], N, Cs) -> {[$\n|Line],N,Cs};
+fread_skip_nonwhite([C|Line], N, Cs) when ?is_whitespace(C) ->
+ {[C|Line],N,Cs};
fread_skip_nonwhite([C|Line], N, Cs) ->
fread_skip_nonwhite(Line, N+1, [C|Cs]);
fread_skip_nonwhite([], N, Cs) -> {[],N,Cs}.
diff --git a/lib/stdlib/test/ets_SUITE.erl b/lib/stdlib/test/ets_SUITE.erl
index c9d82ec5f5..9341300f90 100644
--- a/lib/stdlib/test/ets_SUITE.erl
+++ b/lib/stdlib/test/ets_SUITE.erl
@@ -72,6 +72,7 @@
exit_many_many_tables_owner/1]).
-export([write_concurrency/1, heir/1, give_away/1, setopts/1]).
-export([bad_table/1, types/1]).
+-export([otp_9423/1]).
-export([init_per_testcase/2, end_per_testcase/2]).
%% Convenience for manual testing
@@ -143,7 +144,8 @@ all() ->
otp_8166, exit_large_table_owner,
exit_many_large_table_owner, exit_many_tables_owner,
exit_many_many_tables_owner, write_concurrency, heir,
- give_away, setopts, bad_table, types].
+ give_away, setopts, bad_table, types,
+ otp_9423].
groups() ->
[{new, [],
@@ -5420,7 +5422,39 @@ types_do(Opts) ->
?line verify_etsmem(EtsMem).
-
+otp_9423(doc) -> ["vm-deadlock caused by race between ets:delete and others on write_concurrency table"];
+otp_9423(Config) when is_list(Config) ->
+ InitF = fun(_) -> {0,0} end,
+ ExecF = fun({S,F}) ->
+ receive
+ stop ->
+ io:format("~p got stop\n", [self()]),
+ [end_of_work | {"Succeded=",S,"Failed=",F}]
+ after 0 ->
+ %%io:format("~p (~p) doing lookup\n", [self(), {S,F}]),
+ try ets:lookup(otp_9423, key) of
+ [] -> {S+1,F}
+ catch
+ error:badarg -> {S,F+1}
+ end
+ end
+ end,
+ FiniF = fun(R) -> R end,
+ case run_workers(InitF, ExecF, FiniF, infinite, 1) of
+ Pids when is_list(Pids) ->
+ %%[P ! start || P <- Pids],
+ repeat(fun() -> ets:new(otp_9423, [named_table, public, {write_concurrency,true}]),
+ ets:delete(otp_9423)
+ end, 10000),
+ [P ! stop || P <- Pids],
+ wait_pids(Pids),
+ ok;
+
+ Skipped -> Skipped
+ end.
+
+
+
%
% Utility functions:
@@ -5434,21 +5468,30 @@ add_lists([E1|T1], [E2|T2], Acc) ->
add_lists(T1, T2, [E1+E2 | Acc]).
run_workers(InitF,ExecF,FiniF,Laps) ->
+ run_workers(InitF,ExecF,FiniF,Laps, 0).
+run_workers(InitF,ExecF,FiniF,Laps, Exclude) ->
case erlang:system_info(smp_support) of
true ->
- run_workers_do(InitF,ExecF,FiniF,Laps);
+ run_workers_do(InitF,ExecF,FiniF,Laps, Exclude);
false ->
{skipped,"No smp support"}
end.
-
+
run_workers_do(InitF,ExecF,FiniF,Laps) ->
- NumOfProcs = erlang:system_info(schedulers),
+ run_workers_do(InitF,ExecF,FiniF,Laps, 0).
+run_workers_do(InitF,ExecF,FiniF,Laps, Exclude) ->
+ ?line NumOfProcs = case erlang:system_info(schedulers) of
+ N when (N > Exclude) -> N - Exclude
+ end,
io:format("smp starting ~p workers\n",[NumOfProcs]),
Seeds = [{ProcN,random:uniform(9999)} || ProcN <- lists:seq(1,NumOfProcs)],
Parent = self(),
Pids = [spawn_link(fun()-> worker(Seed,InitF,ExecF,FiniF,Laps,Parent,NumOfProcs) end)
|| Seed <- Seeds],
- wait_pids(Pids).
+ case Laps of
+ infinite -> Pids;
+ _ -> wait_pids(Pids)
+ end.
worker({ProcN,Seed}, InitF, ExecF, FiniF, Laps, Parent, NumOfProcs) ->
io:format("smp worker ~p, seed=~p~n",[self(),Seed]),
@@ -5463,6 +5506,8 @@ worker_loop(0, _, State) ->
State;
worker_loop(_, _, [end_of_work|State]) ->
State;
+worker_loop(infinite, ExecF, State) ->
+ worker_loop(infinite,ExecF,ExecF(State));
worker_loop(N, ExecF, State) ->
worker_loop(N-1,ExecF,ExecF(State)).
diff --git a/lib/stdlib/test/io_SUITE.erl b/lib/stdlib/test/io_SUITE.erl
index 54a98985cd..bb02a879c2 100644
--- a/lib/stdlib/test/io_SUITE.erl
+++ b/lib/stdlib/test/io_SUITE.erl
@@ -27,7 +27,7 @@
otp_6282/1, otp_6354/1, otp_6495/1, otp_6517/1, otp_6502/1,
manpage/1, otp_6708/1, otp_7084/1, otp_7421/1,
io_lib_collect_line_3_wb/1, cr_whitespace_in_string/1,
- io_fread_newlines/1, otp_8989/1]).
+ io_fread_newlines/1, otp_8989/1, io_lib_fread_literal/1]).
%-define(debug, true).
@@ -62,7 +62,7 @@ all() ->
otp_6282, otp_6354, otp_6495, otp_6517, otp_6502,
manpage, otp_6708, otp_7084, otp_7421,
io_lib_collect_line_3_wb, cr_whitespace_in_string,
- io_fread_newlines, otp_8989].
+ io_fread_newlines, otp_8989, io_lib_fread_literal].
groups() ->
[].
@@ -1995,3 +1995,29 @@ otp_8989(Suite) when is_list(Suite) ->
?line "Hel " = fmt("~-4.*s", [3,Hello]),
?line "Hel " = fmt("~*.*s", [-4,3,Hello]),
ok.
+
+io_lib_fread_literal(doc) ->
+ "OTP-9439 io_lib:fread bug for literate at end";
+io_lib_fread_literal(Suite) when is_list(Suite) ->
+ ?line {more,"~d",0,""} = io_lib:fread("~d", ""),
+ ?line {error,{fread,integer}} = io_lib:fread("~d", " "),
+ ?line {more,"~d",1,""} = io_lib:fread(" ~d", " "),
+ ?line {ok,[17],"X"} = io_lib:fread(" ~d", " 17X"),
+ %%
+ ?line {more,"d",0,""} = io_lib:fread("d", ""),
+ ?line {error,{fread,input}} = io_lib:fread("d", " "),
+ ?line {more,"d",1,""} = io_lib:fread(" d", " "),
+ ?line {ok,[],"X"} = io_lib:fread(" d", " dX"),
+ %%
+ ?line {done,eof,_} = io_lib:fread([], eof, "~d"),
+ ?line {done,eof,_} = io_lib:fread([], eof, " ~d"),
+ ?line {more,C1} = io_lib:fread([], " \n", " ~d"),
+ ?line {done,{error,{fread,input}},_} = io_lib:fread(C1, eof, " ~d"),
+ ?line {done,{ok,[18]},""} = io_lib:fread(C1, "18\n", " ~d"),
+ %%
+ ?line {done,eof,_} = io_lib:fread([], eof, "d"),
+ ?line {done,eof,_} = io_lib:fread([], eof, " d"),
+ ?line {more,C2} = io_lib:fread([], " \n", " d"),
+ ?line {done,{error,{fread,input}},_} = io_lib:fread(C2, eof, " d"),
+ ?line {done,{ok,[]},[]} = io_lib:fread(C2, "d\n", " d"),
+ ok.