aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp
diff options
context:
space:
mode:
authorMicael Karlberg <[email protected]>2013-09-10 10:18:53 +0200
committerMicael Karlberg <[email protected]>2013-10-09 10:37:43 +0200
commit7558861af77de9405decc8d88b2c799e15f266da (patch)
tree05cebcea60b2e73a1f72577e7a130f93f7b9ee29 /lib/snmp
parenta49cb1b7492b4c34f5887eaa0cb7774c693a524d (diff)
downloadotp-7558861af77de9405decc8d88b2c799e15f266da.tar.gz
otp-7558861af77de9405decc8d88b2c799e15f266da.tar.bz2
otp-7558861af77de9405decc8d88b2c799e15f266da.zip
[snmp/manager] Improve handling of unexpected/invalid snmpm_user callbacks
Improved handling of unexpected return values from snmpm_user callback functions. Violations of the documented API (crashes or invalid return values) will now result in an error message. Updated doc for snmpm_user bahaviour and some other stuff. Add more (common) type defs. Update manager example. Fixed manager test(s). Fixed unused vars in (manager) test suite. Make test user follow defined behaviour.
Diffstat (limited to 'lib/snmp')
-rw-r--r--lib/snmp/doc/src/notes.xml85
-rw-r--r--lib/snmp/doc/src/snmpm_user.xml187
-rw-r--r--lib/snmp/examples/ex2/snmp_ex2_manager.erl9
-rw-r--r--lib/snmp/src/app/snmp.appup.src42
-rw-r--r--lib/snmp/src/app/snmp.erl52
-rw-r--r--lib/snmp/src/app/snmp_internal.hrl4
-rw-r--r--lib/snmp/src/manager/snmpm.erl27
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl184
-rw-r--r--lib/snmp/src/manager/snmpm_user.erl173
-rw-r--r--lib/snmp/test/snmp_manager_test.erl66
-rw-r--r--lib/snmp/test/snmp_manager_user.erl17
-rw-r--r--lib/snmp/test/snmp_test_manager.erl20
-rw-r--r--lib/snmp/vsn.mk2
13 files changed, 614 insertions, 254 deletions
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 21c417f0c1..646e3027d6 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -34,6 +34,91 @@
<section>
+ <title>SNMP Development Toolkit 4.25</title>
+ <p>Version 4.25 supports code replacement in runtime from/to
+ version 4.24.1, 4.24, 4.23.1 and 4.23. </p>
+
+ <section>
+ <title>Improvements and new features</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>[manager] Improved handling of unexpected return values from
+ <seealso marker="snmpm_user">snmpm_user</seealso>
+ callback functions. </p>
+ <p>Violations of the documented API (crashes or invalid return
+ values) will now result in an error message. </p>
+ <p>Own Id: OTP-11307</p>
+ </item>
+
+ </list>
+
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+
+<!--
+ <list type="bulleted">
+ <item>
+ <p>[agent] Reading the value of the vacmViewTreeFamilyMask returns
+ it in the wrong (internal bitlist) format. </p>
+ <p>The vacmViewTreeFamilyMask is defined as a bit string in the MIB
+ (OCTET STRING). Internally a bitlist (list of 1's and 0's,
+ see <seealso marker="snmp_agent_config_files#vacm">vacm config file</seealso>
+ for more info) is used.
+ However, the MIB implementation assumed the latter, effectively
+ rendering all attempts to read/set masks via SNMP unsuccessful. </p>
+ <p>Since the mask is used in hot paths (e.g. access permission checks
+ for each SNMP operation, the bitlist representation of the mask has
+ benefits (e.g. faster processing). Reading/writing the view mask
+ objects is less time-critical. Therefore, to fix the issue, convert
+ between the bitlist (internal) representation and bitstring
+ (external) when the vacmViewTreeFamilyMask objects are accessed. </p>
+ <p>Also, the check of the vacm config file was invalid with
+ regard to the mask value. It was assumed to be a proper oid, which
+ is not strictly the case (see bitlist above). </p>
+ <p>Own Id: OTP-11177</p>
+ <p>Stefan Zegenhagen</p>
+ </item>
+
+ <item>
+ <p>[agent] The counter increment function in the local-db was
+ incorrect. It did not handle counter wrap correctly. </p>
+ <p>Own Id: OTP-11192</p>
+ </item>
+
+ </list>
+-->
+
+ </section>
+
+ <section>
+ <title>Incompatibilities</title>
+<!--
+ <p>-</p>
+-->
+
+ <list type="bulleted">
+ <item>
+ <p>[manager] The
+ <seealso marker="snmpm_user">snmpm_user</seealso>
+ callback functions are no longer allowed to "return" via
+ exit or throw. </p>
+ <p>Own Id: OTP-11307</p>
+ </item>
+
+ </list>
+ </section>
+
+ </section> <!-- 4.25 -->
+
+
+ <section>
<title>SNMP Development Toolkit 4.24.1</title>
<p>Version 4.24.1 supports code replacement in runtime from/to
version 4.24, 4.23.1 and 4.23. </p>
diff --git a/lib/snmp/doc/src/snmpm_user.xml b/lib/snmp/doc/src/snmpm_user.xml
index 1823e0c815..cb2deab976 100644
--- a/lib/snmp/doc/src/snmpm_user.xml
+++ b/lib/snmp/doc/src/snmpm_user.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="iso-8859-1" ?>
<!DOCTYPE erlref SYSTEM "erlref.dtd">
<erlref>
<header>
<copyright>
- <year>2004</year><year>2009</year>
+ <year>2004</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
@@ -56,40 +56,59 @@
<item>
<p>handle_report/3</p>
</item>
+ <item>
+ <p>handle_invalid_result/2</p>
+ </item>
</list>
<p>The semantics of them and their exact signatures are explained
- below. </p>
- <p>Note that if an agent is registered using the old, no longer
- documented, functions (using Addr and Port), the old variant of the
- callback functions, handle_pdu, handle_trap, handle_inform and
- handle_report, will be called. </p>
+ below. </p>
+ <p>Some of the function has no defined return value (<c>void()</c>),
+ they can ofcourse return anythyng. But the functions that do have
+ specified return value(s) <em>must</em> adhere to this. None of the
+ functions can use exit of throw to return. </p>
- <marker id="handle_error"></marker>
+ <marker id="types"></marker>
</description>
+
+ <section>
+ <title>DATA TYPES</title>
+ <code type="none"><![CDATA[
+snmp_gen_info() = {ErrorStatus :: atom(),
+ ErrorIndex :: pos_integer(),
+ Varbinds :: [snmp:varbind()]}
+snmp_v1_trap_info() :: {Enteprise :: snmp:oid(),
+ Generic :: integer(),
+ Spec :: integer(),
+ Timestamp :: integer(),
+ Varbinds :: [snmp:varbind()]}
+ ]]></code>
+ <marker id="handle_error"></marker>
+ </section>
+
<funcs>
<func>
- <name>handle_error(ReqId, Reason, UserData) -> Reply</name>
+ <name>handle_error(ReqId, Reason, UserData) -> void()</name>
<fsummary>Handle error</fsummary>
<type>
<v>ReqId = integer()</v>
<v>Reason = {unexpected_pdu, SnmpInfo} | {invalid_sec_info, SecInfo, SnmpInfo} | {empty_message, Addr, Port} | term()</v>
+ <v>SnmpInfo = snmp_gen_info()</v>
+ <v>SecInfo = term()</v>
<v>Addr = ip_address()</v>
<v>Port = integer()</v>
<v>UserData = term()</v>
- <v>Reply = ignore</v>
</type>
<desc>
<p>This function is called when the manager needs to
- communicate an "asynchronous" error, to the user:
- e.g. failure to send an asynchronous message (i.e. encoding
- error), a received message was discarded due to security
- error, the manager failed to generate a response message to
- a received inform-request, or when receiving an unexpected
- PDU from an agent (could be an expired async request). </p>
- <p>If <c>ReqId</c> is less then 0, it means that this
- information was not available to the manager (that info was
- never retrieved before the message was discarded).
- </p>
+ communicate an "asynchronous" error to the user:
+ e.g. failure to send an asynchronous message (i.e. encoding
+ error), a received message was discarded due to security
+ error, the manager failed to generate a response message to
+ a received inform-request, or when receiving an unexpected
+ PDU from an agent (could be an expired async request). </p>
+ <p>If <c>ReqId</c> is less then 0, it means that this
+ information was not available to the manager (that info was
+ never retrieved before the message was discarded). </p>
<p>For <c>SnmpInfo</c> see handle_agent below.</p>
<marker id="handle_agent"></marker>
@@ -104,22 +123,22 @@
<v>Port = integer()</v>
<v>Type = pdu | trap | report | inform</v>
<v>SnmpInfo = SnmpPduInfo | SnmpTrapInfo | SnmpReportInfo | SnmpInformInfo</v>
- <v>ErrorStatus = atom()</v>
- <v>ErrorIndex = integer()</v>
- <v>Varbinds = [varbind()]</v>
- <v>varbind() = #varbind</v>
+ <v>SnmpPduInfo = snmp_gen_info()</v>
+ <v>SnmpTrapInfo = snmp_v1_trap_info()</v>
+ <v>SnmpReportInfo = snmp_gen_info()</v>
+ <v>SnmpInformInfo = snmp_gen_info()</v>
<v>UserData = term()</v>
- <v>Reply = ignore | {register, UserId, TargetName, agent_info()}</v>
+ <v>Reply = ignore | {register, UserId, TargetName, AgentConfig}</v>
<v>UserId = term()</v>
<v>TargetName = target_name()</v>
- <v>agent_info() = [{agent_info_item(), agent_info_value()}]</v>
+ <v>AgentConfig = [agent_config()]</v>
</type>
<desc>
- <p>This function is called when a message is received from an
- unknown agent.</p>
+ <p>This function is called when a message is received from an
+ unknown agent.</p>
<p>Note that this will always be the default user that is called.</p>
- <p>For more info about the <c>agent_info()</c>, see
- <seealso marker="snmpm#register_agent">register_agent</seealso>.</p>
+ <p>For more info about the <c>agent_config()</c>, see
+ <seealso marker="snmpm#register_agent">register_agent</seealso>.</p>
<p>The arguments <c>Type</c> and <c>SnmpInfo</c> relates in the
following way: </p>
@@ -148,7 +167,7 @@
</list>
<p>The only user which would return
- <c>{register, UserId, TargetName, agent_info()}</c> is the
+ <c>{register, UserId, TargetName, AgentConfig}</c> is the
<em>default user</em>.</p>
<marker id="handle_pdu"></marker>
@@ -156,18 +175,13 @@
</func>
<func>
- <name>handle_pdu(TargetName, ReqId, SnmpPduInfo, UserData) -> Reply</name>
+ <name>handle_pdu(TargetName, ReqId, SnmpPduInfo, UserData) -> void()</name>
<fsummary>Handle the reply to an asynchronous request</fsummary>
<type>
<v>TargetName = target_name()</v>
<v>ReqId = term()</v>
- <v>SnmpPduInfo = {ErrorStatus, ErrorIndex, Varbinds}</v>
- <v>ErrorStatus = atom()</v>
- <v>ErrorIndex = integer()</v>
- <v>Varbinds = [varbind()]</v>
- <v>varbind() = #varbind</v>
+ <v>SnmpPduInfo = snmp_gen_info()</v>
<v>UserData = term()</v>
- <v>Reply = ignore</v>
</type>
<desc>
<p>Handle the reply to an asynchronous request, such as
@@ -186,27 +200,19 @@
<fsummary>Handle a trap/notification message</fsummary>
<type>
<v>TargetName = TargetName2 = target_name()</v>
- <v>SnmpTrapInfo = {Enteprise, Generic, Spec, Timestamp, Varbinds} | {ErrorStatus, ErrorIndex, Varbinds}</v>
- <v>Enterprise = oid()</v>
- <v>Generic = integer()</v>
- <v>Spec = integer()</v>
- <v>Timestamp = integer()</v>
- <v>ErrorStatus = atom()</v>
- <v>ErrorIndex = integer()</v>
- <v>Varbinds = [varbind()]</v>
- <v>varbind() = #varbind</v>
+ <v>SnmpTrapInfo = snmp_v1_trap_info() | snmp_gen_info()</v>
<v>UserData = term()</v>
- <v>Reply = ignore | unregister | {register, UserId, TargetName2, agent_info()}</v>
+ <v>Reply = ignore | unregister | {register, UserId, TargetName2, AgentConfig}</v>
<v>UserId = term()</v>
- <v>agent_info() = [{agent_info_item(), agent_info_value()}]</v>
+ <v>AgentConfig = [agent_config()]</v>
</type>
<desc>
<p>Handle a trap/notification message from an agent.</p>
- <p>For more info about the <c>agent_info()</c>, see
- <seealso marker="snmpm#register_agent">register_agent</seealso></p>
+ <p>For more info about the <c>agent_config()</c>, see
+ <seealso marker="snmpm#register_agent">register_agent</seealso></p>
<p>The only user which would return
- <c>{register, UserId, TargetName2, agent_info()}</c> is the
- <em>default user</em>.</p>
+ <c>{register, UserId, TargetName2, agent_info()}</c> is the
+ <em>default user</em>.</p>
<marker id="handle_inform"></marker>
</desc>
@@ -217,29 +223,25 @@
<fsummary>Handle a inform message</fsummary>
<type>
<v>TargetName = TargetName2 = target_name()</v>
- <v>SnmpInformInfo = {ErrorStatus, ErrorIndex, Varbinds}</v>
- <v>ErrorStatus = atom()</v>
- <v>ErrorIndex = integer()</v>
- <v>Varbinds = [varbind()]</v>
- <v>varbind() = #varbind</v>
+ <v>SnmpInformInfo = snmp_gen_info()</v>
<v>UserData = term()</v>
- <v>Reply = ignore | unregister | {register, UserId, TargetName2, agent_info()}</v>
+ <v>Reply = ignore | no_reply | unregister | {register, UserId, TargetName2, AgentConfig}</v>
<v>UserId = term()</v>
- <v>agent_info() = [{agent_info_item(), agent_info_value()}]</v>
+ <v>AgentConfig = [agent_config()]</v>
</type>
<desc>
<p>Handle a inform message.</p>
- <p>For more info about the <c>agent_info()</c>, see
- <seealso marker="snmpm#register_agent">register_agent</seealso></p>
+ <p>For more info about the <c>agent_config()</c>, see
+ <seealso marker="snmpm#register_agent">register_agent</seealso></p>
<p>The only user which would return
- <c>{register, UserId, TargetName2, agent_info()}</c> is the
- <em>default user</em>.</p>
- <p>If the
- <seealso marker="snmp_app">inform request behaviour</seealso>
- configuration option is set to <c>user</c> or
- <c>{user, integer()}</c>, the response (acknowledgment) to this
- inform-request will be sent when this function returns.</p>
-
+ <c>{register, UserId, TargetName2, AgentConfig}</c> is the
+ <em>default user</em>.</p>
+ <p>If the
+ <seealso marker="snmp_app">inform request behaviour</seealso>
+ configuration option is set to <c>user</c> or
+ <c>{user, integer()}</c>, the response (acknowledgment) to this
+ inform-request will be sent when this function returns.</p>
+
<marker id="handle_report"></marker>
</desc>
</func>
@@ -251,23 +253,46 @@
<v>TargetName = TargetName2 = target_name()</v>
<v>Addr = ip_address()</v>
<v>Port = integer()</v>
- <v>SnmpReportInfo = {ErrorStatus, ErrorIndex, Varbinds}</v>
- <v>ErrorStatus = atom()</v>
- <v>ErrorIndex = integer()</v>
- <v>Varbinds = [varbind()]</v>
- <v>varbind() = #varbind</v>
+ <v>SnmpReportInfo = snmp_gen_info()</v>
<v>UserData = term()</v>
- <v>Reply = ignore | unregister | {register, UserId, TargetName2, agent_info()}</v>
+ <v>Reply = ignore | unregister | {register, UserId, TargetName2, AgentConfig}</v>
<v>UserId = term()</v>
- <v>agent_info() = [{agent_info_item(), agent_info_value()}]</v>
+ <v>AgentConfig = [agent_config()]</v>
</type>
<desc>
<p>Handle a report message.</p>
- <p>For more info about the <c>agent_info()</c>, see
- <seealso marker="snmpm#register_agent">register_agent</seealso></p>
+ <p>For more info about the <c>agent_config()</c>, see
+ <seealso marker="snmpm#register_agent">register_agent</seealso></p>
<p>The only user which would return
- <c>{register, UserId, TargetName2, agent_info()}</c> is the
- <em>default user</em>.</p>
+ <c>{register, UserId, TargetName2, AgentConfig}</c> is the
+ <em>default user</em>.</p>
+
+ <marker id="handle_invalid_result"></marker>
+ </desc>
+ </func>
+
+ <func>
+ <name>handle_invalid_result(IN, OUT) -> void()</name>
+ <fsummary>Handle a report message</fsummary>
+ <type>
+ <v>IN = {Func, Args}</v>
+ <v>Func = atom()</v>
+ <v>Args = list()</v>
+ <v>OUT = {crash, CrashInfo} | {result, InvalidResult}</v>
+ <v>CrashInfo = {ErrorType, Error, Stacktrace}</v>
+ <v>ErrorType = atom()</v>
+ <v>Error = term()</v>
+ <v>Stacktrace = list()</v>
+ <v>InvalidResult = term()</v>
+ </type>
+ <desc>
+ <p>If <em>any</em> of the <em>other</em> callback functions crashes
+ (exit, throw or a plain crash) or return an invalid result (if a valid
+ return has been specified), this function is called.
+ The purpose is to allow the user handle this
+ error (for instance to issue an error report).</p>
+ <p><c>IN</c> reprecents the function called (and its arguments).
+ <c>OUT</c> represents the unexpected/invalid result. </p>
</desc>
</func>
</funcs>
diff --git a/lib/snmp/examples/ex2/snmp_ex2_manager.erl b/lib/snmp/examples/ex2/snmp_ex2_manager.erl
index 1b247d713d..a9dcc09b77 100644
--- a/lib/snmp/examples/ex2/snmp_ex2_manager.erl
+++ b/lib/snmp/examples/ex2/snmp_ex2_manager.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2013. 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
@@ -43,7 +43,8 @@
handle_pdu/4,
handle_trap/3,
handle_inform/3,
- handle_report/3]).
+ handle_report/3,
+ handle_invalid_result/3]).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
@@ -406,5 +407,9 @@ handle_report(TargetName, SnmpReport, Server) when is_pid(Server) ->
report_callback(Server, handle_inform, {TargetName, SnmpReport}),
ok.
+handle_invalid_result(In, Out, Server) when is_pid(Server) ->
+ report_callback(Server, handle_invalid_result, {In, Out}),
+ ok.
+
report_callback(Pid, Tag, Info) ->
Pid ! {snmp_callback, Tag, Info}.
diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index 16b626111b..7bd50c2c4d 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -29,11 +29,32 @@
%% {add_module, snmpm_net_if_mt}
[
+ {"4.24.2",
+ [
+ {load_module, snmp, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmp]},
+ {load_module, snmpm_user, soft_purge, soft_purge, [snmp, snmpm]},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user]}
+ ]
+ },
+ {"4.24.1",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_agent]},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []}
+ ]
+ },
{"4.24",
[
+ {load_module, snmp, soft_purge, soft_purge, []},
{load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmp]},
+ {load_module, snmpm_user, soft_purge, soft_purge, [snmp, snmpm]},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
{load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
[snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user]},
{update, snmpa_local_db, soft, soft_purge, soft_purge, []}
]
},
@@ -47,11 +68,32 @@
%% {remove, {snmpm_net_if_mt, soft_purge, soft_purge}}
[
+ {"4.24.2",
+ [
+ {load_module, snmp, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmp]},
+ {load_module, snmpm_user, soft_purge, soft_purge, [snmp, snmpm]},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user]}
+ ]
+ },
+ {"4.24.1",
+ [
+ {load_module, snmpa, soft_purge, soft_purge, [snmpa_agent]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_agent]},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []}
+ ]
+ },
{"4.24",
[
+ {load_module, snmp, soft_purge, soft_purge, []},
{load_module, snmp_conf, soft_purge, soft_purge, []},
+ {load_module, snmpm, soft_purge, soft_purge, [snmp]},
+ {load_module, snmpm_user, soft_purge, soft_purge, [snmp, snmpm]},
+ {load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
{load_module, snmp_view_based_acm_mib, soft_purge, soft_purge,
[snmp_conf]},
+ {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_user]},
{update, snmpa_local_db, soft, soft_purge, soft_purge, []}
]
},
diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl
index 1bb562654a..a37979f5eb 100644
--- a/lib/snmp/src/app/snmp.erl
+++ b/lib/snmp/src/app/snmp.erl
@@ -91,8 +91,30 @@
]).
-export_type([
+ snmp_timer/0,
+
+ engine_id/0,
+ tdomain/0,
+ community/0,
+ mms/0,
+ version/0,
+ sec_model/0,
+ sec_name/0,
+ sec_level/0,
+
oid/0,
-
+ varbind/0,
+ ivarbind/0,
+ asn1_type/0,
+ table_info/0,
+ variable_info/0,
+ me/0,
+ trap/0,
+ notification/0,
+ pdu/0,
+ trappdu/0,
+ mib/0,
+
void/0
]).
@@ -149,14 +171,38 @@
-define(APPLICATION, snmp).
+-include_lib("snmp/include/snmp_types.hrl").
%%-----------------------------------------------------------------
%% Types
%%-----------------------------------------------------------------
--type oid() :: [non_neg_integer()].
--type void() :: term().
+-type snmp_timer() :: #snmp_incr_timer{}.
+
+-type engine_id() :: string().
+-type tdomain() :: transportDomainUdpIpv4 | transportDomainUdpIpv6.
+-type community() :: string().
+-type mms() :: non_neg_integer().
+-type version() :: v1 | v2 | v3.
+-type sec_model() :: any | v1 | v2c | usm.
+-type sec_name() :: string().
+-type sec_level() :: noAuthNoPriv | authNoPriv | authPriv.
+
+-type oid() :: [non_neg_integer()].
+-type varbind() :: #varbind{}.
+-type ivarbind() :: #ivarbind{}.
+-type asn1_type() :: #asn1_type{}.
+-type table_info() :: #table_info{}.
+-type variable_info() :: #variable_info{}.
+-type me() :: #me{}.
+-type trap() :: #trap{}.
+-type notification() :: #notification{}.
+-type mib() :: #mib{}.
+-type pdu() :: #pdu{}.
+-type trappdu() :: #trappdu{}.
+
+-type void() :: term().
%%-----------------------------------------------------------------
diff --git a/lib/snmp/src/app/snmp_internal.hrl b/lib/snmp/src/app/snmp_internal.hrl
index 5ff715e0b7..f04fa4dd53 100644
--- a/lib/snmp/src/app/snmp_internal.hrl
+++ b/lib/snmp/src/app/snmp_internal.hrl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2006-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2006-2013. 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
@@ -24,6 +24,8 @@
-define(APPLICATION, snmp).
-endif.
+-define(STACK(), erlang:get_stacktrace()).
+
-define(snmp_info(C, F, A), ?snmp_msg(info_msg, C, F, A)).
-define(snmp_warning(C, F, A), ?snmp_msg(warning_msg, C, F, A)).
-define(snmp_error(C, F, A), ?snmp_msg(error_msg, C, F, A)).
diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl
index 6ac0115dad..8bfca76a1c 100644
--- a/lib/snmp/src/manager/snmpm.erl
+++ b/lib/snmp/src/manager/snmpm.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2013. 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
@@ -111,6 +111,12 @@
-export([start_link/3, snmpm_start_verify/2, snmpm_start_verify/3]).
-export([target_name/1, target_name/2]).
+-export_type([
+ register_timeout/0,
+ agent_config/0,
+ target_name/0
+ ]).
+
-include_lib("snmp/src/misc/snmp_debug.hrl").
-include_lib("snmp/include/snmp_types.hrl").
@@ -121,6 +127,25 @@
-define(DEFAULT_AGENT_PORT, 161).
+%%-----------------------------------------------------------------
+%% Types
+%%-----------------------------------------------------------------
+
+-type register_timeout() :: pos_integer() | snmp:snmp_timer().
+-type agent_config() :: {engine_id, snmp:engine_id()} | % Mandatory
+ {address, inet:ip_address()} | % Mandatory
+ {port, inet:port_number()} | % Optional
+ {tdomain, snmp:tdomain()} | % Optional
+ {community, snmp:community()} | % Optional
+ {timeout, register_timeout()} | % Optional
+ {max_message_size, snmp:mms()} | % Optional
+ {version, snmp:version()} | % Optional
+ {sec_moduel, snmp:sec_model()} | % Optional
+ {sec_name, snmp:sec_name()} | % Optional
+ {sec_level, snmp:sec_level()}. % Optional
+-type target_name() :: string().
+
+
%% This function is called when the snmp application
%% starts.
start_link(Opts, normal, []) ->
diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 61d22362cc..9c79df2748 100644
--- a/lib/snmp/src/manager/snmpm_server.erl
+++ b/lib/snmp/src/manager/snmpm_server.erl
@@ -488,7 +488,7 @@ cancel_async_request(UserId, ReqId) ->
%% discovery(UserId, BAddr, Port, Config, Expire, ExtraInfo) ->
%% call({discovery, self(), UserId, BAddr, Port, Config, Expire, ExtraInfo}).
-
+
verbosity(Verbosity) ->
case ?vvalidate(Verbosity) of
Verbosity ->
@@ -1851,7 +1851,17 @@ handle_snmp_error(Addr, Port, ReqId, Reason, State) ->
handle_error(_UserId, Mod, Reason, ReqId, Data, _State) ->
?vtrace("handle_error -> entry when"
"~n Mod: ~p", [Mod]),
- F = fun() -> (catch Mod:handle_error(ReqId, Reason, Data)) end,
+ F = fun() ->
+ try
+ begin
+ Mod:handle_error(ReqId, Reason, Data)
+ end
+ catch
+ T:E ->
+ CallbackArgs = [ReqId, Reason, Data],
+ handle_invalid_result(handle_error, CallbackArgs, T, E)
+ end
+ end,
handle_callback(F),
ok.
@@ -2031,7 +2041,15 @@ handle_pdu(_UserId, Mod, target_name = _RegType, TargetName, _Addr, _Port,
?vtrace("handle_pdu(target_name) -> entry when"
"~n Mod: ~p", [Mod]),
F = fun() ->
- (catch Mod:handle_pdu(TargetName, ReqId, SnmpResponse, Data))
+ try
+ begin
+ Mod:handle_pdu(TargetName, ReqId, SnmpResponse, Data)
+ end
+ catch
+ T:E ->
+ CallbackArgs = [TargetName, ReqId, SnmpResponse, Data],
+ handle_invalid_result(handle_pdu, CallbackArgs, T, E)
+ end
end,
handle_callback(F),
ok;
@@ -2064,8 +2082,37 @@ do_handle_agent(DefUserId, DefMod,
SnmpInfo, DefData, State) ->
?vdebug("do_handle_agent -> entry when"
"~n DefUserId: ~p", [DefUserId]),
- case (catch DefMod:handle_agent(Addr, Port, Type, SnmpInfo, DefData)) of
- {'EXIT', {undef, _}} when Type =:= pdu ->
+ try DefMod:handle_agent(Addr, Port, Type, SnmpInfo, DefData) of
+ {register, UserId2, TargetName, Config} ->
+ ?vtrace("do_handle_agent -> register: "
+ "~n UserId2: ~p"
+ "~n TargetName: ~p"
+ "~n Config: ~p",
+ [UserId2, TargetName, Config]),
+ Config2 = ensure_present([{address, Addr}, {port, Port}], Config),
+ Config3 = [{reg_type, target_name} | Config2],
+ case snmpm_config:register_agent(UserId2,
+ TargetName, Config3) of
+ ok ->
+ ok;
+ {error, Reason} ->
+ error_msg("failed registering agent - "
+ "handling agent "
+ "~p <~p,~p>: ~n~w",
+ [TargetName, Addr, Port, Reason]),
+ ok
+ end;
+
+ ignore ->
+ ?vdebug("do_handle_agent -> ignore", []),
+ ok;
+
+ InvalidResult ->
+ CallbackArgs = [Addr, Port, Type, SnmpInfo, DefData],
+ handle_invalid_result(handle_agent, CallbackArgs, InvalidResult)
+
+ catch
+ error:{undef, _} when Type =:= pdu ->
%% Maybe, still on the old API
?vdebug("do_handle_agent -> maybe still on the old api", []),
case (catch DefMod:handle_agent(Addr, Port, SnmpInfo, DefData)) of
@@ -2113,10 +2160,10 @@ do_handle_agent(DefUserId, DefMod,
ok
end;
- {'EXIT', {undef, _}} ->
+ error:{undef, _} ->
%% If the user does not implement the new API (but the
%% old), then this clause catches all non-pdu handle_agent
- %% calls. These calls was previously never made,so we make
+ %% calls. These calls was previously never made, so we make
%% a best-effert call (using reg-type target_name) to the
%% various callback functions, and leave it to the user to
%% figure out
@@ -2148,31 +2195,11 @@ do_handle_agent(DefUserId, DefMod,
"regarding agent "
"<~p,~p>: ~n~w", [Type, Addr, Port, SnmpInfo])
end;
-
- {register, UserId2, TargetName, Config} ->
- ?vtrace("do_handle_agent -> register: "
- "~n UserId2: ~p"
- "~n TargetName: ~p"
- "~n Config: ~p",
- [UserId2, TargetName, Config]),
- Config2 = ensure_present([{address, Addr}, {port, Port}], Config),
- Config3 = [{reg_type, target_name} | Config2],
- case snmpm_config:register_agent(UserId2,
- TargetName, Config3) of
- ok ->
- ok;
- {error, Reason} ->
- error_msg("failed registering agent - "
- "handling agent "
- "~p <~p,~p>: ~n~w",
- [TargetName, Addr, Port, Reason]),
- ok
- end;
- _Ignore ->
- ?vdebug("do_handle_agent -> ignore", []),
- ok
-
+ T:E ->
+ CallbackArgs = [Addr, Port, Type, SnmpInfo, DefData],
+ handle_invalid_result(handle_agent, CallbackArgs, T, E)
+
end.
ensure_present([], Config) ->
@@ -2305,15 +2332,17 @@ do_handle_trap(UserId, Mod,
RegType, Target, Addr, Port, SnmpTrapInfo, Data, _State) ->
?vdebug("do_handle_trap -> entry with"
"~n UserId: ~p", [UserId]),
- HandleTrap =
+ {HandleTrap, CallbackArgs} =
case RegType of
target_name ->
- fun() -> Mod:handle_trap(Target, SnmpTrapInfo, Data) end;
+ {fun() -> Mod:handle_trap(Target, SnmpTrapInfo, Data) end,
+ [Target, SnmpTrapInfo, Data]};
addr_port ->
- fun() -> Mod:handle_trap(Addr, Port, SnmpTrapInfo, Data) end
+ {fun() -> Mod:handle_trap(Addr, Port, SnmpTrapInfo, Data) end,
+ [Addr, Port, SnmpTrapInfo, Data]}
end,
- case (catch HandleTrap()) of
+ try HandleTrap() of
{register, UserId2, Config} ->
?vtrace("do_handle_trap -> register: "
"~n UserId2: ~p"
@@ -2362,9 +2391,17 @@ do_handle_trap(UserId, Mod,
[Addr, Port, Reason]),
ok
end;
- _Ignore ->
+ ignore ->
?vtrace("do_handle_trap -> ignore", []),
- ok
+ ok;
+
+ InvalidResult ->
+ handle_invalid_result(handle_trap, CallbackArgs, InvalidResult)
+
+ catch
+ T:E ->
+ handle_invalid_result(handle_trap, CallbackArgs, T, E)
+
end.
@@ -2465,16 +2502,18 @@ do_handle_inform(UserId, Mod, Ref,
RegType, Target, Addr, Port, SnmpInform, Data, State) ->
?vdebug("do_handle_inform -> entry with"
"~n UserId: ~p", [UserId]),
- HandleInform =
+ {HandleInform, CallbackArgs} =
case RegType of
target_name ->
- fun() -> Mod:handle_inform(Target, SnmpInform, Data) end;
+ {fun() -> Mod:handle_inform(Target, SnmpInform, Data) end,
+ [Target, SnmpInform, Data]};
addr_port ->
- fun() -> Mod:handle_inform(Addr, Port, SnmpInform, Data) end
+ {fun() -> Mod:handle_inform(Addr, Port, SnmpInform, Data) end,
+ [Addr, Port, SnmpInform, Data]}
end,
Rep =
- case (catch HandleInform()) of
+ try HandleInform() of
{register, UserId2, Config} ->
?vtrace("do_handle_inform -> register: "
"~n UserId2: ~p"
@@ -2494,6 +2533,7 @@ do_handle_inform(UserId, Mod, Ref,
[Target2, Addr, Port, Reason]),
reply
end;
+
{register, UserId2, Target2, Config} ->
?vtrace("do_handle_inform -> register: "
"~n UserId2: ~p"
@@ -2512,6 +2552,7 @@ do_handle_inform(UserId, Mod, Ref,
[Target2, Addr, Port, Reason]),
reply
end;
+
unregister ->
?vtrace("do_handle_inform -> unregister", []),
case snmpm_config:unregister_agent(UserId,
@@ -2525,12 +2566,25 @@ do_handle_inform(UserId, Mod, Ref,
[Addr, Port, Reason]),
reply
end;
+
no_reply ->
?vtrace("do_handle_inform -> no_reply", []),
no_reply;
- _Ignore ->
+
+ ignore ->
?vtrace("do_handle_inform -> ignore", []),
+ reply;
+
+ InvalidResult ->
+ handle_invalid_result(handle_inform, CallbackArgs,
+ InvalidResult),
reply
+
+ catch
+ T:E ->
+ handle_invalid_result(handle_inform, CallbackArgs, T, E),
+ reply
+
end,
handle_inform_response(Rep, Ref, Addr, Port, State),
ok.
@@ -2760,15 +2814,17 @@ do_handle_report(UserId, Mod,
RegType, Target, Addr, Port, SnmpReport, Data, _State) ->
?vdebug("do_handle_report -> entry with"
"~n UserId: ~p", [UserId]),
- HandleReport =
+ {HandleReport, CallbackArgs} =
case RegType of
target_name ->
- fun() -> Mod:handle_report(Target, SnmpReport, Data) end;
+ {fun() -> Mod:handle_report(Target, SnmpReport, Data) end,
+ [Target, SnmpReport, Data]};
addr_port ->
- fun() -> Mod:handle_report(Addr, Port, SnmpReport, Data) end
+ {fun() -> Mod:handle_report(Addr, Port, SnmpReport, Data) end,
+ [Addr, Port, SnmpReport, Data]}
end,
- case (catch HandleReport()) of
+ try HandleReport() of
{register, UserId2, Config} ->
?vtrace("do_handle_report -> register: "
"~n UserId2: ~p"
@@ -2788,6 +2844,7 @@ do_handle_report(UserId, Mod,
[Addr, Port, Reason]),
ok
end;
+
{register, UserId2, Target2, Config} ->
?vtrace("do_handle_report -> register: "
"~n UserId2: ~p"
@@ -2806,6 +2863,7 @@ do_handle_report(UserId, Mod,
[Target2, Addr, Port, Reason]),
reply
end;
+
unregister ->
?vtrace("do_handle_trap -> unregister", []),
case snmpm_config:unregister_agent(UserId,
@@ -2819,9 +2877,20 @@ do_handle_report(UserId, Mod,
[Addr, Port, Reason]),
ok
end;
- _Ignore ->
+
+ ignore ->
?vtrace("do_handle_report -> ignore", []),
- ok
+ ok;
+
+ InvalidResult ->
+ handle_invalid_result(handle_report, CallbackArgs, InvalidResult),
+ reply
+
+ catch
+ T:E ->
+ handle_invalid_result(handle_report, CallbackArgs, T, E),
+ reply
+
end.
@@ -2835,6 +2904,25 @@ handle_callback(F) ->
end).
+
+handle_invalid_result(Func, Args, T, E) ->
+ Stacktrace = ?STACK(),
+ error_msg("Callback function failed: "
+ "~n Function: ~p"
+ "~n Args: ~p"
+ "~n Error Type: ~p"
+ "~n Error: ~p"
+ "~n Stacktrace: ~p",
+ [Func, Args, T, E, Stacktrace]).
+
+handle_invalid_result(Func, Args, InvalidResult) ->
+ error_msg("Callback function returned invalid result: "
+ "~n Function: ~p"
+ "~n Args: ~p"
+ "~n Invalid result: ~p",
+ [Func, Args, InvalidResult]).
+
+
handle_down(MonRef) ->
(catch do_handle_down(MonRef)).
diff --git a/lib/snmp/src/manager/snmpm_user.erl b/lib/snmp/src/manager/snmpm_user.erl
index 78aa560b2e..e6b0b6943e 100644
--- a/lib/snmp/src/manager/snmpm_user.erl
+++ b/lib/snmp/src/manager/snmpm_user.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2004-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2004-2013. 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
@@ -19,79 +19,100 @@
-module(snmpm_user).
--export([behaviour_info/1]).
-
-behaviour_info(callbacks) ->
- [{handle_error, 3},
- {handle_agent, 5},
- {handle_pdu, 4},
- {handle_trap, 3},
- {handle_inform, 3},
- {handle_report, 3}];
-behaviour_info(_) ->
- undefined.
-
-
-%% handle_error(ReqId, Reason, UserData) -> Reply
-%% ReqId -> integer()
-%% Reason -> term()
-%% UserData -> term() (supplied when the user register)
-%% Reply -> ignore
-
-%% handle_agent(Addr, Port, Type, SnmpInfo, UserData) -> Reply
-%% Addr -> term()
-%% Port -> integer()
-%% Type -> pdu | trap | inform | report
-%% SnmpInfo -> {ErrorStatus, ErrorIndex, Varbinds}
-%% UserId -> term()
-%% ErrorStatus -> atom()
-%% ErrorIndex -> integer()
-%% Varbinds -> [varbind()]
-%% UserData -> term() (supplied when the user register)
-%% Reply -> ignore | {register, UserId, agent_info()}
-%% agent_info() -> [{agent_info_item(), agent_info_value()}]
-%% This is the same info as in update_agent_info/4
-
-%% handle_pdu(TargetName, ReqId, SnmpResponse, UserData) -> Reply
-%% TargetName -> target_name()
-%% ReqId -> term() (returned when calling ag(...), ...)
-%% SnmpResponse -> {ErrorStatus, ErrorIndex, Varbinds}
-%% ErrorStatus -> atom()
-%% ErrorIndex -> integer()
-%% Varbinds -> [varbind()]
-%% UserData -> term() (supplied when the user register)
-%% Reply -> ignore
-
-%% handle_trap(TargetName, SnmpTrapInfo, UserData) -> Reply
-%% TargetName -> target_name()
-%% SnmpTrapInfo -> {Enteprise, Generic, Spec, Timestamp, Varbinds} |
-%% {ErrorStatus, ErrorIndex, Varbinds}
-%% Enteprise -> oid()
-%% Generic -> integer()
-%% Spec -> integer()
-%% Timestamp -> integer()
-%% ErrorStatus -> atom()
-%% ErrorIndex -> integer()
-%% Varbinds -> [varbind()]
-%% UserData -> term() (supplied when the user register)
-%% Reply -> ignore | unregister | {register, UserId, agent_info()}
-
-%% handle_inform(TargetName, SnmpInform, UserData) -> Reply
-%% TargetName -> target_name()
-%% SnmpInform -> {ErrorStatus, ErrorIndex, Varbinds}
-%% ErrorStatus -> atom()
-%% ErrorIndex -> integer()
-%% Varbinds -> [varbind()]
-%% UserData -> term() (supplied when the user register)
-%% Reply -> ignore | unregister | {register, UserId, agent_info()}
-%%
-
-%% handle_report(TargetName, SnmpReport, UserData) -> Reply
-%% TargetName -> target_name()
-%% SnmpReport -> {ErrorStatus, ErrorIndex, Varbinds}
-%% ErrorStatus -> integer()
-%% ErrorIndex -> integer()
-%% Varbinds -> [varbind()]
-%% UserData -> term() (supplied when the user register)
-%% Reply -> ignore | unregister | {register, UserId, agent_info()}
+-export_type([
+ snmp_gen_info/0,
+ snmp_v1_trap_info/0
+ ]).
+
+-type snmp_gen_info() :: {ErrorStatus :: atom(),
+ ErrorIndex :: pos_integer(),
+ Varbinds :: [snmp:varbind()]}.
+-type snmp_v1_trap_info() :: {Enteprise :: snmp:oid(),
+ Generic :: integer(),
+ Spec :: integer(),
+ Timestamp :: integer(),
+ Varbinds :: [snmp:varbind()]}.
+-type ip_address() :: inet:ip_address().
+-type port_number() :: inet:port_number().
+
+
+%% *** handle_error ***
+%% An "asynchronous" error has been detected
+
+-callback handle_error(ReqId :: integer(),
+ Reason :: {unexpected_pdu, SnmpInfo :: snmp_gen_info()} |
+ {invalid_sec_info, SecInfo :: term(), SnmpInfo :: snmp_gen_info()} |
+ {empty_message, Addr :: ip_address(), Port :: port_number()} |
+ term(),
+ UserData :: term()) ->
+ snmp:void().
+
+
+%% *** handle_agent ***
+%% A message was received from an unknown agent
+
+-callback handle_agent(Addr :: term(),
+ Port :: pos_integer(),
+ Type :: pdu | trap | inform | report,
+ SnmpInfo :: snmp_gen_info() | snmp_v1_trap_info(),
+ UserData :: term()) ->
+ Reply :: ignore |
+ {register,
+ UserId :: term(),
+ RTargetName :: snmpm:target_name(),
+ AgentConfig :: [snmpm:agent_config()]}.
+
+
+%% *** handle_pdu ***
+%% Handle the reply to an async request (such as get, get-next and set).
+
+-callback handle_pdu(TargetName :: snmpm:target_name(),
+ ReqId :: term(),
+ SnmpResponse :: snmp_gen_info(),
+ UserData :: term()) ->
+ snmp:void().
+
+
+%% *** handle_trap ***
+%% Handle a trap/notification message received from an agent
+
+-callback handle_trap(TargetName :: snmpm:target_name(),
+ SnmpTrapInfo :: snmp_gen_info() | snmp_v1_trap_info(),
+ UserData :: term()) ->
+ Reply :: ignore |
+ unregister |
+ {register,
+ UserId :: term(),
+ RTargetName :: snmpm:target_name(),
+ AgentConfig :: [snmpm:agent_config()]}.
+
+
+%% *** handle_inform ***
+%% Handle a inform message received from an agent
+
+-callback handle_inform(TargetName :: snmpm:target_name(),
+ SnmpInform :: snmp_gen_info(),
+ UserData :: term()) ->
+ Reply :: ignore | no_reply |
+ unregister |
+ {register,
+ UserId :: term(),
+ RTargetName :: snmpm:target_name(),
+ AgentConfig :: [snmpm:agent_config()]}.
+
+
+%% *** handle_report ***
+%% Handle a report message received from an agent
+
+-callback handle_report(TargetName :: snmpm:target_name(),
+ SnmpReport :: snmp_gen_info(),
+ UserData :: term()) ->
+ Reply :: ignore |
+ unregister |
+ {register,
+ UserId :: term(),
+ RTargetName :: snmpm:target_name(),
+ AgentConfig :: [snmpm:agent_config()]}.
+
+
diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl
index dedbae5ce4..5fe18980bc 100644
--- a/lib/snmp/test/snmp_manager_test.erl
+++ b/lib/snmp/test/snmp_manager_test.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2003-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2003-2013. 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
@@ -1615,10 +1615,10 @@ simple_sync_get1(Config) when is_list(Config) ->
ok.
do_simple_sync_get(Node, Addr, Port, Oids) ->
- ?line {ok, Reply, Rem} = mgr_user_sync_get(Node, Addr, Port, Oids),
+ ?line {ok, Reply, _Rem} = mgr_user_sync_get(Node, Addr, Port, Oids),
?DBG("~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
%% verify that the operation actually worked:
%% The order should be the same, so no need to seach
@@ -1682,10 +1682,10 @@ do_simple_sync_get2(Config, Get, PostVerify) ->
do_simple_sync_get2(Node, TargetName, Oids, Get, PostVerify)
when is_function(Get, 3) andalso is_function(PostVerify, 0) ->
- ?line {ok, Reply, Rem} = Get(Node, TargetName, Oids),
+ ?line {ok, Reply, _Rem} = Get(Node, TargetName, Oids),
?DBG("~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
%% verify that the operation actually worked:
%% The order should be the same, so no need to seach
@@ -2061,10 +2061,10 @@ simple_sync_get_next1(Config) when is_list(Config) ->
do_simple_get_next(N, Node, Addr, Port, Oids, Verify) ->
p("issue get-next command ~w", [N]),
case mgr_user_sync_get_next(Node, Addr, Port, Oids) of
- {ok, Reply, Rem} ->
+ {ok, Reply, _Rem} ->
?DBG("get-next ok:"
"~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
Verify(Reply);
Error ->
@@ -2217,10 +2217,10 @@ do_simple_sync_get_next2(Config, GetNext, PostVerify)
do_simple_get_next(N, Node, TargetName, Oids, Verify, GetNext, PostVerify) ->
p("issue get-next command ~w", [N]),
case GetNext(Node, TargetName, Oids) of
- {ok, Reply, Rem} ->
+ {ok, Reply, _Rem} ->
?DBG("get-next ok:"
"~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
PostVerify(Verify(Reply));
Error ->
@@ -2551,10 +2551,10 @@ simple_sync_set1(Config) when is_list(Config) ->
do_simple_set1(Node, Addr, Port, VAVs) ->
[SysName, SysLoc] = value_of_vavs(VAVs),
- ?line {ok, Reply, Rem} = mgr_user_sync_set(Node, Addr, Port, VAVs),
+ ?line {ok, Reply, _Rem} = mgr_user_sync_set(Node, Addr, Port, VAVs),
?DBG("~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
%% verify that the operation actually worked:
%% The order should be the same, so no need to seach
@@ -2631,10 +2631,10 @@ do_simple_sync_set2(Config, Set, PostVerify)
do_simple_set2(Node, TargetName, VAVs, Set, PostVerify) ->
[SysName, SysLoc] = value_of_vavs(VAVs),
- ?line {ok, Reply, Rem} = Set(Node, TargetName, VAVs),
+ ?line {ok, Reply, _Rem} = Set(Node, TargetName, VAVs),
?DBG("~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
%% verify that the operation actually worked:
%% The order should be the same, so no need to seach
@@ -3026,10 +3026,10 @@ fl(L) ->
do_simple_get_bulk1(N, Node, Addr, Port, NonRep, MaxRep, Oids, Verify) ->
p("issue get-bulk command ~w", [N]),
case mgr_user_sync_get_bulk(Node, Addr, Port, NonRep, MaxRep, Oids) of
- {ok, Reply, Rem} ->
+ {ok, Reply, _Rem} ->
?DBG("get-bulk ok:"
"~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
Verify(Reply);
Error ->
@@ -3213,10 +3213,10 @@ do_simple_get_bulk2(N,
is_function(PostVerify) ->
p("issue get-bulk command ~w", [N]),
case GetBulk(NonRep, MaxRep, Oids) of
- {ok, Reply, Rem} ->
+ {ok, Reply, _Rem} ->
?DBG("get-bulk ok:"
"~n Reply: ~p"
- "~n Rem: ~w", [Reply, Rem]),
+ "~n Rem: ~w", [Reply, _Rem]),
PostVerify(Verify(Reply));
Error ->
@@ -5609,11 +5609,11 @@ init_mgr_user_data1(Conf) ->
[{address, Addr},
{port, Port},
{engine_id, "agentEngine"}]),
- Agents = mgr_user_which_own_agents(Node),
- ?DBG("Own agents: ~p", [Agents]),
+ _Agents = mgr_user_which_own_agents(Node),
+ ?DBG("Own agents: ~p", [_Agents]),
- ?line {ok, DefAgentConf} = mgr_user_agent_info(Node, TargetName, all),
- ?DBG("Default agent config: ~n~p", [DefAgentConf]),
+ ?line {ok, _DefAgentConf} = mgr_user_agent_info(Node, TargetName, all),
+ ?DBG("Default agent config: ~n~p", [_DefAgentConf]),
?line ok = mgr_user_update_agent_info(Node, TargetName,
community, "all-rights"),
@@ -5624,8 +5624,8 @@ init_mgr_user_data1(Conf) ->
?line ok = mgr_user_update_agent_info(Node, TargetName,
max_message_size, 1024),
- ?line {ok, AgentConf} = mgr_user_agent_info(Node, TargetName, all),
- ?DBG("Updated agent config: ~n~p", [AgentConf]),
+ ?line {ok, _AgentConf} = mgr_user_agent_info(Node, TargetName, all),
+ ?DBG("Updated agent config: ~n~p", [_AgentConf]),
Conf.
init_mgr_user_data2(Conf) ->
@@ -5639,11 +5639,11 @@ init_mgr_user_data2(Conf) ->
[{address, Addr},
{port, Port},
{engine_id, "agentEngine"}]),
- Agents = mgr_user_which_own_agents(Node),
- ?DBG("Own agents: ~p", [Agents]),
+ _Agents = mgr_user_which_own_agents(Node),
+ ?DBG("Own agents: ~p", [_Agents]),
- ?line {ok, DefAgentConf} = mgr_user_agent_info(Node, TargetName, all),
- ?DBG("Default agent config: ~n~p", [DefAgentConf]),
+ ?line {ok, _DefAgentConf} = mgr_user_agent_info(Node, TargetName, all),
+ ?DBG("Default agent config: ~n~p", [_DefAgentConf]),
?line ok = mgr_user_update_agent_info(Node, TargetName,
community, "all-rights"),
@@ -5652,8 +5652,8 @@ init_mgr_user_data2(Conf) ->
?line ok = mgr_user_update_agent_info(Node, TargetName,
max_message_size, 1024),
- ?line {ok, AgentConf} = mgr_user_agent_info(Node, TargetName, all),
- ?DBG("Updated agent config: ~n~p", [AgentConf]),
+ ?line {ok, _AgentConf} = mgr_user_agent_info(Node, TargetName, all),
+ ?DBG("Updated agent config: ~n~p", [_AgentConf]),
Conf.
fin_mgr_user_data1(Conf) ->
@@ -5853,12 +5853,12 @@ mgr_user_name_to_oid(Node, Name) ->
start_manager(Node, Vsns, Config) ->
start_manager(Node, Vsns, Config, []).
-start_manager(Node, Vsns, Conf0, Opts) ->
+start_manager(Node, Vsns, Conf0, _Opts) ->
?DBG("start_manager -> entry with"
"~n Node: ~p"
"~n Vsns: ~p"
"~n Conf0: ~p"
- "~n Opts: ~p", [Node, Vsns, Conf0, Opts]),
+ "~n Opts: ~p", [Node, Vsns, Conf0, _Opts]),
AtlDir = ?config(manager_log_dir, Conf0),
ConfDir = ?config(manager_conf_dir, Conf0),
@@ -5908,12 +5908,12 @@ stop_manager(Node, Conf) ->
start_agent(Node, Vsns, Config) ->
start_agent(Node, Vsns, Config, []).
-start_agent(Node, Vsns, Conf0, Opts) ->
+start_agent(Node, Vsns, Conf0, _Opts) ->
?DBG("start_agent -> entry with"
"~n Node: ~p"
"~n Vsns: ~p"
"~n Conf0: ~p"
- "~n Opts: ~p", [Node, Vsns, Conf0, Opts]),
+ "~n Opts: ~p", [Node, Vsns, Conf0, _Opts]),
AtlDir = ?config(agent_log_dir, Conf0),
ConfDir = ?config(agent_conf_dir, Conf0),
diff --git a/lib/snmp/test/snmp_manager_user.erl b/lib/snmp/test/snmp_manager_user.erl
index 4e789bbaec..ddbe156130 100644
--- a/lib/snmp/test/snmp_manager_user.erl
+++ b/lib/snmp/test/snmp_manager_user.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2012. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2013. 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
@@ -681,6 +681,15 @@ loop(#state{parent = Parent, id = Id} = S) ->
Parent ! {async_event, TargetName, {report, SnmpReport}},
loop(S);
+ {handle_invalid_result, _Pid, In, Out} ->
+ d("loop -> received invalid result callback from manager for "
+ "~n In: ~p",
+ "~n Out: ~p", [In, Out]),
+ info("received invalid result message: "
+ "~n In: ~p"
+ "~n Out: ~p", [In, Out]),
+ loop(S);
+
{'EXIT', Parent, Reason} ->
d("received exit signal from parent: ~n~p", [Reason]),
info("received exit signal from parent: ~n~p", [Reason]),
@@ -770,7 +779,7 @@ handle_pdu(TargetName, ReqId, SnmpResponse, UserPid) ->
handle_trap(TargetName, SnmpTrap, UserPid) ->
UserPid ! {handle_trap, self(), TargetName, SnmpTrap},
- ok.
+ ignore.
handle_inform(TargetName, SnmpInform, UserPid) ->
UserPid ! {handle_inform, self(), TargetName, SnmpInform},
@@ -778,12 +787,12 @@ handle_inform(TargetName, SnmpInform, UserPid) ->
{handle_inform_no_response, TargetName} ->
no_reply;
{handle_inform_response, TargetName} ->
- ok
+ ignore
end.
handle_report(TargetName, SnmpReport, UserPid) ->
UserPid ! {handle_report, self(), TargetName, SnmpReport},
- ok.
+ ignore.
%%----------------------------------------------------------------------
diff --git a/lib/snmp/test/snmp_test_manager.erl b/lib/snmp/test/snmp_test_manager.erl
index 1f3383a7a8..925ae77ab5 100644
--- a/lib/snmp/test/snmp_test_manager.erl
+++ b/lib/snmp/test/snmp_test_manager.erl
@@ -47,7 +47,8 @@
handle_pdu/4,
handle_trap/3,
handle_inform/3,
- handle_report/3
+ handle_report/3,
+ handle_invalid_result/3
]).
@@ -279,12 +280,18 @@ handle_info({snmp_inform, TargetName, Info, Pid},
handle_info({snmp_report, TargetName, Info, Pid},
#state{parent = P} = State) ->
info_msg("received snmp report: "
- "~n TargetName: ~p"
- "~n Info: ~p", [TargetName, Info]),
+ "~n TargetName: ~p"
+ "~n Info: ~p", [TargetName, Info]),
Pid ! {snmp_report_reply, ignore, self()},
P ! {snmp_report, TargetName, Info},
{noreply, State};
+handle_info({snmp_invalid_result, In, Out}, State) ->
+ error_msg("Callback failure: "
+ "~n In: ~p"
+ "~n Out: ~p", [In, Out]),
+ {noreply, State};
+
handle_info(Info, State) ->
error_msg("received unknown info: "
"~n Info: ~p", [Info]),
@@ -369,7 +376,12 @@ handle_report(TargetName, SnmpInfo, Pid) ->
after 10000 ->
ignore
end.
-
+
+
+handle_invalid_result(In, Out, Pid) ->
+ Pid ! {snmp_invalid_result, In, Out},
+ ignore.
+
%%----------------------------------------------------------------------
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index e987649e11..70f7c2b19a 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -18,6 +18,6 @@
# %CopyrightEnd%
APPLICATION = snmp
-SNMP_VSN = 4.24.1
+SNMP_VSN = 4.25
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)"