diff options
Diffstat (limited to 'lib/snmp')
62 files changed, 2603 insertions, 1913 deletions
diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile index 3ebee792f9..e7ab491eef 100644 --- a/lib/snmp/doc/src/Makefile +++ b/lib/snmp/doc/src/Makefile @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2017. All Rights Reserved. +# Copyright Ericsson AB 1997-2018. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -140,6 +140,7 @@ clean_man: clean_html: @echo "cleaning html:" rm -rf $(HTMLDIR)/* + rm -rf $(XMLDIR) $(MAN7DIR)/%.7: $(MIBSDIR)/%.mib @echo "processing $*" diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index f64e0cca97..423d90fef6 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1996</year><year>2017</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -34,7 +34,46 @@ </header> - <section><title>SNMP 5.2.11</title> + <section><title>SNMP 5.2.12</title> + + <section><title>Fixed Bugs and Malfunctions</title> + <list> + <item> + <p>Conversion of (agent) Audit Trail Log (ATL) failed due + to invalid log entries.</p> <p>The conversion aborted + completely midway because the ATL contained invalid + entries. The conversion has been improved so that it now + firstly handles encountered errors and write an + informative message (into the converted stream) and + secondly keeps count of the number of successful or + failed entry conversions. See <seealso + marker="snmpa#log_to_txt">log_to_txt</seealso> for more + info. </p> <p>The reason the ATL contained invalid + entries have also been fixed. The reason was that for + some outgoing messages (not response):</p> <list + type="bulleted"> <item> <p>encrypted (v3 messages)</p> + <p>Was logged "as is" (encrypted) without the info to + decrypt, making conversion impossible (which was the + reason the log contained bad entries).</p> </item> <item> + <p>un-encrypted</p> <p>Was not logged at all. </p> + </item> </list> + <p> + Own Id: OTP-15287 Aux Id: ERIERL-206 </p> + </item> + <item> + <p> + [compiler] Spurious version message removed. The snmp mib + compiler printed an spurious version message if the + 'version' option was provided.</p> + <p> + Own Id: OTP-15290</p> + </item> + </list> + </section> + +</section> + +<section><title>SNMP 5.2.11</title> <section><title>Fixed Bugs and Malfunctions</title> <list> @@ -48,7 +87,7 @@ </list> </section> -</section> + </section> <section><title>SNMP 5.2.10</title> diff --git a/lib/snmp/doc/src/snmp.xml b/lib/snmp/doc/src/snmp.xml index 801193675c..d20f1a8d06 100644 --- a/lib/snmp/doc/src/snmp.xml +++ b/lib/snmp/doc/src/snmp.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>1996</year><year>2016</year> + <year>1996</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,7 +32,7 @@ <rev></rev> <file>snmp.xml</file> </header> - <module>snmp</module> + <module since="">snmp</module> <modulesummary>Interface functions to the SNMP toolkit</modulesummary> <description> <p>The module <c>snmp</c> contains interface functions to the @@ -56,7 +56,7 @@ <funcs> <func> - <name>config() -> ok | {error, Reason}</name> + <name since="">config() -> ok | {error, Reason}</name> <fsummary>Configure with a simple interactive tool</fsummary> <desc> <p>A simple interactive configuration tool. Simple @@ -78,8 +78,8 @@ </func> <func> - <name>start() -> ok | {error, Reason}</name> - <name>start(Type) -> ok | {error, Reason}</name> + <name since="">start() -> ok | {error, Reason}</name> + <name since="">start(Type) -> ok | {error, Reason}</name> <fsummary>Start the SNMP application</fsummary> <type> <v>Type = start_type()</v> @@ -93,8 +93,8 @@ </func> <func> - <name>start_agent() -> ok | {error, Reason}</name> - <name>start_agent(Type) -> ok | {error, Reason}</name> + <name since="">start_agent() -> ok | {error, Reason}</name> + <name since="">start_agent(Type) -> ok | {error, Reason}</name> <fsummary>Start the agent part of the SNMP application</fsummary> <type> <v>Type = start_type()</v> @@ -117,8 +117,8 @@ </func> <func> - <name>start_manager() -> ok | {error, Reason}</name> - <name>start_manager(Type) -> ok | {error, Reason}</name> + <name since="">start_manager() -> ok | {error, Reason}</name> + <name since="">start_manager(Type) -> ok | {error, Reason}</name> <fsummary>Start the manager part of the SNMP application</fsummary> <type> <v>Type = start_type()</v> @@ -141,7 +141,7 @@ </func> <func> - <name>date_and_time() -> DateAndTime</name> + <name since="">date_and_time() -> DateAndTime</name> <fsummary>Return the current date and time as an OCTET STRING</fsummary> <type> <v>DateAndTime = [int()]</v> @@ -155,7 +155,7 @@ </func> <func> - <name>date_and_time_to_universal_time_dst(DateAndTime) -> [utc()]</name> + <name since="">date_and_time_to_universal_time_dst(DateAndTime) -> [utc()]</name> <fsummary>Convert a DateAndTime value to a list of possible utc()</fsummary> <type> <v>DateAndTime = [int()]</v> @@ -171,8 +171,8 @@ </func> <func> - <name>date_and_time_to_string(DateAndTime) -> string()</name> - <name>date_and_time_to_string(DateAndTime, Validate) -> string()</name> + <name since="">date_and_time_to_string(DateAndTime) -> string()</name> + <name since="">date_and_time_to_string(DateAndTime, Validate) -> string()</name> <fsummary>Convert a DateAndTime value to a string</fsummary> <type> <v>DateAndTime = [int()]</v> @@ -194,7 +194,7 @@ </func> <func> - <name>date_and_time_to_string2(DateAndTime) -> string()</name> + <name since="">date_and_time_to_string2(DateAndTime) -> string()</name> <fsummary>Convert a DateAndTime value to a string</fsummary> <type> <v>DateAndTime = [int()]</v> @@ -210,7 +210,7 @@ </func> <func> - <name>local_time_to_date_and_time_dst(Local) -> [DateAndTime]</name> + <name since="">local_time_to_date_and_time_dst(Local) -> [DateAndTime]</name> <fsummary>Convert a Local time value to a list of possible DateAndTime(s)</fsummary> <type> <v>Local = {{Y,Mo,D},{H,M,S}}</v> @@ -226,7 +226,7 @@ </func> <func> - <name>universal_time_to_date_and_time(UTC) -> DateAndTime</name> + <name since="">universal_time_to_date_and_time(UTC) -> DateAndTime</name> <fsummary>Convert a UTC value to DateAndTime</fsummary> <type> <v>UTC = {{Y,Mo,D},{H,M,S}}</v> @@ -241,8 +241,8 @@ </func> <func> - <name>validate_date_and_time(DateAndTime) -> bool()</name> - <name>validate_date_and_time(DateAndTime, Validate) -> bool()</name> + <name since="">validate_date_and_time(DateAndTime) -> bool()</name> + <name since="">validate_date_and_time(DateAndTime, Validate) -> bool()</name> <fsummary>Check if a DateAndTime value is correct</fsummary> <type> <v>DateAndTime = term()</v> @@ -279,7 +279,7 @@ </func> <func> - <name>passwd2localized_key(Alg, Passwd, EngineID) -> Key</name> + <name since="">passwd2localized_key(Alg, Passwd, EngineID) -> Key</name> <fsummary>Generates an localized key</fsummary> <type> <v>Alg = algorithm()</v> @@ -298,7 +298,7 @@ </func> <func> - <name>octet_string_to_bits(S) -> Val</name> + <name since="">octet_string_to_bits(S) -> Val</name> <fsummary>Convert an OCTET-STRING to BITS</fsummary> <type> <v>Val = bits()</v> @@ -312,7 +312,7 @@ </func> <func> - <name>bits_to_octet_string(B) -> Val</name> + <name since="">bits_to_octet_string(B) -> Val</name> <fsummary>Convert an OCTET-STRING to BITS</fsummary> <type> <v>Val = octet_string()</v> @@ -326,7 +326,7 @@ </func> <func> - <name>read_mib(FileName) -> {ok, mib()} | {error, Reason}</name> + <name since="">read_mib(FileName) -> {ok, mib()} | {error, Reason}</name> <fsummary></fsummary> <type> <v>FileName = string()</v> @@ -341,10 +341,10 @@ </func> <func> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Block | Stop) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop, Block) -> ok | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Block | Stop) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R16B03">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop, Block) -> ok | {ok, Cnt} | {error, Reason}</name> <fsummary>Convert an Audit Trail Log to text format</fsummary> <type> <v>LogDir = string()</v> @@ -355,6 +355,9 @@ <v>LogFile = string()</v> <v>Start = Stop = null | datetime() | {local_time,datetime()} | {universal_time,datetime()} </v> <v>Block = boolean()</v> + <v>Cnt = {NumOK, NumERR}</v> + <v>NumOK = non_neg_integer()</v> + <v>NumERR = pos_integer()</v> <v>Reason = term()</v> </type> <desc> @@ -394,16 +397,25 @@ and <c>Vsn</c> is the SNMP version. <c>PDU</c> is a textual version of the protocol data unit. There is a new line between <c>Vsn</c> and <c>PDU</c>.</p> + + <p>If the entire log is successfully converted, the function + will return <c>ok</c>. + If one of more entries fail to convert, the function will instead + return <c>{ok, {NumOK, NumERR}}</c>, where the counters indicate + how many valid and erroneous entries where found. + If instead <c>{error, Reason}</c> is returned, the conversion + encountered a fatal error and where either never done of aborted + midway. </p> <marker id="log_to_io"></marker> </desc> </func> <func> - <name>log_to_io(LogDir, Mibs, LogName, LogFile) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Start, Block | Stop) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop, Block) -> ok | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Start, Block | Stop) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R16B03">log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop, Block) -> ok | {ok, Cnt} | {error, Reason}</name> <fsummary>Convert an Audit Trail Log to text format</fsummary> <type> <v>LogDir = string()</v> @@ -412,6 +424,9 @@ <v>LogName = string()</v> <v>LogFile = string()</v> <v>Start = Stop = null | datetime() | {local_time,datetime()} | {universal_time,datetime()} </v> + <v>Cnt = {NumOK, NumERR}</v> + <v>NumOK = non_neg_integer()</v> + <v>NumERR = pos_integer()</v> <v>Reason = term()</v> </type> <desc> @@ -425,7 +440,7 @@ </func> <func> - <name>change_log_size(LogName, NewSize) -> ok | {error, Reason}</name> + <name since="">change_log_size(LogName, NewSize) -> ok | {error, Reason}</name> <fsummary>Change the size of the Audit Trail Log</fsummary> <type> <v>LogName = string()</v> @@ -448,8 +463,8 @@ </func> <func> - <name>print_version_info() -> void()</name> - <name>print_version_info(Prefix) -> void()</name> + <name since="">print_version_info() -> void()</name> + <name since="">print_version_info(Prefix) -> void()</name> <fsummary>Formatted print of result of the versions functions</fsummary> <type> <v>Prefix = string() | integer()</v> @@ -469,8 +484,8 @@ </func> <func> - <name>versions1() -> {ok, Info} | {error, Reason}</name> - <name>versions2() -> {ok, Info} | {error, Reason}</name> + <name since="">versions1() -> {ok, Info} | {error, Reason}</name> + <name since="">versions2() -> {ok, Info} | {error, Reason}</name> <fsummary>Retrieve various system and application info</fsummary> <type> <v>Info = [info()]</v> @@ -489,8 +504,8 @@ </func> <func> - <name>print_versions(VersionInfo) -> void()</name> - <name>print_versions(Prefix, VersionInfo) -> void()</name> + <name since="">print_versions(VersionInfo) -> void()</name> + <name since="">print_versions(Prefix, VersionInfo) -> void()</name> <fsummary>Formatted print of result of the versions functions</fsummary> <type> <v>VersionInfo = [version_info()]</v> @@ -512,7 +527,7 @@ </func> <func> - <name>enable_trace() -> void()</name> + <name since="">enable_trace() -> void()</name> <fsummary>Starts a tracer</fsummary> <!-- <type> @@ -528,7 +543,7 @@ </func> <func> - <name>disable_trace() -> void()</name> + <name since="">disable_trace() -> void()</name> <fsummary>Stop the tracer</fsummary> <!-- <type> @@ -543,7 +558,7 @@ </func> <func> - <name>set_trace(Targets) -> void()</name> + <name since="">set_trace(Targets) -> void()</name> <fsummary>Set trace target</fsummary> <type> <v>Targets = target() | targets()</v> @@ -567,7 +582,7 @@ </func> <func> - <name>reset_trace(Targets) -> void()</name> + <name since="">reset_trace(Targets) -> void()</name> <fsummary>Reset trace target</fsummary> <type> <v>Targets = module() | modules()</v> @@ -583,7 +598,7 @@ </func> <func> - <name>set_trace(Targets, Opts) -> void()</name> + <name since="">set_trace(Targets, Opts) -> void()</name> <fsummary>Set trace target</fsummary> <type> <v>Targets = target() | targets()</v> diff --git a/lib/snmp/doc/src/snmp_community_mib.xml b/lib/snmp/doc/src/snmp_community_mib.xml index 61dea05950..9800fb6c00 100644 --- a/lib/snmp/doc/src/snmp_community_mib.xml +++ b/lib/snmp/doc/src/snmp_community_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_community_mib.xml</file> </header> - <module>snmp_community_mib</module> + <module since="">snmp_community_mib</module> <modulesummary>Instrumentation Functions for SNMP-COMMUNITY-MIB</modulesummary> <description> <p>The module <c>snmp_community_mib</c> implements the instrumentation @@ -45,7 +45,7 @@ <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-COMMUNITY-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -77,7 +77,7 @@ </func> <func> - <name>reconfigure(ConfDir) -> void()</name> + <name since="">reconfigure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-COMMUNITY-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -108,8 +108,8 @@ </func> <func> - <name>add_community(Idx, CommName, SecName, CtxName, TransportTag) -> Ret</name> - <name>add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) -> Ret</name> + <name since="">add_community(Idx, CommName, SecName, CtxName, TransportTag) -> Ret</name> + <name since="OTP R14B03">add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) -> Ret</name> <fsummary>Added one community</fsummary> <type> <v>Idx = string()</v> @@ -132,7 +132,7 @@ </func> <func> - <name>delete_community(Key) -> Ret</name> + <name since="">delete_community(Key) -> Ret</name> <fsummary>Delete one community</fsummary> <type> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmp_framework_mib.xml b/lib/snmp/doc/src/snmp_framework_mib.xml index 64e5df6ff5..d84327d4d5 100644 --- a/lib/snmp/doc/src/snmp_framework_mib.xml +++ b/lib/snmp/doc/src/snmp_framework_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_framework_mib.xml</file> </header> - <module>snmp_framework_mib</module> + <module since="">snmp_framework_mib</module> <modulesummary>Instrumentation Functions for SNMP-FRAMEWORK-MIB</modulesummary> <description> <p>The module <c>snmp_framework_mib</c> implements instrumentation @@ -44,7 +44,7 @@ </description> <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-FRAMEWORK-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -75,7 +75,7 @@ </desc> </func> <func> - <name>init() -> void()</name> + <name since="">init() -> void()</name> <fsummary>Initialize the SNMP-FRAMEWORK-MIB</fsummary> <desc> <p>This function is called from the supervisor at system @@ -88,7 +88,7 @@ </desc> </func> <func> - <name>add_context(Ctx) -> Ret</name> + <name since="">add_context(Ctx) -> Ret</name> <fsummary>Added one context</fsummary> <type> <v>Ctx = string()</v> @@ -103,7 +103,7 @@ </desc> </func> <func> - <name>delete_context(Key) -> Ret</name> + <name since="">delete_context(Key) -> Ret</name> <fsummary>Delete one context</fsummary> <type> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmp_generic.xml b/lib/snmp/doc/src/snmp_generic.xml index 44762dec59..6fb714907c 100644 --- a/lib/snmp/doc/src/snmp_generic.xml +++ b/lib/snmp/doc/src/snmp_generic.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_generic.xml</file> </header> - <module>snmp_generic</module> + <module since="">snmp_generic</module> <modulesummary>Generic Functions for Implementing SNMP Objects in a Database</modulesummary> <description> <marker id="description"></marker> @@ -127,8 +127,8 @@ value() = term() <funcs> <func> - <name>get_status_col(Name, Cols)</name> - <name>get_status_col(NameDb, Cols) -> {ok, StatusVal} | false</name> + <name since="">get_status_col(Name, Cols)</name> + <name since="">get_status_col(NameDb, Cols) -> {ok, StatusVal} | false</name> <fsummary>Get the value of the status column from <c>Cols</c></fsummary> <type> <v>Name = name()</v> @@ -148,7 +148,7 @@ value() = term() </func> <func> - <name>get_index_types(Name)</name> + <name since="">get_index_types(Name)</name> <fsummary>Get the index types of <c>Name</c></fsummary> <type> <v>Name = name()</v> @@ -163,7 +163,7 @@ value() = term() </func> <func> - <name>get_table_info(Name, Item) -> table_info_result()</name> + <name since="OTP R15B01">get_table_info(Name, Item) -> table_info_result()</name> <fsummary>Get table info item of MIB table <c>Name</c></fsummary> <type> <v>Name = name()</v> @@ -187,8 +187,8 @@ value() = term() </func> <func> - <name>table_func(Op1, NameDb)</name> - <name>table_func(Op2, RowIndex, Cols, NameDb) -> Ret</name> + <name since="">table_func(Op1, NameDb)</name> + <name since="">table_func(Op2, RowIndex, Cols, NameDb) -> Ret</name> <fsummary>Default instrumentation function for tables</fsummary> <type> <v>Op1 = new | delete </v> @@ -232,7 +232,7 @@ value() = term() </func> <func> - <name>table_get_elements(NameDb, RowIndex, Cols) -> Values</name> + <name since="">table_get_elements(NameDb, RowIndex, Cols) -> Values</name> <fsummary>Get elements in a table row</fsummary> <type> <v>NameDb = name_db()</v> @@ -249,7 +249,7 @@ value() = term() </func> <func> - <name>table_next(NameDb, RestOid) -> RowIndex | endOfTable</name> + <name since="">table_next(NameDb, RestOid) -> RowIndex | endOfTable</name> <fsummary>Find the next row in the table</fsummary> <type> <v>NameDb = name_db()</v> @@ -265,7 +265,7 @@ value() = term() </func> <func> - <name>table_row_exists(NameDb, RowIndex) -> bool()</name> + <name since="">table_row_exists(NameDb, RowIndex) -> bool()</name> <fsummary>Check if a row in a table exists</fsummary> <type> <v>NameDb = name_db()</v> @@ -279,7 +279,7 @@ value() = term() </func> <func> - <name>table_set_elements(NameDb, RowIndex, Cols) -> bool()</name> + <name since="">table_set_elements(NameDb, RowIndex, Cols) -> bool()</name> <fsummary>Set elements in a table row</fsummary> <type> <v>NameDb = name_db()</v> @@ -300,8 +300,8 @@ value() = term() </func> <func> - <name>variable_func(Op1, NameDb)</name> - <name>variable_func(Op2, Val, NameDb) -> Ret</name> + <name since="">variable_func(Op1, NameDb)</name> + <name since="">variable_func(Op2, Val, NameDb) -> Ret</name> <fsummary>Default instrumentation function for tables</fsummary> <type> <v>Op1 = new | delete | get</v> @@ -325,7 +325,7 @@ value() = term() </func> <func> - <name>variable_get(NameDb) -> {value, Value} | undefined</name> + <name since="">variable_get(NameDb) -> {value, Value} | undefined</name> <fsummary>Get the value of a variable</fsummary> <type> <v>NameDb = name_db()</v> @@ -339,7 +339,7 @@ value() = term() </func> <func> - <name>variable_set(NameDb, NewVal) -> true | false</name> + <name since="">variable_set(NameDb, NewVal) -> true | false</name> <fsummary>Set a value for a variable</fsummary> <type> <v>NameDb = name_db()</v> diff --git a/lib/snmp/doc/src/snmp_impl_example_agent.xml b/lib/snmp/doc/src/snmp_impl_example_agent.xml index e576fa51f3..7dda3dd5cd 100644 --- a/lib/snmp/doc/src/snmp_impl_example_agent.xml +++ b/lib/snmp/doc/src/snmp_impl_example_agent.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>1997</year><year>2016</year> + <year>1997</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> diff --git a/lib/snmp/doc/src/snmp_index.xml b/lib/snmp/doc/src/snmp_index.xml index 646e9661a3..1497f4cf67 100644 --- a/lib/snmp/doc/src/snmp_index.xml +++ b/lib/snmp/doc/src/snmp_index.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_index.xml</file> </header> - <module>snmp_index</module> + <module since="">snmp_index</module> <modulesummary>Abstract Data Type for SNMP Indexing</modulesummary> <description> <p>The module <c>snmp_index</c> implements an Abstract @@ -159,7 +159,7 @@ get_next_pid(Oid, SnmpIndex) -> </section> <funcs> <func> - <name>delete(Index) -> true</name> + <name since="">delete(Index) -> true</name> <fsummary>Delete an index table</fsummary> <type> <v>Index = NewIndex = index()</v> @@ -173,7 +173,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>delete(Index, Key) -> NewIndex</name> + <name since="">delete(Index, Key) -> NewIndex</name> <fsummary>Delete an item from the index</fsummary> <type> <v>Index = NewIndex = index()</v> @@ -185,7 +185,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>get(Index, KeyOid) -> {ok, {KeyOid, Value}} | undefined</name> + <name since="">get(Index, KeyOid) -> {ok, {KeyOid, Value}} | undefined</name> <fsummary>Get the item with <c>KeyOid</c></fsummary> <type> <v>Index = index()</v> @@ -198,7 +198,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>get_last(Index) -> {ok, {KeyOid, Value}} | undefined</name> + <name since="">get_last(Index) -> {ok, {KeyOid, Value}} | undefined</name> <fsummary>Get the last item in the index structure</fsummary> <type> <v>Index = index()</v> @@ -210,7 +210,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>get_next(Index, KeyOid) -> {ok, {NextKeyOid, Value}} | undefined</name> + <name since="">get_next(Index, KeyOid) -> {ok, {NextKeyOid, Value}} | undefined</name> <fsummary>Get the next item</fsummary> <type> <v>Index = index()</v> @@ -224,7 +224,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>insert(Index, Key, Value) -> NewIndex</name> + <name since="">insert(Index, Key, Value) -> NewIndex</name> <fsummary>Insert an item into the index</fsummary> <type> <v>Index = NewIndex = index()</v> @@ -238,7 +238,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>key_to_oid(Index, Key) -> KeyOid</name> + <name since="">key_to_oid(Index, Key) -> KeyOid</name> <fsummary>Convert a key to an OBJECT IDENTIFIER</fsummary> <type> <v>Index = index()</v> @@ -250,7 +250,7 @@ get_next_pid(Oid, SnmpIndex) -> </desc> </func> <func> - <name>new(KeyTypes) -> Index</name> + <name since="">new(KeyTypes) -> Index</name> <fsummary>Create a new snmp index structure</fsummary> <type> <v>KeyTypes = key_types()</v> diff --git a/lib/snmp/doc/src/snmp_notification_mib.xml b/lib/snmp/doc/src/snmp_notification_mib.xml index d2e288ec15..9395edf155 100644 --- a/lib/snmp/doc/src/snmp_notification_mib.xml +++ b/lib/snmp/doc/src/snmp_notification_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_notification_mib.xml</file> </header> - <module>snmp_notification_mib</module> + <module since="">snmp_notification_mib</module> <modulesummary>Instrumentation Functions for SNMP-NOTIFICATION-MIB</modulesummary> <description> <p>The module <c>snmp_notification_mib</c> implements the @@ -43,7 +43,7 @@ </description> <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-NOTIFICATION-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -70,7 +70,7 @@ </desc> </func> <func> - <name>reconfigure(ConfDir) -> void()</name> + <name since="">reconfigure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-NOTIFICATION-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -98,7 +98,7 @@ </desc> </func> <func> - <name>add_notify(Name, Tag, Type) -> Ret</name> + <name since="">add_notify(Name, Tag, Type) -> Ret</name> <fsummary>Added one notify definition</fsummary> <type> <v>Name = string()</v> @@ -115,7 +115,7 @@ </desc> </func> <func> - <name>delete_notify(Key) -> Ret</name> + <name since="">delete_notify(Key) -> Ret</name> <fsummary>Delete one notify definition</fsummary> <type> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmp_pdus.xml b/lib/snmp/doc/src/snmp_pdus.xml index 1d086e6f48..f403b6edf4 100644 --- a/lib/snmp/doc/src/snmp_pdus.xml +++ b/lib/snmp/doc/src/snmp_pdus.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_pdus.xml</file> </header> - <module>snmp_pdus</module> + <module since="">snmp_pdus</module> <modulesummary>Encode and Decode Functions for SNMP PDUs</modulesummary> <description> <p>RFC1157, RFC1905 and/or RFC2272 should be studied carefully @@ -55,7 +55,7 @@ </description> <funcs> <func> - <name>dec_message([byte()]) -> Message</name> + <name since="">dec_message([byte()]) -> Message</name> <fsummary>Decode an SNMP Message</fsummary> <type> <v>Message = #message</v> @@ -71,7 +71,7 @@ </desc> </func> <func> - <name>dec_message_only([byte()]) -> Message</name> + <name since="">dec_message_only([byte()]) -> Message</name> <fsummary>Decode an SNMP Message, but not the data part</fsummary> <type> <v>Message = #message</v> @@ -84,7 +84,7 @@ </desc> </func> <func> - <name>dec_pdu([byte()]) -> Pdu</name> + <name since="">dec_pdu([byte()]) -> Pdu</name> <fsummary>Decode an SNMP Pdu</fsummary> <type> <v>Pdu = #pdu</v> @@ -94,7 +94,7 @@ </desc> </func> <func> - <name>dec_scoped_pdu([byte()]) -> ScopedPdu</name> + <name since="">dec_scoped_pdu([byte()]) -> ScopedPdu</name> <fsummary>Decode an SNMP ScopedPdu</fsummary> <type> <v>ScopedPdu = #scoped_pdu</v> @@ -104,7 +104,7 @@ </desc> </func> <func> - <name>dec_scoped_pdu_data([byte()]) -> ScopedPduData</name> + <name since="">dec_scoped_pdu_data([byte()]) -> ScopedPduData</name> <fsummary>Decode an SNMP ScopedPduData</fsummary> <type> <v>ScopedPduData = #scoped_pdu | EncryptedPDU</v> @@ -116,7 +116,7 @@ </desc> </func> <func> - <name>dec_usm_security_parameters([byte()]) -> UsmSecParams</name> + <name since="">dec_usm_security_parameters([byte()]) -> UsmSecParams</name> <fsummary>Decode SNMP UsmSecurityParameters</fsummary> <type> <v>UsmSecParams = #usmSecurityParameters</v> @@ -126,7 +126,7 @@ </desc> </func> <func> - <name>enc_encrypted_scoped_pdu(EncryptedScopedPdu) -> [byte()]</name> + <name since="">enc_encrypted_scoped_pdu(EncryptedScopedPdu) -> [byte()]</name> <fsummary>Encode an encrypted SNMP scopedPDU</fsummary> <type> <v>EncryptedScopedPdu = [byte()]</v> @@ -142,7 +142,7 @@ </desc> </func> <func> - <name>enc_message(Message) -> [byte()]</name> + <name since="">enc_message(Message) -> [byte()]</name> <fsummary>Encode an SNMP Message</fsummary> <type> <v>Message = #message</v> @@ -152,7 +152,7 @@ </desc> </func> <func> - <name>enc_message_only(Message) -> [byte()]</name> + <name since="">enc_message_only(Message) -> [byte()]</name> <fsummary>Encode an SNMP Message, but not the data part</fsummary> <type> <v>Message = #message</v> @@ -166,7 +166,7 @@ </desc> </func> <func> - <name>enc_pdu(Pd) -> [byte()]</name> + <name since="">enc_pdu(Pd) -> [byte()]</name> <fsummary>Encode an SNMP Pdu</fsummary> <type> <v>Pdu = #pdu</v> @@ -176,7 +176,7 @@ </desc> </func> <func> - <name>enc_scoped_pdu(ScopedPdu) -> [byte()]</name> + <name since="">enc_scoped_pdu(ScopedPdu) -> [byte()]</name> <fsummary>Encode an SNMP scopedPDU</fsummary> <type> <v>ScopedPdu = #scoped_pdu</v> @@ -190,7 +190,7 @@ </desc> </func> <func> - <name>enc_usm_security_parameters(UsmSecParams) -> [byte()]</name> + <name since="">enc_usm_security_parameters(UsmSecParams) -> [byte()]</name> <fsummary>Encode SNMP UsmSecurityParameters</fsummary> <type> <v>UsmSecParams = #usmSecurityParameters</v> diff --git a/lib/snmp/doc/src/snmp_standard_mib.xml b/lib/snmp/doc/src/snmp_standard_mib.xml index 35efbba483..eb4e2fd097 100644 --- a/lib/snmp/doc/src/snmp_standard_mib.xml +++ b/lib/snmp/doc/src/snmp_standard_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_standard_mib.xml</file> </header> - <module>snmp_standard_mib</module> + <module since="">snmp_standard_mib</module> <modulesummary>Instrumentation Functions for STANDARD-MIB and SNMPv2-MIB</modulesummary> <description> <p>The module <c>snmp_standard_mib</c> implements the instrumentation functions for the @@ -42,7 +42,7 @@ </description> <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the STANDARD-MIB and SNMPv2-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -71,8 +71,8 @@ </desc> </func> <func> - <name>inc(Name) -> void()</name> - <name>inc(Name, N) -> void()</name> + <name since="">inc(Name) -> void()</name> + <name since="">inc(Name, N) -> void()</name> <fsummary>Increment a variable in the MIB</fsummary> <type> <v>Name = atom()</v> @@ -84,7 +84,7 @@ </desc> </func> <func> - <name>reconfigure(ConfDir) -> void()</name> + <name since="">reconfigure(ConfDir) -> void()</name> <fsummary>Configure the STANDARD-MIB and SNMPv2-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -114,14 +114,14 @@ </desc> </func> <func> - <name>reset() -> void()</name> + <name since="">reset() -> void()</name> <fsummary>Reset all <c>snmp</c>counters to 0</fsummary> <desc> <p>Resets all <c>snmp</c> counters to 0.</p> </desc> </func> <func> - <name>sys_up_time() -> Time</name> + <name since="">sys_up_time() -> Time</name> <fsummary>Get the system up time</fsummary> <type> <v>Time = int()</v> diff --git a/lib/snmp/doc/src/snmp_target_mib.xml b/lib/snmp/doc/src/snmp_target_mib.xml index c3bcd3b4e3..c46edb810d 100644 --- a/lib/snmp/doc/src/snmp_target_mib.xml +++ b/lib/snmp/doc/src/snmp_target_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_target_mib.xml</file> </header> - <module>snmp_target_mib</module> + <module since="">snmp_target_mib</module> <modulesummary>Instrumentation Functions for SNMP-TARGET-MIB</modulesummary> <description> <p>The module <c>snmp_target_mib</c> implements the instrumentation @@ -57,7 +57,7 @@ <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-TARGET-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -85,7 +85,7 @@ </func> <func> - <name>reconfigure(ConfDir) -> void()</name> + <name since="">reconfigure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-TARGET-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -113,7 +113,7 @@ </func> <func> - <name>set_target_engine_id(TargetAddrName, EngineId) -> boolean()</name> + <name since="">set_target_engine_id(TargetAddrName, EngineId) -> boolean()</name> <fsummary>Set the engine id for a targetAddr row.</fsummary> <type> <v>TargetAddrName = string()</v> @@ -130,7 +130,7 @@ </func> <func> - <name>add_addr(Name, Domain, Addr, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name> + <name since="">add_addr(Name, Domain, Addr, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name> <fsummary>Add one target address definition</fsummary> <type> <v>Name = string()</v> @@ -156,7 +156,7 @@ </func> <func> - <name>delete_addr(Key) -> Ret</name> + <name since="">delete_addr(Key) -> Ret</name> <fsummary>Delete one target address definition</fsummary> <type> <v>Key = term()</v> @@ -171,7 +171,7 @@ </func> <func> - <name>add_params(Name, MPModel, SecModel, SecName, SecLevel) -> Ret</name> + <name since="">add_params(Name, MPModel, SecModel, SecName, SecLevel) -> Ret</name> <fsummary>Add one target parameter definition</fsummary> <type> <v>Name = string()</v> @@ -191,7 +191,7 @@ </desc> </func> <func> - <name>delete_params(Key) -> Ret</name> + <name since="">delete_params(Key) -> Ret</name> <fsummary>Delete one target parameter definition</fsummary> <type> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmp_user_based_sm_mib.xml b/lib/snmp/doc/src/snmp_user_based_sm_mib.xml index cc376ac118..6c2203ed22 100644 --- a/lib/snmp/doc/src/snmp_user_based_sm_mib.xml +++ b/lib/snmp/doc/src/snmp_user_based_sm_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_user_based_sm_mib.xml</file> </header> - <module>snmp_user_based_sm_mib</module> + <module since="">snmp_user_based_sm_mib</module> <modulesummary>Instrumentation Functions for SNMP-USER-BASED-SM-MIB</modulesummary> <description> <p>The module <c>snmp_user_based_sm_mib</c> implements the instrumentation @@ -43,7 +43,7 @@ </description> <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-USER-BASED-SM-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -72,7 +72,7 @@ </desc> </func> <func> - <name>reconfigure(ConfDir) -> void()</name> + <name since="">reconfigure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-USER-BASED-SM-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -103,7 +103,7 @@ </desc> </func> <func> - <name>add_user(EngineID, Name, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC, PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey) -> Ret</name> + <name since="">add_user(EngineID, Name, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC, PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey) -> Ret</name> <fsummary>Add one user</fsummary> <type> <v>EngineID = string()</v> @@ -130,7 +130,7 @@ </desc> </func> <func> - <name>delete_user(Key) -> Ret</name> + <name since="">delete_user(Key) -> Ret</name> <fsummary>Delete one user</fsummary> <type> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmp_view_based_acm_mib.xml b/lib/snmp/doc/src/snmp_view_based_acm_mib.xml index fdad735e71..c5e98a3eb5 100644 --- a/lib/snmp/doc/src/snmp_view_based_acm_mib.xml +++ b/lib/snmp/doc/src/snmp_view_based_acm_mib.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmp_view_based_acm_mib.xml</file> </header> - <module>snmp_view_based_acm_mib</module> + <module since="">snmp_view_based_acm_mib</module> <modulesummary>Instrumentation Functions for SNMP-VIEW-BASED-ACM-MIB</modulesummary> <description> <p>The module <c>snmp_view_based_acm_mib</c> implements the instrumentation functions for the @@ -45,7 +45,7 @@ <funcs> <func> - <name>configure(ConfDir) -> void()</name> + <name since="">configure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-VIEW-BASED-ACM-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -71,7 +71,7 @@ </func> <func> - <name>reconfigure(ConfDir) -> void()</name> + <name since="">reconfigure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-VIEW-BASED-ACM-MIB</fsummary> <type> <v>ConfDir = string()</v> @@ -104,7 +104,7 @@ </func> <func> - <name>add_sec2group(SecModel, SecName, GroupName) -> Ret</name> + <name since="">add_sec2group(SecModel, SecName, GroupName) -> Ret</name> <fsummary>Add one security to group definition</fsummary> <type> <v>SecModel = v1 | v2c | usm</v> @@ -124,7 +124,7 @@ </func> <func> - <name>delete_sec2group(Key) -> Ret</name> + <name since="">delete_sec2group(Key) -> Ret</name> <fsummary>Delete one security to group definition</fsummary> <type> <v>Key = term()</v> @@ -139,7 +139,7 @@ </func> <func> - <name>add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) -> Ret</name> + <name since="">add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) -> Ret</name> <fsummary>Add one access definition</fsummary> <type> <v>GroupName = string()</v> @@ -163,7 +163,7 @@ </func> <func> - <name>delete_access(Key) -> Ret</name> + <name since="">delete_access(Key) -> Ret</name> <fsummary>Delete one access definition</fsummary> <type> <v>Key = term()</v> @@ -178,7 +178,7 @@ </func> <func> - <name>add_view_tree_fam(ViewIndex, SubTree, Status, Mask) -> Ret</name> + <name since="">add_view_tree_fam(ViewIndex, SubTree, Status, Mask) -> Ret</name> <fsummary>Add one view tree family definition</fsummary> <type> <v>ViewIndex = integer()</v> @@ -199,7 +199,7 @@ </func> <func> - <name>delete_view_tree_fam(Key) -> Ret</name> + <name since="">delete_view_tree_fam(Key) -> Ret</name> <fsummary>Delete one view tree family definition</fsummary> <type> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml index d756ff7a65..dc2f4e6d66 100644 --- a/lib/snmp/doc/src/snmpa.xml +++ b/lib/snmp/doc/src/snmpa.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2004</year><year>2016</year> + <year>2004</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa.xml</file> </header> - <module>snmpa</module> + <module since="">snmpa</module> <modulesummary>Interface Functions to the SNMP toolkit agent</modulesummary> <description> <p>The module <c>snmpa</c> contains interface functions to the @@ -77,7 +77,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} <funcs> <func> - <name>add_agent_caps(SysORID, SysORDescr) -> SysORIndex</name> + <name since="">add_agent_caps(SysORID, SysORDescr) -> SysORIndex</name> <fsummary>Add an AGENT-CAPABILITY definition to the agent</fsummary> <type> <v>SysORID = oid()</v> @@ -93,7 +93,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>del_agent_caps(SysORIndex) -> void()</name> + <name since="">del_agent_caps(SysORIndex) -> void()</name> <fsummary>Delete an AGENT-CAPABILITY definition from the agent</fsummary> <type> <v>SysORIndex = integer()</v> @@ -108,7 +108,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>get_agent_caps() -> [[SysORIndex, SysORID, SysORDescr, SysORUpTime]]</name> + <name since="">get_agent_caps() -> [[SysORIndex, SysORID, SysORDescr, SysORUpTime]]</name> <fsummary>Return all AGENT-CAPABILITY definitions in the agent</fsummary> <type> <v>SysORIndex = integer()</v> @@ -125,8 +125,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>get(Agent, Vars) -> Values | {error, Reason}</name> - <name>get(Agent, Vars, Context) -> Values | {error, Reason}</name> + <name since="">get(Agent, Vars) -> Values | {error, Reason}</name> + <name since="">get(Agent, Vars, Context) -> Values | {error, Reason}</name> <fsummary>Perform a get operation on the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -150,8 +150,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>get_next(Agent, Vars) -> Values | {error, Reason}</name> - <name>get_next(Agent, Vars, Context) -> Values | {error, Reason}</name> + <name since="">get_next(Agent, Vars) -> Values | {error, Reason}</name> + <name since="">get_next(Agent, Vars, Context) -> Values | {error, Reason}</name> <fsummary>Perform a get-next operation on the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -176,7 +176,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} <!-- <func> - <name>get_symbolic_store_db() -> Db</name> + <name since="">get_symbolic_store_db() -> Db</name> <fsummary>Retrieve the symbolic store database reference</fsummary> <type> <v>Db = term()</v> @@ -193,8 +193,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} --> <func> - <name>backup(BackupDir) -> ok | {error, Reason}</name> - <name>backup(Agent, BackupDir) -> ok | {error, Reason}</name> + <name since="">backup(BackupDir) -> ok | {error, Reason}</name> + <name since="">backup(Agent, BackupDir) -> ok | {error, Reason}</name> <fsummary>Backup agent data</fsummary> <type> <v>BackupDir = string()</v> @@ -216,8 +216,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </desc> </func> <func> - <name>info() -> [{Key, Value}]</name> - <name>info(Agent) -> [{Key, Value}]</name> + <name since="">info() -> [{Key, Value}]</name> + <name since="">info(Agent) -> [{Key, Value}]</name> <fsummary>Return information about the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -236,7 +236,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>old_info_format(NewInfo) -> OldInfo</name> + <name since="">old_info_format(NewInfo) -> OldInfo</name> <fsummary>Return information about the agent</fsummary> <type> <v>OldInfo = NewInfo = [{Key, Value}]</v> @@ -251,8 +251,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>load_mib(Mib) -> ok | {error, Reason}</name> - <name>load_mib(Agent, Mib) -> ok | {error, Reason}</name> + <name since="OTP R16B02">load_mib(Mib) -> ok | {error, Reason}</name> + <name since="OTP R16B02">load_mib(Agent, Mib) -> ok | {error, Reason}</name> <fsummary>Load single MIB into the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -273,10 +273,10 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>load_mibs(Mibs) -> ok | {error, Reason}</name> - <name>load_mibs(Mibs, Force) -> ok | {error, Reason}</name> - <name>load_mibs(Agent, Mibs) -> ok | {error, Reason}</name> - <name>load_mibs(Agent, Mibs, Force) -> ok | {error, Reason}</name> + <name since="">load_mibs(Mibs) -> ok | {error, Reason}</name> + <name since="">load_mibs(Mibs, Force) -> ok | {error, Reason}</name> + <name since="">load_mibs(Agent, Mibs) -> ok | {error, Reason}</name> + <name since="OTP R16B02">load_mibs(Agent, Mibs, Force) -> ok | {error, Reason}</name> <fsummary>Load MIBs into the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -305,8 +305,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>unload_mib(Mib) -> ok | {error, Reason}</name> - <name>unload_mib(Agent, Mib) -> ok | {error, Reason}</name> + <name since="OTP R16B02">unload_mib(Mib) -> ok | {error, Reason}</name> + <name since="OTP R16B02">unload_mib(Agent, Mib) -> ok | {error, Reason}</name> <fsummary>Unload single MIB from the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -321,10 +321,10 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>unload_mibs(Mibs) -> ok | {error, Reason}</name> - <name>unload_mibs(Mibs, Force) -> ok | {error, Reason}</name> - <name>unload_mibs(Agent, Mibs) -> ok | {error, Reason}</name> - <name>unload_mibs(Agent, Mibs, Force) -> ok | {error, Reason}</name> + <name since="">unload_mibs(Mibs) -> ok | {error, Reason}</name> + <name since="">unload_mibs(Mibs, Force) -> ok | {error, Reason}</name> + <name since="">unload_mibs(Agent, Mibs) -> ok | {error, Reason}</name> + <name since="OTP R16B02">unload_mibs(Agent, Mibs, Force) -> ok | {error, Reason}</name> <fsummary>Unload MIBs from the agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -347,8 +347,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_mibs() -> Mibs</name> - <name>which_mibs(Agent) -> Mibs</name> + <name since="">which_mibs() -> Mibs</name> + <name since="">which_mibs(Agent) -> Mibs</name> <fsummary>Get a list of all the loaded mibs</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -365,8 +365,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>whereis_mib(MibName) -> {ok, MibFile} | {error, Reason}</name> - <name>whereis_mib(Agent, MibName) -> {ok, MibFile} | {error, Reason}</name> + <name since="">whereis_mib(MibName) -> {ok, MibFile} | {error, Reason}</name> + <name since="">whereis_mib(Agent, MibName) -> {ok, MibFile} | {error, Reason}</name> <fsummary>Get the path to the mib file</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -385,10 +385,10 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>current_request_id() -> {value, RequestId} | false</name> - <name>current_context() -> {value, Context} | false</name> - <name>current_community() -> {value, Community} | false</name> - <name>current_address() -> {value, Address} | false</name> + <name since="">current_request_id() -> {value, RequestId} | false</name> + <name since="">current_context() -> {value, Context} | false</name> + <name since="">current_community() -> {value, Community} | false</name> + <name since="">current_address() -> {value, Address} | false</name> <fsummary>Get the request-id, context, community and address of the current request</fsummary> <type> <v>RequestId = integer()</v> @@ -409,8 +409,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>enum_to_int(Name, Enum) -> {value, Int} | false</name> - <name>enum_to_int(Db, Name, Enum) -> {value, Int} | false</name> + <name since="">enum_to_int(Name, Enum) -> {value, Int} | false</name> + <name since="">enum_to_int(Db, Name, Enum) -> {value, Int} | false</name> <fsummary>Convert an enum value to an integer</fsummary> <type> <v>Db = term()</v> @@ -435,8 +435,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>int_to_enum(Name, Int) -> {value, Enum} | false</name> - <name>int_to_enum(Db, Name, Int) -> {value, Enum} | false</name> + <name since="">int_to_enum(Name, Int) -> {value, Enum} | false</name> + <name since="">int_to_enum(Db, Name, Int) -> {value, Enum} | false</name> <fsummary>Convert an integer to an enum value</fsummary> <type> <v>Db = term()</v> @@ -461,8 +461,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>name_to_oid(Name) -> {value, oid()} | false</name> - <name>name_to_oid(Db, Name) -> {value, oid()} | false</name> + <name since="">name_to_oid(Name) -> {value, oid()} | false</name> + <name since="">name_to_oid(Db, Name) -> {value, oid()} | false</name> <fsummary>Convert a symbolic name to an OID</fsummary> <type> <v>Db = term()</v> @@ -482,8 +482,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>oid_to_name(OID) -> {value, Name} | false</name> - <name>oid_to_name(Db, OID) -> {value, Name} | false</name> + <name since="">oid_to_name(OID) -> {value, Name} | false</name> + <name since="">oid_to_name(Db, OID) -> {value, Name} | false</name> <fsummary>Convert an OID to a symbolic name</fsummary> <type> <v>Db = term()</v> @@ -503,7 +503,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_aliasnames() -> Result</name> + <name since="">which_aliasnames() -> Result</name> <fsummary>Get all alias-names known to the agent</fsummary> <type> <v>Result = [atom()]</v> @@ -515,7 +515,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_tables() -> Result</name> + <name since="">which_tables() -> Result</name> <fsummary>Get all tables known to the agent</fsummary> <type> <v>Result = [atom()]</v> @@ -528,7 +528,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_variables() -> Result</name> + <name since="">which_variables() -> Result</name> <fsummary>Get all variables known to the agent</fsummary> <type> <v>Result = [atom()]</v> @@ -541,7 +541,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_notifications() -> Result</name> + <name since="">which_notifications() -> Result</name> <fsummary>Get all notifications known to the agent</fsummary> <type> <v>Result = [{Name, MibName, Info}]</v> @@ -557,15 +557,15 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>log_to_txt(LogDir)</name> - <name>log_to_txt(LogDir, Block | Mibs)</name> - <name>log_to_txt(LogDir, Mibs, Block | OutFile) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, Block | LogName) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, Block | LogFile) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start, Stop) -> ok | {error, Reason}</name> + <name since="OTP R15B01">log_to_txt(LogDir)</name> + <name since="">log_to_txt(LogDir, Block | Mibs)</name> + <name since="">log_to_txt(LogDir, Mibs, Block | OutFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, Block | LogName) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, Block | LogFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R16B03">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> <fsummary>Convert an Audit Trail Log to text format</fsummary> <type> <v>LogDir = string()</v> @@ -576,6 +576,9 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} <v>LogName = string()</v> <v>LogFile = string()</v> <v>Start = Stop = null | calendar:datetime() | {local_time, calendar:datetime()} | {universal_time, calendar:datetime()} </v> + <v>Cnt = {NumOK, NumERR}</v> + <v>NumOK = non_neg_integer()</v> + <v>NumERR = pos_integer()</v> <v>Reason = disk_log_open_error() | file_open_error() | term()</v> <v>disk_log_open_error() = {LogName, term()}</v> <v>file_open_error() = {OutFile, term()}</v> @@ -597,14 +600,14 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>log_to_io(LogDir) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Block | Mibs) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, Block | LogName) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, Block | LogFile) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start, Stop) -> ok | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Block | Mibs) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, Block | LogName) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, Block | LogFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R16B03">log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> <fsummary>Convert an Audit Trail Log to text format</fsummary> <type> <v>LogDir = string()</v> @@ -614,6 +617,9 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} <v>LogName = string()</v> <v>LogFile = string()</v> <v>Start = Stop = null | calendar:datetime() | {local_time, calendar:datetime()} | {universal_time, calendar:datetime()} </v> + <v>Cnt = {NumOK, NumERR}</v> + <v>NumOK = non_neg_integer()</v> + <v>NumERR = pos_integer()</v> <v>Reason = disk_log_open_error() | file_open_error() | term()</v> <v>disk_log_open_error() = {LogName, term()}</v> <v>file_open_error() = {OutFile, term()}</v> @@ -635,7 +641,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>change_log_size(NewSize) -> ok | {error, Reason}</name> + <name since="">change_log_size(NewSize) -> ok | {error, Reason}</name> <fsummary>Change the size of the Audit Trail Log</fsummary> <type> <v>NewSize = {MaxBytes, MaxFiles}</v> @@ -656,8 +662,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>set_log_type(NewType) -> {ok, OldType} | {error, Reason}</name> - <name>set_log_type(Agent, NewType) -> {ok, OldType} | {error, Reason}</name> + <name since="">set_log_type(NewType) -> {ok, OldType} | {error, Reason}</name> + <name since="">set_log_type(Agent, NewType) -> {ok, OldType} | {error, Reason}</name> <fsummary>Change the type of the Audit Trail Log</fsummary> <type> <v>NewType = OldType = atl_type()</v> @@ -678,8 +684,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>mib_of(Oid) -> {ok, MibName} | {error, Reason}</name> - <name>mib_of(Agent, Oid) -> {ok, MibName} | {error, Reason}</name> + <name since="">mib_of(Oid) -> {ok, MibName} | {error, Reason}</name> + <name since="">mib_of(Agent, Oid) -> {ok, MibName} | {error, Reason}</name> <fsummary>Which mib an Oid belongs to</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -698,8 +704,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>me_of(Oid) -> {ok, Me} | {error, Reason}</name> - <name>me_of(Agent, Oid) -> {ok, Me} | {error, Reason}</name> + <name since="">me_of(Oid) -> {ok, Me} | {error, Reason}</name> + <name since="">me_of(Agent, Oid) -> {ok, Me} | {error, Reason}</name> <fsummary>Retrieve the mib-entry of an Oid</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -718,8 +724,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>invalidate_mibs_cache() -> void()</name> - <name>invalidate_mibs_cache(Agent) -> void()</name> + <name since="">invalidate_mibs_cache() -> void()</name> + <name since="">invalidate_mibs_cache(Agent) -> void()</name> <fsummary>Invalidate the mib server cache</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -733,8 +739,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>enable_mibs_cache() -> void()</name> - <name>enable_mibs_cache(Agent) -> void()</name> + <name since="">enable_mibs_cache() -> void()</name> + <name since="">enable_mibs_cache(Agent) -> void()</name> <fsummary>Enable the mib server cache</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -747,8 +753,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>disable_mibs_cache() -> void()</name> - <name>disable_mibs_cache(Agent) -> void()</name> + <name since="">disable_mibs_cache() -> void()</name> + <name since="">disable_mibs_cache(Agent) -> void()</name> <fsummary>Disable the mib server cache</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -761,8 +767,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_mibs_cache_size() -> void()</name> - <name>which_mibs_cache_size(Agent) -> void()</name> + <name since="OTP R14B">which_mibs_cache_size() -> void()</name> + <name since="OTP R14B">which_mibs_cache_size(Agent) -> void()</name> <fsummary>The size of the mib server cache</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -775,12 +781,12 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>gc_mibs_cache() -> {ok, NumElementsGCed} | {error, Reason}</name> - <name>gc_mibs_cache(Agent) -> {ok, NumElementsGCed} | {error, Reason}</name> - <name>gc_mibs_cache(Age) -> {ok, NumElementsGCed} | {error, Reason}</name> - <name>gc_mibs_cache(Agent, Age) -> {ok, NumElementsGCed} | {error, Reason}</name> - <name>gc_mibs_cache(Age, GcLimit) -> {ok, NumElementsGCed} | {error, Reason}</name> - <name>gc_mibs_cache(Agent, Age, GcLimit) -> {ok, NumElementsGCed} | {error, Reason}</name> + <name since="">gc_mibs_cache() -> {ok, NumElementsGCed} | {error, Reason}</name> + <name since="">gc_mibs_cache(Agent) -> {ok, NumElementsGCed} | {error, Reason}</name> + <name since="">gc_mibs_cache(Age) -> {ok, NumElementsGCed} | {error, Reason}</name> + <name since="">gc_mibs_cache(Agent, Age) -> {ok, NumElementsGCed} | {error, Reason}</name> + <name since="">gc_mibs_cache(Age, GcLimit) -> {ok, NumElementsGCed} | {error, Reason}</name> + <name since="">gc_mibs_cache(Agent, Age, GcLimit) -> {ok, NumElementsGCed} | {error, Reason}</name> <fsummary>Perform mib server cache gc</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -802,8 +808,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>enable_mibs_cache_autogc() -> void()</name> - <name>enable_mibs_cache_autogc(Agent) -> void()</name> + <name since="">enable_mibs_cache_autogc() -> void()</name> + <name since="">enable_mibs_cache_autogc(Agent) -> void()</name> <fsummary>Enable automatic gc of the mib server cache</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -816,8 +822,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>disable_mibs_cache_autogc() -> void()</name> - <name>disable_mibs_cache_autogc(Agent) -> void()</name> + <name since="">disable_mibs_cache_autogc() -> void()</name> + <name since="">disable_mibs_cache_autogc(Agent) -> void()</name> <fsummary>Disable automatic gc of the mib server cache</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -830,8 +836,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>update_mibs_cache_age(NewAge) -> ok | {error, Reason}</name> - <name>update_mibs_cache_age(Agent, NewAge) -> ok | {error, Reason}</name> + <name since="">update_mibs_cache_age(NewAge) -> ok | {error, Reason}</name> + <name since="">update_mibs_cache_age(Agent, NewAge) -> ok | {error, Reason}</name> <fsummary>Change the mib server cache age property</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -846,8 +852,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>update_mibs_cache_gclimit(NewGcLimit) -> ok | {error, Reason}</name> - <name>update_mibs_cache_gclimit(Agent, NewGCLimit) -> ok | {error, Reason}</name> + <name since="">update_mibs_cache_gclimit(NewGcLimit) -> ok | {error, Reason}</name> + <name since="">update_mibs_cache_gclimit(Agent, NewGCLimit) -> ok | {error, Reason}</name> <fsummary>Change the mib server cache gclimit property</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -863,10 +869,10 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} <func> - <name>register_notification_filter(Id, Mod, Data) -> ok | {error, Reason}</name> - <name>register_notification_filter(Agent, Id, Mod, Data) -> ok | {error, Reason}</name> - <name>register_notification_filter(Id, Mod, Data, Where) -> ok | {error, Reason}</name> - <name>register_notification_filter(Agent, Id, Mod, Data, Where) -> ok | {error, Reason}</name> + <name since="">register_notification_filter(Id, Mod, Data) -> ok | {error, Reason}</name> + <name since="">register_notification_filter(Agent, Id, Mod, Data) -> ok | {error, Reason}</name> + <name since="">register_notification_filter(Id, Mod, Data, Where) -> ok | {error, Reason}</name> + <name since="">register_notification_filter(Agent, Id, Mod, Data, Where) -> ok | {error, Reason}</name> <fsummary>Register a notification filter</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -891,8 +897,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>unregister_notification_filter(Id) -> ok | {error, Reason}</name> - <name>unregister_notification_filter(Agent, Id) -> ok | {error, Reason}</name> + <name since="">unregister_notification_filter(Id) -> ok | {error, Reason}</name> + <name since="">unregister_notification_filter(Agent, Id) -> ok | {error, Reason}</name> <fsummary>Unregister a notification filter</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -907,8 +913,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>which_notification_filter() -> Filters</name> - <name>which_notification_filter(Agent) -> Filters</name> + <name since="">which_notification_filter() -> Filters</name> + <name since="">which_notification_filter(Agent) -> Filters</name> <fsummary>Which notification filter</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -923,8 +929,8 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>set_request_limit(NewLimit) -> {ok, OldLimit} | {error, Reason}</name> - <name>set_request_limit(Agent, NewLimit) -> {ok, OldLimit} | {error, Reason}</name> + <name since="">set_request_limit(NewLimit) -> {ok, OldLimit} | {error, Reason}</name> + <name since="">set_request_limit(Agent, NewLimit) -> {ok, OldLimit} | {error, Reason}</name> <fsummary>Change the request limit</fsummary> <type> <v>NewLimit = OldLimit = infinity | integer() >= 0</v> @@ -944,7 +950,7 @@ notification_delivery_info() = #snmpa_notification_delivery_info{} </func> <func> - <name>register_subagent(Agent, SubTreeOid, Subagent) -> ok | {error, Reason}</name> + <name since="">register_subagent(Agent, SubTreeOid, Subagent) -> ok | {error, Reason}</name> <fsummary>Register a sub-agent under a sub-tree</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -969,7 +975,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>unregister_subagent(Agent, SubagentOidOrPid) -> ok | {ok, SubAgentPid} | {error, Reason}</name> + <name since="">unregister_subagent(Agent, SubagentOidOrPid) -> ok | {ok, SubAgentPid} | {error, Reason}</name> <fsummary>Unregister a sub-agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -986,7 +992,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). <func> - <name>send_notification2(Agent, Notification, SendOpts) -> void()</name> + <name since="OTP R14B03">send_notification2(Agent, Notification, SendOpts) -> void()</name> <fsummary>Send notification</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -1113,11 +1119,11 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). <func> - <name>send_notification(Agent, Notification, Receiver)</name> - <name>send_notification(Agent, Notification, Receiver, Varbinds)</name> - <name>send_notification(Agent, Notification, Receiver, NotifyName, Varbinds)</name> - <name>send_notification(Agent, Notification, Receiver, NotifyName, ContextName, Varbinds) -> void() </name> - <name>send_notification(Agent, Notification, Receiver, NotifyName, ContextName, Varbinds, LocalEngineID) -> void() </name> + <name since="">send_notification(Agent, Notification, Receiver)</name> + <name since="">send_notification(Agent, Notification, Receiver, Varbinds)</name> + <name since="">send_notification(Agent, Notification, Receiver, NotifyName, Varbinds)</name> + <name since="">send_notification(Agent, Notification, Receiver, NotifyName, ContextName, Varbinds) -> void() </name> + <name since="OTP R14B">send_notification(Agent, Notification, Receiver, NotifyName, ContextName, Varbinds, LocalEngineID) -> void() </name> <fsummary>Send a notification</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -1318,13 +1324,13 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). <func> - <name>discovery(TargetName, Notification) -> {ok, ManagerEngineID} | {error, Reason}</name> - <name>discovery(TargetName, Notification, Varbinds) -> {ok, ManagerEngineID} | {error, Reason}</name> - <name>discovery(TargetName, Notification, DiscoHandler) -> {ok, ManagerEngineID} | {error, Reason}</name> - <name>discovery(TargetName, Notification, ContextName, Varbinds) -> {ok, ManagerEngineID} | {error, Reason}</name> - <name>discovery(TargetName, Notification, Varbinds, DiscoHandler) -> {ok, ManagerEngineID} | {error, Reason}</name> - <name>discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler) -> {ok, ManagerEngineID} | {error, Reason}</name> - <name>discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler, ExtraInfo) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification, Varbinds) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification, DiscoHandler) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification, ContextName, Varbinds) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification, Varbinds, DiscoHandler) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler) -> {ok, ManagerEngineID} | {error, Reason}</name> + <name since="">discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler, ExtraInfo) -> {ok, ManagerEngineID} | {error, Reason}</name> <fsummary>Initiate the discovery process with a manager</fsummary> <type> <v>TargetName = string()</v> @@ -1373,7 +1379,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>convert_config(OldConfig) -> AgentConfig</name> + <name since="">convert_config(OldConfig) -> AgentConfig</name> <fsummary>Convert old snmp config to new agent config</fsummary> <type> <v>OldConfig = list()</v> @@ -1397,8 +1403,8 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>restart_worker() -> void()</name> - <name>restart_worker(Agent) -> void()</name> + <name since="">restart_worker() -> void()</name> + <name since="">restart_worker(Agent) -> void()</name> <fsummary>Restart the worker process of a multi-threaded agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -1413,8 +1419,8 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>restart_set_worker() -> void()</name> - <name>restart_set_worker(Agent) -> void()</name> + <name since="">restart_set_worker() -> void()</name> + <name since="">restart_set_worker(Agent) -> void()</name> <fsummary>Restart the set worker process of a multi-threaded agent</fsummary> <type> <v>Agent = pid() | atom()</v> @@ -1429,7 +1435,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>print_mib_info() -> void()</name> + <name since="OTP R14B02">print_mib_info() -> void()</name> <fsummary>Print mib info</fsummary> <desc> <p>Prints the content of all the (snmp) tables and variables @@ -1440,7 +1446,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>print_mib_tables() -> void()</name> + <name since="OTP R14B02">print_mib_tables() -> void()</name> <fsummary>Print mib tables</fsummary> <desc> <p>Prints the content of all the (snmp) tables @@ -1451,7 +1457,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>print_mib_variables() -> void()</name> + <name since="OTP R14B02">print_mib_variables() -> void()</name> <fsummary>Print mib variables</fsummary> <desc> <p>Prints the content of all the (snmp) variables @@ -1462,7 +1468,7 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </func> <func> - <name>verbosity(Ref,Verbosity) -> void()</name> + <name since="">verbosity(Ref,Verbosity) -> void()</name> <fsummary>Assign a new verbosity for the process</fsummary> <type> <v>Ref = pid() | sub_agents | master_agent | net_if | mib_server | symbolic_store | note_store | local_db</v> diff --git a/lib/snmp/doc/src/snmpa_conf.xml b/lib/snmp/doc/src/snmpa_conf.xml index 503e44a6a2..4134a81c0c 100644 --- a/lib/snmp/doc/src/snmpa_conf.xml +++ b/lib/snmp/doc/src/snmpa_conf.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_conf.xml</file> </header> - <module>snmpa_conf</module> + <module since="">snmpa_conf</module> <modulesummary>Utility functions for handling the agent config files.</modulesummary> <description> <p>The module <c>snmpa_conf</c> contains various utility functions to @@ -92,7 +92,7 @@ word() = 0..65535 <funcs> <func> - <name>agent_entry(Tag, Val) -> agent_entry()</name> + <name since="">agent_entry(Tag, Val) -> agent_entry()</name> <fsummary>Create an agent entry</fsummary> <type> <v>Tag = intAgentTransports | intAgentUDPPort | intAgentMaxPacketSize | snmpEngineMaxMessageSize | snmpEngineID</v> @@ -111,8 +111,8 @@ word() = 0..65535 </func> <func> - <name>write_agent_config(Dir, Conf) -> ok</name> - <name>write_agent_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_agent_config(Dir, Conf) -> ok</name> + <name since="">write_agent_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -134,7 +134,7 @@ word() = 0..65535 </func> <func> - <name>append_agent_config(Dir, Conf) -> ok</name> + <name since="">append_agent_config(Dir, Conf) -> ok</name> <fsummary>Append the agent config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -153,7 +153,7 @@ word() = 0..65535 </func> <func> - <name>read_agent_config(Dir) -> Conf</name> + <name since="">read_agent_config(Dir) -> Conf</name> <fsummary>Read the agent config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -172,7 +172,7 @@ word() = 0..65535 </func> <func> - <name>standard_entry(Tag, Val) -> standard_entry()</name> + <name since="">standard_entry(Tag, Val) -> standard_entry()</name> <fsummary>Create an standard entry</fsummary> <type> <v>Tag = sysDescr | sysObjectID | sysContact | sysName | sysLocation | sysServices | snmpEnableAuthenTraps</v> @@ -192,8 +192,8 @@ word() = 0..65535 </func> <func> - <name>write_standard_config(Dir, Conf) -> ok</name> - <name>write_standard_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_standard_config(Dir, Conf) -> ok</name> + <name since="">write_standard_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent standard config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -216,7 +216,7 @@ word() = 0..65535 </func> <func> - <name>append_standard_config(Dir, Conf) -> ok</name> + <name since="">append_standard_config(Dir, Conf) -> ok</name> <fsummary>Append the agent standard config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -236,7 +236,7 @@ word() = 0..65535 </func> <func> - <name>read_standard_config(Dir) -> Conf</name> + <name since="">read_standard_config(Dir) -> Conf</name> <fsummary>Read the agent standard config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -255,7 +255,7 @@ word() = 0..65535 </func> <func> - <name>context_entry(Context) -> context_entry()</name> + <name since="">context_entry(Context) -> context_entry()</name> <fsummary>Create an context entry</fsummary> <type> <v>Context = string()</v> @@ -273,8 +273,8 @@ word() = 0..65535 </func> <func> - <name>write_context_config(Dir, Conf) -> ok</name> - <name>write_context_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_context_config(Dir, Conf) -> ok</name> + <name since="">write_context_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent context(s) to the config file</fsummary> <type> <v>Dir = string()</v> @@ -297,7 +297,7 @@ word() = 0..65535 </func> <func> - <name>append_context_config(Dir, Conf) -> ok</name> + <name since="">append_context_config(Dir, Conf) -> ok</name> <fsummary>Append the agent context(s) to the config file</fsummary> <type> <v>Dir = string()</v> @@ -317,7 +317,7 @@ word() = 0..65535 </func> <func> - <name>read_context_config(Dir) -> Conf</name> + <name since="">read_context_config(Dir) -> Conf</name> <fsummary>Read the agent context config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -336,8 +336,8 @@ word() = 0..65535 </func> <func> - <name>community_entry(CommunityIndex) -> community_entry()</name> - <name>community_entry(CommunityIndex, CommunityName, SecName, ContextName, TransportTag) -> community_entry()</name> + <name since="">community_entry(CommunityIndex) -> community_entry()</name> + <name since="">community_entry(CommunityIndex, CommunityName, SecName, ContextName, TransportTag) -> community_entry()</name> <fsummary>Create an community entry</fsummary> <type> <v>CommunityIndex = string()</v> @@ -364,8 +364,8 @@ word() = 0..65535 </func> <func> - <name>write_community_config(Dir, Conf) -> ok</name> - <name>write_community_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_community_config(Dir, Conf) -> ok</name> + <name since="">write_community_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent community config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -388,7 +388,7 @@ word() = 0..65535 </func> <func> - <name>append_community_config(Dir, Conf) -> ok</name> + <name since="">append_community_config(Dir, Conf) -> ok</name> <fsummary>Append the agent community config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -408,7 +408,7 @@ word() = 0..65535 </func> <func> - <name>read_community_config(Dir) -> Conf</name> + <name since="">read_community_config(Dir) -> Conf</name> <fsummary>Read the agent community config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -427,10 +427,10 @@ word() = 0..65535 </func> <func> - <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId) -> target_addr_entry()</name> - <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask) -> target_addr_entry()</name> - <name>target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> - <name>target_addr_entry(Name, Domain, Addr, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> + <name since="">target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId) -> target_addr_entry()</name> + <name since="OTP 17.3">target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask) -> target_addr_entry()</name> + <name since="">target_addr_entry(Name, Domain, Addr, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> + <name since="">target_addr_entry(Name, Domain, Addr, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> <fsummary>Create an target_addr entry</fsummary> <type> <v>Name = string()</v> @@ -464,8 +464,8 @@ word() = 0..65535 </func> <func> - <name>write_target_addr_config(Dir, Conf) -> ok</name> - <name>write_target_addr_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_target_addr_config(Dir, Conf) -> ok</name> + <name since="">write_target_addr_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent target_addr config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -488,7 +488,7 @@ word() = 0..65535 </func> <func> - <name>append_target_addr_config(Dir, Conf) -> ok</name> + <name since="">append_target_addr_config(Dir, Conf) -> ok</name> <fsummary>Append the agent target_addr config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -508,7 +508,7 @@ word() = 0..65535 </func> <func> - <name>read_target_addr_config(Dir) -> Conf</name> + <name since="">read_target_addr_config(Dir) -> Conf</name> <fsummary>Read the agent target_addr config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -527,9 +527,9 @@ word() = 0..65535 </func> <func> - <name>target_params_entry(Name, Vsn) -> target_params_entry()</name> - <name>target_params_entry(Name, Vsn, SecName, SecLevel) -> target_params_entry()</name> - <name>target_params_entry(Name, MPModel, SecModel, SecName, SecLevel) -> target_params_entry()</name> + <name since="">target_params_entry(Name, Vsn) -> target_params_entry()</name> + <name since="">target_params_entry(Name, Vsn, SecName, SecLevel) -> target_params_entry()</name> + <name since="">target_params_entry(Name, MPModel, SecModel, SecName, SecLevel) -> target_params_entry()</name> <fsummary>Create an target_params entry</fsummary> <type> <v>Name = string()</v> @@ -564,8 +564,8 @@ word() = 0..65535 </func> <func> - <name>write_target_params_config(Dir, Conf) -> ok</name> - <name>write_target_params_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_target_params_config(Dir, Conf) -> ok</name> + <name since="">write_target_params_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent target_params config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -588,7 +588,7 @@ word() = 0..65535 </func> <func> - <name>append_target_params_config(Dir, Conf) -> ok</name> + <name since="">append_target_params_config(Dir, Conf) -> ok</name> <fsummary>Append the agent target_params config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -608,7 +608,7 @@ word() = 0..65535 </func> <func> - <name>read_target_params_config(Dir) -> Conf</name> + <name since="">read_target_params_config(Dir) -> Conf</name> <fsummary>Read the agent target_params config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -627,10 +627,10 @@ word() = 0..65535 </func> <func> - <name>vacm_s2g_entry(SecModel, SecName, GroupName) -> vacm_s2g_entry()</name> - <name>vacm_acc_entry(GroupName, Prefix, SecModel, SecLevel, Match, ReadView, WriteView, NotifyView) -> vacm_acc_entry()</name> - <name>vacm_vtf_entry(ViewIndex, ViewSubtree) -> vacm_vtf_entry()</name> - <name>vacm_vtf_entry(ViewIndex, ViewSubtree, ViewStatus, ViewMask) -> vacm_vtf_entry()</name> + <name since="">vacm_s2g_entry(SecModel, SecName, GroupName) -> vacm_s2g_entry()</name> + <name since="">vacm_acc_entry(GroupName, Prefix, SecModel, SecLevel, Match, ReadView, WriteView, NotifyView) -> vacm_acc_entry()</name> + <name since="">vacm_vtf_entry(ViewIndex, ViewSubtree) -> vacm_vtf_entry()</name> + <name since="">vacm_vtf_entry(ViewIndex, ViewSubtree, ViewStatus, ViewMask) -> vacm_vtf_entry()</name> <fsummary>Create an vacm entry</fsummary> <type> <v>SecModel = v1 | v2c | usm</v> @@ -665,8 +665,8 @@ word() = 0..65535 </func> <func> - <name>write_vacm_config(Dir, Conf) -> ok</name> - <name>write_vacm_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_vacm_config(Dir, Conf) -> ok</name> + <name since="">write_vacm_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent vacm config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -690,7 +690,7 @@ word() = 0..65535 </func> <func> - <name>append_vacm_config(Dir, Conf) -> ok</name> + <name since="">append_vacm_config(Dir, Conf) -> ok</name> <fsummary>Append the agent vacm config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -710,7 +710,7 @@ word() = 0..65535 </func> <func> - <name>read_vacm_config(Dir) -> Conf</name> + <name since="">read_vacm_config(Dir) -> Conf</name> <fsummary>Read the agent vacm config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -729,8 +729,8 @@ word() = 0..65535 </func> <func> - <name>usm_entry(EngineId) -> usm_entry()</name> - <name>usm_entry(EngineID, UserName, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC, PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey) -> usm_entry()</name> + <name since="">usm_entry(EngineId) -> usm_entry()</name> + <name since="">usm_entry(EngineID, UserName, SecName, Clone, AuthP, AuthKeyC, OwnAuthKeyC, PrivP, PrivKeyC, OwnPrivKeyC, Public, AuthKey, PrivKey) -> usm_entry()</name> <fsummary>Create an usm entry</fsummary> <type> <v>EngineId = string()</v> @@ -762,8 +762,8 @@ word() = 0..65535 </func> <func> - <name>write_usm_config(Dir, Conf) -> ok</name> - <name>write_usm_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_usm_config(Dir, Conf) -> ok</name> + <name since="">write_usm_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent usm config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -786,7 +786,7 @@ word() = 0..65535 </func> <func> - <name>append_usm_config(Dir, Conf) -> ok</name> + <name since="">append_usm_config(Dir, Conf) -> ok</name> <fsummary>Append the agent usm config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -805,7 +805,7 @@ word() = 0..65535 </func> <func> - <name>read_usm_config(Dir) -> Conf</name> + <name since="">read_usm_config(Dir) -> Conf</name> <fsummary>Read the agent usm config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -824,7 +824,7 @@ word() = 0..65535 </func> <func> - <name>notify_entry(Name, Tag, Type) -> notify_entry()</name> + <name since="">notify_entry(Name, Tag, Type) -> notify_entry()</name> <fsummary>Create an notify entry</fsummary> <type> <v>Name = string()</v> @@ -845,8 +845,8 @@ word() = 0..65535 </func> <func> - <name>write_notify_config(Dir, Conf) -> ok</name> - <name>write_notify_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_notify_config(Dir, Conf) -> ok</name> + <name since="">write_notify_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the agent notify config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -869,7 +869,7 @@ word() = 0..65535 </func> <func> - <name>append_notify_config(Dir, Conf) -> ok</name> + <name since="">append_notify_config(Dir, Conf) -> ok</name> <fsummary>Append the agent notify config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -889,7 +889,7 @@ word() = 0..65535 </func> <func> - <name>read_notify_config(Dir) -> Conf</name> + <name since="">read_notify_config(Dir) -> Conf</name> <fsummary>Read the agent notify config from the config file</fsummary> <type> <v>Dir = string()</v> diff --git a/lib/snmp/doc/src/snmpa_discovery_handler.xml b/lib/snmp/doc/src/snmpa_discovery_handler.xml index 0ea72a880c..21b8746c11 100644 --- a/lib/snmp/doc/src/snmpa_discovery_handler.xml +++ b/lib/snmp/doc/src/snmpa_discovery_handler.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_discovery_handler.xml</file> </header> - <module>snmpa_discovery_handler</module> + <module since="">snmpa_discovery_handler</module> <modulesummary>Behaviour module for the SNMP agent discovery handler.</modulesummary> <description> <p>This module defines the behaviour of the agent discovery @@ -51,7 +51,7 @@ <funcs> <func> - <name>stage1_finish(TargetName, ManagerEngineID, ExtraInfo) -> ignore | {ok, usm_entry() | [usm_entry()]} | {ok, usm_entry() | [usm_entry()], NewExtraInfo}</name> + <name since="">stage1_finish(TargetName, ManagerEngineID, ExtraInfo) -> ignore | {ok, usm_entry() | [usm_entry()]} | {ok, usm_entry() | [usm_entry()], NewExtraInfo}</name> <fsummary>Discovery stage 1 finish</fsummary> <type> <v>TargetName = string()</v> diff --git a/lib/snmp/doc/src/snmpa_error.xml b/lib/snmp/doc/src/snmpa_error.xml index 7cc4a3513d..6e6761b7a5 100644 --- a/lib/snmp/doc/src/snmpa_error.xml +++ b/lib/snmp/doc/src/snmpa_error.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_error.xml</file> </header> - <module>snmpa_error</module> + <module since="">snmpa_error</module> <modulesummary>Functions for Reporting SNMP Errors</modulesummary> <description> <marker id="desc"></marker> @@ -57,7 +57,7 @@ </description> <funcs> <func> - <name>config_err(Format, Args) -> void()</name> + <name since="">config_err(Format, Args) -> void()</name> <fsummary>Called if a configuration error occurs</fsummary> <type> <v>Format = string()</v> @@ -76,7 +76,7 @@ </func> <func> - <name>user_err(Format, Args) -> void()</name> + <name since="">user_err(Format, Args) -> void()</name> <fsummary>Called if a user related error occurs</fsummary> <type> <v>Format = string()</v> diff --git a/lib/snmp/doc/src/snmpa_error_io.xml b/lib/snmp/doc/src/snmpa_error_io.xml index bcb2688646..d78e09ff13 100644 --- a/lib/snmp/doc/src/snmpa_error_io.xml +++ b/lib/snmp/doc/src/snmpa_error_io.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_error_io.xml</file> </header> - <module>snmpa_error_io</module> + <module since="">snmpa_error_io</module> <modulesummary>Functions for Reporting SNMP Errors on stdio</modulesummary> <description> <p>The module <c>snmpa_error_io</c> implements the @@ -52,7 +52,7 @@ </description> <funcs> <func> - <name>config_err(Format, Args) -> void()</name> + <name since="">config_err(Format, Args) -> void()</name> <fsummary>Called if a configuration error occurs</fsummary> <type> <v>Format = string()</v> @@ -68,7 +68,7 @@ </desc> </func> <func> - <name>user_err(Format, Args) -> void()</name> + <name since="">user_err(Format, Args) -> void()</name> <fsummary>Called if a user related error occurs</fsummary> <type> <v>Format = string()</v> diff --git a/lib/snmp/doc/src/snmpa_error_logger.xml b/lib/snmp/doc/src/snmpa_error_logger.xml index 4feb2e7f32..b0565a6839 100644 --- a/lib/snmp/doc/src/snmpa_error_logger.xml +++ b/lib/snmp/doc/src/snmpa_error_logger.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_error_logger.xml</file> </header> - <module>snmpa_error_logger</module> + <module since="">snmpa_error_logger</module> <modulesummary>Functions for Reporting SNMP Errors through the error_logger</modulesummary> <description> <p>The module <c>snmpa_error_logger</c> implements the @@ -54,7 +54,7 @@ </description> <funcs> <func> - <name>config_err(Format, Args) -> void()</name> + <name since="">config_err(Format, Args) -> void()</name> <fsummary>Called if a configuration error occurs</fsummary> <type> <v>Format = string()</v> @@ -70,7 +70,7 @@ </desc> </func> <func> - <name>user_err(Format, Args) -> void()</name> + <name since="">user_err(Format, Args) -> void()</name> <fsummary>Called if a user related error occurs</fsummary> <type> <v>Format = string()</v> diff --git a/lib/snmp/doc/src/snmpa_error_report.xml b/lib/snmp/doc/src/snmpa_error_report.xml index 282d9b4e59..f08dc1df23 100644 --- a/lib/snmp/doc/src/snmpa_error_report.xml +++ b/lib/snmp/doc/src/snmpa_error_report.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_error_report.xml</file> </header> - <module>snmpa_error_report</module> + <module since="">snmpa_error_report</module> <modulesummary>Behaviour module for reporting SNMP agent errors</modulesummary> <description> <marker id="desc"></marker> @@ -52,7 +52,7 @@ </description> <funcs> <func> - <name>config_err(Format, Args) -> void()</name> + <name since="">config_err(Format, Args) -> void()</name> <fsummary>Called if a configuration error occurs</fsummary> <type> <v>Format = string()</v> @@ -68,7 +68,7 @@ </desc> </func> <func> - <name>user_err(Format, Args) -> void()</name> + <name since="">user_err(Format, Args) -> void()</name> <fsummary>Called if a user related error occurs</fsummary> <type> <v>Format = string()</v> diff --git a/lib/snmp/doc/src/snmpa_local_db.xml b/lib/snmp/doc/src/snmpa_local_db.xml index ac8d466ab3..229f22ab70 100644 --- a/lib/snmp/doc/src/snmpa_local_db.xml +++ b/lib/snmp/doc/src/snmpa_local_db.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_local_db.xml</file> </header> - <module>snmpa_local_db</module> + <module since="">snmpa_local_db</module> <modulesummary>The SNMP built-in database</modulesummary> <description> <p>The module <c>snmpa_local_db</c> contains functions for @@ -86,7 +86,7 @@ </section> <funcs> <func> - <name>dump() -> ok | {error, Reason}</name> + <name since="">dump() -> ok | {error, Reason}</name> <fsummary>Dump the database to disk</fsummary> <type> <v>Reason = term()</v> @@ -97,7 +97,7 @@ </desc> </func> <func> - <name>match(NameDb, Pattern)</name> + <name since="">match(NameDb, Pattern)</name> <fsummary>Perform a match on the table</fsummary> <desc> <p>Performs an ets/dets matching on the table. @@ -106,9 +106,9 @@ </desc> </func> <func> - <name>print()</name> - <name>print(TableName)</name> - <name>print(TableName, Db)</name> + <name since="">print()</name> + <name since="">print(TableName)</name> + <name since="">print(TableName, Db)</name> <fsummary>Print the database to screen</fsummary> <type> <v>TableName = atom()</v> @@ -124,7 +124,7 @@ </desc> </func> <func> - <name>table_create(NameDb) -> bool()</name> + <name since="">table_create(NameDb) -> bool()</name> <fsummary>Create a table</fsummary> <desc> <p>Creates a table. If the table already exist, the old copy @@ -135,7 +135,7 @@ </desc> </func> <func> - <name>table_create_row(NameDb, RowIndex, Row) -> bool()</name> + <name since="">table_create_row(NameDb, RowIndex, Row) -> bool()</name> <fsummary>Create a row in a table</fsummary> <type> <v>Row = {Val1, Val2, ..., ValN}</v> @@ -147,28 +147,28 @@ </desc> </func> <func> - <name>table_delete(NameDb) -> void()</name> + <name since="">table_delete(NameDb) -> void()</name> <fsummary>Delete a table</fsummary> <desc> <p>Deletes a table.</p> </desc> </func> <func> - <name>table_delete_row(NameDb, RowIndex) -> bool()</name> + <name since="">table_delete_row(NameDb, RowIndex) -> bool()</name> <fsummary>Delete the row in the table</fsummary> <desc> <p>Deletes the row in the table.</p> </desc> </func> <func> - <name>table_exists(NameDb) -> bool()</name> + <name since="">table_exists(NameDb) -> bool()</name> <fsummary>Check if a table exists</fsummary> <desc> <p>Checks if a table exists.</p> </desc> </func> <func> - <name>table_get_row(NameDb, RowIndex) -> Row | undefined</name> + <name since="">table_get_row(NameDb, RowIndex) -> Row | undefined</name> <fsummary>Get a row from the table</fsummary> <type> <v>Row = {Val1, Val2, ..., ValN}</v> diff --git a/lib/snmp/doc/src/snmpa_mib_data.xml b/lib/snmp/doc/src/snmpa_mib_data.xml index 1a73c9b634..b849a2826a 100644 --- a/lib/snmp/doc/src/snmpa_mib_data.xml +++ b/lib/snmp/doc/src/snmpa_mib_data.xml @@ -30,7 +30,7 @@ <file>snmpa_mib_data.xml</file> </header> - <module>snmpa_mib_data</module> + <module since="OTP R16B01">snmpa_mib_data</module> <modulesummary>Behaviour module for the SNMP agent mib-server data module.</modulesummary> <description> @@ -108,7 +108,7 @@ <funcs> <func> - <name>Module:new(Storage) -> State</name> + <name since="OTP R16B01">Module:new(Storage) -> State</name> <fsummary>Create new (mib-server) data instance</fsummary> <type> <v>Storage = mib_storage()</v> @@ -122,7 +122,7 @@ </func> <func> - <name>Module:close(State) -> void()</name> + <name since="OTP R16B01">Module:close(State) -> void()</name> <fsummary>Close the mib-server data instance</fsummary> <type> <v>State = term()</v> @@ -135,7 +135,7 @@ </func> <func> - <name>Module:sync(State) -> void()</name> + <name since="OTP R16B01">Module:sync(State) -> void()</name> <fsummary>Synchronize to disc</fsummary> <type> <v>State = term()</v> @@ -151,7 +151,7 @@ </func> <func> - <name>Module:load_mib(State, Filename, MeOverride, TeOverride) -> {ok, NewState} | {error, Reason}</name> + <name since="OTP R16B01">Module:load_mib(State, Filename, MeOverride, TeOverride) -> {ok, NewState} | {error, Reason}</name> <fsummary>Load a mib into the mib-server</fsummary> <type> <v>State = NewState = term()</v> @@ -172,7 +172,7 @@ </func> <func> - <name>Module:unload_mib(State, Filename) -> {ok, NewState} | {error, Reason}</name> + <name since="OTP R16B01">Module:unload_mib(State, Filename) -> {ok, NewState} | {error, Reason}</name> <fsummary>Unload mib from the mib-server</fsummary> <type> <v>State = NewState = term()</v> @@ -188,7 +188,7 @@ </func> <func> - <name>Module:lookup(State, Oid) -> Reply</name> + <name since="OTP R16B01">Module:lookup(State, Oid) -> Reply</name> <fsummary>Find the mib-entry corresponding to the Oid</fsummary> <type> <v>State = term()</v> @@ -210,7 +210,7 @@ </func> <func> - <name>Module:next(State, Oid, MibView) -> Reply</name> + <name since="OTP R16B01">Module:next(State, Oid, MibView) -> Reply</name> <fsummary>Finds the lexicographically next oid</fsummary> <type> <v>State = term()</v> @@ -227,7 +227,7 @@ </func> <func> - <name>Module:register_subagent(State, Oid, Pid) -> Reply</name> + <name since="OTP R16B01">Module:register_subagent(State, Oid, Pid) -> Reply</name> <fsummary>Register the subagent</fsummary> <type> <v>State = NewState = term()</v> @@ -245,7 +245,7 @@ </func> <func> - <name>Module:unregister_subagent(State, PidOrOid) -> Reply</name> + <name since="OTP R16B01">Module:unregister_subagent(State, PidOrOid) -> Reply</name> <fsummary>Unregister the subagent</fsummary> <type> <v>State = NewState = term()</v> @@ -266,7 +266,7 @@ </func> <func> - <name>Module:dump(State, Destination) -> Reply</name> + <name since="OTP R16B01">Module:dump(State, Destination) -> Reply</name> <fsummary>Unregister the subagent</fsummary> <type> <v>State = term()</v> @@ -284,7 +284,7 @@ </func> <func> - <name>Module:which_mib(State, Oid) -> Reply</name> + <name since="OTP R16B01">Module:which_mib(State, Oid) -> Reply</name> <fsummary>Retrieve the mib file for an oid()</fsummary> <type> <v>State = term()</v> @@ -301,7 +301,7 @@ </func> <func> - <name>Module:which_mibs(State) -> Reply</name> + <name since="OTP R16B01">Module:which_mibs(State) -> Reply</name> <fsummary>Retrieve all loaded mib files</fsummary> <type> <v>State = term()</v> @@ -317,7 +317,7 @@ </func> <func> - <name>Module:whereis_mib(State, MibName) -> Reply</name> + <name since="OTP R16B01">Module:whereis_mib(State, MibName) -> Reply</name> <fsummary>Retrieve the mib file for the mib</fsummary> <type> <v>State = term()</v> @@ -334,7 +334,7 @@ </func> <func> - <name>Module:info(State) -> Reply</name> + <name since="OTP R16B01">Module:info(State) -> Reply</name> <fsummary>Retrieve misc info for the mib data</fsummary> <type> <v>State = term()</v> @@ -352,7 +352,7 @@ </func> <func> - <name>Module:backup(State, BackupDir) -> Reply</name> + <name since="OTP R16B01">Module:backup(State, BackupDir) -> Reply</name> <fsummary>Perform a backup of the mib-server data</fsummary> <type> <v>State = term()</v> @@ -370,7 +370,7 @@ </func> <func> - <name>Module:code_change(Destination, Vsn, Extra, State) -> NewState</name> + <name since="OTP R16B01">Module:code_change(Destination, Vsn, Extra, State) -> NewState</name> <fsummary>Perform a code-change</fsummary> <type> <v>Destination = up | down</v> diff --git a/lib/snmp/doc/src/snmpa_mib_storage.xml b/lib/snmp/doc/src/snmpa_mib_storage.xml index 58ce2167ec..ee2b009e77 100644 --- a/lib/snmp/doc/src/snmpa_mib_storage.xml +++ b/lib/snmp/doc/src/snmpa_mib_storage.xml @@ -30,7 +30,7 @@ <file>snmpa_mib_storage.xml</file> </header> - <module>snmpa_mib_storage</module> + <module since="OTP R16B01">snmpa_mib_storage</module> <modulesummary> Behaviour module for the SNMP agent mib storage. </modulesummary> @@ -96,7 +96,7 @@ <funcs> <func> - <name>Module:open(Name, RecordName, Fields, Type, Options) -> {ok, TabId} | {error, Reason}</name> + <name since="OTP R16B01">Module:open(Name, RecordName, Fields, Type, Options) -> {ok, TabId} | {error, Reason}</name> <fsummary>Create new (mib-server) data instance</fsummary> <type> <v>Name = atom()</v> @@ -122,7 +122,7 @@ </func> <func> - <name>Module:close(TabId) -> void()</name> + <name since="OTP R16B01">Module:close(TabId) -> void()</name> <fsummary>Close the mib-storage table</fsummary> <type> <v>State = term()</v> @@ -135,7 +135,7 @@ </func> <func> - <name>Module:read(TabId, Key) -> false | {value, Record}</name> + <name since="OTP R16B01">Module:read(TabId, Key) -> false | {value, Record}</name> <fsummary>Read a record from the mib-storage table</fsummary> <type> <v>TabId = term()</v> @@ -150,7 +150,7 @@ </func> <func> - <name>Module:write(TabId, Record) -> ok | {error, Reason}</name> + <name since="OTP R16B01">Module:write(TabId, Record) -> ok | {error, Reason}</name> <fsummary>Write a record to the mib-storage table</fsummary> <type> <v>TabId = term()</v> @@ -165,7 +165,7 @@ </func> <func> - <name>Module:delete(TabId) -> void()</name> + <name since="OTP R16B01">Module:delete(TabId) -> void()</name> <fsummary>Delete an entire mib-storage table</fsummary> <type> <v>TabId = term()</v> @@ -178,7 +178,7 @@ </func> <func> - <name>Module:delete(TabId, Key) -> ok | {error, Reason}</name> + <name since="OTP R16B01">Module:delete(TabId, Key) -> ok | {error, Reason}</name> <fsummary>Delete a record from the mib-storage table</fsummary> <type> <v>TabId = term()</v> @@ -193,7 +193,7 @@ </func> <func> - <name>Module:match_object(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name> + <name since="OTP R16B01">Module:match_object(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name> <fsummary>Search the mib-storage table for record matching pattern</fsummary> <type> <v>TabId = term()</v> @@ -210,7 +210,7 @@ </func> <func> - <name>Module:match_delete(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name> + <name since="OTP R16B01">Module:match_delete(TabId, Pattern) -> {ok, Recs} | {error, Reason}</name> <fsummary>Delete records in the mib-storage table matching pattern</fsummary> <type> <v>TabId = term()</v> @@ -228,7 +228,7 @@ </func> <func> - <name>Module:tab2list(TabId) -> Recs</name> + <name since="OTP R16B01">Module:tab2list(TabId) -> Recs</name> <fsummary>Return all records of the mib-storage table</fsummary> <type> <v>TabId = term()</v> @@ -243,7 +243,7 @@ </func> <func> - <name>Module:info(TabId) -> {ok, Info} | {error, Reason}</name> + <name since="OTP R16B01">Module:info(TabId) -> {ok, Info} | {error, Reason}</name> <fsummary>Returns information about the mib-storage table. </fsummary> <type> <v>TabId = term()</v> @@ -259,7 +259,7 @@ </func> <func> - <name>Module:sync(TabId) -> void()</name> + <name since="OTP R16B01">Module:sync(TabId) -> void()</name> <fsummary>Synchronize mib-storage table</fsummary> <type> <v>TabId = term()</v> @@ -273,7 +273,7 @@ </func> <func> - <name>Module:backup(TabId, BackupDir) -> ok | {error, Reason}</name> + <name since="OTP R16B01">Module:backup(TabId, BackupDir) -> ok | {error, Reason}</name> <fsummary>Perform a backup of the mib-storage table</fsummary> <type> <v>TabId = term()</v> diff --git a/lib/snmp/doc/src/snmpa_mpd.xml b/lib/snmp/doc/src/snmpa_mpd.xml index a39c087c20..d76a9c4a94 100644 --- a/lib/snmp/doc/src/snmpa_mpd.xml +++ b/lib/snmp/doc/src/snmpa_mpd.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_mpd.xml</file> </header> - <module>snmpa_mpd</module> + <module since="">snmpa_mpd</module> <modulesummary>Message Processing and Dispatch module for the SNMP agent</modulesummary> <description> <p>The module <c>snmpa_mpd</c> implements the version independent @@ -52,7 +52,7 @@ <funcs> <func> - <name>init(Vsns) -> mpd_state()</name> + <name since="">init(Vsns) -> mpd_state()</name> <fsummary>Initialize the MPD module</fsummary> <type> <v>Vsns = [Vsn]</v> @@ -70,8 +70,8 @@ </func> <func> - <name>process_packet(Packet, From, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name> - <name>process_packet(Packet, From, LocalEngineID, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name> + <name since="OTP 17.3">process_packet(Packet, From, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name> + <name since="OTP R14B">process_packet(Packet, From, LocalEngineID, State, NoteStore, Log) -> {ok, Vsn, Pdu, PduMS, ACMData} | {discarded, Reason} | {discovery, DiscoPacket}</name> <fsummary>Process a packet received from the network</fsummary> <type> <v>Packet = binary()</v> @@ -108,8 +108,8 @@ </func> <func> - <name>generate_response_msg(Vsn, RePdu, Type, ACMData, Log) -> {ok, Packet} | {discarded, Reason}</name> - <name>generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) -> {ok, Packet} | {discarded, Reason}</name> + <name since="OTP R14B">generate_response_msg(Vsn, RePdu, Type, ACMData, Log) -> {ok, Packet} | {discarded, Reason}</name> + <name since="OTP R14B">generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) -> {ok, Packet} | {discarded, Reason}</name> <fsummary>Generate a response packet to be sent to the network</fsummary> <type> <v>Vsn = 'version-1' | 'version-2' | 'version-3'</v> @@ -136,8 +136,8 @@ </func> <func> - <name>generate_msg(Vsn, NoteStore, Pdu, MsgData, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name> - <name>generate_msg(Vsn, NoteStore, Pdu, MsgData, LocalEngineID, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name> + <name since="OTP R14B">generate_msg(Vsn, NoteStore, Pdu, MsgData, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name> + <name since="OTP R14B">generate_msg(Vsn, NoteStore, Pdu, MsgData, LocalEngineID, To) -> {ok, PacketsAndAddresses} | {discarded, Reason}</name> <fsummary>Generate a request message to be sent to the network</fsummary> <type> <v>Vsn = 'version-1' | 'version-2' | 'version-3'</v> @@ -185,7 +185,7 @@ </func> <func> - <name>process_taddrs(TDests) -> Dests</name> + <name since="OTP 17.3">process_taddrs(TDests) -> Dests</name> <fsummary>Transform addresses from internal MIB format to a less internal </fsummary> <type> @@ -211,7 +211,7 @@ </func> <func> - <name>discarded_pdu(Variable) -> void()</name> + <name since="">discarded_pdu(Variable) -> void()</name> <fsummary>Increment the variable associated with a discarded pdu</fsummary> <type> <v>Variable = atom()</v> diff --git a/lib/snmp/doc/src/snmpa_network_interface.xml b/lib/snmp/doc/src/snmpa_network_interface.xml index d4d4989e90..3e79df11b1 100644 --- a/lib/snmp/doc/src/snmpa_network_interface.xml +++ b/lib/snmp/doc/src/snmpa_network_interface.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_network_interface.xml</file> </header> - <module>snmpa_network_interface</module> + <module since="">snmpa_network_interface</module> <modulesummary>Behaviour module for the SNMP agent network interface.</modulesummary> <description> <p>This module defines the behaviour of the agent network @@ -68,7 +68,7 @@ <funcs> <func> - <name>start_link(Prio, NoteStore, MasterAgent, Opts) -> {ok, Pid} | {error, Reason}</name> + <name since="">start_link(Prio, NoteStore, MasterAgent, Opts) -> {ok, Pid} | {error, Reason}</name> <fsummary>Start-link the network interface process</fsummary> <type> <v>Prio = priority()</v> @@ -93,7 +93,7 @@ </func> <func> - <name>info(Pid) -> [{Key, Value}]</name> + <name since="">info(Pid) -> [{Key, Value}]</name> <fsummary>Return information about the running network interface process</fsummary> <type> <v>Pid = pid()</v> @@ -112,7 +112,7 @@ </func> <func> - <name>verbosity(Pid, Verbosity) -> void()</name> + <name since="">verbosity(Pid, Verbosity) -> void()</name> <fsummary>Change the verbosity of a running network interface process</fsummary> <type> <v>Pid = pid()</v> @@ -126,7 +126,7 @@ </func> <func> - <name>get_log_type(Pid) -> {ok, LogType} | {error, Reason}</name> + <name since="">get_log_type(Pid) -> {ok, LogType} | {error, Reason}</name> <fsummary>Get the Audit Trail Log type</fsummary> <type> <v>Pid = pid()</v> @@ -147,7 +147,7 @@ </func> <func> - <name>set_log_type(Pid, NewType) -> {ok, OldType} | {error, Reason}</name> + <name since="">set_log_type(Pid, NewType) -> {ok, OldType} | {error, Reason}</name> <fsummary>Change the Audit Trail Log type</fsummary> <type> <v>Pid = pid()</v> diff --git a/lib/snmp/doc/src/snmpa_network_interface_filter.xml b/lib/snmp/doc/src/snmpa_network_interface_filter.xml index 7cd08f8935..02c7d291dd 100644 --- a/lib/snmp/doc/src/snmpa_network_interface_filter.xml +++ b/lib/snmp/doc/src/snmpa_network_interface_filter.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_network_interface_filter.xml</file> </header> - <module>snmpa_network_interface_filter</module> + <module since="">snmpa_network_interface_filter</module> <modulesummary>Behaviour module for the SNMP agent network-interface filter.</modulesummary> <description> <p>This module defines the behaviour of the agent network interface @@ -101,7 +101,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </section> <funcs> <func> - <name>accept_recv(Domain, Addr) -> boolean()</name> + <name since="">accept_recv(Domain, Addr) -> boolean()</name> <fsummary>Shall the received message be accepted</fsummary> <type> <v>Domain = transportDomain()</v> @@ -116,7 +116,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </desc> </func> <func> - <name>accept_send(Domain, Addr) -> boolean()</name> + <name since="">accept_send(Domain, Addr) -> boolean()</name> <fsummary>Shall the message be sent</fsummary> <type> <v>Domain = transportDomain()</v> @@ -131,7 +131,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </desc> </func> <func> - <name>accept_recv_pdu(Domain, Addr, PduType) -> boolean()</name> + <name since="">accept_recv_pdu(Domain, Addr, PduType) -> boolean()</name> <fsummary>Shall the received pdu be accepted</fsummary> <type> <v>Domain = transportDomain()</v> @@ -148,7 +148,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </desc> </func> <func> - <name>accept_send_pdu(Targets, PduType) -> Reply</name> + <name since="">accept_send_pdu(Targets, PduType) -> Reply</name> <fsummary>Shall the pdu be sent</fsummary> <type> <v>Targets = targets()</v> diff --git a/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml b/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml index cbae158544..5dad372710 100644 --- a/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml +++ b/lib/snmp/doc/src/snmpa_notification_delivery_info_receiver.xml @@ -34,7 +34,7 @@ <rev></rev> <file>snmpa_notification_delivery_info_receiver.xml</file> </header> - <module>snmpa_notification_delivery_info_receiver</module> + <module since="">snmpa_notification_delivery_info_receiver</module> <modulesummary> Behaviour module for the SNMP agent notification delivery information receiver. @@ -76,7 +76,7 @@ <funcs> <func> - <name>delivery_targets(Tag, Targets, Extra) -> void()</name> + <name since="">delivery_targets(Tag, Targets, Extra) -> void()</name> <fsummary>Inform about target addresses</fsummary> <type> <v>Tag = term()</v> @@ -97,7 +97,7 @@ </func> <func> - <name>delivery_info(Tag, Target, DeliveryResult, Extra) -> void()</name> + <name since="">delivery_info(Tag, Target, DeliveryResult, Extra) -> void()</name> <fsummary>Inform about delivery result</fsummary> <type> <v>Tag = term()</v> diff --git a/lib/snmp/doc/src/snmpa_notification_filter.xml b/lib/snmp/doc/src/snmpa_notification_filter.xml index 0f16ba4440..902412ccc5 100644 --- a/lib/snmp/doc/src/snmpa_notification_filter.xml +++ b/lib/snmp/doc/src/snmpa_notification_filter.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_notification_filter.xml</file> </header> - <module>snmpa_notification_filter</module> + <module since="">snmpa_notification_filter</module> <modulesummary>Behaviour module for the SNMP agent notification filters.</modulesummary> <description> <p>This module defines the behaviour of the agent notification @@ -51,7 +51,7 @@ </description> <funcs> <func> - <name>handle_notification(Notif, Data) -> Reply</name> + <name since="">handle_notification(Notif, Data) -> Reply</name> <fsummary>Handle a notification</fsummary> <type> <v>Reply = send | {send, NewNotif} | dont_send</v> diff --git a/lib/snmp/doc/src/snmpa_supervisor.xml b/lib/snmp/doc/src/snmpa_supervisor.xml index 86c6fbc350..e11cde390f 100644 --- a/lib/snmp/doc/src/snmpa_supervisor.xml +++ b/lib/snmp/doc/src/snmpa_supervisor.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpa_supervisor.xml</file> </header> - <module>snmpa_supervisor</module> + <module since="">snmpa_supervisor</module> <modulesummary>A supervisor for the SNMP agent Processes</modulesummary> <description> <p>This is the top supervisor for the agent part of the SNMP @@ -42,7 +42,7 @@ </description> <funcs> <func> - <name>start_sub_sup(Opts) -> {ok, pid()} | {error, {already_started, pid()}} | {error, Reason}</name> + <name since="">start_sub_sup(Opts) -> {ok, pid()} | {error, {already_started, pid()}} | {error, Reason}</name> <fsummary>Start the SNMP supervisor for sub-agents only</fsummary> <type> <v>Opts = [opt()]</v> @@ -60,7 +60,7 @@ </desc> </func> <func> - <name>start_master_sup(Opts) -> {ok, pid()} | {error, {already_started, pid()}} | {error, Reason}</name> + <name since="">start_master_sup(Opts) -> {ok, pid()} | {error, {already_started, pid()}} | {error, Reason}</name> <fsummary>Start the SNMP supervisor for all agents</fsummary> <type> <v>Opts = [opt()]</v> @@ -82,7 +82,7 @@ </desc> </func> <func> - <name>start_sub_agent(ParentAgent,Subtree,Mibs) -> {ok, pid()} | {error, Reason}</name> + <name since="">start_sub_agent(ParentAgent,Subtree,Mibs) -> {ok, pid()} | {error, Reason}</name> <fsummary>Start a sub-agent</fsummary> <type> <v>ParentAgent = pid()</v> @@ -99,7 +99,7 @@ </desc> </func> <func> - <name>stop_sub_agent(SubAgent) -> ok | no_such_child</name> + <name since="">stop_sub_agent(SubAgent) -> ok | no_such_child</name> <fsummary>Stop a sub-agent</fsummary> <type> <v>SubAgent = pid()</v> diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml index aba51bb500..b22b32a133 100644 --- a/lib/snmp/doc/src/snmpc.xml +++ b/lib/snmp/doc/src/snmpc.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpc.xml</file> </header> - <module>snmpc</module> + <module since="">snmpc</module> <modulesummary>Interface Functions to the SNMP toolkit MIB compiler</modulesummary> <description> <p>The module <c>snmpc</c> contains interface functions to the @@ -43,8 +43,8 @@ <funcs> <func> - <name>compile(File)</name> - <name>compile(File, Options) -> {ok, BinFileName} | {error, Reason}</name> + <name since="">compile(File)</name> + <name since="">compile(File, Options) -> {ok, BinFileName} | {error, Reason}</name> <fsummary>Compile the specified MIB</fsummary> <type> <v>File = string()</v> @@ -236,7 +236,7 @@ </func> <func> - <name>is_consistent(Mibs) -> ok | {error, Reason}</name> + <name since="">is_consistent(Mibs) -> ok | {error, Reason}</name> <fsummary>Check for OID conflicts between MIBs</fsummary> <type> <v>Mibs = [MibName]</v> @@ -252,7 +252,7 @@ </func> <func> - <name>mib_to_hrl(MibName) -> ok | {error, Reason}</name> + <name since="">mib_to_hrl(MibName) -> ok | {error, Reason}</name> <fsummary>Generate constants for the objects in the MIB</fsummary> <type> <v>MibName = string()</v> diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml index 4818aeb697..c45df98ee0 100644 --- a/lib/snmp/doc/src/snmpm.xml +++ b/lib/snmp/doc/src/snmpm.xml @@ -4,7 +4,7 @@ <erlref> <header> <copyright> - <year>2004</year><year>2016</year> + <year>2004</year><year>2018</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -32,7 +32,7 @@ <rev></rev> <file>snmpm.xml</file> </header> - <module>snmpm</module> + <module since="">snmpm</module> <modulesummary>Interface functions to the SNMP toolkit manager</modulesummary> <description> <p>The module <c>snmpm</c> contains interface functions to the @@ -77,7 +77,7 @@ sec_level() = noAuthNoPriv | authNoPriv | authPriv </section> <funcs> <func> - <name>monitor() -> Ref</name> + <name since="">monitor() -> Ref</name> <fsummary>Monitor the snmp manager</fsummary> <type> <v>Ref = reference()</v> @@ -92,7 +92,7 @@ sec_level() = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>demonitor(Ref) -> void()</name> + <name since="">demonitor(Ref) -> void()</name> <fsummary>Turn off monitoring of the snmp manager</fsummary> <type> <v>Ref = reference()</v> @@ -105,7 +105,7 @@ sec_level() = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>notify_started(Timeout) -> Pid</name> + <name since="">notify_started(Timeout) -> Pid</name> <fsummary>Request to be notified when manager started</fsummary> <type> <v>Timeout = integer()</v> @@ -148,7 +148,7 @@ sec_level() = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>cancel_notify_started(Pid) -> void()</name> + <name since="">cancel_notify_started(Pid) -> void()</name> <fsummary>Cancel request to be notified when manager started</fsummary> <type> <v>Pid = pid()</v> @@ -161,8 +161,8 @@ sec_level() = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>register_user(Id, Module, Data) -> ok | {error, Reason}</name> - <name>register_user(Id, Module, Data, DefaultAgentConfig) -> ok | {error, Reason}</name> + <name since="">register_user(Id, Module, Data) -> ok | {error, Reason}</name> + <name since="">register_user(Id, Module, Data, DefaultAgentConfig) -> ok | {error, Reason}</name> <fsummary>Register a user of the manager</fsummary> <type> <v>Id = term()</v> @@ -204,8 +204,8 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>register_user_monitor(Id, Module, Data) -> ok | {error, Reason}</name> - <name>register_user_monitor(Id, Module, Data, DefaultAgentConfig) -> ok | {error, Reason}</name> + <name since="">register_user_monitor(Id, Module, Data) -> ok | {error, Reason}</name> + <name since="">register_user_monitor(Id, Module, Data, DefaultAgentConfig) -> ok | {error, Reason}</name> <fsummary>Register a monitored user of the manager</fsummary> <type> <v>Id = term()</v> @@ -252,7 +252,7 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>unregister_user(Id) -> ok | {error, Reason}</name> + <name since="">unregister_user(Id) -> ok | {error, Reason}</name> <fsummary>Unregister the user</fsummary> <type> <v>Id = term()</v> @@ -265,7 +265,7 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>which_users() -> Users</name> + <name since="">which_users() -> Users</name> <fsummary>Get a list of all users</fsummary> <type> <v>Users = [UserId]</v> @@ -279,7 +279,7 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>register_agent(UserId, TargetName, Config) -> ok | {error, Reason}</name> + <name since="">register_agent(UserId, TargetName, Config) -> ok | {error, Reason}</name> <fsummary>Register this agent</fsummary> <type> <v>UserId = term()</v> @@ -325,7 +325,7 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>unregister_agent(UserId, TargetName) -> ok | {error, Reason}</name> + <name since="">unregister_agent(UserId, TargetName) -> ok | {error, Reason}</name> <fsummary>Unregister the user</fsummary> <type> <v>UserId = term()</v> @@ -339,7 +339,7 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>agent_info(TargetName, Item) -> {ok, Val} | {error, Reason}</name> + <name since="">agent_info(TargetName, Item) -> {ok, Val} | {error, Reason}</name> <fsummary>Retrieve agent config</fsummary> <type> <v>TargetName = target_name()</v> @@ -354,8 +354,8 @@ 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> + <name since="OTP R14B04">update_agent_info(UserId, TargetName, Info) -> ok | {error, Reason}</name> + <name since="">update_agent_info(UserId, TargetName, Item, Val) -> ok | {error, Reason}</name> <fsummary>Update agent config</fsummary> <type> <v>UserId = term()</v> @@ -379,8 +379,8 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>which_agents() -> Agents</name> - <name>which_agents(UserId) -> Agents</name> + <name since="">which_agents() -> Agents</name> + <name since="">which_agents(UserId) -> Agents</name> <fsummary>List the registered agents</fsummary> <type> <v>UserId = term()</v> @@ -396,7 +396,7 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> - <name>register_usm_user(EngineID, UserName, Conf) -> ok | {error, Reason}</name> + <name since="">register_usm_user(EngineID, UserName, Conf) -> ok | {error, Reason}</name> <fsummary>Register this USM user</fsummary> <type> <v>EngineID = string()</v> @@ -427,7 +427,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>unregister_usm_user(EngineID, UserName) -> ok | {error, Reason}</name> + <name since="">unregister_usm_user(EngineID, UserName) -> ok | {error, Reason}</name> <fsummary>Unregister this USM user</fsummary> <type> <v>EngineID = string()</v> @@ -442,7 +442,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>usm_user_info(EngineID, UserName, Item) -> {ok, Val} | {error, Reason}</name> + <name since="">usm_user_info(EngineID, UserName, Item) -> {ok, Val} | {error, Reason}</name> <fsummary>Retrieve usm user config</fsummary> <type> <v>EngineID = string()</v> @@ -458,7 +458,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>update_usm_user_info(EngineID, UserName, Item, Val) -> ok | {error, Reason}</name> + <name since="">update_usm_user_info(EngineID, UserName, Item, Val) -> ok | {error, Reason}</name> <fsummary>Update agent config</fsummary> <type> <v>EngineID = string()</v> @@ -475,7 +475,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>which_usm_users() -> UsmUsers</name> + <name since="">which_usm_users() -> UsmUsers</name> <fsummary>List all the registered usm users</fsummary> <type> <v>UsmUsers = [{EngineID,UserName}]</v> @@ -490,7 +490,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>which_usm_users(EngineID) -> UsmUsers</name> + <name since="">which_usm_users(EngineID) -> UsmUsers</name> <fsummary>List the registered usm users</fsummary> <type> <v>UsmUsers = [UserName]</v> @@ -505,8 +505,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_get2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_get2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_get2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>get-request</c></fsummary> <type> <v>UserId = term()</v> @@ -559,11 +559,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_get(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get(UserId, TargetName, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get(UserId, TargetName, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get(UserId, TargetName, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get(UserId, TargetName, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>get-request</c></fsummary> <type> <v>UserId = term()</v> @@ -605,8 +605,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_get2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_get2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_get2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>get-request</c></fsummary> <type> <v>UserId = term()</v> @@ -647,11 +647,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_get(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get(UserId, TargetName, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get(UserId, TargetName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get(UserId, TargetName, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get(UserId, TargetName, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get(UserId, TargetName, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get(UserId, TargetName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get(UserId, TargetName, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get(UserId, TargetName, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>get-request</c></fsummary> <type> <v>UserId = term()</v> @@ -683,8 +683,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_get_next2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_get_next2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>get-next-request</c></fsummary> <type> <v>UserId = term()</v> @@ -737,11 +737,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_get_next(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_next(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_next(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_next(UserId, TargetName, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_next(UserId, TargetName, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_next(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_next(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_next(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_next(UserId, TargetName, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_next(UserId, TargetName, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>get-next-request</c></fsummary> <type> <v>UserId = term()</v> @@ -775,8 +775,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_get_next2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_get_next2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>get-next-request</c></fsummary> <type> <v>UserId = term()</v> @@ -814,11 +814,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_get_next(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_next(UserId, TargetName, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_next(UserId, TargetName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_next(UserId, TargetName, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_next(UserId, TargetName, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_next(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_next(UserId, TargetName, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_next(UserId, TargetName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_next(UserId, TargetName, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_next(UserId, TargetName, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>get-next-request</c></fsummary> <type> <v>UserId = term()</v> @@ -849,8 +849,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_set2(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_set2(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>set-request</c></fsummary> <type> <v>UserId = term()</v> @@ -906,11 +906,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_set(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_set(UserId, TargetName, ContextName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_set(UserId, TargetName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_set(UserId, TargetName, ContextName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_set(UserId, TargetName, ContextName, VarsAndVals, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_set(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_set(UserId, TargetName, ContextName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_set(UserId, TargetName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_set(UserId, TargetName, ContextName, VarsAndVals, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_set(UserId, TargetName, ContextName, VarsAndVals, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>set-request</c></fsummary> <type> <v>UserId = term()</v> @@ -946,8 +946,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_set2(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> - <name>async_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_set2(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>set-request</c></fsummary> <type> <v>UserId = term()</v> @@ -990,11 +990,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_set(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> - <name>async_set(UserId, TargetName, ContextName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> - <name>async_set(UserId, TargetName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_set(UserId, TargetName, ContextName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_set(UserId, TargetName, ContextName, VarsAndVals, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_set(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_set(UserId, TargetName, ContextName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_set(UserId, TargetName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_set(UserId, TargetName, ContextName, VarsAndVals, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_set(UserId, TargetName, ContextName, VarsAndVals, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>set-request</c></fsummary> <type> <v>UserId = term()</v> @@ -1026,8 +1026,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="OTP R14B03">sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>get-bulk-request</c></fsummary> <type> <v>UserId = term()</v> @@ -1082,11 +1082,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> - <name>sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_bulk(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_bulk(UserId, TragetName, NonRep, MaxRep, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name since="">sync_get_bulk(UserId, TragetName, NonRep, MaxRep, ContextName, Oids, Timeout, ExtraInfo) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <fsummary>Synchronous <c>get-bulk-request</c></fsummary> <type> <v>UserId = term()</v> @@ -1121,8 +1121,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="OTP R14B03">async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>get-bulk-request</c></fsummary> <type> <v>UserId = term()</v> @@ -1162,11 +1162,11 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> - <name>async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids, Expire) -> {ok, ReqId} | {error, Reason}</name> + <name since="">async_get_bulk(UserId, TargetName, NonRep, MaxRep, ContextName, Oids, Expire, ExtraInfo) -> {ok, ReqId} | {error, Reason}</name> <fsummary>Asynchronous <c>get-bulk-request</c></fsummary> <type> <v>UserId = term()</v> @@ -1199,7 +1199,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>cancel_async_request(UserId, ReqId) -> ok | {error, Reason}</name> + <name since="">cancel_async_request(UserId, ReqId) -> ok | {error, Reason}</name> <fsummary>Cancel a asynchronous request</fsummary> <type> <v>UserId = term()</v> @@ -1214,15 +1214,15 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>log_to_txt(LogDir)</name> - <name>log_to_txt(LogDir, Block | Mibs)</name> - <name>log_to_txt(LogDir, Mibs, Block | OutFile) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, Block | LogName) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, Block | LogFile) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> ok | {error, Reason}</name> - <name>log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start, Stop) -> ok | {error, Reason}</name> + <name since="OTP R16B03">log_to_txt(LogDir)</name> + <name since="">log_to_txt(LogDir, Block | Mibs)</name> + <name since="">log_to_txt(LogDir, Mibs, Block | OutFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, Block | LogName) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, Block | LogFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R16B03">log_to_txt(LogDir, Mibs, OutFile, LogName, LogFile, Block, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> <fsummary>Convert an Audit Trail Log to text format</fsummary> <type> <v>LogDir = string()</v> @@ -1233,6 +1233,9 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <v>LogName = string()</v> <v>LogFile = string()</v> <v>Start = Stop = null | calendar:datetime() | {local_time, calendar:datetime()} | {universal_time, calendar:datetime()} </v> + <v>Cnt = {NumOK, NumERR}</v> + <v>NumOK = non_neg_integer()</v> + <v>NumERR = pos_integer()</v> <v>Reason = disk_log_open_error() | file_open_error() | term()</v> <v>disk_log_open_error() = {LogName, term()}</v> <v>file_open_error() = {OutFile, term()}</v> @@ -1254,15 +1257,15 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>log_to_io(LogDir) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Block | Mibs) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, Block | LogName) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, Block | LogFile) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> ok | {error, Reason}</name> - <name>log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start, Stop) -> ok | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Block | Mibs) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs) -> ok | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, Block | LogName) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, Block | LogFile) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Block | Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R15B01">log_to_io(LogDir, Mibs, LogName, LogFile, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> + <name since="OTP R16B03">log_to_io(LogDir, Mibs, LogName, LogFile, Block, Start, Stop) -> ok | {ok, Cnt} | {error, Reason}</name> <fsummary>Convert an Audit Trail Log to text format</fsummary> <type> <v>LogDir = string()</v> @@ -1272,6 +1275,9 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <v>LogName = string()</v> <v>LogFile = string()</v> <v>Start = Stop = null | calendar:datetime() | {local_time, calendar:datetime()} | {universal_time, calendar:datetime()} </v> + <v>Cnt = {NumOK, NumERR}</v> + <v>NumOK = non_neg_integer()</v> + <v>NumERR = pos_integer()</v> <v>Reason = disk_log_open_error() | file_open_error() | term()</v> <v>disk_log_open_error() = {LogName, term()}</v> <v>file_open_error() = {OutFile, term()}</v> @@ -1293,7 +1299,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>change_log_size(NewSize) -> ok | {error, Reason}</name> + <name since="">change_log_size(NewSize) -> ok | {error, Reason}</name> <fsummary>Change the size of the Audit Trail Log</fsummary> <type> <v>NewSize = {MaxBytes, MaxFiles}</v> @@ -1315,7 +1321,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>set_log_type(NewType) -> {ok, OldType} | {error, Reason}</name> + <name since="">set_log_type(NewType) -> {ok, OldType} | {error, Reason}</name> <fsummary>Change the Audit Trail Log type</fsummary> <type> <v>NewType = OldType = atl_type()</v> @@ -1334,7 +1340,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>load_mib(Mib) -> ok | {error, Reason}</name> + <name since="">load_mib(Mib) -> ok | {error, Reason}</name> <fsummary>Load a MIB into the manager</fsummary> <type> <v>Mib = MibName</v> @@ -1355,7 +1361,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>unload_mib(Mib) -> ok | {error, Reason}</name> + <name since="">unload_mib(Mib) -> ok | {error, Reason}</name> <fsummary>Unload a MIB from the manager</fsummary> <type> <v>Mib = MibName</v> @@ -1376,7 +1382,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>which_mibs() -> Mibs</name> + <name since="">which_mibs() -> Mibs</name> <fsummary>Which mibs are loaded into the manager</fsummary> <type> <v>Mibs = [{MibName, MibFile}]</v> @@ -1391,7 +1397,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>name_to_oid(Name) -> {ok, Oids} | {error, Reason}</name> + <name since="">name_to_oid(Name) -> {ok, Oids} | {error, Reason}</name> <fsummary>Get all the possible oid's for an alias-name</fsummary> <type> <v>Name = atom()</v> @@ -1408,7 +1414,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>oid_to_name(Oid) -> {ok, Name} | {error, Reason}</name> + <name since="">oid_to_name(Oid) -> {ok, Name} | {error, Reason}</name> <fsummary>Get the alias-name of the oid </fsummary> <type> <v>Oid = oid()</v> @@ -1423,7 +1429,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>oid_to_type(Oid) -> {ok, Type} | {error, Reason}</name> + <name since="">oid_to_type(Oid) -> {ok, Type} | {error, Reason}</name> <fsummary>Get the type of the the oid</fsummary> <type> <v>Oid = oid()</v> @@ -1438,7 +1444,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>backup(BackupDir) -> ok | {error, Reason}</name> + <name since="">backup(BackupDir) -> ok | {error, Reason}</name> <fsummary>Backup manager data</fsummary> <type> <v>BackupDir = string()</v> @@ -1452,7 +1458,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>info() -> [{Key, Value}]</name> + <name since="">info() -> [{Key, Value}]</name> <fsummary>Return information about the manager</fsummary> <type> <v>Key = atom()</v> @@ -1469,7 +1475,7 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>verbosity(Ref, Verbosity) -> void()</name> + <name since="">verbosity(Ref, Verbosity) -> void()</name> <fsummary>Assign a new verbosity for the process</fsummary> <type> <v>Ref = server | config | net_if | note_store | all</v> @@ -1486,8 +1492,8 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 </func> <func> - <name>format_reason(Reason) -> string()</name> - <name>format_reason(Prefix, Reason) -> string()</name> + <name since="">format_reason(Reason) -> string()</name> + <name since="">format_reason(Prefix, Reason) -> string()</name> <fsummary>Assign a new verbosity for the process</fsummary> <type> <v>Reason = term()</v> diff --git a/lib/snmp/doc/src/snmpm_conf.xml b/lib/snmp/doc/src/snmpm_conf.xml index a3097e5f7e..17ecf2df7c 100644 --- a/lib/snmp/doc/src/snmpm_conf.xml +++ b/lib/snmp/doc/src/snmpm_conf.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpm_conf.xml</file> </header> - <module>snmpm_conf</module> + <module since="">snmpm_conf</module> <modulesummary>Utility functions for handling the manager config files.</modulesummary> <description> <p>The module <c>snmpm_conf</c> contains various utility functions to @@ -42,7 +42,7 @@ </description> <funcs> <func> - <name>manager_entry(Tag, Val) -> manager_entry()</name> + <name since="">manager_entry(Tag, Val) -> manager_entry()</name> <fsummary>Create an manager entry</fsummary> <type> <v>Tag = address | port | engine_id | max_message_size</v> @@ -60,8 +60,8 @@ </desc> </func> <func> - <name>write_manager_config(Dir, Conf) -> ok</name> - <name>write_manager_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_manager_config(Dir, Conf) -> ok</name> + <name since="">write_manager_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the manager config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -81,7 +81,7 @@ </desc> </func> <func> - <name>append_manager_config(Dir, Conf) -> ok</name> + <name since="">append_manager_config(Dir, Conf) -> ok</name> <fsummary>Append the manager config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -98,7 +98,7 @@ </desc> </func> <func> - <name>read_manager_config(Dir) -> Conf</name> + <name since="">read_manager_config(Dir) -> Conf</name> <fsummary>Read the manager config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -115,9 +115,9 @@ </desc> </func> <func> - <name>users_entry(UserId) -> users_entry()</name> - <name>users_entry(UserId, UserMod) -> users_entry()</name> - <name>users_entry(UserId, UserMod, UserData) -> users_entry()</name> + <name since="">users_entry(UserId) -> users_entry()</name> + <name since="">users_entry(UserId, UserMod) -> users_entry()</name> + <name since="">users_entry(UserId, UserMod, UserData) -> users_entry()</name> <fsummary>Create an users entry</fsummary> <type> <v>UserId = term()</v> @@ -139,8 +139,8 @@ </desc> </func> <func> - <name>write_users_config(Dir, Conf) -> ok</name> - <name>write_users_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_users_config(Dir, Conf) -> ok</name> + <name since="">write_users_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the manager users config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -161,7 +161,7 @@ </desc> </func> <func> - <name>append_users_config(Dir, Conf) -> ok</name> + <name since="">append_users_config(Dir, Conf) -> ok</name> <fsummary>Append the manager users config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -179,7 +179,7 @@ </desc> </func> <func> - <name>read_users_config(Dir) -> Conf</name> + <name since="">read_users_config(Dir) -> Conf</name> <fsummary>Read the manager users config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -196,7 +196,7 @@ </desc> </func> <func> - <name>agents_entry(UserId, TargetName, Comm, Domain, Addr, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel) -> agents_entry()</name> + <name since="">agents_entry(UserId, TargetName, Comm, Domain, Addr, EngineID, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel) -> agents_entry()</name> <fsummary>Create an agents entry</fsummary> <type> <v>UserId = term()</v> @@ -223,8 +223,8 @@ </desc> </func> <func> - <name>write_agents_config(Dir, Conf) -> ok</name> - <name>write_agents_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_agents_config(Dir, Conf) -> ok</name> + <name since="">write_agents_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the manager agents to the config file</fsummary> <type> <v>Dir = string()</v> @@ -245,7 +245,7 @@ </desc> </func> <func> - <name>append_agents_config(Dir, Conf) -> ok</name> + <name since="">append_agents_config(Dir, Conf) -> ok</name> <fsummary>Append the manager agents to the config file</fsummary> <type> <v>Dir = string()</v> @@ -263,7 +263,7 @@ </desc> </func> <func> - <name>read_agents_config(Dir) -> Conf</name> + <name since="">read_agents_config(Dir) -> Conf</name> <fsummary>Read the manager agents config from the config file</fsummary> <type> <v>Dir = string()</v> @@ -280,8 +280,8 @@ </desc> </func> <func> - <name>usm_entry(EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey) -> usm_entry()</name> - <name>usm_entry(EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey) -> usm_entry()</name> + <name since="">usm_entry(EngineID, UserName, AuthP, AuthKey, PrivP, PrivKey) -> usm_entry()</name> + <name since="">usm_entry(EngineID, UserName, SecName, AuthP, AuthKey, PrivP, PrivKey) -> usm_entry()</name> <fsummary>Create an usm entry</fsummary> <type> <v>EngineID = string()</v> @@ -303,8 +303,8 @@ </desc> </func> <func> - <name>write_usm_config(Dir, Conf) -> ok</name> - <name>write_usm_config(Dir, Hdr, Conf) -> ok</name> + <name since="">write_usm_config(Dir, Conf) -> ok</name> + <name since="">write_usm_config(Dir, Hdr, Conf) -> ok</name> <fsummary>Write the manager usm config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -325,7 +325,7 @@ </desc> </func> <func> - <name>append_usm_config(Dir, Conf) -> ok</name> + <name since="">append_usm_config(Dir, Conf) -> ok</name> <fsummary>Append the manager usm config to the config file</fsummary> <type> <v>Dir = string()</v> @@ -343,7 +343,7 @@ </desc> </func> <func> - <name>read_usm_config(Dir) -> Conf</name> + <name since="">read_usm_config(Dir) -> Conf</name> <fsummary>Read the manager usm config from the config file</fsummary> <type> <v>Dir = string()</v> diff --git a/lib/snmp/doc/src/snmpm_mpd.xml b/lib/snmp/doc/src/snmpm_mpd.xml index 08276e4b30..b024f8d294 100644 --- a/lib/snmp/doc/src/snmpm_mpd.xml +++ b/lib/snmp/doc/src/snmpm_mpd.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpm_mpd.xml</file> </header> - <module>snmpm_mpd</module> + <module since="">snmpm_mpd</module> <modulesummary>Message Processing and Dispatch module for the SNMP manager</modulesummary> <description> <p>The module <c>snmpm_mpd</c> implements the version independent @@ -48,7 +48,7 @@ <funcs> <func> - <name>init_mpd(Vsns) -> mpd_state()</name> + <name since="">init_mpd(Vsns) -> mpd_state()</name> <fsummary>Initialize the MPD module</fsummary> <type> <v>Vsns = [Vsn]</v> @@ -64,7 +64,7 @@ </desc> </func> <func> - <name>process_msg(Msg, Domain, Addr, State, NoteStore, Logger) -> {ok, Vsn, Pdu, PduMS, MsgData} | {discarded, Reason}</name> + <name since="OTP 17.3">process_msg(Msg, Domain, Addr, State, NoteStore, Logger) -> {ok, Vsn, Pdu, PduMS, MsgData} | {discarded, Reason}</name> <fsummary>Process a message received from the network</fsummary> <type> <v>Msg = binary()</v> @@ -92,7 +92,7 @@ </desc> </func> <func> - <name>generate_msg(Vsn, NoteStore, Pdu, MsgData, Logger) -> {ok, Packet} | {discarded, Reason}</name> + <name since="">generate_msg(Vsn, NoteStore, Pdu, MsgData, Logger) -> {ok, Packet} | {discarded, Reason}</name> <fsummary>Generate a request message to be sent to the network</fsummary> <type> <v>Vsn = 'version-1' | 'version-2' | 'version-3'</v> @@ -117,7 +117,7 @@ </desc> </func> <func> - <name>generate_response_msg(Vsn, Pdu, MsgData, Logger) -> {ok, Packet} | {discarded, Reason}</name> + <name since="">generate_response_msg(Vsn, Pdu, MsgData, Logger) -> {ok, Packet} | {discarded, Reason}</name> <fsummary>Generate a response packet to be sent to the network</fsummary> <type> <v>Vsn = 'version-1' | 'version-2' | 'version-3'</v> diff --git a/lib/snmp/doc/src/snmpm_network_interface.xml b/lib/snmp/doc/src/snmpm_network_interface.xml index 73892aa2e8..e4a66ceef2 100644 --- a/lib/snmp/doc/src/snmpm_network_interface.xml +++ b/lib/snmp/doc/src/snmpm_network_interface.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpm_network_interface.xml</file> </header> - <module>snmpm_network_interface</module> + <module since="">snmpm_network_interface</module> <modulesummary>Behaviour module for the SNMP manager network interface.</modulesummary> <description> <p>This module defines the behaviour of the manager network @@ -79,7 +79,7 @@ <funcs> <func> - <name>start_link(Server, NoteStore) -> {ok, Pid} | {error, Reason}</name> + <name since="">start_link(Server, NoteStore) -> {ok, Pid} | {error, Reason}</name> <fsummary>Start-link the network interface process</fsummary> <type> <v>Server = pid()</v> @@ -95,7 +95,7 @@ </func> <func> - <name>stop(Pid) -> void()</name> + <name since="">stop(Pid) -> void()</name> <fsummary>Stop the network interface process</fsummary> <type> <v>Pid = pid()</v> @@ -108,7 +108,7 @@ </func> <func> - <name>send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo) -> void()</name> + <name since="">send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, ExtraInfo) -> void()</name> <fsummary>Request the network interface process to send this pdu</fsummary> <type> <v>Pid = pid()</v> @@ -142,7 +142,7 @@ </func> <func> - <name>inform_response(Pid, Ref, Addr, Port) -> void()</name> + <name since="">inform_response(Pid, Ref, Addr, Port) -> void()</name> <fsummary>Send the inform-request ack</fsummary> <type> <v>Pid = pid()</v> @@ -163,7 +163,7 @@ </func> <func> - <name>note_store(Pid, NoteStore) -> void()</name> + <name since="">note_store(Pid, NoteStore) -> void()</name> <fsummary>Change the verbosity of the network interface process</fsummary> <type> <v>Pid = pid()</v> @@ -179,7 +179,7 @@ </func> <func> - <name>info(Pid) -> [{Key, Value}]</name> + <name since="">info(Pid) -> [{Key, Value}]</name> <fsummary>Return information about the running network interface process</fsummary> <type> <v>Pid = pid()</v> @@ -198,7 +198,7 @@ </func> <func> - <name>verbosity(Pid, Verbosity) -> void()</name> + <name since="">verbosity(Pid, Verbosity) -> void()</name> <fsummary>Change the verbosity of the network interface process</fsummary> <type> <v>Pid = pid()</v> @@ -212,7 +212,7 @@ </func> <func> - <name>get_log_type(Pid) -> {ok, LogType} | {error, Reason}</name> + <name since="">get_log_type(Pid) -> {ok, LogType} | {error, Reason}</name> <fsummary>Get the Audit Trail Log type</fsummary> <type> <v>Pid = pid()</v> @@ -233,7 +233,7 @@ </func> <func> - <name>set_log_type(Pid, NewType) -> {ok, OldType} | {error, Reason}</name> + <name since="">set_log_type(Pid, NewType) -> {ok, OldType} | {error, Reason}</name> <fsummary>Change the Audit Trail Log type</fsummary> <type> <v>Pid = pid()</v> diff --git a/lib/snmp/doc/src/snmpm_network_interface_filter.xml b/lib/snmp/doc/src/snmpm_network_interface_filter.xml index 742cd53fc6..a50572da51 100644 --- a/lib/snmp/doc/src/snmpm_network_interface_filter.xml +++ b/lib/snmp/doc/src/snmpm_network_interface_filter.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpm_network_interface_filter.xml</file> </header> - <module>snmpm_network_interface_filter</module> + <module since="">snmpm_network_interface_filter</module> <modulesummary>Behaviour module for the SNMP manager network-interface filter.</modulesummary> <description> <p>This module defines the behaviour of the manager network interface @@ -100,7 +100,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | <funcs> <func> - <name>accept_recv(Domain, Addr) -> boolean()</name> + <name since="">accept_recv(Domain, Addr) -> boolean()</name> <fsummary>Shall the received message be accepted</fsummary> <type> <v>Domain = transportDomain()</v> @@ -116,7 +116,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </func> <func> - <name>accept_send(Domain, Addr) -> boolean()</name> + <name since="">accept_send(Domain, Addr) -> boolean()</name> <fsummary>Shall the message be sent</fsummary> <type> <v>Domain = transportDomain()</v> @@ -132,7 +132,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </func> <func> - <name>accept_recv_pdu(Domain, Addr, PduType) -> boolean()</name> + <name since="">accept_recv_pdu(Domain, Addr, PduType) -> boolean()</name> <fsummary>Shall the received pdu be accepted</fsummary> <type> <v>Domain = transportDomain()</v> @@ -150,7 +150,7 @@ pdu_type() = 'get-request' | 'get-next-request' | 'get-response' | </func> <func> - <name>accept_send_pdu(Domain, Addr, PduType) -> boolean()</name> + <name since="">accept_send_pdu(Domain, Addr, PduType) -> boolean()</name> <fsummary>Shall the pdu be sent</fsummary> <type> <v>Domain = transportDomain()</v> diff --git a/lib/snmp/doc/src/snmpm_user.xml b/lib/snmp/doc/src/snmpm_user.xml index 87ae1d224a..9abf596c83 100644 --- a/lib/snmp/doc/src/snmpm_user.xml +++ b/lib/snmp/doc/src/snmpm_user.xml @@ -32,7 +32,7 @@ <rev></rev> <file>snmpm_user.xml</file> </header> - <module>snmpm_user</module> + <module since="">snmpm_user</module> <modulesummary>Behaviour module for the SNMP manager user.</modulesummary> <description> <p>This module defines the behaviour of the manager user. @@ -93,7 +93,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), <funcs> <func> - <name>handle_error(ReqId, Reason, UserData) -> void()</name> + <name since="">handle_error(ReqId, Reason, UserData) -> void()</name> <fsummary>Handle error</fsummary> <type> <v>ReqId = integer()</v> @@ -122,7 +122,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), </func> <func> - <name>handle_agent(Domain, Addr, Type, SnmpInfo, UserData) -> Reply</name> + <name since="">handle_agent(Domain, Addr, Type, SnmpInfo, UserData) -> Reply</name> <fsummary>Handle agent</fsummary> <type> <v>Domain = transportDomainUdpIpv4 | transportDomainUdpIpv6</v> @@ -181,7 +181,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), </func> <func> - <name>handle_pdu(TargetName, ReqId, SnmpPduInfo, UserData) -> void()</name> + <name since="">handle_pdu(TargetName, ReqId, SnmpPduInfo, UserData) -> void()</name> <fsummary>Handle the reply to an asynchronous request</fsummary> <type> <v>TargetName = target_name()</v> @@ -202,7 +202,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), </func> <func> - <name>handle_trap(TargetName, SnmpTrapInfo, UserData) -> Reply</name> + <name since="">handle_trap(TargetName, SnmpTrapInfo, UserData) -> Reply</name> <fsummary>Handle a trap/notification message</fsummary> <type> <v>TargetName = TargetName2 = target_name()</v> @@ -225,7 +225,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), </func> <func> - <name>handle_inform(TargetName, SnmpInformInfo, UserData) -> Reply</name> + <name since="">handle_inform(TargetName, SnmpInformInfo, UserData) -> Reply</name> <fsummary>Handle a inform message</fsummary> <type> <v>TargetName = TargetName2 = target_name()</v> @@ -253,7 +253,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), </func> <func> - <name>handle_report(TargetName, SnmpReportInfo, UserData) -> Reply</name> + <name since="">handle_report(TargetName, SnmpReportInfo, UserData) -> Reply</name> <fsummary>Handle a report message</fsummary> <type> <v>TargetName = TargetName2 = target_name()</v> @@ -278,7 +278,7 @@ snmp_v1_trap_info() :: {Enteprise :: snmp:oid(), </func> <func> - <name>handle_invalid_result(IN, OUT) -> void()</name> + <name since="OTP R16B03">handle_invalid_result(IN, OUT) -> void()</name> <fsummary>Handle a report message</fsummary> <type> <v>IN = {Func, Args}</v> diff --git a/lib/snmp/include/snmp_types.hrl b/lib/snmp/include/snmp_types.hrl index ffe30996dc..eff17a13a3 100644 --- a/lib/snmp/include/snmp_types.hrl +++ b/lib/snmp/include/snmp_types.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2016. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -349,6 +349,9 @@ -define(view_included, 1). -define(view_excluded, 2). +-define(view_wildcard, 0). +-define(view_exact, 1). + %%----------------------------------------------------------------- %% From SNMPv2-SMI diff --git a/lib/snmp/src/agent/depend.mk b/lib/snmp/src/agent/depend.mk index 8eba50fa3b..49c7669e41 100644 --- a/lib/snmp/src/agent/depend.mk +++ b/lib/snmp/src/agent/depend.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2016. All Rights Reserved. +# Copyright Ericsson AB 2004-2019. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -24,6 +24,9 @@ $(EBIN)/snmpa_authentication_service.$(EMULATOR): \ $(EBIN)/snmpa_error_report.$(EMULATOR): \ snmpa_error_report.erl +$(EBIN)/snmpa_get_mechanism.$(EMULATOR): \ + snmpa_get_mechanism.erl + $(EBIN)/snmpa_network_interface.$(EMULATOR): \ snmpa_network_interface.erl @@ -78,6 +81,20 @@ $(EBIN)/snmpa_error_logger.$(EMULATOR): \ snmpa_error_report.erl \ snmpa_error_logger.erl +$(EBIN)/snmpa_set.$(EMULATOR): \ + snmpa_set_mechanism.erl \ + snmpa_set.erl \ + ../misc/snmp_verbosity.hrl + +$(EBIN)/snmpa_get.$(EMULATOR): \ + snmpa_get_mechanism.erl \ + snmpa_get.erl \ + ../misc/snmp_verbosity.hrl + +$(EBIN)/snmpa_get_lib.$(EMULATOR): \ + snmpa_get_lib.erl \ + ../misc/snmp_verbosity.hrl + $(EBIN)/snmpa_local_db.$(EMULATOR): \ snmpa_local_db.erl \ ../misc/snmp_debug.hrl \ diff --git a/lib/snmp/src/agent/modules.mk b/lib/snmp/src/agent/modules.mk index 0f8615588a..49cc158c2e 100644 --- a/lib/snmp/src/agent/modules.mk +++ b/lib/snmp/src/agent/modules.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 2004-2016. All Rights Reserved. +# Copyright Ericsson AB 2004-2019. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ BEHAVIOUR_MODULES = \ snmpa_authentication_service \ snmpa_discovery_handler \ snmpa_error_report \ + snmpa_get_mechanism \ snmpa_mib_storage \ snmpa_mib_data \ snmpa_network_interface \ @@ -30,12 +31,24 @@ BEHAVIOUR_MODULES = \ snmpa_notification_filter \ snmpa_set_mechanism +MIB_MODULES = \ + snmp_community_mib \ + snmp_framework_mib \ + snmp_notification_mib \ + snmp_standard_mib \ + snmp_target_mib \ + snmp_user_based_sm_mib \ + snmp_view_based_acm_mib + # snmpa is "plain" interface module but also defines some agent specific types # and therefor must be compiled before the modules that use them, including # the behaviour modules... +# Some of the MIB modules also define types used elsewhere and therefor +# has to be built before the other mods. # snmpa_mib_data_ttln MODULES = \ snmpa \ + $(MIB_MODULES) \ $(BEHAVIOUR_MODULES) \ snmpa_acm \ snmpa_agent \ @@ -46,6 +59,8 @@ MODULES = \ snmpa_error \ snmpa_error_io \ snmpa_error_logger \ + snmpa_get \ + snmpa_get_lib \ snmpa_local_db \ snmpa_mib_storage_ets \ snmpa_mib_storage_dets \ @@ -66,17 +81,10 @@ MODULES = \ snmpa_trap \ snmpa_usm \ snmpa_vacm \ - snmp_community_mib \ - snmp_framework_mib \ snmp_generic \ snmp_generic_mnesia \ snmp_index \ - snmp_notification_mib \ - snmp_shadow_table \ - snmp_standard_mib \ - snmp_target_mib \ - snmp_user_based_sm_mib \ - snmp_view_based_acm_mib + snmp_shadow_table INTERNAL_HRL_FILES = \ 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 02415e8036..c6eeb7cea2 100644 --- a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl +++ b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2016. All Rights Reserved. +%% Copyright Ericsson AB 1999-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -37,6 +37,12 @@ %% -export([emask2imask/1]). +-export_type([ + mibview/0, + internal_view_mask/0, + internal_view_mask_element/0, + internal_view_type/0 + ]). -include("snmp_types.hrl"). -include("SNMPv2-TC.hrl"). @@ -53,7 +59,13 @@ -type internal_view_mask() :: null | [internal_view_mask_element()]. --type internal_view_mask_element() :: 0 | 1. +-type internal_view_mask_element() :: ?view_wildcard | + ?view_exact. +-type internal_view_type() :: ?view_included | ?view_excluded. + +-type mibview() :: [{SubTree :: snmp:oid(), + Mask :: internal_view_mask(), + Type :: internal_view_type()}]. -type external_view_mask() :: octet_string(). % At most length of 16 octet -type octet_string() :: [octet()]. diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index 458b88359b..a521b3773b 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -28,7 +28,8 @@ %% External exports -export([start_link/4, start_link/5, stop/1]). --export([subagent_set/2, +-export([subagent_get/3, subagent_get_next/3, + subagent_set/2, load_mibs/3, unload_mibs/3, which_mibs/1, whereis_mib/2, info/1, register_subagent/3, unregister_subagent/2, @@ -362,12 +363,19 @@ do_init(Prio, Parent, Ref, Options) -> "~n Options: ~p",[Prio, Parent, Ref, Options]), Mibs = get_mibs(Options), + SetModule = get_set_mechanism(Options), put(set_module, SetModule), + ?vtrace("set-module: ~w", [SetModule]), + + GetModule = get_get_mechanism(Options), + put(get_module, GetModule), + ?vtrace("get-module: ~w", [GetModule]), %% OTP-3324. For AXD301. AuthModule = get_authentication_service(Options), put(auth_module, AuthModule), + ?vtrace("auth-module: ~w", [AuthModule]), MultiT = get_multi_threaded(Options), Vsns = get_versions(Options), @@ -1133,7 +1141,7 @@ handle_call({subagent_get_next, MibView, Varbinds, PduData}, _From, S) -> "~n PduData: ~p", [MibView,Varbinds,PduData]), put_pdu_data(PduData), - {reply, do_get_next(MibView, Varbinds, infinity), S}; + {reply, do_get_next(MibView, Varbinds), S}; handle_call({subagent_set, Arguments, PduData}, _From, S) -> ?vlog("[handle_call] subagent set:" "~n Arguments: ~p" @@ -1174,7 +1182,7 @@ handle_call({get_next, Vars, Context}, _From, S) -> ?vdebug("Varbinds: ~p",[Varbinds]), MibView = snmpa_acm:get_root_mib_view(), Reply = - case do_get_next(MibView, Varbinds, infinity) of + case do_get_next(MibView, Varbinds) of {noError, 0, NewVarbinds} -> Vbs = lists:keysort(#varbind.org_index, NewVarbinds), [{Oid,Val} || #varbind{oid = Oid, value = Val} <- Vbs]; @@ -2559,7 +2567,7 @@ process_pdu(#pdu{type = 'get-next-request', request_id = ReqId, varbinds = Vbs}, "~n ReqId: ~p" "~n Vbs: ~p" "~n MibView: ~p",[ReqId, Vbs, MibView]), - Res = get_err(do_get_next(MibView, Vbs, infinity)), + Res = get_err(do_get_next(MibView, Vbs)), ?vtrace("get-next result: " "~n ~p",[Res]), {ErrStatus, ErrIndex, ResVarbinds} = @@ -2650,8 +2658,7 @@ validate_next_v1_2([Vb | _Vbs], _MibView, _Res) {noSuchName, Vb#varbind.org_index}; validate_next_v1_2([Vb | Vbs], MibView, Res) when Vb#varbind.variabletype =:= 'Counter64' -> - case validate_next_v1( - do_get_next(MibView, [mk_next_oid(Vb)], infinity), MibView) of + case validate_next_v1( do_get_next(MibView, [mk_next_oid(Vb)]), MibView) of {noError, 0, [NVb]} -> validate_next_v1_2(Vbs, MibView, [NVb | Res]); {Error, Index, _OrgVb} -> @@ -2693,6 +2700,20 @@ mk_next_oid(Vb) -> %%%----------------------------------------------------------------- %%----------------------------------------------------------------- +%% Func: do_get/2 +%% Purpose: Handles all VBs in a request that is inside the +%% mibview (local). +%% Returns: {noError, 0, ListOfNewVarbinds} | +%% {ErrorStatus, ErrorIndex, []} +%%----------------------------------------------------------------- + +do_get(UnsortedVarbinds, IsNotification) -> + Extra = get(net_if_data), + GetModule = get(get_module), + GetModule:do_get(UnsortedVarbinds, IsNotification, Extra). + + +%%----------------------------------------------------------------- %% Func: do_get/3 %% Purpose: do_get handles "getRequests". %% Pre: incoming varbinds have type == 'NULL', value == unSpecified @@ -2700,390 +2721,24 @@ mk_next_oid(Vb) -> %% {ErrorStatus, ErrorIndex, []} %%----------------------------------------------------------------- -%% If this function is called from a worker-process, we *may* -%% need to tunnel into the master-agent and let it do the -%% work +%% If this function is called from a worker-process (or other process), +%% we *may* need to tunnel into the master-agent and let it do the work. do_get(MibView, UnsortedVarbinds, IsNotification) -> - do_get(MibView, UnsortedVarbinds, IsNotification, false). + Extra = get(net_if_data), + GetModule = get(get_module), + GetModule:do_get(MibView, UnsortedVarbinds, IsNotification, Extra). do_get(MibView, UnsortedVarbinds, IsNotification, ForceMaster) -> - ?vtrace("do_get -> entry with" - "~n MibView: ~p" - "~n UnsortedVarbinds: ~p" - "~n IsNotification: ~p", - [MibView, UnsortedVarbinds, IsNotification]), case (whereis(snmp_master_agent) =:= self()) of false when (ForceMaster =:= true) -> - %% I am a lowly worker process, handoff to the master agent PduData = get_pdu_data(), call(snmp_master_agent, {do_get, MibView, UnsortedVarbinds, IsNotification, PduData}); - - _ -> - %% This is me, the master, so go ahead - {OutSideView, InSideView} = - split_vbs_view(UnsortedVarbinds, MibView), - {Error, Index, NewVbs} = - do_get(InSideView, IsNotification), - {Error, Index, NewVbs ++ OutSideView} - - end. - - -split_vbs_view(Vbs, MibView) -> - ?vtrace("split the varbinds view", []), - split_vbs_view(Vbs, MibView, [], []). - -split_vbs_view([Vb | Vbs], MibView, Out, In) -> - case snmpa_acm:validate_mib_view(Vb#varbind.oid, MibView) of - true -> split_vbs_view(Vbs, MibView, Out, [Vb | In]); - false -> split_vbs_view(Vbs, MibView, - [Vb#varbind{value = noSuchObject} | Out], In) - end; -split_vbs_view([], _MibView, Out, In) -> - {Out, In}. - -do_get(UnsortedVarbinds, IsNotification) -> - {MyVarbinds, SubagentVarbinds} = sort_varbindlist(UnsortedVarbinds), - case do_get_local(MyVarbinds, [], IsNotification) of - {noError, 0, NewMyVarbinds} -> - case do_get_subagents(SubagentVarbinds, IsNotification) of - {noError, 0, NewSubagentVarbinds} -> - {noError, 0, NewMyVarbinds ++ NewSubagentVarbinds}; - {ErrorStatus, ErrorIndex, _} -> - {ErrorStatus, ErrorIndex, []} - end; - {ErrorStatus, ErrorIndex, _} -> - {ErrorStatus, ErrorIndex, []} + _ -> + do_get(MibView, UnsortedVarbinds, IsNotification) end. -%%----------------------------------------------------------------- -%% Func: do_get_local/3 -%% Purpose: Loop the variablebindings list. We know that each varbind -%% in that list belongs to us. -%% Returns: {noError, 0, ListOfNewVarbinds} | -%% {ErrorStatus, ErrorIndex, []} -%%----------------------------------------------------------------- -do_get_local([Vb | Vbs], Res, IsNotification) -> - case try_get(Vb, IsNotification) of - NewVb when is_record(NewVb, varbind) -> - do_get_local(Vbs, [NewVb | Res], IsNotification); - ListOfNewVb when is_list(ListOfNewVb) -> - do_get_local(Vbs, lists:append(ListOfNewVb, Res), IsNotification); - {error, Error, OrgIndex} -> - {Error, OrgIndex, []} - end; -do_get_local([], Res, _IsNotification) -> - {noError, 0, Res}. - -%%----------------------------------------------------------------- -%% Func: do_get_subagents/2 -%% Purpose: Loop the list of varbinds for different subagents. -%% For each of them, call sub_agent_get to retreive -%% the values for them. -%% Returns: {noError, 0, ListOfNewVarbinds} | -%% {ErrorStatus, ErrorIndex, []} -%%----------------------------------------------------------------- -do_get_subagents(SubagentVarbinds, IsNotification) -> - do_get_subagents(SubagentVarbinds, [], IsNotification). -do_get_subagents([{SubAgentPid, SAVbs} | Tail], Res, IsNotification) -> - {_SAOids, Vbs} = sa_split(SAVbs), - case catch subagent_get(SubAgentPid, Vbs, IsNotification) of - {noError, 0, NewVbs} -> - do_get_subagents(Tail, lists:append(NewVbs, Res), IsNotification); - {ErrorStatus, ErrorIndex, _} -> - {ErrorStatus, ErrorIndex, []}; - {'EXIT', Reason} -> - user_err("Lost contact with subagent (get) ~w. Using genErr", - [Reason]), - {genErr, 0, []} - end; -do_get_subagents([], Res, _IsNotification) -> - {noError, 0, Res}. - - -%%----------------------------------------------------------------- -%% Func: try_get/2 -%% Returns: {error, ErrorStatus, OrgIndex} | -%% #varbind | -%% List of #varbind -%%----------------------------------------------------------------- -try_get(IVb, IsNotification) when is_record(IVb, ivarbind) -> - ?vtrace("try_get(ivarbind) -> entry with" - "~n IVb: ~p", [IVb]), - get_var_value_from_ivb(IVb, IsNotification); -try_get({TableOid, TableVbs}, IsNotification) -> - ?vtrace("try_get(table) -> entry with" - "~n TableOid: ~p" - "~n TableVbs: ~p", [TableOid, TableVbs]), - [#ivarbind{mibentry = MibEntry}|_] = TableVbs, - {NoAccessVbs, AccessVbs} = - check_all_table_vbs(TableVbs, IsNotification, [], []), - case get_tab_value_from_mib(MibEntry, TableOid, AccessVbs) of - {error, ErrorStatus, OrgIndex} -> - {error, ErrorStatus, OrgIndex}; - NVbs -> - NVbs ++ NoAccessVbs - end. - -%%----------------------------------------------------------------- -%% Make sure all requested columns are accessible. -%%----------------------------------------------------------------- -check_all_table_vbs([IVb| IVbs], IsNotification, NoA, A) -> - #ivarbind{mibentry = Me, varbind = Vb} = IVb, - case Me#me.access of - 'not-accessible' -> - NNoA = [Vb#varbind{value = noSuchInstance} | NoA], - check_all_table_vbs(IVbs, IsNotification, NNoA, A); - 'accessible-for-notify' when IsNotification =:= false -> - NNoA = [Vb#varbind{value = noSuchInstance} | NoA], - check_all_table_vbs(IVbs, IsNotification, NNoA, A); - 'write-only' -> - NNoA = [Vb#varbind{value = noSuchInstance} | NoA], - check_all_table_vbs(IVbs, IsNotification, NNoA, A); - _ -> - check_all_table_vbs(IVbs, IsNotification, NoA, [IVb | A]) - end; -check_all_table_vbs([], _IsNotification, NoA, A) -> {NoA, A}. - -%%----------------------------------------------------------------- -%% Returns: {error, ErrorStatus, OrgIndex} | -%% #varbind -%%----------------------------------------------------------------- -get_var_value_from_ivb(IVb, IsNotification) - when IVb#ivarbind.status =:= noError -> - ?vtrace("get_var_value_from_ivb(noError) -> entry", []), - #ivarbind{mibentry = Me, varbind = Vb} = IVb, - #varbind{org_index = OrgIndex, oid = Oid} = Vb, - case Me#me.access of - 'not-accessible' -> - Vb#varbind{value = noSuchInstance}; - 'accessible-for-notify' when IsNotification =:= false -> - Vb#varbind{value = noSuchInstance}; - 'write-only' -> - Vb#varbind{value = noSuchInstance}; - _ -> - case get_var_value_from_mib(Me, Oid) of - {value, Type, Value} -> - Vb#varbind{variabletype = Type, value = Value}; - {error, ErrorStatus} -> - {error, ErrorStatus, OrgIndex} - end - end; -get_var_value_from_ivb(#ivarbind{status = Status, varbind = Vb}, _) -> - ?vtrace("get_var_value_from_ivb(~p) -> entry", [Status]), - Vb#varbind{value = Status}. - -%%----------------------------------------------------------------- -%% Func: get_var_value_from_mib/1 -%% Purpose: -%% Returns: {error, ErrorStatus} | -%% {value, Type, Value} -%%----------------------------------------------------------------- -%% Pre: Oid is a correct instance Oid (lookup checked that). -%% Returns: A correct return value (see make_value_a_correct_value) -get_var_value_from_mib(#me{entrytype = variable, - asn1_type = ASN1Type, - mfa = {Mod, Func, Args}}, - _Oid) -> - ?vtrace("get_var_value_from_mib(variable) -> entry when" - "~n Mod: ~p" - "~n Func: ~p" - "~n Args: ~p", [Mod, Func, Args]), - Result = (catch dbg_apply(Mod, Func, [get | Args])), - % mib shall return {value, <a-nice-value-within-range>} | - % {noValue, noSuchName} (v1) | - % {noValue, noSuchObject | noSuchInstance} (v2, v1) - % everything else (including 'genErr') will generate 'genErr'. - make_value_a_correct_value(Result, ASN1Type, {Mod, Func, Args}); - -get_var_value_from_mib(#me{entrytype = table_column, - oid = MeOid, - asn1_type = ASN1Type, - mfa = {Mod, Func, Args}}, - Oid) -> - ?vtrace("get_var_value_from_mib(table_column) -> entry when" - "~n MeOid: ~p" - "~n Mod: ~p" - "~n Func: ~p" - "~n Args: ~p" - "~n Oid: ~p", [MeOid, Mod, Func, Args, Oid]), - Col = lists:last(MeOid), - Indexes = snmp_misc:diff(Oid, MeOid), - [Result] = (catch dbg_apply(Mod, Func, [get, Indexes, [Col] | Args])), - make_value_a_correct_value(Result, ASN1Type, - {Mod, Func, Args, Indexes, Col}). - - -%% For table operations we need to pass RestOid down to the table-function. -%% Its up to the table-function to check for noSuchInstance (ex: a -%% non-existing row). -%% Returns: {error, ErrorStatus, OrgIndex} | -%% {value, Type, Value} -get_tab_value_from_mib(#me{mfa = {Mod, Func, Args}}, TableOid, TableVbs) -> - ?vtrace("get_tab_value_from_mib -> entry when" - "~n Mod: ~p" - "~n Func: ~p" - "~n Args: ~p", [Mod, Func, Args]), - TableOpsWithShortOids = deletePrefixes(TableOid, TableVbs), - SortedVBsRows = snmpa_svbl:sort_varbinds_rows(TableOpsWithShortOids), - case get_value_all_rows(SortedVBsRows, Mod, Func, Args, []) of - {Error, Index} -> - #ivarbind{varbind = Vb} = lists:nth(Index, TableVbs), - {error, Error, Vb#varbind.org_index}; - ListOfValues -> - merge_varbinds_and_value(TableVbs, ListOfValues) - end. - -%%----------------------------------------------------------------- -%% Values is a scrambled list of {CorrectValue, Index}, where Index -%% is index into the #ivarbind list. So for each Value, we must -%% find the corresponding #ivarbind, and merge them into a new -%% #varbind. -%% The Values list comes from validate_tab_res. -%%----------------------------------------------------------------- -merge_varbinds_and_value(IVbs, [{{value, Type, Value}, Index} | Values]) -> - #ivarbind{varbind = Vb} = lists:nth(Index, IVbs), - [Vb#varbind{variabletype = Type, value = Value} | - merge_varbinds_and_value(IVbs, Values)]; -merge_varbinds_and_value(_, []) -> []. - -get_value_all_rows([{[], OrgCols} | Rows], Mod, Func, Args, Res) -> - ?vtrace("get_value_all_rows -> entry when" - "~n OrgCols: ~p", [OrgCols]), - Cols = [{{value, noValue, noSuchInstance}, Index} || - {_Col, _ASN1Type, Index} <- OrgCols], - NewRes = lists:append(Cols, Res), - get_value_all_rows(Rows, Mod, Func, Args, NewRes); -get_value_all_rows([{RowIndex, OrgCols} | Rows], Mod, Func, Args, Res) -> - ?vtrace("get_value_all_rows -> entry when" - "~n RowIndex: ~p" - "~n OrgCols: ~p", [RowIndex, OrgCols]), - {DOrgCols, Dup} = remove_duplicates(OrgCols), - Cols = delete_index(DOrgCols), - Result = (catch dbg_apply(Mod, Func, [get, RowIndex, Cols | Args])), - case validate_tab_res(Result, DOrgCols, {Mod, Func, Args}) of - Values when is_list(Values) -> - NVals = restore_duplicates(Dup, Values), - NewRes = lists:append(NVals, Res), - get_value_all_rows(Rows, Mod, Func, Args, NewRes); - {error, ErrorStatus, Index} -> - validate_err(row_set, {ErrorStatus, Index}, {Mod, Func, Args}) - end; -get_value_all_rows([], _Mod, _Func, _Args, Res) -> - ?vtrace("get_value_all_rows -> entry when done" - "~n Res: ~p", [Res]), - Res. - -%%----------------------------------------------------------------- -%% Returns: list of {ShortOid, ASN1TYpe} -%%----------------------------------------------------------------- -deletePrefixes(Prefix, [#ivarbind{varbind = Varbind, mibentry = ME} | Vbs]) -> - #varbind{oid = Oid} = Varbind, - [{snmp_misc:diff(Oid, Prefix), ME#me.asn1_type} | - deletePrefixes(Prefix, Vbs)]; -deletePrefixes(_Prefix, []) -> []. - -%%----------------------------------------------------------------- -%% Args: {RowIndex, list of {ShortOid, ASN1Type}} -%% Returns: list of Col -%%----------------------------------------------------------------- -delete_index([{Col, _Val, _OrgIndex} | T]) -> - [Col | delete_index(T)]; -delete_index([]) -> []. - -%%----------------------------------------------------------------- -%% This function is called before 'get' on a table, and removes -%% any duplicate columns. It returns {Cols, DupInfo}. The Cols -%% are the unique columns. The instrumentation function is -%% called to get the values. These values, together with the -%% DupInfo, is later passed to restore_duplicates, which uses -%% the retrieved values to reconstruct the original column list, -%% but with the retrieved value for each column. -%%----------------------------------------------------------------- -remove_duplicates(Cols) -> - remove_duplicates(Cols, [], []). - - -remove_duplicates([{Col, V1, OrgIdx1}, {Col, V2, OrgIdx2} | T], NCols, Dup) -> - remove_duplicates([{Col, V1, OrgIdx1} | T], NCols, - [{Col, V2, OrgIdx2} | Dup]); -remove_duplicates([Col | T], NCols, Dup) -> - remove_duplicates(T, [Col | NCols], Dup); -remove_duplicates([], NCols, Dup) -> - {lists:reverse(NCols), lists:reverse(Dup)}. - -restore_duplicates([], Cols) -> - [{Val, OrgIndex} || {_Col, Val, OrgIndex} <- Cols]; -restore_duplicates([{Col, _Val2, OrgIndex2} | Dup], - [{Col, NVal, OrgIndex1} | Cols]) -> - [{NVal, OrgIndex2} | - restore_duplicates(Dup, [{Col, NVal, OrgIndex1} | Cols])]; -restore_duplicates(Dup, [{_Col, Val, OrgIndex} | T]) -> - [{Val, OrgIndex} | restore_duplicates(Dup, T)]. - -%% Maps the column number to Index. -% col_to_index(0, _) -> 0; -% col_to_index(Col, [{Col, _, Index}|_]) -> -% Index; -% col_to_index(Col, [_|Cols]) -> -% col_to_index(Col, Cols). - -%%----------------------------------------------------------------- -%% Three cases: -%% 1) All values ok -%% 2) table_func returned {Error, ...} -%% 3) Some value in Values list is erroneous. -%% Args: Value is a list of values from table_func(get..) -%% OrgCols is a list with {Col, ASN1Type, OrgIndex} -%% each element in Values and OrgCols correspond to each -%% other. -%%----------------------------------------------------------------- -validate_tab_res(Values, OrgCols, Mfa) when is_list(Values) -> - {_Col, _ASN1Type, OneIdx} = hd(OrgCols), - validate_tab_res(Values, OrgCols, Mfa, [], OneIdx); -validate_tab_res({noValue, Error}, OrgCols, Mfa) -> - Values = lists:duplicate(length(OrgCols), {noValue, Error}), - validate_tab_res(Values, OrgCols, Mfa); -validate_tab_res({genErr, Col}, OrgCols, Mfa) -> - case lists:keysearch(Col, 1, OrgCols) of - {value, {_Col, _ASN1Type, Index}} -> - {error, genErr, Index}; - _ -> - user_err("Invalid column in {genErr, ~w} from ~w (get)", - [Col, Mfa]), - [{_Col, _ASN1Type, Index} | _] = OrgCols, - {error, genErr, Index} - end; -validate_tab_res(genErr, [{_Col, __ASN1Type, Index} | _OrgCols], _Mfa) -> - {error, genErr, Index}; -validate_tab_res(Error, [{_Col, _ASN1Type, Index} | _OrgCols], Mfa) -> - user_err("Invalid return value ~w from ~w (get)",[Error, Mfa]), - {error, genErr, Index}. - -validate_tab_res([Value | Values], - [{Col, ASN1Type, Index} | OrgCols], - Mfa, Res, I) -> - %% This one makes it possible to return a list of genErr, which - %% is not allowed according to the manual. But that's ok, as - %% everything else will generate a genErr! (the only problem is - %% that it won't generate a user_error). - case make_value_a_correct_value(Value, ASN1Type, Mfa) of - {error, ErrorStatus} -> - {error, ErrorStatus, Index}; - CorrectValue -> - NewRes = [{Col, CorrectValue, Index} | Res], - validate_tab_res(Values, OrgCols, Mfa, NewRes, I) - end; -validate_tab_res([], [], _Mfa, Res, _I) -> - lists:reverse(Res); -validate_tab_res([], [{_Col, _ASN1Type, Index}|_], Mfa, _Res, _I) -> - user_err("Too few values returned from ~w (get)", [Mfa]), - {error, genErr, Index}; -validate_tab_res(_TooMany, [], Mfa, _Res, I) -> - user_err("Too many values returned from ~w (get)", [Mfa]), - {error, genErr, I}. %%%----------------------------------------------------------------- @@ -3125,491 +2780,12 @@ validate_tab_res(_TooMany, [], Mfa, _Res, I) -> %% subagent must be considered to be very rare. %%----------------------------------------------------------------- -%% It may be a bit agressive to check this already, -%% but since it is a security measure, it makes sense. -do_get_next(_MibView, UnsortedVarbinds, GbMaxVBs) - when (is_integer(GbMaxVBs) andalso (length(UnsortedVarbinds) > GbMaxVBs)) -> - {tooBig, 0, []}; % What is the correct index in this case? -do_get_next(MibView, UnsortedVBs, GbMaxVBs) -> - ?vt("do_get_next -> entry when" - "~n MibView: ~p" - "~n UnsortedVBs: ~p", [MibView, UnsortedVBs]), - SortedVBs = oid_sort_vbs(UnsortedVBs), - ?vt("do_get_next -> " - "~n SortedVBs: ~p", [SortedVBs]), - next_loop_varbinds([], SortedVBs, MibView, [], [], GbMaxVBs). - -oid_sort_vbs(Vbs) -> - lists:keysort(#varbind.oid, Vbs). - -next_loop_varbinds(_, Vbs, _MibView, Res, _LAVb, GbMaxVBs) - when (is_integer(GbMaxVBs) andalso - ((length(Vbs) + length(Res)) > GbMaxVBs)) -> - {tooBig, 0, []}; % What is the correct index in this case? - -%% LAVb is Last Accessible Vb -next_loop_varbinds([], [Vb | Vbs], MibView, Res, LAVb, GbMaxVBs) -> - ?vt("next_loop_varbinds -> entry when" - "~n Vb: ~p" - "~n MibView: ~p", [Vb, MibView]), - case varbind_next(Vb, MibView) of - endOfMibView -> - ?vt("next_loop_varbind -> endOfMibView", []), - RVb = if LAVb =:= [] -> Vb; - true -> LAVb - end, - NewVb = RVb#varbind{variabletype = 'NULL', value = endOfMibView}, - next_loop_varbinds([], Vbs, MibView, [NewVb | Res], [], GbMaxVBs); - - {variable, ME, VarOid} when ((ME#me.access =/= 'not-accessible') andalso - (ME#me.access =/= 'write-only') andalso - (ME#me.access =/= 'accessible-for-notify')) -> - ?vt("next_loop_varbind -> variable: " - "~n ME: ~p" - "~n VarOid: ~p", [ME, VarOid]), - case try_get_instance(Vb, ME) of - {value, noValue, _NoSuchSomething} -> - ?vt("next_loop_varbind -> noValue", []), - %% Try next one - NewVb = Vb#varbind{oid = VarOid, - value = 'NULL'}, - next_loop_varbinds([], [NewVb | Vbs], MibView, Res, [], - GbMaxVBs); - {value, Type, Value} -> - ?vt("next_loop_varbind -> value" - "~n Type: ~p" - "~n Value: ~p", [Type, Value]), - NewVb = Vb#varbind{oid = VarOid, - variabletype = Type, - value = Value}, - next_loop_varbinds([], Vbs, MibView, [NewVb | Res], [], - GbMaxVBs); - {error, ErrorStatus} -> - ?vdebug("next loop varbinds:" - "~n ErrorStatus: ~p",[ErrorStatus]), - {ErrorStatus, Vb#varbind.org_index, []} - end; - {variable, _ME, VarOid} -> - ?vt("next_loop_varbind -> variable: " - "~n VarOid: ~p", [VarOid]), - RVb = if LAVb =:= [] -> Vb; - true -> LAVb - end, - NewVb = Vb#varbind{oid = VarOid, value = 'NULL'}, - next_loop_varbinds([], [NewVb | Vbs], MibView, Res, RVb, GbMaxVBs); - {table, TableOid, TableRestOid, ME} -> - ?vt("next_loop_varbind -> table: " - "~n TableOid: ~p" - "~n TableRestOid: ~p" - "~n ME: ~p", [TableOid, TableRestOid, ME]), - next_loop_varbinds({table, TableOid, ME, - [{tab_oid(TableRestOid), Vb}]}, - Vbs, MibView, Res, [], GbMaxVBs); - {subagent, SubAgentPid, SAOid} -> - ?vt("next_loop_varbind -> subagent: " - "~n SubAgentPid: ~p" - "~n SAOid: ~p", [SubAgentPid, SAOid]), - NewVb = Vb#varbind{variabletype = 'NULL', value = 'NULL'}, - next_loop_varbinds({subagent, SubAgentPid, SAOid, [NewVb]}, - Vbs, MibView, Res, [], GbMaxVBs) - end; -next_loop_varbinds({table, TableOid, ME, TabOids}, - [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) -> - ?vt("next_loop_varbinds(table) -> entry with" - "~n TableOid: ~p" - "~n Vb: ~p", [TableOid, Vb]), - case varbind_next(Vb, MibView) of - {table, TableOid, TableRestOid, _ME} -> - next_loop_varbinds({table, TableOid, ME, - [{tab_oid(TableRestOid), Vb} | TabOids]}, - Vbs, MibView, Res, [], GbMaxVBs); - _ -> - case get_next_table(ME, TableOid, TabOids, MibView) of - {ok, TabRes, TabEndOfTabVbs} -> - NewVbs = lists:append(TabEndOfTabVbs, [Vb | Vbs]), - NewRes = lists:append(TabRes, Res), - next_loop_varbinds([], NewVbs, MibView, NewRes, [], - GbMaxVBs); - {ErrorStatus, OrgIndex} -> - ?vdebug("next loop varbinds: next varbind" - "~n ErrorStatus: ~p" - "~n OrgIndex: ~p", - [ErrorStatus,OrgIndex]), - {ErrorStatus, OrgIndex, []} - end - end; -next_loop_varbinds({table, TableOid, ME, TabOids}, - [], MibView, Res, _LAVb, GbMaxVBs) -> - ?vt("next_loop_varbinds(table) -> entry with" - "~n TableOid: ~p", [TableOid]), - case get_next_table(ME, TableOid, TabOids, MibView) of - {ok, TabRes, TabEndOfTabVbs} -> - ?vt("next_loop_varbinds(table) -> get_next_table result:" - "~n TabRes: ~p" - "~n TabEndOfTabVbs: ~p", [TabRes, TabEndOfTabVbs]), - NewRes = lists:append(TabRes, Res), - next_loop_varbinds([], TabEndOfTabVbs, MibView, NewRes, [], - GbMaxVBs); - {ErrorStatus, OrgIndex} -> - ?vdebug("next loop varbinds: next table" - "~n ErrorStatus: ~p" - "~n OrgIndex: ~p", - [ErrorStatus,OrgIndex]), - {ErrorStatus, OrgIndex, []} - end; -next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, - [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) -> - ?vt("next_loop_varbinds(subagent) -> entry with" - "~n SAPid: ~p" - "~n SAOid: ~p" - "~n Vb: ~p", [SAPid, SAOid, Vb]), - case varbind_next(Vb, MibView) of - {subagent, _SubAgentPid, SAOid} -> - next_loop_varbinds({subagent, SAPid, SAOid, - [Vb | SAVbs]}, - Vbs, MibView, Res, [], GbMaxVBs); - _ -> - case get_next_sa(SAPid, SAOid, SAVbs, MibView) of - {ok, SARes, SAEndOfMibViewVbs} -> - NewVbs = lists:append(SAEndOfMibViewVbs, [Vb | Vbs]), - NewRes = lists:append(SARes, Res), - next_loop_varbinds([], NewVbs, MibView, NewRes, [], - GbMaxVBs); - {noSuchName, OrgIndex} -> - %% v1 reply, treat this Vb as endOfMibView, and try again - %% for the others. - case lists:keysearch(OrgIndex, #varbind.org_index, SAVbs) of - {value, EVb} -> - NextOid = next_oid(SAOid), - EndOfVb = - EVb#varbind{oid = NextOid, - value = {endOfMibView, NextOid}}, - case lists:delete(EVb, SAVbs) of - [] -> - next_loop_varbinds([], [EndOfVb, Vb | Vbs], - MibView, Res, [], - GbMaxVBs); - TryAgainVbs -> - next_loop_varbinds({subagent, SAPid, SAOid, - TryAgainVbs}, - [EndOfVb, Vb | Vbs], - MibView, Res, [], - GbMaxVBs) - end; - false -> - %% bad index from subagent - {genErr, (hd(SAVbs))#varbind.org_index, []} - end; - {ErrorStatus, OrgIndex} -> - ?vdebug("next loop varbinds: next subagent" - "~n Vb: ~p" - "~n ErrorStatus: ~p" - "~n OrgIndex: ~p", - [Vb,ErrorStatus,OrgIndex]), - {ErrorStatus, OrgIndex, []} - end - end; -next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, - [], MibView, Res, _LAVb, GbMaxVBs) -> - ?vt("next_loop_varbinds(subagent) -> entry with" - "~n SAPid: ~p" - "~n SAOid: ~p", [SAPid, SAOid]), - case get_next_sa(SAPid, SAOid, SAVbs, MibView) of - {ok, SARes, SAEndOfMibViewVbs} -> - NewRes = lists:append(SARes, Res), - next_loop_varbinds([], SAEndOfMibViewVbs, MibView, NewRes, [], - GbMaxVBs); - {noSuchName, OrgIndex} -> - %% v1 reply, treat this Vb as endOfMibView, and try again for - %% the others. - case lists:keysearch(OrgIndex, #varbind.org_index, SAVbs) of - {value, EVb} -> - NextOid = next_oid(SAOid), - EndOfVb = EVb#varbind{oid = NextOid, - value = {endOfMibView, NextOid}}, - case lists:delete(EVb, SAVbs) of - [] -> - next_loop_varbinds([], [EndOfVb], MibView, Res, [], - GbMaxVBs); - TryAgainVbs -> - next_loop_varbinds({subagent, SAPid, SAOid, - TryAgainVbs}, - [EndOfVb], MibView, Res, [], - GbMaxVBs) - end; - false -> - %% bad index from subagent - {genErr, (hd(SAVbs))#varbind.org_index, []} - end; - {ErrorStatus, OrgIndex} -> - ?vdebug("next loop varbinds: next subagent" - "~n ErrorStatus: ~p" - "~n OrgIndex: ~p", - [ErrorStatus,OrgIndex]), - {ErrorStatus, OrgIndex, []} - end; -next_loop_varbinds([], [], _MibView, Res, _LAVb, _GbMaxVBs) -> - ?vt("next_loop_varbinds -> entry when done", []), - {noError, 0, Res}. - -try_get_instance(_Vb, #me{mfa = {M, F, A}, asn1_type = ASN1Type}) -> - ?vtrace("try_get_instance -> entry with" - "~n M: ~p" - "~n F: ~p" - "~n A: ~p", [M,F,A]), - Result = (catch dbg_apply(M, F, [get | A])), - % mib shall return {value, <a-nice-value-within-range>} | - % {noValue, noSuchName} (v1) | - % {noValue, noSuchObject | noSuchInstance} (v2, v1) - % everything else (including 'genErr') will generate 'genErr'. - make_value_a_correct_value(Result, ASN1Type, {M, F, A}). - -tab_oid([]) -> [0]; -tab_oid(X) -> X. - - -%%----------------------------------------------------------------- -%% Perform a next, using the varbinds Oid if value is simple -%% value. If value is {endOf<something>, NextOid}, use NextOid. -%% This case happens when a table has returned endOfTable, or -%% a subagent has returned endOfMibView. -%%----------------------------------------------------------------- -varbind_next(#varbind{value = Value, oid = Oid}, MibView) -> - ?vt("varbind_next -> entry with" - "~n Value: ~p" - "~n Oid: ~p" - "~n MibView: ~p", [Value, Oid, MibView]), - case Value of - {endOfTable, NextOid} -> - snmpa_mib:next(get(mibserver), NextOid, MibView); - {endOfMibView, NextOid} -> - snmpa_mib:next(get(mibserver), NextOid, MibView); - _ -> - snmpa_mib:next(get(mibserver), Oid, MibView) - end. - -get_next_table(#me{mfa = {M, F, A}}, TableOid, TableOids, MibView) -> - % We know that all TableOids have at least a column number as oid - ?vt("get_next_table -> entry with" - "~n M: ~p" - "~n F: ~p" - "~n A: ~p" - "~n TableOid: ~p" - "~n TableOids: ~p" - "~n MibView: ~p", [M, F, A, TableOid, TableOids, MibView]), - Sorted = snmpa_svbl:sort_varbinds_rows(TableOids), - case get_next_values_all_rows(Sorted, M,F,A, [], TableOid) of - NewVbs when is_list(NewVbs) -> - ?vt("get_next_table -> " - "~n NewVbs: ~p", [NewVbs]), - % We must now check each Vb for endOfTable and that it is - % in the MibView. If not, it becomes a endOfTable. We - % collect all of these together. - transform_tab_next_result(NewVbs, {[], []}, MibView); - {ErrorStatus, OrgIndex} -> - {ErrorStatus, OrgIndex} - end. - -get_next_values_all_rows([Row | Rows], M, F, A, Res, TabOid) -> - {RowIndex, TableOids} = Row, - Cols = delete_index(TableOids), - ?vt("get_next_values_all_rows -> " - "~n Cols: ~p", [Cols]), - Result = (catch dbg_apply(M, F, [get_next, RowIndex, Cols | A])), - ?vt("get_next_values_all_rows -> " - "~n Result: ~p", [Result]), - case validate_tab_next_res(Result, TableOids, {M, F, A}, TabOid) of - Values when is_list(Values) -> - ?vt("get_next_values_all_rows -> " - "~n Values: ~p", [Values]), - NewRes = lists:append(Values, Res), - get_next_values_all_rows(Rows, M, F, A, NewRes, TabOid); - {ErrorStatus, OrgIndex} -> - {ErrorStatus, OrgIndex} - end; -get_next_values_all_rows([], _M, _F, _A, Res, _TabOid) -> - Res. - -transform_tab_next_result([Vb | Vbs], {Res, EndOfs}, MibView) -> - case Vb#varbind.value of - {endOfTable, _} -> -%% ?vtrace("transform_tab_next_result -> endOfTable: " -%% "split varbinds",[]), -%% R = split_varbinds(Vbs, Res, [Vb | EndOfs]), -%% ?vtrace("transform_tab_next_result -> " -%% "~n R: ~p", [R]), -%% R; - split_varbinds(Vbs, Res, [Vb | EndOfs]); - _ -> - case snmpa_acm:validate_mib_view(Vb#varbind.oid, MibView) of - true -> - transform_tab_next_result(Vbs, {[Vb|Res], EndOfs},MibView); - _ -> - Oid = Vb#varbind.oid, - NewEndOf = Vb#varbind{value = {endOfTable, Oid}}, - transform_tab_next_result(Vbs, {Res, [NewEndOf | EndOfs]}, - MibView) - end - end; -transform_tab_next_result([], {Res, EndOfs}, _MibView) -> - ?vt("transform_tab_next_result -> entry with: " - "~n Res: ~p" - "~n EndIfs: ~p",[Res, EndOfs]), - {ok, Res, EndOfs}. - -%%----------------------------------------------------------------- -%% Three cases: -%% 1) All values ok -%% 2) table_func returned {Error, ...} -%% 3) Some value in Values list is erroneous. -%% Args: Value is a list of values from table_func(get_next, ...) -%% TableOids is a list of {TabRestOid, OrgVb} -%% each element in Values and TableOids correspond to each -%% other. -%% Returns: List of NewVarbinds | -%% {ErrorStatus, OrgIndex} -%% (In the NewVarbinds list, the value may be endOfTable) -%%----------------------------------------------------------------- -validate_tab_next_res(Values, TableOids, Mfa, TabOid) -> - ?vt("validate_tab_next_res -> entry with: " - "~n Values: ~p" - "~n TableOids: ~p" - "~n Mfa: ~p" - "~n TabOid: ~p", [Values, TableOids, Mfa, TabOid]), - {_Col, _ASN1Type, OneIdx} = hd(TableOids), - validate_tab_next_res(Values, TableOids, Mfa, [], TabOid, - next_oid(TabOid), OneIdx). -validate_tab_next_res([{NextOid, Value} | Values], - [{_ColNo, OrgVb, _Index} | TableOids], - Mfa, Res, TabOid, TabNextOid, I) -> - ?vt("validate_tab_next_res -> entry with: " - "~n NextOid: ~p" - "~n Value: ~p" - "~n Values: ~p" - "~n TableOids: ~p" - "~n Mfa: ~p" - "~n TabOid: ~p", - [NextOid, Value, Values, TableOids, Mfa, TabOid]), - #varbind{org_index = OrgIndex} = OrgVb, - ?vt("validate_tab_next_res -> OrgIndex: ~p", [OrgIndex]), - NextCompleteOid = lists:append(TabOid, NextOid), - case snmpa_mib:lookup(get(mibserver), NextCompleteOid) of - {table_column, #me{asn1_type = ASN1Type}, _TableEntryOid} -> - ?vt("validate_tab_next_res -> ASN1Type: ~p", [ASN1Type]), - case make_value_a_correct_value({value, Value}, ASN1Type, Mfa) of - {error, ErrorStatus} -> - ?vt("validate_tab_next_res -> " - "~n ErrorStatus: ~p", [ErrorStatus]), - {ErrorStatus, OrgIndex}; - {value, Type, NValue} -> - ?vt("validate_tab_next_res -> " - "~n Type: ~p" - "~n NValue: ~p", [Type, NValue]), - NewVb = OrgVb#varbind{oid = NextCompleteOid, - variabletype = Type, value = NValue}, - validate_tab_next_res(Values, TableOids, Mfa, - [NewVb | Res], TabOid, TabNextOid, I) - end; - Error -> - user_err("Invalid oid ~w from ~w (get_next). Using genErr => ~p", - [NextOid, Mfa, Error]), - {genErr, OrgIndex} - end; -validate_tab_next_res([endOfTable | Values], - [{_ColNo, OrgVb, _Index} | TableOids], - Mfa, Res, TabOid, TabNextOid, I) -> - ?vt("validate_tab_next_res(endOfTable) -> entry with: " - "~n Values: ~p" - "~n OrgVb: ~p" - "~n TableOids: ~p" - "~n Mfa: ~p" - "~n Res: ~p" - "~n TabOid: ~p" - "~n TabNextOid: ~p" - "~n I: ~p", - [Values, OrgVb, TableOids, Mfa, Res, TabOid, TabNextOid, I]), - NewVb = OrgVb#varbind{value = {endOfTable, TabNextOid}}, - validate_tab_next_res(Values, TableOids, Mfa, [NewVb | Res], - TabOid, TabNextOid, I); -validate_tab_next_res([], [], _Mfa, Res, _TabOid, _TabNextOid, _I) -> - Res; -validate_tab_next_res([], [{_Col, _OrgVb, Index}|_], Mfa, _Res, _, _, _I) -> - user_err("Too few values returned from ~w (get_next)", [Mfa]), - {genErr, Index}; -validate_tab_next_res({genErr, ColNumber}, OrgCols, - Mfa, _Res, _TabOid, _TabNextOid, _I) -> - OrgIndex = snmpa_svbl:col_to_orgindex(ColNumber, OrgCols), - validate_err(table_next, {genErr, OrgIndex}, Mfa); -validate_tab_next_res({error, Reason}, [{_ColNo, OrgVb, _Index} | _TableOids], - Mfa, _Res, _TabOid, _TabNextOid, _I) -> - #varbind{org_index = OrgIndex} = OrgVb, - user_err("Erroneous return value ~w from ~w (get_next)", - [Reason, Mfa]), - {genErr, OrgIndex}; -validate_tab_next_res(Error, [{_ColNo, OrgVb, _Index} | _TableOids], - Mfa, _Res, _TabOid, _TabNextOid, _I) -> - #varbind{org_index = OrgIndex} = OrgVb, - user_err("Invalid return value ~w from ~w (get_next)", - [Error, Mfa]), - {genErr, OrgIndex}; -validate_tab_next_res(TooMany, [], Mfa, _Res, _, _, I) -> - user_err("Too many values ~w returned from ~w (get_next)", - [TooMany, Mfa]), - {genErr, I}. - -%%----------------------------------------------------------------- -%% Func: get_next_sa/4 -%% Purpose: Loop the list of varbinds for the subagent. -%% Call subagent_get_next to retreive -%% the next varbinds. -%% Returns: {ok, ListOfNewVbs, ListOfEndOfMibViewsVbs} | -%% {ErrorStatus, ErrorIndex} -%%----------------------------------------------------------------- -get_next_sa(SAPid, SAOid, SAVbs, MibView) -> - case catch subagent_get_next(SAPid, MibView, SAVbs) of - {noError, 0, NewVbs} -> - NewerVbs = transform_sa_next_result(NewVbs,SAOid,next_oid(SAOid)), - split_varbinds(NewerVbs, [], []); - {ErrorStatus, ErrorIndex, _} -> - {ErrorStatus, ErrorIndex}; - {'EXIT', Reason} -> - user_err("Lost contact with subagent (next) ~w. Using genErr", - [Reason]), - {genErr, 0} - end. -%%----------------------------------------------------------------- -%% Check for wrong prefix returned or endOfMibView, and convert -%% into {endOfMibView, SANextOid}. -%%----------------------------------------------------------------- -transform_sa_next_result([Vb | Vbs], SAOid, SANextOid) - when Vb#varbind.value =:= endOfMibView -> - [Vb#varbind{value = {endOfMibView, SANextOid}} | - transform_sa_next_result(Vbs, SAOid, SANextOid)]; -transform_sa_next_result([Vb | Vbs], SAOid, SANextOid) -> - case lists:prefix(SAOid, Vb#varbind.oid) of - true -> - [Vb | transform_sa_next_result(Vbs, SAOid, SANextOid)]; - _ -> - [Vb#varbind{oid = SANextOid, value = {endOfMibView, SANextOid}} | - transform_sa_next_result(Vbs, SAOid, SANextOid)] - end; -transform_sa_next_result([], _SAOid, _SANextOid) -> - []. - -split_varbinds([Vb | Vbs], Res, EndOfs) -> - case Vb#varbind.value of - {endOfMibView, _} -> split_varbinds(Vbs, Res, [Vb | EndOfs]); - {endOfTable, _} -> split_varbinds(Vbs, Res, [Vb | EndOfs]); - _ -> split_varbinds(Vbs, [Vb | Res], EndOfs) - end; -split_varbinds([], Res, EndOfs) -> {ok, Res, EndOfs}. +do_get_next(MibView, UnsortedVarbinds) -> + Extra = get(net_if_data), + GetModule = get(get_module), + GetModule:do_get_next(MibView, UnsortedVarbinds, Extra). -next_oid(Oid) -> - case lists:reverse(Oid) of - [H | T] -> lists:reverse([H+1 | T]); - [] -> [] - end. %%%----------------------------------------------------------------- @@ -3623,200 +2799,12 @@ next_oid(Oid) -> %%%----------------------------------------------------------------- do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds, GbMaxVBs) -> - ?vtrace("do_get_bulk -> entry with" - "~n MibView: ~p" - "~n NonRepeaters: ~p" - "~n MaxRepetitions: ~p" - "~n PduMS: ~p" - "~n Varbinds: ~p" - "~n GbMaxVBs: ~p", - [MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds, GbMaxVBs]), - {NonRepVbs, RestVbs} = split_vbs(NonRepeaters, Varbinds, []), - ?vt("do_get_bulk -> split: " - "~n NonRepVbs: ~p" - "~n RestVbs: ~p", [NonRepVbs, RestVbs]), - case do_get_next(MibView, NonRepVbs, GbMaxVBs) of - {noError, 0, UResNonRepVbs} -> - ?vt("do_get_bulk -> next noError: " - "~n UResNonRepVbs: ~p", [UResNonRepVbs]), - ResNonRepVbs = lists:keysort(#varbind.org_index, UResNonRepVbs), - %% Decode the first varbinds, produce a reversed list of - %% listOfBytes. - case (catch enc_vbs(PduMS - ?empty_pdu_size, ResNonRepVbs)) of - {error, Idx, Reason} -> - user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]), - {genErr, Idx, []}; - {SizeLeft, Res} when is_integer(SizeLeft) and is_list(Res) -> - ?vtrace("do_get_bulk -> encoded: " - "~n SizeLeft: ~p" - "~n Res: ~w", [SizeLeft, Res]), - case (catch do_get_rep(SizeLeft, MibView, MaxRepetitions, - RestVbs, Res, - length(UResNonRepVbs), GbMaxVBs)) of - {error, Idx, Reason} -> - user_err("failed encoding varbind ~w:~n~p", - [Idx, Reason]), - {genErr, Idx, []}; - Res when is_list(Res) -> - ?vtrace("do get bulk -> Res: " - "~n ~w", [Res]), - {noError, 0, conv_res(Res)}; - {noError, 0, Data} = OK -> - ?vtrace("do get bulk -> OK: " - "~n length(Data): ~w", [length(Data)]), - OK; - Else -> - ?vtrace("do get bulk -> Else: " - "~n ~w", [Else]), - Else - end; - Res when is_list(Res) -> - {noError, 0, conv_res(Res)} - end; + Extra = get(net_if_data), + GetModule = get(get_module), + GetModule:do_get_bulk(MibView, NonRepeaters, MaxRepetitions, + PduMS, Varbinds, GbMaxVBs, + Extra). - {ErrorStatus, Index, _} -> - ?vdebug("do get bulk: " - "~n ErrorStatus: ~p" - "~n Index: ~p",[ErrorStatus, Index]), - {ErrorStatus, Index, []} - end. - -% sz(L) when list(L) -> length(L); -% sz(B) when binary(B) -> size(B); -% sz(_) -> unknown. - -split_vbs(N, Varbinds, Res) when N =< 0 -> {Res, Varbinds}; -split_vbs(N, [H | T], Res) -> split_vbs(N-1, T, [H | Res]); -split_vbs(_N, [], Res) -> {Res, []}. - -enc_vbs(SizeLeft, Vbs) -> - ?vt("enc_vbs -> entry with" - "~n SizeLeft: ~w", [SizeLeft]), - Fun = fun(Vb, {Sz, Res}) when Sz > 0 -> - ?vt("enc_vbs -> (fun) entry with" - "~n Vb: ~p" - "~n Sz: ~p" - "~n Res: ~w", [Vb, Sz, Res]), - case (catch snmp_pdus:enc_varbind(Vb)) of - {'EXIT', Reason} -> - ?vtrace("enc_vbs -> encode failed: " - "~n Reason: ~p", [Reason]), - throw({error, Vb#varbind.org_index, Reason}); - X -> - ?vt("enc_vbs -> X: ~w", [X]), - Lx = length(X), - ?vt("enc_vbs -> Lx: ~w", [Lx]), - if - Lx < Sz -> - {Sz - length(X), [X | Res]}; - true -> - throw(Res) - end - end; - (_Vb, {_Sz, [_H | T]}) -> - ?vt("enc_vbs -> (fun) entry with" - "~n T: ~p", [T]), - throw(T); - (_Vb, {_Sz, []}) -> - ?vt("enc_vbs -> (fun) entry", []), - throw([]) - end, - lists:foldl(Fun, {SizeLeft, []}, Vbs). - -do_get_rep(Sz, MibView, MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs) - when MaxRepetitions >= 0 -> - do_get_rep(Sz, MibView, 0, MaxRepetitions, Varbinds, Res, - GbNumVBs, GbMaxVBs); -do_get_rep(Sz, MibView, _MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs) -> - do_get_rep(Sz, MibView, 0, 0, Varbinds, Res, GbNumVBs, GbMaxVBs). - -conv_res(ResVarbinds) -> - conv_res(ResVarbinds, []). -conv_res([VbListOfBytes | T], Bytes) -> - conv_res(T, VbListOfBytes ++ Bytes); -conv_res([], Bytes) -> - Bytes. - -%% The only other value, then a positive integer, is infinity. -do_get_rep(_Sz, _MibView, Count, Max, _, _Res, GbNumVBs, GbMaxVBs) - when (is_integer(GbMaxVBs) andalso (GbNumVBs > GbMaxVBs)) -> - ?vinfo("Max Get-BULK VBs limit (~w) exceeded (~w) when:" - "~n Count: ~p" - "~n Max: ~p", [GbMaxVBs, GbNumVBs, Count, Max]), - {tooBig, 0, []}; -do_get_rep(_Sz, _MibView, Max, Max, _, Res, _GbNumVBs, _GbMaxVBs) -> - ?vt("do_get_rep -> done when: " - "~n Res: ~p", [Res]), - {noError, 0, conv_res(Res)}; -do_get_rep(Sz, MibView, Count, Max, Varbinds, Res, GbNumVBs, GbMaxVBs) -> - ?vt("do_get_rep -> entry when: " - "~n Sz: ~p" - "~n Count: ~p" - "~n Res: ~w", [Sz, Count, Res]), - case try_get_bulk(Sz, MibView, Varbinds, GbMaxVBs) of - {noError, NextVarbinds, SizeLeft, Res2} -> - ?vt("do_get_rep -> noError: " - "~n SizeLeft: ~p" - "~n Res2: ~p", [SizeLeft, Res2]), - do_get_rep(SizeLeft, MibView, Count+1, Max, NextVarbinds, - Res2 ++ Res, - GbNumVBs + length(Varbinds), GbMaxVBs); - {endOfMibView, _NextVarbinds, _SizeLeft, Res2} -> - ?vt("do_get_rep -> endOfMibView: " - "~n Res2: ~p", [Res2]), - {noError, 0, conv_res(Res2 ++ Res)}; - {ErrorStatus, Index} -> - ?vtrace("do_get_rep -> done when error: " - "~n ErrorStatus: ~p" - "~n Index: ~p", [ErrorStatus, Index]), - {ErrorStatus, Index, []} - end. - -org_index_sort_vbs(Vbs) -> - lists:keysort(#varbind.org_index, Vbs). - -try_get_bulk(Sz, MibView, Varbinds, GbMaxVBs) -> - ?vt("try_get_bulk -> entry with" - "~n Sz: ~w" - "~n MibView: ~w" - "~n Varbinds: ~w", [Sz, MibView, Varbinds]), - case do_get_next(MibView, Varbinds, GbMaxVBs) of - {noError, 0, UNextVarbinds} -> - ?vt("try_get_bulk -> noError: " - "~n UNextVarbinds: ~p", [UNextVarbinds]), - NextVarbinds = org_index_sort_vbs(UNextVarbinds), - case (catch enc_vbs(Sz, NextVarbinds)) of - {error, Idx, Reason} -> - user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]), - ?vtrace("try_get_bulk -> encode error: " - "~n Idx: ~p" - "~n Reason: ~p", [Idx, Reason]), - {genErr, Idx}; - {SizeLeft, Res} when is_integer(SizeLeft) andalso - is_list(Res) -> - ?vt("try get bulk -> encode ok: " - "~n SizeLeft: ~w" - "~n Res: ~w", [SizeLeft, Res]), - {check_end_of_mibview(NextVarbinds), - NextVarbinds, SizeLeft, Res}; - Res when is_list(Res) -> - ?vt("try get bulk -> Res: " - "~n ~w", [Res]), - {endOfMibView, [], 0, Res} - end; - {ErrorStatus, Index, _} -> - ?vt("try_get_bulk -> error: " - "~n ErrorStatus: ~p" - "~n Index: ~p", [ErrorStatus, Index]), - {ErrorStatus, Index} - end. - -%% If all variables in this pass are endOfMibView, -%% there is no reason to continue. -check_end_of_mibview([#varbind{value = endOfMibView} | T]) -> - check_end_of_mibview(T); -check_end_of_mibview([]) -> endOfMibView; -check_end_of_mibview(_) -> noError. %%%-------------------------------------------------- @@ -3834,14 +2822,11 @@ do_subagent_set(Arguments) -> SetModule = get(set_module), apply(SetModule, do_subagent_set, [Arguments]). + + %%%----------------------------------------------------------------- %%% 7. Misc functions %%%----------------------------------------------------------------- -sort_varbindlist(Varbinds) -> - snmpa_svbl:sort_varbindlist(get(mibserver), Varbinds). - -sa_split(SubagentVarbinds) -> - snmpa_svbl:sa_split(SubagentVarbinds). make_response_pdu(ReqId, ErrStatus, ErrIndex, OrgVarbinds, _ResponseVarbinds) when ErrIndex =/= 0 -> @@ -4139,6 +3124,7 @@ report_err(Val, Mfa, Err) -> user_err("Got ~p from ~w. Using ~w", [Val, Mfa, Err]), {error, Err}. + is_valid_pdu_type('get-request') -> true; is_valid_pdu_type('get-next-request') -> true; is_valid_pdu_type('get-bulk-request') -> true; @@ -4176,33 +3162,8 @@ mapfoldl(F, Eas, Accu0, [Hd|Tail]) -> mapfoldl(_F, _Eas, Accu, []) -> {Accu,[]}. -%%----------------------------------------------------------------- -%% Runtime debugging of the agent. -%%----------------------------------------------------------------- - -dbg_apply(M,F,A) -> - case get(verbosity) of - silence -> - apply(M,F,A); - _ -> - ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]), - Res = (catch apply(M,F,A)), - case Res of - {'EXIT', Reason} -> - ?vinfo("Call to: " - "~n Module: ~p" - "~n Function: ~p" - "~n Args: ~p" - "~n" - "~nresulted in an exit" - "~n" - "~n ~p", [M, F, A, Reason]); - _ -> - ?vlog("~n returned: ~p", [Res]) - end, - Res - end. +%% --------------------------------------------------------------------- short_name(none) -> ma; short_name(_Pid) -> sa. @@ -4450,6 +3411,9 @@ get_mib_storage(Opts) -> get_set_mechanism(Opts) -> get_option(set_mechanism, Opts, snmpa_set). +get_get_mechanism(Opts) -> + get_option(get_mechanism, Opts, snmpa_get). + get_authentication_service(Opts) -> get_option(authentication_service, Opts, snmpa_acm). diff --git a/lib/snmp/src/agent/snmpa_app.erl b/lib/snmp/src/agent/snmpa_app.erl index 86ff145e93..c00929c334 100644 --- a/lib/snmp/src/agent/snmpa_app.erl +++ b/lib/snmp/src/agent/snmpa_app.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2016. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -67,6 +67,7 @@ convert_config(Opts) -> SaVerb = get_sub_agent_verbosity(Opts), [{agent_type, AgentType}, {agent_verbosity, SaVerb}, + {get_mechanism, snmpa_get}, {set_mechanism, SetModule}, {authentication_service, AuthModule}, {priority, Prio}, @@ -97,6 +98,7 @@ convert_config(Opts) -> {verbosity, ConfVerb}], [{agent_type, AgentType}, {agent_verbosity, MaVerb}, + {get_mechanism, snmpa_get}, {set_mechanism, SetModule}, {authentication_service, AuthModule}, {db_dir, DbDir}, diff --git a/lib/snmp/src/agent/snmpa_get.erl b/lib/snmp/src/agent/snmpa_get.erl new file mode 100644 index 0000000000..e67975a67d --- /dev/null +++ b/lib/snmp/src/agent/snmpa_get.erl @@ -0,0 +1,1150 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(snmpa_get). + +-behaviour(snmpa_get_mechanism). + + +%%%----------------------------------------------------------------- +%%% snmpa_get_mechanism exports +%%%----------------------------------------------------------------- + +-export([ + do_get/3, do_get/4, + do_get_next/3, + do_get_bulk/7 + ]). + +-define(VMODULE,"GET"). +-include("snmpa_internal.hrl"). +-include("snmp_types.hrl"). +-include("snmp_debug.hrl"). +-include("snmp_verbosity.hrl"). + +-ifndef(default_verbosity). +-define(default_verbosity,silence). +-endif. + +-define(empty_pdu_size, 21). + +-ifdef(snmp_extended_verbosity). +-define(vt(F,A), ?vtrace(F, A)). +-else. +-define(vt(_F, _A), ok). +-endif. + + +-define(AGENT, snmpa_agent). +-define(LIB, snmpa_get_lib). + + + +%%%----------------------------------------------------------------- +%%% 3. GET REQUEST +%%% -------------- +%%% According to RFC1157, section 4.1.2 and RFC1905, section 4.2.1. +%%% In rfc1157:4.1.2 it isn't specified if noSuchName should be +%%% returned even if some other varbind generates a genErr. +%%% In rfc1905:4.2.1 this is not a problem since exceptions are +%%% used, and thus a genErr will be returned anyway. +%%%----------------------------------------------------------------- + +%%----------------------------------------------------------------- +%% Func: do_get/2 +%% Purpose: Handles all VBs in a request that is inside the +%% mibview (local). +%% Returns: {noError, 0, ListOfNewVarbinds} | +%% {ErrorStatus, ErrorIndex, []} +%%----------------------------------------------------------------- + +do_get(UnsortedVarbinds, IsNotification, _Extra) -> + {MyVarbinds, SubagentVarbinds} = ?LIB:agent_sort_vbs(UnsortedVarbinds), + case do_get_local(MyVarbinds, IsNotification) of + {noError, 0, NewMyVarbinds} -> + case do_get_subagents(SubagentVarbinds, IsNotification) of + {noError, 0, NewSubagentVarbinds} -> + {noError, 0, NewMyVarbinds ++ NewSubagentVarbinds}; + {ErrorStatus, ErrorIndex, _} -> + {ErrorStatus, ErrorIndex, []} + end; + {ErrorStatus, ErrorIndex, _} -> + {ErrorStatus, ErrorIndex, []} + end. + + +%%----------------------------------------------------------------- +%% Func: do_get/3 +%% Purpose: do_get handles "getRequests". +%% Pre: incoming varbinds have type == 'NULL', value == unSpecified +%% Returns: {noError, 0, ListOfNewVarbinds} | +%% {ErrorStatus, ErrorIndex, []} +%%----------------------------------------------------------------- + +do_get(MibView, UnsortedVarbinds, IsNotification, Extra) -> + ?vtrace("do_get -> entry with" + "~n MibView: ~p" + "~n UnsortedVarbinds: ~p" + "~n IsNotification: ~p", + [MibView, UnsortedVarbinds, IsNotification]), + %% This is me, the master, so go ahead + {OutSideView, InSideView} = ?LIB:split_vbs_view(UnsortedVarbinds, MibView), + {Error, Index, NewVbs} = do_get(InSideView, IsNotification, Extra), + {Error, Index, NewVbs ++ OutSideView}. + + + +%%----------------------------------------------------------------- +%% Func: do_get_local/2,3 +%% Purpose: Loop the variablebindings list. We know that each varbind +%% in that list belongs to us. +%% Returns: {noError, 0, ListOfNewVarbinds} | +%% {ErrorStatus, ErrorIndex, []} +%%----------------------------------------------------------------- + +do_get_local(VBs, IsNotification) -> + do_get_local(VBs, [], IsNotification). + +do_get_local([Vb | Vbs], Res, IsNotification) -> + case try_get(Vb, IsNotification) of + NewVb when is_record(NewVb, varbind) -> + do_get_local(Vbs, [NewVb | Res], IsNotification); + ListOfNewVb when is_list(ListOfNewVb) -> + do_get_local(Vbs, lists:append(ListOfNewVb, Res), IsNotification); + {error, Error, OrgIndex} -> + {Error, OrgIndex, []} + end; +do_get_local([], Res, _IsNotification) -> + {noError, 0, Res}. + + + +%%----------------------------------------------------------------- +%% Func: do_get_subagents/2 +%% Purpose: Loop the list of varbinds for different subagents. +%% For each of them, call sub_agent_get to retreive +%% the values for them. +%% Returns: {noError, 0, ListOfNewVarbinds} | +%% {ErrorStatus, ErrorIndex, []} +%%----------------------------------------------------------------- +do_get_subagents(SubagentVarbinds, IsNotification) -> + do_get_subagents(SubagentVarbinds, [], IsNotification). +do_get_subagents([{SubAgentPid, SAVbs} | Tail], Res, IsNotification) -> + {_SAOids, Vbs} = ?LIB:sa_split(SAVbs), + case catch ?AGENT:subagent_get(SubAgentPid, Vbs, IsNotification) of + {noError, 0, NewVbs} -> + do_get_subagents(Tail, lists:append(NewVbs, Res), IsNotification); + {ErrorStatus, ErrorIndex, _} -> + {ErrorStatus, ErrorIndex, []}; + {'EXIT', Reason} -> + ?LIB:user_err("Lost contact with subagent (get) ~w. Using genErr", + [Reason]), + {genErr, 0, []} + end; +do_get_subagents([], Res, _IsNotification) -> + {noError, 0, Res}. + + +%%----------------------------------------------------------------- +%% Func: try_get/2 +%% Returns: {error, ErrorStatus, OrgIndex} | +%% #varbind | +%% List of #varbind +%%----------------------------------------------------------------- +try_get(IVb, IsNotification) when is_record(IVb, ivarbind) -> + ?vtrace("try_get(ivarbind) -> entry with" + "~n IVb: ~p", [IVb]), + get_var_value_from_ivb(IVb, IsNotification); +try_get({TableOid, TableVbs}, IsNotification) -> + ?vtrace("try_get(table) -> entry with" + "~n TableOid: ~p" + "~n TableVbs: ~p", [TableOid, TableVbs]), + [#ivarbind{mibentry = MibEntry}|_] = TableVbs, + {NoAccessVbs, AccessVbs} = + check_all_table_vbs(TableVbs, IsNotification, [], []), + case get_tab_value_from_mib(MibEntry, TableOid, AccessVbs) of + {error, ErrorStatus, OrgIndex} -> + {error, ErrorStatus, OrgIndex}; + NVbs -> + NVbs ++ NoAccessVbs + end. + +%%----------------------------------------------------------------- +%% Make sure all requested columns are accessible. +%%----------------------------------------------------------------- +check_all_table_vbs([IVb| IVbs], IsNotification, NoA, A) -> + #ivarbind{mibentry = Me, varbind = Vb} = IVb, + case Me#me.access of + 'not-accessible' -> + NNoA = [Vb#varbind{value = noSuchInstance} | NoA], + check_all_table_vbs(IVbs, IsNotification, NNoA, A); + 'accessible-for-notify' when IsNotification =:= false -> + NNoA = [Vb#varbind{value = noSuchInstance} | NoA], + check_all_table_vbs(IVbs, IsNotification, NNoA, A); + 'write-only' -> + NNoA = [Vb#varbind{value = noSuchInstance} | NoA], + check_all_table_vbs(IVbs, IsNotification, NNoA, A); + _ -> + check_all_table_vbs(IVbs, IsNotification, NoA, [IVb | A]) + end; +check_all_table_vbs([], _IsNotification, NoA, A) -> {NoA, A}. + +%%----------------------------------------------------------------- +%% Returns: {error, ErrorStatus, OrgIndex} | +%% #varbind +%%----------------------------------------------------------------- +get_var_value_from_ivb(IVb, IsNotification) + when IVb#ivarbind.status =:= noError -> + ?vtrace("get_var_value_from_ivb(noError) -> entry", []), + #ivarbind{mibentry = Me, varbind = Vb} = IVb, + #varbind{org_index = OrgIndex, oid = Oid} = Vb, + case Me#me.access of + 'not-accessible' -> + Vb#varbind{value = noSuchInstance}; + 'accessible-for-notify' when IsNotification =:= false -> + Vb#varbind{value = noSuchInstance}; + 'write-only' -> + Vb#varbind{value = noSuchInstance}; + _ -> + case get_var_value_from_mib(Me, Oid) of + {value, Type, Value} -> + Vb#varbind{variabletype = Type, value = Value}; + {error, ErrorStatus} -> + {error, ErrorStatus, OrgIndex} + end + end; +get_var_value_from_ivb(#ivarbind{status = Status, varbind = Vb}, _) -> + ?vtrace("get_var_value_from_ivb(~p) -> entry", [Status]), + Vb#varbind{value = Status}. + +%%----------------------------------------------------------------- +%% Func: get_var_value_from_mib/1 +%% Purpose: +%% Returns: {error, ErrorStatus} | +%% {value, Type, Value} +%%----------------------------------------------------------------- +%% Pre: Oid is a correct instance Oid (lookup checked that). +%% Returns: A correct return value (see ?AGENT:make_value_a_correct_value) +get_var_value_from_mib(#me{entrytype = variable, + asn1_type = ASN1Type, + mfa = {Mod, Func, Args}}, + _Oid) -> + ?vtrace("get_var_value_from_mib(variable) -> entry when" + "~n Mod: ~p" + "~n Func: ~p" + "~n Args: ~p", [Mod, Func, Args]), + Result = (catch ?LIB:dbg_apply(Mod, Func, [get | Args])), + %% mib shall return {value, <a-nice-value-within-range>} | + %% {noValue, noSuchName} (v1) | + %% {noValue, noSuchObject | noSuchInstance} (v2, v1) + %% everything else (including 'genErr') will generate 'genErr'. + ?AGENT:make_value_a_correct_value(Result, ASN1Type, {Mod, Func, Args}); + +get_var_value_from_mib(#me{entrytype = table_column, + oid = MeOid, + asn1_type = ASN1Type, + mfa = {Mod, Func, Args}}, + Oid) -> + ?vtrace("get_var_value_from_mib(table_column) -> entry when" + "~n MeOid: ~p" + "~n Mod: ~p" + "~n Func: ~p" + "~n Args: ~p" + "~n Oid: ~p", [MeOid, Mod, Func, Args, Oid]), + Col = lists:last(MeOid), + Indexes = snmp_misc:diff(Oid, MeOid), + [Result] = (catch ?LIB:dbg_apply(Mod, Func, [get, Indexes, [Col] | Args])), + ?AGENT:make_value_a_correct_value(Result, ASN1Type, + {Mod, Func, Args, Indexes, Col}). + + +%% For table operations we need to pass RestOid down to the table-function. +%% Its up to the table-function to check for noSuchInstance (ex: a +%% non-existing row). +%% Returns: {error, ErrorStatus, OrgIndex} | +%% {value, Type, Value} +get_tab_value_from_mib(#me{mfa = {Mod, Func, Args}}, TableOid, TableVbs) -> + ?vtrace("get_tab_value_from_mib -> entry when" + "~n Mod: ~p" + "~n Func: ~p" + "~n Args: ~p", [Mod, Func, Args]), + TableOpsWithShortOids = ?LIB:delete_prefixes(TableOid, TableVbs), + SortedVBsRows = snmpa_svbl:sort_varbinds_rows(TableOpsWithShortOids), + case get_value_all_rows(SortedVBsRows, Mod, Func, Args, []) of + {Error, Index} -> + #ivarbind{varbind = Vb} = lists:nth(Index, TableVbs), + {error, Error, Vb#varbind.org_index}; + ListOfValues -> + merge_varbinds_and_value(TableVbs, ListOfValues) + end. + +%%----------------------------------------------------------------- +%% Values is a scrambled list of {CorrectValue, Index}, where Index +%% is index into the #ivarbind list. So for each Value, we must +%% find the corresponding #ivarbind, and merge them into a new +%% #varbind. +%% The Values list comes from validate_tab_res. +%%----------------------------------------------------------------- +merge_varbinds_and_value(IVbs, [{{value, Type, Value}, Index} | Values]) -> + #ivarbind{varbind = Vb} = lists:nth(Index, IVbs), + [Vb#varbind{variabletype = Type, value = Value} | + merge_varbinds_and_value(IVbs, Values)]; +merge_varbinds_and_value(_, []) -> []. + +get_value_all_rows([{[], OrgCols} | Rows], Mod, Func, Args, Res) -> + ?vtrace("get_value_all_rows -> entry when" + "~n OrgCols: ~p", [OrgCols]), + Cols = [{{value, noValue, noSuchInstance}, Index} || + {_Col, _ASN1Type, Index} <- OrgCols], + NewRes = lists:append(Cols, Res), + get_value_all_rows(Rows, Mod, Func, Args, NewRes); +get_value_all_rows([{RowIndex, OrgCols} | Rows], Mod, Func, Args, Res) -> + ?vtrace("get_value_all_rows -> entry when" + "~n RowIndex: ~p" + "~n OrgCols: ~p", [RowIndex, OrgCols]), + {DOrgCols, Dup} = remove_duplicates(OrgCols), + Cols = delete_index(DOrgCols), + Result = (catch ?LIB:dbg_apply(Mod, Func, [get, RowIndex, Cols | Args])), + case validate_tab_res(Result, DOrgCols, {Mod, Func, Args}) of + Values when is_list(Values) -> + NVals = restore_duplicates(Dup, Values), + NewRes = lists:append(NVals, Res), + get_value_all_rows(Rows, Mod, Func, Args, NewRes); + {error, ErrorStatus, Index} -> + ?AGENT:validate_err(row_set, {ErrorStatus, Index}, {Mod, Func, Args}) + end; +get_value_all_rows([], _Mod, _Func, _Args, Res) -> + ?vtrace("get_value_all_rows -> entry when done" + "~n Res: ~p", [Res]), + Res. + +%%----------------------------------------------------------------- +%% Args: {RowIndex, list of {ShortOid, ASN1Type}} +%% Returns: list of Col +%%----------------------------------------------------------------- +delete_index([{Col, _Val, _OrgIndex} | T]) -> + [Col | delete_index(T)]; +delete_index([]) -> []. + +%%----------------------------------------------------------------- +%% This function is called before 'get' on a table, and removes +%% any duplicate columns. It returns {Cols, DupInfo}. The Cols +%% are the unique columns. The instrumentation function is +%% called to get the values. These values, together with the +%% DupInfo, is later passed to restore_duplicates, which uses +%% the retrieved values to reconstruct the original column list, +%% but with the retrieved value for each column. +%%----------------------------------------------------------------- +remove_duplicates(Cols) -> + remove_duplicates(Cols, [], []). + + +remove_duplicates([{Col, V1, OrgIdx1}, {Col, V2, OrgIdx2} | T], NCols, Dup) -> + remove_duplicates([{Col, V1, OrgIdx1} | T], NCols, + [{Col, V2, OrgIdx2} | Dup]); +remove_duplicates([Col | T], NCols, Dup) -> + remove_duplicates(T, [Col | NCols], Dup); +remove_duplicates([], NCols, Dup) -> + {lists:reverse(NCols), lists:reverse(Dup)}. + +restore_duplicates([], Cols) -> + [{Val, OrgIndex} || {_Col, Val, OrgIndex} <- Cols]; +restore_duplicates([{Col, _Val2, OrgIndex2} | Dup], + [{Col, NVal, OrgIndex1} | Cols]) -> + [{NVal, OrgIndex2} | + restore_duplicates(Dup, [{Col, NVal, OrgIndex1} | Cols])]; +restore_duplicates(Dup, [{_Col, Val, OrgIndex} | T]) -> + [{Val, OrgIndex} | restore_duplicates(Dup, T)]. + + + +%%----------------------------------------------------------------- +%% Three cases: +%% 1) All values ok +%% 2) table_func returned {Error, ...} +%% 3) Some value in Values list is erroneous. +%% Args: Value is a list of values from table_func(get..) +%% OrgCols is a list with {Col, ASN1Type, OrgIndex} +%% each element in Values and OrgCols correspond to each +%% other. +%%----------------------------------------------------------------- +validate_tab_res(Values, OrgCols, Mfa) when is_list(Values) -> + {_Col, _ASN1Type, OneIdx} = hd(OrgCols), + validate_tab_res(Values, OrgCols, Mfa, [], OneIdx); +validate_tab_res({noValue, Error}, OrgCols, Mfa) -> + Values = lists:duplicate(length(OrgCols), {noValue, Error}), + validate_tab_res(Values, OrgCols, Mfa); +validate_tab_res({genErr, Col}, OrgCols, Mfa) -> + case lists:keysearch(Col, 1, OrgCols) of + {value, {_Col, _ASN1Type, Index}} -> + {error, genErr, Index}; + _ -> + ?LIB:user_err("Invalid column in {genErr, ~w} from ~w (get)", + [Col, Mfa]), + [{_Col, _ASN1Type, Index} | _] = OrgCols, + {error, genErr, Index} + end; +validate_tab_res(genErr, [{_Col, __ASN1Type, Index} | _OrgCols], _Mfa) -> + {error, genErr, Index}; +validate_tab_res(Error, [{_Col, _ASN1Type, Index} | _OrgCols], Mfa) -> + ?LIB:user_err("Invalid return value ~w from ~w (get)",[Error, Mfa]), + {error, genErr, Index}. + +validate_tab_res([Value | Values], + [{Col, ASN1Type, Index} | OrgCols], + Mfa, Res, I) -> + %% This one makes it possible to return a list of genErr, which + %% is not allowed according to the manual. But that's ok, as + %% everything else will generate a genErr! (the only problem is + %% that it won't generate a user_error). + case ?AGENT:make_value_a_correct_value(Value, ASN1Type, Mfa) of + {error, ErrorStatus} -> + {error, ErrorStatus, Index}; + CorrectValue -> + NewRes = [{Col, CorrectValue, Index} | Res], + validate_tab_res(Values, OrgCols, Mfa, NewRes, I) + end; +validate_tab_res([], [], _Mfa, Res, _I) -> + lists:reverse(Res); +validate_tab_res([], [{_Col, _ASN1Type, Index}|_], Mfa, _Res, _I) -> + ?LIB:user_err("Too few values returned from ~w (get)", [Mfa]), + {error, genErr, Index}; +validate_tab_res(_TooMany, [], Mfa, _Res, I) -> + ?LIB:user_err("Too many values returned from ~w (get)", [Mfa]), + {error, genErr, I}. + + + +%%%----------------------------------------------------------------- +%%% 4. GET-NEXT REQUEST +%%% -------------- +%%% According to RFC1157, section 4.1.3 and RFC1905, section 4.2.2. +%%%----------------------------------------------------------------- +%%----------------------------------------------------------------- +%% Func: do_get_next/3 +%% Purpose: do_get_next handles "getNextRequests". +%% Note: Even if it is SNMPv1, a varbind's value can be +%% endOfMibView. This is converted to noSuchName in process_pdu. +%% Returns: {noError, 0, ListOfNewVarbinds} | +%% {ErrorStatus, ErrorIndex, []} +%% Note2: ListOfNewVarbinds is not sorted in any order!!! +%% Alg: First, the variables are sorted in OID order. +%% +%% Second, next in the MIB is performed for each OID, and +%% the result is collected as: if next oid is a variable, +%% perform a get to retrieve its value; if next oid is in a +%% table, save this value and continue until we get an oid +%% outside this table. Then perform get_next on the table, +%% and continue with all endOfTables and the oid outside the +%% table; if next oid is an subagent, save this value and +%% continue as in the table case. +%% +%% Third, each response is checked for endOfMibView, or (for +%% subagents) that the Oid returned has the correct prefix. +%% (This is necessary since an SA can be registered under many +%% separated subtrees, and if the last variable in the first +%% subtree is requested in a next, the SA will return the first +%% variable in the second subtree. This might be working, since +%% there may be a variable in between these subtrees.) For each +%% of these, a new get-next is performed, one at a time. +%% This alg. might be optimised in several ways. The most +%% striking one is that the same SA might be called several +%% times, when one time should be enough. But it isn't clear +%% that this really matters, since many nexts across the same +%% subagent must be considered to be very rare. +%%----------------------------------------------------------------- + +do_get_next(MibView, UnsortedVBs, _Extra) -> + do_get_next2(MibView, UnsortedVBs, infinity). + +%% The third argument is only used if we are called as result +%% of a get-bulk request. +do_get_next2(_MibView, UnsortedVarbinds, GbMaxVBs) + when (is_integer(GbMaxVBs) andalso (length(UnsortedVarbinds) > GbMaxVBs)) -> + {tooBig, 0, []}; % What is the correct index in this case? +do_get_next2(MibView, UnsortedVBs, GbMaxVBs) -> + ?vt("do_get_next2 -> entry when" + "~n MibView: ~p" + "~n UnsortedVBs: ~p", [MibView, UnsortedVBs]), + SortedVBs = ?LIB:oid_sort_vbs(UnsortedVBs), + ?vt("do_get_next -> " + "~n SortedVBs: ~p", [SortedVBs]), + next_loop_varbinds([], SortedVBs, MibView, [], [], GbMaxVBs). + +next_loop_varbinds(_, Vbs, _MibView, Res, _LAVb, GbMaxVBs) + when (is_integer(GbMaxVBs) andalso + ((length(Vbs) + length(Res)) > GbMaxVBs)) -> + {tooBig, 0, []}; % What is the correct index in this case? + +%% LAVb is Last Accessible Vb +next_loop_varbinds([], [Vb | Vbs], MibView, Res, LAVb, GbMaxVBs) -> + ?vt("next_loop_varbinds -> entry when" + "~n Vb: ~p" + "~n MibView: ~p", [Vb, MibView]), + case varbind_next(Vb, MibView) of + endOfMibView -> + ?vt("next_loop_varbind -> endOfMibView", []), + RVb = if LAVb =:= [] -> Vb; + true -> LAVb + end, + NewVb = RVb#varbind{variabletype = 'NULL', value = endOfMibView}, + next_loop_varbinds([], Vbs, MibView, [NewVb | Res], [], GbMaxVBs); + + {variable, ME, VarOid} when ((ME#me.access =/= 'not-accessible') andalso + (ME#me.access =/= 'write-only') andalso + (ME#me.access =/= 'accessible-for-notify')) -> + ?vt("next_loop_varbind -> variable: " + "~n ME: ~p" + "~n VarOid: ~p", [ME, VarOid]), + case try_get_instance(Vb, ME) of + {value, noValue, _NoSuchSomething} -> + ?vt("next_loop_varbind -> noValue", []), + %% Try next one + NewVb = Vb#varbind{oid = VarOid, + value = 'NULL'}, + next_loop_varbinds([], [NewVb | Vbs], MibView, Res, [], + GbMaxVBs); + {value, Type, Value} -> + ?vt("next_loop_varbind -> value" + "~n Type: ~p" + "~n Value: ~p", [Type, Value]), + NewVb = Vb#varbind{oid = VarOid, + variabletype = Type, + value = Value}, + next_loop_varbinds([], Vbs, MibView, [NewVb | Res], [], + GbMaxVBs); + {error, ErrorStatus} -> + ?vdebug("next loop varbinds:" + "~n ErrorStatus: ~p",[ErrorStatus]), + {ErrorStatus, Vb#varbind.org_index, []} + end; + {variable, _ME, VarOid} -> + ?vt("next_loop_varbind -> variable: " + "~n VarOid: ~p", [VarOid]), + RVb = if LAVb =:= [] -> Vb; + true -> LAVb + end, + NewVb = Vb#varbind{oid = VarOid, value = 'NULL'}, + next_loop_varbinds([], [NewVb | Vbs], MibView, Res, RVb, GbMaxVBs); + {table, TableOid, TableRestOid, ME} -> + ?vt("next_loop_varbind -> table: " + "~n TableOid: ~p" + "~n TableRestOid: ~p" + "~n ME: ~p", [TableOid, TableRestOid, ME]), + next_loop_varbinds({table, TableOid, ME, + [{tab_oid(TableRestOid), Vb}]}, + Vbs, MibView, Res, [], GbMaxVBs); + {subagent, SubAgentPid, SAOid} -> + ?vt("next_loop_varbind -> subagent: " + "~n SubAgentPid: ~p" + "~n SAOid: ~p", [SubAgentPid, SAOid]), + NewVb = Vb#varbind{variabletype = 'NULL', value = 'NULL'}, + next_loop_varbinds({subagent, SubAgentPid, SAOid, [NewVb]}, + Vbs, MibView, Res, [], GbMaxVBs) + end; +next_loop_varbinds({table, TableOid, ME, TabOids}, + [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) -> + ?vt("next_loop_varbinds(table) -> entry with" + "~n TableOid: ~p" + "~n Vb: ~p", [TableOid, Vb]), + case varbind_next(Vb, MibView) of + {table, TableOid, TableRestOid, _ME} -> + next_loop_varbinds({table, TableOid, ME, + [{tab_oid(TableRestOid), Vb} | TabOids]}, + Vbs, MibView, Res, [], GbMaxVBs); + _ -> + case get_next_table(ME, TableOid, TabOids, MibView) of + {ok, TabRes, TabEndOfTabVbs} -> + NewVbs = lists:append(TabEndOfTabVbs, [Vb | Vbs]), + NewRes = lists:append(TabRes, Res), + next_loop_varbinds([], NewVbs, MibView, NewRes, [], + GbMaxVBs); + {ErrorStatus, OrgIndex} -> + ?vdebug("next loop varbinds: next varbind" + "~n ErrorStatus: ~p" + "~n OrgIndex: ~p", + [ErrorStatus,OrgIndex]), + {ErrorStatus, OrgIndex, []} + end + end; +next_loop_varbinds({table, TableOid, ME, TabOids}, + [], MibView, Res, _LAVb, GbMaxVBs) -> + ?vt("next_loop_varbinds(table) -> entry with" + "~n TableOid: ~p", [TableOid]), + case get_next_table(ME, TableOid, TabOids, MibView) of + {ok, TabRes, TabEndOfTabVbs} -> + ?vt("next_loop_varbinds(table) -> get_next_table result:" + "~n TabRes: ~p" + "~n TabEndOfTabVbs: ~p", [TabRes, TabEndOfTabVbs]), + NewRes = lists:append(TabRes, Res), + next_loop_varbinds([], TabEndOfTabVbs, MibView, NewRes, [], + GbMaxVBs); + {ErrorStatus, OrgIndex} -> + ?vdebug("next loop varbinds: next table" + "~n ErrorStatus: ~p" + "~n OrgIndex: ~p", + [ErrorStatus,OrgIndex]), + {ErrorStatus, OrgIndex, []} + end; +next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, + [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) -> + ?vt("next_loop_varbinds(subagent) -> entry with" + "~n SAPid: ~p" + "~n SAOid: ~p" + "~n Vb: ~p", [SAPid, SAOid, Vb]), + case varbind_next(Vb, MibView) of + {subagent, _SubAgentPid, SAOid} -> + next_loop_varbinds({subagent, SAPid, SAOid, + [Vb | SAVbs]}, + Vbs, MibView, Res, [], GbMaxVBs); + _ -> + case get_next_sa(SAPid, SAOid, SAVbs, MibView) of + {ok, SARes, SAEndOfMibViewVbs} -> + NewVbs = lists:append(SAEndOfMibViewVbs, [Vb | Vbs]), + NewRes = lists:append(SARes, Res), + next_loop_varbinds([], NewVbs, MibView, NewRes, [], + GbMaxVBs); + {noSuchName, OrgIndex} -> + %% v1 reply, treat this Vb as endOfMibView, and try again + %% for the others. + case lists:keysearch(OrgIndex, #varbind.org_index, SAVbs) of + {value, EVb} -> + NextOid = next_oid(SAOid), + EndOfVb = + EVb#varbind{oid = NextOid, + value = {endOfMibView, NextOid}}, + case lists:delete(EVb, SAVbs) of + [] -> + next_loop_varbinds([], [EndOfVb, Vb | Vbs], + MibView, Res, [], + GbMaxVBs); + TryAgainVbs -> + next_loop_varbinds({subagent, SAPid, SAOid, + TryAgainVbs}, + [EndOfVb, Vb | Vbs], + MibView, Res, [], + GbMaxVBs) + end; + false -> + %% bad index from subagent + {genErr, (hd(SAVbs))#varbind.org_index, []} + end; + {ErrorStatus, OrgIndex} -> + ?vdebug("next loop varbinds: next subagent" + "~n Vb: ~p" + "~n ErrorStatus: ~p" + "~n OrgIndex: ~p", + [Vb,ErrorStatus,OrgIndex]), + {ErrorStatus, OrgIndex, []} + end + end; +next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, + [], MibView, Res, _LAVb, GbMaxVBs) -> + ?vt("next_loop_varbinds(subagent) -> entry with" + "~n SAPid: ~p" + "~n SAOid: ~p", [SAPid, SAOid]), + case get_next_sa(SAPid, SAOid, SAVbs, MibView) of + {ok, SARes, SAEndOfMibViewVbs} -> + NewRes = lists:append(SARes, Res), + next_loop_varbinds([], SAEndOfMibViewVbs, MibView, NewRes, [], + GbMaxVBs); + {noSuchName, OrgIndex} -> + %% v1 reply, treat this Vb as endOfMibView, and try again for + %% the others. + case lists:keysearch(OrgIndex, #varbind.org_index, SAVbs) of + {value, EVb} -> + NextOid = next_oid(SAOid), + EndOfVb = EVb#varbind{oid = NextOid, + value = {endOfMibView, NextOid}}, + case lists:delete(EVb, SAVbs) of + [] -> + next_loop_varbinds([], [EndOfVb], MibView, Res, [], + GbMaxVBs); + TryAgainVbs -> + next_loop_varbinds({subagent, SAPid, SAOid, + TryAgainVbs}, + [EndOfVb], MibView, Res, [], + GbMaxVBs) + end; + false -> + %% bad index from subagent + {genErr, (hd(SAVbs))#varbind.org_index, []} + end; + {ErrorStatus, OrgIndex} -> + ?vdebug("next loop varbinds: next subagent" + "~n ErrorStatus: ~p" + "~n OrgIndex: ~p", + [ErrorStatus,OrgIndex]), + {ErrorStatus, OrgIndex, []} + end; +next_loop_varbinds([], [], _MibView, Res, _LAVb, _GbMaxVBs) -> + ?vt("next_loop_varbinds -> entry when done", []), + {noError, 0, Res}. + +try_get_instance(_Vb, #me{mfa = {M, F, A}, asn1_type = ASN1Type}) -> + ?vtrace("try_get_instance -> entry with" + "~n M: ~p" + "~n F: ~p" + "~n A: ~p", [M,F,A]), + Result = (catch ?LIB:dbg_apply(M, F, [get | A])), + % mib shall return {value, <a-nice-value-within-range>} | + % {noValue, noSuchName} (v1) | + % {noValue, noSuchObject | noSuchInstance} (v2, v1) + % everything else (including 'genErr') will generate 'genErr'. + ?AGENT:make_value_a_correct_value(Result, ASN1Type, {M, F, A}). + +tab_oid([]) -> [0]; +tab_oid(X) -> X. + + +%%----------------------------------------------------------------- +%% Perform a next, using the varbinds Oid if value is simple +%% value. If value is {endOf<something>, NextOid}, use NextOid. +%% This case happens when a table has returned endOfTable, or +%% a subagent has returned endOfMibView. +%%----------------------------------------------------------------- +varbind_next(#varbind{value = Value, oid = Oid}, MibView) -> + ?vt("varbind_next -> entry with" + "~n Value: ~p" + "~n Oid: ~p" + "~n MibView: ~p", [Value, Oid, MibView]), + case Value of + {endOfTable, NextOid} -> + snmpa_mib:next(get(mibserver), NextOid, MibView); + {endOfMibView, NextOid} -> + snmpa_mib:next(get(mibserver), NextOid, MibView); + _ -> + snmpa_mib:next(get(mibserver), Oid, MibView) + end. + +get_next_table(#me{mfa = {M, F, A}}, TableOid, TableOids, MibView) -> + % We know that all TableOids have at least a column number as oid + ?vt("get_next_table -> entry with" + "~n M: ~p" + "~n F: ~p" + "~n A: ~p" + "~n TableOid: ~p" + "~n TableOids: ~p" + "~n MibView: ~p", [M, F, A, TableOid, TableOids, MibView]), + Sorted = snmpa_svbl:sort_varbinds_rows(TableOids), + case get_next_values_all_rows(Sorted, M,F,A, [], TableOid) of + NewVbs when is_list(NewVbs) -> + ?vt("get_next_table -> " + "~n NewVbs: ~p", [NewVbs]), + % We must now check each Vb for endOfTable and that it is + % in the MibView. If not, it becomes a endOfTable. We + % collect all of these together. + transform_tab_next_result(NewVbs, {[], []}, MibView); + {ErrorStatus, OrgIndex} -> + {ErrorStatus, OrgIndex} + end. + +get_next_values_all_rows([Row | Rows], M, F, A, Res, TabOid) -> + {RowIndex, TableOids} = Row, + Cols = delete_index(TableOids), + ?vt("get_next_values_all_rows -> " + "~n Cols: ~p", [Cols]), + Result = (catch ?LIB:dbg_apply(M, F, [get_next, RowIndex, Cols | A])), + ?vt("get_next_values_all_rows -> " + "~n Result: ~p", [Result]), + case validate_tab_next_res(Result, TableOids, {M, F, A}, TabOid) of + Values when is_list(Values) -> + ?vt("get_next_values_all_rows -> " + "~n Values: ~p", [Values]), + NewRes = lists:append(Values, Res), + get_next_values_all_rows(Rows, M, F, A, NewRes, TabOid); + {ErrorStatus, OrgIndex} -> + {ErrorStatus, OrgIndex} + end; +get_next_values_all_rows([], _M, _F, _A, Res, _TabOid) -> + Res. + +transform_tab_next_result([Vb | Vbs], {Res, EndOfs}, MibView) -> + case Vb#varbind.value of + {endOfTable, _} -> + {ResVBs, EndOfVBs} = ?LIB:split_vbs(Vbs, Res, [Vb | EndOfs]), + {ok, ResVBs, EndOfVBs}; + _ -> + case snmpa_acm:validate_mib_view(Vb#varbind.oid, MibView) of + true -> + transform_tab_next_result(Vbs, {[Vb|Res], EndOfs},MibView); + _ -> + Oid = Vb#varbind.oid, + NewEndOf = Vb#varbind{value = {endOfTable, Oid}}, + transform_tab_next_result(Vbs, {Res, [NewEndOf | EndOfs]}, + MibView) + end + end; +transform_tab_next_result([], {Res, EndOfs}, _MibView) -> + ?vt("transform_tab_next_result -> entry with: " + "~n Res: ~p" + "~n EndIfs: ~p",[Res, EndOfs]), + {ok, Res, EndOfs}. + + + +%%----------------------------------------------------------------- +%% Three cases: +%% 1) All values ok +%% 2) table_func returned {Error, ...} +%% 3) Some value in Values list is erroneous. +%% Args: Value is a list of values from table_func(get_next, ...) +%% TableOids is a list of {TabRestOid, OrgVb} +%% each element in Values and TableOids correspond to each +%% other. +%% Returns: List of NewVarbinds | +%% {ErrorStatus, OrgIndex} +%% (In the NewVarbinds list, the value may be endOfTable) +%%----------------------------------------------------------------- +validate_tab_next_res(Values, TableOids, Mfa, TabOid) -> + ?vt("validate_tab_next_res -> entry with: " + "~n Values: ~p" + "~n TableOids: ~p" + "~n Mfa: ~p" + "~n TabOid: ~p", [Values, TableOids, Mfa, TabOid]), + {_Col, _ASN1Type, OneIdx} = hd(TableOids), + validate_tab_next_res(Values, TableOids, Mfa, [], TabOid, + next_oid(TabOid), OneIdx). +validate_tab_next_res([{NextOid, Value} | Values], + [{_ColNo, OrgVb, _Index} | TableOids], + Mfa, Res, TabOid, TabNextOid, I) -> + ?vt("validate_tab_next_res -> entry with: " + "~n NextOid: ~p" + "~n Value: ~p" + "~n Values: ~p" + "~n TableOids: ~p" + "~n Mfa: ~p" + "~n TabOid: ~p", + [NextOid, Value, Values, TableOids, Mfa, TabOid]), + #varbind{org_index = OrgIndex} = OrgVb, + ?vt("validate_tab_next_res -> OrgIndex: ~p", [OrgIndex]), + NextCompleteOid = lists:append(TabOid, NextOid), + case snmpa_mib:lookup(get(mibserver), NextCompleteOid) of + {table_column, #me{asn1_type = ASN1Type}, _TableEntryOid} -> + ?vt("validate_tab_next_res -> ASN1Type: ~p", [ASN1Type]), + case ?AGENT:make_value_a_correct_value({value, Value}, ASN1Type, Mfa) of + {error, ErrorStatus} -> + ?vt("validate_tab_next_res -> " + "~n ErrorStatus: ~p", [ErrorStatus]), + {ErrorStatus, OrgIndex}; + {value, Type, NValue} -> + ?vt("validate_tab_next_res -> " + "~n Type: ~p" + "~n NValue: ~p", [Type, NValue]), + NewVb = OrgVb#varbind{oid = NextCompleteOid, + variabletype = Type, value = NValue}, + validate_tab_next_res(Values, TableOids, Mfa, + [NewVb | Res], TabOid, TabNextOid, I) + end; + Error -> + ?LIB:user_err("Invalid oid ~w from ~w (get_next). Using genErr => ~p", + [NextOid, Mfa, Error]), + {genErr, OrgIndex} + end; +validate_tab_next_res([endOfTable | Values], + [{_ColNo, OrgVb, _Index} | TableOids], + Mfa, Res, TabOid, TabNextOid, I) -> + ?vt("validate_tab_next_res(endOfTable) -> entry with: " + "~n Values: ~p" + "~n OrgVb: ~p" + "~n TableOids: ~p" + "~n Mfa: ~p" + "~n Res: ~p" + "~n TabOid: ~p" + "~n TabNextOid: ~p" + "~n I: ~p", + [Values, OrgVb, TableOids, Mfa, Res, TabOid, TabNextOid, I]), + NewVb = OrgVb#varbind{value = {endOfTable, TabNextOid}}, + validate_tab_next_res(Values, TableOids, Mfa, [NewVb | Res], + TabOid, TabNextOid, I); +validate_tab_next_res([], [], _Mfa, Res, _TabOid, _TabNextOid, _I) -> + Res; +validate_tab_next_res([], [{_Col, _OrgVb, Index}|_], Mfa, _Res, _, _, _I) -> + ?LIB:user_err("Too few values returned from ~w (get_next)", [Mfa]), + {genErr, Index}; +validate_tab_next_res({genErr, ColNumber}, OrgCols, + Mfa, _Res, _TabOid, _TabNextOid, _I) -> + OrgIndex = snmpa_svbl:col_to_orgindex(ColNumber, OrgCols), + ?AGENT:validate_err(table_next, {genErr, OrgIndex}, Mfa); +validate_tab_next_res({error, Reason}, [{_ColNo, OrgVb, _Index} | _TableOids], + Mfa, _Res, _TabOid, _TabNextOid, _I) -> + #varbind{org_index = OrgIndex} = OrgVb, + ?LIB:user_err("Erroneous return value ~w from ~w (get_next)", + [Reason, Mfa]), + {genErr, OrgIndex}; +validate_tab_next_res(Error, [{_ColNo, OrgVb, _Index} | _TableOids], + Mfa, _Res, _TabOid, _TabNextOid, _I) -> + #varbind{org_index = OrgIndex} = OrgVb, + ?LIB:user_err("Invalid return value ~w from ~w (get_next)", + [Error, Mfa]), + {genErr, OrgIndex}; +validate_tab_next_res(TooMany, [], Mfa, _Res, _, _, I) -> + ?LIB:user_err("Too many values ~w returned from ~w (get_next)", + [TooMany, Mfa]), + {genErr, I}. + +%%----------------------------------------------------------------- +%% Func: get_next_sa/4 +%% Purpose: Loop the list of varbinds for the subagent. +%% Call subagent_get_next to retreive +%% the next varbinds. +%% Returns: {ok, ListOfNewVbs, ListOfEndOfMibViewsVbs} | +%% {ErrorStatus, ErrorIndex} +%%----------------------------------------------------------------- +get_next_sa(SAPid, SAOid, SAVbs, MibView) -> + case catch ?AGENT:subagent_get_next(SAPid, MibView, SAVbs) of + {noError, 0, NewVbs} -> + NewerVbs = transform_sa_next_result(NewVbs,SAOid,next_oid(SAOid)), + {ResVBs, EndOfVBs} = ?LIB:split_vbs(NewerVbs), + {ok, ResVBs, EndOfVBs}; + {ErrorStatus, ErrorIndex, _} -> + {ErrorStatus, ErrorIndex}; + {'EXIT', Reason} -> + ?LIB:user_err("Lost contact with subagent (next) ~w. Using genErr", + [Reason]), + {genErr, 0} + end. + +%%----------------------------------------------------------------- +%% Check for wrong prefix returned or endOfMibView, and convert +%% into {endOfMibView, SANextOid}. +%%----------------------------------------------------------------- +transform_sa_next_result([Vb | Vbs], SAOid, SANextOid) + when Vb#varbind.value =:= endOfMibView -> + [Vb#varbind{value = {endOfMibView, SANextOid}} | + transform_sa_next_result(Vbs, SAOid, SANextOid)]; +transform_sa_next_result([Vb | Vbs], SAOid, SANextOid) -> + case lists:prefix(SAOid, Vb#varbind.oid) of + true -> + [Vb | transform_sa_next_result(Vbs, SAOid, SANextOid)]; + _ -> + [Vb#varbind{oid = SANextOid, value = {endOfMibView, SANextOid}} | + transform_sa_next_result(Vbs, SAOid, SANextOid)] + end; +transform_sa_next_result([], _SAOid, _SANextOid) -> + []. + + +next_oid(Oid) -> + case lists:reverse(Oid) of + [H | T] -> lists:reverse([H+1 | T]); + [] -> [] + end. + + + +%%%----------------------------------------------------------------- +%%% 5. GET-BULK REQUEST +%%% +%%% In order to prevent excesses in reply sizes there are two +%%% preventive methods in place. One is to check that the encode +%%% size does not exceed Max PDU size (this is mentioned in the +%%% standard). The other is a simple VBs limit. That is, the +%%% resulting response cannot contain more then this number of VBs. +%%%----------------------------------------------------------------- + +do_get_bulk(MibView, NonRepeaters, MaxRepetitions, + PduMS, Varbinds, GbMaxVBs, _Extra) -> + ?vtrace("do_get_bulk -> entry with" + "~n MibView: ~p" + "~n NonRepeaters: ~p" + "~n MaxRepetitions: ~p" + "~n PduMS: ~p" + "~n Varbinds: ~p" + "~n GbMaxVBs: ~p", + [MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds, GbMaxVBs]), + {NonRepVbs, RestVbs} = ?LIB:split_vbs_gb(NonRepeaters, Varbinds), + ?vt("do_get_bulk -> split: " + "~n NonRepVbs: ~p" + "~n RestVbs: ~p", [NonRepVbs, RestVbs]), + case do_get_next2(MibView, NonRepVbs, GbMaxVBs) of + {noError, 0, UResNonRepVbs} -> + ?vt("do_get_bulk -> next noError: " + "~n UResNonRepVbs: ~p", [UResNonRepVbs]), + ResNonRepVbs = lists:keysort(#varbind.org_index, UResNonRepVbs), + %% Decode the first varbinds, produce a reversed list of + %% listOfBytes. + case (catch enc_vbs(PduMS - ?empty_pdu_size, ResNonRepVbs)) of + {error, Idx, Reason} -> + ?LIB:user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]), + {genErr, Idx, []}; + {SizeLeft, Res} when is_integer(SizeLeft) and is_list(Res) -> + ?vtrace("do_get_bulk -> encoded: " + "~n SizeLeft: ~p" + "~n Res: ~w", [SizeLeft, Res]), + case (catch do_get_rep(SizeLeft, MibView, MaxRepetitions, + RestVbs, Res, + length(UResNonRepVbs), GbMaxVBs)) of + {error, Idx, Reason} -> + ?LIB:user_err("failed encoding varbind ~w:~n~p", + [Idx, Reason]), + {genErr, Idx, []}; + Res when is_list(Res) -> + ?vtrace("do get bulk -> Res: " + "~n ~w", [Res]), + {noError, 0, conv_res(Res)}; + {noError, 0, Data} = OK -> + ?vtrace("do get bulk -> OK: " + "~n length(Data): ~w", [length(Data)]), + OK; + Else -> + ?vtrace("do get bulk -> Else: " + "~n ~w", [Else]), + Else + end; + Res when is_list(Res) -> + {noError, 0, conv_res(Res)} + end; + + {ErrorStatus, Index, _} -> + ?vdebug("do get bulk: " + "~n ErrorStatus: ~p" + "~n Index: ~p",[ErrorStatus, Index]), + {ErrorStatus, Index, []} + end. + +enc_vbs(SizeLeft, Vbs) -> + ?vt("enc_vbs -> entry with" + "~n SizeLeft: ~w", [SizeLeft]), + Fun = fun(Vb, {Sz, Res}) when Sz > 0 -> + ?vt("enc_vbs -> (fun) entry with" + "~n Vb: ~p" + "~n Sz: ~p" + "~n Res: ~w", [Vb, Sz, Res]), + case (catch snmp_pdus:enc_varbind(Vb)) of + {'EXIT', Reason} -> + ?vtrace("enc_vbs -> encode failed: " + "~n Reason: ~p", [Reason]), + throw({error, Vb#varbind.org_index, Reason}); + X -> + ?vt("enc_vbs -> X: ~w", [X]), + Lx = length(X), + ?vt("enc_vbs -> Lx: ~w", [Lx]), + if + Lx < Sz -> + {Sz - length(X), [X | Res]}; + true -> + throw(Res) + end + end; + (_Vb, {_Sz, [_H | T]}) -> + ?vt("enc_vbs -> (fun) entry with" + "~n T: ~p", [T]), + throw(T); + (_Vb, {_Sz, []}) -> + ?vt("enc_vbs -> (fun) entry", []), + throw([]) + end, + lists:foldl(Fun, {SizeLeft, []}, Vbs). + +do_get_rep(Sz, MibView, MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs) + when MaxRepetitions >= 0 -> + do_get_rep(Sz, MibView, 0, MaxRepetitions, Varbinds, Res, + GbNumVBs, GbMaxVBs); +do_get_rep(Sz, MibView, _MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs) -> + do_get_rep(Sz, MibView, 0, 0, Varbinds, Res, GbNumVBs, GbMaxVBs). + +conv_res(ResVarbinds) -> + conv_res(ResVarbinds, []). +conv_res([VbListOfBytes | T], Bytes) -> + conv_res(T, VbListOfBytes ++ Bytes); +conv_res([], Bytes) -> + Bytes. + +%% The only other value, then a positive integer, is infinity. +do_get_rep(_Sz, _MibView, Count, Max, _, _Res, GbNumVBs, GbMaxVBs) + when (is_integer(GbMaxVBs) andalso (GbNumVBs > GbMaxVBs)) -> + ?vinfo("Max Get-BULK VBs limit (~w) exceeded (~w) when:" + "~n Count: ~p" + "~n Max: ~p", [GbMaxVBs, GbNumVBs, Count, Max]), + {tooBig, 0, []}; +do_get_rep(_Sz, _MibView, Max, Max, _, Res, _GbNumVBs, _GbMaxVBs) -> + ?vt("do_get_rep -> done when: " + "~n Res: ~p", [Res]), + {noError, 0, conv_res(Res)}; +do_get_rep(Sz, MibView, Count, Max, Varbinds, Res, GbNumVBs, GbMaxVBs) -> + ?vt("do_get_rep -> entry when: " + "~n Sz: ~p" + "~n Count: ~p" + "~n Res: ~w", [Sz, Count, Res]), + case try_get_bulk(Sz, MibView, Varbinds, GbMaxVBs) of + {noError, NextVarbinds, SizeLeft, Res2} -> + ?vt("do_get_rep -> noError: " + "~n SizeLeft: ~p" + "~n Res2: ~p", [SizeLeft, Res2]), + do_get_rep(SizeLeft, MibView, Count+1, Max, NextVarbinds, + Res2 ++ Res, + GbNumVBs + length(Varbinds), GbMaxVBs); + {endOfMibView, _NextVarbinds, _SizeLeft, Res2} -> + ?vt("do_get_rep -> endOfMibView: " + "~n Res2: ~p", [Res2]), + {noError, 0, conv_res(Res2 ++ Res)}; + {ErrorStatus, Index} -> + ?vtrace("do_get_rep -> done when error: " + "~n ErrorStatus: ~p" + "~n Index: ~p", [ErrorStatus, Index]), + {ErrorStatus, Index, []} + end. + +try_get_bulk(Sz, MibView, Varbinds, GbMaxVBs) -> + ?vt("try_get_bulk -> entry with" + "~n Sz: ~w" + "~n MibView: ~w" + "~n Varbinds: ~w", [Sz, MibView, Varbinds]), + case do_get_next2(MibView, Varbinds, GbMaxVBs) of + {noError, 0, UNextVarbinds} -> + ?vt("try_get_bulk -> noError: " + "~n UNextVarbinds: ~p", [UNextVarbinds]), + NextVarbinds = ?LIB:org_index_sort_vbs(UNextVarbinds), + case (catch enc_vbs(Sz, NextVarbinds)) of + {error, Idx, Reason} -> + ?LIB:user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]), + ?vtrace("try_get_bulk -> encode error: " + "~n Idx: ~p" + "~n Reason: ~p", [Idx, Reason]), + {genErr, Idx}; + {SizeLeft, Res} when is_integer(SizeLeft) andalso + is_list(Res) -> + ?vt("try get bulk -> encode ok: " + "~n SizeLeft: ~w" + "~n Res: ~w", [SizeLeft, Res]), + {check_end_of_mibview(NextVarbinds), + NextVarbinds, SizeLeft, Res}; + Res when is_list(Res) -> + ?vt("try get bulk -> Res: " + "~n ~w", [Res]), + {endOfMibView, [], 0, Res} + end; + {ErrorStatus, Index, _} -> + ?vt("try_get_bulk -> error: " + "~n ErrorStatus: ~p" + "~n Index: ~p", [ErrorStatus, Index]), + {ErrorStatus, Index} + end. + +%% If all variables in this pass are endOfMibView, +%% there is no reason to continue. +check_end_of_mibview([#varbind{value = endOfMibView} | T]) -> + check_end_of_mibview(T); +check_end_of_mibview([]) -> endOfMibView; +check_end_of_mibview(_) -> noError. + + + diff --git a/lib/snmp/src/agent/snmpa_get_lib.erl b/lib/snmp/src/agent/snmpa_get_lib.erl new file mode 100644 index 0000000000..eaf7fe2641 --- /dev/null +++ b/lib/snmp/src/agent/snmpa_get_lib.erl @@ -0,0 +1,254 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +%% +%% Note that most of these functions *assume* that they are executed +%% by the agent. If they are not they may note work as they require +%% some properties to be set in the process dictionary! +%% + +-module(snmpa_get_lib). + +-export([ + split_vbs/1, split_vbs/3, + split_vbs_view/2, + split_vbs_gb/2, + + agent_sort_vbs/1, + oid_sort_vbs/1, org_index_sort_vbs/1, + + sa_split/1, + + delete_prefixes/2, + + dbg_apply/3, + + user_err/2 + ]). + +-define(VMODULE,"GET-LIB"). +-include("snmpa_internal.hrl"). +-include("snmp_types.hrl"). +-include("snmp_debug.hrl"). +-include("snmp_verbosity.hrl"). + + + + +%%----------------------------------------------------------------- +%% split_vbs/1,3 +%% +%% Splits the list of varbinds (basically) into two lists. One +%% of 'end of'-varbinds (mib view and tables) and then the rest +%% of the varbinds. +%%----------------------------------------------------------------- + +-spec split_vbs(VBs :: [snmp:varbind()]) -> + {ResVBs :: [snmp:varbind()], + EndOfVBs :: [snmp:varbind()]}. + +split_vbs(VBs) -> + split_vbs(VBs, [], []). + +-spec split_vbs(VBs :: [snmp:varbind()], + Res :: [snmp:varbind()], + EndOfs :: [snmp:varbind()]) -> + {ResVBs :: [snmp:varbind()], + EndOfVBs :: [snmp:varbind()]}. + +split_vbs([], ResVBs, EndOfVBs) -> + {ResVBs, EndOfVBs}; +split_vbs([VB | VBs], Res, EndOfs) -> + case VB#varbind.value of + {endOfMibView, _} -> split_vbs(VBs, Res, [VB | EndOfs]); + {endOfTable, _} -> split_vbs(VBs, Res, [VB | EndOfs]); + _ -> split_vbs(VBs, [VB | Res], EndOfs) + end. + + + +%%----------------------------------------------------------------- +%% split_vbs_view/2 +%% +%% Splits a list of varbinds into two lists based on the provided +%% MibView. One list of varbinds inside the MibView and one of +%% varbinds outside the MibView. +%%----------------------------------------------------------------- + +-spec split_vbs_view(VBs :: [snmp:varbind()], + MibView :: snmp_view_based_acm_mib:mibview()) -> + {OutSideView :: [snmp:varbind()], + InSideView :: [snmp:varbind()]}. + +split_vbs_view(VBs, MibView) -> + ?vtrace("split the varbinds view", []), + split_vbs_view(VBs, MibView, [], []). + +split_vbs_view([], _MibView, Out, In) -> + {Out, In}; +split_vbs_view([VB | VBs], MibView, Out, In) -> + case snmpa_acm:validate_mib_view(VB#varbind.oid, MibView) of + true -> + split_vbs_view(VBs, MibView, Out, [VB | In]); + false -> + VB2 = VB#varbind{value = noSuchObject}, + split_vbs_view(VBs, MibView, [VB2 | Out], In) + end. + + + +%%----------------------------------------------------------------- +%% split_vbs_gb/2 +%% +%% Performs a get-bulk split of the varbinds +%%----------------------------------------------------------------- + +-spec split_vbs_gb(NonRepeaters :: integer(), + VBs :: [snmp:varbind()]) -> + {NonRepVBs :: [snmp:varbind()], + RestVBs :: [snmp:varbind()]}. + +split_vbs_gb(N, VBs) -> + split_vbs_gb(N, VBs, []). + +split_vbs_gb(N, Varbinds, Res) when N =< 0 -> + {Res, Varbinds}; +split_vbs_gb(N, [H | T], Res) -> + split_vbs_gb(N-1, T, [H | Res]); +split_vbs_gb(_N, [], Res) -> + {Res, []}. + + + +%%----------------------------------------------------------------- +%% agent_sort_vbs/1 +%% +%% Sorts the varbinds into two categories. The first is varbinds +%% belonging to "our" agent and the other is varbinds for +%% subagents. +%%----------------------------------------------------------------- + +-spec agent_sort_vbs(VBs :: [snmp:varbind()]) -> + {AgentVBs :: [snmp:varbind()], + SubAgentVBs :: [snmp:varbind()]}. + +agent_sort_vbs(VBs) -> + snmpa_svbl:sort_varbindlist(get(mibserver), VBs). + + +%%----------------------------------------------------------------- +%% oid_sort_vbs/1 +%% +%% Sorts the varbinds based on their oid. +%%----------------------------------------------------------------- + +-spec oid_sort_vbs(VBs :: [snmp:varbind()]) -> SortedVBs :: [snmp:varbind()]. + +oid_sort_vbs(VBs) -> + lists:keysort(#varbind.oid, VBs). + + +%%----------------------------------------------------------------- +%% org_index_sort_vbs/1 +%% +%% Sorts the varbinds based on their org_index. +%%----------------------------------------------------------------- + +-spec org_index_sort_vbs(VBs :: [snmp:varbind()]) -> SortedVBs :: [snmp:varbind()]. + +org_index_sort_vbs(Vbs) -> + lists:keysort(#varbind.org_index, Vbs). + + + +%%----------------------------------------------------------------- +%% sa_split/1 +%% +%% Splits a list of {oid(), varbind()} into two lists of oid() +%% and varbind. The resulting lists are reversed! +%%----------------------------------------------------------------- + +-spec sa_split(SAVBs :: [{SAOid :: snmp:oid(), snmp:varbind()}]) -> + {Oids :: [snmp:oid()], VBs :: [snmp:varbind()]}. + +sa_split(SAVBs) -> + snmpa_svbl:sa_split(SAVBs). + + + +%%----------------------------------------------------------------- +%% delete_prefixes/2 +%% +%% Takes an Oid prefix and a list of ivarbinds and produces a list +%% of {ShortOid, ASN1Type}. The ShortOid is basically the oid with +%% the OidPrefix removed. +%%----------------------------------------------------------------- + +-spec delete_prefixes(OidPrefix :: snmp:oid(), + VBs :: [snmp:ivarbind()]) -> + [{ShortOid :: snmp:oid(), + ASN1Type :: snmp:asn1_type()}]. + +delete_prefixes(OidPrefix, IVBs) -> + [{snmp_misc:diff(Oid, OidPrefix), ME#me.asn1_type} || + #ivarbind{varbind = #varbind{oid = Oid}, mibentry = ME} <- IVBs]. + + + +%%----------------------------------------------------------------- +%% dbg_apply/3 +%% +%% Call instrumentation functions, but allow for debug printing +%% of useful debug info. +%%----------------------------------------------------------------- + +-spec dbg_apply(M :: atom(), F :: atom(), A :: list()) -> + any(). + +dbg_apply(M, F, A) -> + case get(verbosity) of + silence -> + apply(M,F,A); + _ -> + ?vlog("~n apply: ~w, ~w, ~p~n", [M,F,A]), + Res = (catch apply(M,F,A)), + case Res of + {'EXIT', Reason} -> + ?vinfo("Call to: " + "~n Module: ~p" + "~n Function: ~p" + "~n Args: ~p" + "~n" + "~nresulted in an exit" + "~n" + "~n ~p~n", [M, F, A, Reason]); + _ -> + ?vlog("~n returned: ~p~n", [Res]) + end, + Res + end. + + +%% --------------------------------------------------------------------- + +user_err(F, A) -> + snmpa_error:user_err(F, A). + + diff --git a/lib/snmp/src/agent/snmpa_get_mechanism.erl b/lib/snmp/src/agent/snmpa_get_mechanism.erl new file mode 100644 index 0000000000..744a6529e1 --- /dev/null +++ b/lib/snmp/src/agent/snmpa_get_mechanism.erl @@ -0,0 +1,79 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(snmpa_get_mechanism). + +%% +%% This module defines the behaviour for the undocumented (hidden) +%% get-mechanism feature. This allows for implementing your own +%% handling of get, get-next and get-bulk requests. +%% Probably only useful for special cases (e.g. optimization). +%% + + + +%% ----------- do_get/2,3 ----------------------------------------------------- + +%% Purpose: Handles all VBs in a request that is inside the +%% mibview (local). + +-callback do_get(UnsortedVBs :: [snmp:varbind()], + IsNotification :: boolean(), + Extra :: term()) -> + {noError, 0, ResVBs :: [snmp:varbind()]} | + {ErrStatus :: snmp:error_status(), ErrIndex :: snmp:error_index(), []}. + + +%% Purpose: Handles "get-requests". + +-callback do_get(MibView :: snmp_view_based_acm_mib:mibview(), + UnsortedVBs :: [snmp:varbind()], + IsNotification :: boolean(), + Extra :: term()) -> + {noError, 0, ResVBs :: [snmp:varbind()]} | + {ErrStatus :: snmp:error_status(), ErrIndex :: snmp:error_index(), []}. + + + + +%% ----------- do_get_next/2 ------------------------------------------------ + +%% Purpose: Handles "get-next-requests". + +-callback do_get_next(MibView :: snmp_view_based_acm_mib:mibview(), + UnsortedVBs :: [snmp:varbind()], + Extra :: term()) -> + {noError, 0, ResVBs :: [snmp:varbind()]} | + {ErrStatus :: snmp:error_status(), ErrIndex :: snmp:error_index(), []}. + + + + +%% ----------- do_get_bulk/6 ------------------------------------------------ + +-callback do_get_bulk(MibView :: snmp_view_based_acm_mib:mibview(), + NonRepeaters :: non_neg_integer(), + MaxRepetitions :: non_neg_integer(), + PduMS :: pos_integer(), + VBs :: [snmp:varbind()], + MaxVBs :: pos_integer(), + Extra :: term()) -> + {noError, 0, ResVBs :: [snmp:varbind()]} | + {ErrStatus :: snmp:error_status(), ErrIndex :: snmp:error_index(), []}. diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index ecf9498ca9..afed4482d2 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2015. All Rights Reserved. +%% Copyright Ericsson AB 2004-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -137,11 +137,10 @@ init(Prio, NoteStore, MasterAgent, Parent, Opts) -> proc_lib:init_ack({ok, self()}), try loop(State) catch - C:E when C =/= exit, E =/= shutdown -> + C:E:S when C =/= exit, E =/= shutdown -> Fmt = "loop/1 EXCEPTION ~w:~w~n" " ~p", - S = erlang:get_stacktrace(), case C of exit -> %% Externally killed, root cause is elsewhere @@ -647,10 +646,10 @@ maybe_handle_recv( case try FilterMod:accept_recv(From_1, From_2) catch - Class:Exception -> + Class:Exception:StackTrace -> error_msg( "FilterMod:accept_recv(~p, ~p) crashed: ~w:~w~n ~p", - [From_1,From_2,Class,Exception,erlang:get_stacktrace()]), + [From_1, From_2, Class, Exception, StackTrace]), true end of @@ -753,12 +752,11 @@ maybe_handle_recv_pdu( case try FilterMod:accept_recv_pdu(From_1, From_2, Type) catch - Class:Exception -> + Class:Exception:StackTrace -> error_msg( "FilterMod:accept_recv_pdu(~p, ~p, ~p) crashed: ~w:~w~n" " ~p", - [From_1,From_2,Type,Class,Exception, - erlang:get_stacktrace()]), + [From_1, From_2, Type, Class, Exception, StackTrace]), true end of @@ -834,11 +832,10 @@ maybe_handle_reply_pdu( try FilterMod:accept_send_pdu(Addresses, Type) catch - Class:Exception -> + Class:Exception:StackTrace -> error_msg( "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", - [Addresses, Type, Class, Exception, - erlang:get_stacktrace()]), + [Addresses, Type, Class, Exception, StackTrace]), true end of @@ -872,7 +869,7 @@ handle_reply_pdu( ACMData, LogF)) of {ok, Packet} -> ?vinfo("time in agent: ~w mysec", [time_in_agent()]), - try maybe_udp_send(S, Transport, To, Packet) + try maybe_udp_send_wo_log(S, Transport, To, Packet) catch {Reason, Sz} -> error_msg("Cannot send message " @@ -917,11 +914,10 @@ maybe_handle_send_pdu( case try FilterMod:accept_send_pdu(AddressesToFilter, Type) catch - Class:Exception -> + Class:Exception:StackTrace -> error_msg( "FilterMod:accept_send_pdu(~p, ~p) crashed: ~w:~w~n ~p", - [AddressesToFilter,Type, - Class,Exception,erlang:get_stacktrace()]), + [AddressesToFilter, Type, Class, Exception, StackTrace]), true end of @@ -1049,46 +1045,36 @@ do_handle_send_pdu(S, Type, Pdu, Addresses) -> [Sz, Reason, Pdu]) end. -do_handle_send_pdu1( - #state{transports = Transports} = S, - Type, Addresses) -> +do_handle_send_pdu1(S, Type, Addresses) -> lists:foreach( - fun ({Domain, Address, Packet}) when is_binary(Packet) -> - ?vdebug( - "[~w] sending packet:~n" - " size: ~p~n" - " to: ~p", [Domain, sz(Packet), Address]), - To = {Domain, Address}, - case select_transport_from_domain(Domain, Transports) of - false -> - error_msg( - "Can not find transport~n" - " size: ~p~n" - " to: ~s", - [sz(Packet), format_address(To)]); - Transport -> - maybe_udp_send(S, Transport, To, Packet) - end; - ({Domain, Address, {Packet, LogData}}) when is_binary(Packet) -> - ?vdebug( - "[~w] sending encrypted packet:~n" - " size: ~p~n" - " to: ~p", [Domain, sz(Packet), Address]), - To = {Domain, Address}, - case select_transport_from_domain(Domain, Transports) of - false -> - error_msg( - "Can not find transport~n" - " size: ~p~n" - " to: ~s", - [sz(Packet), format_address(To)]); - Transport -> - maybe_udp_send(S, Transport, To, Packet, Type, LogData) - end + fun ({Domain, Address, Pkg}) when is_binary(Pkg) -> + do_handle_send_pdu2(S, Type, Domain, Address, + Pkg, Pkg, ""); + ({Domain, Address, {Pkg, LogPkg}}) when is_binary(Pkg) -> + do_handle_send_pdu2(S, Type, Domain, Address, + Pkg, LogPkg, " encrypted") end, Addresses). -maybe_udp_send( +do_handle_send_pdu2(#state{transports = Transports} = S, + Type, Domain, Address, Pkg, LogPkg, EncrStr) -> + ?vdebug("[~w] sending~s packet:" + "~n size: ~p" + "~n to: ~p", [Domain, EncrStr, sz(Pkg), Address]), + To = {Domain, Address}, + case select_transport_from_domain(Domain, Transports) of + false -> + error_msg("Can not find transport: " + "~n size: ~p" + "~n to: ~s", + [sz(Pkg), format_address(To)]); + Transport -> + maybe_udp_send_w_log(S, Transport, To, Pkg, LogPkg, Type) + end. + + +%% This function is used when logging has already been done! +maybe_udp_send_wo_log( #state{filter = FilterMod, transports = Transports}, #transport{socket = Socket}, To, Packet) -> @@ -1096,10 +1082,10 @@ maybe_udp_send( case try FilterMod:accept_send(To_1, To_2) catch - Class:Exception -> + Class:Exception:StackTrace -> error_msg( "FilterMod:accept_send(~p, ~p) crashed: ~w:~w~n ~p", - [To_1,To_2,Class,Exception,erlang:get_stacktrace()]), + [To_1, To_2, Class, Exception, StackTrace]), true end of @@ -1118,18 +1104,18 @@ maybe_udp_send( udp_send(Socket, To, Packet) end. -maybe_udp_send( +maybe_udp_send_w_log( #state{log = Log, filter = FilterMod, transports = Transports}, #transport{socket = Socket}, - To, Packet, Type, _LogData) -> + To, Pkg, LogPkg, Type) -> {To_1, To_2} = fix_filter_address(Transports, To), case try FilterMod:accept_send(To_1, To_2) catch - Class:Exception -> + Class:Exception:StackTrace -> error_msg( "FilterMod:accept_send(~p, ~p) crashed for: ~w:~w~n ~p", - [To_1, To_2, Class, Exception, erlang:get_stacktrace()]), + [To_1, To_2, Class, Exception, StackTrace]), true end of @@ -1143,10 +1129,10 @@ maybe_udp_send( _ -> error_msg( "FilterMod:accept_send(~p, ~p) returned: ~p", - [To_1,To_2,Other]) + [To_1, To_2, Other]) end, - log(Log, Type, Packet, To), - udp_send(Socket, To, Packet) + log(Log, Type, LogPkg, To), + udp_send(Socket, To, Pkg) end. udp_send(Socket, To, B) -> @@ -1168,11 +1154,10 @@ udp_send(Socket, To, B) -> ok -> ok catch - error:ExitReason -> + error:ExitReason:StackTrace -> error_msg("[exit] cannot send message " "(destination: ~p:~p, size: ~p, reason: ~p, at: ~p)", - [IpAddr, IpPort, sz(B), ExitReason, - erlang:get_stacktrace()]) + [IpAddr, IpPort, sz(B), ExitReason, StackTrace]) end. sz(L) when is_list(L) -> length(L); diff --git a/lib/snmp/src/agent/snmpa_set_lib.erl b/lib/snmp/src/agent/snmpa_set_lib.erl index 57507a36e8..3dcf49cbe6 100644 --- a/lib/snmp/src/agent/snmpa_set_lib.erl +++ b/lib/snmp/src/agent/snmpa_set_lib.erl @@ -390,7 +390,7 @@ dbg_apply(M,F,A) -> {'EXIT', {function_clause, [{M, F, A} | _]}} -> {'EXIT', {hook_function_clause, {M, F, A}}}; - % XYZ: Older format for compatibility + %% XYZ: Older format for compatibility {'EXIT', {undef, {M, F, A}}} -> {'EXIT', {hook_undef, {M, F, A}}}; {'EXIT', {function_clause, {M, F, A}}} -> diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl index cdb5ca840d..2cb0556001 100644 --- a/lib/snmp/src/agent/snmpa_supervisor.erl +++ b/lib/snmp/src/agent/snmpa_supervisor.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2016. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -193,36 +193,36 @@ init([AgentType, Opts]) -> ?vdebug("agent restart type: ~w", [Restart]), %% -- Agent type -- - ets:insert(snmp_agent_table, {agent_type, AgentType}), + store(agent_type, AgentType), %% -- Prio -- Prio = get_opt(priority, Opts, normal), ?vdebug("[agent table] store priority: ~p",[Prio]), - ets:insert(snmp_agent_table, {priority, Prio}), + store(priority, Prio), %% -- Versions -- Vsns = get_opt(versions, Opts, [v1,v2,v3]), ?vdebug("[agent table] store versions: ~p",[Vsns]), - ets:insert(snmp_agent_table, {versions, Vsns}), + store(versions, Vsns), %% -- Max number of VBs in a Get-BULK response -- GbMaxVBs = get_gb_max_vbs(Opts), ?vdebug("[agent table] Get-BULK max VBs: ~p", [GbMaxVBs]), - ets:insert(snmp_agent_table, {gb_max_vbs, GbMaxVBs}), + store(gb_max_vbs, GbMaxVBs), %% -- DB-directory -- DbDir = get_opt(db_dir, Opts), ?vdebug("[agent table] store db_dir: ~n ~p",[DbDir]), - ets:insert(snmp_agent_table, {db_dir, filename:join([DbDir])}), + store(db_dir, filename:join([DbDir])), DbInitError = get_opt(db_init_error, Opts, terminate), ?vdebug("[agent table] store db_init_error: ~n ~p",[DbInitError]), - ets:insert(snmp_agent_table, {db_init_error, DbInitError}), + store(db_init_error, DbInitError), %% -- Error report module -- ErrorReportMod = get_opt(error_report_mod, Opts, snmpa_error_logger), ?vdebug("[agent table] store error report module: ~w",[ErrorReportMod]), - ets:insert(snmp_agent_table, {error_report_mod, ErrorReportMod}), + store(error_report_mod, ErrorReportMod), %% -- mib storage -- %% MibStorage has only one mandatory part: module @@ -320,31 +320,31 @@ init([AgentType, Opts]) -> end, ?vdebug("[agent table] store mib storage: ~w", [MibStorage]), - ets:insert(snmp_agent_table, {mib_storage, MibStorage}), + store(mib_storage, MibStorage), %% -- Agent mib storage -- AgentMibStorage = get_opt(agent_mib_storage, Opts, persistent), %% ?vdebug("[agent table] store agent mib storage: ~w",[AgentMibStorage]), - ets:insert(snmp_agent_table, {agent_mib_storage, AgentMibStorage}), + store(agent_mib_storage, AgentMibStorage), %% -- System start time -- ?vdebug("[agent table] store system start time",[]), - ets:insert(snmp_agent_table, {system_start_time, snmp_misc:now(cs)}), + store(system_start_time, snmp_misc:now(cs)), %% -- Symbolic store options -- SsOpts = get_opt(symbolic_store, Opts, []), ?vdebug("[agent table] store symbolic store options: ~w",[SsOpts]), - ets:insert(snmp_agent_table, {symbolic_store, SsOpts}), + store(symbolic_store, SsOpts), %% -- Local DB options -- LdbOpts = get_opt(local_db, Opts, []), ?vdebug("[agent table] store local db options: ~w",[LdbOpts]), - ets:insert(snmp_agent_table, {local_db, LdbOpts}), + store(local_db, LdbOpts), %% -- Target cache options -- TargetCacheOpts = get_opt(target_cache, Opts, []), ?vdebug("[agent table] store target cache options: ~w",[TargetCacheOpts]), - ets:insert(snmp_agent_table, {target_cache, TargetCacheOpts}), + store(target_cache, TargetCacheOpts), %% -- Specs -- SupFlags = {one_for_all, 0, 3600}, @@ -377,7 +377,7 @@ init([AgentType, Opts]) -> %% -- Config -- ConfOpts = get_opt(config, Opts, []), ?vdebug("[agent table] store config options: ~p", [ConfOpts]), - ets:insert(snmp_agent_table, {config, ConfOpts}), + store(config, ConfOpts), ConfigArgs = [Vsns, ConfOpts], ConfigSpec = @@ -390,43 +390,46 @@ init([AgentType, Opts]) -> %% -- Discovery processing -- DiscoOpts = get_opt(discovery, Opts, []), ?vdebug("[agent table] store discovery options: ~p", [DiscoOpts]), - ets:insert(snmp_agent_table, {discovery, DiscoOpts}), + store(discovery, DiscoOpts), %% -- Mibs -- Mibs = get_mibs(get_opt(mibs, Opts, []), Vsns), ?vdebug("[agent table] store mibs: ~n ~p",[Mibs]), - ets:insert(snmp_agent_table, {mibs, Mibs}), + store(mibs, Mibs), Ref = make_ref(), + %% -- Get module -- + GetModule = get_opt(get_mechanism, Opts, snmpa_get), + ?vdebug("[agent table] store get-module: ~p", [GetModule]), + store(get_mechanism, GetModule), + %% -- Set module -- SetModule = get_opt(set_mechanism, Opts, snmpa_set), ?vdebug("[agent table] store set-module: ~p",[SetModule]), - ets:insert(snmp_agent_table, {set_mechanism, ConfOpts}), + store(set_mechanism, SetModule), %% -- Authentication service -- AuthModule = get_opt(authentication_service, Opts, snmpa_acm), ?vdebug("[agent table] store authentication service: ~w", [AuthModule]), - ets:insert(snmp_agent_table, - {authentication_service, AuthModule}), + store(authentication_service, AuthModule), %% -- Multi-threaded -- MultiT = get_opt(multi_threaded, Opts, false), - ?vdebug("[agent table] store multi-threaded: ~p",[MultiT]), - ets:insert(snmp_agent_table, {multi_threaded, MultiT}), + ?vdebug("[agent table] store multi-threaded: ~p", [MultiT]), + store(multi_threaded, MultiT), %% -- Audit trail log -- case get_opt(audit_trail_log, Opts, not_found) of not_found -> - ?vdebug("[agent table] no audit trail log",[]), + ?vdebug("[agent table] no audit trail log", []), ok; AtlOpts -> ?vdebug("[agent table] " "store audit trail log options: ~p", [AtlOpts]), - ets:insert(snmp_agent_table, - {audit_trail_log, AtlOpts}), + store(audit_trail_log, AtlOpts), ok end, @@ -434,24 +437,25 @@ init([AgentType, Opts]) -> MibsOpts = get_opt(mib_server, Opts, []), ?vdebug("[agent table] store mib-server options: " "~n ~p", [MibsOpts]), - ets:insert(snmp_agent_table, {mib_server, MibsOpts}), + store(mib_server, MibsOpts), %% -- Network interface -- NiOpts = get_opt(net_if, Opts, []), ?vdebug("[agent table] store net-if options: " "~n ~p", [NiOpts]), - ets:insert(snmp_agent_table, {net_if, NiOpts}), + store(net_if, NiOpts), %% -- Note store -- NsOpts = get_opt(note_store, Opts, []), ?vdebug("[agent table] store note-store options: " "~n ~p",[NsOpts]), - ets:insert(snmp_agent_table, {note_store, NsOpts}), + store(note_store, NsOpts), AgentOpts = [{verbosity, AgentVerb}, {mibs, Mibs}, {mib_storage, MibStorage}, + {get_mechanism, GetModule}, {set_mechanism, SetModule}, {authentication_service, AuthModule}, {multi_threaded, MultiT}, @@ -480,6 +484,10 @@ init([AgentType, Opts]) -> {ok, {SupFlags, [MiscSupSpec, SymStoreSpec, LocalDbSpec, TargetCacheSpec | Rest]}}. + +store(Key, Value) -> + ets:insert(snmp_agent_table, {Key, Value}). + get_mibs(Mibs, Vsns) -> MibDir = filename:join(code:priv_dir(snmp), "mibs"), StdMib = diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index e75016f7ec..31805c3bee 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -917,7 +917,7 @@ do_send_v2_trap(Recvs, Vbs, ExtraInfo, NetIf) -> TrapPdu = make_v2_notif_pdu(Vbs, 'snmpv2-trap'), AddrCommunities = mk_addr_communities(Recvs), lists:foreach(fun({Community, Addrs}) -> - ?vtrace("~n send v2 trap to ~p",[Addrs]), + ?vtrace("send v2 trap to ~p",[Addrs]), NetIf ! {send_pdu, 'version-2', TrapPdu, {community, Community}, Addrs, ExtraInfo} end, AddrCommunities), diff --git a/lib/snmp/src/app/snmp.app.src b/lib/snmp/src/app/snmp.app.src index d4bf0de61a..178309b488 100644 --- a/lib/snmp/src/app/snmp.app.src +++ b/lib/snmp/src/app/snmp.app.src @@ -49,6 +49,9 @@ snmpa_error_io, snmpa_error_logger, snmpa_error_report, + snmpa_get, + snmpa_get_lib, + snmpa_get_mechanism, snmpa_local_db, snmpa_mib, snmpa_mib_data, diff --git a/lib/snmp/src/app/snmp.config b/lib/snmp/src/app/snmp.config index b66ef5d7df..f35a636157 100644 --- a/lib/snmp/src/app/snmp.config +++ b/lib/snmp/src/app/snmp.config @@ -8,6 +8,7 @@ %% {agent_verbosity, verbosity()} | %% {versions, versions()} | %% {priority, atom()} | +%% {get_mechanism, module()} | %% {set_mechanism, module()} | %% {authentication_service, module()} | %% {multi_threaded, bool()} | diff --git a/lib/snmp/src/app/snmp.erl b/lib/snmp/src/app/snmp.erl index 8a736f688b..216452afdd 100644 --- a/lib/snmp/src/app/snmp.erl +++ b/lib/snmp/src/app/snmp.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2017. All Rights Reserved. +%% Copyright Ericsson AB 1996-2019. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -116,7 +116,10 @@ pdu/0, trappdu/0, mib/0, - mib_name/0, + mib_name/0, + + error_status/0, + error_index/0, void/0 ]). @@ -208,6 +211,23 @@ -type pdu() :: #pdu{}. -type trappdu() :: #trappdu{}. +%% We should really specify all of these, but they are so numerous... +%% See the validate_err/1 function in the snmpa_agent. +%% Here are a number of them: +%% badValue | +%% commitFailed | +%% genErr | +%% inconsistentName | inconsistentValue | +%% noAccess | noCreation | +%% noSuchInstance | noSuchName | noSuchObject | +%% notWritable | +%% resourceUnavailable | +%% undoFailed | +%% wrongValue + +-type error_status() :: atom(). +-type error_index() :: pos_integer(). + -type void() :: term(). diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl index 7f627d66d9..c810bfcd41 100644 --- a/lib/snmp/src/compile/snmpc.erl +++ b/lib/snmp/src/compile/snmpc.erl @@ -169,11 +169,7 @@ get_version() -> MI = ?MODULE:module_info(), Attr = get_info(attributes, MI), Vsn = get_info(app_vsn, Attr), - Comp = get_info(compile, MI), - Time = get_info(time, Comp), - {Year, Month, Day, Hour, Min, Sec} = Time, - io_lib:format("~s [~.4w-~.2.0w-~.2.0w ~.2.0w:~.2.0w:~.2.0w]", - [Vsn, Year, Month, Day, Hour, Min, Sec]). + Vsn. maybe_display_options(Opts) -> case lists:member(options, Opts) of diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index 767d801eee..5713c14912 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2016. All Rights Reserved. +%% Copyright Ericsson AB 1997-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. @@ -649,13 +649,14 @@ do_log_to_file(Log, TextFile, Mibs, Start, Stop) -> MiniMib = snmp_mini_mib:create(Mibs), Write = fun(X) -> case format_msg(X, MiniMib, Start, Stop) of - {ok, S} -> - io:format(Fd, "~s", [S]); - _ -> - ok + {Tag, S} when (Tag =:= ok) orelse (Tag =:= error) -> + io:format(Fd, "~s", [S]), + Tag; + Ignore -> + Ignore end end, - Res = (catch loop(disk_log:chunk(Log, start), Log, Write)), + Res = (catch loop(Log, Write)), snmp_mini_mib:delete(MiniMib), file:close(Fd), Res; @@ -668,39 +669,63 @@ do_log_to_io(Log, Mibs, Start, Stop) -> MiniMib = snmp_mini_mib:create(Mibs), Write = fun(X) -> case format_msg(X, MiniMib, Start, Stop) of - {ok, S} -> - io:format("~s", [S]); - _ -> - ok + {Tag, S} when (Tag =:= ok) orelse (Tag =:= error) -> + io:format("~s", [S]), + Tag; + X -> + X end end, - (catch loop(disk_log:chunk(Log, start), Log, Write)), + Res = (catch loop(Log, Write)), snmp_mini_mib:delete(MiniMib), - ok. + Res. + +loop(Log, Write) -> + loop(disk_log:chunk(Log, start), Log, Write, 0, 0). -loop(eof, _Log, _Write) -> +loop(eof, _Log, _Write, _NumOK, 0 = _NumERR) -> ok; -loop({error, _} = Error, _Log, _Write) -> +loop(eof, _Log, _Write, NumOK, NumERR) -> + {ok, {NumOK, NumERR}}; +loop({error, _} = Error, _Log, _Write, _NumOK, _NumERR) -> Error; -loop({Cont, Terms}, Log, Write) -> - case (catch lists:foreach(Write, Terms)) of - {'EXIT', Reason} -> - {error, Reason}; - _ -> - loop(disk_log:chunk(Log, Cont), Log, Write) +loop({Cont, Terms}, Log, Write, NumOK, NumERR) -> + try loop_terms(Terms, Write) of + {ok, {AddedOK, AddedERR}} -> + loop(disk_log:chunk(Log, Cont), Log, Write, + NumOK+AddedOK, NumERR+AddedERR) + catch + C:E:S -> + {error, {C, E, S}} end; -loop({Cont, Terms, BadBytes}, Log, Write) -> +loop({Cont, Terms, BadBytes}, Log, Write, NumOK, NumERR) -> error_logger:error_msg("Skipping ~w bytes while converting ~p~n~n", [BadBytes, Log]), - case (catch lists:foreach(Write, Terms)) of - {'EXIT', Reason} -> - {error, Reason}; - _ -> - loop(disk_log:chunk(Log, Cont), Log, Write) - end; -loop(Error, _Log, _Write) -> - Error. + try loop_terms(Terms, Write) of + {ok, {AddedOK, AddedERR}} -> + loop(disk_log:chunk(Log, Cont), Log, Write, + NumOK+AddedOK, NumERR+AddedERR) + catch + C:E:S -> + {error, {C, E, S}} + end. + + +loop_terms(Terms, Write) -> + loop_terms(Terms, Write, 0, 0). + +loop_terms([], _Write, NumOK, NumERR) -> + {ok, {NumOK, NumERR}}; +loop_terms([Term|Terms], Write, NumOK, NumERR) -> + case Write(Term) of + ok -> + loop_terms(Terms, Write, NumOK+1, NumERR); + error -> + loop_terms(Terms, Write, NumOK, NumERR+1); + _ -> + loop_terms(Terms, Write, NumOK, NumERR) + end. format_msg(Entry, Mib, Start, Stop) -> @@ -733,88 +758,149 @@ do_format_msg({Timestamp, SeqNo, Packet, Ip, Port}, Mib) -> %% This is crap... do_format_msg(_, _) -> - format_tab("** unknown entry in log file\n\n", []). + {error, format_tab("** unknown entry in log file\n\n", [])}. do_format_msg(TimeStamp, {V3Hdr, ScopedPdu}, AddrStr, Mib) -> - case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of + try snmp_pdus:dec_scoped_pdu(ScopedPdu) of ScopedPDU when is_record(ScopedPDU, scopedPdu) -> Msg = #message{version = 'version-3', vsn_hdr = V3Hdr, data = ScopedPDU}, - f(ts2str(TimeStamp), "", Msg, AddrStr, Mib); - {'EXIT', Reason} -> - format_tab( - "** error in log file at ~s from ~s ~p\n\n", - [ts2str(TimeStamp), AddrStr, Reason]) + try f(ts2str(TimeStamp), "", Msg, AddrStr, Mib) of + {ok, _} = OK -> + OK + catch + FormatT:FormatE -> + format_error("format scoped pdu", + TimeStamp, AddrStr, FormatT, FormatE) + end + catch + DecT:DecE -> + format_error("decode scoped pdu", + TimeStamp, AddrStr, DecT, DecE) end; do_format_msg(TimeStamp, Packet, AddrStr, Mib) -> - case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of + try snmp_pdus:dec_message(binary_to_list(Packet)) of Msg when is_record(Msg, message) -> - f(ts2str(TimeStamp), "", Msg, AddrStr, Mib); - {'EXIT', Reason} -> - format_tab("** error in log file ~p\n\n", [Reason]) + try f(ts2str(TimeStamp), "", Msg, AddrStr, Mib) of + {ok, _} = OK -> + OK + catch + FormatT:FormatE -> + %% Provide info about the message + Extra = + case Msg#message.version of + 'version-3' -> + #v3_hdr{msgID = ID, + msgFlags = Flags, + msgSecurityModel = SecModel} = + Msg#message.vsn_hdr, + SecLevel = snmp_misc:get_sec_level(Flags), + f("msg-id: ~w, sec-level: ~w, sec-model: ~w", + [ID, SecLevel, sm2atom(SecModel)]); + _ -> %% Community + f("community: ~s", [Msg#message.vsn_hdr]) + end, + format_error(f("format ~p message; ~s", + [Msg#message.version, Extra]), + TimeStamp, AddrStr, FormatT, FormatE) + end + catch + DecT:DecE -> + format_error("decode message", + TimeStamp, AddrStr, DecT, DecE) + end. - + +sm2atom(?SEC_ANY) -> any; +sm2atom(?SEC_V1) -> v1; +sm2atom(?SEC_V2C) -> v2c; +sm2atom(?SEC_USM) -> usm; +sm2atom(_) -> unknown. + do_format_msg(TimeStamp, SeqNo, {V3Hdr, ScopedPdu}, AddrStr, Mib) -> - case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of + try snmp_pdus:dec_scoped_pdu(ScopedPdu) of ScopedPDU when is_record(ScopedPDU, scopedPdu) -> Msg = #message{version = 'version-3', vsn_hdr = V3Hdr, data = ScopedPDU}, - f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib); - {'EXIT', Reason} -> - format_tab( - "** error in log file at ~s from ~s ~p\n\n", - [ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason]) + try f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib) of + {ok, _} = OK -> + OK + catch + FormatT:FormatE -> + format_error("format scoped pdu", + TimeStamp, SeqNo, AddrStr, FormatT, FormatE) + end + catch + DecT:DecE -> + format_error("decode scoped pdu", + TimeStamp, SeqNo, AddrStr, DecT, DecE) end; do_format_msg(TimeStamp, SeqNo, Packet, AddrStr, Mib) -> - case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of + try snmp_pdus:dec_message(binary_to_list(Packet)) of Msg when is_record(Msg, message) -> - f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib); - {'EXIT', Reason} -> - format_tab( - "** error in log file ~s from ~s ~p\n\n", - [ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason]) + try f(ts2str(TimeStamp), sn2str(SeqNo), Msg, AddrStr, Mib) of + {ok, _} = OK -> + OK + + catch + FormatT:FormatE -> + %% Provide info about the message + Extra = + case Msg#message.version of + 'version-3' -> + #v3_hdr{msgID = ID, + msgFlags = Flags, + msgSecurityModel = SecModel} = + Msg#message.vsn_hdr, + SecLevel = snmp_misc:get_sec_level(Flags), + f("msg-id: ~w, sec-level: ~w, sec-model: ~w", + [ID, SecLevel, sm2atom(SecModel)]); + _ -> %% Community + f("community: ~s", [Msg#message.vsn_hdr]) + end, + format_error(f("format ~p message; ~s", + [Msg#message.version, Extra]), + TimeStamp, SeqNo, AddrStr, FormatT, FormatE) + end + catch + DecT:DecE -> + format_error("decode message", + TimeStamp, SeqNo, AddrStr, DecT, DecE) end. - - -%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, {Addr, Port}}, -%% Mib, Start, Stop) -> -%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port}, -%% Mib, Start, Stop); -%% format_msg({TimeStamp, {V3Hdr, ScopedPdu}, Addr, Port}, -%% Mib, Start, Stop) -> -%% case timestamp_filter(TimeStamp, Start, Stop) of -%% true -> -%% case (catch snmp_pdus:dec_scoped_pdu(ScopedPdu)) of -%% ScopedPDU when record(ScopedPDU, scopedPdu) -> -%% Msg = #message{version = 'version-3', -%% vsn_hdr = V3Hdr, -%% data = ScopedPDU}, -%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib); -%% {'EXIT', Reason} -> -%% format_tab("** error in log file at ~s from ~p:~w ~p\n\n", -%% [ts2str(TimeStamp), ip(Addr), Port, Reason]) -%% end; -%% false -> -%% ignore -%% end; -%% format_msg({TimeStamp, Packet, {Addr, Port}}, Mib, Start, Stop) -> -%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop); -%% format_msg({TimeStamp, Packet, Addr, Port}, Mib, Start, Stop) -> -%% case timestamp_filter(TimeStamp, Start, Stop) of -%% true -> -%% case (catch snmp_pdus:dec_message(binary_to_list(Packet))) of -%% Msg when record(Msg, message) -> -%% f(ts2str(TimeStamp), Msg, Addr, Port, Mib); -%% {'EXIT', Reason} -> -%% format_tab("** error in log file ~p\n\n", [Reason]) -%% end; -%% false -> -%% ignore -%% end; -%% format_msg(_, _Mib, _Start, _Stop) -> -%% format_tab("** unknown entry in log file\n\n", []). + + +format_error(WhatStr, TimeStamp, AddrStr, throw, {error, Reason}) -> + {ok, Str} = + format_tab( + "** error (~s) in log file at ~s from ~s: " + "~n ~p\n\n", + [WhatStr, ts2str(TimeStamp), AddrStr, Reason]), + {error, Str}; +format_error(WhatStr, TimeStamp, AddrStr, T, E) -> + {ok, Str} = + format_tab( + "** error (~s) in log file at ~s from ~s: " + "~n ~w: ~p\n\n", + [WhatStr, ts2str(TimeStamp), AddrStr, T, E]), + {error, Str}. + +format_error(WhatStr, TimeStamp, SeqNo, AddrStr, throw, {error, Reason}) -> + {ok, Str} = + format_tab( + "** error (~s) in log file at ~s~s from ~s: " + "~n ~p\n\n", + [WhatStr, ts2str(TimeStamp), sn2str(SeqNo), AddrStr, Reason]), + {error, Str}; +format_error(WhatStr, TimeStamp, SeqNo, AddrStr, T, E) -> + {ok, Str} = + format_tab( + "** error (~s) in log file at ~s~s from ~s: " + "~n ~w, ~p\n\n", + [WhatStr, ts2str(TimeStamp), sn2str(SeqNo), AddrStr, T, E]), + {error, Str}. + f(TimeStamp, SeqNo, #message{version = Vsn, vsn_hdr = VsnHdr, data = Data}, @@ -838,51 +924,21 @@ f(TimeStamp, SeqNo, end, format_tab( "~w ~s - ~s [~s]~s ~w\n~s", - [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]). - -%% f(TimeStamp, SeqNo, -%% #message{version = Vsn, vsn_hdr = VsnHdr, data = Data}, -%% Addr, Port, Mib) -> -%% Str = format_pdu(Data, Mib), -%% HdrStr = format_header(Vsn, VsnHdr), -%% case get_type(Data) of -%% trappdu -> -%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); -%% 'snmpv2-trap' -> -%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); -%% 'inform-request' -> -%% f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); -%% 'get-response' -> -%% f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); -%% report -> -%% f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port); -%% _ -> -%% f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -%% end. - -%% f_request(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> -%% format_tab("request ~s:~w - ~s [~s]~s ~w\n~s", -%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). - -%% f_response(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> -%% format_tab("response ~s:~w - ~s [~s]~s ~w\n~s", -%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). - -%% f_report(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> -%% format_tab("report ~s:~w - ~s [~s]~s ~w\n~s", -%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). + [Class, AddrStr, HdrStr, TimeStamp, SeqNo, Vsn, Str]); +f(TimeStamp, SeqNo, Msg, AddrStr, _Mib) -> + io:format("<ERROR> Unexpected data: " + "~n TimeStamp: ~s~s" + "~n Msg: ~p" + "~n AddrStr: ~p" + "~n", [TimeStamp, SeqNo, Msg, AddrStr]), + throw({error, 'invalid-message'}). -%% f_trap(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> -%% format_tab("trap ~s:~w - ~s [~s]~s ~w\n~s", -%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). +f(F, A) -> + lists:flatten(io_lib:format(F, A)). -%% f_inform(TimeStamp, SeqNo, Vsn, HdrStr, Str, Addr, Port) -> -%% format_tab("inform ~s:~w - ~s [~s]~s ~w\n~s", -%% [ip(Addr), Port, HdrStr, TimeStamp, SeqNo, Vsn, Str]). ipPort2Str(Ip, Port) -> snmp_conf:mk_addr_string({Ip, Port}). - %% io_lib:format("~s:~w", [ip(Ip), Port]). %% Convert a timestamp 2-tupple to a printable string %% @@ -973,7 +1029,13 @@ format_pdu(#scopedPdu{contextName = Context, data = Pdu}, Mib) -> io_lib:format("Context: \"~s\"\n~s", [Context, snmp_misc:format_pdu(Pdu, Mib)]); format_pdu(Pdu, Mib) -> - snmp_misc:format_pdu(Pdu, Mib). + try snmp_misc:format_pdu(Pdu, Mib) of + Str -> + Str + catch + _:_ -> + throw({error, 'invalid-pdu'}) + end. get_type(#scopedPdu{data = Pdu}) -> get_type(Pdu); @@ -983,12 +1045,6 @@ get_type(#pdu{type = Type}) -> Type. -%% ip(Domain, Addr) -> -%% snmp_conf:mk_addr_string(Domain, Addr). -%% ip({A,B,C,D}) -> -%% io_lib:format("~w.~w.~w.~w", [A,B,C,D]). - - %% ------------------------------------------------------------------- %% Various utility functions diff --git a/lib/snmp/test/modules.mk b/lib/snmp/test/modules.mk index 0f54e67c65..8b6547f9a9 100644 --- a/lib/snmp/test/modules.mk +++ b/lib/snmp/test/modules.mk @@ -31,6 +31,7 @@ SUITE_MODULES = \ snmp_agent_mibs_test \ snmp_agent_nfilter_test \ snmp_agent_test \ + snmp_agent_test_get \ snmp_agent_conf_test \ snmp_agent_test_lib \ snmp_manager_config_test \ diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 2ed2c4580c..f9c18af6ea 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2016. All Rights Reserved. +%% Copyright Ericsson AB 2003-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/snmp/test/snmp_agent_test_get.erl b/lib/snmp/test/snmp_agent_test_get.erl new file mode 100644 index 0000000000..517c71507a --- /dev/null +++ b/lib/snmp/test/snmp_agent_test_get.erl @@ -0,0 +1,58 @@ +%% +%% %CopyrightBegin% +%% +%% Copyright Ericsson AB 2019-2019. All Rights Reserved. +%% +%% Licensed under the Apache License, Version 2.0 (the "License"); +%% you may not use this file except in compliance with the License. +%% You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, software +%% distributed under the License is distributed on an "AS IS" BASIS, +%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +%% See the License for the specific language governing permissions and +%% limitations under the License. +%% +%% %CopyrightEnd% +%% + +-module(snmp_agent_test_get). + +-behaviour(snmpa_get_mechanism). + + +%%%----------------------------------------------------------------- +%%% snmpa_get_mechanism exports +%%%----------------------------------------------------------------- + +-export([ + do_get/3, do_get/4, + do_get_next/3, + do_get_bulk/7 + ]). + + + +do_get(UnsortedVarbinds, IsNotification, Extra) -> + snmpa_get:do_get(UnsortedVarbinds, IsNotification, Extra). + + + +do_get(MibView, UnsortedVarbinds, IsNotification, Extra) -> + snmpa_get:do_get(MibView, UnsortedVarbinds, IsNotification, Extra). + + + +do_get_next(MibView, UnsortedVBs, Extra) -> + snmpa_get:do_get_next(MibView, UnsortedVBs, Extra). + + + + +do_get_bulk(MibView, NonRepeaters, MaxRepetitions, + PduMS, Varbinds, GbMaxVBs, Extra) -> + snmpa_get:do_get_bulk(MibView, NonRepeaters, MaxRepetitions, + PduMS, Varbinds, GbMaxVBs, + Extra). diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 66211d7105..c19c88528f 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -445,6 +445,7 @@ start_agent(Config, Vsns, Opts) -> [{versions, Vsns}, {agent_type, master}, {agent_verbosity, trace}, + {get_mechanism, snmp_agent_test_get}, {db_dir, AgentDbDir}, {audit_trail_log, [{type, read_write}, {dir, AgentLogDir}, diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 6ced55f0cc..bb9b05b89f 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -6179,7 +6179,12 @@ start_agent(Node, Vsns, Conf0, _Opts) -> {mib_server, [{verbosity, MSV}]}, {note_store, [{verbosity, NSV}]}, {stymbolic_store, [{verbosity, SSV}]}, - {net_if, [{verbosity, NIV}]}, + {net_if, [{verbosity, NIV}, + %% On some linux "they" add a 127.0.1.1 or somthing + %% similar, so if we don't specify bind_to + %% we don't know which address will be selected + %% (which will cause problems for some test cases). + {options, [{bind_to, true}]}]}, {multi_threaded, true}], ?line ok = set_agent_env(Node, Env), diff --git a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl index 6a3466b6e4..b83c7461d1 100644 --- a/lib/snmp/test/snmp_to_snmpnet_SUITE.erl +++ b/lib/snmp/test/snmp_to_snmpnet_SUITE.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2014-2016. All Rights Reserved. +%% Copyright Ericsson AB 2014-2018. All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 96123f02f5..4d5a0fbce8 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2017. All Rights Reserved. +# Copyright Ericsson AB 1997-2018. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -19,6 +19,6 @@ # %CopyrightEnd% APPLICATION = snmp -SNMP_VSN = 5.2.11 +SNMP_VSN = 5.2.12 PRE_VSN = APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" |