diff options
Diffstat (limited to 'lib/snmp')
50 files changed, 4182 insertions, 2247 deletions
diff --git a/lib/snmp/Makefile b/lib/snmp/Makefile index 20e3d4692a..ff6fad8ddc 100644 --- a/lib/snmp/Makefile +++ b/lib/snmp/Makefile @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1996-2009. All Rights Reserved. +# Copyright Ericsson AB 1996-2011. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -54,6 +54,9 @@ else endif +DIA_PLT = ./priv/plt/$(APPLICATION).plt +DIA_ANALYSIS = $(basename $(DIA_PLT)).dialyzer_analysis + # ---------------------------------------------------- # Default Subdir Targets # ---------------------------------------------------- @@ -67,7 +70,7 @@ do_configure: configure configure: configure.in autoconf -.PHONY: info +.PHONY: info gclean info: @echo "OS: $(OS)" @@ -75,6 +78,14 @@ info: @echo "" @echo "SNMP_VSN: $(SNMP_VSN)" @echo "APP_VSN: $(APP_VSN)" + @echo "" + @echo "DIA_PLT: $(DIA_PLT)" + @echo "DIA_ANALYSIS: $(DIA_ANALYSIS)" + @echo "" + + +gclean: + git clean -fXd # ---------------------------------------------------- @@ -117,3 +128,23 @@ tar: $(APP_TAR_FILE) $(APP_TAR_FILE): $(APP_DIR) (cd $(APP_RELEASE_DIR); gtar zcf $(APP_TAR_FILE) $(DIR_NAME)) + +dclean: + rm -f $(DIA_PLT) + rm -f $(DIA_ANALYSIS) + +dialyzer_plt: $(DIA_PLT) + +$(DIA_PLT): + @echo "Building $(APPLICATION) plt file" + @dialyzer --build_plt \ + --output_plt $@ \ + -r ../$(APPLICATION)/ebin \ + --output $(DIA_ANALYSIS) \ + --verbose + +dialyzer: $(DIA_PLT) + @echo "Running dialyzer on $(APPLICATION)" + @dialyzer --plt $< \ + ../$(APPLICATION)/ebin \ + --verbose
\ No newline at end of file diff --git a/lib/snmp/doc/src/Makefile b/lib/snmp/doc/src/Makefile index 35ed63e103..aa9431477c 100644 --- a/lib/snmp/doc/src/Makefile +++ b/lib/snmp/doc/src/Makefile @@ -152,6 +152,7 @@ $(TOP_PDF_FILE): $(XML_FILES) pdf: $(TOP_PDF_FILE) html: gifs $(HTML_REF_MAN_FILE) +html2: html $(INDEX_TARGET) clean clean_docs: clean_html clean_man clean_pdf rm -f errs core *~ @@ -228,6 +229,7 @@ clean_man: clean_html: @echo "cleaning html:" rm -rf $(HTMLDIR)/* + rm -f $(INDEX_TARGET) $(MAN7DIR)/%.7: $(MIBSDIR)/%.mib @echo "processing $*" @@ -286,7 +288,7 @@ release_docs_spec: docs $(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR) $(INSTALL_DIR) $(RELEASE_PATH)/man/man1 $(INSTALL_DATA) $(MAN1_FILES) $(RELEASE_PATH)/man/man1 - $(INSTALL_DIR) $(RELEASE_PATH)/man/man + $(INSTALL_DIR) $(RELEASE_PATH)/man/man3 $(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3 $(INSTALL_DIR) $(RELEASE_PATH)/man/man6 $(INSTALL_DATA) $(MAN6_FILES) $(RELEASE_PATH)/man/man6 diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 6a20d8ee3a..3a129a9c07 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>2011</year> + <year>1996</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -33,165 +33,83 @@ </header> <section> - <title>SNMP Development Toolkit 4.20</title> - <p>Version 4.20 supports code replacement in runtime from/to - version 4.19 and 4.18.</p> + <title>SNMP Development Toolkit 4.21.6</title> + <p>Version 4.21.6 supports code replacement in runtime from/to + version 4.21.5, 4.21.4, 4.21.3, 4.21.2, 4.21.1, 4.21, 4.20.1 and + 4.20. </p> <section> <title>Improvements and new features</title> -<!-- + <!-- <p>-</p> ---> - <list type="bulleted"> - <item> - <p>[agent] Added support for sending traps to IPv6 targets. </p> - <p>See the - <seealso marker="snmp_agent_config_files#target_addr">target address config file</seealso>, - the <seealso marker="snmpa_conf#target_addr_entry">target_addr_entry/11</seealso> function or - <seealso marker="snmp_target_mib#add_addr">add_addr/11</seealso> for more info. </p> - <p>Own Id: OTP-9088</p> - <p>Aux Id: Seq 11790</p> - </item> - - - <item> - <p>[agent] To be able to handle multiple engine-id(s) when - sending trap(s), the function - <seealso marker="snmp_community_mib#add_community"> - add_community/6</seealso> has been added. </p> - <p>Own Id: OTP-9119</p> - <p>Aux Id: Seq 11792</p> - </item> - - <item> - <p>[manager] The API for snmp requests has been augmented to - allow the caller to override some configuration. </p> - <p>This has been done by introducing a new set of API functions, see - <seealso marker="snmpm#sync_get2">sync_get2/3,4</seealso>, - <seealso marker="snmpm#async_get2">async_get2/3,4</seealso>, - <seealso marker="snmpm#sync_get_next2">sync_get_next2/3,4</seealso>, - <seealso marker="snmpm#async_get_next2">async_get_next2/3,4</seealso>, - <seealso marker="snmpm#sync_get_bulk2">sync_get_bulk2/5,6</seealso>, - <seealso marker="snmpm#async_get_bulk2">async_get_bulk2/5,6</seealso>, - <seealso marker="snmpm#sync_set2">sync_set2/3,4</seealso> and - <seealso marker="snmpm#async_set2">async_set2/3,4</seealso> - for more info. </p> - <p>Own Id: OTP-9162</p> - </item> - - <item> - <p>[manager] The old API functions (for get and set - requests: - snmpm:g/3,4,5,6,7, snmpm:ag/3,4,5,6,7, - snmpm:gn/3,4,5,6,7, snmpm:agn/3,4,5,6,7, - snmpm:s/3,4,5,6,7, snmpm:s/3,4,5,6,7, - snmpm:gb/5,6,7,8,9 and snmpm:agb/5,6,7,8,9) - are now officially deprecated. - They will be removed as of R16B. </p> - <p>Own Id: OTP-9174</p> - </item> + --> + <list type="bulleted"> <item> - <p>[agent] Pass extra info through the agent to the net-if - process when sending notifications. </p> - <p>See - <seealso marker="snmpa#send_notification2"> - snmpa:send_notification2/3</seealso> for more info. - See also the incomming net-if messages when sending a - <seealso marker="snmp_agent_netif#im_send_pdu">trap</seealso> - (send_pdu message) and - <seealso marker="snmp_agent_netif#im_send_pdu_req"> - notification</seealso> (send_pdu_req message). </p> - <p>Own Id: OTP-9183</p> - <p>Aux Id: Seq 11817</p> + <p>[agent] DoS attack using GET-BULK with large value of + MaxRepetitions. + A preventive method has been implementing by simply + limit the number of varbinds that can be included in + a Get-BULK response message. This is specified by the + new config option, + <seealso marker="snmp_app#agent_gb_max_vbs">gb_max_vbs</seealso>. + </p> + <p>Own Id: OTP-9700</p> </item> - <item> - <p>Added type specs for functions that do not return. </p> - <p>Kostis Sagonas</p> - <p>Own Id: OTP-9208</p> - </item> </list> + </section> <section> - <title>Fixed Bugs and Malfunctions</title> -<!-- - <p>-</p> ---> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> <list type="bulleted"> <item> - <p>Fixed endode/decode of values of type <c>Counter32</c>. </p> - <p>This type (<c>Counter32</c>) is an unsigned integer 32, - but is actually encoded as an signed integer 32. - The encode/decode functions however, treated it as if it was - encodeded as an unsigned integer 32. </p> - <p>Own Id: OTP-9022</p> - </item> + <p>[agent] Mib server cache gclimit update function incorrectly calls + age update function. + The gclimit update function, + <seealso marker="snmpa#update_mibs_cache_gclimit">update_mibs_cache_gclimit/1</seealso>, + <em>incorrectly</em> called the age update function, + <seealso marker="snmpa#update_mibs_cache_age">update_mibs_cache_age/2</seealso>. </p> + <p>Johan Claesson</p> + <p>Own Id: OTP-9868</p> + </item> </list> - </section> + </section> <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.20 --> + </section> <!-- 4.21.6 --> <section> - <title>SNMP Development Toolkit 4.19</title> - <p>Version 4.19 supports code replacement in runtime from/to - version 4.18.</p> + <title>SNMP Development Toolkit 4.21.5</title> + <p>Version 4.21.5 supports code replacement in runtime from/to + version 4.21.4, 4.21.3, 4.21.2, 4.21.1, 4.21, 4.20.1 and 4.20. </p> <section> <title>Improvements and new features</title> <!-- <p>-</p> --> - <list type="bulleted"> - <item> - <p>[compiler] Added support for textual convention - <c>AGENT-CAPABILITIES</c> and "full" support for textual - convention MODULE-COMPLIANCE, both defined by the SNMPv2-CONF - mib.</p> - <p>The <c>reference</c> and <c>modules</c> part(s) are - stored in the <c>assocList</c> of the mib-entry (<c>me</c>) - record. - Only handled <em>if</em> the option(s) <c>agent_capabilities</c> - and <c>module_compliance</c> (respectively) are provided to the - compiler. </p> - <p>See <seealso marker="snmpc#compile">compile/2</seealso> - for more info. </p> - <p>For backward compatibillity, the MIBs provided with - this application are <em>not</em> compiled with these - options. </p> - <p>Own Id: OTP-8966</p> - </item> - - <item> - <p>[agent] Added a "complete" set of (snmp) table and variable - print functions, for each mib handled by the SNMP (agent) - application. This will be usefull when debugging a running agent.</p> - <p>See - <seealso marker="snmpa#print_mib_info">print_mib_info/0</seealso>, - <seealso marker="snmpa#print_mib_tables">print_mib_tables/0</seealso> - and - <seealso marker="snmpa#print_mib_variables">print_mib_variables/0</seealso> - for more info. </p> - <p>Own Id: OTP-8977</p> - </item> + <list type="bulleted"> <item> - <p>[compiler] Added a MIB compiler (frontend) escript, - <c>snmpc</c>. </p> - <p>Own Id: OTP-9004</p> + <p>[agent] Removed (more) use of old style tuple funs. </p> + <p>Own Id: OTP-9783</p> </item> </list> + </section> <section> @@ -199,194 +117,116 @@ <!-- <p>-</p> --> - <list type="bulleted"> - <item> - <p>[agent] For the table vacmAccessTable, - when performing the is_set_ok and set operation(s), - all values of the vacmAccessSecurityModel column was - incorrectly translated to <c>any</c>. </p> -<!-- -that is when calling: -snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). ---> - <p>Own Id: OTP-8980</p> - </item> + <list type="bulleted"> <item> - <p>[agent] When calling - <seealso marker="snmp_view_based_acm_mib#reconfigure">snmp_view_based_acm_mib:reconfigure/1</seealso> - on a running node, the table <c>vacmAccessTable</c> was not properly - cleaned. - This meant that if some entries in the vacm.conf file was removed - (compared to the <c>current</c> config), - while others where modified and/or added, the removed entrie(s) - would still exist in the <c>vacmAccessTable</c> table. </p> - <p>Own Id: OTP-8981</p> - <p>Aux Id: Seq 11750</p> + <p>[agent] Repeated vacm table dumping fails due to file name + conflict. When dumping the vacm table to disk, a temoporary + file with a fixed name was used. If the table dumping + (snmpa_vacm:dump_table/0) was initiated from several different + processes in rapid succesion, the dumping could fail because the + different processes was simultaniously trying to write to the + same file. This problem has been eliminated by creating a unique + name for the temporary file. </p> + <p>Own Id: OTP-9851</p> + <p>Aux Id: Seq 11980</p> </item> </list> </section> - <section> <title>Incompatibilities</title> <p>-</p> - </section> - - </section> <!-- 4.19 --> - - - <section> - <title>SNMP Development Toolkit 4.18</title> - <p>Version 4.18 supports code replacement in runtime from/to - version 4.17.1 and 4.17.</p> - - <section> - <title>Improvements and new features</title> - <list type="bulleted"> - <item> - <p>Prepared for R14B release.</p> - </item> - </list> - </section> - <section><title>Fixed Bugs and Malfunctions</title> - <p>-</p> <!-- <list type="bulleted"> <item> - <p>[agent] When the function FilterMod:accept_recv/2 returned false - the SNMP agent stopped collecting messages from UDP.</p> - <p>Own Id: OTP-8761</p> + <p>foo. </p> + <p>Own Id: OTP-9718</p> </item> + </list> --> - </section> - <section> - <title>Incompatibilities</title> - <p>-</p> </section> - </section> <!-- 4.18 --> + + </section> <!-- 4.21.5 --> <section> - <title>SNMP Development Toolkit 4.17.1</title> - <p>Version 4.17.1 supports code replacement in runtime from/to - version 4.17, 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> + <title>SNMP Development Toolkit 4.21.4</title> + <p>This version has never been released for R14B.</p> + <p>Version 4.21.4 supports code replacement in runtime from/to + version 4.21.3, 4.21.2, 4.21.1, 4.21, 4.20.1, 4.20 and 4.19. </p> <section> <title>Improvements and new features</title> - <p>-</p> - </section> + <p>-</p> - <section> - <title>Reported Fixed Bugs and Malfunctions</title> +<!-- <list type="bulleted"> <item> - <p>When the function FilterMod:accept_recv/2 - returned false the SNMP agent stopped collecting - messages from UDP.</p> - <p>Own Id: OTP-8761</p> + <p>[compiler] Improved version info printout from the + <seealso marker="snmpc(command)#">MIB compiler frontend escript</seealso>. </p> + <p>Own Id: OTP-9618</p> </item> + </list> - </section> +--> - <section> - <title>Incompatibilities</title> - <p>-</p> </section> - </section> <!-- 4.17.1 --> - - - <section> - <title>SNMP Development Toolkit 4.17</title> - <p>Version 4.17 supports code replacement in runtime from/to - version 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> <section> - <title>Improvements and new features</title> - <!-- + <title>Fixed Bugs and Malfunctions</title> +<!-- <p>-</p> - --> +--> + <list type="bulleted"> <item> - <p>[agent] Added very basic support for multiple SNMPv3 - EngineIDs in a single agent. See - <seealso marker="snmpa#send_notification">send_notification/7</seealso>, - <seealso marker="snmpa_mpd#process_packet">process_packet/7</seealso>, - <seealso marker="snmpa_mpd#generate_response_msg">generate_response_msg/6</seealso> or - <seealso marker="snmpa_mpd#generate_msg">generate_msg/6</seealso> - for more info. </p> - - <p>Own Id: OTP-8478</p> + <p>[agent] Removed use of old style tuple funs. </p> + <p>Own Id: OTP-9779</p> </item> </list> - </section> <section> - <title>Reported Fixed Bugs and Malfunctions</title> + <title>Incompatibilities</title> <p>-</p> - <!-- +<!-- <list type="bulleted"> <item> - <p>The config utility - (<seealso marker="snmp#config">snmp:config/0</seealso>) - generated a default notify.conf - with a bad name for the standard trap entry (was "stadard trap", - but should have been "standard trap"). This has been corrected. </p> - <p>Kenji Rikitake</p> - <p>Own Id: OTP-8433</p> + <p>foo. </p> + <p>Own Id: OTP-9718</p> </item> </list> - --> +--> </section> - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.17 --> + </section> <!-- 4.21.4 --> <section> - <title>SNMP Development Toolkit 4.16.2</title> - <p>Version 4.16.2 supports code replacement in runtime from/to - version 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> + <title>SNMP Development Toolkit 4.21.3</title> + <p>Version 4.21.3 supports code replacement in runtime from/to + version 4.21.2, 4.21.1, 4.21, 4.20.1, 4.20 and 4.19. </p> <section> <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[compiler] The SMI specifies that a table row OID should be - named: { <tableIdentifier> "1" }. </p> - <p>A new option has been introduced, - <seealso marker="snmpc#compiler_opts">relaxed_row_name_assign_check</seealso>, - that allows for a more liberal numbering scheme</p> - <p>Own Id: OTP-8574</p> - </item> - - <item> - <p>[agent|manager] Changes to make snmp (forward) compatible with - the new version of the crypto application (released in R14). - As of R14, crypto is implemented using NIFs. Also, - the API is more strict. </p> - <p>Own Id: OTP-8594</p> - </item> +<!-- + <p>-</p> +--> + <list type="bulleted"> <item> - <p>Auto [agent] Changed default value for the MIB server cache. - GC is now on by default. </p> - <p>Own Id: OTP-8648</p> + <p>[compiler] Improved version info printout from the + <seealso marker="snmpc(command)#">MIB compiler frontend escript</seealso>. </p> + <p>Own Id: OTP-9618</p> </item> </list> @@ -394,1152 +234,533 @@ snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). </section> <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> + <title>Fixed Bugs and Malfunctions</title> +<!-- + <p>-</p> +--> <list type="bulleted"> <item> - <p>Encode/decode of Counter64 values larger than - 16#7fffffffffffffff (9223372036854775807) failed. </p> - <p>Own Id: OTP-8563</p> + <p>[agent] Version 4.20 introduced a change that broke trap + sending from subagents. Due to a bug in the test code, + this was not discovered, until that bug was fixed. </p> + <p>Own Id: OTP-9745</p> </item> <item> - <p>[compiler] Fails to compile non-contiguous BITS. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-8595</p> + <p>[agent] When sending an error message (reply) regarding + <c>snmpUnknownPDUHandlers</c>, the agent used the wrong OID. </p> + <p>Own Id: OTP-9747</p> </item> <item> - <p>[manager] Raise condition causing the manager server process to - crash. Unregistering an agent while traffic (set/get-operations) - is ongoing could cause a crash in the manager server process - (raise condition). </p> - <p>Own Id: OTP-8646</p> - <p>Aux Id: Seq 11585</p> + <p>[compiler] Fix the <c>--warnings/--W</c> option parsing in the + <seealso marker="snmpc(command)#option_warnings">snmpc</seealso> + wrapper (e)script. + The short warning option was incorrectly <c>--w</c>, instead + of as documented <c>--W</c>. This has now been corrected. </p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Tuncer Ayaz</p> + <p>Own Id: OTP-9718</p> </item> </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> </section> - </section> <!-- 4.16.2 --> - - - <section> - <title>SNMP Development Toolkit 4.16.1</title> - <p>Version 4.16.1 supports code replacement in runtime from/to - version 4.16, 4.15, 4.14 and 4.13.5.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <p>[agent|manager] Entries in the audit trail log can now be - augmented by a sequence number. </p> - <p>This is enabled by the <c>seqno</c> option, which is part of the - <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso> - config option. </p> - <p>See the - <seealso marker="snmp_app#configuration_params">reference manual</seealso> - or the - <seealso marker="snmp_config#configuration_params">Configuring the application</seealso> - chapter of the User's Guide for further info. </p> - - <p>Own Id: OTP-8395</p> - </item> - </list> - --> - - </section> <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- + <title>Incompatibilities</title> +<!-- <p>-</p> - --> +--> <list type="bulleted"> <item> - <p>[manager] Fixed an upgrade/downgrade problem. </p> - <p>Upgrade/downgrade from/to 4.13.5 did not work for the net-if - process. This has now been fixed. </p> - <p>Own Id: OTP-8481</p> - </item> - - <item> - <p>[agent] A minor mnesia related performance improvement. </p> - <p>Own Id: OTP-8480</p> + <p>[compiler] The short warning option has been changed from + <c>--w</c> to <c>--W</c> to comply with the documentation. </p> + <p>Tuncer Ayaz</p> + <p>Own Id: OTP-9718</p> </item> </list> - </section> - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.16.1 --> + </section> <!-- 4.21.3 --> <section> - <title>SNMP Development Toolkit 4.16</title> - <p>Version 4.16 supports code replacement in runtime from/to - version 4.15, 4.14 and 4.13.5.</p> + <title>SNMP Development Toolkit 4.21.2</title> + <p>Version 4.21.2 supports code replacement in runtime from/to + version 4.21.1, 4.21, 4.20.1, 4.20 and 4.19. </p> <section> <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent|manager] Entries in the audit trail log can now be - augmented by a sequence number. </p> - <p>This is enabled by the <c>seqno</c> option, which is part of the - <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso> - config option. </p> - <p>See the - <seealso marker="snmp_app#configuration_params">reference manual</seealso> - or the - <seealso marker="snmp_config#configuration_params">Configuring the application</seealso> - chapter of the User's Guide for further info. </p> - - <p>Own Id: OTP-8395</p> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- <p>-</p> - --> +<!-- <list type="bulleted"> <item> - <p>[manager] Registration of agents using the config file, - <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>, - does not work. This has now been corrected. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-8442</p> - </item> - - <item> - <p>The config utility - (<seealso marker="snmp#config">snmp:config/0</seealso>) - generated a default notify.conf - with a bad name for the standard trap entry (was "stadard trap", - but should have been "standard trap"). This has been corrected. </p> - <p>Kenji Rikitake</p> - <p>Own Id: OTP-8433</p> + <p>Bad note store GC timer deactivation. + Wrong field in the state record was set (timeout instead active). </p> + <p>Stefan Grundmann</p> + <p>Own Id: OTP-9690</p> </item> </list> +--> </section> <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.16 --> - - - <section> - <title>SNMP Development Toolkit 4.15</title> - - <p>Version 4.15 supports code replacement in runtime from/to - version 4.14 and 4.13.5.</p> - - <section> - <title>Improvements and new features</title> - <!-- + <title>Fixed Bugs and Malfunctions</title> +<!-- <p>-</p> - --> +--> <list type="bulleted"> <item> - <p>The documentation is now built with open source tools - (<em>xsltproc</em> and <em>fop</em>) that exists on most - platforms. One visible change is that the frames are removed.</p> - <p>Own Id: OTP-8249</p> + <p>Bad note store GC timer deactivation. + Wrong field in the state record was set (timeout instead active). </p> + <p>Stefan Grundmann</p> + <p>Own Id: OTP-9690</p> </item> </list> - </section> + <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- + <title>Incompatibilities</title> <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] When information from an unknown agent is received, - it was previously delivered to the default user via calls to all - the functions of the callback API depending on the info type - (<c>pdu</c>, <c>trap</c>, <c>report</c> or <c>inform</c>). - The problem was that the <c>TargetName</c> argument was useless - in this case (only an already known agent has a known/valid - <c>TargetName</c>, but the <c>TargetName</c> used in these calls - was generated "on the fly"). </p> - <p>This has now been changed so that when a message is received - from an unknown agent, then only - <seealso marker="snmpm_user#handle_agent">handle_agent</seealso> - (for the default user) is called, but now this call also has a - <c>Type</c> argument, which is - <c>pdu | trap | report | inform</c>, depending on what kind of - message was actually received, thus making it possible for the - user to properly analyze the data received. </p> - <p>To handle this, the - <seealso marker="snmpm_user">snmpm_user</seealso> behaviour has - been updated. </p> - <p>*** POTENTIAL INCOMPATIBILITY ***</p> - <p>Own Id: OTP-8229</p> - <!-- <p>Aux Id: Seq 11312</p> --> - </item> - - </list> - </section> - </section> <!-- 4.15 --> + </section> <!-- 4.21.2 --> <section> - <title>SNMP Development Toolkit 4.14</title> - - <p>Version 4.14 supports code replacement in runtime from/to - version 4.13.5, 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + <title>SNMP Development Toolkit 4.21.1</title> + <p>Version 4.21.1 supports code replacement in runtime from/to + version 4.20.1, 4.20 and 4.19. </p> <section> <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - +<!-- + <p>-</p> +--> <list type="bulleted"> <item> - <p>[compiler] Include object- and notification groups in the - compiled mib. - This will make it possible to import groups from other mibs. </p> - <p>Also the SNMPv2-MIB-file has been updated to a more - up-to-date version. </p> - <p>Own Id: OTP-8223</p> - <!-- <p>Aux Id: Seq 11383</p> --> - </item> - - <item> - <p>[manager] Added support for message filtering in the - network interface module provided with the application. - The component that actually make the filter decisions - is the network interface filter module. This module - must implement the - <seealso marker="snmpm_network_interface_filter">network interface filter behaviour</seealso> - for message filtering. - See also the Configuring chapter of - the User's Guide to see how to configure this feature. </p> - <p>See the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the filter options.</p> - <p>Own Id: OTP-8228</p> - <p>Aux Id: Seq 11411</p> + <p>[compiler] Used wrong variable name (for + warnings-as-errors variable), which caused the + compiler to crash when using the snmpc (e)script. </p> + <p>Also added the option + <seealso marker="snmpc(command)#option_werror">--Werror</seealso> + for the SNMP MIB compiler (escript) frontend (to mimic + <seealso marker="erts:erlc">erlc</seealso>), + which specifies whether warnings should be treated as errors. </p> + <p>Own Id: OTP-9447</p> </item> <item> - <p>The MIBs delivered as part of the application is now - also available as man pages, section 7. </p> - <p>Own Id: OTP-8237</p> - <!-- <p>Aux Id: Seq 11383</p> --> + <p>[agent] Some very minor debugging improvements. </p> + <p>Own Id: OTP-9446</p> </item> - </list> </section> <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <p>-</p> + <title>Fixed Bugs and Malfunctions</title> + <p>-</p> - <!-- +<!-- <list type="bulleted"> <item> - <p>[agent] The main agent type header file contained some miss-information - regarding the type of the entrytype field of the me-record, causing - unneccessary confusion.</p> - <p>Own Id: OTP-8116</p> - <p>Aux Id: Seq 11312</p> - </item> + <p>The snmp config tool could not handle (manager) audit trail config + because the option seqno was not handled. </p> + <p>Own Id: OTP-9354</p> + </item> </list> - --> - +--> </section> + <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.14 --> + </section> <!-- 4.21.1 --> - <section> - <title>SNMP Development Toolkit 4.13.5</title> - <p>Version 4.13.5 supports code replacement in runtime from/to - version 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + <section> + <title>SNMP Development Toolkit 4.21</title> + <p>Version 4.21 supports code replacement in runtime from/to + version 4.20.1, 4.20 and 4.19. </p> <section> <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - +<!-- + <p>-</p> +--> <list type="bulleted"> <item> - <p>[agent] Improved the cache handling of the mib server. </p> - <p>A number of new functions and config options for the mib server - cache has been added. </p> - <p>See - <seealso marker="snmpa#invalidate_mibs_cache">invalidate_mibs_cache/0,1</seealso>, - <seealso marker="snmpa#enable_mibs_cache">enable_mibs_cache/0,1</seealso>, - <seealso marker="snmpa#disable_mibs_cache">disable_mibs_cache/0,1</seealso>, - <seealso marker="snmpa#gc_mibs_cache">gc_mibs_cache/0,1,2,3</seealso>, - <seealso marker="snmpa#enable_mibs_cache_autogc">enable_mibs_cache_autogc/0,1</seealso>, - <seealso marker="snmpa#disable_mibs_cache_autogc">disable_mibs_cache_autogc/0,1</seealso>, - <seealso marker="snmpa#update_mibs_cache_age">update_mibs_cache_age/1,2</seealso> and - <seealso marker="snmpa#update_mibs_cache_gclimit">update_mibs_cache_gclimit/1,2</seealso> for more info. </p> - <p>See also the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the mib server cache options.</p> - <p>Own Id: OTP-8182</p> - <p>Aux Id: Seq 11383</p> + <p>[manager] There was no way to specify transport domain. + The transport domains was assumed to be IPv4 (transportDomainUdpIpv4). + This has now been changed so that it can also be IPv6 + (transportDomainUdpIpv6). + To facilitate this, the transport domain, <c>tdomain</c>, + is now a (new) valid option when + <seealso marker="snmpm#register_agent">registering</seealso> + a new agent (and + <seealso marker="snmpm#update_agent_info">updating</seealso> + agent info). </p> + <p>This also mean that the transport behaviour has changed. </p> + <p>Own Id: OTP-9305</p> + <p>Aux Id: Seq 11847</p> </item> <item> - <p>[agent] A manager could no longer use the SNMPv3 user "initial" - as this was interpretated as the first step of the discovery. </p> - <p>Introduced a new terminating option, <c>trigger_username</c> to - make it possible to configure the username the agent reacts to. - Default is <c>""</c>. </p> - <p>See the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the discovery options.</p> - <p>Own Id: OTP-8120</p> - <p>Aux Id: Seq 11361</p> - </item> - - </list> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] The main agent type header file contained some miss-information - regarding the type of the entrytype field of the me-record, causing - unneccessary confusion.</p> - <p>Own Id: OTP-8116</p> - <p>Aux Id: Seq 11312</p> + <p>[compiler] Added the option + <seealso marker="snmpc#compile">warnings_as_errors</seealso> + (for the SNMP MIB compiler (escript) frontend, the option + <seealso marker="snmpc(command)#option_wae">--wae</seealso> is used) + which specifies whether warnings should be treated as errors. </p> + <p>Tuncer Ayaz</p> + <p>Own Id: OTP-9437</p> </item> - </list> </section> <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.5 --> - - - <section> - <title>SNMP Development Toolkit 4.13.4</title> - - <p>Version 4.13.4 supports code replacement in runtime from/to - version 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> - - <section> - <title>Improvements and new features</title> + <title>Fixed Bugs and Malfunctions</title> +<!-- <p>-</p> +--> - <!-- - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> <list type="bulleted"> <item> - <p>[agent] Originating discovery problems. </p> - <p>Invalid state variable update during second stage of - discovery causes master agent crash. </p> - <p>Also the net_if process failed to activate socket - ({active, once}) after first discovery response was sent. </p> - <p>Own Id: OTP-8044</p> - <p>Aux Id: Seq 11295</p> - </item> + <p>The snmp config tool could not handle (manager) audit trail config + because the option seqno was not handled. </p> + <p>Own Id: OTP-9354</p> + </item> <item> - <p>[agent] Terminating discovery problem. </p> - <p>The reply to the second stage request should include a - varbind with <c>usmStatsNotInTimeWindows</c>.</p> - <p>Own Id: OTP-8062</p> - <p>Aux Id: Seq 11318</p> - </item> + <p>[agent] The SNMP ACM cache was not properly updated when + changes where made to the VACM security-to-group, access and + view-tree-family tables. </p> + <p>Own Id: OTP-9367</p> + <p>Aux Id: Seq 11858</p> + </item> <item> - <p>[agent] Originating discovery improvement. </p> - <p>Added the ExtraInfo argument to the - <seealso marker="snmpa#discovery">discovery</seealso> function. - This argument will be passed on to the stage1_finish callback - function. Also, the - <seealso marker="snmpa#discovery">discovery</seealso> function - will now always return <c>{ok, ManagerEngineID}</c> on successful - discovery. </p> - <p>The <seealso marker="snmpa_discovery_handler">discovery handler</seealso> - behaviour updated accordingly. </p> - <p>Own Id: OTP-8098</p> - <p>Aux Id: Seq 11346</p> - </item> + <p>Fixed install directory typo for man3. </p> + <p>Peter Lemenkov</p> + <p>Hans Ulrich Niedermann</p> + <p>Own Id: OTP-9442</p> + </item> </list> - </section> + <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.13.4 --> + </section> <!-- 4.21 --> - <section> - <title>SNMP Development Toolkit 4.13.3</title> - <p>Version 4.13.3 supports code replacement in runtime from/to - version 4.13.2, 4.13.1 and 4.13.</p> + <section> + <title>SNMP Development Toolkit 4.20.1</title> + <p>Version 4.20.1 supports code replacement in runtime from/to + version 4.20, 4.19 and 4.18.</p> <section> <title>Improvements and new features</title> - <p>-</p> - - <!-- + <p>-</p> +<!-- <list type="bulleted"> <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> + <p>Added type specs for functions that do not return. </p> + <p>Kostis Sagonas</p> + <p>Own Id: OTP-9208</p> </item> - </list> - --> - +--> </section> <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> + <title>Fixed Bugs and Malfunctions</title> +<!-- + <p>-</p> +--> <list type="bulleted"> <item> - <p>[manager] A request for an oid of type BITS was actually - returned as OCTET STRING. </p> - <p>Values of type BITS are encoded as OCTET STRING, - which makes it impossible for the decoder to know that - they should really be of type BITS. - Instead, this has to be done higher up in the stack, where - there is knowledge of the MIB (assuming that the mib has - been loaded, there is info about the type of the mibentry). </p> - <p>This problem has now been fixed, but requires that the MIB - defining this mib-entry is loaded! </p> - <p>The utility function - <seealso marker="snmpm#oid_to_type">oid_to_type</seealso> - has been added, for debug purpose. </p> - <p>The utility function(s) - <seealso marker="snmp#octet_string_to_bits">octet_string_to_bits</seealso> - and - <seealso marker="snmp#bits_to_octet_string">bits_to_octet_string</seealso> - has also been added. These can be used if the user prefers to - handle the conversion on their own. </p> - <p>Own Id: OTP-8015</p> - <p>Aux Id: Seq 11285</p> - </item> + <p>[agent] Did not handle transport domains properly in some cases, + for instance trap sending. </p> + <p>Own Id: OTP-9400</p> + </item> <item> - <p>[agent] Fixed some issues with the discovery handling. </p> - <p>Changed the API of the - <seealso marker="snmpa#discovery">discovery</seealso> - function to solve some - of these problems. </p> - <p>Introduced various options for controlling the discovery - process. See the - <seealso marker="snmp_app#configuration_params">configuration</seealso> - chapter for more info about the discovery options.</p> - <p>Own Id: OTP-8020</p> - <p>Aux Id: Seq 11295</p> - </item> + <p>[agent] Wrong default transport domain, snmpUDPDomain, instead + of transportDomainUdpIpv4. </p> + <p>Own Id: OTP-9425</p> + <p>Aux Id: Seq 11874</p> + </item> </list> - </section> + <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.13.3 --> + </section> <!-- 4.20.1 --> - <section> - <title>SNMP Development Toolkit 4.13.2</title> - <p>Version 4.13.2 supports code replacement in runtime from/to - version 4.13.1 and 4.13.</p> + <section> + <title>SNMP Development Toolkit 4.20</title> + <p>Version 4.20 supports code replacement in runtime from/to + version 4.19 and 4.18.</p> <section> <title>Improvements and new features</title> - <p>-</p> - - <!-- - <list type="bulleted"> - <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- +<!-- <p>-</p> - --> +--> <list type="bulleted"> <item> - <p>[manager] Failure during downed user cleanup. - As part of the cleanup after a crashed user, - the manager attempts to unregister the agents - registered by this user. This however failed, - causing a server crash. </p> - <p>Own Id: OTP-7961</p> - <p>Aux Id: Seq 11275</p> - </item> + <p>[agent] Added support for sending traps to IPv6 targets. </p> + <p>See the + <seealso marker="snmp_agent_config_files#target_addr">target address config file</seealso>, + the <seealso marker="snmpa_conf#target_addr_entry">target_addr_entry/11</seealso> function or + <seealso marker="snmp_target_mib#add_addr">add_addr/11</seealso> for more info. </p> + <p>Own Id: OTP-9088</p> + <p>Aux Id: Seq 11790</p> + </item> + <item> - <p>[manager] Incorrectly documented value type for - IpAddress (ip). The value type for IpAddress is - documented as ip but is actually ia. The value type - ip has been added. The old (not documented) value - type ia still works. </p> - <p>Own Id: OTP-7977</p> - <p>Aux Id: Seq 11279</p> + <p>[agent] To be able to handle multiple engine-id(s) when + sending trap(s), the function + <seealso marker="snmp_community_mib#add_community"> + add_community/6</seealso> has been added. </p> + <p>Own Id: OTP-9119</p> + <p>Aux Id: Seq 11792</p> </item> <item> - <p>[manager] EngineId lookup fails when using version-3. </p> - <p>Own Id: OTP-7983</p> - <p>Aux Id: Seq 11275</p> + <p>[manager] The API for snmp requests has been augmented to + allow the caller to override some configuration. </p> + <p>This has been done by introducing a new set of API functions, see + <seealso marker="snmpm#sync_get2">sync_get2/3,4</seealso>, + <seealso marker="snmpm#async_get2">async_get2/3,4</seealso>, + <seealso marker="snmpm#sync_get_next2">sync_get_next2/3,4</seealso>, + <seealso marker="snmpm#async_get_next2">async_get_next2/3,4</seealso>, + <seealso marker="snmpm#sync_get_bulk2">sync_get_bulk2/5,6</seealso>, + <seealso marker="snmpm#async_get_bulk2">async_get_bulk2/5,6</seealso>, + <seealso marker="snmpm#sync_set2">sync_set2/3,4</seealso> and + <seealso marker="snmpm#async_set2">async_set2/3,4</seealso> + for more info. </p> + <p>Own Id: OTP-9162</p> </item> <item> - <p>[agent] As of version 4.13 the possible return values - of the function - <seealso marker="snmpa_mpd#process_packet">snmpa_mpd:process_packet/4</seealso> - changed, but this was not documented. </p> - <p>Own Id: OTP-7989</p> - <p>Aux Id: Seq 11275</p> + <p>[manager] The old API functions (for get and set + requests: + snmpm:g/3,4,5,6,7, snmpm:ag/3,4,5,6,7, + snmpm:gn/3,4,5,6,7, snmpm:agn/3,4,5,6,7, + snmpm:s/3,4,5,6,7, snmpm:s/3,4,5,6,7, + snmpm:gb/5,6,7,8,9 and snmpm:agb/5,6,7,8,9) + are now officially deprecated. + They will be removed as of R16B. </p> + <p>Own Id: OTP-9174</p> </item> - </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.2 --> - - <section> - <title>SNMP Development Toolkit 4.13.1</title> - - <p>Version 4.13.1 supports code replacement in runtime from/to - version 4.13.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - - <!-- - <list type="bulleted"> <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> + <p>[agent] Pass extra info through the agent to the net-if + process when sending notifications. </p> + <p>See + <seealso marker="snmpa#send_notification2"> + snmpa:send_notification2/3</seealso> for more info. + See also the incomming net-if messages when sending a + <seealso marker="snmp_agent_netif#im_send_pdu">trap</seealso> + (send_pdu message) and + <seealso marker="snmp_agent_netif#im_send_pdu_req"> + notification</seealso> (send_pdu_req message). </p> + <p>Own Id: OTP-9183</p> + <p>Aux Id: Seq 11817</p> </item> - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> <item> - <p>[manager] Registration of users had some issues. </p> - <p>Not all of the registration functions where actually exported - (<seealso marker="snmpm#register_user">register_user/4</seealso> - and - <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>). - This has now been fixed. </p> - <p>Also, the registration did not succeed unless - user implemented the *new* behaviour. This has now - also been fixed (registration succeeds if the user - implements either the new (i.e. updated - <seealso marker="snmpm_user">snmpm_user</seealso>) - or the old user behaviour (<c>snmpm_user_old</c>)). </p> - <p>Own Id: OTP-7902</p> - <p>Aux Id: Seq 11240</p> + <p>Added type specs for functions that do not return. </p> + <p>Kostis Sagonas</p> + <p>Own Id: OTP-9208</p> </item> - </list> - </section> <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.13.1 --> - - <section> - <title>SNMP Development Toolkit 4.13</title> + <title>Fixed Bugs and Malfunctions</title> <!-- - <p>Version 4.13 supports code replacement in runtime from/to - version 4.12.1.</p> + <p>-</p> --> - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> <list type="bulleted"> <item> - <p>[agent] Support for the discovery process. </p> - <p>The agent can both initiate discovery itself (see the - <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter - for more info) and respond to discovery initiated by a manager.</p> - <p>Own Id: OTP-7571</p> - <p>Aux Id: Seq 11053</p> - </item> + <p>Fixed endode/decode of values of type <c>Counter32</c>. </p> + <p>This type (<c>Counter32</c>) is an unsigned integer 32, + but is actually encoded as an signed integer 32. + The encode/decode functions however, treated it as if it was + encodeded as an unsigned integer 32. </p> + <p>Own Id: OTP-9022</p> + </item> </list> - </section> - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Unnecessary use of math:pow/2 could cause problems - on systems without floating point support. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7735</p> - <!-- <p>Aux Id: Seq 10966</p> --> - </item> - - <item> - <p>[manager] A major flaw was discovered with the agent handling. </p> - <p>First, <c>TargetName</c> was never used as intended, as a unique - identifier for the target (agent in this case). </p> - <p>Second, <c>TargetName</c> had a <em>default value</em>, which meant - that several agents could have the same <c>TargetName</c>, causing - unpredictable behaviour in the manager. </p> - <p>Third, <c>EngineID</c> was not a mandatory config option and had - furthermore also a <em>default value</em>. </p> - - <p>These problems has been solved in the following way: </p> - <p>First, a new set of api functions has been introduced (and documented): - <seealso marker="snmpm#register_user">register_user/4</seealso>, - <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>, - <seealso marker="snmpm#register_agent">register_agent/3</seealso>, - <seealso marker="snmpm#unregister_agent">unregister_agent/2</seealso>, - <seealso marker="snmpm#agent_info">agent_info/2</seealso>, - <seealso marker="snmpm#update_agent_info">update_agent_info/4</seealso>, - <seealso marker="snmpm#sync_get">sync_get/3,4,5,6</seealso>, - <seealso marker="snmpm#async_get">async_get/3,4,5,6</seealso>, - <seealso marker="snmpm#sync_get_next">sync_get_next/3,4,5,6</seealso>, - <seealso marker="snmpm#async_get_next">async_get_next/3,4,5,6</seealso>, - <seealso marker="snmpm#sync_set">sync_set/3,4,5,6</seealso>, - <seealso marker="snmpm#async_set">async_set/3,4,5,6</seealso>, - <seealso marker="snmpm#sync_get_bulk">sync_get_bulk/5,6,7,8</seealso> and - <seealso marker="snmpm#async_get_bulk">async_get_bulk/5,6,7,8</seealso> - that all use <c>TargetName</c> (and not, as previously, <c>Addr</c> - and <c>Port</c>) to identify the agent (also the return value of - <seealso marker="snmpm#which_agents">which_agents</seealso> has - been changed). </p> - <p>Second, for backward compatibility, the old functions still - exist, but are no longer documented and are now wrappers for the - new functions, including erroneous default value for EngineID and - all. The TargetName is however generated from the provided - <c>Addr</c>, <c>Port</c> and <c>Version</c> config options. </p> - <p>Third, the behaviour of the - <seealso marker="snmpm_user">SNMP manager user</seealso> has - been changed to reflect this, i.e. - <seealso marker="snmpm_user#handle_pdu">handle_pdu/4</seealso>, - <seealso marker="snmpm_user#handle_trap">handle_trap/3</seealso>, - <seealso marker="snmpm_user#handle_inform">handle_inform/3</seealso>, - <seealso marker="snmpm_user#handle_report">handle_report/3</seealso> - and the return-value of - <seealso marker="snmpm_user#handle_agent">handle_agent/4</seealso>. - The old (non-documented) callback-functions (using Addr and Port) - will still be called if the agent was registered using the old - registration functions. </p> - - <p>Own Id: OTP-7836</p> - <!-- <p>Aux Id: Seq 10966</p> --> - </item> - - </list> - - </section> <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.13 --> - <section> - <title>SNMP Development Toolkit 4.12.2</title> - <p>Version 4.12.2 supports code replacement in runtime from/to - version 4.12.1, 4.12, 4.11.2, 4.11.1 and 4.11.</p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <item> - <p>[agent] Improvement of the inform reporting. - It was previously not certain how many acks an - application received, 0, 1 or 2. This has now been - fixed, so that only 1 (one) ack is issued. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7525</p> - </item> - - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Bad session cache (usm+camv-info) invalidation - could cause user crash, through call(s) to (a number of) - MIB API function(s) (undefined function). </p> - <p>Own Id: OTP-7868</p> - <!-- <p>Aux Id: Seq 11124</p> --> - </item> - - </list> - - </section> + </section> <!-- 4.20 --> - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.12.2 --> <section> - <title>SNMP Development Toolkit 4.12.1</title> - <p>Version 4.12.1 supports code replacement in runtime from/to - version 4.12, 4.11.2, 4.11.1 and 4.11.</p> + <title>SNMP Development Toolkit 4.19</title> + <p>Version 4.19 supports code replacement in runtime from/to + version 4.18.</p> <section> <title>Improvements and new features</title> - <p>-</p> - <!-- +<!-- + <p>-</p> +--> <list type="bulleted"> <item> - <item> - <p>[agent] Improvement of the inform reporting. - It was previously not certain how many acks an - application received, 0, 1 or 2. This has now been - fixed, so that only 1 (one) ack is issued. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7525</p> + <p>[compiler] Added support for textual convention + <c>AGENT-CAPABILITIES</c> and "full" support for textual + convention MODULE-COMPLIANCE, both defined by the SNMPv2-CONF + mib.</p> + <p>The <c>reference</c> and <c>modules</c> part(s) are + stored in the <c>assocList</c> of the mib-entry (<c>me</c>) + record. + Only handled <em>if</em> the option(s) <c>agent_capabilities</c> + and <c>module_compliance</c> (respectively) are provided to the + compiler. </p> + <p>See <seealso marker="snmpc#compile">compile/2</seealso> + for more info. </p> + <p>For backward compatibillity, the MIBs provided with + this application are <em>not</em> compiled with these + options. </p> + <p>Own Id: OTP-8966</p> </item> - </list> - --> - - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> <item> - <p>Logging of messages with the GetBulk-request PDU - incorrectly produced an erroneous entry in the - log: "An error occurred". </p> - <p>The reason for this was that the PDU-fields - error_status and error_index is re-used for - Non-repeaters and Max-repetitions for - GetBulk-request PDUs, but this was not handled - by the logging code. </p> - <p>Own Id: OTP-7695</p> - <p>Aux Id: Seq 11124</p> + <p>[agent] Added a "complete" set of (snmp) table and variable + print functions, for each mib handled by the SNMP (agent) + application. This will be usefull when debugging a running agent.</p> + <p>See + <seealso marker="snmpa#print_mib_info">print_mib_info/0</seealso>, + <seealso marker="snmpa#print_mib_tables">print_mib_tables/0</seealso> + and + <seealso marker="snmpa#print_mib_variables">print_mib_variables/0</seealso> + for more info. </p> + <p>Own Id: OTP-8977</p> </item> <item> - <p>[agent] An attempt to set the row status to active for an - notReady table row, could result in an "inconsistentValue" - error. </p> - <p>The same problem existed when attempting to set row status - to notInService for a row in notReady. </p> - <p>Serge Aleynikov</p> - <p>Own Id: OTP-7698</p> - <!-- <p>Aux Id: Seq 10966</p> --> + <p>[compiler] Added a MIB compiler (frontend) escript, + <c>snmpc</c>. </p> + <p>Own Id: OTP-9004</p> </item> </list> - - </section> - - <section> - <title>Incompatibilities</title> - <p>-</p> </section> - </section> <!-- 4.12.1 --> - - <section> - <title>SNMP Development Toolkit 4.12</title> - <p>Version 4.12 supports code replacement in runtime from/to - version 4.11.2, 4.11.1 and 4.11.</p> <section> - <title>Improvements and new features</title> - <!-- + <title>Fixed Bugs and Malfunctions</title> +<!-- <p>-</p> - --> +--> <list type="bulleted"> <item> - <p>[agent] A simple lookup cache has been added to improve - the mib server lookup performance. </p> - <p>This can be disabled with the mib_server - <seealso marker="snmp_app">cache</seealso> option. </p> - <p>Own Id: OTP-7346</p> + <p>[agent] For the table vacmAccessTable, + when performing the is_set_ok and set operation(s), + all values of the vacmAccessSecurityModel column was + incorrectly translated to <c>any</c>. </p> +<!-- +that is when calling: +snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). +--> + <p>Own Id: OTP-8980</p> </item> <item> - <p>[agent] Improvement of the inform reporting. - It was previously not certain how many acks an - application received, 0, 1 or 2. This has now been - fixed, so that only 1 (one) ack is issued. </p> - <p>Per Hedeland</p> - <p>Own Id: OTP-7525</p> + <p>[agent] When calling + <seealso marker="snmp_view_based_acm_mib#reconfigure">snmp_view_based_acm_mib:reconfigure/1</seealso> + on a running node, the table <c>vacmAccessTable</c> was not properly + cleaned. + This meant that if some entries in the vacm.conf file was removed + (compared to the <c>current</c> config), + while others where modified and/or added, the removed entrie(s) + would still exist in the <c>vacmAccessTable</c> table. </p> + <p>Own Id: OTP-8981</p> + <p>Aux Id: Seq 11750</p> </item> </list> - </section> - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <p>[manager] Encryption error when attempting to send - version 3 inform-requests. </p> - <p>Own Id: OTP-7432</p> - <p>Aux Id: Seq 10966</p> - </item> - - </list> - --> - - </section> <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.12 --> - - <section> - <title>SNMP Development Toolkit 4.11.2</title> - <p>Version 4.11.2 supports code replacement in runtime from/to - version 4.11.1 and 4.11. </p> - - <section> - <title>Improvements and new features</title> - <p>-</p> - <!-- - <list type="bulleted"> - <item> - <p>Added utility functions for transforming DateAndTime - as [int()] to strings; - <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> - and - <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> - <p>Also added new validation function - <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> - <p>Own Id: OTP-7412</p> - <p>Aux Id: Seq 10987</p> - </item> - </list> - --> - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Erroneous engine-id check when receiving version 3 - informs. </p> - <p>Own Id: OTP-7570</p> - <p>Aux Id: Seq 11060</p> - </item> - - <item> - <p>Receiving an snmp message with a very large version - number could cause the erlang node to run out of - memory and consequently crash. </p> - <p>The standard specifies the snmp version as an - (unlimited) INTEGER, but today only - 0 (version 1), 1 (version 2) and 3 (version 3) is - actually used. So, when decoding a message, a limit - has been put on the snmp version integer in order - to not allow this kind of a problem. </p> - <p>Own Id: OTP-7575</p> - <p>Aux Id: Seq 11064</p> - </item> - - </list> - </section> - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.11.2 --> + </section> <!-- 4.19 --> <section> - <title>SNMP Development Toolkit 4.11.1</title> - <p>Version 4.11.1 supports code replacement in runtime from/to - version 4.11.</p> + <title>SNMP Development Toolkit 4.18</title> + <p>Version 4.18 supports code replacement in runtime from/to + version 4.17.1 and 4.17.</p> <section> <title>Improvements and new features</title> - <!-- - <p>-</p> - --> <list type="bulleted"> <item> - <p>[compiler] The MIB compiler did not retrieve the REFERENCE part - of a SNMP MIB definition. </p> - <p>This problem has been partly solved. For SNMP tables, - the assocList field of the tables mib-entry record now contains - this info (as <c>{reference, string()}</c>), <em>if</em> the - MIB was compiled with the compiler option <em>+reference</em>. </p> - <p>This solution is temporary, until such time as a permanent - solution (and probably not backward compatible) is devised, which - retrieves and stores all REFERENCE part(s) of a MIB. </p> - <p>See the - <seealso marker="snmpc#compiler_opts">compiler options</seealso> - for more info. </p> - - <p>Serge Aleynikov</p> - <p>Own Id: OTP-7426</p> - </item> - - <item> - <p>Added utility functions for transforming DateAndTime - as [int()] to strings; - <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> - and - <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> - <p>Also added new validation function - <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> - <p>Own Id: OTP-7412</p> - <p>Aux Id: Seq 10987</p> + <p>Prepared for R14B release.</p> </item> - </list> - </section> - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- + <section><title>Fixed Bugs and Malfunctions</title> <p>-</p> - --> +<!-- <list type="bulleted"> <item> - <p>[manager] Encryption error when attempting to send - version 3 inform-requests. </p> - <p>Own Id: OTP-7432</p> - <p>Aux Id: Seq 10966</p> + <p>[agent] When the function FilterMod:accept_recv/2 returned false + the SNMP agent stopped collecting messages from UDP.</p> + <p>Own Id: OTP-8761</p> </item> - </list> +--> </section> <section> <title>Incompatibilities</title> <p>-</p> </section> - </section> <!-- 4.11.1 --> - - <section> - <title>SNMP Development Toolkit 4.11</title> - <p>Version 4.11 supports code replacement in runtime from/to - version 4.10.3, 4.10.2, 4.10.1 and 4.10.</p> - - <section> - <title>Improvements and new features</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[agent] Performance improvements in the case when an SNMP - manager performs an snmpwalk. </p> - <p>Martin Björklund</p> - <p>Own Id: OTP-7201</p> - </item> - - <item> - <p>The API for sending inform(s) has been improved. Also - the documentation has been corrected and updated. See - <seealso marker="snmpa#send_notification">snmpa:send_notification</seealso> and - <seealso marker="snmpa_notification_delivery_info_receiver">snmpa_notification_delivery_info_receiver</seealso> - for more info.</p> - <p>Own Id: OTP-7287</p> - <p>Aux Id: Seq 10926</p> - </item> - - <item> - <p>[agent] Performance of the internal database (local-db) - has been improved.</p> - <p>Own Id: OTP-7319</p> - <p>Aux Id: Seq 10942</p> - </item> - - <item> - <p>[agent] Added utility functions, - <seealso marker="snmpa#restart_worker">snmpa:restart_worker/0,1</seealso> and - <seealso marker="snmpa#restart_set_worker">snmpa:restart_set_worker/0,1</seealso>, - for restarting the agent worker processes (in case the agent is - multi-threaded).</p> - <p>Own Id: OTP-7369</p> - </item> - - <item> - <p>Add utility function to - <seealso marker="snmp#read_mib">read</seealso> - a compiled mib. </p> - <p>Own Id: OTP-7371</p> - </item> - - </list> - </section> - - <section> - <title>Reported Fixed Bugs and Malfunctions</title> - <!-- - <p>-</p> - --> - <list type="bulleted"> - <item> - <p>[manager] Encryption error when attempting to send - version 3 inform-requests. </p> - <p>Own Id: OTP-7377</p> - <p>Aux Id: Seq 10966</p> - </item> - - </list> - </section> + </section> <!-- 4.18 --> - <section> - <title>Incompatibilities</title> - <p>-</p> - </section> - </section> <!-- 4.11 --> <!-- section> <title>Release notes history</title> diff --git a/lib/snmp/doc/src/notes_history.xml b/lib/snmp/doc/src/notes_history.xml index 934df87866..023717cd7c 100644 --- a/lib/snmp/doc/src/notes_history.xml +++ b/lib/snmp/doc/src/notes_history.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> <header> <copyright> - <year>2004</year><year>2010</year> + <year>2004</year><year>2012</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -33,6 +33,1277 @@ </header> <section> + <title>SNMP Development Toolkit 4.17.1</title> + <p>Version 4.17.1 supports code replacement in runtime from/to + version 4.17, 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <list type="bulleted"> + <item> + <p>When the function FilterMod:accept_recv/2 + returned false the SNMP agent stopped collecting + messages from UDP.</p> + <p>Own Id: OTP-8761</p> + </item> + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.17.1 --> + + + <section> + <title>SNMP Development Toolkit 4.17</title> + <p>Version 4.17 supports code replacement in runtime from/to + version 4.16.2, 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Added very basic support for multiple SNMPv3 + EngineIDs in a single agent. See + <seealso marker="snmpa#send_notification">send_notification/7</seealso>, + <seealso marker="snmpa_mpd#process_packet">process_packet/7</seealso>, + <seealso marker="snmpa_mpd#generate_response_msg">generate_response_msg/6</seealso> or + <seealso marker="snmpa_mpd#generate_msg">generate_msg/6</seealso> + for more info. </p> + + <p>Own Id: OTP-8478</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>The config utility + (<seealso marker="snmp#config">snmp:config/0</seealso>) + generated a default notify.conf + with a bad name for the standard trap entry (was "stadard trap", + but should have been "standard trap"). This has been corrected. </p> + <p>Kenji Rikitake</p> + <p>Own Id: OTP-8433</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.17 --> + + + <section> + <title>SNMP Development Toolkit 4.16.2</title> + <p>Version 4.16.2 supports code replacement in runtime from/to + version 4.16.1, 4.16, 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[compiler] The SMI specifies that a table row OID should be + named: { <tableIdentifier> "1" }. </p> + <p>A new option has been introduced, + <seealso marker="snmpc#compiler_opts">relaxed_row_name_assign_check</seealso>, + that allows for a more liberal numbering scheme</p> + <p>Own Id: OTP-8574</p> + </item> + + <item> + <p>[agent|manager] Changes to make snmp (forward) compatible with + the new version of the crypto application (released in R14). + As of R14, crypto is implemented using NIFs. Also, + the API is more strict. </p> + <p>Own Id: OTP-8594</p> + </item> + + <item> + <p>Auto [agent] Changed default value for the MIB server cache. + GC is now on by default. </p> + <p>Own Id: OTP-8648</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>Encode/decode of Counter64 values larger than + 16#7fffffffffffffff (9223372036854775807) failed. </p> + <p>Own Id: OTP-8563</p> + </item> + + <item> + <p>[compiler] Fails to compile non-contiguous BITS. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-8595</p> + </item> + + <item> + <p>[manager] Raise condition causing the manager server process to + crash. Unregistering an agent while traffic (set/get-operations) + is ongoing could cause a crash in the manager server process + (raise condition). </p> + <p>Own Id: OTP-8646</p> + <p>Aux Id: Seq 11585</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.16.2 --> + + + <section> + <title>SNMP Development Toolkit 4.16.1</title> + <p>Version 4.16.1 supports code replacement in runtime from/to + version 4.16, 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <p>[agent|manager] Entries in the audit trail log can now be + augmented by a sequence number. </p> + <p>This is enabled by the <c>seqno</c> option, which is part of the + <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso> + config option. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">reference manual</seealso> + or the + <seealso marker="snmp_config#configuration_params">Configuring the application</seealso> + chapter of the User's Guide for further info. </p> + + <p>Own Id: OTP-8395</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[manager] Fixed an upgrade/downgrade problem. </p> + <p>Upgrade/downgrade from/to 4.13.5 did not work for the net-if + process. This has now been fixed. </p> + <p>Own Id: OTP-8481</p> + </item> + + <item> + <p>[agent] A minor mnesia related performance improvement. </p> + <p>Own Id: OTP-8480</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.16.1 --> + + + <section> + <title>SNMP Development Toolkit 4.16</title> + <p>Version 4.16 supports code replacement in runtime from/to + version 4.15, 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent|manager] Entries in the audit trail log can now be + augmented by a sequence number. </p> + <p>This is enabled by the <c>seqno</c> option, which is part of the + <seealso marker="snmp_config#audit_trail_log">Audit Trail Log</seealso> + config option. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">reference manual</seealso> + or the + <seealso marker="snmp_config#configuration_params">Configuring the application</seealso> + chapter of the User's Guide for further info. </p> + + <p>Own Id: OTP-8395</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[manager] Registration of agents using the config file, + <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>, + does not work. This has now been corrected. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-8442</p> + </item> + + <item> + <p>The config utility + (<seealso marker="snmp#config">snmp:config/0</seealso>) + generated a default notify.conf + with a bad name for the standard trap entry (was "stadard trap", + but should have been "standard trap"). This has been corrected. </p> + <p>Kenji Rikitake</p> + <p>Own Id: OTP-8433</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.16 --> + + + <section> + <title>SNMP Development Toolkit 4.15</title> + + <p>Version 4.15 supports code replacement in runtime from/to + version 4.14 and 4.13.5.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>The documentation is now built with open source tools + (<em>xsltproc</em> and <em>fop</em>) that exists on most + platforms. One visible change is that the frames are removed.</p> + <p>Own Id: OTP-8249</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] When information from an unknown agent is received, + it was previously delivered to the default user via calls to all + the functions of the callback API depending on the info type + (<c>pdu</c>, <c>trap</c>, <c>report</c> or <c>inform</c>). + The problem was that the <c>TargetName</c> argument was useless + in this case (only an already known agent has a known/valid + <c>TargetName</c>, but the <c>TargetName</c> used in these calls + was generated "on the fly"). </p> + <p>This has now been changed so that when a message is received + from an unknown agent, then only + <seealso marker="snmpm_user#handle_agent">handle_agent</seealso> + (for the default user) is called, but now this call also has a + <c>Type</c> argument, which is + <c>pdu | trap | report | inform</c>, depending on what kind of + message was actually received, thus making it possible for the + user to properly analyze the data received. </p> + <p>To handle this, the + <seealso marker="snmpm_user">snmpm_user</seealso> behaviour has + been updated. </p> + <p>*** POTENTIAL INCOMPATIBILITY ***</p> + <p>Own Id: OTP-8229</p> + <!-- <p>Aux Id: Seq 11312</p> --> + </item> + + </list> + + </section> + + </section> <!-- 4.15 --> + + + <section> + <title>SNMP Development Toolkit 4.14</title> + + <p>Version 4.14 supports code replacement in runtime from/to + version 4.13.5, 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[compiler] Include object- and notification groups in the + compiled mib. + This will make it possible to import groups from other mibs. </p> + <p>Also the SNMPv2-MIB-file has been updated to a more + up-to-date version. </p> + <p>Own Id: OTP-8223</p> + <!-- <p>Aux Id: Seq 11383</p> --> + </item> + + <item> + <p>[manager] Added support for message filtering in the + network interface module provided with the application. + The component that actually make the filter decisions + is the network interface filter module. This module + must implement the + <seealso marker="snmpm_network_interface_filter">network interface filter behaviour</seealso> + for message filtering. + See also the Configuring chapter of + the User's Guide to see how to configure this feature. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the filter options.</p> + <p>Own Id: OTP-8228</p> + <p>Aux Id: Seq 11411</p> + </item> + + <item> + <p>The MIBs delivered as part of the application is now + also available as man pages, section 7. </p> + <p>Own Id: OTP-8237</p> + <!-- <p>Aux Id: Seq 11383</p> --> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] The main agent type header file contained some miss-information + regarding the type of the entrytype field of the me-record, causing + unneccessary confusion.</p> + <p>Own Id: OTP-8116</p> + <p>Aux Id: Seq 11312</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.14 --> + + + <section> + <title>SNMP Development Toolkit 4.13.5</title> + + <p>Version 4.13.5 supports code replacement in runtime from/to + version 4.13.4, 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + + <list type="bulleted"> + <item> + <p>[agent] Improved the cache handling of the mib server. </p> + <p>A number of new functions and config options for the mib server + cache has been added. </p> + <p>See + <seealso marker="snmpa#invalidate_mibs_cache">invalidate_mibs_cache/0,1</seealso>, + <seealso marker="snmpa#enable_mibs_cache">enable_mibs_cache/0,1</seealso>, + <seealso marker="snmpa#disable_mibs_cache">disable_mibs_cache/0,1</seealso>, + <seealso marker="snmpa#gc_mibs_cache">gc_mibs_cache/0,1,2,3</seealso>, + <seealso marker="snmpa#enable_mibs_cache_autogc">enable_mibs_cache_autogc/0,1</seealso>, + <seealso marker="snmpa#disable_mibs_cache_autogc">disable_mibs_cache_autogc/0,1</seealso>, + <seealso marker="snmpa#update_mibs_cache_age">update_mibs_cache_age/1,2</seealso> and + <seealso marker="snmpa#update_mibs_cache_gclimit">update_mibs_cache_gclimit/1,2</seealso> for more info. </p> + <p>See also the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the mib server cache options.</p> + <p>Own Id: OTP-8182</p> + <p>Aux Id: Seq 11383</p> + </item> + + <item> + <p>[agent] A manager could no longer use the SNMPv3 user "initial" + as this was interpretated as the first step of the discovery. </p> + <p>Introduced a new terminating option, <c>trigger_username</c> to + make it possible to configure the username the agent reacts to. + Default is <c>""</c>. </p> + <p>See the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the discovery options.</p> + <p>Own Id: OTP-8120</p> + <p>Aux Id: Seq 11361</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] The main agent type header file contained some miss-information + regarding the type of the entrytype field of the me-record, causing + unneccessary confusion.</p> + <p>Own Id: OTP-8116</p> + <p>Aux Id: Seq 11312</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.5 --> + + + <section> + <title>SNMP Development Toolkit 4.13.4</title> + + <p>Version 4.13.4 supports code replacement in runtime from/to + version 4.13.3, 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Originating discovery problems. </p> + <p>Invalid state variable update during second stage of + discovery causes master agent crash. </p> + <p>Also the net_if process failed to activate socket + ({active, once}) after first discovery response was sent. </p> + <p>Own Id: OTP-8044</p> + <p>Aux Id: Seq 11295</p> + </item> + + <item> + <p>[agent] Terminating discovery problem. </p> + <p>The reply to the second stage request should include a + varbind with <c>usmStatsNotInTimeWindows</c>.</p> + <p>Own Id: OTP-8062</p> + <p>Aux Id: Seq 11318</p> + </item> + + <item> + <p>[agent] Originating discovery improvement. </p> + <p>Added the ExtraInfo argument to the + <seealso marker="snmpa#discovery">discovery</seealso> function. + This argument will be passed on to the stage1_finish callback + function. Also, the + <seealso marker="snmpa#discovery">discovery</seealso> function + will now always return <c>{ok, ManagerEngineID}</c> on successful + discovery. </p> + <p>The <seealso marker="snmpa_discovery_handler">discovery handler</seealso> + behaviour updated accordingly. </p> + <p>Own Id: OTP-8098</p> + <p>Aux Id: Seq 11346</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.4 --> + + + <section> + <title>SNMP Development Toolkit 4.13.3</title> + + <p>Version 4.13.3 supports code replacement in runtime from/to + version 4.13.2, 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] A request for an oid of type BITS was actually + returned as OCTET STRING. </p> + <p>Values of type BITS are encoded as OCTET STRING, + which makes it impossible for the decoder to know that + they should really be of type BITS. + Instead, this has to be done higher up in the stack, where + there is knowledge of the MIB (assuming that the mib has + been loaded, there is info about the type of the mibentry). </p> + <p>This problem has now been fixed, but requires that the MIB + defining this mib-entry is loaded! </p> + <p>The utility function + <seealso marker="snmpm#oid_to_type">oid_to_type</seealso> + has been added, for debug purpose. </p> + <p>The utility function(s) + <seealso marker="snmp#octet_string_to_bits">octet_string_to_bits</seealso> + and + <seealso marker="snmp#bits_to_octet_string">bits_to_octet_string</seealso> + has also been added. These can be used if the user prefers to + handle the conversion on their own. </p> + <p>Own Id: OTP-8015</p> + <p>Aux Id: Seq 11285</p> + </item> + + <item> + <p>[agent] Fixed some issues with the discovery handling. </p> + <p>Changed the API of the + <seealso marker="snmpa#discovery">discovery</seealso> + function to solve some + of these problems. </p> + <p>Introduced various options for controlling the discovery + process. See the + <seealso marker="snmp_app#configuration_params">configuration</seealso> + chapter for more info about the discovery options.</p> + <p>Own Id: OTP-8020</p> + <p>Aux Id: Seq 11295</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.3 --> + + + <section> + <title>SNMP Development Toolkit 4.13.2</title> + + <p>Version 4.13.2 supports code replacement in runtime from/to + version 4.13.1 and 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Failure during downed user cleanup. + As part of the cleanup after a crashed user, + the manager attempts to unregister the agents + registered by this user. This however failed, + causing a server crash. </p> + <p>Own Id: OTP-7961</p> + <p>Aux Id: Seq 11275</p> + </item> + + <item> + <p>[manager] Incorrectly documented value type for + IpAddress (ip). The value type for IpAddress is + documented as ip but is actually ia. The value type + ip has been added. The old (not documented) value + type ia still works. </p> + <p>Own Id: OTP-7977</p> + <p>Aux Id: Seq 11279</p> + </item> + + <item> + <p>[manager] EngineId lookup fails when using version-3. </p> + <p>Own Id: OTP-7983</p> + <p>Aux Id: Seq 11275</p> + </item> + + <item> + <p>[agent] As of version 4.13 the possible return values + of the function + <seealso marker="snmpa_mpd#process_packet">snmpa_mpd:process_packet/4</seealso> + changed, but this was not documented. </p> + <p>Own Id: OTP-7989</p> + <p>Aux Id: Seq 11275</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.2 --> + + <section> + <title>SNMP Development Toolkit 4.13.1</title> + + <p>Version 4.13.1 supports code replacement in runtime from/to + version 4.13.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + + <!-- + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Registration of users had some issues. </p> + <p>Not all of the registration functions where actually exported + (<seealso marker="snmpm#register_user">register_user/4</seealso> + and + <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>). + This has now been fixed. </p> + <p>Also, the registration did not succeed unless + user implemented the *new* behaviour. This has now + also been fixed (registration succeeds if the user + implements either the new (i.e. updated + <seealso marker="snmpm_user">snmpm_user</seealso>) + or the old user behaviour (<c>snmpm_user_old</c>)). </p> + <p>Own Id: OTP-7902</p> + <p>Aux Id: Seq 11240</p> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13.1 --> + + <section> + <title>SNMP Development Toolkit 4.13</title> +<!-- + <p>Version 4.13 supports code replacement in runtime from/to + version 4.12.1.</p> +--> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Support for the discovery process. </p> + <p>The agent can both initiate discovery itself (see the + <seealso marker="snmp_agent_funct_descr#discovery">discovery</seealso> chapter + for more info) and respond to discovery initiated by a manager.</p> + <p>Own Id: OTP-7571</p> + <p>Aux Id: Seq 11053</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Unnecessary use of math:pow/2 could cause problems + on systems without floating point support. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7735</p> + <!-- <p>Aux Id: Seq 10966</p> --> + </item> + + <item> + <p>[manager] A major flaw was discovered with the agent handling. </p> + <p>First, <c>TargetName</c> was never used as intended, as a unique + identifier for the target (agent in this case). </p> + <p>Second, <c>TargetName</c> had a <em>default value</em>, which meant + that several agents could have the same <c>TargetName</c>, causing + unpredictable behaviour in the manager. </p> + <p>Third, <c>EngineID</c> was not a mandatory config option and had + furthermore also a <em>default value</em>. </p> + + <p>These problems has been solved in the following way: </p> + <p>First, a new set of api functions has been introduced (and documented): + <seealso marker="snmpm#register_user">register_user/4</seealso>, + <seealso marker="snmpm#register_user_monitor">register_user_monitor/4</seealso>, + <seealso marker="snmpm#register_agent">register_agent/3</seealso>, + <seealso marker="snmpm#unregister_agent">unregister_agent/2</seealso>, + <seealso marker="snmpm#agent_info">agent_info/2</seealso>, + <seealso marker="snmpm#update_agent_info">update_agent_info/4</seealso>, + <seealso marker="snmpm#sync_get">sync_get/3,4,5,6</seealso>, + <seealso marker="snmpm#async_get">async_get/3,4,5,6</seealso>, + <seealso marker="snmpm#sync_get_next">sync_get_next/3,4,5,6</seealso>, + <seealso marker="snmpm#async_get_next">async_get_next/3,4,5,6</seealso>, + <seealso marker="snmpm#sync_set">sync_set/3,4,5,6</seealso>, + <seealso marker="snmpm#async_set">async_set/3,4,5,6</seealso>, + <seealso marker="snmpm#sync_get_bulk">sync_get_bulk/5,6,7,8</seealso> and + <seealso marker="snmpm#async_get_bulk">async_get_bulk/5,6,7,8</seealso> + that all use <c>TargetName</c> (and not, as previously, <c>Addr</c> + and <c>Port</c>) to identify the agent (also the return value of + <seealso marker="snmpm#which_agents">which_agents</seealso> has + been changed). </p> + <p>Second, for backward compatibility, the old functions still + exist, but are no longer documented and are now wrappers for the + new functions, including erroneous default value for EngineID and + all. The TargetName is however generated from the provided + <c>Addr</c>, <c>Port</c> and <c>Version</c> config options. </p> + <p>Third, the behaviour of the + <seealso marker="snmpm_user">SNMP manager user</seealso> has + been changed to reflect this, i.e. + <seealso marker="snmpm_user#handle_pdu">handle_pdu/4</seealso>, + <seealso marker="snmpm_user#handle_trap">handle_trap/3</seealso>, + <seealso marker="snmpm_user#handle_inform">handle_inform/3</seealso>, + <seealso marker="snmpm_user#handle_report">handle_report/3</seealso> + and the return-value of + <seealso marker="snmpm_user#handle_agent">handle_agent/4</seealso>. + The old (non-documented) callback-functions (using Addr and Port) + will still be called if the agent was registered using the old + registration functions. </p> + + <p>Own Id: OTP-7836</p> + <!-- <p>Aux Id: Seq 10966</p> --> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.13 --> + + <section> + <title>SNMP Development Toolkit 4.12.2</title> + <p>Version 4.12.2 supports code replacement in runtime from/to + version 4.12.1, 4.12, 4.11.2, 4.11.1 and 4.11.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <item> + <p>[agent] Improvement of the inform reporting. + It was previously not certain how many acks an + application received, 0, 1 or 2. This has now been + fixed, so that only 1 (one) ack is issued. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7525</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Bad session cache (usm+camv-info) invalidation + could cause user crash, through call(s) to (a number of) + MIB API function(s) (undefined function). </p> + <p>Own Id: OTP-7868</p> + <!-- <p>Aux Id: Seq 11124</p> --> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.12.2 --> + + <section> + <title>SNMP Development Toolkit 4.12.1</title> + <p>Version 4.12.1 supports code replacement in runtime from/to + version 4.12, 4.11.2, 4.11.1 and 4.11.</p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <item> + <p>[agent] Improvement of the inform reporting. + It was previously not certain how many acks an + application received, 0, 1 or 2. This has now been + fixed, so that only 1 (one) ack is issued. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7525</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>Logging of messages with the GetBulk-request PDU + incorrectly produced an erroneous entry in the + log: "An error occurred". </p> + <p>The reason for this was that the PDU-fields + error_status and error_index is re-used for + Non-repeaters and Max-repetitions for + GetBulk-request PDUs, but this was not handled + by the logging code. </p> + <p>Own Id: OTP-7695</p> + <p>Aux Id: Seq 11124</p> + </item> + + <item> + <p>[agent] An attempt to set the row status to active for an + notReady table row, could result in an "inconsistentValue" + error. </p> + <p>The same problem existed when attempting to set row status + to notInService for a row in notReady. </p> + <p>Serge Aleynikov</p> + <p>Own Id: OTP-7698</p> + <!-- <p>Aux Id: Seq 10966</p> --> + </item> + + </list> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.12.1 --> + + <section> + <title>SNMP Development Toolkit 4.12</title> + <p>Version 4.12 supports code replacement in runtime from/to + version 4.11.2, 4.11.1 and 4.11.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] A simple lookup cache has been added to improve + the mib server lookup performance. </p> + <p>This can be disabled with the mib_server + <seealso marker="snmp_app">cache</seealso> option. </p> + <p>Own Id: OTP-7346</p> + </item> + + <item> + <p>[agent] Improvement of the inform reporting. + It was previously not certain how many acks an + application received, 0, 1 or 2. This has now been + fixed, so that only 1 (one) ack is issued. </p> + <p>Per Hedeland</p> + <p>Own Id: OTP-7525</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <p>[manager] Encryption error when attempting to send + version 3 inform-requests. </p> + <p>Own Id: OTP-7432</p> + <p>Aux Id: Seq 10966</p> + </item> + + </list> + --> + + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.12 --> + + <section> + <title>SNMP Development Toolkit 4.11.2</title> + <p>Version 4.11.2 supports code replacement in runtime from/to + version 4.11.1 and 4.11. </p> + + <section> + <title>Improvements and new features</title> + <p>-</p> + <!-- + <list type="bulleted"> + <item> + <p>Added utility functions for transforming DateAndTime + as [int()] to strings; + <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> + and + <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> + <p>Also added new validation function + <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> + <p>Own Id: OTP-7412</p> + <p>Aux Id: Seq 10987</p> + </item> + </list> + --> + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Erroneous engine-id check when receiving version 3 + informs. </p> + <p>Own Id: OTP-7570</p> + <p>Aux Id: Seq 11060</p> + </item> + + <item> + <p>Receiving an snmp message with a very large version + number could cause the erlang node to run out of + memory and consequently crash. </p> + <p>The standard specifies the snmp version as an + (unlimited) INTEGER, but today only + 0 (version 1), 1 (version 2) and 3 (version 3) is + actually used. So, when decoding a message, a limit + has been put on the snmp version integer in order + to not allow this kind of a problem. </p> + <p>Own Id: OTP-7575</p> + <p>Aux Id: Seq 11064</p> + </item> + + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.11.2 --> + + + <section> + <title>SNMP Development Toolkit 4.11.1</title> + <p>Version 4.11.1 supports code replacement in runtime from/to + version 4.11.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[compiler] The MIB compiler did not retrieve the REFERENCE part + of a SNMP MIB definition. </p> + <p>This problem has been partly solved. For SNMP tables, + the assocList field of the tables mib-entry record now contains + this info (as <c>{reference, string()}</c>), <em>if</em> the + MIB was compiled with the compiler option <em>+reference</em>. </p> + <p>This solution is temporary, until such time as a permanent + solution (and probably not backward compatible) is devised, which + retrieves and stores all REFERENCE part(s) of a MIB. </p> + <p>See the + <seealso marker="snmpc#compiler_opts">compiler options</seealso> + for more info. </p> + + <p>Serge Aleynikov</p> + <p>Own Id: OTP-7426</p> + </item> + + <item> + <p>Added utility functions for transforming DateAndTime + as [int()] to strings; + <seealso marker="snmp#dat2s">date_and_time_to_string/2</seealso> + and + <seealso marker="snmp#dat2s2">date_and_time_to_string2/1</seealso>. </p> + <p>Also added new validation function + <seealso marker="snmp#vdat">validate_date_and_time/2</seealso>. </p> + <p>Own Id: OTP-7412</p> + <p>Aux Id: Seq 10987</p> + </item> + + </list> + + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Encryption error when attempting to send + version 3 inform-requests. </p> + <p>Own Id: OTP-7432</p> + <p>Aux Id: Seq 10966</p> + </item> + + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.11.1 --> + + <section> + <title>SNMP Development Toolkit 4.11</title> + <p>Version 4.11 supports code replacement in runtime from/to + version 4.10.3, 4.10.2, 4.10.1 and 4.10.</p> + + <section> + <title>Improvements and new features</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[agent] Performance improvements in the case when an SNMP + manager performs an snmpwalk. </p> + <p>Martin Björklund</p> + <p>Own Id: OTP-7201</p> + </item> + + <item> + <p>The API for sending inform(s) has been improved. Also + the documentation has been corrected and updated. See + <seealso marker="snmpa#send_notification">snmpa:send_notification</seealso> and + <seealso marker="snmpa_notification_delivery_info_receiver">snmpa_notification_delivery_info_receiver</seealso> + for more info.</p> + <p>Own Id: OTP-7287</p> + <p>Aux Id: Seq 10926</p> + </item> + + <item> + <p>[agent] Performance of the internal database (local-db) + has been improved.</p> + <p>Own Id: OTP-7319</p> + <p>Aux Id: Seq 10942</p> + </item> + + <item> + <p>[agent] Added utility functions, + <seealso marker="snmpa#restart_worker">snmpa:restart_worker/0,1</seealso> and + <seealso marker="snmpa#restart_set_worker">snmpa:restart_set_worker/0,1</seealso>, + for restarting the agent worker processes (in case the agent is + multi-threaded).</p> + <p>Own Id: OTP-7369</p> + </item> + + <item> + <p>Add utility function to + <seealso marker="snmp#read_mib">read</seealso> + a compiled mib. </p> + <p>Own Id: OTP-7371</p> + </item> + + </list> + </section> + + <section> + <title>Reported Fixed Bugs and Malfunctions</title> + <!-- + <p>-</p> + --> + <list type="bulleted"> + <item> + <p>[manager] Encryption error when attempting to send + version 3 inform-requests. </p> + <p>Own Id: OTP-7377</p> + <p>Aux Id: Seq 10966</p> + </item> + + </list> + </section> + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + </section> <!-- 4.11 --> + + + <section> <title>SNMP Development Toolkit 4.10.3</title> <p>Version 4.10.3 supports code replacement in runtime from/to version 4.10.2, 4.10.1 and 4.10.</p> diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml index 694e619da1..f6abe783b3 100644 --- a/lib/snmp/doc/src/snmp_app.xml +++ b/lib/snmp/doc/src/snmp_app.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE appref SYSTEM "appref.dtd"> <appref> <header> <copyright> - <year>1997</year><year>2010</year> + <year>1997</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -78,7 +78,15 @@ ]. </pre> - <!-- The info below is also found in the snmp_config.xml file --> + + <!-- + ******************************************************** + + The info below is also found in the snmp_config.xml file + + ******************************************************** + --> + <p>Each snmp component has its own set of configuration parameters, even though some of the types are common to both components. </p> @@ -92,6 +100,7 @@ {agent_verbosity, verbosity()} | {discovery, agent_discovery()} | {versions, versions()} | + {gb_max_vbs, gb_max_vbs()} | {priority, priority()} | {multi_threaded, multi_threaded()} | {db_dir, db_dir()} | @@ -122,8 +131,10 @@ {def_user_data, def_user_data()} </pre> + <marker id="agent_opts_and_types"></marker> <p>Agent specific config options and types:</p> <taglist> + <marker id="agent_type"></marker> <tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag> <item> <p>If <c>master</c>, one master agent is @@ -131,6 +142,7 @@ <p>Default is <c>master</c>.</p> </item> + <marker id="agent_disco"></marker> <tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag> <item> <p><c>agent_discovery_opt() = @@ -143,6 +155,7 @@ <p>For defaults see the options in <c>agent_discovery_opt()</c>.</p> </item> + <marker id="agent_term_disco_opts"></marker> <tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag> <item> <p><c>agent_terminating_discovery_opt() = @@ -160,6 +173,7 @@ </list> </item> + <marker id="agent_orig_disco_opts"></marker> <tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag> <item> <p><c>agent_originating_discovery_opt() = @@ -173,6 +187,7 @@ </list> </item> + <marker id="agent_mt"></marker> <tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c>, the agent is multi-threaded, with one @@ -180,11 +195,21 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="agent_data_dir"></marker> <tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP agent internal db files are stored.</p> </item> + <marker id="agent_gb_max_vbs"></marker> + <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag> + <item> + <p>Defines the maximum number of varbinds allowed + in a Get-BULK response.</p> + <p>Default is <c>1000</c>.</p> + </item> + + <marker id="agent_local_db"></marker> <tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag> <item> <p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p> @@ -192,6 +217,7 @@ <p>For defaults see the options in <c>local_db_opt()</c>.</p> </item> + <marker id="agent_ldb_repair"></marker> <tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag> <item> <p>When starting snmpa_local_db it always tries to open an @@ -202,6 +228,7 @@ <p>Default is <c>true</c>.</p> </item> + <marker id="agent_ldb_auto_save"></marker> <tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag> <item> <p>The auto save interval. The table is flushed to disk @@ -209,6 +236,7 @@ <p>Default is <c>5000</c>.</p> </item> + <marker id="agent_net_if"></marker> <tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag> <item> <p><c>agent_net_if_opt() = {module, agent_net_if_module()} | {verbosity, verbosity()} | {options, agent_net_if_options()}</c></p> @@ -217,6 +245,7 @@ <p>For defaults see the options in <c>agent_net_if_opt()</c>.</p> </item> + <marker id="agent_ni_module"></marker> <tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface part for the @@ -225,6 +254,7 @@ <p>Default is <c>snmpa_net_if</c>.</p> </item> + <marker id="agent_ni_opts"></marker> <tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag> <item> <p><c>agent_net_if_option() = {bind_to, bind_to()} | @@ -239,12 +269,14 @@ <p>For defaults see the options in <c>agent_net_if_option()</c>.</p> </item> + <marker id="agent_ni_req_limit"></marker> <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag> <item> <p>Max number of simultaneous requests handled by the agent.</p> <p>Default is <c>infinity</c>.</p> </item> + <marker id="agent_ni_filter_opts"></marker> <tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag> <item> <p><c>agent_net_if_filter_option() = {module, agent_net_if_filter_module()}</c></p> @@ -255,6 +287,7 @@ <c>agent_net_if_filter_option()</c>.</p> </item> + <marker id="agent_ni_filter_module"></marker> <tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface filter part for the @@ -263,6 +296,7 @@ <p>Default is <c>snmpa_net_if_filter</c>.</p> </item> + <marker id="agent_mibs"></marker> <tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag> <item> <p>Specifies a list of MIBs (including path) that defines which MIBs @@ -277,6 +311,7 @@ <p>Default is <c>[]</c>.</p> </item> + <marker id="agent_mib_storage"></marker> <tag><c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag> <item> <p>Specifies how info retrieved from the mibs will be stored.</p> @@ -302,6 +337,7 @@ mnesia/dets table already exist.</p> </item> + <marker id="agent_mib_server"></marker> <tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag> <item> <p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()}</c></p> @@ -309,6 +345,7 @@ <p>For defaults see the options in <c>mib_server_opt()</c>.</p> </item> + <marker id="agent_ms_meo"></marker> <tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag> <item> <p>If this value is false, then when loading a mib each mib- @@ -318,6 +355,7 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="agent_ms_teo"></marker> <tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag> <item> <p>If this value is false, then when loading a mib each trap @@ -327,6 +365,7 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="agent_ms_cache"></marker> <tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag> <item> <p>Shall the agent utilize the mib server lookup cache or not.</p> @@ -334,6 +373,7 @@ default values apply).</p> </item> + <marker id="agent_ms_cache_opts"></marker> <tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag> <item> <p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p> @@ -341,6 +381,7 @@ <p>For defaults see the options in <c>mibs_cache_opt()</c>.</p> </item> + <marker id="agent_ms_cache_autogc"></marker> <tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag> <item> <p>Defines if the mib server shall perform cache gc automatically or @@ -349,6 +390,7 @@ <p>Default is <c>true</c>.</p> </item> + <marker id="agent_ms_cache_age"></marker> <tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag> <item> <p>Defines how old the entries in the cache will be allowed before @@ -358,6 +400,7 @@ <p>Default is <c>10 timutes</c>.</p> </item> + <marker id="agent_ms_cache_gclimit"></marker> <tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag> <item> <p>When performing a GC, this is the max number of cache entries @@ -368,6 +411,7 @@ <p>Default is <c>100</c>.</p> </item> + <marker id="agent_error_report_mod"></marker> <tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag> <item> <p>Defines an error report module, implementing the @@ -377,6 +421,7 @@ <p>Default is <c>snmpa_error_logger</c>.</p> </item> + <marker id="agent_symbolic_store"></marker> <tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag> <item> <p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p> @@ -384,23 +429,29 @@ <p>For defaults see the options in <c>symbolic_store_opt()</c>.</p> </item> + <marker id="agent_target_cache"></marker> <tag><c>target_cache() = [target_cache_opt()]</c></tag> <item> <p><c>target_cache_opt() = {verbosity, verbosity()}</c></p> <p>Defines options specific for the SNMP agent target cache. </p> <p>For defaults see the options in <c>target_cache_opt()</c>.</p> </item> + + <marker id="agent_config"></marker> <tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag> <item> <p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p> <p>Defines specific config related options for the SNMP agent. </p> <p>For defaults see the options in <c>agent_config_opt()</c>.</p> </item> + + <marker id="agent_config_dir"></marker> <tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP agent configuration files are stored.</p> </item> + <marker id="agent_force_load"></marker> <tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c> the configuration files are re-read @@ -412,14 +463,18 @@ </item> </taglist> + <marker id="manager_opts_and_types"></marker> <p>Manager specific config options and types:</p> <taglist> + <marker id="manager_server"></marker> <tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag> <item> <p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p> <p>Specifies the options for the manager server process.</p> <p>Default is <c>silence</c>.</p> </item> + + <marker id="manager_server_timeout"></marker> <tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag> <item> <p>Asynchroneous request cleanup time. For every requests, @@ -440,6 +495,7 @@ <p>Default is <c>30000</c>.</p> </item> + <marker id="manager_config"></marker> <tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag> <item> <p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p> @@ -447,16 +503,19 @@ <p>For defaults see the options in <c>manager_config_opt()</c>.</p> </item> + <marker id="manager_config_dir"></marker> <tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP manager configuration files are stored.</p> </item> + <marker id="manager_config_db_dir"></marker> <tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP manager store persistent data.</p> </item> + <marker id="manager_config_repair"></marker> <tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag> <item> <p>Defines the repair option for the persistent database (if @@ -464,6 +523,7 @@ <p>Default is <c>true</c>.</p> </item> + <marker id="manager_config_auto_save"></marker> <tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag> <item> <p>The auto save interval. The table is flushed to disk @@ -471,6 +531,7 @@ <p>Default is <c>5000</c>.</p> </item> + <marker id="manager_irb"></marker> <tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag> <item> <p>This option defines how the manager will handle the sending of @@ -500,6 +561,7 @@ <p>Default is <c>auto</c>.</p> </item> + <marker id="manager_mibs"></marker> <tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag> <item> <p>Specifies a list of MIBs (including path) and defines which MIBs @@ -507,6 +569,7 @@ <p>Default is <c>[]</c>.</p> </item> + <marker id="manager_net_if"></marker> <tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag> <item> <p><c>manager_net_if_opt() = {module, manager_net_if_module()} | @@ -517,6 +580,7 @@ <p>For defaults see the options in <c>manager_net_if_opt()</c>.</p> </item> + <marker id="manager_ni_opts"></marker> <tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag> <item> <p><c>manager_net_if_option() = {bind_to, bind_to()} | @@ -530,6 +594,7 @@ <p>For defaults see the options in <c>manager_net_if_option()</c>.</p> </item> + <marker id="manager_ni_module"></marker> <tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface part for the @@ -538,6 +603,7 @@ <p>Default is <c>snmpm_net_if</c>.</p> </item> + <marker id="manager_ni_filter_opts"></marker> <tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag> <item> <p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p> @@ -548,6 +614,7 @@ <c>manager_net_if_filter_option()</c>.</p> </item> + <marker id="manager_ni_filter_module"></marker> <tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface filter part for the @@ -556,6 +623,7 @@ <p>Default is <c>snmpm_net_if_filter</c>.</p> </item> + <marker id="manager_def_user_module"></marker> <tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag> <item> <p>The module implementing the default user. See the @@ -563,6 +631,7 @@ <p>Default is <c>snmpm_user_default</c>.</p> </item> + <marker id="manager_def_user_data"></marker> <tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag> <item> <p>Data for the default user. Passed to the user module when @@ -571,8 +640,10 @@ </item> </taglist> + <marker id="common_types"></marker> <p>Common config types:</p> <taglist> + <marker id="restart_type"></marker> <tag><c>restart_type() = permanent | transient | temporary</c></tag> <item> <p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso> @@ -580,6 +651,8 @@ <p>Default is <c>permanent</c> for the agent and <c>transient</c> for the manager.</p> </item> + + <marker id="db_init_error"></marker> <tag><c>db_init_error() = terminate | create</c></tag> <item> <p>Defines what to do if the agent or manager is unable to open an @@ -588,23 +661,31 @@ agent/manager will remove the faulty file(s) and create new ones.</p> <p>Default is <c>terminate</c>.</p> </item> + + <marker id="prio"></marker> <tag><c><![CDATA[priority() = atom() <optional>]]></c></tag> <item> <p>Defines the Erlang priority for all SNMP processes.</p> <p>Default is <c>normal</c>.</p> </item> + + <marker id="versions"></marker> <tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag> <item> <p><c>version() = v1 | v2 | v3</c></p> <p>Which SNMP versions shall be accepted/used.</p> <p>Default is <c>[v1,v2,v3]</c>.</p> </item> + + <marker id="verbosity"></marker> <tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag> <item> <p>Verbosity for a SNMP process. This specifies now much debug info is printed.</p> <p>Default is <c>silence</c>.</p> </item> + + <marker id="bind_to"></marker> <tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c>, net_if binds to the IP address. @@ -612,6 +693,8 @@ where it is running. </p> <p>Default is <c>false</c>.</p> </item> + + <marker id="no_reuse"></marker> <tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c>, net_if does not specify that the IP @@ -619,22 +702,30 @@ the address is set to reusable. </p> <p>Default is <c>false</c>.</p> </item> + + <marker id="recbuf"></marker> <tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag> <item> <p>Receive buffer size. </p> <p>Default value is defined by <c>gen_udp</c>.</p> </item> + + <marker id="sndbuf"></marker> <tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag> <item> <p>Send buffer size. </p> <p>Default value is defined by <c>gen_udp</c>.</p> </item> + + <marker id="note_store"></marker> <tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag> <item> <p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p> <p>Specifies the start-up verbosity for the SNMP note store.</p> <p>For defaults see the options in <c>note_store_opt()</c>.</p> </item> + + <marker id="ns_timeout"></marker> <tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag> <item> <p>Note cleanup time. When storing a note in the note store, @@ -643,9 +734,9 @@ milli-seconds.</p> <p>Default is <c>30000</c>.</p> - <marker id="audit_trail_log"></marker> </item> + <marker id="audit_trail_log"></marker> <tag><c><![CDATA[audit_trail_log() = [audit_trail_log_opt()] <optional>]]></c></tag> <item> <p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p> @@ -655,6 +746,8 @@ <c>size</c> options are mandatory.</p> <p>If not present, audit trail logging is not used.</p> </item> + + <marker id="atl_type"></marker> <tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag> <item> <p>Specifies what type of an audit trail log should be used. @@ -675,12 +768,16 @@ </list> <p>Default is <c>read_write</c>.</p> </item> + + <marker id="atl_dir"></marker> <tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag> <item> <p>Specifies where the audit trail log should be stored.</p> <p>If <c>audit_trail_log</c> specifies that logging should take place, this parameter <em>must</em> be defined.</p> </item> + + <marker id="atl_size"></marker> <tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag> <item> <p>Specifies the size of the audit @@ -688,6 +785,8 @@ <p>If <c>audit_trail_log</c> specifies that logging should take place, this parameter <em>must</em> be defined.</p> </item> + + <marker id="atl_repair"></marker> <tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag> <item> <p>Specifies if and how the audit trail log shall be repaired @@ -699,6 +798,8 @@ analysis.</p> <p>Default is <c>true</c>.</p> </item> + + <marker id="atl_seqno"></marker> <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag> <item> <p>Specifies if the audit trail log entries will be (sequence) diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml index fc8562b638..0a49b7a62e 100644 --- a/lib/snmp/doc/src/snmp_config.xml +++ b/lib/snmp/doc/src/snmp_config.xml @@ -40,6 +40,7 @@ <item>starting the application (agent and/or manager)</item> <item>debugging the application (agent and/or manager)</item> </list> + <p>Refer also to the chapter(s) <seealso marker="snmp_agent_config_files">Definition of Agent Configuration Files</seealso> and <seealso marker="snmp_manager_config_files">Definition of Manager Configuration Files</seealso> which contains more detailed information @@ -73,7 +74,14 @@ </item> </list> - <!-- The info below is also found in the snmp_app.xml file --> + + <!-- + ***************************************************** + + The info below is also found in the snmp_app.xml file + + ***************************************************** + --> <p>The agent and manager uses (application) configuration parameters to find out where these directories are located. The parameters should be @@ -87,6 +95,7 @@ {agent_verbosity, verbosity()} | {versions, versions()} | {discovery, agent_discovery()} | + {gb_max_vbs, gb_max_vbs()} | {priority, priority()} | {multi_threaded, multi_threaded()} | {db_dir, db_dir()} | @@ -117,8 +126,10 @@ {def_user_data, def_user_data()} </pre> + <marker id="agent_opts_and_types"></marker> <p>Agent specific config options and types:</p> <taglist> + <marker id="agent_type"></marker> <tag><c><![CDATA[agent_type() = master | sub <optional>]]></c></tag> <item> <p>If <c>master</c>, one master agent is @@ -126,6 +137,7 @@ <p>Default is <c>master</c>.</p> </item> + <marker id="agent_disco"></marker> <tag><c><![CDATA[agent_discovery() = [agent_discovery_opt()] <optional>]]></c></tag> <item> <p><c>agent_discovery_opt() = @@ -138,6 +150,7 @@ <p>For defaults see the options in <c>agent_discovery_opt()</c>.</p> </item> + <marker id="agent_term_disco_opts"></marker> <tag><c><![CDATA[agent_terminating_discovery_opts() = [agent_terminating_discovery_opt()] <optional>]]></c></tag> <item> <p><c>agent_terminating_discovery_opt() = @@ -155,6 +168,7 @@ </list> </item> + <marker id="agent_orig_disco_opts"></marker> <tag><c><![CDATA[agent_originating_discovery_opts() = [agent_originating_discovery_opt()] <optional>]]></c></tag> <item> <p><c>agent_originating_discovery_opt() = @@ -168,6 +182,7 @@ </list> </item> + <marker id="agent_mt"></marker> <tag><c><![CDATA[multi_threaded() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c>, the agent is multi-threaded, with one @@ -175,11 +190,21 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="agent_data_dir"></marker> <tag><c><![CDATA[db_dir() = string() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP agent internal db files are stored.</p> </item> + <marker id="agent_gb_max_vbs"></marker> + <tag><c><![CDATA[gb_max_vbs() = pos_integer() | infinity <optional>]]></c></tag> + <item> + <p>Defines the maximum number of varbinds allowed + in a Get-BULK response.</p> + <p>Default is <c>1000</c>.</p> + </item> + + <marker id="agent_local_db"></marker> <tag><c><![CDATA[local_db() = [local_db_opt()] <optional>]]></c></tag> <item> <p><c>local_db_opt() = {repair, agent_repair()} | {auto_save, agent_auto_save()} | {verbosity, verbosity()}</c></p> @@ -187,6 +212,7 @@ <p>For defaults see the options in <c>local_db_opt()</c>.</p> </item> + <marker id="agent_ldb_repair"></marker> <tag><c><![CDATA[agent_repair() = false | true | force <optional>]]></c></tag> <item> <p>When starting snmpa_local_db it always tries to open an @@ -197,6 +223,7 @@ <p>Default is <c>true</c>.</p> </item> + <marker id="agent_ldb_auto_save"></marker> <tag><c><![CDATA[agent_auto_save() = integer() | infinity <optional>]]></c></tag> <item> <p>The auto save interval. The table is flushed to disk @@ -204,6 +231,7 @@ <p>Default is <c>5000</c>.</p> </item> + <marker id="agent_net_if"></marker> <tag><c><![CDATA[agent_net_if() = [agent_net_if_opt()] <optional>]]></c></tag> <item> <p><c>agent_net_if_option() = {module, agent_net_if_module()} | @@ -214,6 +242,7 @@ <p>For defaults see the options in <c>agent_net_if_opt()</c>.</p> </item> + <marker id="agent_ni_module"></marker> <tag><c><![CDATA[agent_net_if_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface part for the @@ -222,6 +251,7 @@ <p>Default is <c>snmpa_net_if</c>.</p> </item> + <marker id="agent_ni_opts"></marker> <tag><c><![CDATA[agent_net_if_options() = [agent_net_if_option()] <optional>]]></c></tag> <item> <p><c>agent_net_if_option() = {bind_to, bind_to()} | @@ -236,6 +266,14 @@ <p>For defaults see the options in <c>agent_net_if_option()</c>.</p> </item> + <marker id="agent_ni_req_limit"></marker> + <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag> + <item> + <p>Max number of simultaneous requests handled by the agent.</p> + <p>Default is <c>infinity</c>.</p> + </item> + + <marker id="agent_ni_filter_opts"></marker> <tag><c><![CDATA[agent_net_if_filter_options() = [agent_net_if_filter_option()] <optional>]]></c></tag> <item> <p><c><![CDATA[agent_net_if_filter_option() = {module, agent_net_if_filter_module()}]]></c></p> @@ -245,6 +283,7 @@ <p>For defaults see the options in <c>agent_net_if_filter_option()</c>.</p> </item> + <marker id="agent_ni_filter_module"></marker> <tag><c><![CDATA[agent_net_if_filter_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface filter part for the @@ -254,12 +293,7 @@ <p>Default is <c>snmpa_net_if_filter</c>.</p> </item> - <tag><c><![CDATA[req_limit() = integer() | infinity <optional>]]></c></tag> - <item> - <p>Max number of simultaneous requests handled by the agent.</p> - <p>Default is <c>infinity</c>.</p> - </item> - + <marker id="agent_mibs"></marker> <tag><c><![CDATA[agent_mibs() = [string()] <optional>]]></c></tag> <item> <p>Specifies a list of MIBs (including path) that defines which MIBs @@ -274,6 +308,7 @@ <p>Default is <c>[]</c>.</p> </item> + <marker id="agent_mib_storage"></marker> <tag><c><![CDATA[mib_storage() = ets | {ets, Dir} | {ets, Dir, Action} | dets | {dets, Dir} | {dets, Dir, Action} | mnesia | {mnesia, Nodes} | {mnesia, Nodes, Action} <optional>]]></c></tag> <item> <p>Specifies how info retrieved from the mibs will be stored.</p> @@ -299,6 +334,7 @@ mnesia/dets table already exist.</p> </item> + <marker id="agent_mib_server"></marker> <tag><c><![CDATA[mib_server() = [mib_server_opt()] <optional>]]></c></tag> <item> <p><c>mib_server_opt() = {mibentry_override, mibentry_override()} | {trapentry_override, trapentry_override()} | {verbosity, verbosity()} | {cache, mibs_cache()}</c></p> @@ -306,6 +342,7 @@ <p>For defaults see the options in <c>mib_server_opt()</c>.</p> </item> + <marker id="agent_ms_meo"></marker> <tag><c><![CDATA[mibentry_override() = bool() <optional>]]></c></tag> <item> <p>If this value is false, then when loading a mib each mib- @@ -315,6 +352,7 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="agent_ms_teo"></marker> <tag><c><![CDATA[trapentry_override() = bool() <optional>]]></c></tag> <item> <p>If this value is false, then when loading a mib each trap @@ -324,6 +362,7 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="agent_ms_cache"></marker> <tag><c><![CDATA[mibs_cache() = bool() | mibs_cache_opts() <optional>]]></c></tag> <item> <p>Shall the agent utilize the mib server lookup cache or not.</p> @@ -331,6 +370,7 @@ default values apply).</p> </item> + <marker id="agent_ms_cache_opts"></marker> <tag><c><![CDATA[mibs_cache_opts() = [mibs_cache_opt()] <optional>]]></c></tag> <item> <p><c>mibs_cache_opt() = {autogc, mibs_cache_autogc()} | {gclimit, mibs_cache_gclimit()} | {age, mibs_cache_age()}</c></p> @@ -338,6 +378,7 @@ <p>For defaults see the options in <c>mibs_cache_opt()</c>.</p> </item> + <marker id="agent_ms_cache_autogc"></marker> <tag><c><![CDATA[mibs_cache_autogc() = bool() <optional>]]></c></tag> <item> <p>Defines if the mib server shall perform cache gc automatically or @@ -346,6 +387,7 @@ <p>Default is <c>true</c>.</p> </item> + <marker id="agent_ms_cache_age"></marker> <tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag> <item> <p>Defines how old the entries in the cache will be allowed before @@ -355,6 +397,7 @@ <p>Default is <c>10 timutes</c>.</p> </item> + <marker id="agent_ms_cache_gclimit"></marker> <tag><c><![CDATA[mibs_cache_gclimit() = integer() > 0 | infinity <optional>]]></c></tag> <item> <p>When performing a GC, this is the max number of cache entries @@ -365,6 +408,7 @@ <p>Default is <c>100</c>.</p> </item> + <marker id="agent_error_report_mod"></marker> <tag><c><![CDATA[error_report_mod() = atom() <optional>]]></c></tag> <item> <p>Defines an error report module, implementing the @@ -374,6 +418,7 @@ <p>Default is <c>snmpa_error_logger</c>.</p> </item> + <marker id="agent_symbolic_store"></marker> <tag><c>symbolic_store() = [symbolic_store_opt()]</c></tag> <item> <p><c>symbolic_store_opt() = {verbosity, verbosity()}</c></p> @@ -381,12 +426,15 @@ <p>For defaults see the options in <c>symbolic_store_opt()</c>.</p> </item> + <marker id="agent_target_cache"></marker> <tag><c>target_cache() = [target_cache_opt()]</c></tag> <item> <p><c>target_cache_opt() = {verbosity, verbosity()}</c></p> <p>Defines options specific for the SNMP agent target cache. </p> <p>For defaults see the options in <c>target_cache_opt()</c>.</p> </item> + + <marker id="agent_config"></marker> <tag><c><![CDATA[agent_config() = [agent_config_opt()] <mandatory>]]></c></tag> <item> <p><c>agent_config_opt() = {dir, agent_config_dir()} | {force_load, force_load()} | {verbosity, verbosity()}</c></p> @@ -394,11 +442,13 @@ <p>For defaults see the options in <c>agent_config_opt()</c>.</p> </item> + <marker id="agent_config_dir"></marker> <tag><c><![CDATA[agent_config_dir = dir() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP agent configuration files are stored.</p> </item> + <marker id="agent_force_load"></marker> <tag><c><![CDATA[force_load() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c> the configuration files are re-read @@ -410,14 +460,18 @@ </item> </taglist> + <marker id="manager_opts_and_types"></marker> <p>Manager specific config options and types:</p> <taglist> + <marker id="manager_server"></marker> <tag><c><![CDATA[server() = [server_opt()] <optional>]]></c></tag> <item> <p><c>server_opt() = {timeout, server_timeout()} | {verbosity, verbosity()}</c></p> <p>Specifies the options for the manager server process.</p> <p>Default is <c>silence</c>.</p> </item> + + <marker id="manager_server_timeout"></marker> <tag><c><![CDATA[server_timeout() = integer() <optional>]]></c></tag> <item> <p>Asynchroneous request cleanup time. For every requests, @@ -438,6 +492,7 @@ <p>Default is <c>30000</c>.</p> </item> + <marker id="manager_config"></marker> <tag><c><![CDATA[manager_config() = [manager_config_opt()] <mandatory>]]></c></tag> <item> <p><c>manager_config_opt() = {dir, manager_config_dir()} | {db_dir, manager_db_dir()} | {db_init_error, db_init_error()} | {repair, manager_repair()} | {auto_save, manager_auto_save()} | {verbosity, verbosity()}</c></p> @@ -445,16 +500,19 @@ <p>For defaults see the options in <c>manager_config_opt()</c>.</p> </item> + <marker id="manager_config_dir"></marker> <tag><c><![CDATA[manager_config_dir = dir() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP manager configuration files are stored.</p> </item> + <marker id="manager_config_db_dir"></marker> <tag><c><![CDATA[manager_db_dir = dir() <mandatory>]]></c></tag> <item> <p>Defines where the SNMP manager store persistent data.</p> </item> + <marker id="manager_config_repair"></marker> <tag><c><![CDATA[manager_repair() = false | true | force <optional>]]></c></tag> <item> <p>Defines the repair option for the persistent database (if @@ -462,6 +520,7 @@ <p>Default is <c>true</c>.</p> </item> + <marker id="manager_config_auto_save"></marker> <tag><c><![CDATA[manager_auto_save() = integer() | infinity <optional>]]></c></tag> <item> <p>The auto save interval. The table is flushed to disk @@ -469,6 +528,7 @@ <p>Default is <c>5000</c>.</p> </item> + <marker id="manager_irb"></marker> <tag><c><![CDATA[manager_irb() = auto | user | {user, integer()} <optional>]]></c></tag> <item> <p>This option defines how the manager will handle the sending of @@ -498,6 +558,7 @@ <p>Default is <c>auto</c>.</p> </item> + <marker id="manager_mibs"></marker> <tag><c><![CDATA[manager_mibs() = [string()] <optional>]]></c></tag> <item> <p>Specifies a list of MIBs (including path) and defines which MIBs @@ -505,6 +566,7 @@ <p>Default is <c>[]</c>.</p> </item> + <marker id="manager_net_if"></marker> <tag><c><![CDATA[manager_net_if() = [manager_net_if_opt()] <optional>]]></c></tag> <item> <p><c>manager_net_if_opt() = {module, manager_net_if_module()} | @@ -515,6 +577,7 @@ <p>For defaults see the options in <c>manager_net_if_opt()</c>.</p> </item> + <marker id="manager_ni_opts"></marker> <tag><c><![CDATA[manager_net_if_options() = [manager_net_if_option()] <optional>]]></c></tag> <item> <p><c>manager_net_if_option() = {bind_to, bind_to()} | @@ -528,6 +591,7 @@ <p>For defaults see the options in <c>manager_net_if_option()</c>.</p> </item> + <marker id="manager_ni_module"></marker> <tag><c><![CDATA[manager_net_if_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface part for the @@ -536,6 +600,7 @@ <p>Default is <c>snmpm_net_if</c>.</p> </item> + <marker id="manager_ni_filter_opts"></marker> <tag><c><![CDATA[manager_net_if_filter_options() = [manager_net_if_filter_option()] <optional>]]></c></tag> <item> <p><c>manager_net_if_filter_option() = {module, manager_net_if_filter_module()}</c></p> @@ -546,6 +611,7 @@ <c>manager_net_if_filter_option()</c>.</p> </item> + <marker id="manager_ni_filter_module"></marker> <tag><c><![CDATA[manager_net_if_filter_module() = atom() <optional>]]></c></tag> <item> <p>Module which handles the network interface filter part for the @@ -554,6 +620,7 @@ <p>Default is <c>snmpm_net_if_filter</c>.</p> </item> + <marker id="manager_def_user_module"></marker> <tag><c><![CDATA[def_user_module() = atom() <optional>]]></c></tag> <item> <p>The module implementing the default user. See the @@ -561,6 +628,7 @@ <p>Default is <c>snmpm_user_default</c>.</p> </item> + <marker id="manager_def_user_data"></marker> <tag><c><![CDATA[def_user_data() = term() <optional>]]></c></tag> <item> <p>Data for the default user. Passed to the user when calling @@ -569,8 +637,10 @@ </item> </taglist> + <marker id="common_types"></marker> <p>Common config types:</p> <taglist> + <marker id="restart_type"></marker> <tag><c>restart_type() = permanent | transient | temporary</c></tag> <item> <p>See <seealso marker="stdlib:supervisor#child_spec">supervisor</seealso> @@ -579,6 +649,7 @@ for the manager.</p> </item> + <marker id="db_init_error"></marker> <tag><c>db_init_error() = terminate | create</c></tag> <item> <p>Defines what to do if the agent is unable to open an @@ -588,12 +659,14 @@ <p>Default is <c>terminate</c>.</p> </item> + <marker id="prio"></marker> <tag><c><![CDATA[priority() = atom() <optional>]]></c></tag> <item> <p>Defines the Erlang priority for all SNMP processes.</p> <p>Default is <c>normal</c>.</p> </item> + <marker id="versions"></marker> <tag><c><![CDATA[versions() = [version()] <optional>]]></c></tag> <item> <p><c>version() = v1 | v2 | v3</c></p> @@ -601,6 +674,7 @@ <p>Default is <c>[v1,v2,v3]</c>.</p> </item> + <marker id="verbosity"></marker> <tag><c><![CDATA[verbosity() = silence | info | log | debug | trace <optional>]]></c></tag> <item> <p>Verbosity for a SNMP process. This specifies now much debug info @@ -608,6 +682,7 @@ <p>Default is <c>silence</c>.</p> </item> + <marker id="bind_to"></marker> <tag><c><![CDATA[bind_to() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c>, net_if binds to the IP address. @@ -616,6 +691,7 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="no_reuse"></marker> <tag><c><![CDATA[no_reuse() = bool() <optional>]]></c></tag> <item> <p>If <c>true</c>, net_if does not specify that the IP @@ -624,17 +700,21 @@ <p>Default is <c>false</c>.</p> </item> + <marker id="recbuf"></marker> <tag><c><![CDATA[recbuf() = integer() <optional>]]></c></tag> <item> <p>Receive buffer size. </p> <p>Default value is defined by <c>gen_udp</c>.</p> </item> + + <marker id="sndbuf"></marker> <tag><c><![CDATA[sndbuf() = integer() <optional>]]></c></tag> <item> <p>Send buffer size. </p> <p>Default value is defined by <c>gen_udp</c>.</p> </item> + <marker id="note_store"></marker> <tag><c><![CDATA[note_store() = [note_store_opt()] <optional>]]></c></tag> <item> <p><c>note_store_opt() = {timeout, note_store_timeout()} | {verbosity, verbosity()}</c></p> @@ -642,6 +722,7 @@ <p>For defaults see the options in <c>note_store_opt()</c>.</p> </item> + <marker id="ns_timeout"></marker> <tag><c><![CDATA[note_store_timeout() = integer() <optional>]]></c></tag> <item> <p>Note cleanup time. When storing a note in the note store, @@ -649,10 +730,9 @@ process performs a GC to remove the expired note's. Time in milli-seconds.</p> <p>Default is <c>30000</c>.</p> - - <marker id="audit_trail_log"></marker> </item> + <marker id="audit_trail_log"></marker> <tag><c><![CDATA[audit_trail_log() [audit_trail_log_opt()] <optional>]]></c></tag> <item> <p><c>audit_trail_log_opt() = {type, atl_type()} | {dir, atl_dir()} | {size, atl_size()} | {repair, atl_repair()} | {seqno, atl_seqno()}</c></p> @@ -663,6 +743,7 @@ <p>If not present, audit trail logging is not used.</p> </item> + <marker id="atl_type"></marker> <tag><c><![CDATA[atl_type() = read | write | read_write <optional>]]></c></tag> <item> <p>Specifies what type of an audit trail log should be used. @@ -684,6 +765,7 @@ <p>Default is <c>read_write</c>.</p> </item> + <marker id="atl_dir"></marker> <tag><c><![CDATA[atl_dir = dir() <mandatory>]]></c></tag> <item> <p>Specifies where the audit trail log should be stored.</p> @@ -691,6 +773,7 @@ place, this parameter <em>must</em> be defined.</p> </item> + <marker id="atl_size"></marker> <tag><c><![CDATA[atl_size() = {integer(), integer()} <mandatory>]]></c></tag> <item> <p>Specifies the size of the audit @@ -699,6 +782,7 @@ take place, this parameter <em>must</em> be defined.</p> </item> + <marker id="atl_repair"></marker> <tag><c><![CDATA[atl_repair() = true | false | truncate | snmp_repair <optional>]]></c></tag> <item> <p>Specifies if and how the audit trail log shall be repaired @@ -710,6 +794,8 @@ analysis.</p> <p>Default is <c>true</c>.</p> </item> + + <marker id="atl_seqno"></marker> <tag><c><![CDATA[atl_seqno() = true | false <optional>]]></c></tag> <item> <p>Specifies if the audit trail log entries will be (sequence) diff --git a/lib/snmp/doc/src/snmpc.xml b/lib/snmp/doc/src/snmpc.xml index 771629492d..61d19251c5 100644 --- a/lib/snmp/doc/src/snmpc.xml +++ b/lib/snmp/doc/src/snmpc.xml @@ -48,7 +48,11 @@ <type> <v>File = string()</v> <v>Options = [opt()]</v> - <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | description() | reference() | group_check() | i() | il() | imports() | module() | module_identity() | module_compliance() | agent_capabilities() | outdir() | no_defs() | verbosity() | warnings()</v> + <v>opt() = db() | relaxed_row_name_assign_check() | deprecated() | + description() | reference() | group_check() | i() | il() | + imports() | module() | module_identity() | module_compliance() | + agent_capabilities() | outdir() | no_defs() | verbosity() | + warnings() | warnings_as_errors()</v> <v>db() = {db, volatile|persistent|mnesia}</v> <v>deprecated() = {deprecated, bool()}</v> <v>relaxed_row_name_assign_check() = relaxed_row_name_assign_check</v> @@ -66,6 +70,7 @@ <v>outdir() = {outdir, dir()}</v> <v>verbosity() = {verbosity, silence|warning|info|log|debug|trace}</v> <v>warnings() = {warnings, bool()}</v> + <v>warnings_as_errors() = warnings_as_errors</v> <v>dir() = string()</v> <v>BinFileName = string()</v> </type> @@ -200,11 +205,17 @@ <item> <p>The option <c>warnings</c> specifies whether warning - messages should be shown. </p> + messages should be shown. </p> <p>Default is <c>true</c>. </p> </item> + <item> + <p>The option <c>warnings_as_errors</c>, if present, specifies + whether warnings should be treated as errors.</p> + </item> + </list> + <p>The MIB compiler understands both SMIv1 and SMIv2 MIBs. It uses the <c>MODULE-IDENTITY</c> statement to determine if the MIB is version 1 or 2. diff --git a/lib/snmp/doc/src/snmpc_cmd.xml b/lib/snmp/doc/src/snmpc_cmd.xml index 9358382a10..971f8a3cff 100644 --- a/lib/snmp/doc/src/snmpc_cmd.xml +++ b/lib/snmp/doc/src/snmpc_cmd.xml @@ -50,6 +50,8 @@ with definitions of Erlang constants for the objects in the MIB, see <seealso marker="snmpc#mib_to_hrl">mib_to_hrl/1</seealso>. </p> + + <marker id="options"></marker> </desc> </func> </funcs> @@ -58,15 +60,18 @@ <title>Compiler options</title> <p>The following options are supported (note that most of these relate to the compilation of the MIB file):</p> + <marker id="option_help"></marker> <taglist> <tag>--help</tag> <item> <p>Prints help info.</p> + <marker id="option_version"></marker> </item> <tag>--version</tag> <item> <p>Prints application and mib format version.</p> + <marker id="option_verbosity"></marker> </item> <tag>--verbosity <em>verbosity</em></tag> @@ -74,11 +79,22 @@ <p>Print debug info. </p> <p><c>verbosity</c> = <c>trace</c> | <c>debug</c> | <c>log</c> | <c>info</c> | <c>silence</c></p> <p>Defaults to <c>silence</c>.</p> + <marker id="option_w"></marker> + <marker id="option_warnings"></marker> </item> - <tag>--warnings</tag> + <tag>--warnings | --W</tag> <item> <p>Print warning messages. </p> + <marker id="option_wae"></marker> + <marker id="option_werror"></marker> + </item> + + <tag>--wae | --Werror</tag> + <item> + <p>Warnings as errors. + Indicates that warnings shall be treated as errors. </p> + <marker id="option_odir"></marker> </item> <tag>--o <em>directory</em></tag> @@ -86,6 +102,7 @@ <p>The directory where the compiler should place the output files. If not specified, output files will be placed in the current working directory.</p> + <marker id="option_idir"></marker> </item> <tag>--i <em>Directory</em></tag> @@ -94,6 +111,7 @@ By default, the current working directory is always included. </p> <p>This option can be present several times, each time specifying <em>one</em> path. </p> + <marker id="option_ildir"></marker> </item> <tag>--il <em>Directory</em></tag> @@ -106,6 +124,7 @@ the current version may be in the system). The current directory and the "snmp-home"/priv/mibs/ are always listed last in the include path. </p> + <marker id="option_sgc"></marker> </item> <tag>--sgc</tag> @@ -114,42 +133,50 @@ group check of the mib compiler. That is, should the OBJECT-GROUP and the NOTIFICATION-GROUP macro(s) be checked for correctness or not. </p> + <marker id="option_dep"></marker> </item> <tag>--dep</tag> <item> <p>Keep deprecated definition(s). If not specified the compiler will ignore deprecated definitions. </p> + <marker id="option_desc"></marker> </item> <tag>--desc</tag> <item> <p>The DESCRIPTION field will be included. </p> + <marker id="option_ref"></marker> </item> <tag>--ref</tag> <item> <p>The REFERENCE field will be included. </p> + <marker id="option_imp"></marker> </item> <tag>--imp</tag> <item> <p>The IMPORTS field will be included. </p> + <marker id="option_mi"></marker> </item> <tag>--mi</tag> <item> <p>The MODULE-IDENTITY field will be included. </p> + <marker id="option_mc"></marker> </item> <tag>--mc</tag> <item> <p>The MODULE-COMPLIANCE field will be included. </p> + <marker id="option_ac"></marker> </item> <tag>--ac</tag> <item> <p>The AGENT-CAPABILITIES field will be included. </p> + <marker id="option_mod"></marker> </item> <tag>--mod <em>module</em></tag> @@ -157,6 +184,7 @@ <p>The module which implements all the instrumentation functions. </p> <p>The name of all instrumentation functions must be the same as the corresponding managed object it implements. </p> + <marker id="option_nd"></marker> </item> <tag>--nd</tag> @@ -165,6 +193,7 @@ used if a managed object have no instrumentation function. Instead this will be reported as an error, and the compilation aborts. </p> + <marker id="option_rrnac"></marker> </item> <tag>--rrnac</tag> @@ -176,6 +205,7 @@ This means that the error will be converted to a warning. </p> <p>By default it is not included, but if this option is present it will be. </p> + <marker id="see_also"></marker> </item> </taglist> @@ -183,7 +213,7 @@ <section> <title>SEE ALSO</title> - <p><seealso marker="erlc">erlc(1)</seealso>, + <p><seealso marker="erts:erlc">erlc(1)</seealso>, <seealso marker="compiler:compile">compile(3)</seealso>, <seealso marker="snmp:snmpc">snmpc(3)</seealso></p> </section> diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml index b527d171b0..c36a1b2a24 100644 --- a/lib/snmp/doc/src/snmpm.xml +++ b/lib/snmp/doc/src/snmpm.xml @@ -283,27 +283,27 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv <v>TargetName = target_name()</v> <v>Config = [agent_config()]</v> <v>agent_config() = {Item, Val}</v> - <v>Item = engine_id | address | port | community | timeout | max_message_size | version | sec_model | sec_name | sec_level</v> + <v>Item = engine_id | address | port | community | timeout | max_message_size | version | sec_model | sec_name | sec_level | tdomain</v> <v>Val = term()</v> <v>Reason = term()</v> </type> <desc> <p>Explicitly instruct the manager to handle this agent, with - <c>UserId</c> as the responsible user. </p> - <p>Called to instruct the manager that this agent - shall be handled. This function is used when - the user knows in advance which agents the - manager shall handle. - Note that there is an alternate way to do the same thing: - Add the agent to the manager config files (see - <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>).</p> + <c>UserId</c> as the responsible user. </p> + <p>Called to instruct the manager that this agent shall be handled. + This function is used when the user knows in advance which agents + the manager shall handle. + Note that there is an alternate way to do the same thing: + Add the agent to the manager config files (see + <seealso marker="snmp_manager_config_files#agents">agents.conf</seealso>).</p> <p><c>TargetName</c> is a non-empty string, - uniquely identifying the agent. </p> - <p>The type of <c>Val</c> depends on <c>Item</c>: </p> + uniquely identifying the agent. </p> + <p>The type of <c>Val</c> depends on <c>Item</c>: </p> <code type="none"><![CDATA[ [mandatory] engine_id = string() [mandatory] address = ip_address() [optional] port = integer() +[optional] tdomain = transportDomainUdpIpv4 | transportDomainUdpIpv6 [optional] community = string() [optional] timeout = integer() | snmp_timer() [optional] max_message_size = integer() @@ -312,7 +312,9 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv [optional] sec_name = string() [optional] sec_level = noAuthNoPriv | authNoPriv | authPriv ]]></code> - <p>Note that if no <c>Port</c> is given, the default value is used.</p> + <p>Note that if no <c>tdomain</c> is given, the default value, + <c>transportDomainUdpIpv4</c>, is used.</p> + <p>Note that if no <c>port</c> is given, the default value is used.</p> <marker id="unregister_agent"></marker> </desc> @@ -348,17 +350,25 @@ sec_level = noAuthNoPriv | authNoPriv | authPriv </func> <func> + <name>update_agent_info(UserId, TargetName, Info) -> ok | {error, Reason}</name> <name>update_agent_info(UserId, TargetName, Item, Val) -> ok | {error, Reason}</name> <fsummary>Update agent config</fsummary> <type> <v>UserId = term()</v> <v>TargetName = target_name()</v> - <v>Item = atom()</v> - <v>Val = term()</v> + <v>Info = [{item(), item_value()}]</v> + <v>Item = item()</v> + <v>item() = atom()</v> + <v>Val = item_value()</v> + <v>item_value() = term()</v> <v>Reason = term()</v> </type> <desc> - <p>Update agent config.</p> + <p>Update agent config. The function <c>update_agent_info/3</c> + should be used when several values needs to be updated atomically. </p> + <p>See function + <seealso marker="#register_agent">register_agent</seealso>) + for more info about what kind of items are allowed. </p> <marker id="which_agents"></marker> </desc> diff --git a/lib/snmp/priv/plt/.gitignore b/lib/snmp/priv/plt/.gitignore new file mode 100644 index 0000000000..174481f561 --- /dev/null +++ b/lib/snmp/priv/plt/.gitignore @@ -0,0 +1,3 @@ +/*.plt +/*.dialyzer_analysis + diff --git a/lib/snmp/src/agent/depend.mk b/lib/snmp/src/agent/depend.mk index bc39e1fa35..078ef15821 100644 --- a/lib/snmp/src/agent/depend.mk +++ b/lib/snmp/src/agent/depend.mk @@ -52,6 +52,7 @@ $(EBIN)/snmpa_acm.$(EMULATOR): \ $(EBIN)/snmpa_agent.$(EMULATOR): \ snmpa_agent.erl \ + snmpa_internal.hrl \ ../misc/snmp_debug.hrl \ ../misc/snmp_verbosity.hrl \ ../../include/snmp_types.hrl @@ -136,6 +137,7 @@ $(EBIN)/snmpa_set_lib.$(EMULATOR): \ $(EBIN)/snmpa_supervisor.$(EMULATOR): \ snmpa_supervisor.erl \ + snmpa_internal.hrl \ ../misc/snmp_debug.hrl \ ../misc/snmp_verbosity.hrl diff --git a/lib/snmp/src/agent/snmp_generic_mnesia.erl b/lib/snmp/src/agent/snmp_generic_mnesia.erl index a73aad5b33..ce42af404b 100644 --- a/lib/snmp/src/agent/snmp_generic_mnesia.erl +++ b/lib/snmp/src/agent/snmp_generic_mnesia.erl @@ -121,7 +121,7 @@ table_func(set, RowIndex, Cols, Name) -> fun() -> snmp_generic:table_set_row( {Name, mnesia}, nofunc, - {snmp_generic_mnesia, table_try_make_consistent}, + fun table_try_make_consistent/2, RowIndex, Cols) end) of {atomic, Value} -> @@ -368,7 +368,8 @@ table_set_elements(Name, RowIndex, Cols) -> _ -> false end. table_set_elements(Name, RowIndex, Cols, ConsFunc) -> - #table_info{index_types = Indexes, first_own_index = FirstOwnIndex} = + #table_info{index_types = Indexes, + first_own_index = FirstOwnIndex} = snmp_generic:table_info(Name), AddCol = if FirstOwnIndex == 0 -> 2; diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 77910541a2..a45db89c09 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -46,8 +46,14 @@ %% Column not accessible via SNMP - needed when the agent sends informs -define(snmpTargetAddrEngineId, 10). %% Extra comlumns for the augmented table snmpTargetAddrExtTable --define(snmpTargetAddrTMask, 11). --define(snmpTargetAddrMMS, 12). +-define(snmpTargetAddrTMask, 11). +-define(snmpTargetAddrMMS, 12). + +-ifdef(snmp_extended_verbosity). +-define(vt(F,A), ?vtrace(F, A)). +-else. +-define(vt(_F, _A), ok). +-endif. %%----------------------------------------------------------------- @@ -383,10 +389,18 @@ is_valid_tag(Tag, TDomain, TAddress) -> is_valid_tag(TDomain, TAddress, Tag, []). is_valid_tag(TDomain, TAddress, Tag, Key) -> + ?vtrace("is_valid_tag -> entry with" + "~n TDomain: ~p" + "~n TAddress: ~p" + "~n Tag: ~p" + "~n Key: ~p", [TDomain, TAddress, Tag, Key]), case table_next(snmpTargetAddrTable, Key) of endOfTable -> + ?vtrace("is_valid_tag -> endOfTable", []), false; NextKey -> + ?vtrace("is_valid_tag -> next key found" + "~n NextKey: ~p", [NextKey]), case get(snmpTargetAddrTable, NextKey, [?snmpTargetAddrTDomain, ?snmpTargetAddrTAddress, ?snmpTargetAddrTagList, @@ -395,6 +409,8 @@ is_valid_tag(TDomain, TAddress, Tag, Key) -> {value, TAddress}, % RFC2576: chapters 5.2.1 & 5.3 {value, TagList}, {value, []}] -> + ?vtrace("is_valid_tag -> found with exact match" + "~n TagList: ~p", [TagList]), case snmp_misc:is_tag_member(Tag, TagList) of true -> ?vtrace("is_valid_tag -> exact: " @@ -410,9 +426,14 @@ is_valid_tag(TDomain, TAddress, Tag, Key) -> {value, TAddress2}, {value, TagList}, {value, TMask}] when TMask =/= [] -> + ?vtrace("is_valid_tag -> found with exact match" + "~n TagList: ~p" + "~n TMask: ~p", [TagList, TMask]), case snmp_misc:is_tmask_match(TAddress, TAddress2, TMask) of true -> + ?vtrace("is_valid_tag -> " + "tmask match - now check tag member", []), case snmp_misc:is_tag_member(Tag, TagList) of true -> ?vtrace("is_valid_tag -> masked: " @@ -425,10 +446,12 @@ is_valid_tag(TDomain, TAddress, Tag, Key) -> Tag, NextKey) end; false -> + ?vtrace("is_valid_tag -> tmask NO match", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end; _ -> + ?vtrace("is_valid_tag -> not found - try next", []), is_valid_tag(TDomain, TAddress, Tag, NextKey) end end. @@ -442,10 +465,16 @@ get_target_addrs() -> get_target_addrs(Key, {Tab, _} = TabDb, Acc) -> + ?vt("get_target_addrs -> entry with" + "~n Key: ~p", [Key]), case table_next(Tab, Key) of endOfTable -> + ?vt("get_target_addrs -> endOfTable when" + "~n Acc: ~p", [Acc]), Acc; NextKey -> + ?vt("get_target_addrs -> next ok: " + "~n NextKey: ~p", [NextKey]), case get_target_addr(TabDb, NextKey) of {ok, Targ} -> get_target_addrs(NextKey, TabDb, [Targ| Acc]); @@ -591,9 +620,9 @@ snmpTargetAddrTable(print) -> [Prefix, element(?snmpTargetAddrName, Row), Prefix, element(?snmpTargetAddrTDomain, Row), case element(?snmpTargetAddrTDomain, Row) of - ?snmpUDPDomain -> udp; - ?transportDomainUdpIpv4 -> udpIpv4; - ?transportDomainUdpIpv6 -> udpIpv6; + ?snmpUDPDomain -> snmpUDPDomain; + ?transportDomainUdpIpv4 -> transportDomainUdpIpv4; + ?transportDomainUdpIpv6 -> transportDomainUdpIpv6; _ -> undefined end, Prefix, element(?snmpTargetAddrTAddress, Row), diff --git a/lib/snmp/src/agent/snmp_view_based_acm_mib.erl b/lib/snmp/src/agent/snmp_view_based_acm_mib.erl index 28469a7b4e..2cee91b081 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-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -203,18 +203,16 @@ init_sec2group_table([Row | T]) -> init_sec2group_table(T); init_sec2group_table([]) -> true. -init_access_table([{GN, Prefix, Model, Level, Row} | T]) -> -%% ?vtrace("init access table: " -%% "~n GN: ~p" -%% "~n Prefix: ~p" -%% "~n Model: ~p" -%% "~n Level: ~p" -%% "~n Row: ~p",[GN, Prefix, Model, Level, Row]), - Key = [length(GN) | GN] ++ [length(Prefix) | Prefix] ++ [Model, Level], - snmpa_vacm:insert([{Key, Row}], false), - init_access_table(T); -init_access_table([]) -> - snmpa_vacm:dump_table(). +make_access_key(GN, Prefix, Model, Level) -> + [length(GN) | GN] ++ [length(Prefix) | Prefix] ++ [Model, Level]. + +make_access_entry({GN, Prefix, Model, Level, Row}) -> + Key = make_access_key(GN, Prefix, Model, Level), + {Key, Row}. + +init_access_table(TableData) -> + TableData2 = [make_access_entry(E) || E <- TableData], + snmpa_vacm:insert(TableData2, true). init_view_table([Row | T]) -> %% ?vtrace("init view table: " @@ -247,6 +245,7 @@ add_sec2group(SecModel, SecName, GroupName) -> Key = [Key1, length(Key2) | Key2], case table_cre_row(vacmSecurityToGroupTable, Key, Row) of true -> + snmpa_agent:invalidate_ca_cache(), {ok, Key}; false -> {error, create_failed} @@ -260,6 +259,7 @@ add_sec2group(SecModel, SecName, GroupName) -> delete_sec2group(Key) -> case table_del_row(vacmSecurityToGroupTable, Key) of true -> + snmpa_agent:invalidate_ca_cache(), ok; false -> {error, delete_failed} @@ -274,11 +274,9 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) -> Match, RV, WV, NV}, case (catch check_vacm(Access)) of {ok, {vacmAccess, {GN, Pref, SM, SL, Row}}} -> - Key1 = [length(GN) | GN], - Key2 = [length(Pref) | Pref], - Key3 = [SM, SL], - Key = Key1 ++ Key2 ++ Key3, + Key = make_access_key(GN, Pref, SM, SL), snmpa_vacm:insert([{Key, Row}], false), + snmpa_agent:invalidate_ca_cache(), {ok, Key}; {error, Reason} -> {error, Reason}; @@ -287,6 +285,7 @@ add_access(GroupName, Prefix, SecModel, SecLevel, Match, RV, WV, NV) -> end. delete_access(Key) -> + snmpa_agent:invalidate_ca_cache(), snmpa_vacm:delete(Key). @@ -299,6 +298,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) -> Key = [length(Key1) | Key1] ++ [length(Key2) | Key2], case table_cre_row(vacmViewTreeFamilyTable, Key, Row) of true -> + snmpa_agent:invalidate_ca_cache(), {ok, Key}; false -> {error, create_failed} @@ -312,6 +312,7 @@ add_view_tree_fam(ViewIndex, SubTree, Status, Mask) -> delete_view_tree_fam(Key) -> case table_del_row(vacmViewTreeFamilyTable, Key) of true -> + snmpa_agent:invalidate_ca_cache(), ok; false -> {error, delete_failed} diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index 50b169e4e7..c400aaddf7 100644 --- a/lib/snmp/src/agent/snmpa.erl +++ b/lib/snmp/src/agent/snmpa.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -547,7 +547,7 @@ update_mibs_cache_age(Agent, Age) -> update_mibs_cache_gclimit(GcLimit) -> - update_mibs_cache_age(snmp_master_agent, GcLimit). + update_mibs_cache_gclimit(snmp_master_agent, GcLimit). update_mibs_cache_gclimit(Agent, GcLimit) -> snmpa_agent:update_mibs_cache_gclimit(Agent, GcLimit). diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index 82a7ec647b..17cb9c9fe3 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -68,8 +68,11 @@ %% Internal exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3, tr_var/2, tr_varbind/1, - handle_pdu/7, worker/2, worker_loop/1, + handle_pdu/8, worker/2, worker_loop/1, do_send_trap/7, do_send_trap/8]). +%% <BACKWARD-COMPAT> +-export([handle_pdu/7]). +%% </BACKWARD-COMPAT> -include("snmpa_internal.hrl"). @@ -87,7 +90,6 @@ -define(DISCO_TERMINATING_TRIGGER_USERNAME, ""). - -ifdef(snmp_debug). -define(GS_START_LINK3(Prio, Parent, Ref, Opts), gen_server:start_link(?MODULE, [Prio, Parent, Ref, Opts], @@ -103,13 +105,49 @@ gen_server:start_link({local, Name}, ?MODULE, [Prio, Parent, Ref, Opts],[])). -endif. - + +%% Increment this whenever a change is made to the worker interface +-define(WORKER_INTERFACE_VERSION, 1). + +%% -- Utility macros for creating worker commands -- +-define(mk_pdu_wreq(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra), + #wrequest{cmd = handle_pdu, + info = [{vsn, Vsn}, + {pdu, Pdu}, + {pdu_ms, PduMS}, + {acm_data, ACMData}, + {addr, Address}, + {gb_max_vbs, GbMaxVBs}, + {extra, Extra}]}). +-define(mk_send_trap_wreq(TrapRec, NotifyName, ContextName, + Recv, Vbs, LocalEngineID, Extra), + #wrequest{cmd = send_trap, + info = [{trap_rec, TrapRec}, + {notify_name, NotifyName}, + {context_name, ContextName}, + {receiver, Recv}, + {varbinds, Vbs}, + {local_engine_id, LocalEngineID}, + {extra, Extra}]}). +-define(mk_terminate_wreq(), #wrequest{cmd = terminate, info = []}). +-define(mk_verbosity_wreq(V), #wrequest{cmd = verbosity, + info = [{verbosity, V}]}). + -record(notification_filter, {id, mod, data}). -record(disco, {from, rec, sender, target, engine_id, sec_level, ctx, ivbs, stage, handler, extra}). +%% This record is used when sending requests to the worker processes +-record(wrequest, + { + version = ?WORKER_INTERFACE_VERSION, + cmd, + info + } + ). + %%----------------------------------------------------------------- %% The agent is multi-threaded, i.e. each request is handled @@ -142,7 +180,8 @@ net_if_mod, backup, disco, - mibs_cache_request}). + mibs_cache_request, + gb_max_vbs}). %%%----------------------------------------------------------------- @@ -330,6 +369,8 @@ do_init(Prio, Parent, Ref, Options) -> MultiT = get_multi_threaded(Options), Vsns = get_versions(Options), + GbMaxVbs = get_gb_max_vbs(Options), + NS = start_note_store(Prio, Ref, Options), {Type, NetIfPid, NetIfMod} = start_net_if(Parent, Prio, Ref, Vsns, NS, Options), @@ -348,7 +389,8 @@ do_init(Prio, Parent, Ref, Options) -> ref = Ref, vsns = Vsns, note_store = NS, - net_if_mod = NetIfMod}}. + net_if_mod = NetIfMod, + gb_max_vbs = GbMaxVbs}}. start_note_store(Prio, Ref, Options) -> @@ -410,7 +452,8 @@ start_net_if(Parent, _Prio, _Ref, _Vsns, _NoteStore, _Options) start_mib_server(Prio, Ref, Mibs, Options) -> ?vdebug("start_mib_server -> with Prio: ~p", [Prio]), MibStorage = get_mib_storage(Options), - MibsOpts = [{mib_storage, MibStorage}|get_option(mib_server, Options, [])], + MibsOpts = [{mib_storage, MibStorage} | + get_option(mib_server, Options, [])], ?vtrace("start_mib_server -> " "~n Mibs: ~p" @@ -558,25 +601,6 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) -> ], send_notification(Agent, Trap, SendOpts). -%% send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) -> -%% ?d("send_trap -> entry with" -%% "~n self(): ~p" -%% "~n Agent: ~p [~p]" -%% "~n Trap: ~p" -%% "~n NotifyName: ~p" -%% "~n CtxName: ~p" -%% "~n Recv: ~p" -%% "~n Varbinds: ~p", -%% [self(), Agent, wis(Agent), -%% Trap, NotifyName, CtxName, Recv, Varbinds]), -%% Msg = {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds}, -%% case (wis(Agent) =:= self()) of -%% false -> -%% call(Agent, Msg); -%% true -> -%% Agent ! Msg -%% end. - send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> ?d("send_trap -> entry with" "~n self(): ~p" @@ -599,27 +623,6 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> ], send_notification(Agent, Trap, SendOpts). -%% send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> -%% ?d("send_trap -> entry with" -%% "~n self(): ~p" -%% "~n Agent: ~p [~p]" -%% "~n Trap: ~p" -%% "~n NotifyName: ~p" -%% "~n CtxName: ~p" -%% "~n Recv: ~p" -%% "~n Varbinds: ~p" -%% "~n LocalEngineID: ~p", -%% [self(), Agent, wis(Agent), -%% Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID]), -%% Msg = -%% {send_trap, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID}, -%% case (wis(Agent) =:= self()) of -%% false -> -%% call(Agent, Msg); -%% true -> -%% Agent ! Msg -%% end. - %% </BACKWARD-COMPAT> @@ -709,11 +712,6 @@ wis(Atom) when is_atom(Atom) -> whereis(Atom). -forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds) -> - ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, - forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds, - ExtraInfo). - forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds, ExtraInfo) -> Agent ! {forward_trap, TrapRecord, NotifyName, CtxName, Recv, Varbinds, @@ -796,7 +794,8 @@ handle_info({snmp_pdu, Vsn, Pdu, PduMS, ACMData, Address, Extra}, S) -> ?vdebug("handle_info(snmp_pdu) -> entry with" "~n Vsn: ~p" "~n Pdu: ~p" - "~n Address: ~p", [Vsn, Pdu, Address]), + "~n Address: ~p" + "~n Extra: ~p", [Vsn, Pdu, Address, Extra]), NewS = handle_snmp_pdu(is_valid_pdu_type(Pdu#pdu.type), Vsn, Pdu, PduMS, ACMData, Address, Extra, S), @@ -808,11 +807,11 @@ handle_info(worker_available, S) -> {noreply, S#state{worker_state = ready}}; handle_info({send_notif, Notification, SendOpts}, S) -> - ?vlog("[handle_info] send trap request:" + ?vlog("[handle_info] send notif request:" "~n Notification: ~p" "~n SendOpts: ~p", [Notification, SendOpts]), - case (catch handle_send_trap(cast, S, Notification, SendOpts)) of + case (catch handle_send_trap(S, Notification, SendOpts)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -832,7 +831,7 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) -> "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, - LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, + LocalEngineID = local_engine_id(S), case (catch handle_send_trap(S, Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> @@ -979,6 +978,7 @@ handle_info({'EXIT', Pid, Reason}, S) -> end, {noreply, S} end; + handle_info({'DOWN', Ref, process, Pid, {mibs_cache_reply, Reply}}, #state{mibs_cache_request = {Pid, Ref, From}} = S) -> ?vlog("reply from the mibs cache request handler (~p): ~n~p", @@ -1014,11 +1014,11 @@ handle_call(restart_set_worker, _From, #state{set_worker = Pid} = S) -> {reply, ok, S}; handle_call({send_notif, Notification, SendOpts}, _From, S) -> - ?vlog("[handle_info] send trap request:" + ?vlog("[handle_call] send notif request:" "~n Notification: ~p" "~n SendOpts: ~p", [Notification, SendOpts]), - case (catch handle_send_trap(call, S, Notification, SendOpts)) of + case (catch handle_send_trap(S, Notification, SendOpts)) of {ok, NewS} -> {reply, ok, NewS}; {'EXIT', Reason} -> @@ -1039,18 +1039,8 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, "~n Recv: ~p" "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), - ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, - LocalEngineID = - case S#state.type of - master_agent -> - ?DEFAULT_LOCAL_ENGINE_ID; - _ -> - %% subagent - - %% we don't need this now, eventually the trap send - %% request will reach the master-agent and then it - %% will look up the proper engine id. - ignore - end, + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + LocalEngineID = local_engine_id(S), case (catch handle_send_trap(S, Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> @@ -1130,7 +1120,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), S}; + {reply, do_get_next(MibView, Varbinds, infinity), S}; handle_call({subagent_set, Arguments, PduData}, _From, S) -> ?vlog("[handle_call] subagent set:" "~n Arguments: ~p" @@ -1171,7 +1161,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) of + case do_get_next(MibView, Varbinds, infinity) of {noError, 0, NewVarbinds} -> Vbs = lists:keysort(#varbind.org_index, NewVarbinds), [{Oid,Val} || #varbind{oid = Oid, value = Val} <- Vbs]; @@ -1338,27 +1328,27 @@ handle_call({me_of, Oid}, _From, S) -> {reply, Reply, S}; handle_call(get_log_type, _From, S) -> - ?vlog("get_log_type", []), + ?vlog("handle_call(get_log_type) -> entry with", []), Reply = handle_get_log_type(S), {reply, Reply, S}; handle_call({set_log_type, NewType}, _From, S) -> - ?vlog("set_log_type -> " + ?vlog("handle_call(set_log_type) -> entry with" "~n NewType: ~p", [NewType]), Reply = handle_set_log_type(S, NewType), {reply, Reply, S}; handle_call(get_request_limit, _From, S) -> - ?vlog("get_request_limit", []), + ?vlog("handle_call(get_request_limit) -> entry with", []), Reply = handle_get_request_limit(S), {reply, Reply, S}; handle_call({set_request_limit, NewLimit}, _From, S) -> - ?vlog("set_request_limit -> " + ?vlog("handle_call(set_request_limit) -> entry with" "~n NewLimit: ~p", [NewLimit]), Reply = handle_set_request_limit(S, NewLimit), {reply, Reply, S}; - + handle_call(stop, _From, S) -> {stop, normal, ok, S}; @@ -1367,15 +1357,15 @@ handle_call(Req, _From, S) -> Reply = {error, {unknown, Req}}, {reply, Reply, S}. -handle_cast({verbosity,Verbosity}, S) -> - ?vlog("verbosity: ~p -> ~p",[get(verbosity),Verbosity]), +handle_cast({verbosity, Verbosity}, S) -> + ?vlog("verbosity: ~p -> ~p",[get(verbosity), Verbosity]), put(verbosity,snmp_verbosity:validate(Verbosity)), case S#state.worker of - Pid when is_pid(Pid) -> Pid ! {verbosity,Verbosity}; + Pid when is_pid(Pid) -> Pid ! ?mk_verbosity_wreq(Verbosity); _ -> ok end, case S#state.set_worker of - Pid2 when is_pid(Pid2) -> Pid2 ! {verbosity,Verbosity}; + Pid2 when is_pid(Pid2) -> Pid2 ! ?mk_verbosity_wreq(Verbosity); _ -> ok end, {noreply, S}; @@ -1462,13 +1452,80 @@ handle_mibs_cache_request(MibServer, Req) -> %% Downgrade %% -%% code_change({down, _Vsn}, S, downgrade_to_pre_4_13) -> -%% {ok, S2}; +code_change({down, _Vsn}, S1, downgrade_to_pre_4_17_3) -> + #state{type = Type, + parent = Parent, + worker = Worker, + worker_state = WorkerState, + set_worker = SetWorker, + multi_threaded = MT, + ref = Ref, + vsns = Vsns, + nfilters = NF, + note_store = NoteStore, + mib_server = MS, + net_if = NetIf, + net_if_mod = NetIfMod, + backup = Backup, + disco = Disco, + mibs_cache_request = MCR} = S1, + S2 = {state, + type = Type, + parent = Parent, + worker = Worker, + worker_state = WorkerState, + set_worker = SetWorker, + multi_threaded = MT, + ref = Ref, + vsns = Vsns, + nfilters = NF, + note_store = NoteStore, + mib_server = MS, + net_if = NetIf, + net_if_mod = NetIfMod, + backup = Backup, + disco = Disco, + mibs_cache_request = MCR}, + {ok, S2}; %% Upgrade %% -%% code_change(_Vsn, S, upgrade_from_pre_4_13) -> -%% {ok, S2}; +code_change(_Vsn, S1, upgrade_from_pre_4_17_3) -> + {state, + type = Type, + parent = Parent, + worker = Worker, + worker_state = WorkerState, + set_worker = SetWorker, + multi_threaded = MT, + ref = Ref, + vsns = Vsns, + nfilters = NF, + note_store = NoteStore, + mib_server = MS, + net_if = NetIf, + net_if_mod = NetIfMod, + backup = Backup, + disco = Disco, + mibs_cache_request = MCR} = S1, + S2 = #state{type = Type, + parent = Parent, + worker = Worker, + worker_state = WorkerState, + set_worker = SetWorker, + multi_threaded = MT, + ref = Ref, + vsns = Vsns, + nfilters = NF, + note_store = NoteStore, + mib_server = MS, + net_if = NetIf, + net_if_mod = NetIfMod, + backup = Backup, + disco = Disco, + mibs_cache_request = MCR, + gb_max_vbs = ?DEFAULT_GB_MAX_VBS}, + {ok, S2}; code_change(_Vsn, S, _Extra) -> {ok, S}. @@ -1508,7 +1565,7 @@ worker_start(Dict) -> %% worker_stop(Pid, infinity). worker_stop(Pid, Timeout) when is_pid(Pid) -> - Pid ! terminate, + Pid ! ?mk_terminate_wreq(), receive {'EXIT', Pid, normal} -> ok @@ -1595,7 +1652,7 @@ handle_backup_res([{Who, Crap}|Results], Acc) -> %% because we (for some reason) support the function %% snmpa:current_community(). %%----------------------------------------------------------------- -cheat({community, SecModel, Community, _TAddress}, Address, ContextName) -> +cheat({community, _SecModel, Community, _TAddress}, Address, ContextName) -> {Community, Address, ContextName}; cheat({community, _SecModel, Community, _TDomain, _TAddress}, Address, ContextName) -> @@ -1626,7 +1683,7 @@ invalidate_ca_cache() -> MasterAgent ! invalidate_ca_cache; false -> %% This is running on a sub-agent node, - %% so sent skip it + %% so skip it ok end; _ -> % Not on this node @@ -1645,9 +1702,11 @@ invalidate_ca_cache() -> %% %%----------------------------------------------------------------- -spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, Extra) -> +%% This functions spawns a temporary worker process, +%% that evaluates one request and then silently exits. +spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra) -> Dict = get(), - Args = [Vsn, Pdu, PduMS, ACMData, Address, Extra, Dict], + Args = [Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra, Dict], proc_lib:spawn_link(?MODULE, handle_pdu, Args). spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs, @@ -1665,7 +1724,7 @@ do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, ExtraInfo, Dict) -> lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict), - put(sname,trap_sender_short_name(get(sname))), + put(sname, trap_sender_short_name(get(sname))), ?vlog("starting",[]), snmpa_trap:send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, ExtraInfo, get(net_if)). @@ -1677,58 +1736,122 @@ worker(Master, Dict) -> worker_loop(Master). worker_loop(Master) -> - receive - {Vsn, Pdu, PduMS, ACMData, Address, Extra} -> - ?vtrace("worker_loop -> received request", []), - handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra), - Master ! worker_available; - - %% We don't trap EXITs! - {TrapRec, NotifyName, ContextName, Recv, Vbs} -> - ?vtrace("worker_loop -> send trap:" - "~n ~p", [TrapRec]), - snmpa_trap:send_trap(TrapRec, NotifyName, - ContextName, Recv, Vbs, - ?DEFAULT_NOTIF_EXTRA_INFO, - get(net_if)), - Master ! worker_available; - - %% We don't trap EXITs! - {send_trap, - TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID} -> - ?vtrace("worker_loop -> send trap:" - "~n ~p", [TrapRec]), - snmpa_trap:send_trap(TrapRec, NotifyName, - ContextName, Recv, Vbs, - LocalEngineID, ?DEFAULT_NOTIF_EXTRA_INFO, - get(net_if)), - Master ! worker_available; - - {send_trap, - TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, ExtraInfo} -> - ?vtrace("worker_loop -> send trap:" - "~n ~p", [TrapRec]), - snmpa_trap:send_trap(TrapRec, NotifyName, - ContextName, Recv, Vbs, - LocalEngineID, ExtraInfo, - get(net_if)), - Master ! worker_available; - - {verbosity, Verbosity} -> - put(verbosity,snmp_verbosity:validate(Verbosity)); - - terminate -> - exit(normal); - - _X -> - %% ignore - ok - - after 30000 -> - %% This is to assure that the worker process leaves a - %% possibly old version of this module. - ok - end, + Res = + receive + #wrequest{cmd = handle_pdu, + info = Info} = Req -> + ?vtrace("worker_loop -> received handle_pdu request with" + "~n Info: ~p", [Info]), + Vsn = proplists:get_value(vsn, Info), + Pdu = proplists:get_value(pdu, Info), + PduMS = proplists:get_value(pdu_ms, Info), + ACMData = proplists:get_value(acm_data, Info), + Address = proplists:get_value(addr, Info), + GbMaxVBs = proplists:get_value(gb_max_vbs, Info), + Extra = proplists:get_value(extra, Info), + HandlePduRes = + try + begin + handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, + GbMaxVBs, Extra) + end + catch + T:E -> + exit({worker_crash, Req, T, E, + erlang:get_stacktrace()}) + end, + Master ! worker_available, + HandlePduRes; % For debugging... + + + #wrequest{cmd = send_trap, + info = Info} = Req -> + ?vtrace("worker_loop -> received send_trap request with" + "~n Info: ~p", [Info]), + TrapRec = proplists:get_value(trap_rec, Info), + NotifyName = proplists:get_value(notify_name, Info), + ContextName = proplists:get_value(context_name, Info), + Recv = proplists:get_value(receiver, Info), + Vbs = proplists:get_value(varbinds, Info), + LocalEngineID = proplists:get_value(local_engine_id, Info), + Extra = proplists:get_value(extra, Info), + SendTrapRes = + try + begin + snmpa_trap:send_trap(TrapRec, NotifyName, + ContextName, Recv, Vbs, + LocalEngineID, Extra, + get(net_if)) + end + catch + T:E -> + exit({worker_crash, Req, T, E, + erlang:get_stacktrace()}) + end, + Master ! worker_available, + SendTrapRes; % For debugging... + + + #wrequest{cmd = verbosity, + info = Info} -> + Verbosity = proplists:get_value(verbosity, Info), + put(verbosity, snmp_verbosity:validate(Verbosity)); + + + #wrequest{cmd = terminate} -> + ?vtrace("worker_loop -> received terminate request", []), + exit(normal); + + + %% ************************************************************* + %% + %% Kept for backward compatibillity reasons + %% + %% ************************************************************* + + {Vsn, Pdu, PduMS, ACMData, Address, Extra} -> + ?vtrace("worker_loop -> received request", []), + handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, + ?DEFAULT_GB_MAX_VBS, Extra), + Master ! worker_available; + + %% We don't trap exits! + {TrapRec, NotifyName, ContextName, Recv, Vbs} -> + ?vtrace("worker_loop -> send trap:" + "~n ~p", [TrapRec]), + snmpa_trap:send_trap(TrapRec, NotifyName, + ContextName, Recv, Vbs, get(net_if)), + Master ! worker_available; + + %% We don't trap exits! + {send_trap, + TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, + ExtraInfo} -> + ?vtrace("worker_loop -> send trap:" + "~n ~p", [TrapRec]), + snmpa_trap:send_trap(TrapRec, NotifyName, + ContextName, Recv, Vbs, + LocalEngineID, ExtraInfo, + get(net_if)), + Master ! worker_available; + + {verbosity, Verbosity} -> + put(verbosity, snmp_verbosity:validate(Verbosity)); + + terminate -> + exit(normal); + + _X -> + %% ignore + ignore_unknown + + after 30000 -> + %% This is to assure that the worker process leaves a + %% possibly old version of this module. + ok + end, + ?vtrace("worker_loop -> wrap with" + "~n ~p", [Res]), ?MODULE:worker_loop(Master). @@ -1736,42 +1859,52 @@ worker_loop(Master) -> %%----------------------------------------------------------------- handle_snmp_pdu(true, Vsn, Pdu, PduMS, ACMData, Address, Extra, - #state{multi_threaded = false} = S) -> + #state{multi_threaded = false, + gb_max_vbs = GbMaxVBs} = S) -> ?vtrace("handle_snmp_pdu -> single-thread agent",[]), - handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra), + handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra), S; handle_snmp_pdu(true, Vsn, #pdu{type = 'set-request'} = Pdu, PduMS, ACMData, Address, Extra, #state{set_worker = Worker} = S) -> ?vtrace("handle_snmp_pdu -> multi-thread agent: " "send set-request to main worker",[]), - Worker ! {Vsn, Pdu, PduMS, ACMData, Address, Extra}, + WRequest = ?mk_pdu_wreq(Vsn, Pdu, PduMS, ACMData, Address, infinity, Extra), + Worker ! WRequest, S#state{worker_state = busy}; handle_snmp_pdu(true, Vsn, Pdu, PduMS, ACMData, Address, Extra, - #state{worker_state = busy} = S) -> + #state{worker_state = busy, + gb_max_vbs = GbMaxVBs} = S) -> ?vtrace("handle_snmp_pdu -> multi-thread agent: " "main worker busy - create new worker",[]), - spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, Extra), + spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra), S; handle_snmp_pdu(true, Vsn, Pdu, PduMS, ACMData, Address, Extra, - #state{worker = Worker} = S) -> + #state{worker = Worker, + gb_max_vbs = GbMaxVBs} = S) -> ?vtrace("handle_snmp_pdu -> multi-thread agent: " "send to main worker",[]), - Worker ! {Vsn, Pdu, PduMS, ACMData, Address, Extra}, + WRequest = ?mk_pdu_wreq(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra), + Worker ! WRequest, S#state{worker_state = busy}; handle_snmp_pdu(_, _Vsn, _Pdu, _PduMS, _ACMData, _Address, _Extra, S) -> S. %% Called via the spawn_thread function +%% <BACKWARD-COMPAT> handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra, Dict) -> + handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, ?DEFAULT_GB_MAX_VBS, Extra, + Dict). +%% </BACKWARD-COMPAT> +handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra, Dict) -> lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict), put(sname, pdu_handler_short_name(get(sname))), ?vlog("new worker starting",[]), - handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra). + handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra). -handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra) -> +handle_pdu2(Vsn, Pdu, PduMS, ACMData, Address, GbMaxVBs, Extra) -> %% OTP-3324 AuthMod = get(auth_module), case AuthMod:init_check_access(Pdu, ACMData) of @@ -1780,7 +1913,8 @@ handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra) -> "~n MibView: ~p" "~n ContextName: ~p", [MibView, ContextName]), AgentData = cheat(ACMData, Address, ContextName), - do_handle_pdu(MibView, Vsn, Pdu, PduMS, ACMData, AgentData, Extra); + do_handle_pdu(MibView, Vsn, Pdu, PduMS, ACMData, AgentData, + GbMaxVBs, Extra); {error, Reason} -> ?vlog("handle_pdu -> error:" "~n Reason: ~p", [Reason]), @@ -1794,16 +1928,19 @@ handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra) -> end. do_handle_pdu(MibView, Vsn, Pdu, PduMS, - ACMData, {Community, Address, ContextName}, Extra) -> + ACMData, {Community, Address, ContextName}, + GbMaxVBs, Extra) -> put(net_if_data, Extra), + RePdu = process_msg(MibView, Vsn, Pdu, PduMS, Community, - Address, ContextName), + Address, ContextName, GbMaxVBs), ?vtrace("do_handle_pdu -> processed:" "~n RePdu: ~p", [RePdu]), - get(net_if) ! {snmp_response, Vsn, RePdu, - RePdu#pdu.type, ACMData, Address, Extra}. + NetIf = get(net_if), + NetIf ! {snmp_response, Vsn, RePdu, + RePdu#pdu.type, ACMData, Address, Extra}. handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) -> @@ -1859,7 +1996,7 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) -> ok end. -get_opt(Key, Default, SendOpts) -> +get_send_opt(Key, Default, SendOpts) -> case lists:keysearch(Key, 1, SendOpts) of {value, {Key, Value}} -> Value; @@ -1867,40 +2004,19 @@ get_opt(Key, Default, SendOpts) -> Default end. -handle_send_trap(call, #state{type = master_agent} = S, - Notification, SendOpts) -> - SendOpts2 = - case lists:keymember(local_engine_id, 1, SendOpts) of - true -> - SendOpts; - false -> - [{local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID}|SendOpts] - end, - handle_send_trap(S, Notification, SendOpts2); -handle_send_trap(call, S, Notification, SendOpts) -> - SendOpts2 = - case lists:keymember(local_engine_id, 1, SendOpts) of - true -> - SendOpts; - false -> - %% subagent - - %% we don't need this now, eventually the trap send - %% request will reach the master-agent and then it - %% will look up the proper engine id. - [{local_engine_id, ignore}|SendOpts] - end, - handle_send_trap(S, Notification, SendOpts2); -handle_send_trap(_, S, Notification, SendOpts) -> - handle_send_trap(S, Notification, SendOpts). - handle_send_trap(S, Notification, SendOpts) -> - NotifyName = get_opt(name, "", SendOpts), - ContextName = get_opt(context, "", SendOpts), - Recv = get_opt(receiver, no_receiver, SendOpts), - Varbinds = get_opt(varbinds, [], SendOpts), - ExtraInfo = get_opt(extra, ?DEFAULT_NOTIF_EXTRA_INFO, SendOpts), + NotifyName = get_send_opt(name, "", SendOpts), + ContextName = get_send_opt(context, "", SendOpts), + Recv = get_send_opt(receiver, no_receiver, SendOpts), + Varbinds = get_send_opt(varbinds, [], SendOpts), + ExtraInfo = get_send_opt(extra, ?DEFAULT_NOTIF_EXTRA_INFO, SendOpts), LocalEngineID = - get_opt(local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID, SendOpts), + case lists:keysearch(local_engine_id, 1, SendOpts) of + {value, {local_engine_id, Value}} -> + Value; + false -> + local_engine_id(S) + end, handle_send_trap(S, Notification, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo). @@ -1908,11 +2024,11 @@ handle_send_trap(#state{type = Type} = S, Notification, NotifyName, ContextName, Recv, Varbinds, LocalEngineID, ExtraInfo) -> ?vtrace("handle_send_trap -> entry with" - "~n Agent type: ~p" - "~n TrapName: ~p" - "~n NotifyName: ~p" - "~n ContextName: ~p" - "~n LocalEngineID: ~p", + "~n Agent type: ~p" + "~n TrapName: ~p" + "~n NotifyName: ~p" + "~n ContextName: ~p" + "~n LocalEngineID: ~p", [Type, Notification, NotifyName, ContextName, LocalEngineID]), case snmpa_trap:construct_trap(Notification, Varbinds) of {ok, TrapRecord, VarList} -> @@ -2025,9 +2141,9 @@ do_handle_send_trap(S, TrapRec, NotifyName, ContextName, Recv, Varbinds, master_agent -> %% Send to main worker ?vtrace("do_handle_send_trap -> send to main worker",[]), - S#state.worker ! {send_trap, - TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, ExtraInfo}, + S#state.worker ! ?mk_send_trap_wreq(TrapRec, NotifyName, + ContextName, Recv, Vbs, + LocalEngineID, ExtraInfo), {ok, S#state{worker_state = busy}} end. @@ -2367,17 +2483,18 @@ handle_mib_of(MibServer, Oid) -> %% Func: process_msg/7 %% Returns: RePdu %%----------------------------------------------------------------- -process_msg(MibView, Vsn, Pdu, PduMS, Community, {Ip, Udp}, ContextName) -> +process_msg(MibView, Vsn, Pdu, PduMS, Community, {Ip, Udp}, ContextName, + GbMaxVBs) -> #pdu{request_id = ReqId} = Pdu, put(snmp_address, {tuple_to_list(Ip), Udp}), put(snmp_request_id, ReqId), put(snmp_community, Community), put(snmp_context, ContextName), ?vtrace("process ~p",[Pdu#pdu.type]), - process_pdu(Pdu, PduMS, Vsn, MibView). + process_pdu(Pdu, PduMS, Vsn, MibView, GbMaxVBs). process_pdu(#pdu{type='get-request', request_id = ReqId, varbinds=Vbs}, - _PduMS, Vsn, MibView) -> + _PduMS, Vsn, MibView, _GbMaxVBs) -> ?vtrace("get ~p",[ReqId]), Res = get_err(do_get(MibView, Vbs, false)), ?vtrace("get result: " @@ -2398,12 +2515,12 @@ process_pdu(#pdu{type='get-request', request_id = ReqId, varbinds=Vbs}, make_response_pdu(ReqId, ErrStatus, ErrIndex, Vbs, ResponseVarbinds); process_pdu(#pdu{type = 'get-next-request', request_id = ReqId, varbinds = Vbs}, - _PduMS, Vsn, MibView) -> + _PduMS, Vsn, MibView, _GbMaxVBs) -> ?vtrace("process get-next-request -> entry with" "~n ReqId: ~p" "~n Vbs: ~p" "~n MibView: ~p",[ReqId, Vbs, MibView]), - Res = get_err(do_get_next(MibView, Vbs)), + Res = get_err(do_get_next(MibView, Vbs, infinity)), ?vtrace("get-next result: " "~n ~p",[Res]), {ErrStatus, ErrIndex, ResVarbinds} = @@ -2420,11 +2537,15 @@ process_pdu(#pdu{type = 'get-next-request', request_id = ReqId, varbinds = Vbs}, "~n ~p",[ResponseVarbinds]), make_response_pdu(ReqId, ErrStatus, ErrIndex, Vbs, ResponseVarbinds); -process_pdu(#pdu{type = 'get-bulk-request',request_id = ReqId,varbinds = Vbs, - error_status = NonRepeaters, error_index = MaxRepetitions}, - PduMS, _Vsn, MibView)-> +process_pdu(#pdu{type = 'get-bulk-request', + request_id = ReqId, + varbinds = Vbs, + error_status = NonRepeaters, + error_index = MaxRepetitions}, + PduMS, _Vsn, MibView, GbMaxVBs) -> {ErrStatus, ErrIndex, ResponseVarbinds} = - get_err(do_get_bulk(MibView,NonRepeaters,MaxRepetitions,PduMS,Vbs)), + get_err(do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Vbs, + GbMaxVBs)), ?vtrace("get-bulk final result: " "~n Error status: ~p" "~n Error index: ~p" @@ -2433,7 +2554,7 @@ process_pdu(#pdu{type = 'get-bulk-request',request_id = ReqId,varbinds = Vbs, make_response_pdu(ReqId, ErrStatus, ErrIndex, Vbs, ResponseVarbinds); process_pdu(#pdu{type = 'set-request', request_id = ReqId, varbinds = Vbs}, - _PduMS, Vsn, MibView)-> + _PduMS, Vsn, MibView, _GbMaxVbs)-> Res = do_set(MibView, Vbs), ?vtrace("set result: " "~n ~p",[Res]), @@ -2490,7 +2611,8 @@ 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)]), MibView) of + case validate_next_v1( + do_get_next(MibView, [mk_next_oid(Vb)], infinity), MibView) of {noError, 0, [NVb]} -> validate_next_v1_2(Vbs, MibView, [NVb | Res]); {Error, Index, _OrgVb} -> @@ -2963,59 +3085,97 @@ validate_tab_res(_TooMany, [], Mfa, _Res, I) -> %% that this really matters, since many nexts across the same %% subagent must be considered to be very rare. %%----------------------------------------------------------------- -do_get_next(MibView, UnsortedVarbinds) -> - SortedVarbinds = oid_sort_varbindlist(UnsortedVarbinds), - next_loop_varbinds([], SortedVarbinds, MibView, [], []). -oid_sort_varbindlist(Vbs) -> +%% 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) -> +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], []); + 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, []); + NewVb = Vb#varbind{oid = VarOid, + value = 'NULL'}, + next_loop_varbinds([], [NewVb | Vbs], MibView, Res, [], + GbMaxVBs); {value, Type, Value} -> - NewVb = Vb#varbind{oid = VarOid, variabletype = Type, - value = Value}, - next_loop_varbinds([], Vbs, MibView, [NewVb | Res], []); + ?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); + 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, []); + 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, []) + Vbs, MibView, Res, [], GbMaxVBs) end; next_loop_varbinds({table, TableOid, ME, TabOids}, - [Vb | Vbs], MibView, Res, _LAVb) -> + [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) -> ?vt("next_loop_varbinds(table) -> entry with" "~n TableOid: ~p" "~n Vb: ~p", [TableOid, Vb]), @@ -3023,13 +3183,14 @@ next_loop_varbinds({table, TableOid, ME, TabOids}, {table, TableOid, TableRestOid, _ME} -> next_loop_varbinds({table, TableOid, ME, [{tab_oid(TableRestOid), Vb} | TabOids]}, - Vbs, MibView, Res, []); + 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, []); + next_loop_varbinds([], NewVbs, MibView, NewRes, [], + GbMaxVBs); {ErrorStatus, OrgIndex} -> ?vdebug("next loop varbinds: next varbind" "~n ErrorStatus: ~p" @@ -3039,7 +3200,7 @@ next_loop_varbinds({table, TableOid, ME, TabOids}, end end; next_loop_varbinds({table, TableOid, ME, TabOids}, - [], MibView, Res, _LAVb) -> + [], MibView, Res, _LAVb, GbMaxVBs) -> ?vt("next_loop_varbinds(table) -> entry with" "~n TableOid: ~p", [TableOid]), case get_next_table(ME, TableOid, TabOids, MibView) of @@ -3048,7 +3209,8 @@ next_loop_varbinds({table, TableOid, ME, TabOids}, "~n TabRes: ~p" "~n TabEndOfTabVbs: ~p", [TabRes, TabEndOfTabVbs]), NewRes = lists:append(TabRes, Res), - next_loop_varbinds([], TabEndOfTabVbs, MibView, NewRes, []); + next_loop_varbinds([], TabEndOfTabVbs, MibView, NewRes, [], + GbMaxVBs); {ErrorStatus, OrgIndex} -> ?vdebug("next loop varbinds: next table" "~n ErrorStatus: ~p" @@ -3057,7 +3219,7 @@ next_loop_varbinds({table, TableOid, ME, TabOids}, {ErrorStatus, OrgIndex, []} end; next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, - [Vb | Vbs], MibView, Res, _LAVb) -> + [Vb | Vbs], MibView, Res, _LAVb, GbMaxVBs) -> ?vt("next_loop_varbinds(subagent) -> entry with" "~n SAPid: ~p" "~n SAOid: ~p" @@ -3066,13 +3228,14 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, {subagent, _SubAgentPid, SAOid} -> next_loop_varbinds({subagent, SAPid, SAOid, [Vb | SAVbs]}, - Vbs, MibView, Res, []); + 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, []); + next_loop_varbinds([], NewVbs, MibView, NewRes, [], + GbMaxVBs); {noSuchName, OrgIndex} -> %% v1 reply, treat this Vb as endOfMibView, and try again %% for the others. @@ -3085,12 +3248,14 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, case lists:delete(EVb, SAVbs) of [] -> next_loop_varbinds([], [EndOfVb, Vb | Vbs], - MibView, Res, []); + MibView, Res, [], + GbMaxVBs); TryAgainVbs -> next_loop_varbinds({subagent, SAPid, SAOid, TryAgainVbs}, [EndOfVb, Vb | Vbs], - MibView, Res, []) + MibView, Res, [], + GbMaxVBs) end; false -> %% bad index from subagent @@ -3106,14 +3271,15 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, end end; next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, - [], MibView, Res, _LAVb) -> + [], 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, []); + next_loop_varbinds([], SAEndOfMibViewVbs, MibView, NewRes, [], + GbMaxVBs); {noSuchName, OrgIndex} -> %% v1 reply, treat this Vb as endOfMibView, and try again for %% the others. @@ -3124,11 +3290,13 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, value = {endOfMibView, NextOid}}, case lists:delete(EVb, SAVbs) of [] -> - next_loop_varbinds([], [EndOfVb], MibView, Res, []); + next_loop_varbinds([], [EndOfVb], MibView, Res, [], + GbMaxVBs); TryAgainVbs -> next_loop_varbinds({subagent, SAPid, SAOid, TryAgainVbs}, - [EndOfVb], MibView, Res, []) + [EndOfVb], MibView, Res, [], + GbMaxVBs) end; false -> %% bad index from subagent @@ -3141,12 +3309,15 @@ next_loop_varbinds({subagent, SAPid, SAOid, SAVbs}, [ErrorStatus,OrgIndex]), {ErrorStatus, OrgIndex, []} end; -next_loop_varbinds([], [], _MibView, Res, _LAVb) -> +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 from <~p,~p,~p>",[M,F,A]), + ?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) | @@ -3157,6 +3328,7 @@ try_get_instance(_Vb, #me{mfa = {M, F, A}, asn1_type = ASN1Type}) -> 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. @@ -3403,22 +3575,30 @@ next_oid(Oid) -> %%%----------------------------------------------------------------- %%% 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) -> - ?vtrace("do get bulk: start with" + +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", - [MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds]), + "~n Varbinds: ~p" + "~n GbMaxVBs: ~p", + [MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds, GbMaxVBs]), {NonRepVbs, RestVbs} = split_vbs(NonRepeaters, Varbinds, []), - ?vt("do get bulk -> split: " + ?vt("do_get_bulk -> split: " "~n NonRepVbs: ~p" "~n RestVbs: ~p", [NonRepVbs, RestVbs]), - case do_get_next(MibView, NonRepVbs) of - {noError, 0, UResNonRepVbs} -> - ?vt("do get bulk -> next: " + 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 @@ -3428,11 +3608,12 @@ do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) -> 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: " + ?vtrace("do_get_bulk -> encoded: " "~n SizeLeft: ~p" "~n Res: ~w", [SizeLeft, Res]), case (catch do_get_rep(SizeLeft, MibView, MaxRepetitions, - RestVbs, Res)) of + RestVbs, Res, + length(UResNonRepVbs), GbMaxVBs)) of {error, Idx, Reason} -> user_err("failed encoding varbind ~w:~n~p", [Idx, Reason]), @@ -3441,6 +3622,10 @@ do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) -> ?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]), @@ -3449,6 +3634,7 @@ do_get_bulk(MibView, NonRepeaters, MaxRepetitions, PduMS, Varbinds) -> Res when is_list(Res) -> {noError, 0, conv_res(Res)} end; + {ErrorStatus, Index, _} -> ?vdebug("do get bulk: " "~n ErrorStatus: ~p" @@ -3498,11 +3684,12 @@ enc_vbs(SizeLeft, Vbs) -> end, lists:foldl(Fun, {SizeLeft, []}, Vbs). -do_get_rep(Sz, MibView, MaxRepetitions, Varbinds, Res) +do_get_rep(Sz, MibView, MaxRepetitions, Varbinds, Res, GbNumVBs, GbMaxVBs) when MaxRepetitions >= 0 -> - do_get_rep(Sz, MibView, 0, MaxRepetitions, Varbinds, Res); -do_get_rep(Sz, MibView, _MaxRepetitions, Varbinds, Res) -> - do_get_rep(Sz, MibView, 0, 0, Varbinds, Res). + 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, []). @@ -3511,22 +3698,30 @@ conv_res([VbListOfBytes | T], Bytes) -> conv_res([], Bytes) -> Bytes. -do_get_rep(_Sz, _MibView, Max, Max, _, Res) -> +%% 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) -> +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) of + 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); + Res2 ++ Res, + GbNumVBs + length(Varbinds), GbMaxVBs); {endOfMibView, _NextVarbinds, _SizeLeft, Res2} -> ?vt("do_get_rep -> endOfMibView: " "~n Res2: ~p", [Res2]), @@ -3538,22 +3733,29 @@ do_get_rep(Sz, MibView, Count, Max, Varbinds, Res) -> {ErrorStatus, Index, []} end. -try_get_bulk(Sz, MibView, Varbinds) -> +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", [Sz]), - case do_get_next(MibView, Varbinds) of + "~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", []), - NextVarbinds = lists:keysort(#varbind.org_index, 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 -> error: " + ?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 -> " + {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), @@ -3564,9 +3766,9 @@ try_get_bulk(Sz, MibView, Varbinds) -> {endOfMibView, [], 0, Res} end; {ErrorStatus, Index, _} -> - ?vt("try get bulk: " + ?vt("try_get_bulk -> error: " "~n ErrorStatus: ~p" - "~n Index: ~p",[ErrorStatus, Index]), + "~n Index: ~p", [ErrorStatus, Index]), {ErrorStatus, Index} end. @@ -3707,9 +3909,8 @@ get_err({ErrC, ErrI, Vbs}) -> {get_err_i(ErrC), ErrI, Vbs}. get_err_i(noError) -> noError; -get_err_i(S) -> - ?vtrace("convert '~p' to 'genErr'",[S]), - genErr. +get_err_i(tooBig) -> tooBig; % OTP-9700 +get_err_i(ES) -> ?vtrace("convert ErrorStatus '~p' to 'genErr'", [ES]), genErr. v2err_to_v1err(noError) -> noError; v2err_to_v1err(noAccess) -> noSuchName; @@ -3935,6 +4136,7 @@ mapfoldl(F, Eas, Accu0, [Hd|Tail]) -> {Accu2,[R|Rs]}; mapfoldl(_F, _Eas, Accu, []) -> {Accu,[]}. + %%----------------------------------------------------------------- %% Runtime debugging of the agent. %%----------------------------------------------------------------- @@ -4001,6 +4203,18 @@ subagents_verbosity(_,_V) -> %% --------------------------------------------------------------------- +local_engine_id(#state{type = master_agent}) -> + ?DEFAULT_LOCAL_ENGINE_ID; +local_engine_id(_) -> + %% subagent - + %% we don't need this now, eventually the trap send + %% request will reach the master-agent and then it + %% will look up the proper engine id. + ignore. + + +%% --------------------------------------------------------------------- + handle_get_log_type(#state{net_if_mod = Mod}) when Mod =/= undefined -> case (catch Mod:get_log_type(get(net_if))) of @@ -4047,7 +4261,7 @@ handle_set_request_limit(_, _) -> {error, not_supported}. -agent_info(#state{worker = W, set_worker = SW}) -> +agent_info(#state{worker = W, set_worker = SW}) -> case (catch get_agent_info(W, SW)) of Info when is_list(Info) -> Info; @@ -4206,6 +4420,9 @@ get_multi_threaded(Opts) -> get_versions(Opts) -> get_option(versions, Opts, [v1,v2,v3]). +get_gb_max_vbs(Opts) -> + get_option(gb_max_vbs, Opts, infinity). + get_note_store_opt(Opts) -> get_option(note_store, Opts, []). diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index 4b88eb69f7..c17a6abbd7 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -424,7 +424,8 @@ target_addr_entry(Name, EngineId, TMask) -> target_addr_entry(Name, Ip, 162, TagList, - ParamsName, EngineId, TMask, 2048). + ParamsName, EngineId, + TMask, 2048). target_addr_entry(Name, Ip, @@ -435,7 +436,8 @@ target_addr_entry(Name, TMask, MaxMessageSize) -> target_addr_entry(Name, Ip, Udp, 1500, 3, TagList, - ParamsName, EngineId, TMask, MaxMessageSize). + ParamsName, EngineId, + TMask, MaxMessageSize). target_addr_entry(Name, Ip, @@ -448,7 +450,8 @@ target_addr_entry(Name, TMask, MaxMessageSize) -> target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp, - Timeout, RetryCount, TagList, ParamsName, + Timeout, RetryCount, TagList, + ParamsName, EngineId, TMask, MaxMessageSize). target_addr_entry(Name, diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl index a490a78f84..c435b519d9 100644 --- a/lib/snmp/src/agent/snmpa_internal.hrl +++ b/lib/snmp/src/agent/snmpa_internal.hrl @@ -22,9 +22,19 @@ -include_lib("snmp/src/app/snmp_internal.hrl"). --define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()). +%% The DEFAULT_LOCAL_ENGINE_ID macro can only be used by the master_agent!! +-define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()). -define(DEFAULT_NOTIF_EXTRA_INFO, {snmpa_default_notification_extra_info}). +%% -- Max number of VBs in a Get-BULK response -- +%% (( The default value, 1000, is *way* more )) +%% (( then there is room for in a normal pdu )) +%% (( (unless the max pdu size has been )) +%% (( cranked way up), so this value should )) +%% (( suffice as "infinity" without actually )) +%% (( causing memory issues for the VM ... )) +-define(DEFAULT_GB_MAX_VBS, 1000). + -define(snmpa_info(F, A), ?snmp_info("agent", F, A)). -define(snmpa_warning(F, A), ?snmp_warning("agent", F, A)). -define(snmpa_error(F, A), ?snmp_error("agent", F, A)). diff --git a/lib/snmp/src/agent/snmpa_local_db.erl b/lib/snmp/src/agent/snmpa_local_db.erl index d9d6e633de..df01091d53 100644 --- a/lib/snmp/src/agent/snmpa_local_db.erl +++ b/lib/snmp/src/agent/snmpa_local_db.erl @@ -1110,7 +1110,7 @@ table_func(is_set_ok, RowIndex, Cols, NameDb) -> table_func(set, RowIndex, Cols, NameDb) -> snmp_generic:table_set_row(NameDb, nofunc, - {snmp_generic, table_try_make_consistent}, + fun snmp_generic:table_try_make_consistent/3, RowIndex, Cols); diff --git a/lib/snmp/src/agent/snmpa_mib_lib.erl b/lib/snmp/src/agent/snmpa_mib_lib.erl index 078e681945..3c94cc8095 100644 --- a/lib/snmp/src/agent/snmpa_mib_lib.erl +++ b/lib/snmp/src/agent/snmpa_mib_lib.erl @@ -61,23 +61,23 @@ table_del_row({Tab, Db} = TabDb, Key) -> get_table(NameDb, FOI) -> (catch get_table(NameDb, FOI, [], [])). -get_table(NameDb, FOI, Oid, Acc) -> - case table_next(NameDb, Oid) of +get_table(NameDb, FOI, Key, Acc) -> + case table_next(NameDb, Key) of endOfTable -> ?vdebug("end of table",[]), {ok, lists:reverse(Acc)}; - Oid -> + Key -> %% Crap, circular ref - ?vinfo("cyclic reference: ~w -> ~w", [Oid,Oid]), - throw({error, {cyclic_db_reference, Oid, Acc}}); - NextOid -> - ?vtrace("get row for oid ~w", [NextOid]), - case table_get_row(NameDb, NextOid, FOI) of + ?vinfo("cyclic reference: ~w -> ~w", [Key, Key]), + throw({error, {cyclic_db_reference, Key, Acc}}); + NextKey -> + ?vtrace("get row for key ~w", [NextKey]), + case table_get_row(NameDb, NextKey, FOI) of undefined -> - throw({error, {invalid_rowindex, NextOid, Acc}}); + throw({error, {invalid_rowindex, NextKey, Acc}}); Row -> ?vtrace("row: ~w", [Row]), - get_table(NameDb, FOI, NextOid, [{NextOid, Row}|Acc]) + get_table(NameDb, FOI, NextKey, [{NextKey, Row}|Acc]) end end. diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index 14f62b12f3..0305e1fbec 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -32,6 +32,7 @@ -include("SNMP-MPD-MIB.hrl"). -include("SNMPv2-TM.hrl"). -include("SNMP-FRAMEWORK-MIB.hrl"). +-include("TRANSPORT-ADDRESS-MIB.hrl"). -define(VMODULE,"MPD"). -include("snmp_verbosity.hrl"). @@ -467,15 +468,10 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) -> _ -> %% 4.2.2.1.2 NIsReportable = snmp_misc:is_reportable_pdu(Type), - Val = inc(snmpUnknownPDUHandlers), ErrorInfo = - {#varbind{oid = ?snmpUnknownPDUHandlers, - variabletype = 'Counter32', - value = Val}, - SecName, - [{securityLevel, SecLevel}, - {contextEngineID, ContextEngineID}, - {contextName, ContextName}]}, + snmpUnknownPDUHandlers_ei(SecName, SecLevel, + ContextEngineID, + ContextName), case generate_v3_report_msg(MsgID, MsgSecurityModel, Data, LocalEngineID, @@ -506,6 +502,21 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) -> end end. +make_error_info(Variable, Oid, SecName, Opts) -> + Val = inc(Variable), + VB = #varbind{oid = Oid, + variabletype = 'Counter32', + value = Val}, + {VB, SecName, Opts}. + +snmpUnknownPDUHandlers_ei(SecName, SecLevel, + ContextEngineID, ContextName) -> + Opts = [{securityLevel, SecLevel}, + {contextEngineID, ContextEngineID}, + {contextName, ContextName}], + make_error_info(snmpUnknownPDUHandlers, + ?snmpUnknownPDUHandlers_instance, + SecName, Opts). get_security_module(?SEC_USM) -> snmpa_usm; @@ -981,12 +992,15 @@ generate_discovery_msg2(NoteStore, Pdu, discovery_note_timeout(Timeout) -> (Timeout div 100) + 1. -generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]}, +generate_discovery_msg(NoteStore, {TDomain, TAddress}, Pdu, ScopedPduBytes, ContextEngineID, ManagerEngineID, SecModel, SecName, SecLevelFlag, InitialUserName, ContextName, Timeout) -> + + {ok, {_Domain, Address}} = transform_taddr(TDomain, TAddress), + %% 7.1.7 ?vdebug("generate_discovery_msg -> 7.1.7 (~w)", [ManagerEngineID]), MsgID = generate_msg_id(), @@ -1027,7 +1041,7 @@ generate_discovery_msg(NoteStore, {?snmpUDPDomain, [A,B,C,D,U1,U2]}, %% Log(Packet), inc_snmp_out_vars(Pdu), ?vdebug("generate_discovery_msg -> done", []), - {Packet, {{A,B,C,D}, U1 bsl 8 + U2}}; + {Packet, Address}; Error -> throw(Error) @@ -1057,6 +1071,34 @@ generate_sec_discovery_msg(Message, SecModule, end. +transform_taddr(?snmpUDPDomain, TAddress) -> + transform_taddr(?transportDomainUdpIpv4, TAddress); +transform_taddr(?transportDomainUdpIpv4, [A, B, C, D, P1, P2]) -> + Domain = transportDomainUdpIpv4, + Addr = {A,B,C,D}, + Port = P1 bsl 8 + P2, + Address = {Addr, Port}, + {ok, {Domain, Address}}; +transform_taddr(?transportDomainUdpIpv4, BadAddr) -> + {error, {bad_transportDomainUdpIpv4_address, BadAddr}}; +transform_taddr(?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]) -> + Domain = transportDomainUdpIpv6, + Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, + Port = P1 bsl 8 + P2, + Address = {Addr, Port}, + {ok, {Domain, Address}}; +transform_taddr(?transportDomainUdpIpv6, BadAddr) -> + {error, {bad_transportDomainUdpIpv6_address, BadAddr}}; +transform_taddr(BadTDomain, TAddress) -> + case lists:member(BadTDomain, snmp_conf:all_tdomains()) of + true -> + {error, {unsupported_tdomain, BadTDomain, TAddress}}; + false -> + {error, {unknown_tdomain, BadTDomain, TAddress}} + end. + + process_taddrs(Dests) -> ?vtrace("process_taddrs -> entry with" "~n Dests: ~p", [Dests]), @@ -1066,46 +1108,44 @@ process_taddrs([], Acc) -> ?vtrace("process_taddrs -> entry when done with" "~n Acc: ~p", [Acc]), lists:reverse(Acc); - + %% v3 -process_taddrs([{{?snmpUDPDomain, [A,B,C,D,U1,U2]}, SecData} | T], Acc) -> +process_taddrs([{{TDomain, TAddress}, SecData} | T], Acc) -> ?vtrace("process_taddrs -> entry when v3 with" - "~n A: ~p" - "~n B: ~p" - "~n C: ~p" - "~n D: ~p" - "~n U1: ~p" - "~n U2: ~p" - "~n SecData: ~p", [A, B, C, D, U1, U2, SecData]), - Entry = {{snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, SecData}, - process_taddrs(T, [Entry | Acc]); -%% Bad v3 -process_taddrs([{{TDomain, TAddr}, _SecData} | T], Acc) -> - ?vtrace("process_taddrs -> entry when bad v3 with" - "~n TDomain: ~p" - "~n TAddr: ~p", [TDomain, TAddr]), - user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]), - process_taddrs(T, Acc); + "~n TDomain: ~p" + "~n TAddress: ~p" + "~n SecData: ~p", [TDomain, TAddress, SecData]), + case transform_taddr(TDomain, TAddress) of + {ok, DestAddr} -> + ?vtrace("process_taddrs -> transformed: " + "~n DestAddr: ~p", [DestAddr]), + Entry = {DestAddr, SecData}, + process_taddrs(T, [Entry | Acc]); + {error, Reason} -> + ?vinfo("Failed transforming v3 domain and address" + "~n Reason: ~p", [Reason]), + user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]), + process_taddrs(T, Acc) + end; %% v1 & v2 -process_taddrs([{?snmpUDPDomain, [A,B,C,D,U1,U2]} | T], Acc) -> +process_taddrs([{TDomain, TAddress} | T], Acc) -> ?vtrace("process_taddrs -> entry when v1/v2 with" - "~n A: ~p" - "~n B: ~p" - "~n C: ~p" - "~n D: ~p" - "~n U1: ~p" - "~n U2: ~p", [A, B, C, D, U1, U2]), - Entry = {snmpUDPDomain, {{A,B,C,D}, U1 bsl 8 + U2}}, - process_taddrs(T, [Entry | Acc]); -%% Bad v1 or v2 -process_taddrs([{TDomain, TAddr} | T], Acc) -> - ?vtrace("process_taddrs -> entry when bad v1/v2 with" - "~n TDomain: ~p" - "~n TAddr: ~p", [TDomain, TAddr]), - user_err("Bad TDomain/TAddr: ~w/~w", [TDomain, TAddr]), - process_taddrs(T, Acc); + "~n TDomain: ~p" + "~n TAddress: ~p", [TDomain, TAddress]), + case transform_taddr(TDomain, TAddress) of + {ok, DestAddr} -> + ?vtrace("process_taddrs -> transformed: " + "~n DestAddr: ~p", [DestAddr]), + Entry = DestAddr, + process_taddrs(T, [Entry | Acc]); + {error, Reason} -> + ?vinfo("Failed transforming v1/v2 domain and address: " + "~n Reason: ~p", [Reason]), + user_err("Bad TDomain/TAddress: ~w/~w", [TDomain, TAddress]), + process_taddrs(T, Acc) + end; process_taddrs(Crap, Acc) -> - throw({error, {taddrs_crap, Crap, Acc}}). + throw({error, {bad_taddrs, Crap, Acc}}). mk_v1_v2_packet_list(To, Packet, Len, Pdu) -> diff --git a/lib/snmp/src/agent/snmpa_set_lib.erl b/lib/snmp/src/agent/snmpa_set_lib.erl index 191029f6db..9f355855b4 100644 --- a/lib/snmp/src/agent/snmpa_set_lib.erl +++ b/lib/snmp/src/agent/snmpa_set_lib.erl @@ -143,8 +143,8 @@ consistency_check(Varbinds) -> consistency_check(Varbinds, []). consistency_check([{TableOid, TableVbs} | Varbinds], Done) -> ?vtrace("consistency_check -> entry with" - "~n TableOid: ~p" - "~n TableVbs: ~p",[TableOid,TableVbs]), + "~n TableOid: ~p" + "~n TableVbs: ~p", [TableOid, TableVbs]), TableOpsWithShortOids = deletePrefixes(TableOid, TableVbs), [#ivarbind{mibentry = MibEntry}|_] = TableVbs, case is_set_ok_table(MibEntry, TableOpsWithShortOids) of @@ -158,7 +158,7 @@ consistency_check([{TableOid, TableVbs} | Varbinds], Done) -> end; consistency_check([IVarbind | Varbinds], Done) -> ?vtrace("consistency_check -> entry with" - "~n IVarbind: ~p",[IVarbind]), + "~n IVarbind: ~p", [IVarbind]), #ivarbind{varbind = Varbind, mibentry = MibEntry} = IVarbind, #varbind{value = Value, org_index = OrgIndex} = Varbind, case is_set_ok_variable(MibEntry, Value) of @@ -358,32 +358,39 @@ make_value_a_correct_value(Value, ASN1Type, Mfa) -> %% Runtime debug support %%----------------------------------------------------------------- -% XXX: This function match on the exakt return codes from EXIT -% messages. As of this writing it was not decided if this is -% the right way so don't blindly do things this way. -% -% We fake a real EXIT signal as the return value because the -% result is passed to the function snmpa_agent:validate_err() -% that expect it. +%% XYZ: This function match on the exakt return codes from EXIT +%% messages. As of this writing it was not decided if this is +%% the right way so don't blindly do things this way. +%% +%% We fake a real EXIT signal as the return value because the +%% result is passed to the function snmpa_agent:validate_err() +%% that expect it. dbg_apply(M,F,A) -> - Result = - case get(verbosity) of - false -> - (catch apply(M,F,A)); - _ -> - ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]), - Res = (catch apply(M,F,A)), - ?vlog("~n returned: ~p", [Res]), - Res - end, - case Result of + case maybe_verbose_apply(M, F, A) of + %% <Future proofing> + %% As of R15 we get extra info containing, + %% among other things, line numbers. + {'EXIT', {undef, [{M, F, A, _} | _]}} -> + {'EXIT', {hook_undef, {M, F, A}}}; + {'EXIT', {function_clause, [{M, F, A, _} | _]}} -> + {'EXIT', {hook_function_clause, {M, F, A}}}; + + %% This is really overkill, but just to be on the safe side... + {'EXIT', {undef, {M, F, A, _}}} -> + {'EXIT', {hook_undef, {M, F, A}}}; + {'EXIT', {function_clause, {M, F, A, _}}} -> + {'EXIT', {hook_function_clause, {M, F, A}}}; + %% </Future proofing> + + + %% Old format format for compatibility {'EXIT', {undef, [{M, F, A} | _]}} -> {'EXIT', {hook_undef, {M, F, A}}}; {'EXIT', {function_clause, [{M, F, A} | _]}} -> {'EXIT', {hook_function_clause, {M, F, A}}}; - % XXX: Old 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}}} -> @@ -393,3 +400,15 @@ dbg_apply(M,F,A) -> Result end. + +maybe_verbose_apply(M, F, A) -> + case get(verbosity) of + false -> + (catch apply(M,F,A)); + _ -> + ?vlog("~n apply: ~w,~w,~p~n", [M,F,A]), + Res = (catch apply(M,F,A)), + ?vlog("~n returned: ~p", [Res]), + Res + end. + diff --git a/lib/snmp/src/agent/snmpa_supervisor.erl b/lib/snmp/src/agent/snmpa_supervisor.erl index 5ef5914e18..7a9c214e0d 100644 --- a/lib/snmp/src/agent/snmpa_supervisor.erl +++ b/lib/snmp/src/agent/snmpa_supervisor.erl @@ -176,8 +176,8 @@ init([AgentType, Opts]) -> "~n AgentType: ~p" "~n Opts: ~p", [AgentType, Opts]), - put(sname, asup), - put(verbosity,get_verbosity(Opts)), + put(sname, asup), + put(verbosity, get_verbosity(Opts)), ?vlog("starting",[]), @@ -203,7 +203,12 @@ init([AgentType, Opts]) -> Vsns = get_opt(versions, Opts, [v1,v2,v3]), ?vdebug("[agent table] store versions: ~p",[Vsns]), ets:insert(snmp_agent_table, {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}), + %% -- DB-directory -- DbDir = get_opt(db_dir, Opts), ?vdebug("[agent table] store db_dir: ~n ~p",[DbDir]), @@ -377,7 +382,8 @@ init([AgentType, Opts]) -> {versions, Vsns}, {net_if, NiOpts}, {mib_server, MibsOpts}, - {note_store, NsOpts}| + {note_store, NsOpts}, + {gb_max_vbs, GbMaxVBs} | get_opt(master_agent_options, Opts, [])], AgentSpec = @@ -542,6 +548,32 @@ get_verbosity(Opts) -> get_agent_type(Opts) -> get_opt(agent_type, Opts, master). + +%% We validate this option! This should really be done for all +%% options, but it is beyond the scope of this ticket, OTP-9700. + +get_gb_max_vbs(Opts) -> + Validate = + fun(GbMaxVBs) + when ((is_integer(GbMaxVBs) andalso (GbMaxVBs > 0)) orelse + (GbMaxVBs =:= infinity)) -> + ok; + (_) -> + error + end, + get_option(gb_max_vbs, ?DEFAULT_GB_MAX_VBS, Validate, Opts). + +get_option(Key, Default, Validate, Opts) + when is_list(Opts) andalso is_function(Validate) -> + Value = get_opt(Key, Opts, Default), + case Validate(Value) of + ok -> + Value; + error -> + exit({bad_option, Key, Value}) + end. + + get_opt(Key, Opts) -> snmp_misc:get_option(Key, Opts). diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index 567de020c0..994d926224 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -352,11 +352,26 @@ send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, ExtraInfo, NetIf) -> send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, ExtraInfo, NetIf). +%% The agent normally does not care about the result, +%% but since it can be usefull when debugging, add +%% some info when we fail to send the trap(s). send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, ExtraInfo, NetIf) -> - (catch do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, ExtraInfo, NetIf)). - + try + begin + do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, + LocalEngineID, ExtraInfo, NetIf) + end + catch + T:E -> + Info = [{args, [TrapRec, NotifyName, ContextName, + Recv, Vbs, LocalEngineID, ExtraInfo, NetIf]}, + {tag, T}, + {err, E}, + {stacktrace, erlang:get_stacktrace()}], + {error, {failed_sending_trap, Info}} + end. + do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, ExtraInfo, NetIf) -> VarbindList = make_varbind_list(Vbs), @@ -379,8 +394,13 @@ send_discovery(TargetName, Record, ContextName, Vbs, NetIf, ExtraInfo) -> get_values(VariablesWithType) -> {Order, Varbinds} = extract_order(VariablesWithType, 1), + ?vtrace("get_values -> " + "~n Order: ~p" + "~n Varbinds: ~p", [Order, Varbinds]), case snmpa_agent:do_get(snmpa_acm:get_root_mib_view(), Varbinds, true) of {noError, _, NewVarbinds} -> + ?vtrace("get_values -> values retrieved" + "~n NewVarbinds: ~p", [NewVarbinds]), %% NewVarbinds is the result of: %% first a reverse, then a sort on the oid field and finally %% a reverse during the get-processing so we need to re-sort diff --git a/lib/snmp/src/agent/snmpa_vacm.erl b/lib/snmp/src/agent/snmpa_vacm.erl index 892dc265f1..dadcf32543 100644 --- a/lib/snmp/src/agent/snmpa_vacm.erl +++ b/lib/snmp/src/agent/snmpa_vacm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% Copyright Ericsson AB 1999-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -62,6 +62,13 @@ get_mib_view(ViewType, SecModel, SecName, SecLevel, ContextName) -> %% Follows the procedure in rfc2275 auth(ViewType, SecModel, SecName, SecLevel, ContextName) -> + ?vtrace("auth -> entry with" + "~n ViewType: ~p" + "~n SecModel: ~p" + "~n SecName: ~p" + "~n SecLevel: ~p" + "~n ContextName: ~p", + [ViewType, SecModel, SecName, SecLevel, ContextName]), % 3.2.1 - Check that the context is known to us ?vdebug("check that the context (~p) is known to us",[ContextName]), case snmp_view_based_acm_mib:vacmContextTable(get, ContextName, @@ -74,7 +81,7 @@ auth(ViewType, SecModel, SecName, SecLevel, ContextName) -> end, % 3.2.2 - Check that the SecModel and SecName is valid ?vdebug("check that SecModel (~p) and SecName (~p) is valid", - [SecModel,SecName]), + [SecModel, SecName]), GroupName = case snmp_view_based_acm_mib:get(vacmSecurityToGroupTable, [SecModel, length(SecName) | SecName], @@ -111,6 +118,8 @@ check_auth(Res) -> {ok, Res}. %% key in the table >= ViewIndex. %%----------------------------------------------------------------- get_mib_view(ViewName) -> + ?vtrace("get_mib_view -> entry with" + "~n ViewName: ~p", [ViewName]), ViewKey = [length(ViewName) | ViewName], case snmp_view_based_acm_mib:table_next(vacmViewTreeFamilyTable, ViewKey) of @@ -202,6 +211,13 @@ backup(BackupDir) -> %% Ret: {ok, ViewName} | {error, Reason} get_view_name(ViewType, GroupName, ContextName, SecModel, SecLevel) -> + ?vtrace("get_view_name -> entry with" + "~n ViewType: ~p" + "~n GroupName: ~p" + "~n ContextName: ~p" + "~n SecModel: ~p" + "~n SecLevel: ~p", + [ViewType, GroupName, ContextName, SecModel, SecLevel]), GroupKey = [length(GroupName) | GroupName], case get_access_row(GroupKey, ContextName, SecModel, SecLevel) of undefined -> @@ -266,9 +282,10 @@ dump_table(true) -> dump_table(_) -> ok. + dump_table() -> [{_, FName}] = ets:lookup(snmp_agent_table, snmpa_vacm_file), - TmpName = FName ++ ".tmp", + TmpName = unique_table_name(FName), case ets:tab2file(snmpa_vacm, TmpName) of ok -> case file:rename(TmpName, FName) of @@ -283,6 +300,35 @@ dump_table() -> [FName, Reason]) end. +%% This little thing is an attempt to create a "unique" filename +%% in order to minimize the risk of two processes at the same +%% time dumping the table. +unique_table_name(Pre) -> + %% We want something that is guaranteed to be unique, + %% therefor we use erlang:now() instead of os:timestamp() + unique_table_name(Pre, erlang:now()). + +unique_table_name(Pre, {_A, _B, C} = Now) -> + {Date, Time} = calendar:now_to_datetime(Now), + {YYYY, MM, DD} = Date, + {Hour, Min, Sec} = Time, + FormatDate = + io_lib:format("~.4w~.2.0w~.2.0w_~.2.0w~.2.0w~.2.0w_~w", + [YYYY, MM, DD, Hour, Min, Sec, round(C/1000)]), + unique_table_name2(Pre, FormatDate). + +unique_table_name2(Pre, FormatedDate) -> + PidPart = unique_table_name_pid(), + lists:flatten(io_lib:format("~s.~s~s.tmp", [Pre, PidPart, FormatedDate])). + +unique_table_name_pid() -> + case string:tokens(pid_to_list(self()), [$<,$.,$>]) of + [A, B, C] -> + A ++ B ++ C ++ "."; + _ -> + "" + end. + %%----------------------------------------------------------------- %% Alg. diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index 5deb40be0f..254e697039 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2011. All Rights Reserved. +%% Copyright Ericsson AB 1999-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -22,86 +22,160 @@ %% ----- U p g r a d e ------------------------------------------------------- [ - {"4.19", + {"4.21.5", [ {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, - {load_module, snmpa_usm, soft_purge, soft_purge, []}, - {load_module, snmpm_usm, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.4", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.3", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.2", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.1", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []} + ] + }, + {"4.20.1", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, + [snmpm_server, snmpm_config, snmp_config]}, {load_module, snmp_conf, soft_purge, soft_purge, []}, - {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmp_misc, soft_purge, soft_purge, []}, {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmpa_trap, soft_purge, soft_purge, - [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, - {load_module, snmpa_acm, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd, snmp_target_mib]}, - {load_module, snmpa_conf, soft_purge, soft_purge, - [snmp_notification_mib]}, - {load_module, snmp_notification_mib, soft_purge, soft_purge, - [snmp_conf, snmp_target_mib]}, - {load_module, snmp_community_mib, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, - [snmp_conf]}, - {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, - {update, snmpa_net_if, soft, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd]}, - {update, snmpa_agent, soft, soft_purge, soft_purge, - [snmpa_acm, snmpa_mpd, snmpa_trap]} + {load_module, snmpm_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config, snmpm_config]}, + {load_module, snmpa_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config]}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, + {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, + {update, snmpm_server, soft, soft_purge, soft_purge, + [snmpm_net_if, snmpm_mpd, snmpm_config]}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpm_mpd, snmpm_config]} ] }, - {"4.18", + {"4.20", [ {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, - {load_module, snmpa_usm, soft_purge, soft_purge, []}, - {load_module, snmpm_usm, soft_purge, soft_purge, []}, - {load_module, snmp_misc, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, + [snmpa_mib_lib, snmp_conf]}, + {load_module, snmpm, soft_purge, soft_purge, + [snmpm_server, snmpm_config, snmp_config]}, {load_module, snmp_conf, soft_purge, soft_purge, []}, - {load_module, snmp_config, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmpa_conf, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmpa_vacm, soft_purge, soft_purge, []}, - {load_module, snmpa_trap, soft_purge, soft_purge, - [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, - {load_module, snmpa_acm, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd, snmp_target_mib]}, - {load_module, snmpa, soft_purge, soft_purge, - [snmp_community_mib, - snmp_framework_mib, - snmp_standard_mib, - snmp_target_mib, - snmp_user_based_sm_mib, - snmp_view_based_acm_mib]}, - {load_module, snmp_notification_mib, soft_purge, soft_purge, - [snmp_conf, snmp_target_mib, snmpa_mib_lib]}, - {load_module, snmp_community_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_framework_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_standard_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_target_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, - [snmpa_mib_lib, snmpa_vacm]}, - {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, - - {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, - - {update, snmpa_net_if, soft, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd]}, - {update, snmpa_agent, soft, soft_purge, soft_purge, - [snmpa_acm, snmpa_mpd, snmpa_trap]} + {load_module, snmp_config, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config, snmpm_config]}, + {load_module, snmpa_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config]}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, + {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, + {update, snmpm_server, soft, soft_purge, soft_purge, + [snmpm_net_if, snmpm_mpd, snmpm_config]}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpm_mpd, snmpm_config]} ] } ], @@ -109,88 +183,159 @@ %% ------D o w n g r a d e --------------------------------------------------- [ - {"4.19", + {"4.21.5", [ {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, - {load_module, snmpa_usm, soft_purge, soft_purge, []}, - {load_module, snmpm_usm, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, - {load_module, snmp_conf, soft_purge, soft_purge, []}, - {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmp_misc, soft_purge, soft_purge, []}, - {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmpa_trap, soft_purge, soft_purge, - [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, - {load_module, snmpa_acm, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd, snmp_target_mib]}, - {load_module, snmpa_conf, soft_purge, soft_purge, - [snmp_notification_mib]}, - {load_module, snmp_notification_mib, soft_purge, soft_purge, - [snmp_conf, snmp_target_mib]}, - {load_module, snmp_community_mib, soft_purge, soft_purge, []}, - {load_module, snmp_target_mib, soft_purge, soft_purge, - [snmp_conf]}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.4", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.3", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21.2", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, - {update, snmpa_net_if, soft, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd]}, - {update, snmpa_agent, soft, soft_purge, soft_purge, - [snmpa_acm, snmpa_mpd, snmpa_trap]} + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []} ] }, - {"4.18", + {"4.21.1", [ {load_module, snmpa, soft_purge, soft_purge, []}, - {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, - {load_module, snmpa_usm, soft_purge, soft_purge, []}, - {load_module, snmpm_usm, soft_purge, soft_purge, []}, - {load_module, snmp_misc, soft_purge, soft_purge, []}, - {load_module, snmp_log, soft_purge, soft_purge, []}, - {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmpa_mib_lib]}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []} + ] + }, + {"4.21", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, []}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []} + ] + }, + {"4.20.1", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, + [snmpm_server, snmpm_config, snmp_config]}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_config, soft_purge, soft_purge, []}, + {load_module, snmpm_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config, snmpm_config]}, + {load_module, snmpa_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config]}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, + {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, + {update, snmpm_server, soft, soft_purge, soft_purge, + [snmpm_net_if, snmpm_mpd, snmpm_config]}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpm_mpd, snmpm_config]} + ] + }, + {"4.20", + [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, + {update, snmpa_supervisor, soft, soft_purge, soft_purge, []}, + + {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_set_lib, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, []}, + {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, []}, + {load_module, snmp_target_mib, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmpm, soft_purge, soft_purge, + [snmpm_server, snmpm_config, snmp_config]}, {load_module, snmp_conf, soft_purge, soft_purge, []}, - {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmp_config, soft_purge, soft_purge, []}, - {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, - {load_module, snmpa_vacm, soft_purge, soft_purge, []}, - {load_module, snmpa_trap, soft_purge, soft_purge, - [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, - {load_module, snmpa_acm, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd, snmp_target_mib]}, - {load_module, snmpa, soft_purge, soft_purge, - [snmp_community_mib, - snmp_framework_mib, - snmp_standard_mib, - snmp_target_mib, - snmp_user_based_sm_mib, - snmp_view_based_acm_mib]}, - {load_module, snmp_notification_mib, soft_purge, soft_purge, - [snmp_conf, snmp_target_mib, snmpa_mib_lib]}, - {load_module, snmp_community_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_framework_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_standard_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_target_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_user_based_sm_mib, soft_purge, soft_purge, - [snmpa_mib_lib]}, - {load_module, snmp_view_based_acm_mib, soft_purge, soft_purge, - [snmpa_mib_lib, snmpa_vacm]}, - {load_module, snmpa_mib_lib, soft_purge, soft_purge, []}, - - {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, - {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, - - {update, snmpa_net_if, soft, soft_purge, soft_purge, - [snmp_conf, snmpa_mpd]}, - {update, snmpa_agent, soft, soft_purge, soft_purge, - [snmpa_acm, snmpa_mpd, snmpa_trap]} + {load_module, snmpm_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config, snmpm_config]}, + {load_module, snmpa_mpd, soft_purge, soft_purge, + [snmp_conf, snmp_config]}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_config]}, + {update, snmp_note_store, soft, soft_purge, soft_purge, []}, + {load_module, snmp_generic_mnesia, soft_purge, soft_purge, []}, + {update, snmpa_local_db, soft, soft_purge, soft_purge, []}, + {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mpd]}, + {update, snmpm_config, soft, soft_purge, soft_purge, [snmp_conf]}, + {update, snmpm_server, soft, soft_purge, soft_purge, + [snmpm_net_if, snmpm_mpd, snmpm_config]}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpm_mpd, snmpm_config]} ] } ] diff --git a/lib/snmp/src/compile/Makefile b/lib/snmp/src/compile/Makefile index 0ceaf276a6..627af6f185 100644 --- a/lib/snmp/src/compile/Makefile +++ b/lib/snmp/src/compile/Makefile @@ -45,11 +45,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/snmp-$(VSN) include modules.mk -ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%) - -ERL_FILES = $(MODULES:%=%.erl) - -TARGET_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) $(ESCRIPT_BIN) +ESCRIPT_BIN = $(ESCRIPT_SRC:%.src=$(BIN)/%) +ERL_FILES = $(MODULES:%=%.erl) +EBIN_FILES = $(MODULES:%=$(EBIN)/%.$(EMULATOR)) +TARGET_FILES = $(EBIN_FILES) $(ESCRIPT_BIN) GENERATED_PARSER = $(PARSER_MODULE:%=%.erl) @@ -125,7 +124,7 @@ release_spec: opt $(INSTALL_DIR) $(RELSYSDIR)/src/compiler $(INSTALL_DATA) $(ESCRIPT_SRC) $(PARSER_SRC) $(ERL_FILES) $(INTERNAL_HRL_FILES) $(RELSYSDIR)/src/compiler $(INSTALL_DIR) $(RELSYSDIR)/ebin - $(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)/ebin + $(INSTALL_DATA) $(EBIN_FILES) $(RELSYSDIR)/ebin $(INSTALL_DIR) $(RELSYSDIR)/bin $(INSTALL_SCRIPT) $(ESCRIPT_BIN) $(RELSYSDIR)/bin diff --git a/lib/snmp/src/compile/depend.mk b/lib/snmp/src/compile/depend.mk index f7084f8bcd..3ee8dc4bec 100644 --- a/lib/snmp/src/compile/depend.mk +++ b/lib/snmp/src/compile/depend.mk @@ -44,6 +44,6 @@ $(EBIN)/snmpc_mib_gram.$(EMULATOR): \ ../../include/snmp_types.hrl \ snmpc_mib_gram.erl -$(BIN)/snmpc: snmpc.src +$(BIN)/snmpc: snmpc.src ../../vsn.mk $(PERL) -p -e 's?%VSN%?$(VSN)? ' < $< > $@ chmod 755 $@ diff --git a/lib/snmp/src/compile/snmpc.erl b/lib/snmp/src/compile/snmpc.erl index 195c238184..5e6b81f1ec 100644 --- a/lib/snmp/src/compile/snmpc.erl +++ b/lib/snmp/src/compile/snmpc.erl @@ -108,6 +108,7 @@ compile(FileName) -> %% {i, [import_dir_string()]} ["./"] %% {il, [import_lib_dir_string()]} [] %% {warnings, bool()} true +%% warnings_as_errors %% {outdir, string()} "./" %% description %% reference @@ -199,6 +200,8 @@ get_options([reference|Opts], Formats, Args) -> get_options(Opts, ["~n reference"|Formats], Args); get_options([{warnings, Val}|Opts], Formats, Args) -> get_options(Opts, ["~n warnings: ~w"|Formats], [Val|Args]); +get_options([warnings_as_errors|Opts], Formats, Args) -> + get_options(Opts, ["~n warnings_as_errors"|Formats], Args); get_options([{verbosity, Val}|Opts], Formats, Args) -> get_options(Opts, ["~n verbosity: ~w"|Formats], [Val|Args]); get_options([imports|Opts], Formats, Args) -> @@ -261,6 +264,8 @@ check_options([{group_check, Atom} | T]) when is_atom(Atom) -> check_options([{warnings, Bool} | T]) -> check_bool(warnings, Bool), check_options(T); +check_options([warnings_as_errors | T]) -> + check_options(T); check_options([{db, volatile} | T]) -> check_options(T); check_options([{db, persistent} | T]) -> @@ -331,6 +336,9 @@ get_agent_capabilities(Options) -> get_module_compliance(Options) -> get_bool_option(module_compliance, Options). +get_warnings_as_errors(Options) -> + lists:member(warnings_as_errors, Options). + get_relaxed_row_name_assign_check(Options) -> lists:member(relaxed_row_name_assign_check, Options). @@ -409,6 +417,7 @@ init(From, MibFileName, Options) -> put(reference, get_reference(Options)), put(agent_capabilities, get_agent_capabilities(Options)), put(module_compliance, get_module_compliance(Options)), + put(warnings_as_errors, get_warnings_as_errors(Options)), File = filename:rootname(MibFileName, ".mib"), put(filename, filename:basename(File ++ ".mib")), R = case catch c_impl(File) of diff --git a/lib/snmp/src/compile/snmpc.src b/lib/snmp/src/compile/snmpc.src index 5f9b154bfa..9d1af42764 100644 --- a/lib/snmp/src/compile/snmpc.src +++ b/lib/snmp/src/compile/snmpc.src @@ -46,11 +46,12 @@ agent_capabilities = false, module, no_defaults = false, - relaxed_row_name_assigne_check = false, + relaxed_row_name_assign_check = false, %% The default verbosity (silence) will be filled in %% during argument processing. verbosity, - warnings = false + warnings = false, + warnings_as_errors = false }). @@ -73,7 +74,8 @@ %% --rrnac %% --version %% --verbosity V -%% --warnings +%% --warnings | --W +%% --Werror | --wae | --warnings_as_errors main(Args) when is_list(Args) -> case (catch process_args(Args)) of ok -> @@ -152,11 +154,12 @@ mk_mib_options(#state{outdir = OutDir, agent_capabilities = AC, module = Mod, no_defaults = ND, - relaxed_row_name_assigne_check = RRNAC, + relaxed_row_name_assign_check = RRNAC, %% The default verbosity (silence) will be filled in %% during argument processing. verbosity = V, - warnings = W}) -> + warnings = W, + warnings_as_errors = WAE}) -> [{outdir, OutDir}, {db, DB}, {i, IDs}, @@ -178,7 +181,8 @@ mk_mib_options(#state{outdir = OutDir, maybe_option(Imp, imports) ++ maybe_option(MI, module_identity) ++ maybe_option(MC, module_compliance) ++ - maybe_option(AC, agent_capabilities). + maybe_option(AC, agent_capabilities) ++ + maybe_option(WAE, warnings_as_errors). maybe_option(true, Opt) -> [Opt]; maybe_option(_, _) -> []. @@ -217,7 +221,10 @@ process_args([], #state{verbosity = Verbosity0, file = MIB} = State) -> process_args(["--help"|_Args], _State) -> ok; process_args(["--version"|_Args], #state{version = Version, mfv = MFV} = _State) -> - {ok, lists:flatten(io_lib:format("snmpc ~s (~s)", [Version, MFV]))}; + OtpVersion = otp_release(), + {ok, lists:flatten( + io_lib:format("snmpc ~s [Mib format version ~s] (OTP ~s)", + [Version, MFV, OtpVersion]))}; process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State) when (V =:= undefined) -> Verbosity = list_to_atom(Verbosity0), @@ -230,6 +237,8 @@ process_args(["--verbosity", Verbosity0|Args], #state{verbosity = V} = State) process_args(["--verbosity"|_Args], #state{verbosity = V}) when (V =/= undefined) -> e(lists:flatten(io_lib:format("Verbosity already set to ~w", [V]))); +process_args(["--W"|Args], State) -> + process_args(Args, State#state{warnings = true}); process_args(["--warnings"|Args], State) -> process_args(Args, State#state{warnings = true}); process_args(["--o", Dir|Args], State) -> @@ -291,7 +300,13 @@ process_args(["--mod"|_Args], #state{module = M}) process_args(["--nd"|Args], State) -> process_args(Args, State#state{no_defaults = true}); process_args(["--rrnac"|Args], State) -> - process_args(Args, State#state{relaxed_row_name_assigne_check = true}); + process_args(Args, State#state{relaxed_row_name_assign_check = true}); +process_args(["--Werror"|Args], State) -> + process_args(Args, State#state{warnings_as_errors = true}); +process_args(["--wae"|Args], State) -> + process_args(Args, State#state{warnings_as_errors = true}); +process_args(["--warnings_as_errors"|Args], State) -> + process_args(Args, State#state{warnings_as_errors = true}); process_args([MIB], State) -> Ext = filename:extension(MIB), if @@ -326,7 +341,7 @@ usage() -> "~n --verbosity <verbosity> - Print debug info." "~n verbosity = trace | debug | log | info | silence" "~n Defaults to silence." - "~n --warnings - Print warning messages." + "~n --warnings | --W - Print warning messages." "~n --o <output dir> - The output dir." "~n Defaults to current working dir." "~n --i <include dir> - Add this dir to the list of dirs that will be" @@ -334,16 +349,19 @@ usage() -> "~n The current workin dir will always be included. " "~n --il <include_lib dir> - Add this dir to the list of dirs that will be" "~n searched for imported (compiled) MIB files." - "~n It assumes that the first element in the dir name" - "~n correspond to an OTP application. For example snmp/mibs/" - "~n The current workin dir and the <snmp-home>/priv/mibs " + "~n It assumes that the first element in the dir " + "~n name correspond to an OTP application. " + "~n For example snmp/mibs/ " + "~n The current workin dir and the " + "~n <snmp-home>/priv/mibs " "~n are always listed last the includ path. " "~n --db <DB> - Database to used for the default instrumentation." "~n Defaults to volatile." - "~n --sgc - This option (skip group check), if present, disables " - "~n the \"group check\" of the mib compiler. " - "~n That is, should the OBJECT-GROUP and the NOTIFICATION-GROUP " - "~n macro(s) be checked for correctness or not. " + "~n --sgc - This option (skip group check), if present, " + "~n disables the \"group check\" of the mib compiler. " + "~n That is, should the OBJECT-GROUP and the " + "~n NOTIFICATION-GROUP macro(s) be checked for " + "~n correctness or not. " "~n By default the check is done. " "~n --dep - Keep deprecated definition(s)." "~n If not specified the compiler will ignore" @@ -354,23 +372,27 @@ usage() -> "~n --mi - The MODULE-IDENTITY field will be included." "~n --mc - The MODULE-COMPLIANCE field will be included." "~n --ac - The AGENT-CAPABILITIES field will be included." - "~n --mod <module> - The module which implements all the instrumentation" - "~n functions. " + "~n --mod <module> - The module which implements all the " + "~n instrumentation functions. " "~n The name of all instrumentation functions must" "~n be the same as the corresponding managed object" "~n it implements." - "~n --nd - The default instrumentation functions will *not* be used" - "~n if a managed object have no instrumentation function. " - "~n Instead this will be reported as an error, and the " - "~n compilation aborts. " - "~n --rrnac - This option, if present, specifies that the row name " - "~n assign check shall not be done strictly according to" - "~n the SMI (which allows only the value 1). " - "~n With this option, all values greater than zero is allowed" - "~n (>= 1). This means that the error will be converted to " + "~n --nd - The default instrumentation functions will *not* " + "~n be used if a managed object have no " + "~n instrumentation function. Instead this will be " + "~n reported as an error, and the compilation aborts. " + "~n --rrnac - This option, if present, specifies that the row " + "~n name assign check shall not be done strictly " + "~n according to the SMI (which allows only the " + "~n value 1). With this option, all values greater " + "~n than zero is allowed (>= 1). " + "~n This means that the error will be converted to " "~n a warning. " - "~n By default it is not included, but if this option is " - "~n present it will be. " + "~n By default it is not included, but if this " + "~n option is present it will be. " + "~n --wae | --Werror - Warnings as errors. " + "~n Indicates that warnings shall be treated as " + "~n errors. " "~n " "~n", []), halt(1). @@ -379,3 +401,16 @@ usage() -> e(Reason) -> throw({error, Reason}). +otp_release() -> + system_info(otp_release, string). + + +system_info(Tag, Type) -> + case (catch erlang:system_info(Tag)) of + {'EXIT', _} -> + "-"; + Info when is_list(Info) andalso (Type =:= string) -> + Info; + Info -> + lists:flatten(io_lib:format("~w", [Info])) + end. diff --git a/lib/snmp/src/compile/snmpc_lib.erl b/lib/snmp/src/compile/snmpc_lib.erl index 4f71c47bfa..38bb8f3ac6 100644 --- a/lib/snmp/src/compile/snmpc_lib.erl +++ b/lib/snmp/src/compile/snmpc_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2010. All Rights Reserved. +%% Copyright Ericsson AB 1997-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1754,12 +1754,12 @@ error(FormatStr, Data, Line) when is_list(FormatStr) -> exit(error). print_error(FormatStr, Data) when is_list(FormatStr) -> - ok = io:format("~s: Error: " ++ FormatStr,[get(filename)|Data]), + ok = io:format("~s: " ++ FormatStr,[get(filename)|Data]), put(errors,yes), io:format("~n"). print_error(FormatStr, Data,Line) when is_list(FormatStr) -> - ok = io:format("~s: ~w: Error: " ++ FormatStr,[get(filename), Line |Data]), + ok = io:format("~s: ~w: " ++ FormatStr,[get(filename), Line |Data]), put(errors,yes), io:format("~n"). diff --git a/lib/snmp/src/compile/snmpc_lib.hrl b/lib/snmp/src/compile/snmpc_lib.hrl index 000486e728..35ec9abd03 100644 --- a/lib/snmp/src/compile/snmpc_lib.hrl +++ b/lib/snmp/src/compile/snmpc_lib.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2009. All Rights Reserved. +%% Copyright Ericsson AB 2009-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -20,8 +20,17 @@ -ifndef(snmpc_lib). -define(snmpc_lib, true). --define(vwarning(F, A), ?verbosity(warning, F, A, ignore)). --define(vwarning2(F, A, MibLine), ?verbosity(warning, F, A, MibLine)). +-define(vwarning(F, A), + case get(warnings_as_errors) of + true -> snmpc_lib:error(F, A); + _ -> ?verbosity(warning, F, A, ignore) + end). + +-define(vwarning2(F, A, MibLine), + case get(warnings_as_errors) of + true -> snmpc_lib:error(F, A, MibLine); + _ -> ?verbosity(warning, F, A, MibLine) + end). -define(vinfo(F, A), ?verbosity(info, F, A, ignore)). -define(vinfo2(F, A, MibLine), ?verbosity(info, F, A, MibLine)). -define(vlog(F, A), ?verbosity(log, F, A, ignore)). diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index 0d084332de..6d2ac8d747 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -50,7 +50,7 @@ register_agent/2, register_agent/3, register_agent/4, unregister_agent/2, unregister_agent/3, which_agents/0, which_agents/1, - agent_info/2, update_agent_info/4, + agent_info/2, update_agent_info/3, update_agent_info/4, register_usm_user/3, unregister_usm_user/2, which_usm_users/0, which_usm_users/1, @@ -167,6 +167,7 @@ -include_lib("snmp/include/snmp_types.hrl"). -include("snmpm_atl.hrl"). -include("snmpm_internal.hrl"). +-include("snmp_verbosity.hrl"). -define(DEFAULT_AGENT_PORT, 161). @@ -447,8 +448,11 @@ agent_info(Addr, Port, Item) -> Error end. +update_agent_info(UserId, TargetName, Info) when is_list(Info) -> + snmpm_config:update_agent_info(UserId, TargetName, Info). + update_agent_info(UserId, TargetName, Item, Val) -> - snmpm_config:update_agent_info(UserId, TargetName, Item, Val). + update_agent_info(UserId, TargetName, [{Item, Val}]). %% Backward compatibility functions update_agent_info(UserId, Addr, Port, Item, Val) -> diff --git a/lib/snmp/src/manager/snmpm_config.erl b/lib/snmp/src/manager/snmpm_config.erl index fd6da3e71a..c2e57abddb 100644 --- a/lib/snmp/src/manager/snmpm_config.erl +++ b/lib/snmp/src/manager/snmpm_config.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% Copyright Ericsson AB 2004-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -36,7 +36,8 @@ user_info/0, user_info/1, user_info/2, register_agent/3, unregister_agent/2, - agent_info/0, agent_info/2, agent_info/3, update_agent_info/4, + agent_info/0, agent_info/2, agent_info/3, + update_agent_info/3, update_agent_info/4, which_agents/0, which_agents/1, is_known_engine_id/2, @@ -84,7 +85,9 @@ backup/1, - mk_target_name/3 + mk_target_name/3, + + default_transport_domain/0 ]). @@ -127,23 +130,24 @@ %% Macros and Constants: --define(SERVER, ?MODULE). --define(BACKUP_DB, snmpm_config_backup). --define(CONFIG_DB, snmpm_config_db). +-define(SERVER, ?MODULE). +-define(BACKUP_DB, snmpm_config_backup). +-define(CONFIG_DB, snmpm_config_db). -define(DEFAULT_USER, default_user). -define(DEFAULT_AGENT_PORT, 161). --define(IRB_DEFAULT, auto). -%% -define(IRB_DEFAULT, {user, timer:seconds(15)}). +-define(IRB_DEFAULT, auto). +%% -define(IRB_DEFAULT, {user, timer:seconds(15)}). --define(USER_MOD_DEFAULT, snmpm_user_default). --define(USER_DATA_DEFAULT, undefined). +-define(USER_MOD_DEFAULT, snmpm_user_default). +-define(USER_DATA_DEFAULT, undefined). %% -define(DEF_ADDR_TAG, default_addr_tag). -define(DEFAULT_TARGETNAME, default_agent). --define(DEF_PORT_TAG, default_port_tag). +-define(DEF_PORT_TAG, default_port_tag). +-define(SUPPORTED_DOMAINS, [transportDomainUdpIpv4, transportDomainUdpIpv6]). -ifdef(snmp_debug). -define(GS_START_LINK(Opts), @@ -159,6 +163,11 @@ %%%------------------------------------------------------------------- %%% API %%%------------------------------------------------------------------- + +default_transport_domain() -> + transportDomainUdpIpv4. + + start_link(Opts) -> ?d("start_link -> entry with" "~n Opts: ~p", [Opts]), @@ -269,9 +278,10 @@ do_user_info(_UserId, BadItem) -> error({not_found, BadItem}). -%% A target-name constructed in this way is a string with the following +%% A target-name constructed in this way is a string with the following: %% <IP-address>:<Port>-<Version> -%% +%% This is intended for backward compatibility and therefor has +%% only support for IPv4 addresses and *no* other transport domain. mk_target_name(Addr0, Port, Config) when is_list(Config) -> Version = case lists:keysearch(version, 1, Config) of @@ -280,7 +290,6 @@ mk_target_name(Addr0, Port, Config) when is_list(Config) -> false -> select_lowest_supported_version() end, -%% p("mk_target_name -> Version: ~p", [Version]), case normalize_address(Addr0) of {A, B, C, D} -> lists:flatten( @@ -308,57 +317,99 @@ select_lowest_supported_version([H|T], Versions) -> end. -register_agent(UserId, _TargetName, _Config) when (UserId =:= user_id) -> +register_agent(UserId, _TargetName, _Config0) when (UserId =:= user_id) -> {error, {bad_user_id, UserId}}; -register_agent(UserId, TargetName, Config) +register_agent(UserId, TargetName, Config0) when (is_list(TargetName) andalso (length(TargetName) > 0) andalso - is_list(Config)) -> + is_list(Config0)) -> -%% p("register_agent -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Config: ~p", [UserId, TargetName, Config]), + ?vtrace("register_agent -> entry with" + "~n UserId: ~p" + "~n TargetName: ~p" + "~n Config0: ~p", [UserId, TargetName, Config0]), %% Check: %% 1) That the mandatory configs are present - %% 2) That the illegal config user_id (used internally) is - %% not present + %% 2) That no illegal config, e.g. user_id (used internally), + %% is not present %% 3) Check that there are no invalid or erroneous configs - %% 4) Chack that the manager is capable to use the selected version - case verify_agent_config(Config) of - ok -> + %% 4) Check that the manager is capable of using the selected version + case verify_agent_config(Config0) of + {ok, Config} -> call({register_agent, UserId, TargetName, Config}); Error -> Error end. -verify_agent_config(Conf) -> - ok = verify_mandatory(Conf, [engine_id, address, reg_type]), - case verify_invalid(Conf, [user_id]) of - ok -> - case verify_agent_config2(Conf) of - ok -> - {ok, Vsns} = system_info(versions), - Vsn = - case lists:keysearch(version, 1, Conf) of - {value, {version, V}} -> - V; - false -> - v1 - end, - case lists:member(Vsn, Vsns) of - true -> - ok; - false -> - {error, {version_not_supported_by_manager, Vsn, Vsns}} - end - end; - Error -> +verify_agent_config(Conf0) -> + try + begin + verify_mandatory(Conf0, [engine_id, address, reg_type]), + verify_invalid(Conf0, [user_id]), + Conf = verify_agent_config3(Conf0), + Vsns = versions(), + Vsn = which_version(Conf), + verify_version(Vsn, Vsns), + {ok, Conf} + end + catch + throw:Error -> Error end. +versions() -> + case system_info(versions) of + {ok, Vsns} -> + Vsns; + {error, _} = ERROR -> + throw(ERROR) + end. + +which_version(Conf) -> + case lists:keysearch(version, 1, Conf) of + {value, {version, V}} -> + V; + false -> + v1 + end. + +verify_version(Vsn, Vsns) -> + case lists:member(Vsn, Vsns) of + true -> + ok; + false -> + Reason = {version_not_supported_by_manager, Vsn, Vsns}, + throw({error, Reason}) + end. + +verify_agent_config3(Conf0) -> + %% Fix (transport) address and domain + {TDomain, Conf1} = + case lists:keysearch(tdomain, 1, Conf0) of + {value, {tdomain, Dom}} -> + {Dom, Conf0}; + false -> + Dom = default_transport_domain(), + {Dom, [{tdomain, Dom} | Conf0]} + end, + Conf2 = case lists:keysearch(address, 1, Conf1) of + {value, {address, Address}} -> + lists:keyreplace(address, 1, Conf1, + {address, {TDomain, Address}}); + false -> + %% This is a mandatory config option, + %% a later test will detect this + Conf1 + end, + case verify_agent2(Conf2) of + {ok, Conf} -> + Conf; + {error, _} = ERROR -> + throw(ERROR) + end. + verify_agent_config2(Conf) -> verify_agent2(Conf). @@ -366,6 +417,7 @@ verify_agent_config2(Conf) -> unregister_agent(UserId, TargetName) -> call({unregister_agent, UserId, TargetName}). +%% This is the old style agent unregistration (using Addr and Port). unregister_agent(UserId, Addr0, Port) -> Addr = normalize_address(Addr0), case do_agent_info(Addr, Port, target_name) of @@ -421,17 +473,51 @@ which_agents(UserId) -> Agents = ets:match(snmpm_agent_table, Pat), [TargetName || [TargetName] <- Agents]. - -update_agent_info(UserId, TargetName, Item, Val0) - when (Item =/= user_id) -> - case (catch verify_val(Item, Val0)) of - {ok, Val} -> - call({update_agent_info, UserId, TargetName, Item, Val}); - Error -> + +verify_agent_info(TargetName, Info0) -> + try + begin + verify_invalid(Info0, [user_id]), + %% Check if address is part of the list and + %% if so update it with the domain info. + Info = + case lists:keysearch(address, 1, Info0) of + {value, {address, Addr}} -> + %% If domain is part of the info, then use it. + %% If not, lookup what is already stored for + %% this agent and use that. + Domain = + case lists:keysearch(tdomain, 1, Info0) of + {value, {tdomain, Dom}} -> + Dom; + false -> + {ok, Dom} = + agent_info(TargetName, tdomain), + Dom + end, + Addr2 = {Domain, Addr}, + lists:keyreplace(address, 1, Info0, {address, Addr2}); + false -> + Info0 + end, + verify_agent2(Info) + end + catch + throw:Error -> Error end. -%% Backward compatibillity +update_agent_info(UserId, TargetName, Info) -> + call({update_agent_info, UserId, TargetName, Info}). + +%% <BACKWARD-COMPAT-2> +%% This is wrapped in the interface module, so this function is +%% only here to catch code-upgrade problems. +update_agent_info(UserId, TargetName, Item, Val) -> + update_agent_info(UserId, TargetName, [{Item, Val}]). +%% </BACKWARD-COMPAT-2> + +%% <BACKWARD-COMPAT-1> update_agent_info(UserId, Addr, Port, Item, Val) -> case agent_info(Addr, Port, target_name) of {ok, TargetName} -> @@ -439,6 +525,7 @@ update_agent_info(UserId, Addr, Port, Item, Val) -> Error -> Error end. +%% </BACKWARD-COMPAT-1> is_known_engine_id(EngineID, TargetName) -> case agent_info(TargetName, engine_id) of @@ -650,22 +737,14 @@ unregister_usm_user(EngineID, Name) call({unregister_usm_user, EngineID, Name}). verify_usm_user_config(EngineID, Name, Config) -> - %% case verify_mandatory(Config, []) of - %% ok -> - %% case verify_invalid(Config, [engine_id, name]) of - %% ok -> - %% verify_usm_user_config2(EngineID, Name, Config); - %% Error -> - %% Error - %% end; - %% Error -> - %% Error - %% end. - ok = verify_mandatory(Config, []), - case verify_invalid(Config, [engine_id, name]) of - ok -> - verify_usm_user_config2(EngineID, Name, Config); - Error -> + try + begin + verify_mandatory(Config, []), + verify_invalid(Config, [engine_id, name]), + verify_usm_user_config2(EngineID, Name, Config) + end + catch + throw:Error -> Error end. @@ -1590,6 +1669,7 @@ check_agent_config2(Agent) -> throw(Err) end. +%% For backward compatibility check_agent_config({UserId, TargetName, Community, @@ -1597,10 +1677,27 @@ check_agent_config({UserId, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}) -> + TDomain = default_transport_domain(), + check_agent_config({UserId, + TargetName, + Community, + TDomain, Ip, Port, + EngineId, + Timeout, MaxMessageSize, + Version, SecModel, SecName, SecLevel}); + +check_agent_config({UserId, + TargetName, + Community, + TDomain, Ip, Port, + EngineId, + Timeout, MaxMessageSize, + Version, SecModel, SecName, SecLevel}) -> ?vtrace("check_agent_config -> entry with" "~n UserId: ~p" "~n TargetName: ~p" "~n Community: ~p" + "~n TDomain: ~p" "~n Ip: ~p" "~n Port: ~p" "~n EngineId: ~p" @@ -1610,15 +1707,16 @@ check_agent_config({UserId, "~n SecModel: ~p" "~n SecName: ~p" "~n SecLevel: ~p", - [UserId, TargetName, Community, Ip, Port, + [UserId, TargetName, Community, + TDomain, Ip, Port, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel]), - Addr = normalize_address(Ip), + Addr = normalize_address(TDomain, Ip), ?vtrace("check_agent_config -> Addr: ~p", [Addr]), Agent = {UserId, TargetName, Community, - Addr, Port, + TDomain, Addr, Port, EngineId, Timeout, MaxMessageSize, Version, SecModel, SecName, SecLevel}, @@ -1644,6 +1742,7 @@ init_agent_config({UserId, TargetName, Config}) -> end. +%% For backward compatibility verify_agent({UserId, TargetName, Comm, @@ -1651,48 +1750,68 @@ verify_agent({UserId, EngineId, Timeout, MMS, Version, SecModel, SecName, SecLevel}) -> - ?vtrace("verify_agent -> entry with" + TDomain = default_transport_domain(), + verify_agent({UserId, + TargetName, + Comm, + TDomain, Ip, Port, + EngineId, + Timeout, MMS, + Version, SecModel, SecName, SecLevel}); + +verify_agent({UserId, + TargetName, + Comm, + TDomain, Ip, Port, + EngineId, + Timeout, MMS, + Version, SecModel, SecName, SecLevel}) -> + ?vdebug("verify_agent -> entry with" "~n UserId: ~p" "~n TargetName: ~p", [UserId, TargetName]), snmp_conf:check_string(TargetName, {gt, 0}), - case verify_val(address, Ip) of - {ok, Addr} -> - snmp_conf:check_integer(Port, {gt, 0}), - Conf = - [{reg_type, target_name}, - {address, Addr}, - {port, Port}, - {community, Comm}, - {engine_id, EngineId}, - {timeout, Timeout}, - {max_message_size, MMS}, - {version, Version}, - {sec_model, SecModel}, - {sec_name, SecName}, - {sec_level, SecLevel} - ], - case verify_agent2(Conf) of - ok -> - {UserId, TargetName, Conf, Version}; - Err -> - throw(Err) - end; - - Error -> - ?vlog("verify_agent -> failed: ~n ~p", [Error]), - throw(Error) + snmp_conf:check_integer(Port, {gt, 0}), + %% Note that the order of Conf *is* important. + %% Some properties may depend on others, so that + %% in order to verify one property, another must + %% be already verified (and present). An example + %% of this is the property 'address', for which + %% the property tdomain is needed. + Conf0 = + [{reg_type, target_name}, + {tdomain, TDomain}, + %% This should be taddress, but what the*... + {address, {TDomain, Ip}}, + {port, Port}, + {community, Comm}, + {engine_id, EngineId}, + {timeout, Timeout}, + {max_message_size, MMS}, + {version, Version}, + {sec_model, SecModel}, + {sec_name, SecName}, + {sec_level, SecLevel} + ], + case verify_agent2(Conf0) of + {ok, Conf} -> + {UserId, TargetName, Conf, Version}; + Err -> + throw(Err) end. -verify_agent2([]) -> - ok; -verify_agent2([{Item, Val}|Items]) -> - case verify_val(Item, Val) of - {ok, _Val} -> - verify_agent2(Items); +verify_agent2(Conf) -> + verify_agent2(Conf, []). + +verify_agent2([], VerifiedConf) -> + {ok, VerifiedConf}; +verify_agent2([{Item, Val0}|Items], VerifiedConf) -> + case verify_val(Item, Val0) of + {ok, Val} -> + verify_agent2(Items, [{Item, Val} | VerifiedConf]); Err -> Err end; -verify_agent2([Bad|_]) -> +verify_agent2([Bad|_], _VerifiedConf) -> {error, {bad_agent_config, Bad}}. @@ -1708,14 +1827,28 @@ read_users_config_file(Dir) -> check_user_config({Id, Mod, Data}) -> + ?vtrace("check_user_config -> entry with" + "~n Id: ~p" + "~n Mod: ~p" + "~n Data: ~p", [Id, Mod, Data]), check_user_config({Id, Mod, Data, []}); -check_user_config({Id, Mod, _Data, DefaultAgentConfig} = User) +check_user_config({Id, Mod, Data, DefaultAgentConfig} = _User) when (Id =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) -> + ?vtrace("check_user_config -> entry with" + "~n Id: ~p" + "~n Mod: ~p" + "~n Data: ~p" + "~n DefaultAgentConfig: ~p", + [Id, Mod, Data, DefaultAgentConfig]), case (catch verify_user_behaviour(Mod)) of ok -> + ?vtrace("check_user_config -> user behaviour verified", []), case verify_user_agent_config(DefaultAgentConfig) of - ok -> - {ok, User}; + {ok, DefAgentConf} -> + ?vtrace("check_user_config -> " + "user agent (default) config verified", []), + User2 = {Id, Mod, Data, DefAgentConf}, + {ok, User2}; {error, Reason} -> error({bad_default_agent_config, Reason}) end; @@ -1756,16 +1889,16 @@ verify_user({Id, UserMod, UserData}) -> verify_user({Id, UserMod, UserData, DefaultAgentConfig}) when (Id =/= ?DEFAULT_USER) andalso is_list(DefaultAgentConfig) -> ?d("verify_user -> entry with" - "~n Id: ~p" - "~n UserMod: ~p" - "~n UserData: ~p" + "~n Id: ~p" + "~n UserMod: ~p" + "~n UserData: ~p" "~n DefaultAgentConfig: ~p", [Id, UserMod, UserData, DefaultAgentConfig]), case (catch verify_user_behaviour(UserMod)) of ok -> case verify_user_agent_config(DefaultAgentConfig) of - ok -> - Config = default_agent_config(DefaultAgentConfig), + {ok, DefAgentConf} -> + Config = default_agent_config(DefAgentConf), {ok, #user{id = Id, mod = UserMod, data = UserData, @@ -1783,10 +1916,15 @@ verify_user({Id, _, _, _}) -> {error, {bad_user_id, Id}}. verify_user_agent_config(Conf) -> - case verify_invalid(Conf, [user_id, engine_id, address]) of - ok -> - verify_agent_config2(Conf); - Error -> + try + begin + verify_invalid(Conf, [user_id, engine_id, address]), + verify_agent_config2(Conf) + end + catch + throw:Error -> + ?vdebug("verify_user_agent_config -> throw" + "~n Error: ~p", [Error]), Error end. @@ -2147,6 +2285,16 @@ handle_call({unregister_agent, UserId, TargetName}, _From, State) -> Reply = handle_unregister_agent(UserId, TargetName), {reply, Reply, State}; +handle_call({update_agent_info, UserId, TargetName, Info}, + _From, State) -> + ?vlog("received update_agent_info request: " + "~n UserId: ~p" + "~n TargetName: ~p" + "~n Info: ~p", [UserId, TargetName, Info]), + Reply = handle_update_agent_info(UserId, TargetName, Info), + {reply, Reply, State}; + +%% <BACKWARD-COMPAT> handle_call({update_agent_info, UserId, TargetName, Item, Val}, _From, State) -> ?vlog("received update_agent_info request: " @@ -2156,6 +2304,7 @@ handle_call({update_agent_info, UserId, TargetName, Item, Val}, "~n Val: ~p", [UserId, TargetName, Item, Val]), Reply = handle_update_agent_info(UserId, TargetName, Item, Val), {reply, Reply, State}; +%% </BACKWARD-COMPAT> handle_call({register_usm_user, User}, _From, State) -> ?vlog("received register_usm_user request: " @@ -2517,16 +2666,27 @@ handle_register_agent(UserId, TargetName, Config) -> "~n Config: ~p", [UserId, TargetName, Config]), case (catch agent_info(TargetName, user_id)) of {error, _} -> + ?vtrace("handle_register_agent -> user_id not found in config", []), case ets:lookup(snmpm_user_table, UserId) of [#user{default_agent_config = DefConfig}] -> + ?vtrace("handle_register_agent -> " + "~n DefConfig: ~p", [DefConfig]), + %% First, insert this users default config + ?vtrace("handle_register_agent -> store default config", []), do_handle_register_agent(TargetName, DefConfig), + %% Second, insert the config for this agent + ?vtrace("handle_register_agent -> store config", []), do_handle_register_agent(TargetName, [{user_id, UserId}|Config]), %% <DIRTY-BACKWARD-COMPATIBILLITY> %% And now for some (backward compatibillity) %% dirty crossref stuff + ?vtrace("handle_register_agent -> lookup address", []), {ok, Addr} = agent_info(TargetName, address), + ?vtrace("handle_register_agent -> Addr: ~p, lookup Port", + [Addr]), {ok, Port} = agent_info(TargetName, port), + ?vtrace("handle_register_agent -> register cross-ref fix", []), ets:insert(snmpm_agent_table, {{Addr, Port, target_name}, TargetName}), %% </DIRTY-BACKWARD-COMPATIBILLITY> @@ -2551,10 +2711,18 @@ handle_register_agent(UserId, TargetName, Config) -> do_handle_register_agent(_TargetName, []) -> ok; do_handle_register_agent(TargetName, [{Item, Val}|Rest]) -> + ?vtrace("handle_register_agent -> entry with" + "~n TargetName: ~p" + "~n Item: ~p" + "~n Val: ~p" + "~n Rest: ~p", [TargetName, Item, Val, Rest]), case (catch do_update_agent_info(TargetName, Item, Val)) of ok -> do_handle_register_agent(TargetName, Rest); {error, Reason} -> + ?vtrace("handle_register_agent -> failed updating ~p" + "~n Item: ~p" + "~n Reason: ~p", [Item, Reason]), ets:match_delete(snmpm_agent_table, {TargetName, '_'}), {error, Reason} end; @@ -2589,41 +2757,61 @@ handle_unregister_agent(UserId, TargetName) -> end. -handle_update_agent_info(UserId, TargetName, Item, Val) -> +handle_update_agent_info(UserId, TargetName, Info) -> ?vdebug("handle_update_agent_info -> entry with" "~n UserId: ~p" "~n TargetName: ~p" - "~n Item: ~p" - "~n Val: ~p", [UserId, TargetName, Item, Val]), + "~n Info: ~p", [UserId, TargetName, Info]), + %% Verify ownership case (catch agent_info(TargetName, user_id)) of - {ok, UserId} -> - do_update_agent_info(TargetName, Item, Val); + {ok, UserId} -> + handle_update_agent_info(TargetName, Info); {ok, OtherUserId} -> {error, {not_owner, OtherUserId}}; Error -> Error end. -do_update_agent_info(TargetName, Item, Val0) -> -%% p("do_update_agent_info -> entry with" -%% "~n TargetName: ~p" -%% "~n Item: ~p" -%% "~n Val0: ~p", [TargetName, Item, Val0]), - case verify_val(Item, Val0) of - {ok, Val} -> -%% p("do_update_agent_info -> verified value" -%% "~n Val: ~p", [Val]), - ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}), - ok; +handle_update_agent_info(TargetName, Info0) -> + ?vtrace("handle_update_agent_info -> entry with" + "~n TargetName: ~p" + "~n Info0: ~p", [TargetName, Info0]), + %% Verify info + try verify_agent_info(TargetName, Info0) of + {ok, Info} -> + do_update_agent_info(TargetName, Info); Error -> - ?vlog("do_update_agent_info -> verify value failed: " - "~n TargetName: ~p" - "~n Item: ~p" - "~n Val0: ~p" - "~n Error: ~p", [TargetName, Item, Val0, Error]), - {error, {bad_agent_val, TargetName, Item, Val0}} + Error + catch + throw:Error -> + Error; + T:E -> + {error, {failed_info_verification, Info0, T, E}} end. +handle_update_agent_info(UserId, TargetName, Item, Val) -> + ?vdebug("handle_update_agent_info -> entry with" + "~n UserId: ~p" + "~n TargetName: ~p" + "~n Item: ~p" + "~n Val: ~p", [UserId, TargetName, Item, Val]), + handle_update_agent_info(TargetName, [{Item, Val}]). + +do_update_agent_info(TargetName, Info) -> + InsertItem = + fun({Item, Val}) -> + ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}) + end, + lists:foreach(InsertItem, Info). + +do_update_agent_info(TargetName, Item, Val) -> + ?vtrace("do_update_agent_info -> entry with" + "~n TargetName: ~p" + "~n Item: ~p" + "~n Val: ~p", [TargetName, Item, Val]), + ets:insert(snmpm_agent_table, {{TargetName, Item}, Val}), + ok. + handle_register_usm_user(#usm_user{engine_id = EngineID, name = Name} = User) -> @@ -2791,7 +2979,7 @@ verify_mandatory(Conf, [Mand|Mands]) -> true -> verify_mandatory(Conf, Mands); false -> - {error, {missing_mandatory_config, Mand}} + throw({error, {missing_mandatory_config, Mand}}) end. verify_invalid(_, []) -> @@ -2801,7 +2989,7 @@ verify_invalid(Conf, [Inv|Invs]) -> false -> verify_invalid(Conf, Invs); true -> - {error, {illegal_config, Inv}} + throw({error, {illegal_config, Inv}}) end. @@ -2810,10 +2998,26 @@ verify_val(user_id, UserId) -> verify_val(reg_type, RegType) when (RegType =:= addr_port) orelse (RegType =:= target_name) -> {ok, RegType}; -verify_val(address, Addr0) -> - case normalize_address(Addr0) of +verify_val(tdomain = Item, snmpUDPDomain = _Domain) -> + verify_val(Item, transportDomainUdpIpv4); +verify_val(tdomain, Domain) -> + case lists:member(Domain, ?SUPPORTED_DOMAINS) of + true -> + {ok, Domain}; + false -> + case lists:member(Domain, snmp_conf:all_domains()) of + true -> + error({unsupported_domain, Domain}); + false -> + error({unknown_domain, Domain}) + end + end; +verify_val(address, {Domain, Addr0}) -> + case normalize_address(Domain, Addr0) of {_A1, _A2, _A3, _A4} = Addr -> {ok, Addr}; + {_A1, _A2, _A3, _A4, _A5, _A6, _A7, _A8} = Addr -> + {ok, Addr}; _ when is_list(Addr0) -> case (catch snmp_conf:check_ip(Addr0)) of ok -> @@ -2824,6 +3028,8 @@ verify_val(address, Addr0) -> _ -> error({bad_address, Addr0}) end; +verify_val(address, BadAddress) -> + error({bad_address, BadAddress}); verify_val(port, Port) -> case (catch snmp_conf:check_integer(Port, {gt, 0})) of ok -> @@ -2875,7 +3081,7 @@ verify_val(sec_name, BadName) -> verify_val(sec_level, Level) -> (catch snmp_conf:check_sec_level(Level)); verify_val(Item, _) -> - {error, {no_such_item, Item}}. + {error, {unknown_item, Item}}. %%%------------------------------------------------------------------- @@ -3034,11 +3240,17 @@ init_mini_mib_elems(MibName, [_|T], Res) -> %%---------------------------------------------------------------------- normalize_address(Addr) -> - case inet:getaddr(Addr, inet) of + normalize_address(snmpUDPDomain, Addr). + +normalize_address(snmpUDPDomain, Addr) -> + normalize_address(transportDomainUdpIpv4, Addr); + +normalize_address(Domain, Addr) -> + case inet:getaddr(Addr, td2fam(Domain)) of {ok, Addr2} -> Addr2; _ when is_list(Addr) -> - case (catch snmp_conf:check_ip(Addr)) of + case (catch snmp_conf:check_ip(Domain, Addr)) of ok -> list_to_tuple(Addr); _ -> @@ -3048,6 +3260,9 @@ normalize_address(Addr) -> Addr end. +td2fam(transportDomainUdpIpv4) -> inet; +td2fam(transportDomainUdpIpv6) -> inet6. + %%---------------------------------------------------------------------- diff --git a/lib/snmp/src/manager/snmpm_mpd.erl b/lib/snmp/src/manager/snmpm_mpd.erl index 7712370d28..103c87d32b 100644 --- a/lib/snmp/src/manager/snmpm_mpd.erl +++ b/lib/snmp/src/manager/snmpm_mpd.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2010. All Rights Reserved. +%% Copyright Ericsson AB 2004-2011. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -92,7 +92,7 @@ reset(#state{v3 = V3}) -> %% Purpose: This is the main Message Dispatching function. (see %% section 4.2.1 in rfc2272) %%----------------------------------------------------------------- -process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) -> +process_msg(Msg, Domain, Addr, Port, State, NoteStore, Logger) -> inc(snmpInPkts), @@ -102,18 +102,18 @@ process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) -> #message{version = 'version-1', vsn_hdr = Community, data = Data} when State#state.v1 =:= true -> HS = ?empty_msg_size + length(Community), - process_v1_v2c_msg('version-1', NoteStore, Msg, TDomain, - Addr, Port, + process_v1_v2c_msg('version-1', NoteStore, Msg, + Domain, Addr, Port, Community, Data, HS, Logger); %% Version 2 #message{version = 'version-2', vsn_hdr = Community, data = Data} when State#state.v2c =:= true -> HS = ?empty_msg_size + length(Community), - process_v1_v2c_msg('version-2', NoteStore, Msg, TDomain, - Addr, Port, - Community, Data, HS, Logger); - + (catch process_v1_v2c_msg('version-2', NoteStore, Msg, + Domain, Addr, Port, + Community, Data, HS, Logger)); + %% Version 3 #message{version = 'version-3', vsn_hdr = H, data = Data} when State#state.v3 =:= true -> @@ -148,17 +148,30 @@ process_msg(Msg, TDomain, Addr, Port, State, NoteStore, Logger) -> %%----------------------------------------------------------------- %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- -process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain, +process_v1_v2c_msg(Vsn, _NoteStore, Msg, Domain, Addr, Port, Community, Data, HS, Log) -> ?vdebug("process_v1_v2c_msg -> entry with" "~n Vsn: ~p" + "~n Domain: ~p" "~n Addr: ~p" "~n Port: ~p" "~n Community: ~p" - "~n HS: ~p", [Vsn, Addr, Port, Community, HS]), + "~n HS: ~p", [Vsn, Domain, Addr, Port, Community, HS]), + {TDomain, TAddress} = + try + begin + TD = snmp_conf:mk_tdomain(Domain), + TA = snmp_conf:mk_taddress(Domain, Addr, Port), + {TD, TA} + end + catch + throw:{error, TReason} -> + throw({discarded, {badarg, Domain, TReason}}) + end, + Max = get_max_message_size(), AgentMax = get_agent_max_message_size(Addr, Port), PduMS = pdu_ms(Max, AgentMax, HS), @@ -170,14 +183,14 @@ process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain, ?vtrace("process_v1_v2c_msg -> was a pdu", []), Log(Msg), inc_snmp_in(Pdu), - MsgData = {Community, sec_model(Vsn)}, + MsgData = {Community, sec_model(Vsn), TDomain, TAddress}, {ok, Vsn, Pdu, PduMS, MsgData}; Trap when is_record(Trap, trappdu) -> ?vtrace("process_v1_v2c_msg -> was a trap", []), Log(Msg), inc_snmp_in(Trap), - MsgData = {Community, sec_model(Vsn)}, + MsgData = {Community, sec_model(Vsn), TDomain, TAddress}, {ok, Vsn, Trap, PduMS, MsgData}; {'EXIT', Reason} -> @@ -185,11 +198,7 @@ process_v1_v2c_msg(Vsn, _NoteStore, Msg, snmpUDPDomain, "~n Reason: ~p", [Reason]), inc(snmpInASNParseErrs), {discarded, Reason} - end; -process_v1_v2c_msg(_Vsn, _NoteStore, _Msg, TDomain, - _Addr, _Port, - _Comm, _HS, _Data, _Log) -> - {discarded, {badarg, TDomain}}. + end. pdu_ms(MgrMMS, AgentMMS, HS) when AgentMMS < MgrMMS -> AgentMMS - HS; @@ -482,8 +491,8 @@ generate_msg('version-3', NoteStore, Pdu, generate_v3_msg(NoteStore, Pdu, SecModel, SecName, SecLevel, CtxEngineID, CtxName, TargetName, Log); -generate_msg(Vsn, _NoteStore, Pdu, {Community, _SecModel}, Log) -> - generate_v1_v2c_msg(Vsn, Pdu, Community, Log). +generate_msg(Vsn, _NoteStore, Pdu, {Comm, _SecModel}, Log) -> + generate_v1_v2c_msg(Vsn, Pdu, Comm, Log). generate_v3_msg(NoteStore, Pdu, @@ -627,6 +636,8 @@ generate_response_msg('version-3', Pdu, generate_v3_response_msg(Pdu, MsgID, SecModel, SecName, SecLevel, CtxEngineID, CtxName, SecData, Log); generate_response_msg(Vsn, Pdu, {Comm, _SecModel}, Log) -> + generate_v1_v2c_response_msg(Vsn, Pdu, Comm, Log); +generate_response_msg(Vsn, Pdu, {Comm, _SecModel, _TDomain, _TAddress}, Log) -> generate_v1_v2c_response_msg(Vsn, Pdu, Comm, Log). diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index a116c9f26b..4d6bd9aa33 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -28,7 +28,8 @@ start_link/2, stop/1, send_pdu/6, % Backward compatibillity - send_pdu/7, + send_pdu/7, % Backward compatibillity + send_pdu/8, inform_response/4, @@ -101,16 +102,21 @@ stop(Pid) -> send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) -> send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO). -send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) +send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) -> + Domain = snmpm_config:default_transport_domain(), + send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo). + +send_pdu(Pid, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo) when is_record(Pdu, pdu) -> ?d("send_pdu -> entry with" "~n Pid: ~p" "~n Pdu: ~p" "~n Vsn: ~p" "~n MsgData: ~p" + "~n Domain: ~p" "~n Addr: ~p" - "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Addr, Port]), - cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}). + "~n Port: ~p", [Pid, Pdu, Vsn, MsgData, Domain, Addr, Port]), + cast(Pid, {send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}). note_store(Pid, NoteStore) -> call(Pid, {note_store, NoteStore}). @@ -380,15 +386,17 @@ handle_call(Req, From, State) -> %% {noreply, State, Timeout} | %% {stop, Reason, State} (terminate/2 is called) %%-------------------------------------------------------------------- -handle_cast({send_pdu, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo}, State) -> +handle_cast({send_pdu, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo}, + State) -> ?vlog("received send_pdu message with" "~n Pdu: ~p" "~n Vsn: ~p" "~n MsgData: ~p" + "~n Domain: ~p" "~n Addr: ~p" - "~n Port: ~p", [Pdu, Vsn, MsgData, Addr, Port]), + "~n Port: ~p", [Pdu, Vsn, MsgData, Domain, Addr, Port]), maybe_process_extra_info(ExtraInfo), - maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State), + maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State), {noreply, State}; handle_cast({inform_response, Ref, Addr, Port}, State) -> @@ -545,8 +553,9 @@ handle_recv_msg(Addr, Port, Bytes, mpd_state = MpdState, sock = Sock, log = Log} = State) -> + Domain = snmp_conf:which_domain(Addr), % What the ****... Logger = logger(Log, read, Addr, Port), - case (catch snmpm_mpd:process_msg(Bytes, snmpUDPDomain, Addr, Port, + case (catch snmpm_mpd:process_msg(Bytes, Domain, Addr, Port, MpdState, NoteStore, Logger)) of {ok, Vsn, Pdu, MS, ACM} -> @@ -734,17 +743,17 @@ irgc_stop(Ref) -> (catch erlang:cancel_timer(Ref)). -maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, +maybe_handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, #state{filter = FilterMod} = State) -> case (catch FilterMod:accept_send_pdu(Addr, Port, pdu_type_of(Pdu))) of false -> inc(netIfPduOutDrops), ok; _ -> - handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State) + handle_send_pdu(Pdu, Vsn, MsgData, Domain, Addr, Port, State) end. -handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, +handle_send_pdu(Pdu, Vsn, MsgData, _Domain, Addr, Port, #state{server = Pid, note_store = NoteStore, sock = Sock, diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl index 58a58507d6..484954addb 100644 --- a/lib/snmp/src/manager/snmpm_server.erl +++ b/lib/snmp/src/manager/snmpm_server.erl @@ -161,7 +161,8 @@ {id, user_id, reg_type, - target, + target, + domain, addr, port, type, @@ -1175,11 +1176,12 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> "~n From: ~p", [Pid, UserId, TargetName, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_request(Oids, Vsn, MsgData, - Addr, Port, Extra, State), + Domain, Addr, Port, + Extra, State), ?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, Timeout = ?SYNC_GET_TIMEOUT(SendOpts), @@ -1190,6 +1192,7 @@ handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = get, @@ -1227,11 +1230,12 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, "~n From: ~p", [Pid, UserId, TargetName, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Addr, Port, Extra, State), + Domain, Addr, Port, + Extra, State), ?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, Timeout = ?SYNC_GET_NEXT_TIMEOUT(SendOpts), @@ -1242,6 +1246,7 @@ handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = get_next, @@ -1285,10 +1290,11 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, "~n From: ~p", [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), - ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, + ReqId = send_get_bulk_request(Oids, Vsn, MsgData, + Domain, Addr, Port, NonRep, MaxRep, Extra, State), ?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, @@ -1300,6 +1306,7 @@ handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = get_bulk, @@ -1339,11 +1346,12 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> "~n From: ~p", [Pid, UserId, TargetName, VarsAndVals, From]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_set -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Addr, Port, Extra, State), + Domain, Addr, Port, + Extra, State), ?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]), Msg = {sync_timeout, ReqId, From}, Timeout = ?SYNC_SET_TIMEOUT(SendOpts), @@ -1354,6 +1362,7 @@ handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = set, @@ -1391,10 +1400,11 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_get -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), - ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port, + ReqId = send_get_request(Oids, Vsn, MsgData, + Domain, Addr, Port, Extra, State), ?vdebug("handle_async_get -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_TIMEOUT(SendOpts), @@ -1402,6 +1412,7 @@ handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = get, @@ -1439,17 +1450,19 @@ handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_get_next -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_get_next_request(Oids, Vsn, MsgData, - Addr, Port, Extra, State), + Domain, Addr, Port, + Extra, State), ?vdebug("handle_async_get_next -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_NEXT_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = get_next, @@ -1494,10 +1507,11 @@ handle_async_get_bulk(Pid, "~n SendOpts: ~p", [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_get_bulk -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), - ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, + ReqId = send_get_bulk_request(Oids, Vsn, MsgData, + Domain, Addr, Port, NonRep, MaxRep, Extra, State), ?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts), @@ -1505,6 +1519,7 @@ handle_async_get_bulk(Pid, user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = get_bulk, @@ -1541,17 +1556,19 @@ handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> "~n SendOpts: ~p", [Pid, UserId, TargetName, VarsAndVals, SendOpts]), case agent_data(TargetName, SendOpts) of - {ok, RegType, Addr, Port, Vsn, MsgData} -> + {ok, RegType, Domain, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_async_set -> send a ~p message", [Vsn]), Extra = ?GET_EXTRA(SendOpts), ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Addr, Port, Extra, State), + Domain, Addr, Port, + Extra, State), ?vdebug("handle_async_set -> ReqId: ~p", [ReqId]), Expire = ?ASYNC_SET_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, target = TargetName, + domain = Domain, addr = Addr, port = Port, type = set, @@ -2907,7 +2924,7 @@ do_gc(Key, Now) -> %% %%---------------------------------------------------------------------- -send_get_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo, +send_get_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo, #state{net_if = NetIf, net_if_mod = Mod, mini_mib = MiniMIB}) -> @@ -2918,34 +2935,39 @@ send_get_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo, "~n Pdu: ~p" "~n Vsn: ~p" "~n MsgData: ~p" + "~n Domain: ~p" "~n Addr: ~p" - "~n Port: ~p", [Mod, NetIf, Pdu, Vsn, MsgData, Addr, Port]), - (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo)), + "~n Port: ~p", + [Mod, NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port]), + Res = (catch Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, + Domain, Addr, Port, ExtraInfo)), + ?vtrace("send_get_request -> send result:" + "~n ~p", [Res]), Pdu#pdu.request_id. -send_get_next_request(Oids, Vsn, MsgData, Addr, Port, ExtraInfo, +send_get_next_request(Oids, Vsn, MsgData, Domain, Addr, Port, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(get_next, Oids, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo), Pdu#pdu.request_id. -send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, +send_get_bulk_request(Oids, Vsn, MsgData, Domain, Addr, Port, NonRep, MaxRep, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(bulk, {NonRep, MaxRep, Oids}, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo), Pdu#pdu.request_id. -send_set_request(VarsAndVals, Vsn, MsgData, Addr, Port, ExtraInfo, +send_set_request(VarsAndVals, Vsn, MsgData, Domain, Addr, Port, ExtraInfo, #state{mini_mib = MiniMIB, net_if = NetIf, net_if_mod = Mod}) -> Pdu = make_pdu(set, VarsAndVals, MiniMIB), - Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo), + Mod:send_pdu(NetIf, Pdu, Vsn, MsgData, Domain, Addr, Port, ExtraInfo), Pdu#pdu.request_id. %% send_discovery(Vsn, MsgData, Addr, Port, ExtraInfo, @@ -3181,10 +3203,11 @@ agent_data(TargetName, SendOpts) -> {Comm, SecModel} end, + Domain = agent_data_item(tdomain, Info), Addr = agent_data_item(address, Info), Port = agent_data_item(port, Info), RegType = agent_data_item(reg_type, Info), - {ok, RegType, Addr, Port, version(Version), MsgData}; + {ok, RegType, Domain, Addr, Port, version(Version), MsgData}; Error -> Error end. diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 20f4455d10..7249def24e 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -37,7 +37,9 @@ check_timer/1, + all_domains/0, check_domain/1, + all_tdomains/0, check_tdomain/1, mk_tdomain/1, which_domain/1, @@ -345,6 +347,25 @@ check_sec_level(BadSecLevel) -> %% --------- +all_tdomains() -> + [ + ?transportDomainUdpIpv4, + ?transportDomainUdpIpv6, + ?transportDomainUdpIpv4z, + ?transportDomainUdpIpv6z, + ?transportDomainTcpIpv4, + ?transportDomainTcpIpv6, + ?transportDomainTcpIpv4z, + ?transportDomainTcpIpv6z, + ?transportDomainSctpIpv4, + ?transportDomainSctpIpv6, + ?transportDomainSctpIpv4z, + ?transportDomainSctpIpv6z, + ?transportDomainLocal, + ?transportDomainUdpDns, + ?transportDomainTcpDns, + ?transportDomainSctpDns + ]. check_tdomain(TDomain) -> SupportedTDomains = @@ -353,25 +374,7 @@ check_tdomain(TDomain) -> ?transportDomainUdpIpv4, ?transportDomainUdpIpv6 ], - AllTDomains = - [ - ?transportDomainUdpIpv4, - ?transportDomainUdpIpv6, - ?transportDomainUdpIpv4z, - ?transportDomainUdpIpv6z, - ?transportDomainTcpIpv4, - ?transportDomainTcpIpv6, - ?transportDomainTcpIpv4z, - ?transportDomainTcpIpv6z, - ?transportDomainSctpIpv4, - ?transportDomainSctpIpv6, - ?transportDomainSctpIpv4z, - ?transportDomainSctpIpv6z, - ?transportDomainLocal, - ?transportDomainUdpDns, - ?transportDomainTcpDns, - ?transportDomainSctpDns - ], + AllTDomains = all_tdomains(), case lists:member(TDomain, SupportedTDomains) of true -> ok; @@ -388,7 +391,7 @@ check_tdomain(TDomain) -> %% --------- mk_tdomain(snmpUDPDomain) -> - ?snmpUDPDomain; + mk_tdomain(transportDomainUdpIpv4); mk_tdomain(transportDomainUdpIpv4) -> ?transportDomainUdpIpv4; mk_tdomain(transportDomainUdpIpv6) -> @@ -474,6 +477,26 @@ do_check_timer(WaitFor, Factor, Incr, Retry) -> %% --------- +all_domains() -> + [ + transportDomainUdpIpv4, + transportDomainUdpIpv6, + transportDomainUdpIpv4z, + transportDomainUdpIpv6z, + transportDomainTcpIpv4, + transportDomainTcpIpv6, + transportDomainTcpIpv4z, + transportDomainTcpIpv6z, + transportDomainSctpIpv4, + transportDomainSctpIpv6, + transportDomainSctpIpv4z, + transportDomainSctpIpv6z, + transportDomainLocal, + transportDomainUdpDns, + transportDomainTcpDns, + transportDomainSctpDns + ]. + check_domain(Domain) -> SupportedDomains = [ @@ -481,25 +504,7 @@ check_domain(Domain) -> transportDomainUdpIpv4, transportDomainUdpIpv6 ], - AllDomains = - [ - transportDomainUdpIpv4, - transportDomainUdpIpv6, - transportDomainUdpIpv4z, - transportDomainUdpIpv6z, - transportDomainTcpIpv4, - transportDomainTcpIpv6, - transportDomainTcpIpv4z, - transportDomainTcpIpv6z, - transportDomainSctpIpv4, - transportDomainSctpIpv6, - transportDomainSctpIpv4z, - transportDomainSctpIpv6z, - transportDomainLocal, - transportDomainUdpDns, - transportDomainTcpDns, - transportDomainSctpDns - ], + AllDomains = all_domains(), case lists:member(Domain, SupportedDomains) of true -> ok; diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index fcbc6a88c9..6ab20e3e48 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -337,7 +337,7 @@ config_agent_sys() -> {dir, ATLDir}, {size, ATLSize}, {repair, ATLRepair}, - {seqno, ATLSeqNo}]}]; + {seqno, ATLSeqNo}]}]; no -> [] end, @@ -568,7 +568,7 @@ config_agent_snmp(Dir, Vsns) -> false -> ok end, - i("The following agent files were written: agent.conf, " + i("The following agent files where written: agent.conf, " "community.conf,~n" "standard.conf, target_addr.conf, " "target_params.conf, ~n" @@ -776,7 +776,7 @@ config_manager_snmp(Dir, Vsns) -> Users, Agents, Usms)) of ok -> i("~n- - - - - - - - - - - - -"), - i("The following manager files were written: " + i("The following manager files where written: " "manager.conf, agents.conf " ++ case lists:member(v3, Vsns) of true -> @@ -2350,7 +2350,9 @@ write_sys_config_file_manager_atl_opt(Fid, {type, Type}) -> write_sys_config_file_manager_atl_opt(Fid, {size, Size}) -> ok = io:format(Fid, "{size, ~w}", [Size]); write_sys_config_file_manager_atl_opt(Fid, {repair, Rep}) -> - ok = io:format(Fid, "{repair, ~w}", [Rep]). + ok = io:format(Fid, "{repair, ~w}", [Rep]); +write_sys_config_file_manager_atl_opt(Fid, {seqno, SeqNo}) -> + ok = io:format(Fid, "{seqno, ~w}", [SeqNo]). header() -> diff --git a/lib/snmp/src/misc/snmp_note_store.erl b/lib/snmp/src/misc/snmp_note_store.erl index a21a6209f1..23fccf8a5f 100644 --- a/lib/snmp/src/misc/snmp_note_store.erl +++ b/lib/snmp/src/misc/snmp_note_store.erl @@ -258,10 +258,17 @@ code_change({down, _Vsn}, State, _Extra) -> {ok, NState}; % upgrade -code_change(_Vsn, State, _Extra) -> +code_change(_Vsn, State0, _Extra) -> process_flag(trap_exit, true), - NState = restart_timer(State), - {ok, NState}. + State1 = + case State0 of + #state{timeout = false} -> + State0#state{timeout = ?timeout}; + _ -> + State0 + end, + State2 = restart_timer(State1), + {ok, State2}. %%---------------------------------------------------------- @@ -282,7 +289,7 @@ deactivate_timer(#state{timer = Pid, active = true} = State) -> receive deactivated -> ok end, - State#state{timeout = false}; + State#state{active = false}; deactivate_timer(State) -> State. diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 468280db02..abfd528639 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -92,7 +92,8 @@ all() -> Conf1 ++ Conf2. groups() -> - [{all_tcs, [], cases()}, + [ + {all_tcs, [], cases()}, {mib_storage, [], [ {group, mib_storage_ets}, @@ -1320,8 +1321,11 @@ finish_v3(Config) when is_list(Config) -> lists:keydelete(vsn, 1, C1). -mt_cases() -> -[multi_threaded, mt_trap]. +mt_cases() -> + [ + multi_threaded, + mt_trap + ]. init_mt(Config) when is_list(Config) -> SaNode = ?config(snmp_sa, Config), @@ -1498,7 +1502,8 @@ mt_trap(Config) when is_list(Config) -> ?line load_master("TestTrapv2"), try_test(mt_trap_test, [MA]), ?line unload_master("TestTrapv2"), - ?line unload_master("Test1"). + ?line unload_master("Test1"), + ok. v2_types(suite) -> []; v2_types(Config) when is_list(Config) -> @@ -3134,8 +3139,9 @@ mt_trap_test(MA) -> ?DBG("mt_trap_test(01) -> issue testTrapv22 (standard trap)", []), snmpa:send_trap(MA, testTrapv22, "standard trap"), ?DBG("mt_trap_test(02) -> await v2trap", []), - ?line expect(1, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?system ++ [0,1]}]), + ?line expect(mt_trap_test_1, v2trap, + [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?system ++ [0,1]}]), ?DBG("mt_trap_test(03) -> issue mtTrap (standard trap)", []), snmpa:send_trap(MA, mtTrap, "standard trap"), @@ -3143,28 +3149,22 @@ mt_trap_test(MA) -> ?DBG("mt_trap_test(04) -> multi pid: ~p. Now request sysUpTime...", [Pid]), g([[sysUpTime,0]]), - %% Previously (before OTP-6784) this was done at 09 below - %% when the test1:multiStr was actually executed by the - %% worker-process, but as of 4.9.4, this is now executed - %% my the master_agent-process... - ?DBG("mt_trap_test(05) -> send continue to multi-pid", []), - Pid ! continue, - ?DBG("mt_trap_test(06) -> await sysUpTime", []), - ?line expect(2, [{[sysUpTime,0], any}]), + ?line expect(mt_trap_test_2, [{[sysUpTime,0], any}]), ?DBG("mt_trap_test(07) -> issue testTrapv22 (standard trap)", []), snmpa:send_trap(MA, testTrapv22, "standard trap"), ?DBG("mt_trap_test(08) -> await v2trap", []), - ?line expect(3, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?system ++ [0,1]}]), + ?line expect(mt_trap_test_3, v2trap, + [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?system ++ [0,1]}]), - %% ?DBG("mt_trap_test(09) -> send continue to multi-pid", []), - %% Pid ! continue, + ?DBG("mt_trap_test(09) -> send continue to multi-pid", []), + Pid ! continue, ?DBG("mt_trap_test(10) -> await v2trap", []), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?testTrap ++ [2]}, - {[multiStr,0], "ok"}]), + ?line expect(mt_trap_test_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?testTrap ++ [2]}, + {[multiStr,0], "ok"}]), ?DBG("mt_trap_test(11) -> done", []), ok. @@ -3563,53 +3563,82 @@ do_mul_set_err() -> %% Req. SA-MIB sa_mib() -> g([[sa, [2,0]]]), - ?line expect(1, [{[sa, [2,0]], 3}]), + ?line expect(sa_mib_1, [{[sa, [2,0]], 3}]), s([{[sa, [1,0]], s, "sa_test"}]), - ?line expect(2, [{[sa, [1,0]], "sa_test"}]). + ?line expect(sa_mib_2, [{[sa, [1,0]], "sa_test"}]), + ok. ma_trap1(MA) -> ok = snmpa:send_trap(MA, testTrap2, "standard trap"), - ?line expect(1, trap, [system], 6, 1, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}]), + ?line expect(ma_trap1_1, + trap, [system], 6, 1, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}]), ok = snmpa:send_trap(MA, testTrap1, "standard trap"), - ?line expect(2, trap, [1,2,3] , 1, 0, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}]). + ?line expect(ma_trap1_2, + trap, [1,2,3] , 1, 0, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}]), + ok. ma_trap2(MA) -> snmpa:send_trap(MA,testTrap2,"standard trap",[{sysContact,"pelle"}]), - ?line expect(3, trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]). + ?line expect(ma_trap2_3, + trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]), + ok. ma_v2_2_v1_trap(MA) -> snmpa:send_trap(MA,testTrapv22,"standard trap",[{sysContact,"pelle"}]), - ?line expect(3, trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]). + ?line expect(ma_v2_2_v1_trap_3, + trap, [system], 6, 1, [{[system, [4,0]], "pelle"}]), + ok. ma_v2_2_v1_trap2(MA) -> snmpa:send_trap(MA,linkUp,"standard trap",[{ifIndex, [1], 1}, {ifAdminStatus, [1], 1}, {ifOperStatus, [1], 2}]), - ?line expect(3, trap, [1,2,3], 3, 0, [{[ifIndex, 1], 1}, - {[ifAdminStatus, 1], 1}, - {[ifOperStatus, 1], 2}]). + ?line expect(ma_v2_2_v1_trap2_3, + trap, [1,2,3], 3, 0, [{[ifIndex, 1], 1}, + {[ifAdminStatus, 1], 1}, + {[ifOperStatus, 1], 2}]), + ok. sa_trap1(SA) -> - snmpa:send_trap(SA, saTrap, "standard trap"), - ?line expect(4, trap, [ericsson], 6, 1, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}]). + %% io:format("sa_trap1 -> entry with" + %% "~n SA: ~p" + %% "~n node(SA): ~p" + %% "~n self(): ~p" + %% "~n node(): ~p" + %% "~n", [SA, node(SA), self(), node()]), + _VRes = (catch snmpa:verbosity(SA, {subagents, trace})), + %% io:format("sa_trap1 -> SA verbosity set: " + %% "~n VRes: ~p" + %% "~n", [VRes]), + _TSRes = (catch snmpa:send_trap(SA, saTrap, "standard trap")), + %% io:format("sa_trap1 -> SA trap send: " + %% "~n TSRes: ~p" + %% "~n", [TSRes]), + ?line expect(sa_trap1_4, + trap, [ericsson], 6, 1, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. sa_trap2(SA) -> snmpa:send_trap(SA, saTrap, "standard trap",[{sysContact,"pelle"}]), - ?line expect(5, trap, [ericsson], 6, 1, [{[system, [4,0]], - "pelle"}, - {[sa, [1,0]], "sa_test"}]). + ?line expect(sa_trap2_5, + trap, [ericsson], 6, 1, [{[system, [4,0]], "pelle"}, + {[sa, [1,0]], "sa_test"}]), + ok. sa_trap3(SA) -> snmpa:send_trap(SA, saTrap2, "standard trap", [{intViewSubtree, [4], [1,2,3,4]}]), - ?line expect(6, trap, [ericsson], 6, 2, [{[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}, - {[intViewSubtree,4],[1,2,3,4]}]). + ?line expect(sa_trap3_6, + trap, [ericsson], 6, 2, [{[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}, + {[intViewSubtree,4],[1,2,3,4]}]), + ok. ma_v2_trap1(MA) -> ?DBG("ma_v2_traps -> entry with MA = ~p => " @@ -4029,33 +4058,42 @@ ma_v1_2_v2_trap2(MA) -> sa_v1_2_v2_trap1(SA) -> + snmpa:verbosity(SA, {subagents, trace}), snmpa:send_trap(SA, saTrap, "standard trap"), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, - {[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}, - {[snmpTrapEnterprise, 0], ?ericsson}]). + ?line expect(trap1_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, + {[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}, + {[snmpTrapEnterprise, 0], ?ericsson}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. sa_v1_2_v2_trap2(SA) -> + snmpa:verbosity(SA, {subagents, trace}), snmpa:send_trap(SA, saTrap, "standard trap",[{sysContact,"pelle"}]), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, - {[system, [4,0]], "pelle"}, - {[sa, [1,0]], "sa_test"}, - {[snmpTrapEnterprise, 0], ?ericsson}]). - + ?line expect(trap2_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?ericsson ++ [0, 1]}, + {[system, [4,0]], "pelle"}, + {[sa, [1,0]], "sa_test"}, + {[snmpTrapEnterprise, 0], ?ericsson}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. + sa_v1_2_v2_trap3(SA) -> + snmpa:verbosity(SA, {subagents, trace}), snmpa:send_trap(SA, saTrap2, "standard trap", [{intViewSubtree, [4], [1,2,3,4]}]), - ?line expect(4, v2trap, [{[sysUpTime, 0], any}, - {[snmpTrapOID, 0], ?ericsson ++ [0, 2]}, - {[system, [4,0]], - "{mbj,eklas}@erlang.ericsson.se"}, - {[sa, [1,0]], "sa_test"}, - {[intViewSubtree,4],[1,2,3,4]}, - {[snmpTrapEnterprise, 0], ?ericsson}]). + ?line expect(trap3_4, v2trap, [{[sysUpTime, 0], any}, + {[snmpTrapOID, 0], ?ericsson ++ [0, 2]}, + {[system, [4,0]], + "{mbj,eklas}@erlang.ericsson.se"}, + {[sa, [1,0]], "sa_test"}, + {[intViewSubtree,4],[1,2,3,4]}, + {[snmpTrapEnterprise, 0], ?ericsson}]), + snmpa:verbosity(SA, {subagents, silence}), + ok. %% Req. SA-MIB, OLD-SNMPEA-MIB @@ -4195,9 +4233,9 @@ snmp_standard_mib(Config) when is_list(Config) -> %% Req. SNMP-STANDARD-MIB standard_mib_a() -> - ?line [OutPkts] = get_req(2, [[snmpOutPkts,0]]), + ?line [OutPkts] = get_req(2, [[snmpOutPkts,0]]), ?line [OutPkts2] = get_req(3, [[snmpOutPkts,0]]), - ?line OutPkts2 = OutPkts + 1, + ?line OutPkts2 = OutPkts + 1, %% There are some more counters we could test here, but it's not that %% important, since they are removed from SNMPv2-MIB. ok. @@ -4207,27 +4245,27 @@ std_mib_init() -> %% disable authentication failure traps. (otherwise w'd get many of %% them - this is also a test to see that it works). s([{[snmpEnableAuthenTraps,0], 2}]), - ?line expect(1, [{[snmpEnableAuthenTraps, 0], 2}]). + ?line expect(std_mib_init_1, [{[snmpEnableAuthenTraps, 0], 2}]). %% Req. SNMP-STANDARD-MIB | SNMPv2-MIB std_mib_finish() -> %% enable again s([{[snmpEnableAuthenTraps,0], 1}]), - ?line expect(1, [{[snmpEnableAuthenTraps, 0], 1}]). + ?line expect(std_mib_finish_1, [{[snmpEnableAuthenTraps, 0], 1}]). %% Req. SNMP-STANDARD-MIB standard_mib_test_finish() -> - %% force a authenticationFailure + %% force a authenticationFailure (should result in a trap) std_mib_write(), %% check that we got a trap - ?line expect(2, trap, [1,2,3], 4, 0, []). + ?line expect(standard_mib_test_finish_2, trap, [1,2,3], 4, 0, []). %% Req. SNMP-STANDARD-MIB | SNMPv2-MIB std_mib_read() -> ?DBG("std_mib_read -> entry", []), g([[sysUpTime,0]]), % try a bad <something>; msg dropped, no reply ?DBG("std_mib_read -> await timeout (i.e. no reply)", []), - ?line expect(1, timeout). % make sure we don't get a trap! + ?line expect(std_mib_read_1, timeout). % make sure we don't get a trap! %% Req. SNMP-STANDARD-MIB | SNMPv2-MIB @@ -4362,10 +4400,10 @@ std_mib_c({InBadCommunityNames, InBadCommunityUses, InASNErrs}) -> snmpv2_mib_a() -> ?line [SetSerial] = get_req(2, [[snmpSetSerialNo,0]]), s([{[snmpSetSerialNo,0], SetSerial}, {[sysLocation, 0], "val2"}]), - ?line expect(3, [{[snmpSetSerialNo,0], SetSerial}, - {[sysLocation, 0], "val2"}]), + ?line expect(snmpv2_mib_a_3, [{[snmpSetSerialNo,0], SetSerial}, + {[sysLocation, 0], "val2"}]), s([{[sysLocation, 0], "val3"}, {[snmpSetSerialNo,0], SetSerial}]), - ?line expect(4, inconsistentValue, 2, + ?line expect(snmpv2_mib_a_4, inconsistentValue, 2, [{[sysLocation, 0], "val3"}, {[snmpSetSerialNo,0], SetSerial}]), ?line ["val2"] = get_req(5, [[sysLocation,0]]). @@ -4688,46 +4726,46 @@ snmp_view_based_acm_mib() -> do_set(Row) -> s(Row), - expect(1, Row). + expect(do_set_1, Row). add_row(RowStatus) -> s([{RowStatus, ?createAndGo}]), - expect(1, [{RowStatus, ?createAndGo}]). + expect(add_row_1, [{RowStatus, ?createAndGo}]). del_row(RowStatus) -> s([{RowStatus, ?destroy}]), - expect(1, [{RowStatus, ?destroy}]). + expect(del_row_1, [{RowStatus, ?destroy}]). use_no_rights() -> g([[xDescr,0]]), - ?v1_2_3(expect(11, noSuchName, 1, any), - expect(12, [{[xDescr,0], noSuchObject}]), - expect(13, authorizationError, 1, any)), + ?v1_2_3(expect(use_no_rights_11, noSuchName, 1, any), + expect(use_no_rights_12, [{[xDescr,0], noSuchObject}]), + expect(use_no_rights_13, authorizationError, 1, any)), g([[xDescr2,0]]), - ?v1_2_3(expect(21, noSuchName, 1, any), - expect(22, [{[xDescr2,0], noSuchObject}]), - expect(23, authorizationError, 1, any)), + ?v1_2_3(expect(use_no_rights_21, noSuchName, 1, any), + expect(use_no_rights_22, [{[xDescr2,0], noSuchObject}]), + expect(use_no_rights_23, authorizationError, 1, any)), gn([[xDescr]]), - ?v1_2_3(expect(31, noSuchName, 1, any), - expect(32, [{[xDescr], endOfMibView}]), - expect(33, authorizationError, 1, any)), + ?v1_2_3(expect(use_no_rights_31, noSuchName, 1, any), + expect(use_no_rights_32, [{[xDescr], endOfMibView}]), + expect(use_no_rights_33, authorizationError, 1, any)), s([{[xDescr,0], "tryit"}]), - ?v1_2_3(expect(41, noSuchName, 1, any), - expect(42, noAccess, 1, any), - expect(43, authorizationError, 1, any)). + ?v1_2_3(expect(use_no_rights_41, noSuchName, 1, any), + expect(use_no_rights_42, noAccess, 1, any), + expect(use_no_rights_43, authorizationError, 1, any)). use_rights() -> g([[xDescr,0]]), - expect(1, [{[xDescr,0], any}]), + expect(use_rights_1, [{[xDescr,0], any}]), g([[xDescr2,0]]), - expect(2, [{[xDescr2,0], any}]), + expect(use_rights_2, [{[xDescr2,0], any}]), s([{[xDescr,0], "tryit"}]), - expect(3, noError, 0, any), + expect(use_rights_3, noError, 0, any), g([[xDescr,0]]), - expect(4, [{[xDescr,0], "tryit"}]). + expect(use_rights_4, [{[xDescr,0], "tryit"}]). mk_ln(X) -> [length(X) | X]. diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index a18d9f3201..084b3ee8da 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -296,7 +296,12 @@ call(N,M,F,A) -> ?DBG("call -> done:" "~n Ret: ~p" "~n Zed: ~p", [Ret, Zed]), - Ret + case Ret of + {error, Reason} -> + exit(Reason); + OK -> + OK + end end. wait(From, Env, M, F, A) -> @@ -724,17 +729,13 @@ expect(Id, A, B, C, D, E) -> expect2(Id, Fun). expect2(Id, F) -> - io:format("~w:expect2 -> entry with" - "~n Id: ~w" - "~n", [?MODULE, Id]), + io:format("EXPECT for ~w~n", [Id]), case F() of {error, Reason} -> - {error, Id, Reason}; + io:format("EXPECT failed for ~w: ~n~p~n", [Id, Reason]), + throw({error, {expect, Id, Reason}}); Else -> - io:format("~w:expect2 -> " - "~n Id: ~w" - "~n Else: ~p" - "~n", [?MODULE, Id, Else]), + io:format("EXPECT result for ~w: ~n~p~n", [Id, Else]), Else end. @@ -769,21 +770,15 @@ do_expect(Expect) when is_atom(Expect) -> do_expect({any_pdu, To}) when is_integer(To) orelse (To =:= infinity) -> - io:format("~w:do_expect(any_pdu) -> entry with" - "~n To: ~w" - "~n", [?MODULE, To]), + io:format("EXPECT any PDU~n", []), receive_pdu(To); do_expect({any_trap, To}) -> - io:format("~w:do_expect(any_trap) -> entry with" - "~n To: ~w" - "~n", [?MODULE, To]), + io:format("EXPECT any TRAP within ~w~n", [To]), receive_trap(To); do_expect({timeout, To}) -> - io:format("~w:do_expect(timeout) -> entry with" - "~n To: ~w" - "~n", [?MODULE, To]), + io:format("EXPECT nothing within ~w~n", [To]), receive X -> {error, {unexpected, X}} @@ -794,13 +789,16 @@ do_expect({timeout, To}) -> do_expect({Err, To}) when is_atom(Err) andalso (is_integer(To) orelse (To =:= infinity)) -> + io:format("EXPECT error ~w within ~w~n", [Err, To]), do_expect({{error, Err}, To}); do_expect({error, Err}) when is_atom(Err) -> Check = fun(_, R) -> R end, + io:format("EXPECT error ~w~n", [Err]), do_expect2(Check, any, Err, any, any, get_timeout()); do_expect({{error, Err}, To}) -> Check = fun(_, R) -> R end, + io:format("EXPECT error ~w within ~w~n", [Err, To]), do_expect2(Check, any, Err, any, any, To); %% exp_varbinds() -> [exp_varbind()] @@ -810,16 +808,25 @@ do_expect({{error, Err}, To}) -> %% ExpVBs -> exp_varbinds() | {VbsCondition, exp_varbinds()} do_expect(ExpVBs) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'get-response'" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'get-response', noError, 0, ExpVBs, get_timeout()). do_expect(v2trap, ExpVBs) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'snmpv2-trap'" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'snmpv2-trap', noError, 0, ExpVBs, get_timeout()); do_expect(report, ExpVBs) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'report'" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'report', noError, 0, ExpVBs, get_timeout()); @@ -827,16 +834,13 @@ do_expect(inform, ExpVBs) -> do_expect({inform, true}, ExpVBs); do_expect({inform, false}, ExpVBs) -> - io:format("~w:do_expect(inform, false) -> entry with" - "~n ExpVBs: ~p" - "~n", [?MODULE, ExpVBs]), Check = fun(_, R) -> R end, + io:format("EXPECT 'inform-request' (false)" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); do_expect({inform, true}, ExpVBs) -> - io:format("~w:do_expect(inform, true) -> entry with" - "~n ExpVBs: ~p" - "~n", [?MODULE, ExpVBs]), Check = fun(PDU, ok) -> RespPDU = PDU#pdu{type = 'get-response', @@ -847,6 +851,9 @@ do_expect({inform, true}, ExpVBs) -> (_, Err) -> Err end, + io:format("EXPECT 'inform-request' (true)" + "~n with" + "~n Varbinds: ~p~n", [ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()); do_expect({inform, {error, EStat, EIdx}}, ExpVBs) @@ -861,6 +868,11 @@ do_expect({inform, {error, EStat, EIdx}}, ExpVBs) (_, Err) -> Err end, + io:format("EXPECT 'inform-request' (error)" + "~n with" + "~n Error Status: ~p" + "~n Error Index: ~p" + "~n Varbinds: ~p~n", [EStat, EIdx, ExpVBs]), do_expect2(Check, 'inform-request', noError, 0, ExpVBs, get_timeout()). @@ -871,6 +883,12 @@ do_expect(Err, Idx, ExpVBs, To) when is_atom(Err) andalso (is_integer(Idx) orelse is_list(Idx) orelse (Idx == any)) -> Check = fun(_, R) -> R end, + io:format("EXPECT 'get-response'" + "~n with" + "~n Error: ~p" + "~n Index: ~p" + "~n Varbinds: ~p" + "~n within ~w~n", [Err, Idx, ExpVBs, To]), do_expect2(Check, 'get-response', Err, Idx, ExpVBs, To). @@ -878,15 +896,13 @@ do_expect(Type, Enterp, Generic, Specific, ExpVBs) -> do_expect(Type, Enterp, Generic, Specific, ExpVBs, 3500). do_expect(trap, Enterp, Generic, Specific, ExpVBs, To) -> - io:format("~w:do_expect(trap) -> entry with" - "~n Enterp: ~w" - "~n Generic: ~w" - "~n Specific: ~w" - "~n ExpVBs: ~w" - "~n To: ~w" - "~nwhen" - "~n Time: ~w" - "~n", [?MODULE, Enterp, Generic, Specific, ExpVBs, To, t()]), + io:format("EXPECT trap" + "~n with" + "~n Enterp: ~w" + "~n Generic: ~w" + "~n Specific: ~w" + "~n Varbinds: ~w" + "~n within ~w~n", [Enterp, Generic, Specific, ExpVBs, To]), PureE = purify_oid(Enterp), case receive_trap(To) of #trappdu{enterprise = PureE, @@ -916,49 +932,51 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) (is_list(ExpVBs) orelse (ExpVBs =:= any)) andalso (is_integer(To) orelse (To =:= infinity)) -> - io:format("~w:do_expect2 -> entry with" - "~n Type: ~w" - "~n Err: ~w" - "~n Idx: ~w" - "~n ExpVBs: ~w" - "~n To: ~w" - "~nwhen" - "~n Time: ~w" - "~n", [?MODULE, Type, Err, Idx, ExpVBs, To, t()]), - case receive_pdu(To) of #pdu{type = Type, error_status = Err, error_index = Idx} when ExpVBs =:= any -> + io:format("EXPECT received expected pdu (1)~n", []), ok; #pdu{type = Type, request_id = ReqId, error_status = Err2, error_index = Idx} when ExpVBs =:= any -> + io:format("EXPECT received expected pdu with " + "unexpected error status (2): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{error_status = Err} when (Type =:= any) andalso (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu (3)~n", []), ok; #pdu{request_id = ReqId, error_status = Err2} when (Type =:= any) andalso (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu with " + "unexpected error status (4): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{type = Type, error_status = Err} when (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu (5)~n", []), ok; #pdu{type = Type, request_id = ReqId, error_status = Err2} when (Idx =:= any) andalso (ExpVBs =:= any) -> + io:format("EXPECT received expected pdu with " + "unexpected error status (6): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; #pdu{type = Type, @@ -967,8 +985,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> case lists:member(EI, Idx) of true -> + io:format("EXPECT received expected pdu with " + "expected error index (7)~n", []), ok; false -> + io:format("EXPECT received expected pdu with " + "unexpected error index (8): " + "~n Error Index: ~p~n", [EI]), {error, {unexpected_error_index, EI, Idx, ReqId}} end; @@ -978,8 +1001,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_index = EI} when is_list(Idx) andalso (ExpVBs =:= any) -> case lists:member(EI, Idx) of true -> + io:format("EXPECT received expected pdu with " + "unexpected error status (9): " + "~n Error Status: ~p~n", [Err2]), {error, {unexpected_error_status, Err, Err2, ReqId}}; false -> + io:format("EXPECT received expected pdu with " + "unexpected error (10): " + "~n Error Status: ~p" + "~n Error index: ~p~n", [Err2, EI]), {error, {unexpected_error, {Err, Idx}, {Err2, EI}, ReqId}} end; @@ -987,6 +1017,12 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) request_id = ReqId, error_status = Err2, error_index = Idx2} when ExpVBs =:= any -> + io:format("EXPECT received unexpected pdu with (11) " + "~n Type: ~p" + "~n ReqId: ~p" + "~n Errot status: ~p" + "~n Error index: ~p" + "~n", [Type2, ReqId, Err2, Idx2]), {error, {unexpected_pdu, {Type, Err, Idx}, {Type2, Err2, Idx2}, ReqId}}; @@ -995,11 +1031,26 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err, error_index = Idx, varbinds = VBs} = PDU -> + io:format("EXPECT received pdu (12): " + "~n [exp] Type: ~p" + "~n [exp] Error Status: ~p" + "~n [exp] Error Index: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p" + "~n", [Type, Err, Idx, VBs, ExpVBs]), Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); #pdu{type = Type, error_status = Err, varbinds = VBs} = PDU when Idx =:= any -> + io:format("EXPECT received pdu (13): " + "~n [exp] Type: ~p" + "~n [exp] Error Status: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p" + "~n", [Type, Err, VBs, ExpVBs]), Check(PDU, check_vbs(purify_oids(ExpVBs), VBs)); #pdu{type = Type, @@ -1007,6 +1058,15 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err, error_index = EI, varbinds = VBs} = PDU when is_list(Idx) -> + io:format("EXPECT received pdu (14): " + "~n [exp] Type: ~p" + "~n ReqId: ~p" + "~n [exp] Error Status: ~p" + "~n [exp] Error Index: ~p" + "~n VBs: ~p" + "~nwhen" + "~n ExpVBs: ~p" + "~n", [Type, ReqId, Err, EI, VBs, ExpVBs]), PureVBs = purify_oids(ExpVBs), case lists:member(EI, Idx) of true -> @@ -1020,6 +1080,13 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) error_status = Err2, error_index = Idx2, varbinds = VBs2} -> + io:format("EXPECT received unexpected pdu with (15) " + "~n Type: ~p" + "~n ReqId: ~p" + "~n Errot status: ~p" + "~n Error index: ~p" + "~n Varbinds: ~p" + "~n", [Type2, ReqId, Err2, Idx2, VBs2]), {error, {unexpected_pdu, {Type, Err, Idx, purify_oids(ExpVBs)}, @@ -1027,6 +1094,9 @@ do_expect2(Check, Type, Err, Idx, ExpVBs, To) ReqId}}; Error -> + io:format("EXPECT received error (16): " + "~n Error: ~p" + "~n", [Error]), Error end. @@ -1466,7 +1536,7 @@ rpc(Node, F, A) -> %% %% %% t() -> -%% {A,B,C} = erlang:now(), +%% {A,B,C} = os:timestamp(), %% A*1000000000+B*1000+(C div 1000). %% %% @@ -1478,6 +1548,6 @@ rpc(Node, F, A) -> %% Time in milli seconds -t() -> - {A,B,C} = erlang:now(), - A*1000000000+B*1000+(C div 1000). +%% t() -> +%% {A,B,C} = os:timestamp(), +%% A*1000000000+B*1000+(C div 1000). diff --git a/lib/snmp/test/snmp_compiler_test.erl b/lib/snmp/test/snmp_compiler_test.erl index 2e6020ae7a..0a147130b0 100644 --- a/lib/snmp/test/snmp_compiler_test.erl +++ b/lib/snmp/test/snmp_compiler_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2011. All Rights Reserved. +%% Copyright Ericsson AB 2003-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -47,6 +47,7 @@ module_identity/1, agent_capabilities/1, module_compliance/1, + warnings_as_errors/1, otp_6150/1, otp_8574/1, @@ -97,9 +98,10 @@ all() -> description, oid_conflicts, imports, - module_identity, - agent_capabilities, - module_compliance, + module_identity, + agent_capabilities, + module_compliance, + warnings_as_errors, {group, tickets} ]. @@ -152,6 +154,8 @@ description(Config) when is_list(Config) -> ok. +%%====================================================================== + oid_conflicts(suite) -> []; oid_conflicts(Config) when is_list(Config) -> put(tname,oid_conflicts), @@ -165,18 +169,24 @@ oid_conflicts(Config) when is_list(Config) -> ok. +%%====================================================================== + imports(suite) -> []; imports(Config) when is_list(Config) -> ?SKIP(not_yet_implemented). +%%====================================================================== + module_identity(suite) -> []; module_identity(Config) when is_list(Config) -> ?SKIP(not_yet_implemented). +%%====================================================================== + agent_capabilities(suite) -> []; agent_capabilities(Config) when is_list(Config) -> @@ -218,6 +228,8 @@ agent_capabilities(Config) when is_list(Config) -> ok. +%%====================================================================== + module_compliance(suite) -> []; module_compliance(Config) when is_list(Config) -> @@ -259,6 +271,32 @@ module_compliance(Config) when is_list(Config) -> ok. +%%====================================================================== + +warnings_as_errors(suite) -> + ["OTP-9437"]; +warnings_as_errors(Config) when is_list(Config) -> + put(tname,warnings_as_errors), + p("starting with Config: ~p~n", [Config]), + Dir = ?config(comp_dir, Config), + MibDir = ?config(mib_dir, Config), + MibFile = join(MibDir, "OTP8574-MIB.mib"), + OutFile = join(Dir, "OTP8574-MIB.bin"), + Opts = [{group_check, false}, + {outdir, Dir}, + {verbosity, trace}, + relaxed_row_name_assign_check], + {error, compilation_failed} = + snmpc:compile(MibFile, [warnings_as_errors|Opts]), + false = filelib:is_regular(OutFile), + {ok, _} = snmpc:compile(MibFile, Opts), + true = filelib:is_regular(OutFile), + ok = file:delete(OutFile), + ok. + + +%%====================================================================== + otp_6150(suite) -> []; otp_6150(Config) when is_list(Config) -> @@ -273,6 +311,8 @@ otp_6150(Config) when is_list(Config) -> ok. +%%====================================================================== + otp_8574(suite) -> []; otp_8574(Config) when is_list(Config) -> @@ -304,6 +344,8 @@ otp_8574(Config) when is_list(Config) -> end. +%%====================================================================== + otp_8595(suite) -> []; otp_8595(Config) when is_list(Config) -> @@ -524,14 +566,7 @@ p(F, A) -> p(TName, F, A) -> io:format("*** [~w][~s] ***" - "~n" ++ F ++ "~n", [TName,format_timestamp(now())|A]). - -format_timestamp({_N1, _N2, N3} = Now) -> - {Date, Time} = calendar:now_to_datetime(Now), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", - [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), - lists:flatten(FormatDate). + "~n" ++ F ++ "~n", [TName, formated_timestamp()|A]). +formated_timestamp() -> + snmp_test_lib:formated_timestamp(). diff --git a/lib/snmp/test/snmp_manager_config_test.erl b/lib/snmp/test/snmp_manager_config_test.erl index 4498d506f3..3192fe1b40 100644 --- a/lib/snmp/test/snmp_manager_config_test.erl +++ b/lib/snmp/test/snmp_manager_config_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2004-2011. All Rights Reserved. +%% Copyright Ericsson AB 2004-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -2726,14 +2726,7 @@ p(F, A) -> p(TName, F, A) -> io:format("*** [~s] ***" - " ~w -> " ++ F ++ "~n", [format_timestamp(now()),TName|A]). - -format_timestamp({_N1, _N2, N3} = Now) -> - {Date, Time} = calendar:now_to_datetime(Now), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", - [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), - lists:flatten(FormatDate). + " ~w -> " ++ F ++ "~n", [formated_timestamp(),TName|A]). +formated_timestamp() -> + snmp_test_lib:formated_timestamp(). diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 0b536748fb..75c9f7b277 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2003-2011. All Rights Reserved. +%% Copyright Ericsson AB 2003-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -61,6 +61,7 @@ register_agent1/1, register_agent2/1, + register_agent3/1, info/1, @@ -383,12 +384,12 @@ end_per_testcase2(Case, Config) -> all() -> [ {group, start_and_stop_tests}, - {group, misc_tests}, + {group, misc_tests}, {group, user_tests}, - {group, agent_tests}, + {group, agent_tests}, {group, request_tests}, {group, event_tests}, - discovery, + discovery, {group, tickets} ]. @@ -417,7 +418,8 @@ groups() -> {agent_tests, [], [ register_agent1, - register_agent2 + register_agent2, + register_agent3 ] }, {request_tests, [], @@ -477,14 +479,14 @@ groups() -> }, {event_tests, [], [ - trap1, - trap2, - inform1, - inform2, - inform3, - inform4, - inform_swarm, - report + trap1%% , + %% trap2, + %% inform1, + %% inform2, + %% inform3, + %% inform4, + %% inform_swarm, + %% report ] }, {tickets, [], @@ -1134,6 +1136,7 @@ register_agent1(suite) -> register_agent1(Config) when is_list(Config) -> process_flag(trap_exit, true), put(tname,ra1), + p("starting with Config: ~p~n", [Config]), ManagerNode = start_manager_node(), @@ -1164,7 +1167,7 @@ register_agent1(Config) when is_list(Config) -> p("manager info: ~p~n", [mgr_info(ManagerNode)]), - p("register user(s) calvin & hobbe"), + p("register user(s) user_alfa & user_beta"), ?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []), ?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []), p("manager info: ~p~n", [mgr_info(ManagerNode)]), @@ -1293,7 +1296,7 @@ register_agent2(Config) when is_list(Config) -> p("manager info: ~p~n", [mgr_info(ManagerNode)]), - p("register user(s) calvin & hobbe"), + p("register user(s) user_alfa & user_beta"), ?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []), ?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []), p("manager info: ~p~n", [mgr_info(ManagerNode)]), @@ -1348,7 +1351,7 @@ register_agent2(Config) when is_list(Config) -> end, p("manager info: ~p~n", [mgr_info(ManagerNode)]), - + p("unregister user user_alfa"), ?line ok = mgr_unregister_user(ManagerNode, user_alfa), @@ -1377,7 +1380,157 @@ register_agent2(Config) when is_list(Config) -> p("manager info: ~p~n", [mgr_info(ManagerNode)]), - p("unregister user hobbe"), + p("unregister user user_beta"), + ?line ok = mgr_unregister_user(ManagerNode, user_beta), + + p("manager info: ~p~n", [mgr_info(ManagerNode)]), + + ?SLEEP(1000), + + p("stop snmp application (with only manager)"), + ?line ok = stop_snmp(ManagerNode), + + ?SLEEP(1000), + + stop_node(ManagerNode), + + ?SLEEP(1000), + + p("end"), + ok. + + +%%====================================================================== + +register_agent3(doc) -> + ["Test registration of agents with the NEW interface functions " + "and specifying transport domain"]; +register_agent3(suite) -> + []; +register_agent3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, ra3), + p("starting with Config: ~p~n", [Config]), + + ManagerNode = start_manager_node(), + + ConfDir = ?config(manager_conf_dir, Config), + DbDir = ?config(manager_db_dir, Config), + LocalHost = snmp_test_lib:localhost(), + + + write_manager_conf(ConfDir), + + Opts = [{server, [{verbosity, trace}]}, + {net_if, [{verbosity, trace}]}, + {note_store, [{verbosity, trace}]}, + {config, [{verbosity, trace}, {dir, ConfDir}, {db_dir, DbDir}]}], + + + p("load snmp application"), + ?line ok = load_snmp(ManagerNode), + + p("set manager env for the snmp application"), + ?line ok = set_mgr_env(ManagerNode, Opts), + + p("starting snmp application (with only manager)"), + ?line ok = start_snmp(ManagerNode), + + p("started"), + + ?SLEEP(1000), + + p("manager info: ~p~n", [mgr_info(ManagerNode)]), + + p("register user(s) user_alfa & user_beta"), + ?line ok = mgr_register_user(ManagerNode, user_alfa, snmpm_user_default, []), + ?line ok = mgr_register_user(ManagerNode, user_beta, snmpm_user_default, []), + p("manager info: ~p~n", [mgr_info(ManagerNode)]), + + p("register agent(s)"), + TargetName1 = "agent2", + ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName1, + [{tdomain, transportDomainUdpIpv4}, + {address, LocalHost}, + {port, 5001}, + {engine_id, "agentEngineId-1"}]), + TargetName2 = "agent3", + ?line ok = mgr_register_agent(ManagerNode, user_alfa, TargetName2, + [{tdomain, transportDomainUdpIpv6}, + {address, LocalHost}, + {port, 5002}, + {engine_id, "agentEngineId-2"}]), + TargetName3 = "agent4", + ?line {error, {unsupported_domain, _} = Reason4} = + mgr_register_agent(ManagerNode, user_beta, TargetName3, + [{tdomain, transportDomainTcpIpv4}, + {address, LocalHost}, + {port, 5003}, + {engine_id, "agentEngineId-3"}]), + p("Expected registration failure: ~p", [Reason4]), + TargetName4 = "agent5", + ?line {error, {unknown_domain, _} = Reason5} = + mgr_register_agent(ManagerNode, user_beta, TargetName4, + [{tdomain, transportDomainUdpIpv4_bad}, + {address, LocalHost}, + {port, 5004}, + {engine_id, "agentEngineId-4"}]), + p("Expected registration failure: ~p", [Reason5]), + + p("verify all agent(s): expect 2"), + case mgr_which_agents(ManagerNode) of + Agents1 when length(Agents1) =:= 2 -> + p("all agents: ~p~n", [Agents1]), + ok; + Agents1 -> + ?FAIL({agent_registration_failure, Agents1}) + end, + + p("verify user_alfa agent(s)"), + case mgr_which_agents(ManagerNode, user_alfa) of + Agents2 when length(Agents2) =:= 2 -> + p("calvin agents: ~p~n", [Agents2]), + ok; + Agents2 -> + ?FAIL({agent_registration_failure, Agents2}) + end, + + p("verify user_beta agent(s)"), + case mgr_which_agents(ManagerNode, user_beta) of + Agents3 when length(Agents3) =:= 0 -> + p("hobbe agents: ~p~n", [Agents3]), + ok; + Agents3 -> + ?FAIL({agent_registration_failure, Agents3}) + end, + + p("manager info: ~p~n", [mgr_info(ManagerNode)]), + + p("unregister user user_alfa"), + ?line ok = mgr_unregister_user(ManagerNode, user_alfa), + + p("verify all agent(s): expect 0"), + case mgr_which_agents(ManagerNode) of + Agents4 when length(Agents4) =:= 0 -> + p("all agents: ~p~n", [Agents4]), + ok; + Agents4 -> + ?FAIL({agent_unregistration_failure, Agents4}) + end, + p("manager info: ~p~n", [mgr_info(ManagerNode)]), + + p("verify all agent(s): expect 0"), + case mgr_which_agents(ManagerNode) of + [] -> + ok; + Agents5 -> + p("all agents: ~p~n", [Agents5]), + ?FAIL({agent_unregistration_failure, Agents5}) + end, + + p("manager info: ~p~n", [mgr_info(ManagerNode)]), + + p("unregister user user_beta"), ?line ok = mgr_unregister_user(ManagerNode, user_beta), p("manager info: ~p~n", [mgr_info(ManagerNode)]), @@ -5911,7 +6064,7 @@ rcall(Node, Mod, Func, Args) -> %% Time in milli sec %% t() -> -%% {A,B,C} = erlang:now(), +%% {A,B,C} = os:timestamp(), %% A*1000000000+B*1000+(C div 1000). @@ -5925,16 +6078,10 @@ p(F, A) -> p(TName, F, A) -> io:format("*** [~w][~s] ***" - "~n" ++ F ++ "~n", [TName,format_timestamp(now())|A]). - -format_timestamp({_N1, _N2, N3} = Now) -> - {Date, Time} = calendar:now_to_datetime(Now), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", - [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), - lists:flatten(FormatDate). + "~n" ++ F ++ "~n", [TName, formated_timestamp()|A]). + +formated_timestamp() -> + snmp_test_lib:formated_timestamp(). %% p(TName, F, A) -> %% io:format("~w -> " ++ F ++ "~n", [TName|A]). diff --git a/lib/snmp/test/snmp_test_lib.erl b/lib/snmp/test/snmp_test_lib.erl index 54839d989b..e4d58a1253 100644 --- a/lib/snmp/test/snmp_test_lib.erl +++ b/lib/snmp/test/snmp_test_lib.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2010. All Rights Reserved. +%% Copyright Ericsson AB 2002-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -37,7 +37,7 @@ -export([watchdog/3, watchdog_start/1, watchdog_start/2, watchdog_stop/1]). -export([del_dir/1]). -export([cover/1]). --export([p/2, print/5]). +-export([p/2, print/5, formated_timestamp/0]). %% ---------------------------------------------------------------------- @@ -521,15 +521,18 @@ p(F, A) when is_list(F) andalso is_list(A) -> print(Prefix, Module, Line, Format, Args) -> io:format("*** [~s] ~s ~p ~p ~p:~p *** " ++ Format ++ "~n", - [format_timestamp(now()), + [formated_timestamp(), Prefix, node(), self(), Module, Line|Args]). +formated_timestamp() -> + format_timestamp(os:timestamp()). + format_timestamp({_N1, _N2, N3} = Now) -> {Date, Time} = calendar:now_to_datetime(Now), {YYYY,MM,DD} = Date, {Hour,Min,Sec} = Time, FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", + io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w ~w", [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), lists:flatten(FormatDate). diff --git a/lib/snmp/test/snmp_test_mgr.erl b/lib/snmp/test/snmp_test_mgr.erl index 84bdc6b04f..499cf7abcf 100644 --- a/lib/snmp/test/snmp_test_mgr.erl +++ b/lib/snmp/test/snmp_test_mgr.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2010. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -1124,16 +1124,11 @@ d(F,A) -> d(get(debug),F,A). d(true,F,A) -> io:format("*** [~s] MGR_DBG *** " ++ F ++ "~n", - [format_timestamp(now())|A]); + [formated_timestamp()|A]); d(_,_F,_A) -> ok. -format_timestamp({_N1, _N2, N3} = Now) -> - {Date, Time} = calendar:now_to_datetime(Now), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", - [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), - lists:flatten(FormatDate). + +formated_timestamp() -> + snmp_test_lib:formated_timestamp(). diff --git a/lib/snmp/test/snmp_test_mgr_misc.erl b/lib/snmp/test/snmp_test_mgr_misc.erl index fc6dedd96d..5525c5c3ec 100644 --- a/lib/snmp/test/snmp_test_mgr_misc.erl +++ b/lib/snmp/test/snmp_test_mgr_misc.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1996-2011. All Rights Reserved. +%% Copyright Ericsson AB 1996-2012. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -779,16 +779,9 @@ d(F,A) -> d(get(debug),F,A). d(true,F,A) -> io:format("*** [~s] MGR_PS_DBG *** " ++ F ++ "~n", - [format_timestamp(now())|A]); + [formated_timestamp()|A]); d(_,_F,_A) -> ok. -format_timestamp({_N1, _N2, N3} = Now) -> - {Date, Time} = calendar:now_to_datetime(Now), - {YYYY,MM,DD} = Date, - {Hour,Min,Sec} = Time, - FormatDate = - io_lib:format("~.4w:~.2.0w:~.2.0w ~.2.0w:~.2.0w:~.2.0w 4~w", - [YYYY,MM,DD,Hour,Min,Sec,round(N3/1000)]), - lists:flatten(FormatDate). - +formated_timestamp() -> + snmp_test_lib:formated_timestamp(). diff --git a/lib/snmp/test/test_config/Makefile b/lib/snmp/test/test_config/Makefile index d7bebbc431..d65bb8abe2 100644 --- a/lib/snmp/test/test_config/Makefile +++ b/lib/snmp/test/test_config/Makefile @@ -155,23 +155,23 @@ release_spec: release_tests_spec: clean opt $(INSTALL_DIR) $(RELSYSDIR) - chmod -f -R u+w $(RELSYSDIR) + chmod -R u+w $(RELSYSDIR) $(INSTALL_DIR) $(RELSYSDIR)/agent - chmod -f -R u+w $(RELSYSDIR)/agent + chmod -R u+w $(RELSYSDIR)/agent $(INSTALL_DIR) $(RELSYSDIR)/agent/conf - chmod -f -R u+w $(RELSYSDIR)/agent/conf + chmod -R u+w $(RELSYSDIR)/agent/conf $(INSTALL_DIR) $(RELSYSDIR)/agent/db - chmod -f -R u+w $(RELSYSDIR)/agent/db + chmod -R u+w $(RELSYSDIR)/agent/db $(INSTALL_DIR) $(RELSYSDIR)/agent/log - chmod -f -R u+w $(RELSYSDIR)/agent/log + chmod -R u+w $(RELSYSDIR)/agent/log $(INSTALL_DIR) $(RELSYSDIR)/manager - chmod -f -R u+w $(RELSYSDIR)/manager + chmod -R u+w $(RELSYSDIR)/manager $(INSTALL_DIR) $(RELSYSDIR)/manager/conf - chmod -f -R u+w $(RELSYSDIR)/manager/conf + chmod -R u+w $(RELSYSDIR)/manager/conf $(INSTALL_DIR) $(RELSYSDIR)/manager/db - chmod -f -R u+w $(RELSYSDIR)/manager/db + chmod -R u+w $(RELSYSDIR)/manager/db $(INSTALL_DIR) $(RELSYSDIR)/manager/log - chmod -f -R u+w $(RELSYSDIR)/manager/log + chmod -R u+w $(RELSYSDIR)/manager/log $(INSTALL_DATA) $(SYS_CONFIG_FILES) $(RELSYSDIR) $(INSTALL_DATA) $(AGENT_CONFIG_FILES) $(RELSYSDIR)/agent/conf $(INSTALL_DATA) $(MANAGER_CONFIG_FILES) $(RELSYSDIR)/manager/conf diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index 29228fc59b..1fbad654f7 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -2,7 +2,7 @@ # %CopyrightBegin% # -# Copyright Ericsson AB 1997-2011. All Rights Reserved. +# Copyright Ericsson AB 1997-2012. All Rights Reserved. # # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in @@ -17,6 +17,8 @@ # # %CopyrightEnd% -SNMP_VSN = 4.20 -PRE_VSN = -APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" +APPLICATION = snmp +SNMP_VSN = 4.21.6 +PRE_VSN = +APP_VSN = "$(APPLICATION)-$(SNMP_VSN)$(PRE_VSN)" + |