diff options
author | Micael Karlberg <[email protected]> | 2011-05-16 10:09:25 +0200 |
---|---|---|
committer | Micael Karlberg <[email protected]> | 2011-05-16 10:09:25 +0200 |
commit | 3e907e4468651206b8c6c97290e37a5a82102e2f (patch) | |
tree | b9a39fe5fc37c32313f7ae89f2f98a4a68ccfd40 | |
parent | b19a2c6648e65b5ad1b8a0351928856fad941f99 (diff) | |
parent | c2a1108ff4cfdb2a5763349e4f505bed49871cc8 (diff) | |
download | otp-3e907e4468651206b8c6c97290e37a5a82102e2f.tar.gz otp-3e907e4468651206b8c6c97290e37a5a82102e2f.tar.bz2 otp-3e907e4468651206b8c6c97290e37a5a82102e2f.zip |
OTP-9022: Fixed endode/decode of values of type Counter32.
OTP-9088: [agent] Added support for sending traps to IPv6 targets.
OTP-9119: [agent] To be able to handle multiple engine-id(s) when
sending trap(s), the function
snmp_community_mib:add_community/6 has been added.
OTP-9162: [manager] The API for snmp requests has been augmented to
allow the caller to override some configuration.
OTP-9174: [manager] The old API functions (for get and set
requests) are now officially deprecated.
OTP-9183: [agent] Pass extra info through the agent to the net-if
process when sending notifications.
OTP-9208: Added type specs for functions that do not return.
Kostis Sagonas
Merge branch 'bmk/snmp/snmp420_integration' into dev
44 files changed, 4740 insertions, 1363 deletions
diff --git a/lib/snmp/doc/src/files.mk b/lib/snmp/doc/src/files.mk index bd94cd6bac..61c91c9729 100644 --- a/lib/snmp/doc/src/files.mk +++ b/lib/snmp/doc/src/files.mk @@ -157,4 +157,5 @@ MIB_FILES = \ $(MIBSDIR)/SNMP-VIEW-BASED-ACM-MIB.mib \ $(MIBSDIR)/SNMP-USM-AES-MIB.mib \ $(MIBSDIR)/INET-ADDRESS-MIB.mib \ + $(MIBSDIR)/TRANSPORT-ADDRESS-MIB.mib \ $(MIBSDIR)/OTP-SNMPEA-MIB.mib diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml index 2efeb8ae3f..c1debd42b1 100644 --- a/lib/snmp/doc/src/notes.xml +++ b/lib/snmp/doc/src/notes.xml @@ -33,6 +33,123 @@ </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> + + <section> + <title>Improvements and new features</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> + + <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> + + <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> + </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> +<!-- + <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> + <p>Own Id: OTP-8980</p> + </item> + + </list> +--> + </section> + + + <section> + <title>Incompatibilities</title> + <p>-</p> + </section> + + </section> <!-- 4.20 --> + + + <section> <title>SNMP Development Toolkit 4.19</title> <p>Version 4.19 supports code replacement in runtime from/to version 4.18.</p> @@ -126,6 +243,7 @@ snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). </section> <!-- 4.19 --> + <section> <title>SNMP Development Toolkit 4.18</title> <p>Version 4.18 supports code replacement in runtime from/to @@ -226,7 +344,7 @@ snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). <p>The config utility (<seealso marker="snmp#config">snmp:config/0</seealso>) generated a default notify.conf - with a bad name for the starndard trap entry (was "stadard trap", + 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> @@ -430,7 +548,7 @@ snmp_view_basec_acm_mib:vacmAccessTable(set, RowIndex, Cols). <p>The config utility (<seealso marker="snmp#config">snmp:config/0</seealso>) generated a default notify.conf - with a bad name for the starndard trap entry (was "stadard trap", + 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> diff --git a/lib/snmp/doc/src/snmp_agent_config_files.xml b/lib/snmp/doc/src/snmp_agent_config_files.xml index b62269d506..bd5c537522 100644 --- a/lib/snmp/doc/src/snmp_agent_config_files.xml +++ b/lib/snmp/doc/src/snmp_agent_config_files.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> @@ -367,56 +367,50 @@ <marker id="target_addr"></marker> <title>Target Address Definitions</title> <p>The information about Target Address Definitions should be - stored in a file called - <c>target_addr.conf</c>. - </p> + stored in a file called <c>target_addr.conf</c>. </p> <p>The corresponding tables are <c>snmpTargetAddrTable</c> in the - SNMP-TARGET-MIB and <c>snmpTargetAddrExtTable</c> in the SNMP-COMMUNITY-MIB. - </p> - <p>Each entry is a term: - </p> - <p><c>{TargetName, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId}.</c> or <br></br> -<c>{TargetName, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}.</c></p> + SNMP-TARGET-MIB and <c>snmpTargetAddrExtTable</c> in the + SNMP-COMMUNITY-MIB. </p> + <p>Each entry is a term: </p> + <p><c>{TargetName, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId}.</c> <br></br> or <br></br> +<c>{TargetName, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}.</c> <br></br> or <br></br> +<c>{TargetName, Domain, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}.</c></p> <list type="bulleted"> <item> <p><c>TargetName</c> is a unique non-empty string. </p> </item> <item> - <p><c>Ip</c> is a list of four integers. - </p> + <p><c>Domain</c> is one of the atoms: + <c>transportDomainUdpIpv4</c> | <c>transportDomainUdpIpv6</c>. </p> </item> <item> - <p><c>Udp</c> is an integer. - </p> + <p><c>Ip</c> is a list of four or eight integers. </p> </item> <item> - <p><c>Timeout</c> is an integer. - </p> + <p><c>Udp</c> is an integer. </p> </item> <item> - <p><c>RetryCount</c> is an integer. - </p> + <p><c>Timeout</c> is an integer. </p> </item> <item> - <p><c>TagList</c> is a string. - </p> + <p><c>RetryCount</c> is an integer. </p> </item> <item> - <p><c>ParamsName</c> is a string. - </p> + <p><c>TagList</c> is a string. </p> </item> <item> - <p><c>EngineId</c> is a string or the atom <c>discovery</c>. - </p> + <p><c>ParamsName</c> is a string. </p> </item> <item> - <p><c>TMask</c> is a string of size 0, or size 6 (default: []). - </p> + <p><c>EngineId</c> is a string or the atom <c>discovery</c>. </p> </item> <item> - <p><c>MaxMessageSize</c> is an integer (default: 2048). - </p> + <p><c>TMask</c> is a list of integer() of size 0, + size 6 or size 10 (default: []). </p> + </item> + <item> + <p><c>MaxMessageSize</c> is an integer (default: 2048). </p> </item> </list> <p>Note that if <c>EngineId</c> has the value <c>discovery</c>, @@ -429,14 +423,10 @@ <marker id="target_params"></marker> <title>Target Parameters Definitions</title> <p>The information about Target Parameters Definitions should be - stored in a file called - <c>target_params.conf</c>. - </p> + stored in a file called <c>target_params.conf</c>. </p> <p>The corresponding table is <c>snmpTargetParamsTable</c> in the - SNMP-TARGET-MIB. - </p> - <p>Each entry is a term: - </p> + SNMP-TARGET-MIB. </p> + <p>Each entry is a term: </p> <p><c>{ParamsName, MPModel, SecurityModel, SecurityName, SecurityLevel}.</c></p> <list type="bulleted"> <item> diff --git a/lib/snmp/doc/src/snmp_agent_netif.xml b/lib/snmp/doc/src/snmp_agent_netif.xml index 1f2dbe80db..d751740a82 100644 --- a/lib/snmp/doc/src/snmp_agent_netif.xml +++ b/lib/snmp/doc/src/snmp_agent_netif.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE chapter SYSTEM "chapter.dtd"> <chapter> @@ -65,16 +65,19 @@ </section> <section> + <marker id="messages"></marker> <title>Messages</title> <p>The section <em>Messages</em> describes mandatory messages, which Net if must send and be able to receive. </p> <section> + <marker id="outgoing_messages"></marker> <title>Outgoing Messages</title> <p>Net if must send the following message when it receives an - SNMP PDU from the network that is aimed for the MasterAgent: - </p> + SNMP PDU from the network that is aimed for the MasterAgent: + </p> + <marker id="om_snmp_pdu"></marker> <pre> MasterAgent ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, Extra} </pre> @@ -106,9 +109,10 @@ MasterAgent ! {snmp_pdu, Vsn, Pdu, PduMS, ACMData, From, Extra} the request.</item> </list> <p>The following message is used to report that a response to a - request has been received. The only request an agent can send - is an Inform-Request. - </p> + request has been received. The only request an agent can send + is an Inform-Request. + </p> + <marker id="om_snmp_response_received"></marker> <pre> Pid ! {snmp_response_received, Vsn, Pdu, From} </pre> @@ -131,119 +135,153 @@ Pid ! {snmp_response_received, Vsn, Pdu, From} </section> <section> + <marker id="incoming_messages"></marker> <title>Incoming Messages</title> <p>This section describes the incoming messages which a Net if - process must be able to receive. - </p> + process must be able to receive. + </p> <list type="bulleted"> <item> + <marker id="im_snmp_response"></marker> <p><c>{snmp_response, Vsn, Pdu, Type, ACMData, To, Extra}</c></p> <p>This message is sent to the Net if process from a master agent as a response to a previously received request. </p> <list type="bulleted"> - <item><c>Vsn</c> is either <c>'version-1'</c>, - <c>'version-2'</c>, or <c>'version-3'</c>. + <item> + <p><c>Vsn</c> is either <c>'version-1'</c>, + <c>'version-2'</c>, or <c>'version-3'</c>. </p> </item> - <item><c>Pdu</c> is an SNMP PDU record (as defined in - snmp_types.hrl) with the SNMP response. + <item> + <p><c>Pdu</c> is an SNMP PDU record (as defined in + snmp_types.hrl) with the SNMP response. </p> </item> - <item><c>Type</c> is the <c>#pdu.type</c> of the original - request. + <item> + <p><c>Type</c> is the <c>#pdu.type</c> + of the original request. </p> </item> - <item><c>ACMData</c> is data used by the Access Control - Module in use. Normally this is just sent to - <c>snmpa_mpd:generate_response_message</c> (see Reference Manual). + <item> + <p><c>ACMData</c> is data used by the Access Control + Module in use. Normally this is just sent to + <c>snmpa_mpd:generate_response_message</c> + (see Reference Manual). </p> </item> - <item><c>To</c> is the destination address. If UDP over IP - is used, this should be a 2-tuple <c>{IP, UDPport}</c>, - where <c>IP</c> is a 4-tuple with the IP address, and - <c>UDPport</c> is an integer. + <item> + <p><c>To</c> is the destination address. If UDP over IP + is used, this should be a 2-tuple <c>{IP, UDPport}</c>, + where <c>IP</c> is a 4-tuple with the IP address, and + <c>UDPport</c> is an integer. </p> </item> - <item><c>Extra</c> is the term that the Net if process - sent to the agent when the request was sent to the agent. + <item> + <p><c>Extra</c> is the term that the Net if process + sent to the agent when the request was sent to the agent. </p> </item> </list> </item> <item> + <marker id="im_discarded_pdu"></marker> <p><c>{discarded_pdu, Vsn, ReqId, ACMData, Variable, Extra}</c></p> <p>This message is sent from a master agent if it for some - reason decided to discard the pdu. - </p> + reason decided to discard the pdu. </p> <list type="bulleted"> - <item><c>Vsn</c> is either <c>'version-1'</c>, - <c>'version-2'</c>, or <c>'version-3'</c>. + <item> + <p><c>Vsn</c> is either <c>'version-1'</c>, + <c>'version-2'</c>, or <c>'version-3'</c>. </p> </item> - <item><c>ReqId</c> is the request id of the original - request. + <item> + <p><c>ReqId</c> is the request id of the original request. </p> </item> - <item><c>ACMData</c> is data used by the Access Control - Module in use. Normally this is just sent to - <c>snmpa_mpd:generate_response_message</c> (see Reference Manual). + <item> + <p><c>ACMData</c> is data used by the Access Control + Module in use. Normally this is just sent to + <c>snmpa_mpd:generate_response_message</c> + (see Reference Manual). </p> </item> - <item><c>Variable</c> is the name of an snmp counter that - represents the error, e.g. <c>snmpInBadCommunityUses</c>. + <item> + <p><c>Variable</c> is the name of an snmp counter that + represents the error, e.g. <c>snmpInBadCommunityUses</c>. </p> </item> - <item><c>Extra</c> is the term that the Net if process - sent to the agent when the request was sent to the agent. + <item> + <p><c>Extra</c> is the term that the Net if process + sent to the agent when the request was sent to the agent. </p> </item> </list> </item> <item> - <p><c>{send_pdu, Vsn, Pdu, MsgData, To}</c></p> + <marker id="im_send_pdu"></marker> + <p><c>{send_pdu, Vsn, Pdu, MsgData, To, Extra}</c></p> <p>This message is sent from a master agent when a trap is - to be sent. - </p> + to be sent. </p> <list type="bulleted"> - <item><c>Vsn</c> is either <c>'version-1'</c>, - <c>'version-2'</c>, or <c>'version-3'</c>. + <item> + <p><c>Vsn</c> is either <c>'version-1'</c>, + <c>'version-2'</c>, or <c>'version-3'</c>.</p> </item> - <item><c>Pdu</c> is an SNMP PDU record (as defined in - snmp_types.hrl) with the SNMP response. + <item> + <p><c>Pdu</c> is an SNMP PDU record (as defined in + snmp_types.hrl) with the SNMP response. </p> + </item> + <item> + <p><c>MsgData</c> is the message specific data used in + the SNMP message. This value is normally sent to + <c>snmpa_mpd:generate_message/4</c>. In SNMPv1 and + SNMPv2c, this message data is the community string. In + SNMPv3, it is the context information. </p> </item> - <item><c>MsgData</c> is the message specific data used in - the SNMP message. This value is normally sent to - <c>snmpa_mpd:generate_message/4</c>. In SNMPv1 and - SNMPv2c, this message data is the community string. In - SNMPv3, it is the context information. + <item> + <p><c>To</c> is a list of the destination addresses and + their corresponding security parameters. This value is + normally sent to <c>snmpa_mpd:generate_message/4</c>. </p> </item> - <item><c>To</c> is a list of the destination addresses and - their corresponding security parameters. This value is - normally sent to <c>snmpa_mpd:generate_message/4</c>. + <item> + <p><c>Extra</c> is any term that the notification sender + wishes to pass to the Net if process when sending a notification + (see + <seealso marker="snmpa#send_notification2">send notification + </seealso> for more info). </p> </item> </list> </item> <item> - <p><c>{send_pdu_req, Vsn, Pdu, MsgData, To, Pid}</c></p> - <p>This <marker id="message"></marker> - message is sent from a master - agent when a request is - to be sent. The only request an agent can send is - Inform-Request. The net if process needs to remember the - request id and the Pid, and when a response is received for - the request id, send it to Pid, using a - <c>snmp_response_received</c> message. - </p> - <list type="bulleted"> - <item><c>Vsn</c> is either <c>'version-1'</c>, - <c>'version-2'</c>, or <c>'version-3'</c>. - </item> - <item><c>Pdu</c> is an SNMP PDU record (as defined in - snmp_types.hrl) with the SNMP response. - </item> - <item><c>MsgData</c> is the message specific data used in - the SNMP message. This value is normally sent to - <c>snmpa_mpd:generate_message/4</c>. In SNMPv1 and - SNMPv2c, this message data is the community string. In - SNMPv3, it is the context information. + <marker id="im_send_pdu_req"></marker> + <p><c>{send_pdu_req, Vsn, Pdu, MsgData, To, Pid, Extra}</c></p> + <p>This message is sent from a master agent when a request is to + be sent. The only request an agent can send is Inform-Request. + The net if process needs to remember the request id and the Pid, + and when a response is received for the request id, send it to Pid, + using a <c>snmp_response_received</c> message. </p> + <list type="bulleted"> + <item> + <p><c>Vsn</c> is either <c>'version-1'</c>, + <c>'version-2'</c>, or <c>'version-3'</c>.</p> + </item> + <item> + <p><c>Pdu</c> is an SNMP PDU record (as defined in + snmp_types.hrl) with the SNMP response. </p> + </item> + <item> + <p><c>MsgData</c> is the message specific data used in + the SNMP message. This value is normally sent to + <c>snmpa_mpd:generate_message/4</c>. In SNMPv1 and + SNMPv2c, this message data is the community string. In + SNMPv3, it is the context information. </p> + </item> + <item> + <p><c>To</c> is a list of the destination addresses and + their corresponding security parameters. This value is + normally sent to <c>snmpa_mpd:generate_message/4</c>. </p> + </item> + <item> + <p><c>Pid</c> is a process identifier. </p> + </item> + <item> + <p><c>Extra</c> is any term that the notification sender + wishes to pass to the Net if process when sending a notification + (see + <seealso marker="snmpa#send_notification2">send notification + </seealso> for more info). </p> </item> - <item><c>To</c> is a list of the destination addresses and - their corresponding security parameters. This value is - normally sent to <c>snmpa_mpd:generate_message/4</c>. - </item> - <item><c>Pid</c> is a process identifier. - </item> - </list> + </list> </item> </list> </section> diff --git a/lib/snmp/doc/src/snmp_community_mib.xml b/lib/snmp/doc/src/snmp_community_mib.xml index 7c7386af19..5e7bca3e27 100644 --- a/lib/snmp/doc/src/snmp_community_mib.xml +++ b/lib/snmp/doc/src/snmp_community_mib.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1999</year><year>2009</year> + <year>1999</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -35,11 +35,13 @@ <modulesummary>Instrumentation Functions for SNMP-COMMUNITY-MIB</modulesummary> <description> <p>The module <c>snmp_community_mib</c> implements the instrumentation - functions for the - SNMP-COMMUNITY-MIB, and functions for configuring the database. - </p> + functions for the SNMP-COMMUNITY-MIB, and functions for configuring the + database. </p> <p>The configuration files are described in the SNMP User's Manual.</p> + + <marker id="configure"></marker> </description> + <funcs> <func> <name>configure(ConfDir) -> void()</name> @@ -68,8 +70,11 @@ </p> <p>The configuration file read is: <c>community.conf</c>. </p> + + <marker id="reconfigure"></marker> </desc> </func> + <func> <name>reconfigure(ConfDir) -> void()</name> <fsummary>Configure the SNMP-COMMUNITY-MIB</fsummary> @@ -96,28 +101,35 @@ where the configuration files are found. </p> <p>The configuration file read is: <c>community.conf</c>.</p> + <marker id="add_community"></marker> </desc> </func> + <func> <name>add_community(Idx, CommName, SecName, CtxName, TransportTag) -> Ret</name> + <name>add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) -> Ret</name> <fsummary>Added one community</fsummary> <type> <v>Idx = string()</v> <v>CommName = string()</v> <v>SecName = string()</v> + <v>EngineId = string()</v> <v>CtxName = string()</v> <v>TransportTag = string()</v> <v>Ret = {ok, Key} | {error, Reason}</v> <v>Key = term()</v> - <v>Reason = term()</v> + <v>Reason = term()</v> </type> <desc> <p>Adds a community to the agent config. - Equivalent to one line in the <c>community.conf</c> file.</p> + Equivalent to one line in the <c>community.conf</c> file.</p> + <p>With the <c>EngineId</c> argument it is possible to + override the configured engine-id (SNMP-FRAMEWORK-MIB).</p> <marker id="delete_community"></marker> </desc> </func> + <func> <name>delete_community(Key) -> Ret</name> <fsummary>Delete one community</fsummary> diff --git a/lib/snmp/doc/src/snmp_target_mib.xml b/lib/snmp/doc/src/snmp_target_mib.xml index 4a36be19a3..d5151d41de 100644 --- a/lib/snmp/doc/src/snmp_target_mib.xml +++ b/lib/snmp/doc/src/snmp_target_mib.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>1998</year><year>2009</year> + <year>1998</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -39,9 +39,21 @@ and functions for configuring the database. </p> <p>The configuration files are described in the SNMP User's Manual.</p> - <marker id="configure"></marker> + <marker id="types"></marker> </description> + <section> + <title>DATA TYPES</title> + <code type="none"><![CDATA[ +transportDomain() = transportDomainUdpIpv4 | transportDomainUdpIpv6 +transportAddressIPv4() = [integer()], length 4 +transportAddressIPv6() = [integer()], length 8 +transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6) + ]]></code> + + <marker id="configure"></marker> + </section> + <funcs> <func> <name>configure(ConfDir) -> void()</name> @@ -118,17 +130,19 @@ <func> <name>add_addr(Name, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name> + <name>add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> Ret</name> <fsummary>Add one target address definition</fsummary> <type> <v>Name = string()</v> - <v>Ip = [integer()], length 4</v> + <v>Domain = transportDomain()</v> + <v>Ip = transportAddressIPv4() | transportAddressIPv6() (depends on the value of Domain)</v> <v>Port = integer()</v> <v>Timeout = integer()</v> <v>Retry = integer()</v> <v>TagList = string()</v> <v>ParamsName = string()</v> <v>EngineId = string()</v> - <v>TMask = string(), length 0 or 6</v> + <v>TMask = transportAddressMask() (depends on Domain)</v> <v>MMS = integer()</v> <v>Ret = {ok, Key} | {error, Reason}</v> <v>Key = term()</v> diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml index 1d680e80f5..27d89ea4e3 100644 --- a/lib/snmp/doc/src/snmpa.xml +++ b/lib/snmp/doc/src/snmpa.xml @@ -872,10 +872,138 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). then that sub-agent will be unregistered from all trees in <c>Agent</c>. </p> - <marker id="send_notification"></marker> + <marker id="send_notification2"></marker> </desc> </func> + + <func> + <name>send_notification2(Agent, Notification, SendOpts) -> void()</name> + <fsummary>Send notification</fsummary> + <type> + <v>Agent = pid() | atom()</v> + <v>Notification = atom()</v> + <v>SendOpts = [send_option()]</v> + <v>send_option() = {receiver, receiver()} | {name, notify_name()} | {context, context_name()} | {varbinds, varbinds()} | {local_engine_id, string()} | {extra, extra_info()}</v> + <v>receiver() = no_receiver | {tag(), tag_receiver()} | notification_delivery_info()</v> + <v>tag() = term(()</v> + <v>tag_receiver() = pid() | registered_name() | {Mod, Func, Args}</v> + <v>registered_name() = atom()</v> + <v>Mod = atom()</v> + <v>Func = atom()</v> + <v>Args = list()</v> + <v>notify_name() = string()</v> + <v>context_name() = string()</v> + <v>varbinds() = [varbind()]</v> + <v>varbind() = {variable(), value()} | {column(), row_index(), value()} | {oid(), value()}</v> + <v>variable() = atom()</v> + <v>value() = term()</v> + <v>column() = atom()</v> + <v>row_index() = [int()]</v> + <v>extra_info() = term()</v> + </type> + <desc> + <p>Send the notification <c>Notification</c> to the management + targets defined for notify-name (<c>name</c>) in the + <c>snmpNotifyTable</c> in SNMP-NOTIFICATION-MIB from the + specified <c>context</c>. </p> + + <p>If no <c>name</c> is specified (or if it is <c>""</c>), the + notification is sent to all management targets. </p> + + <p>If no <c>context</c> is specified, the default context, <c>""</c>, + is used. </p> + + <p>The send option <c>receiver</c> specifies where information + about delivery of Inform-Requests should be sent. The agent + sends Inform-Requests and waits for acknowledgments from the + management targets. + The <c>receiver</c> can have three values: </p> + + <list type="bulleted"> + <item> + <p><c>no_receiver</c> - No information is delivered. </p> + </item> + + <item> + <p><c>notification_delivery_info()</c> - The information is + delivered via a function call according to this data. See the + <seealso marker="#data_types">DATA TYPES</seealso> section + above for details. </p> + </item> + + <item> + <p><c>{tag(), tag_receiver()}</c> - The information is delivered + either via messages or via a function call according to the value + of <c>tag_receiver()</c>. </p> + <p>Delivery is done differently depending on the value + of <c>tag_receiver()</c>: </p> + + <list> + <item> + <p><c>pid() | registered_name()</c> - The info will be delivered in + the following messages: </p> + <list> + <item> + <p><c>{snmp_targets, tag(), Addresses}</c></p> + <p>This informs the user which target addresses the + notification was sent to. </p> + </item> + <item> + <p><c>{snmp_notification, tag(), {got_response, Address}}</c></p> + <p>This informs the user that this target address + acknowledged the notification. </p> + </item> + <item> + <p><c>{snmp_notification, tag(), {no_response, Address}}</c></p> + <p>This informs the user that this target address + did not acknowledge the notification. </p> + </item> + </list> + <p>The notification is sent as an Inform-Request to each + target address in <c>Addresses</c> and if there are no + targets for which an Inform-Request is sent, <c>Addresses</c> + is the empty list <c>[]</c>. </p> + <p>The <c>tag_receiver()</c> will first be sent the + <c>snmp_targets</c> message, and then for each address in + <c>Addresses</c> list, one of the two <c>snmp_notification</c> + messages. </p> + </item> + + <item> + <p><c>{Mod, Func, Args}</c> - The info will be delivered via + the function call: </p> + <p><c>Mod:Func([Msg | Args])</c></p> + <p>where <c>Msg</c> has the same content and purpose as the + messages descrived above.</p> + </item> + + </list> + </item> + </list> + + <note> + <p>The <c>extra</c> info is not normally interpreted by the agent, + instead it is passed through to the + <seealso marker="snmp_agent_netif">net-if</seealso> process. It is + up to the implementor of that process to make use of this data. </p> + <p>The version of net-if provided by this application makes no use + of this data, with one exception: + Any tuple containing the atom + <c>snmpa_default_notification_extra_info</c> + may be used by the agent and is therefor <em>reserved</em>. </p> + <p>See the net-if incomming messages for sending a + <seealso marker="snmp_agent_netif#im_send_pdu"> + trap</seealso> and + <seealso marker="snmp_agent_netif#im_send_pdu_req"> + notification</seealso> for more info. </p> + </note> + + <marker id="send_notification"></marker> + </desc> + </func> + + <func> <name>send_notification(Agent, Notification, Receiver)</name> <name>send_notification(Agent, Notification, Receiver, Varbinds)</name> @@ -907,18 +1035,19 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </type> <desc> <p>Sends the notification <c>Notification</c> to the - management targets defined for <c>NotifyName</c> in the - <c>snmpNotifyTable</c> in SNMP-NOTIFICATION-MIB from the - specified context. If no <c>NotifyName</c> is specified (or - if it is <c>""</c>), the notification is sent to all - management targets (<c>Addresses</c> below). If no <c>ContextName</c> - is specified, the default <c>""</c> context is used. - </p> + management targets defined for <c>NotifyName</c> in the + <c>snmpNotifyTable</c> in SNMP-NOTIFICATION-MIB from the + specified context. </p> + <p>If no <c>NotifyName</c> is specified (or if it is <c>""</c>), + the notification is sent to all management targets + (<c>Addresses</c> below). </p> + <p>If no <c>ContextName</c> is specified, the default <c>""</c> + context is used. </p> <p>The parameter <c>Receiver</c> specifies where information - about delivery of Inform-Requests should be sent. The agent - sends Inform-Requests and waits for acknowledgments from the - managers. <c>Receiver</c> can have three values: </p> + about delivery of Inform-Requests should be sent. The agent + sends Inform-Requests and waits for acknowledgments from the + managers. <c>Receiver</c> can have three values: </p> <list type="bulleted"> <item> @@ -926,17 +1055,18 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). </item> <item> - <p><c>{Tag, Recv}</c> - The information is delivered either via messages - or via a function call according to the value of <c>Recv</c>. </p> - </item> - - <item> <p><c>notification_delivery_info()</c> - The information is delivered via a function call according to this data. See the <seealso marker="#data_types">DATA TYPES</seealso> section above for details. </p> </item> + <item> + <p><c>{Tag, Recv}</c> - The information is delivered either via + messages or via a function call according to the value of + <c>Recv</c>. </p> + </item> + </list> @@ -1064,86 +1194,20 @@ snmp_agent:register_subagent(SA1,[1,2,3], SA2). (see SNMP-FRAMEWORK-MIB). </p> </note> -<!-- - <marker id="send_trap"></marker> ---> - <marker id="discovery"></marker> + <p><c>ExtraInfo</c> is not normally used in any way by the agent. + It is intended to be passed along to the net-if process, which is + a component that a user can implement themself. The users own net-if + may then make use of ExtraInfo. The net-if provided with this + application does not process ExtraInfo. </p> + <p>There is one exception. <em>Any</em> tuple containing the atom + <c>snmpa_default_notification_extra_info</c> will, in this context, + be considered belonging to this application, and may be processed + by the agent. </p> + + <marker id="discovery"></marker> </desc> </func> -<!-- - <func> - <name>send_trap(Agent,Trap,Community)</name> - <name>send_trap(Agent,Trap,Community,Varbinds) -> void()</name> - <fsummary>Send a trap</fsummary> - <type> - <v>Agent = pid() | atom()</v> - <v>Trap = atom()</v> - <v>Community = string()</v> - <v>Varbinds = [Varbind]</v> - <v>Varbind = {Variable, Value} | {Column, RowIndex, Value} | {OID, Value}</v> - <v>Variable = atom()</v> - <v>Column = atom()</v> - <v>OID = oid()</v> - <v>Value = term()</v> - <v>RowIndex = [int()]</v> - </type> - <desc> - <p>Note! This function is only kept for backwards - compatibility reasons. Use <c>send_notification</c> instead. - </p> - <p>Sends the trap <c>Trap</c> to the managers defined for - <c>Community</c> in the <c>intTrapDestTable</c> in - OTP-SNMPEA-MIB. The optional argument <c>Varbinds</c> defines - values for the objects in the trap. If no value is given for - an object, the <c>Agent</c> performs a get-operation to - retrieve the value. - </p> - <p><c>Varbinds</c> is a list of <c>Varbind</c>, where each - <c>Varbind</c> is one of: - </p> - <list type="bulleted"> - <item><c>{Variable, Value}</c>, where <c>Variable</c> is the - symbolic name of a scalar variable referred to in the trap - specification. - </item> - <item><c>{Column, RowIndex, Value}</c>, where <c>Column</c> - is the symbolic name of a column variable. - <c>RowIndex</c> is a list of indices for the specified - element. If this is the case, the OBJECT IDENTIFIER sent - in the trap is the <c>RowIndex</c> appended to the OBJECT - IDENTIFIER for the table column. This is the OBJECT - IDENTIFIER which specifies the element. - </item> - <item><c>{OID, Value}</c>, where <c>OID</c> is the OBJECT - IDENTIFIER for an instance of an object, scalar variable, - or column variable. - </item> - </list> - <p>For example, to specify that <c>sysLocation</c> should have the - value <c>"upstairs"</c> in the trap, we could use one of: - </p> - <list type="bulleted"> - <item><c>{sysLocation, "upstairs"}</c> or</item> - <item><c>{[1,3,6,1,2,1,1,6,0], "upstairs"}</c> or</item> - <item><c>{?sysLocation_instance, "upstairs"}</c> (provided - that the generated <c>.hrl</c> file is included)</item> - </list> - <p>If a variable in the trap is a table element, the - <c>RowIndex</c> for the element must be given in the - <c>Varbinds</c> list. In this case, the OBJECT IDENTIFIER sent - in the trap is the OBJECT IDENTIFIER that identifies this - element. This OBJECT IDENTIFIER could be used in a get - operation later. - </p> - <p>This function is asynchronous, and does not return any - information. If an error occurs, <c>snmp_error:user_err/2</c> - is called and the trap is discarded. </p> - - <marker id="discovery"></marker> - </desc> - </func> ---> <func> <name>discovery(TargetName, Notification) -> {ok, ManagerEngineID} | {error, Reason}</name> diff --git a/lib/snmp/doc/src/snmpa_conf.xml b/lib/snmp/doc/src/snmpa_conf.xml index d873574c6e..a533c179ee 100644 --- a/lib/snmp/doc/src/snmpa_conf.xml +++ b/lib/snmp/doc/src/snmpa_conf.xml @@ -1,10 +1,10 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> <header> <copyright> - <year>2006</year><year>2010</year> + <year>2006</year><year>2011</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -38,8 +38,21 @@ used for manipulating (write/append/read) the config files of the SNMP agent. </p> - <marker id="agent_entry"></marker> + <marker id="types"></marker> </description> + + <section> + <title>DATA TYPES</title> + <code type="none"><![CDATA[ +transportDomain() = transportDomainUdpIpv4 | transportDomainUdpIpv6 +transportAddressIPv4() = [integer()], length 4 +transportAddressIPv6() = [integer()], length 8 +transportAddressMask() = [integer()], length 0 (default), 6 (IPv4) or 10 (IPv6) + ]]></code> + + <marker id="agent_entry"></marker> + </section> + <funcs> <func> <name>agent_entry(Tag, Val) -> agent_entry()</name> @@ -381,17 +394,19 @@ <name>target_addr_entry(Name, Ip, TagList, ParamsName, EngineId, TMask) -> target_addr_entry()</name> <name>target_addr_entry(Name, Ip, Udp, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> <name>target_addr_entry(Name, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> + <name>target_addr_entry(Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize) -> target_addr_entry()</name> <fsummary>Create an target_addr entry</fsummary> <type> <v>Name = string()</v> - <v>Ip = string()</v> + <v>Domain = transportDomain()</v> + <v>Ip = transportAddressIPv4() | transportAddressIPv6() (depends on Domain)</v> <v>Udp = integer()</v> <v>Timeout = integer()</v> <v>RetryCount = integer()</v> <v>TagList = string()</v> <v>ParamsName = string()</v> <v>EngineId = string()</v> - <v>TMask = string()</v> + <v>TMask = transportAddressMask() (depends on Domain)</v> <v>MaxMessageSize = integer()</v> <v>target_addr_entry() = term()</v> </type> diff --git a/lib/snmp/doc/src/snmpm.xml b/lib/snmp/doc/src/snmpm.xml index 1ee391d9ba..72849b9c9e 100644 --- a/lib/snmp/doc/src/snmpm.xml +++ b/lib/snmp/doc/src/snmpm.xml @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="latin1" ?> +<?xml version="1.0" encoding="iso-8859-1" ?> <!DOCTYPE erlref SYSTEM "erlref.dtd"> <erlref> @@ -63,6 +63,10 @@ value_type() = o ('OBJECT IDENTIFIER') | c64 ('Counter64') | tt ('TimeTicks') value() = term() +community() = string() +sec_model() = any | v1 | v2c | usm +sec_name() = string() +sec_level() = noAuthNoPriv | authNoPriv | authPriv ]]></code> <marker id="monitor"></marker> @@ -482,11 +486,65 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <p>Get a list of all registered usm users with engine-id <c>EngineID</c>.</p> - <marker id="sync_get"></marker> + <marker id="sync_get2"></marker> </desc> </func> <func> + <name>sync_get2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name>sync_get2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <fsummary>Synchronous <c>get-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>Oids = [oid()]</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>SnmpReply = snmp_reply()</v> + <v>Remaining = integer()</v> + <v>Reason = {send_failed, ReqId, ActualReason} | {invalid_sec_info, SecInfo, SnmpInfo} | term()</v> + <v>ReqId = term()</v> + <v>ActualReason = term()</v> + <v>SecInfo = [sec_info()]</v> + <v>sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}</v> + <v>sec_tag() = atom()</v> + <v>ExpectedValue = ReceivedValue = term()</v> + <v>SnmpInfo = term()</v> + </type> + <desc> + <p>Synchronous <c>get-request</c>. </p> + + <p><c>Remaining</c> is the remaining time of the given (or default) + timeout time.</p> + + <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. + <em>ActualReason</em> is the actual reason in this case. </p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <p>For <c>SnmpInfo</c>, see the user callback function + <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p> + + <marker id="sync_get"></marker> + </desc> + </func> + + <func> <name>sync_get(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <name>sync_get(UserId, TargetName, ContextName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> <name>sync_get(UserId, TargetName, Oids, Timeout) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> @@ -513,19 +571,63 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <desc> <p>Synchronous <c>get-request</c>. </p> <p><c>Remaining</c> is the remaining time of the given or - default timeout time.</p> + default timeout time.</p> <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that - the net_if process failed to send the message. This could happen - because of any number of reasons, i.e. encoding error. <em>R</em> - is the actual reason in this case. </p> - <p><c>ExtraInfo</c> is an opaque data structure passed on to - the net-if process. The net-if process included in this - application makes no use of this info, so the only use for it - in such a configuration (when using the built in net-if) would - be tracing.</p> + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. <em>R</em> + is the actual reason in this case. </p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> <p>For <c>SnmpInfo</c>, see the user callback function <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p> + <marker id="async_get2"></marker> + </desc> + </func> + + <func> + <name>async_get2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name>async_get2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <fsummary>Asynchronous <c>get-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>Oids = [oid()]</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>ReqId = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Asynchronous <c>get-request</c>.</p> + + <p>The reply, if it arrives, will be delivered to the user + through a call to the snmpm_user callback function + <c>handle_pdu</c>.</p> + + <p>The send option <c>timeout</c> specifies for how long the request is + valid (after which the manager is free to delete it).</p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + <marker id="async_get"></marker> </desc> </func> @@ -550,17 +652,73 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <desc> <p>Asynchronous <c>get-request</c>.</p> <p>The reply, if it arrives, will be delivered to the user - through a call to the snmpm_user callback function - <c>handle_pdu</c>.</p> - <p>The <c>Expire</c> time indicates for how long the request is - valid (after which the manager is free to delete it).</p> - <p><c>ExtraInfo</c> is an opaque data structure passed on to - the net-if process. The net-if process included in this - application makes no use of this info, so the only use for it - in such a configuration (when using the built in net-if) would - be tracing.</p> - - <marker id="sync_get_next"></marker> + through a call to the snmpm_user callback function + <c>handle_pdu</c>.</p> + <p>The <c>Expire</c> time indicates for how long the request is + valid (after which the manager is free to delete it).</p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <marker id="sync_get_next2"></marker> + </desc> + </func> + + <func> + <name>sync_get_next2(UserId, TargetName, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name>sync_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <fsummary>Synchronous <c>get-next-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>Oids = [oid()]</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>SnmpReply = snmp_reply()</v> + <v>Remaining = integer()</v> + <v>Reason = {send_failed, ReqId, ActualReason} | {invalid_sec_info, SecInfo, SnmpInfo} | term()</v> + <v>ReqId = term()</v> + <v>ActualReason = term()</v> + <v>SecInfo = [sec_info()]</v> + <v>sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}</v> + <v>sec_tag() = atom()</v> + <v>ExpectedValue = ReceivedValue = term()</v> + <v>SnmpInfo = term()</v> + </type> + <desc> + <p>Synchronous <c>get-next-request</c>. </p> + + <p><c>Remaining</c> is the remaining time of the given (or default) + timeout time.</p> + + <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. + <em>ActualReason</em> is the actual reason in this case. </p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <p>For <c>SnmpInfo</c>, see the user callback function + <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p> + + <marker id="sync_get_next"></marker> </desc> </func> @@ -587,16 +745,57 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <p>Synchronous <c>get-next-request</c>. </p> <p><c>Remaining</c> time of the given or default timeout time.</p> <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that - the net_if process failed to send the message. This could happen - because of any number of reasons, i.e. encoding error. <em>R</em> - is the actual reason in this case. </p> - <p><c>ExtraInfo</c> is an opaque data structure passed on to - the net-if process. The net-if process included in this - application makes no use of this info, so the only use for it - in such a configuration (when using the built in net-if) would - be tracing.</p> - - <marker id="async_get_next"></marker> + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. <em>R</em> + is the actual reason in this case. </p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <marker id="async_get_next2"></marker> + </desc> + </func> + + <func> + <name>async_get_next2(UserId, TargetName, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name>async_get_next2(UserId, TargetName, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <fsummary>Asynchronous <c>get-next-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>Oids = [oid()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>ReqId = integer()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Asynchronous <c>get-next-request</c>. </p> + + <p>The reply will be delivered to the user through a call + to the snmpm_user callback function <c>handle_pdu</c>.</p> + + <p>The send option <c>timeout</c> specifies for how long the request is + valid (after which the manager is free to delete it).</p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <marker id="async_get_next"></marker> </desc> </func> @@ -620,11 +819,75 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <desc> <p>Asynchronous <c>get-next-request</c>. </p> <p>The reply will be delivered to the user through a call - to the snmpm_user callback function <c>handle_pdu</c>.</p> + to the snmpm_user callback function <c>handle_pdu</c>.</p> <p>The <c>Expire</c> time indicates for how long the request is - valid (after which the manager is free to delete it).</p> + valid (after which the manager is free to delete it).</p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <marker id="sync_set2"></marker> + </desc> + </func> - <marker id="sync_set"></marker> + <func> + <name>sync_set2(UserId, TargetName, VarsAndVals) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name>sync_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <fsummary>Synchronous <c>set-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>VarsAndVals = vars_and_vals()</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>SnmpReply = snmp_reply()</v> + <v>Remaining = integer()</v> + <v>Reason = {send_failed, ReqId, ActualReason} | {invalid_sec_info, SecInfo, SnmpInfo} | term()</v> + <v>ReqId = term()</v> + <v>ActualReason = term()</v> + <v>SecInfo = [sec_info()]</v> + <v>sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}</v> + <v>sec_tag() = atom()</v> + <v>ExpectedValue = ReceivedValue = term()</v> + <v>SnmpInfo = term()</v> + </type> + <desc> + <p>Synchronous <c>set-request</c>. </p> + + <p><c>Remaining</c> is the remaining time of the given (or default) + timeout time.</p> + + <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. + <em>ActualReason</em> is the actual reason in this case. </p> + + <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the + manager makes an educated guess based on the loaded mibs. </p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <p>For <c>SnmpInfo</c>, see the user callback function + <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p> + + <marker id="sync_set"></marker> </desc> </func> @@ -651,18 +914,64 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <p>Synchronous <c>set-request</c>. </p> <p><c>Remaining</c> time of the given or default timeout time.</p> <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that - the net_if process failed to send the message. This could happen - because of any number of reasons, i.e. encoding error. <em>R</em> - is the actual reason in this case. </p> - <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the - manager makes an educated guess based on the loaded mibs. </p> - <p><c>ExtraInfo</c> is an opaque data structure passed on to - the net-if process. The net-if process included in this - application makes no use of this info, so the only use for it - in such a configuration (when using the built in net-if) would - be tracing.</p> - - <marker id="async_set"></marker> + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. <em>R</em> + is the actual reason in this case. </p> + <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the + manager makes an educated guess based on the loaded mibs. </p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <marker id="async_set2"></marker> + </desc> + </func> + + <func> + <name>async_set2(UserId, TargetName, VarsAndVals) -> {ok, ReqId} | {error, Reason}</name> + <name>async_set2(UserId, TargetName, VarsAndVals, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <fsummary>Asynchronous <c>set-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>VarsAndVals = vars_and_vals()</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>ReqId = term()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Asynchronous <c>set-request</c>. </p> + + <p>The reply will be delivered to the user through a call + to the snmpm_user callback function <c>handle_pdu</c>.</p> + + <p>The send option <c>timeout</c> specifies for how long the request is + valid (after which the manager is free to delete it).</p> + + <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the + manager makes an educated guess based on the loaded mibs. </p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <marker id="async_set"></marker> </desc> </func> @@ -685,18 +994,76 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <desc> <p>Asynchronous <c>set-request</c>. </p> <p>The reply will be delivered to the user through a call - to the snmpm_user callback function <c>handle_pdu</c>.</p> + to the snmpm_user callback function <c>handle_pdu</c>.</p> <p>The <c>Expire</c> time indicates for how long the request is - valid (after which the manager is free to delete it).</p> - <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the - manager makes an educated guess based on the loaded mibs. </p> - <p><c>ExtraInfo</c> is an opaque data structure passed on to - the net-if process. The net-if process included in this - application makes no use of this info, so the only use for it - in such a configuration (when using the built in net-if) would - be tracing.</p> - - <marker id="sync_get_bulk"></marker> + valid (after which the manager is free to delete it).</p> + <p>When <em>var_and_val()</em> is <em>{oid(), value()}</em>, the + manager makes an educated guess based on the loaded mibs. </p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <marker id="sync_get_bulk2"></marker> + </desc> + </func> + + <func> + <name>sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <name>sync_get_bulk2(UserId, TragetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, SnmpReply, Remaining} | {error, Reason}</name> + <fsummary>Synchronous <c>get-bulk-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>NonRep = integer()</v> + <v>MaxRep = integer()</v> + <v>Oids = [oid()]</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>SnmpReply = snmp_reply()</v> + <v>Remaining = integer()</v> + <v>Reason = {send_failed, ReqId, ActualReason} | {invalid_sec_info, SecInfo, SnmpInfo} | term()</v> + <v>ReqId = term()</v> + <v>ActualReason = term()</v> + <v>SecInfo = [sec_info()]</v> + <v>sec_info() = {sec_tag(), ExpectedValue, ReceivedValue}</v> + <v>sec_tag() = atom()</v> + <v>ExpectedValue = ReceivedValue = term()</v> + <v>SnmpInfo = term()</v> + </type> + <desc> + <p>Synchronous <c>get-bulk-request</c> (See RFC1905).</p> + + <p><c>Remaining</c> is the remaining time of the given (or default) + timeout time.</p> + + <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. + <em>ActualReason</em> is the actual reason in this case. </p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a option (when using the built in + net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <p>For <c>SnmpInfo</c>, see the user callback function + <seealso marker="snmpm_user#handle_report">handle_report</seealso>.</p> + + <marker id="sync_get_bulk"></marker> </desc> </func> @@ -723,17 +1090,60 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <desc> <p>Synchronous <c>get-bulk-request</c> (See RFC1905).</p> <p><c>Remaining</c> time of the given or default timeout time.</p> - <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that - the net_if process failed to send the message. This could happen - because of any number of reasons, i.e. encoding error. <em>R</em> - is the actual reason in this case. </p> - <p><c>ExtraInfo</c> is an opaque data structure passed on to - the net-if process. The net-if process included in this - application makes no use of this info, so the only use for it - in such a configuration (when using the built in net-if) would - be tracing.</p> - - <marker id="async_get_bulk"></marker> + <p>When <em>Reason</em> is <em>{send_failed, ...}</em> it means that + the net_if process failed to send the message. This could happen + because of any number of reasons, i.e. encoding error. <em>R</em> + is the actual reason in this case. </p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> + + <marker id="async_get_bulk2"></marker> + </desc> + </func> + + <func> + <name>async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> {ok, ReqId} | {error, Reason}</name> + <name>async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> {ok, ReqId} | {error, Reason}</name> + <fsummary>Asynchronous <c>get-bulk-request</c></fsummary> + <type> + <v>UserId = term()</v> + <v>TargetName = target_name()</v> + <v>NonRep = integer()</v> + <v>MaxRep = integer()</v> + <v>Oids = [oid()]</v> + <v>SendOpts = send_opts()</v> + <v>send_opts() = [send_opt()]</v> + <v>send_opt() = {context, string()} | {timeout, pos_integer()} | {extra, term()} | {community, community()} | {sec_model, sec_model()} | {sec_name, string()} | {sec_level, sec_level()} | {max_message_size, pos_integer()}</v> + <v>ReqId = integer()</v> + <v>Reason = term()</v> + </type> + <desc> + <p>Asynchronous <c>get-bulk-request</c> (See RFC1905).</p> + + <p>The reply will be delivered to the user through a call + to the snmpm_user callback function <c>handle_pdu</c>.</p> + + <p>The send option <c>timeout</c> specifies for how long the request is + valid (after which the manager is free to delete it).</p> + + <p>The send option <c>extra</c> specifies an opaque data structure + passed on to the net-if process. The net-if process included in this + application makes no use of this info, so the only use for it + in such a configuration (when using the built in net-if) would + be tracing.</p> + + <p>Some of the send options (<c>community</c>, <c>sec_model</c>, + <c>sec_name</c>, <c>sec_level</c> and <c>max_message_size</c>) + are <c>override options</c>. That is, + for <em>this</em> request, they override any configuration done + when the agent was registered. </p> + + <marker id="async_get_bulk"></marker> </desc> </func> @@ -759,9 +1169,16 @@ priv_key = [integer()] (length is 16 if priv = usmDESPrivProtocol | usmAesCfb1 <desc> <p>Asynchronous <c>get-bulk-request</c> (See RFC1905).</p> <p>The reply will be delivered to the user through a call - to the snmpm_user callback function <c>handle_pdu</c>.</p> + to the snmpm_user callback function <c>handle_pdu</c>.</p> <p>The <c>Expire</c> time indicates for how long the request is - valid (after which the manager is free to delete it).</p> + valid (after which the manager is free to delete it).</p> + <p><c>ExtraInfo</c> is an opaque data structure passed on to + the net-if process. The net-if process included in this + application makes, with one exception, no use of this info, + so the only use for it in such a configuration (when using the + built in net-if) would be tracing. The one usage exception is: + <em>Any</em> tuple with <c>snmpm_extra_info_tag</c> as its first + element is reserved for internal use. </p> <marker id="cancel_async_request"></marker> </desc> diff --git a/lib/snmp/mibs/Makefile.in b/lib/snmp/mibs/Makefile.in index 7aefb0ea34..3af74eca75 100644 --- a/lib/snmp/mibs/Makefile.in +++ b/lib/snmp/mibs/Makefile.in @@ -61,7 +61,8 @@ MIBS_A = \ SNMP-USER-BASED-SM-MIB \ SNMP-VIEW-BASED-ACM-MIB \ SNMP-USM-AES-MIB \ - INET-ADDRESS-MIB + INET-ADDRESS-MIB \ + TRANSPORT-ADDRESS-MIB MIBS_B = OTP-SNMPEA-MIB diff --git a/lib/snmp/mibs/TRANSPORT-ADDRESS-MIB.mib b/lib/snmp/mibs/TRANSPORT-ADDRESS-MIB.mib new file mode 100644 index 0000000000..7d450fbc2a --- /dev/null +++ b/lib/snmp/mibs/TRANSPORT-ADDRESS-MIB.mib @@ -0,0 +1,417 @@ +TRANSPORT-ADDRESS-MIB DEFINITIONS ::= BEGIN + +IMPORTS + MODULE-IDENTITY, OBJECT-IDENTITY, mib-2 FROM SNMPv2-SMI + TEXTUAL-CONVENTION FROM SNMPv2-TC; + +transportAddressMIB MODULE-IDENTITY + LAST-UPDATED "200211010000Z" + ORGANIZATION + "IETF Operations and Management Area" + CONTACT-INFO + "Juergen Schoenwaelder (Editor) + TU Braunschweig + Bueltenweg 74/75 + 38106 Braunschweig, Germany + Phone: +49 531 391-3289 + EMail: [email protected] + + Send comments to <[email protected]>." + DESCRIPTION + "This MIB module provides commonly used transport + address definitions. + + Copyright (C) The Internet Society (2002). This version of + this MIB module is part of RFC 3419; see the RFC itself for + full legal notices." + + -- Revision log + + REVISION "200211010000Z" + DESCRIPTION + "Initial version, published as RFC 3419." + ::= { mib-2 100 } + + +transportDomains OBJECT IDENTIFIER ::= { transportAddressMIB 1 } + +transportDomainUdpIpv4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The UDP over IPv4 transport domain. The corresponding + transport address is of type TransportAddressIPv4 for + global IPv4 addresses." + ::= { transportDomains 1 } + +transportDomainUdpIpv6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The UDP over IPv6 transport domain. The corresponding + transport address is of type TransportAddressIPv6 for + global IPv6 addresses." + ::= { transportDomains 2 } + +transportDomainUdpIpv4z OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The UDP over IPv4 transport domain. The corresponding + transport address is of type TransportAddressIPv4z for + scoped IPv4 addresses with a zone index." + ::= { transportDomains 3 } + +transportDomainUdpIpv6z OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The UDP over IPv6 transport domain. The corresponding + transport address is of type TransportAddressIPv6z for + scoped IPv6 addresses with a zone index." + ::= { transportDomains 4 } + +transportDomainTcpIpv4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The TCP over IPv4 transport domain. The corresponding + transport address is of type TransportAddressIPv4 for + global IPv4 addresses." + ::= { transportDomains 5 } + +transportDomainTcpIpv6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The TCP over IPv6 transport domain. The corresponding + transport address is of type TransportAddressIPv6 for + global IPv6 addresses." + ::= { transportDomains 6 } + +transportDomainTcpIpv4z OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The TCP over IPv4 transport domain. The corresponding + transport address is of type TransportAddressIPv4z for + scoped IPv4 addresses with a zone index." + ::= { transportDomains 7 } + +transportDomainTcpIpv6z OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The TCP over IPv6 transport domain. The corresponding + transport address is of type TransportAddressIPv6z for + scoped IPv6 addresses with a zone index." + ::= { transportDomains 8 } + +transportDomainSctpIpv4 OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The SCTP over IPv4 transport domain. The corresponding + transport address is of type TransportAddressIPv4 for + global IPv4 addresses. This transport domain usually + represents the primary address on multihomed SCTP + endpoints." + ::= { transportDomains 9 } + +transportDomainSctpIpv6 OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The SCTP over IPv6 transport domain. The corresponding + transport address is of type TransportAddressIPv6 for + global IPv6 addresses. This transport domain usually + represents the primary address on multihomed SCTP + endpoints." + ::= { transportDomains 10 } + +transportDomainSctpIpv4z OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The SCTP over IPv4 transport domain. The corresponding + transport address is of type TransportAddressIPv4z for + scoped IPv4 addresses with a zone index. This transport + domain usually represents the primary address on + multihomed SCTP endpoints." + ::= { transportDomains 11 } + +transportDomainSctpIpv6z OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The SCTP over IPv6 transport domain. The corresponding + transport address is of type TransportAddressIPv6z for + scoped IPv6 addresses with a zone index. This transport + domain usually represents the primary address on + multihomed SCTP endpoints." + ::= { transportDomains 12 } + +transportDomainLocal OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The Posix Local IPC transport domain. The corresponding + transport address is of type TransportAddressLocal. + + The Posix Local IPC transport domain incorporates the + well-known UNIX domain sockets." + ::= { transportDomains 13 } + +transportDomainUdpDns OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The UDP transport domain using fully qualified domain + names. The corresponding transport address is of type + TransportAddressDns." + ::= { transportDomains 14 } + +transportDomainTcpDns OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The TCP transport domain using fully qualified domain + names. The corresponding transport address is of type + TransportAddressDns." + ::= { transportDomains 15 } + +transportDomainSctpDns OBJECT-IDENTITY + STATUS current + DESCRIPTION + "The SCTP transport domain using fully qualified domain + names. The corresponding transport address is of type + TransportAddressDns." + ::= { transportDomains 16 } + +TransportDomain ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "A value that represents a transport domain. + + Some possible values, such as transportDomainUdpIpv4, are + defined in this module. Other possible values can be + defined in other MIB modules." + SYNTAX OBJECT IDENTIFIER + +-- +-- The enumerated values of the textual convention below should +-- be identical to the last sub-identifier of the OID registered +-- for the same domain. +-- + +TransportAddressType ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "A value that represents a transport domain. This is the + enumerated version of the transport domain registrations + in this MIB module. The enumerated values have the + following meaning: + + unknown(0) unknown transport address type + udpIpv4(1) transportDomainUdpIpv4 + udpIpv6(2) transportDomainUdpIpv6 + udpIpv4z(3) transportDomainUdpIpv4z + udpIpv6z(4) transportDomainUdpIpv6z + tcpIpv4(5) transportDomainTcpIpv4 + tcpIpv6(6) transportDomainTcpIpv6 + tcpIpv4z(7) transportDomainTcpIpv4z + tcpIpv6z(8) transportDomainTcpIpv6z + sctpIpv4(9) transportDomainSctpIpv4 + sctpIpv6(10) transportDomainSctpIpv6 + sctpIpv4z(11) transportDomainSctpIpv4z + sctpIpv6z(12) transportDomainSctpIpv6z + local(13) transportDomainLocal + udpDns(14) transportDomainUdpDns + tcpDns(15) transportDomainTcpDns + sctpDns(16) transportDomainSctpDns + + This textual convention can be used to represent transport + domains in situations where a syntax of TransportDomain is + unwieldy (for example, when used as an index). + + The usage of this textual convention implies that additional + transport domains can only be supported by updating this MIB + module. This extensibility restriction does not apply for the + TransportDomain textual convention which allows MIB authors + to define additional transport domains independently in + other MIB modules." + SYNTAX INTEGER { + unknown(0), + udpIpv4(1), + udpIpv6(2), + udpIpv4z(3), + udpIpv6z(4), + tcpIpv4(5), + tcpIpv6(6), + tcpIpv4z(7), + tcpIpv6z(8), + sctpIpv4(9), + sctpIpv6(10), + sctpIpv4z(11), + sctpIpv6z(12), + local(13), + udpDns(14), + tcpDns(15), + sctpDns(16) + } + +TransportAddress ::= TEXTUAL-CONVENTION + STATUS current + DESCRIPTION + "Denotes a generic transport address. + + A TransportAddress value is always interpreted within the + context of a TransportAddressType or TransportDomain value. + Every usage of the TransportAddress textual convention MUST + specify the TransportAddressType or TransportDomain object + which provides the context. Furthermore, MIB authors SHOULD + define a separate TransportAddressType or TransportDomain + object for each TransportAddress object. It is suggested that + the TransportAddressType or TransportDomain is logically + registered before the object(s) which use the + TransportAddress textual convention if they appear in the + same logical row. + + The value of a TransportAddress object must always be + consistent with the value of the associated + TransportAddressType or TransportDomain object. Attempts + to set a TransportAddress object to a value which is + inconsistent with the associated TransportAddressType or + TransportDomain must fail with an inconsistentValue error. + + When this textual convention is used as a syntax of an + index object, there may be issues with the limit of 128 + sub-identifiers specified in SMIv2, STD 58. In this case, + the OBJECT-TYPE declaration MUST include a 'SIZE' clause + to limit the number of potential instance sub-identifiers." + SYNTAX OCTET STRING (SIZE (0..255)) + +TransportAddressIPv4 ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1d.1d.1d.1d:2d" + STATUS current + DESCRIPTION + "Represents a transport address consisting of an IPv4 + address and a port number (as used for example by UDP, + TCP and SCTP): + + octets contents encoding + 1-4 IPv4 address network-byte order + 5-6 port number network-byte order + + This textual convention SHOULD NOT be used directly in object + definitions since it restricts addresses to a specific format. + However, if it is used, it MAY be used either on its own or + in conjunction with TransportAddressType or TransportDomain + as a pair." + SYNTAX OCTET STRING (SIZE (6)) + +TransportAddressIPv6 ::= TEXTUAL-CONVENTION + DISPLAY-HINT "0a[2x:2x:2x:2x:2x:2x:2x:2x]0a:2d" + STATUS current + DESCRIPTION + "Represents a transport address consisting of an IPv6 + address and a port number (as used for example by UDP, + TCP and SCTP): + + octets contents encoding + 1-16 IPv6 address network-byte order + 17-18 port number network-byte order + + This textual convention SHOULD NOT be used directly in object + definitions since it restricts addresses to a specific format. + However, if it is used, it MAY be used either on its own or + in conjunction with TransportAddressType or TransportDomain + as a pair." + SYNTAX OCTET STRING (SIZE (18)) + +TransportAddressIPv4z ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1d.1d.1d.1d%4d:2d" + STATUS current + DESCRIPTION + "Represents a transport address consisting of an IPv4 + address, a zone index and a port number (as used for + example by UDP, TCP and SCTP): + + octets contents encoding + 1-4 IPv4 address network-byte order + 5-8 zone index network-byte order + 9-10 port number network-byte order + + This textual convention SHOULD NOT be used directly in object + definitions since it restricts addresses to a specific format. + However, if it is used, it MAY be used either on its own or + in conjunction with TransportAddressType or TransportDomain + as a pair." + SYNTAX OCTET STRING (SIZE (10)) + +TransportAddressIPv6z ::= TEXTUAL-CONVENTION + DISPLAY-HINT "0a[2x:2x:2x:2x:2x:2x:2x:2x%4d]0a:2d" + STATUS current + DESCRIPTION + "Represents a transport address consisting of an IPv6 + address, a zone index and a port number (as used for + example by UDP, TCP and SCTP): + + octets contents encoding + 1-16 IPv6 address network-byte order + 17-20 zone index network-byte order + 21-22 port number network-byte order + + This textual convention SHOULD NOT be used directly in object + definitions since it restricts addresses to a specific format. + However, if it is used, it MAY be used either on its own or + in conjunction with TransportAddressType or TransportDomain + as a pair." + SYNTAX OCTET STRING (SIZE (22)) + +TransportAddressLocal ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1a" + STATUS current + DESCRIPTION + "Represents a POSIX Local IPC transport address: + + octets contents encoding + all POSIX Local IPC address string + + The Posix Local IPC transport domain subsumes UNIX domain + sockets. + + This textual convention SHOULD NOT be used directly in object + definitions since it restricts addresses to a specific format. + However, if it is used, it MAY be used either on its own or + in conjunction with TransportAddressType or TransportDomain + as a pair. + + When this textual convention is used as a syntax of an + index object, there may be issues with the limit of 128 + sub-identifiers specified in SMIv2, STD 58. In this case, + the OBJECT-TYPE declaration MUST include a 'SIZE' clause + to limit the number of potential instance sub-identifiers." + REFERENCE + "Protocol Independent Interfaces (IEEE POSIX 1003.1g)" + SYNTAX OCTET STRING (SIZE (1..255)) + +TransportAddressDns ::= TEXTUAL-CONVENTION + DISPLAY-HINT "1a" + STATUS current + DESCRIPTION + "Represents a DNS domain name followed by a colon ':' + (ASCII character 0x3A) and a port number in ASCII. + The name SHOULD be fully qualified whenever possible. + + Values of this textual convention are not directly useable as + transport-layer addressing information, and require runtime + resolution. As such, applications that write them must be + prepared for handling errors if such values are not + supported, or cannot be resolved (if resolution occurs at the + time of the management operation). + + The DESCRIPTION clause of TransportAddress objects that may + have TransportAddressDns values must fully describe how (and + when) such names are to be resolved to IP addresses and vice + versa. + + This textual convention SHOULD NOT be used directly in object + definitions since it restricts addresses to a specific format. + However, if it is used, it MAY be used either on its own or + in conjunction with TransportAddressType or TransportDomain + as a pair. + + When this textual convention is used as a syntax of an + index object, there may be issues with the limit of 128 + sub-identifiers specified in SMIv2, STD 58. In this case, + the OBJECT-TYPE declaration MUST include a 'SIZE' clause + to limit the number of potential instance sub-identifiers." + SYNTAX OCTET STRING (SIZE (1..255)) + +END diff --git a/lib/snmp/priv/conf/agent/target_addr.conf b/lib/snmp/priv/conf/agent/target_addr.conf index 33a5d0d4c4..f48a6645a3 100644 --- a/lib/snmp/priv/conf/agent/target_addr.conf +++ b/lib/snmp/priv/conf/agent/target_addr.conf @@ -3,9 +3,13 @@ %% The data is inserted into the snmpTargetAddrTable defined %% in SNMP-TARGET-MIB, and in the snmpTargeAddrExtTabke defined %% in SNMP-COMMUNITY-MIB. -%% Each row is a 9-tuple: -%% {Name, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, -%% TMask, MaxMessageSize}. +%% Each row is a 10 or 11-tuple (Domain is optional): +%% {Name, +%% Domain, Ip, Port, +%% Timeout, RetryCount, TagList, ParamsName, EngineId, +%% TMask, MaxMessageSize}. +%% The value of Domain decide the format of the Ip and TMask values. +%% If not present, classic Ipv4 is assumed. %% The EngineId value is only used if Inform-Requests are sent to this %% target. If Informs are not sent, this value is ignored, and can be %% e.g. an empty string. However, if Informs are sent, it is essential diff --git a/lib/snmp/src/agent/snmp_community_mib.erl b/lib/snmp/src/agent/snmp_community_mib.erl index 5644a43345..3debe0a30e 100644 --- a/lib/snmp/src/agent/snmp_community_mib.erl +++ b/lib/snmp/src/agent/snmp_community_mib.erl @@ -25,7 +25,7 @@ snmpTargetAddrExtTable/3, community2vacm/2, vacm2community/2, get_target_addr_ext_mms/2]). --export([add_community/5, delete_community/1]). +-export([add_community/5, add_community/6, delete_community/1]). -export([check_community/1]). -include("SNMP-COMMUNITY-MIB.hrl"). @@ -128,12 +128,16 @@ read_community_config_files(Dir) -> Comms. check_community({Index, CommunityName, SecName, CtxName, TransportTag}) -> + EngineID = get_engine_id(), + check_community({Index, CommunityName, SecName, + EngineID, CtxName, TransportTag}); +check_community({Index, CommunityName, SecName, + EngineID, CtxName, TransportTag}) -> snmp_conf:check_string(Index,{gt,0}), snmp_conf:check_string(CommunityName), snmp_conf:check_string(SecName), snmp_conf:check_string(CtxName), snmp_conf:check_string(TransportTag), - EngineID = get_engine_id(), Comm = {Index, CommunityName, SecName, EngineID, CtxName, TransportTag, ?'StorageType_nonVolatile', ?'RowStatus_active'}, {ok, Comm}; @@ -173,6 +177,13 @@ table_del_row(Tab, Key) -> %% FIXME: does not work with mnesia add_community(Idx, CommName, SecName, CtxName, TransportTag) -> Community = {Idx, CommName, SecName, CtxName, TransportTag}, + do_add_community(Community). + +add_community(Idx, CommName, SecName, EngineId, CtxName, TransportTag) -> + Community = {Idx, CommName, SecName, EngineId, CtxName, TransportTag}, + do_add_community(Community). + +do_add_community(Community) -> case (catch check_community(Community)) of {ok, Row} -> Key = element(1, Row), diff --git a/lib/snmp/src/agent/snmp_notification_mib.erl b/lib/snmp/src/agent/snmp_notification_mib.erl index 1cd69b430f..3da5766b44 100644 --- a/lib/snmp/src/agent/snmp_notification_mib.erl +++ b/lib/snmp/src/agent/snmp_notification_mib.erl @@ -273,9 +273,12 @@ find_targets(Key, TargAddrs, Db, Res) -> get_targets([{TagList, Addr, TargetName, Params, Timeout, Retry}|T], Tag, Type, Name) -> case snmp_misc:is_tag_member(Tag, TagList) of - true -> [{Name, {Addr, TargetName, Params, type(Type, Timeout, Retry)}}| - get_targets(T, Tag, Type, Name)]; + true -> + ?vtrace("tag ~w *is* member", [Tag]), + [{Name, {Addr, TargetName, Params, type(Type, Timeout, Retry)}}| + get_targets(T, Tag, Type, Name)]; false -> + ?vtrace("tag ~w is *not* member", [Tag]), get_targets(T, Tag, Type, Name) end; get_targets([], _Tag, _Type, _Name) -> diff --git a/lib/snmp/src/agent/snmp_target_mib.erl b/lib/snmp/src/agent/snmp_target_mib.erl index 270a5fd5b6..b2f2417b02 100644 --- a/lib/snmp/src/agent/snmp_target_mib.erl +++ b/lib/snmp/src/agent/snmp_target_mib.erl @@ -26,16 +26,18 @@ snmpTargetParamsTable/1, snmpTargetParamsTable/3, get_target_addrs/0, get_target_engine_id/1, set_target_engine_id/2, is_valid_tag/3, get/3, table_next/2]). --export([add_addr/10, delete_addr/1, +-export([add_addr/10, add_addr/11, delete_addr/1, add_params/5, delete_params/1]). -export([check_target_addr/1, check_target_params/1]). +-export([default_domain/0]). --include("snmp_types.hrl"). --include("snmp_tables.hrl"). --include("SNMP-TARGET-MIB.hrl"). --include("SNMPv2-TC.hrl"). --include("SNMPv2-TM.hrl"). --include("SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). +-include_lib("snmp/include/snmp_tables.hrl"). +-include_lib("snmp/include/SNMP-TARGET-MIB.hrl"). +-include_lib("snmp/include/SNMPv2-TC.hrl"). +-include_lib("snmp/include/SNMPv2-TM.hrl"). +-include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl"). -define(VMODULE,"TARGET-MIB"). -include("snmp_verbosity.hrl"). @@ -49,6 +51,12 @@ %%----------------------------------------------------------------- + +default_domain() -> + snmpUDPDomain. + + +%%----------------------------------------------------------------- %% Func: configure/1 %% Args: Dir is the directory where the configuration files are found. %% Purpose: If the tables doesn't exist, this function reads @@ -139,39 +147,51 @@ read_target_config_files(Dir) -> %% {Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId, %% TMask, MMS} %%----------------------------------------------------------------- -check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, - Params, EngineId, TMask, MMS}) -> + +check_target_addr({Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, + Params, EngineId, TMask, MMS}) -> ?vtrace("check target address with:" - "~n Name: ~s" - "~n Ip: ~p" - "~n Udp: ~p" - "~n Timeout: ~p" - "~n RetryCount: ~p" - "~n TagList: ~p" - "~n Params: ~p" - "~n EngineId: ~p" - "~n TMask: ~p" - "~n MMS: ~p", - [Name,Ip,Udp,Timeout,RetryCount, - TagList,Params,EngineId,TMask,MMS]), + "~n Name: ~s" + "~n Domain: ~p" + "~n Ip: ~p" + "~n Udp: ~p" + "~n Timeout: ~p" + "~n RetryCount: ~p" + "~n TagList: ~p" + "~n Params: ~p" + "~n EngineId: ~p" + "~n TMask: ~p" + "~n MMS: ~p", + [Name, + Domain, Ip, Udp, + Timeout, RetryCount, + TagList, Params, EngineId, TMask, MMS]), snmp_conf:check_string(Name,{gt,0}), - snmp_conf:check_ip(Ip), + snmp_conf:check_domain(Domain), + snmp_conf:check_ip(Domain, Ip), snmp_conf:check_integer(Udp, {gt, 0}), snmp_conf:check_integer(Timeout, {gte, 0}), snmp_conf:check_integer(RetryCount, {gte,0}), snmp_conf:check_string(TagList), snmp_conf:check_string(Params), check_engine_id(EngineId), - TAddr = Ip ++ [Udp div 256, Udp rem 256], - check_mask(TMask, TAddr), + TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp), + TDomain = snmp_conf:mk_tdomain(Domain), + check_tmask(TDomain, TMask, TAddress), snmp_conf:check_packet_size(MMS), ?vtrace("check target address done",[]), - - Addr = {Name, ?snmpUDPDomain, TAddr, Timeout, + Addr = {Name, TDomain, TAddress, Timeout, RetryCount, TagList, Params, ?'StorageType_nonVolatile', ?'RowStatus_active', EngineId, TMask, MMS}, % Values for Augmenting table in SNMP-COMMUNITY-MIB {ok, Addr}; +check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, + Params, EngineId, TMask, MMS}) -> + Domain = default_domain(), + check_target_addr({Name, + Domain, Ip, Udp, + Timeout, RetryCount, TagList, + Params, EngineId, TMask, MMS}); check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, Params, EngineId}) -> check_target_addr({Name, Ip, Udp, Timeout, RetryCount, TagList, @@ -194,12 +214,13 @@ check_engine_id(discovery) -> check_engine_id(EngineId) -> snmp_conf:check_string(EngineId). -check_mask([], _TAddr) -> + +check_tmask(_TDomain, [], _TAddress) -> ok; -check_mask(TMask, TAddr) when length(TMask) == length(TAddr) -> - snmp_conf:check_taddress(TMask); -check_mask(TMask, _TAddr) -> - throw({error, {invalid_mask, TMask}}). +check_tmask(TDomain, TMask, TAddress) when length(TMask) =:= length(TAddress) -> + snmp_conf:check_taddress(TDomain, TMask); +check_tmask(_TDomain, TMask, _TAddr) -> + throw({error, {invalid_tmask, TMask}}). %%----------------------------------------------------------------- @@ -261,7 +282,13 @@ table_del_row(Tab, Key) -> add_addr(Name, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS) -> - Addr = {Name, Ip, Port, Timeout, Retry, TagList, + Domain = default_domain(), + add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList, + Params, EngineId, TMask, MMS). + +add_addr(Name, Domain, Ip, Port, Timeout, Retry, TagList, + Params, EngineId, TMask, MMS) -> + Addr = {Name, Domain, Ip, Port, Timeout, Retry, TagList, Params, EngineId, TMask, MMS}, case (catch check_target_addr(Addr)) of {ok, Row} -> @@ -341,8 +368,11 @@ maybe_create_var(Var) -> init_var(Var) -> ets:insert(snmp_agent_table, {Var, 0}). vars() -> - [snmpUnavailableContexts, - snmpUnknownContexts]. + [ + snmpUnavailableContexts, + snmpUnknownContexts + ]. + %%----------------------------------------------------------------- %% API functions @@ -562,6 +592,8 @@ snmpTargetAddrTable(print) -> Prefix, element(?snmpTargetAddrTDomain, Row), case element(?snmpTargetAddrTDomain, Row) of ?snmpUDPDomain -> udp; + ?transportDomainUdpIpv4 -> udpIpv4; + ?transportDomainUdpIpv6 -> udpIpv6; _ -> undefined end, Prefix, element(?snmpTargetAddrTAddress, Row), @@ -610,14 +642,14 @@ snmpTargetAddrTable(get, RowIndex, Cols) -> snmpTargetAddrTable(get_next, RowIndex, Cols) -> next(snmpTargetAddrTable, RowIndex, Cols); snmpTargetAddrTable(set, RowIndex, Cols0) -> - %% BMK BMK BMK - case (catch verify_targetAddrTable_cols(Cols0, [])) of + %% BMK BMK + case (catch verify_targetAddrTable_cols(Cols0)) of {ok, Cols} -> snmp_notification_mib:invalidate_cache(), %% Add columns for augmenting table snmpTargetAddrExtTable and for - %% target engine ID. Target engine ID is set to "". The function + %% target engine ID. Target engine ID is set to "". The function %% get_target_engine_id will return "" unless a value is set using - %% set_target_engine_id. If it is "" Informs can't be sent to the + %% set_target_engine_id. If it is "" Informs can't be sent to the %% target. NCols = Cols ++ [{?snmpTargetAddrEngineId, ""}, {?snmpTargetAddrTMask, []}, @@ -628,12 +660,12 @@ snmpTargetAddrTable(set, RowIndex, Cols0) -> Error end; snmpTargetAddrTable(is_set_ok, RowIndex, Cols0) -> - case (catch verify_targetAddrTable_cols(Cols0, [])) of + case (catch verify_targetAddrTable_cols(Cols0)) of {ok, Cols} -> %% Add columns for augmenting table snmpTargetAddrExtTable and for - %% target engine ID. Target engine ID is set to "". The function + %% target engine ID. Target engine ID is set to "". The function %% get_target_engine_id will return "" unless a value is set using - %% set_target_engine_id. If it is "" Informs can't be sent to the + %% set_target_engine_id. If it is "" Informs can't be sent to the %% target. NCols = Cols ++ [{?snmpTargetAddrEngineId, ""}, {?snmpTargetAddrTMask, []}, @@ -647,55 +679,83 @@ snmpTargetAddrTable(Op, Arg1, Arg2) -> Db = db(snmpTargetAddrTable), snmp_generic:table_func(Op, Arg1, Arg2, Db). +verify_targetAddrTable_cols(Cols) -> + ValidCols0 = verify_targetAddrTable_cols(Cols, []), + %% Make a last pass to verify TDomain and TAddress. + ValidCols0. + verify_targetAddrTable_cols([], Cols) -> {ok, lists:reverse(Cols)}; -verify_targetAddrTable_cols([{Col, Val0}|Cols], Acc) -> - Val = verify_targetAddrTable_col(Col, Val0), - verify_targetAddrTable_cols(Cols, [{Col, Val}|Acc]). +verify_targetAddrTable_cols([{Col, Val0}|Cols], ValidCols) -> + Val = verify_targetAddrTable_col(Col, Val0, ValidCols), + verify_targetAddrTable_cols(Cols, [{Col, Val}|ValidCols]). -verify_targetAddrTable_col(?snmpTargetAddrName, Name) -> +verify_targetAddrTable_col(?snmpTargetAddrName, Name, _) -> case (catch snmp_conf:check_string(Name)) of ok -> Name; _ -> wrongValue(?snmpTargetAddrName) end; -verify_targetAddrTable_col(?snmpTargetAddrTAddress, TAddr) -> - case (catch snmp_conf:check_taddress(TAddr)) of +verify_targetAddrTable_col(?snmpTargetAddrTDomain, TDomain, _) -> + case (catch snmp_conf:check_tdomain(TDomain)) of ok -> - TAddr; + TDomain; _ -> - wrongValue(?snmpTargetAddrTAddress) + wrongValue(?snmpTargetAddrTDomain) + end; +%% In order to (properly) validate the TAddress, +%% the TDomain must already have been validated +%% (the format of TAddress depends on TDomain). +verify_targetAddrTable_col(?snmpTargetAddrTAddress, TAddress, ValidCols) -> + case lists:keysearch(?snmpTargetAddrTDomain, 1, ValidCols) of + {value, {?snmpTargetAddrTDomain, TDomain}} -> + case (catch snmp_conf:check_taddress(TDomain, TAddress)) of + ok -> + TAddress; + _ -> + wrongValue(?snmpTargetAddrTAddress) + end; + false -> + %% The user did not provide us with a TDomain, which + %% must mean that he/she intends to use the old domain. + TDomain = snmp_conf:mk_tdomain(default_domain()), + case (catch snmp_conf:check_taddress(TDomain, TAddress)) of + ok -> + TAddress; + _ -> + wrongValue(?snmpTargetAddrTAddress) + end end; -verify_targetAddrTable_col(?snmpTargetAddrTimeout, Timeout) -> +verify_targetAddrTable_col(?snmpTargetAddrTimeout, Timeout, _) -> case (catch snmp_conf:check_integer(Timeout)) of ok when Timeout >= 0 -> Timeout; _ -> wrongValue(?snmpTargetAddrTimeout) end; -verify_targetAddrTable_col(?snmpTargetAddrRetryCount, Retry) -> +verify_targetAddrTable_col(?snmpTargetAddrRetryCount, Retry, _) -> case (catch snmp_conf:check_integer(Retry)) of ok when Retry >= 0 -> Retry; _ -> wrongValue(?snmpTargetAddrRetryCount) end; -verify_targetAddrTable_col(?snmpTargetAddrTagList, TagList) -> +verify_targetAddrTable_col(?snmpTargetAddrTagList, TagList, _) -> case (catch snmp_conf:check_string(TagList)) of ok -> TagList; _ -> wrongValue(?snmpTargetAddrTagList) end; -verify_targetAddrTable_col(?snmpTargetAddrParams, Params) -> +verify_targetAddrTable_col(?snmpTargetAddrParams, Params, _) -> case (catch snmp_conf:check_string(Params)) of ok -> Params; _ -> wrongValue(?snmpTargetAddrParams) end; -verify_targetAddrTable_col(_, Val) -> +verify_targetAddrTable_col(_, Val, _) -> Val. diff --git a/lib/snmp/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl index 22fbd33add..b2e4f253ab 100644 --- a/lib/snmp/src/agent/snmpa.erl +++ b/lib/snmp/src/agent/snmpa.erl @@ -60,6 +60,7 @@ register_subagent/3, unregister_subagent/2, + send_notification2/3, send_notification/3, send_notification/4, send_notification/5, send_notification/6, send_notification/7, send_trap/3, send_trap/4, @@ -108,8 +109,9 @@ -export([print_mib_info/0, print_mib_tables/0, print_mib_variables/0]). -include("snmpa_atl.hrl"). +-include("snmpa_internal.hrl"). --define(EXTRA_INFO, undefined). +-define(DISCO_EXTRA_INFO, undefined). %%----------------------------------------------------------------- @@ -596,22 +598,56 @@ set_request_limit(Agent, NewLimit) -> %% - +send_notification2(Agent, Notification, SendOpts) -> + snmpa_agent:send_notification(Agent, Notification, SendOpts). + send_notification(Agent, Notification, Recv) -> - send_notification(Agent, Notification, Recv, "", "", []). + SendOpts = + [ + {receiver, Recv}, + {varbinds, []}, + {name, ""}, + {context, ""}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO} + ], + send_notification2(Agent, Notification, SendOpts). send_notification(Agent, Notification, Recv, Varbinds) -> - send_notification(Agent, Notification, Recv, "", "", Varbinds). + SendOpts = + [ + {receiver, Recv}, + {varbinds, Varbinds}, + {name, ""}, + {context, ""}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO} + ], + send_notification2(Agent, Notification, SendOpts). send_notification(Agent, Notification, Recv, NotifyName, Varbinds) -> - send_notification(Agent, Notification, Recv, NotifyName, "", Varbinds). + SendOpts = + [ + {receiver, Recv}, + {varbinds, Varbinds}, + {name, NotifyName}, + {context, ""}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO} + ], + send_notification2(Agent, Notification, SendOpts). send_notification(Agent, Notification, Recv, NotifyName, ContextName, Varbinds) when (is_list(NotifyName) andalso is_list(ContextName) andalso is_list(Varbinds)) -> - snmpa_agent:send_trap(Agent, Notification, NotifyName, - ContextName, Recv, Varbinds). + SendOpts = + [ + {receiver, Recv}, + {varbinds, Varbinds}, + {name, NotifyName}, + {context, ContextName}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO} + ], + send_notification2(Agent, Notification, SendOpts). send_notification(Agent, Notification, Recv, NotifyName, ContextName, Varbinds, LocalEngineID) @@ -619,8 +655,16 @@ send_notification(Agent, Notification, Recv, is_list(ContextName) andalso is_list(Varbinds) andalso is_list(LocalEngineID)) -> - snmpa_agent:send_trap(Agent, Notification, NotifyName, - ContextName, Recv, Varbinds, LocalEngineID). + SendOpts = + [ + {receiver, Recv}, + {varbinds, Varbinds}, + {name, NotifyName}, + {context, ContextName}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO}, + {local_engine_id, LocalEngineID} + ], + send_notification2(Agent, Notification, SendOpts). %% Kept for backwards compatibility send_trap(Agent, Trap, Community) -> @@ -655,7 +699,7 @@ discovery(TargetName, Notification, Varbinds, DiscoHandler) discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler). discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler) -> - ExtraInfo = ?EXTRA_INFO, + ExtraInfo = ?DISCO_EXTRA_INFO, discovery(TargetName, Notification, ContextName, Varbinds, DiscoHandler, ExtraInfo). diff --git a/lib/snmp/src/agent/snmpa_acm.erl b/lib/snmp/src/agent/snmpa_acm.erl index 6ad4f0b442..30bd34a205 100644 --- a/lib/snmp/src/agent/snmpa_acm.erl +++ b/lib/snmp/src/agent/snmpa_acm.erl @@ -62,11 +62,13 @@ %% {error, Reason} | %% {discarded, Variable, Reason} %% Types: Pdu = #pdu -%% ACMData = acm_data() = {community, Community, Address} | -%% {v3, MsgID, SecModel, SecName, SecLevel, -%% ContextEngineID, ContextName, SecData} +%% ACMData = acm_data() = +%% {community, SecModel, Community, TDomain, TAddress} | +%% {v3, MsgID, SecModel, SecName, SecLevel, +%% ContextEngineID, ContextName, SecData} %% Community = string() -%% Address = ip() ++ udp() (list) +%% TDomain = ?transportDomainUdpIpv4 | ?transportDomainUdpIpv6 +%% TAddress = ip() ++ udp() (list) %% MsgID = integer() <not used> %% SecModel = ?SEC_* (see snmp_types.hrl) %% SecName = string() @@ -114,7 +116,10 @@ error2status(_) -> genErr. %% discarded: no error response is sent %% authentication_failure: no error response is sent, a trap is generated %%----------------------------------------------------------------- -init_ca(Pdu, {community, SecModel, Community, TAddr}) -> +init_ca(Pdu, {community, SecModel, Community, TAddress}) -> + TDomain = snmp_conf:mk_tdomain(snmp_target_mib:default_domain()), + init_ca(Pdu, {community, SecModel, Community, TDomain, TAddress}); +init_ca(Pdu, {community, SecModel, Community, TDomain, TAddress}) -> %% This is a v1 or v2c request. Use SNMP-COMMUNITY-MIB to %% map the community to vacm parameters. ?vtrace("check access for ~n" @@ -126,18 +131,18 @@ init_ca(Pdu, {community, SecModel, Community, TAddr}) -> _ -> read end, ?vtrace("View type: ~p", [ViewType]), - CaCacheKey = {Community, SecModel, TAddr, ViewType}, + CaCacheKey = {Community, SecModel, TDomain, TAddress, ViewType}, case check_ca_cache(CaCacheKey) of false -> - case snmp_community_mib:community2vacm(Community, - {?snmpUDPDomain,TAddr}) of + case snmp_community_mib:community2vacm(Community, + {TDomain, TAddress}) of {SecName, _ContextEngineId, ContextName} -> %% Maybe we should check that the contextEngineID %% matches the local engineID? %% It better, since we don't impl. proxy. ?vtrace("get mib view" "~n Security name: ~p" - "~n Context name: ~p",[SecName,ContextName]), + "~n Context name: ~p",[SecName, ContextName]), case snmpa_vacm:get_mib_view(ViewType, SecModel, SecName, ?'SnmpSecurityLevel_noAuthNoPriv', ContextName) of @@ -153,7 +158,7 @@ init_ca(Pdu, {community, SecModel, Community, TAddr}) -> end; undefined -> {authentication_failure, snmpInBadCommunityNames, - {bad_community_name, TAddr, Community}} + {bad_community_name, TDomain, TAddress, Community}} end; Res -> Res @@ -219,6 +224,7 @@ upd_ca_cache(KeyVal) -> invalidate_ca_cache() -> erase(ca_cache). + %%----------------------------------------------------------------- %% Func: check(Res) -> {ok, MibView} | {discarded, Variable, Reason} %% Args: Res = {ok, AccessFunc} | diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl index f70885b2ec..e4cfeddb6a 100644 --- a/lib/snmp/src/agent/snmpa_agent.erl +++ b/lib/snmp/src/agent/snmpa_agent.erl @@ -30,7 +30,7 @@ -export([subagent_set/2, load_mibs/2, unload_mibs/2, which_mibs/1, whereis_mib/2, info/1, register_subagent/3, unregister_subagent/2, - send_trap/6, send_trap/7, + send_notification/3, register_notification_filter/5, unregister_notification_filter/2, which_notification_filter/1, @@ -62,10 +62,16 @@ -export([increment_counter/3]). -export([restart_worker/1, restart_set_worker/1]). +%% For backward compatibillity +-export([send_trap/6, send_trap/7]). + %% 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, do_send_trap/7]). + handle_pdu/7, worker/2, worker_loop/1, + do_send_trap/7, do_send_trap/8]). + +-include("snmpa_internal.hrl"). -ifndef(default_verbosity). -define(default_verbosity,silence). @@ -527,6 +533,11 @@ which_notification_filter(Agent) -> call(Agent, which_notification_filter). +send_notification(Agent, Notification, SendOpts) -> + Msg = {send_notif, Notification, SendOpts}, + maybe_call(Agent, Msg). + +%% <BACKWARD-COMPAT> send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) -> ?d("send_trap -> entry with" "~n self(): ~p" @@ -538,13 +549,33 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds) -> "~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. + SendOpts = [ + {receiver, Recv}, + {varbinds, Varbinds}, + {name, NotifyName}, + {context, CtxName}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO} + ], + 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" @@ -558,14 +589,38 @@ send_trap(Agent, Trap, NotifyName, CtxName, Recv, Varbinds, LocalEngineID) -> "~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. + SendOpts = [ + {receiver, Recv}, + {varbinds, Varbinds}, + {name, NotifyName}, + {context, CtxName}, + {extra, ?DEFAULT_NOTIF_EXTRA_INFO}, + {local_engine_id, 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> %% -- Discovery functions -- @@ -655,7 +710,14 @@ wis(Atom) when is_atom(Atom) -> forward_trap(Agent, TrapRecord, NotifyName, CtxName, Recv, Varbinds) -> - Agent ! {forward_trap, 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, + ExtraInfo}. %%----------------------------------------------------------------- @@ -745,6 +807,22 @@ handle_info(worker_available, S) -> ?vdebug("worker available",[]), {noreply, S#state{worker_state = ready}}; +handle_info({send_notif, Notification, SendOpts}, S) -> + ?vlog("[handle_info] send trap request:" + "~n Notification: ~p" + "~n SendOpts: ~p", + [Notification, SendOpts]), + case (catch handle_send_trap(cast, S, Notification, SendOpts)) of + {ok, NewS} -> + {noreply, NewS}; + {'EXIT', R} -> + ?vinfo("Trap not sent:~n ~p", [R]), + {noreply, S}; + _ -> + {noreply, S} + end; + +%% <BACKWARD-COMPAT> handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) -> ?vlog("[handle_info] send trap request:" "~n Trap: ~p" @@ -753,9 +831,10 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) -> "~n Recv: ~p" "~n Varbinds: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds]), + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, - case catch handle_send_trap(S, Trap, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID) of + case (catch handle_send_trap(S, Trap, NotifyName, ContextName, + Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -775,8 +854,9 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds, "~n Varbinds: ~p" "~n LocalEngineID: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID]), - case catch handle_send_trap(S, Trap, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID) of + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + case (catch handle_send_trap(S, Trap, NotifyName, ContextName, + Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -785,8 +865,31 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds, _ -> {noreply, S} end; +%% </BACKWARD-COMPAT> handle_info({forward_trap, TrapRecord, NotifyName, ContextName, + Recv, Varbinds, ExtraInfo}, S) -> + ?vlog("[handle_info] forward trap request:" + "~n TrapRecord: ~p" + "~n NotifyName: ~p" + "~n ContextName: ~p" + "~n Recv: ~p" + "~n Varbinds: ~p", + [TrapRecord, NotifyName, ContextName, Recv, Varbinds]), + LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, + case (catch maybe_send_trap(S, TrapRecord, NotifyName, ContextName, + Recv, Varbinds, LocalEngineID, ExtraInfo)) of + {ok, NewS} -> + {noreply, NewS}; + {'EXIT', R} -> + ?vinfo("Trap not sent:~n ~p", [R]), + {noreply, S}; + _ -> + {noreply, S} + end; + +%% <BACKWARD-COMPAT> +handle_info({forward_trap, TrapRecord, NotifyName, ContextName, Recv, Varbinds}, S) -> ?vlog("[handle_info] forward trap request:" "~n TrapRecord: ~p" @@ -795,9 +898,10 @@ handle_info({forward_trap, TrapRecord, NotifyName, ContextName, "~n Recv: ~p" "~n Varbinds: ~p", [TrapRecord, NotifyName, ContextName, Recv, Varbinds]), + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, case (catch maybe_send_trap(S, TrapRecord, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID)) of + Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> {noreply, NewS}; {'EXIT', R} -> @@ -806,6 +910,7 @@ handle_info({forward_trap, TrapRecord, NotifyName, ContextName, _ -> {noreply, S} end; +%% </BACKWARD-COMPAT> handle_info({backup_done, Reply}, #state{backup = {_, From}} = S) -> ?vlog("[handle_info] backup done:" @@ -908,6 +1013,23 @@ handle_call(restart_set_worker, _From, #state{set_worker = Pid} = S) -> end, {reply, ok, S}; +handle_call({send_notif, Notification, SendOpts}, _From, S) -> + ?vlog("[handle_info] send trap request:" + "~n Notification: ~p" + "~n SendOpts: ~p", + [Notification, SendOpts]), + case (catch handle_send_trap(call, S, Notification, SendOpts)) of + {ok, NewS} -> + {reply, ok, NewS}; + {'EXIT', Reason} -> + ?vinfo("Trap not sent:~n ~p", [Reason]), + {reply, {error, {send_failed, Reason}}, S}; + _ -> + ?vinfo("Trap not sent", []), + {reply, {error, send_failed}, S} + end; + +%% <BACKWARD-COMPAT> handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, _From, S) -> ?vlog("[handle_call] send trap request:" @@ -917,19 +1039,20 @@ 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, eventually the trap sent request - %% will reach the master-agent and then it will look up - %% the proper engine id. + %% 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, case (catch handle_send_trap(S, Trap, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID)) of + Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> {reply, ok, NewS}; {'EXIT', Reason} -> @@ -951,8 +1074,9 @@ handle_call({send_trap, Trap, NotifyName, "~n Varbinds: ~p" "~n LocalEngineID: ~p", [Trap, NotifyName, ContextName, Recv, Varbinds, LocalEngineID]), + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, case (catch handle_send_trap(S, Trap, NotifyName, ContextName, - Recv, Varbinds, LocalEngineID)) of + Recv, Varbinds, LocalEngineID, ExtraInfo)) of {ok, NewS} -> {reply, ok, NewS}; {'EXIT', Reason} -> @@ -962,6 +1086,7 @@ handle_call({send_trap, Trap, NotifyName, ?vinfo("Trap not sent", []), {reply, {error, send_failed}, S} end; +%% </BACKWARD-COMPAT> handle_call({discovery, TargetName, Notification, ContextName, Vbs, DiscoHandler, @@ -1470,7 +1595,10 @@ handle_backup_res([{Who, Crap}|Results], Acc) -> %% because we (for some reason) support the function %% snmpa:current_community(). %%----------------------------------------------------------------- -cheat({community, _SecModel, Community, _IpUdp}, Address, ContextName) -> +cheat({community, SecModel, Community, _TAddress}, Address, ContextName) -> + {Community, Address, ContextName}; +cheat({community, _SecModel, Community, _TDomain, _TAddress}, + Address, ContextName) -> {Community, Address, ContextName}; cheat(_, Address, ContextName) -> {"", Address, ContextName}. @@ -1523,19 +1651,24 @@ spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, Extra) -> proc_lib:spawn_link(?MODULE, handle_pdu, Args). spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID) -> + LocalEngineID, ExtraInfo) -> Dict = get(), proc_lib:spawn_link(?MODULE, do_send_trap, [TrapRec, NotifyName, ContextName, - Recv, Vbs, LocalEngineID, Dict]). + Recv, Vbs, LocalEngineID, ExtraInfo, Dict]). do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, Dict) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, + LocalEngineID, ExtraInfo, Dict). +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))), ?vlog("starting",[]), snmpa_trap:send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, get(net_if)). + LocalEngineID, ExtraInfo, get(net_if)). worker(Master, Dict) -> lists:foreach(fun({Key, Val}) -> put(Key, Val) end, Dict), @@ -1550,21 +1683,34 @@ worker_loop(Master) -> handle_pdu(Vsn, Pdu, PduMS, ACMData, Address, Extra), Master ! worker_available; - %% We don't trap exits! + %% 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)), + ContextName, Recv, Vbs, + ?DEFAULT_NOTIF_EXTRA_INFO, + get(net_if)), Master ! worker_available; - %% We don't trap exits! + %% 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, + 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; @@ -1713,34 +1859,79 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) -> ok end. +get_opt(Key, Default, SendOpts) -> + case lists:keysearch(Key, 1, SendOpts) of + {value, {Key, Value}} -> + Value; + false -> + Default + end. -handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds, - LocalEngineID) -> +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), + LocalEngineID = + get_opt(local_engine_id, ?DEFAULT_LOCAL_ENGINE_ID, SendOpts), + handle_send_trap(S, Notification, NotifyName, ContextName, Recv, Varbinds, + LocalEngineID, ExtraInfo). + +handle_send_trap(#state{type = Type} = S, + Notification, NotifyName, ContextName, Recv, Varbinds, + LocalEngineID, ExtraInfo) -> ?vtrace("handle_send_trap -> entry with" - "~n S#state.type: ~p" + "~n Agent type: ~p" "~n TrapName: ~p" "~n NotifyName: ~p" "~n ContextName: ~p" "~n LocalEngineID: ~p", - [S#state.type, TrapName, NotifyName, ContextName, LocalEngineID]), - case snmpa_trap:construct_trap(TrapName, Varbinds) of + [Type, Notification, NotifyName, ContextName, LocalEngineID]), + case snmpa_trap:construct_trap(Notification, Varbinds) of {ok, TrapRecord, VarList} -> ?vtrace("handle_send_trap -> construction complete: " "~n TrapRecord: ~p" "~n VarList: ~p", [TrapRecord, VarList]), - case S#state.type of + case Type of subagent -> ?vtrace("handle_send_trap -> [sub] forward trap",[]), maybe_forward_trap(S, TrapRecord, NotifyName, - ContextName, Recv, VarList), + ContextName, Recv, VarList, ExtraInfo), {ok, S}; master_agent -> ?vtrace("handle_send_trap -> " "[master] handle send trap",[]), maybe_send_trap(S, TrapRecord, NotifyName, ContextName, Recv, VarList, - LocalEngineID) + LocalEngineID, ExtraInfo) end; error -> error @@ -1748,7 +1939,7 @@ handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds, maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S, - TrapRec, NotifyName, ContextName, Recv, V) -> + TrapRec, NotifyName, ContextName, Recv, V, ExtraInfo) -> ?vtrace("maybe_forward_trap -> entry with" "~n NFs: ~p", [NFs]), case filter_notification(NFs, [], TrapRec) of @@ -1764,13 +1955,15 @@ maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S, {send, [], TrapRec2} -> ?vtrace("maybe_forward_trap -> forward trap:" "~n ~p", [TrapRec2]), - forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V), + forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V, + ExtraInfo), {ok, S}; {send, Removed, TrapRec2} -> ?vtrace("maybe_forward_trap -> forward trap:" "~n ~p", [TrapRec2]), - forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V), + forward_trap(Parent, TrapRec2, NotifyName, ContextName, Recv, V, + ExtraInfo), NFs2 = del_notification_filter(Removed, NFs), {ok, S#state{nfilters = NFs2}} end. @@ -1778,7 +1971,7 @@ maybe_forward_trap(#state{parent = Parent, nfilters = NFs} = S, maybe_send_trap(#state{nfilters = NFs} = S, TrapRec, NotifyName, ContextName, Recv, Varbinds, - LocalEngineID) -> + LocalEngineID, ExtraInfo) -> ?vtrace("maybe_send_trap -> entry with" "~n NFs: ~p", [NFs]), case filter_notification(NFs, [], TrapRec) of @@ -1796,7 +1989,7 @@ maybe_send_trap(#state{nfilters = NFs} = S, "~n ~p", [TrapRec2]), do_handle_send_trap(S, TrapRec2, NotifyName, ContextName, Recv, Varbinds, - LocalEngineID); + LocalEngineID, ExtraInfo); {send, Removed, TrapRec2} -> ?vtrace("maybe_send_trap -> send trap:" @@ -1804,36 +1997,37 @@ maybe_send_trap(#state{nfilters = NFs} = S, NFs2 = del_notification_filter(Removed, NFs), do_handle_send_trap(S#state{nfilters = NFs2}, TrapRec2, NotifyName, ContextName, Recv, Varbinds, - LocalEngineID) + LocalEngineID, ExtraInfo) end. do_handle_send_trap(S, TrapRec, NotifyName, ContextName, Recv, Varbinds, - LocalEngineID) -> + LocalEngineID, ExtraInfo) -> Vbs = snmpa_trap:try_initialise_vars(get(mibserver), Varbinds), case S#state.type of subagent -> forward_trap(S#state.parent, TrapRec, NotifyName, ContextName, - Recv, Vbs), + Recv, Vbs, ExtraInfo), {ok, S}; master_agent when S#state.multi_threaded =:= false -> ?vtrace("do_handle_send_trap -> send trap:" "~n ~p", [TrapRec]), snmpa_trap:send_trap(TrapRec, NotifyName, ContextName, - Recv, Vbs, LocalEngineID, get(net_if)), + Recv, Vbs, LocalEngineID, ExtraInfo, + get(net_if)), {ok, S}; master_agent when S#state.worker_state =:= busy -> %% Main worker busy => create new worker ?vtrace("do_handle_send_trap -> main worker busy: " "spawn a trap sender", []), spawn_trap_thread(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID), + LocalEngineID, ExtraInfo), {ok, S}; 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}, + LocalEngineID, ExtraInfo}, {ok, S#state{worker_state = busy}} end. @@ -1932,7 +2126,7 @@ send_discovery(S, From, TargetName, Record, ContextName, InitVars, DiscoHandler, ExtraInfo) -> case snmpa_trap:send_discovery(TargetName, Record, ContextName, - InitVars, get(net_if)) of + InitVars, get(net_if), ExtraInfo) of {ok, Sender, SecLevel} -> Disco = #disco{from = From, rec = Record, @@ -2009,9 +2203,12 @@ handle_discovery_response(#state{disco = #disco{target = TargetName, #disco{rec = Record, ctx = ContextName, ivbs = InitVars} = Disco, - case snmpa_trap:send_discovery(TargetName, Record, + case snmpa_trap:send_discovery(TargetName, + Record, ContextName, - InitVars, get(net_if)) of + InitVars, + get(net_if), + ExtraInfo) of {ok, Sender, _SecLevel} -> ?vdebug("handle_discovery_response(1) -> " "stage 2 trap sent", []), @@ -3971,6 +4168,14 @@ user_err(F, A) -> %% --------------------------------------------------------------------- +maybe_call(Server, Req) -> + case (wis(Server) =:= self()) of + false -> + call(Server, Req); + true -> + Server ! Req + end. + call(Server, Req) -> gen_server:call(Server, Req, infinity). diff --git a/lib/snmp/src/agent/snmpa_authentication_service.erl b/lib/snmp/src/agent/snmpa_authentication_service.erl index 572fab7fbf..d406c58ee4 100644 --- a/lib/snmp/src/agent/snmpa_authentication_service.erl +++ b/lib/snmp/src/agent/snmpa_authentication_service.erl @@ -29,11 +29,12 @@ behaviour_info(_) -> %%----------------------------------------------------------------- %% init_check_access(Pdu, ACMData) %% Pdu = #pdu -%% ACMData = acm_data() = {community, Community, Address} | -%% {v3, MsgID, SecModel, SecName, SecLevel, -%% ContextEngineID, ContextName, SecData} +%% ACMData = acm_data() = {community, SecModel, Community, TDomain, TAddress} | +%% {v3, MsgID, SecModel, SecName, SecLevel, +%% ContextEngineID, ContextName, SecData} %% Community = string() -%% Address = ip() ++ udp() (list) +%% TDomain = ?transportDomainUdpIpv4 | ?transportDomainUdpIpv6 +%% TAddress = ip() ++ udp() (list) %% MsgID = integer() <not used> %% SecModel = ?SEC_* (see snmp_types.hrl) %% SecName = string() diff --git a/lib/snmp/src/agent/snmpa_conf.erl b/lib/snmp/src/agent/snmpa_conf.erl index b4fc716b3e..4e5aab5319 100644 --- a/lib/snmp/src/agent/snmpa_conf.erl +++ b/lib/snmp/src/agent/snmpa_conf.erl @@ -48,7 +48,7 @@ %% target_addr.conf target_addr_entry/5, target_addr_entry/6, - target_addr_entry/8, target_addr_entry/10, + target_addr_entry/8, target_addr_entry/10, target_addr_entry/11, write_target_addr_config/2, write_target_addr_config/3, append_target_addr_config/2, read_target_addr_config/1, @@ -447,7 +447,23 @@ target_addr_entry(Name, EngineId, TMask, MaxMessageSize) -> + target_addr_entry(Name, snmp_target_mib:default_domain(), Ip, Udp, + Timeout, RetryCount, TagList, ParamsName, + TMask, MaxMessageSize). + +target_addr_entry(Name, + Domain, + Ip, + Udp, + Timeout, + RetryCount, + TagList, + ParamsName, + EngineId, + TMask, + MaxMessageSize) -> {Name, + Domain, Ip, Udp, Timeout, @@ -465,9 +481,13 @@ write_target_addr_config(Dir, Conf) -> "%% The data is inserted into the snmpTargetAddrTable defined\n" "%% in SNMP-TARGET-MIB, and in the snmpTargetAddrExtTable defined\n" "%% in SNMP-COMMUNITY-MIB.\n" -"%% Each row is a 10-tuple:\n" -"%% {Name, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId,\n" -"%% TMask, MaxMessageSize}.\n" +"%% Each row is a 10 or 11-tuple (Domain is optional):\n" +"%% {Name, \n" +"%% Domain, Ip, Port, \n" +"%% Timeout, RetryCount, TagList, ParamsName, EngineId,\n" +"%% TMask, MaxMessageSize}.\n" +"%% The value of Domain decide the format of the Ip and TMask values. \n" +"%% If not present, classic Ipv4 is assumed. \n" "%% The EngineId value is only used if Inform-Requests are sent to this\n" "%% target. If Informs are not sent, this value is ignored, and can be\n" "%% e.g. an empty string. However, if Informs are sent, it is essential\n" @@ -521,16 +541,31 @@ write_target_addr_conf(Fd, Hdr, Conf) -> write_target_addr_conf(Fd, Conf) -> Fun = fun(Entry) -> do_write_target_addr_conf(Fd, Entry) end, - lists:foreach(Fun, Conf). + lists:foreach(Fun, Conf), + ok. do_write_target_addr_conf(Fd, - {Name, Ip, Udp, + {Name, + Ip, Udp, + Timeout, RetryCount, TagList, + ParamsName, EngineId, + TMask, MaxMessageSize}) -> + Domain = snmp_target_mib:default_domain(), + do_write_target_addr_conf(Fd, + {Name, + Domain, Ip, Udp, + Timeout, RetryCount, TagList, + ParamsName, EngineId, + TMask, MaxMessageSize}); +do_write_target_addr_conf(Fd, + {Name, + Domain, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize}) -> io:format(Fd, - "{\"~s\", ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n", - [Name, Ip, Udp, Timeout, RetryCount, TagList, + "{\"~s\", ~w, ~w, ~w, ~w, ~w, \"~s\", \"~s\", \"~s\", ~w, ~w}.~n", + [Name, Domain, Ip, Udp, Timeout, RetryCount, TagList, ParamsName, EngineId, TMask, MaxMessageSize]); do_write_target_addr_conf(_Fd, Crap) -> error({bad_target_addr_config, Crap}). @@ -546,13 +581,13 @@ target_params_entry(Name, Vsn) -> target_params_entry(Name, Vsn, SecName, SecLevel). target_params_entry(Name, Vsn, SecName, SecLevel) -> - MPModel = if Vsn == v1 -> v1; - Vsn == v2 -> v2c; - Vsn == v3 -> v3 + MPModel = if Vsn =:= v1 -> v1; + Vsn =:= v2 -> v2c; + Vsn =:= v3 -> v3 end, - SecModel = if Vsn == v1 -> v1; - Vsn == v2 -> v2c; - Vsn == v3 -> usm + SecModel = if Vsn =:= v1 -> v1; + Vsn =:= v2 -> v2c; + Vsn =:= v3 -> usm end, target_params_entry(Name, MPModel, SecModel, SecName, SecLevel). diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl index 9fa874f119..a91f30a4a6 100644 --- a/lib/snmp/src/agent/snmpa_internal.hrl +++ b/lib/snmp/src/agent/snmpa_internal.hrl @@ -23,6 +23,7 @@ -include_lib("snmp/src/app/snmp_internal.hrl"). -define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()). +-define(DEFAULT_NOTIF_EXTRA_INFO, {snmpa_default_notification_extra_info}). -define(snmpa_info(F, A), ?snmp_info("agent", F, A)). -define(snmpa_warning(F, A), ?snmp_warning("agent", F, A)). diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl index fd75b98f84..39a4246d26 100644 --- a/lib/snmp/src/agent/snmpa_mpd.erl +++ b/lib/snmp/src/agent/snmpa_mpd.erl @@ -115,8 +115,8 @@ reset() -> %% Func: process_packet(Packet, TDomain, TAddress, State, Log) -> %% {ok, SnmpVsn, Pdu, PduMS, ACMData} | {discarded, Reason} %% Types: Packet = binary() -%% TDomain = snmpUDPDomain | atom() -%% TAddress = {Ip, Udp} +%% TDomain = snmpUDPDomain | transportDomain() +%% TAddress = {Ip, Udp} (*but* depends on TDomain) %% State = #state %% Purpose: This is the main Message Dispatching function. (see %% section 4.2.1 in rfc2272) @@ -182,24 +182,30 @@ discarded_pdu(Variable) -> inc(Variable). %%----------------------------------------------------------------- %% Handles a Community based message (v1 or v2c). %%----------------------------------------------------------------- -v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain, +v1_v2c_proc(Vsn, NoteStore, Community, Domain, {Ip, Udp}, LocalEngineID, Data, HS, Log, Packet) -> - TAddress = tuple_to_list(Ip) ++ [Udp div 256, Udp rem 256], - AgentMS = get_engine_max_message_size(LocalEngineID), - MgrMS = snmp_community_mib:get_target_addr_ext_mms(?snmpUDPDomain, - TAddress), - PduMS = case MgrMS of - {ok, MMS} when MMS < AgentMS -> MMS - HS; - _ -> AgentMS - HS - end, + TDomain = snmp_conf:mk_tdomain(Domain), + TAddress = snmp_conf:mk_taddress(Domain, Ip, Udp), + AgentMS = get_engine_max_message_size(LocalEngineID), + MgrMS = snmp_community_mib:get_target_addr_ext_mms(TDomain, TAddress), + PduMS = case MgrMS of + {ok, MMS} when MMS < AgentMS -> MMS - HS; + _ -> AgentMS - HS + end, case (catch snmp_pdus:dec_pdu(Data)) of Pdu when is_record(Pdu, pdu) -> Log(Pdu#pdu.type, Packet), inc_snmp_in_vars(Pdu), #pdu{request_id = ReqId} = Pdu, - OkRes = {ok, Vsn, Pdu, PduMS, - {community, sec_model(Vsn), Community, TAddress}}, + + %% <TDomain> + %% We have added TDomain, what are the consequences? + ACMData = + {community, sec_model(Vsn), Community, TDomain, TAddress}, + OkRes = {ok, Vsn, Pdu, PduMS, ACMData}, + %% </TDomain> + %% Make sure that we don't process duplicate SET request %% twice. We don't know what could happen in that case. %% The mgr does, so he has to generate a new SET request. @@ -216,8 +222,6 @@ v1_v2c_proc(Vsn, NoteStore, Community, snmpUDPDomain, snmp_note_store:set_note(NoteStore, 100, Key, true), %% Uses ACMData that snmpa_acm knows of. - %% snmpUDPDomain is implicit, since that's the only - %% one we handle. OkRes; true -> {discarded, duplicate_pdu} @@ -275,12 +279,12 @@ v3_proc(NoteStore, Packet, LocalEngineID, V3Hdr, Data, Log) -> "~n msgSecurityParameters = ~w", [MsgID, MMS, MsgFlags, MsgSecurityModel, SecParams]), %% 7.2.4 - SecModule = get_security_module(MsgSecurityModel), + SecModule = get_security_module(MsgSecurityModel), %% 7.2.5 - SecLevel = check_sec_level(MsgFlags), + SecLevel = check_sec_level(MsgFlags), IsReportable = snmp_misc:is_reportable(MsgFlags), %% 7.2.6 - ?vtrace("v3_proc -> [7.2.6]" + ?vtrace("v3_proc -> [7.2.4-7.2.6]" "~n SecModule = ~p" "~n SecLevel = ~p" "~n IsReportable = ~p", @@ -531,7 +535,7 @@ check_sec_module_result(Res, V3Hdr, Data, LocalEngineID, IsReportable, Log) -> ?vdebug("security module result [7.2.6-b]:" "~n Reason: ~p", [Reason]), throw({discarded, {securityError, Reason}}); - {error, Reason, ErrorInfo} when IsReportable == true -> % case 7.2.6 a + {error, Reason, ErrorInfo} when IsReportable =:= true -> % case 7.2.6 a ?vdebug("security module result when reportable [7.2.6-a]:" "~n Reason: ~p" "~n ErrorInfo: ~p", [Reason, ErrorInfo]), @@ -574,7 +578,7 @@ generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log) -> generate_response_msg(Vsn, RePdu, Type, ACMData, LocalEngineID, Log, 1). generate_response_msg(Vsn, RePdu, Type, - {community, _SecModel, Community, _IpUdp}, + {community, _SecModel, Community, _TDomain, _TAddress}, LocalEngineID, Log, _) -> case catch snmp_pdus:enc_pdu(RePdu) of diff --git a/lib/snmp/src/agent/snmpa_net_if.erl b/lib/snmp/src/agent/snmpa_net_if.erl index 97a7a63dee..bbc5568cde 100644 --- a/lib/snmp/src/agent/snmpa_net_if.erl +++ b/lib/snmp/src/agent/snmpa_net_if.erl @@ -314,6 +314,14 @@ loop(S) -> NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined), loop(NewS); + %% We dont use the extra-info at this time, ... + {send_pdu, Vsn, Pdu, MsgData, To, _ExtraInfo} -> + ?vdebug("send pdu: " + "~n Pdu: ~p" + "~n To: ~p", [Pdu, To]), + NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, undefined), + loop(NewS); + %% Informs {send_pdu_req, Vsn, Pdu, MsgData, To, From} -> ?vdebug("send pdu request: " @@ -324,7 +332,18 @@ loop(S) -> NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, From), loop(NewS); + %% We dont use the extra-info at this time, ... + {send_pdu_req, Vsn, Pdu, MsgData, To, From, _ExtraInfo} -> + ?vdebug("send pdu request: " + "~n Pdu: ~p" + "~n To: ~p" + "~n From: ~p", + [Pdu, To, toname(From)]), + NewS = maybe_handle_send_pdu(S, Vsn, Pdu, MsgData, To, From), + loop(NewS); + %% Discovery Inform + %% <BACKWARD-COMPAT> {send_discovery, Pdu, MsgData, To, From} -> ?vdebug("received send discovery request: " "~n Pdu: ~p" @@ -333,6 +352,18 @@ loop(S) -> [Pdu, To, toname(From)]), NewS = handle_send_discovery(S, Pdu, MsgData, To, From), loop(NewS); + %% </BACKWARD-COMPAT> + + %% Discovery Inform + {send_discovery, Pdu, MsgData, To, From, ExtraInfo} -> + ?vdebug("received send discovery request: " + "~n Pdu: ~p" + "~n To: ~p" + "~n From: ~p" + "~n ExtraInfo: ~p", + [Pdu, To, toname(From), ExtraInfo]), + NewS = handle_send_discovery(S, Pdu, MsgData, To, From), + loop(NewS); {discarded_pdu, _Vsn, ReqId, _ACMData, Variable, _Extra} -> ?vdebug("discard PDU: ~p", [Variable]), @@ -504,7 +535,6 @@ handle_discovery_response(_Ip, _Port, #pdu{request_id = ReqId} = Pdu, S end. - handle_recv(#state{usock = Sock, mpd_state = MpdState, note_store = NS, @@ -513,7 +543,9 @@ handle_recv(#state{usock = Sock, LogF = fun(Type, Data) -> log(Log, Type, Data, Ip, Port) end, - case (catch snmpa_mpd:process_packet(Packet, snmpUDPDomain, {Ip, Port}, + Domain = snmp_conf:which_domain(Ip), % What the ****... + case (catch snmpa_mpd:process_packet(Packet, + Domain, {Ip, Port}, MpdState, NS, LogF)) of {ok, _Vsn, Pdu, _PduMS, {discovery, ManagerEngineId}} -> handle_discovery_response(Ip, Port, Pdu, ManagerEngineId, S); @@ -636,7 +668,6 @@ process_taddrs([{{_Domain, AddrAndPort}, _SecData}|T], Acc) -> process_taddrs([{_Domain, AddrAndPort}|T], Acc) -> process_taddrs(T, [AddrAndPort|Acc]). - merge_taddrs(To1, To2) -> merge_taddrs(To1, To2, []). @@ -776,15 +807,49 @@ handle_send_pdu1(#state{log = Log, usock = Sock, filter = FilterMod}, Type, Addresses) -> SendFun = - fun({snmpUDPDomain, {Ip, Port}, Packet}) when is_binary(Packet) -> - ?vdebug("sending packet:" + fun({snmpUDPDomain, {Ip, Port}, Packet}) + when is_binary(Packet) -> + ?vdebug("[snmpUDPDomain] sending packet:" + "~n size: ~p" + "~n to: ~p:~p", + [sz(Packet), Ip, Port]), + maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet); + + ({snmpUDPDomain, {Ip, Port}, {Packet, _LogData}}) + when is_binary(Packet) -> + ?vdebug("[snmpUDPDomain] sending encrypted packet:" + "~n size: ~p" + "~n to: ~p:~p", + [sz(Packet), Ip, Port]), + maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet); + + ({transportDomainUdpIpv4, {Ip, Port}, Packet}) + when is_binary(Packet) -> + ?vdebug("[transportDomainUdpIpv4] sending packet:" + "~n size: ~p" + "~n to: ~p:~p", + [sz(Packet), Ip, Port]), + maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet); + + ({transportDomainUdpIpv4, {Ip, Port}, {Packet, _LogData}}) + when is_binary(Packet) -> + ?vdebug("[transportDomainUdpIpv4] sending encrypted packet:" + "~n size: ~p" + "~n to: ~p:~p", + [sz(Packet), Ip, Port]), + maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet); + + ({transportDomainUdpIpv6, {Ip, Port}, Packet}) + when is_binary(Packet) -> + ?vdebug("[transportDomainUdpIpv6] sending packet:" "~n size: ~p" "~n to: ~p:~p", [sz(Packet), Ip, Port]), maybe_udp_send(FilterMod, Log, Type, Sock, Ip, Port, Packet); - ({snmpUDPDomain, {Ip, Port}, {Packet, _LogData}}) when is_binary(Packet) -> - ?vdebug("sending encrypted packet:" + ({transportDomainUdpIpv6, {Ip, Port}, {Packet, _LogData}}) + when is_binary(Packet) -> + ?vdebug("[transportDomainUdpIpv6] sending encrypted packet:" "~n size: ~p" "~n to: ~p:~p", [sz(Packet), Ip, Port]), diff --git a/lib/snmp/src/agent/snmpa_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl index 450cb2e9f4..3c7ae804a5 100644 --- a/lib/snmp/src/agent/snmpa_trap.erl +++ b/lib/snmp/src/agent/snmpa_trap.erl @@ -24,27 +24,34 @@ %% External exports -export([construct_trap/2, try_initialise_vars/2, - send_trap/6, send_trap/7]). --export([send_discovery/5]). + send_trap/6, send_trap/7, send_trap/8]). +-export([send_discovery/6]). %% Internal exports --export([init_v2_inform/9, - init_v3_inform/9, init_v3_inform/10, +-export([init_v2_inform/9, init_v2_inform/10, + init_v3_inform/9, init_v3_inform/10, init_v3_inform/11, send_inform/6]). --export([init_discovery_inform/12, send_discovery_inform/5]). - --include("snmp_types.hrl"). --include("snmpa_internal.hrl"). --include("SNMPv2-MIB.hrl"). --include("SNMPv2-TM.hrl"). --include("SNMPv2-TC.hrl"). --include("SNMP-FRAMEWORK-MIB.hrl"). --include("SNMP-TARGET-MIB.hrl"). +-export([init_discovery_inform/13, send_discovery_inform/5]). + +%% <BACKWARD-COMPAT> +-export([send_discovery/5, + init_discovery_inform/12]). +%% </BACKWARD-COMPAT> + +-include_lib("snmp/include/snmp_types.hrl"). +-include_lib("snmp/src/agent/snmpa_internal.hrl"). +-include_lib("snmp/include/SNMPv2-MIB.hrl"). +-include_lib("snmp/include/SNMPv2-TM.hrl"). +-include_lib("snmp/include/SNMPv2-TC.hrl"). +-include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/SNMP-TARGET-MIB.hrl"). +-include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl"). -define(enterpriseSpecific, 6). -define(VMODULE,"TRAP"). -include("snmp_verbosity.hrl"). +-include("snmpa_internal.hrl"). %%----------------------------------------------------------------- @@ -335,25 +342,36 @@ make_varbind_list(Varbinds) -> %% SnmpTargetAddrTable (using the Tag). %%----------------------------------------------------------------- send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, NetIf) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, + send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, + LocalEngineID, ExtraInfo, NetIf). + +send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, ExtraInfo, NetIf) -> LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, NetIf). + LocalEngineID, ExtraInfo, NetIf). -send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, NetIf) -> +send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, + ExtraInfo, NetIf) -> (catch do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, NetIf)). + LocalEngineID, ExtraInfo, NetIf)). do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, - LocalEngineID, NetIf) -> + LocalEngineID, ExtraInfo, NetIf) -> VarbindList = make_varbind_list(Vbs), Dests = find_dests(NotifyName), send_trap_pdus(Dests, ContextName, {TrapRec, VarbindList}, [], [], [], - Recv, LocalEngineID, NetIf). + Recv, LocalEngineID, ExtraInfo, NetIf). send_discovery(TargetName, Record, ContextName, Vbs, NetIf) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + send_discovery(TargetName, Record, ContextName, Vbs, NetIf, ExtraInfo). +send_discovery(TargetName, Record, ContextName, Vbs, NetIf, ExtraInfo) -> case find_dest(TargetName) of {ok, Dest} -> - send_discovery_pdu(Dest, Record, ContextName, Vbs, NetIf); + send_discovery_pdu(Dest, Record, ContextName, Vbs, NetIf, + ExtraInfo); Error -> Error end. @@ -440,11 +458,13 @@ split_variables([]) -> {[], []}. %% NOTE: This function is executed in the master agent's context %%----------------------------------------------------------------- find_dests("") -> + ?vtrace("find destinations", []), snmp_notification_mib:get_targets(); find_dests(NotifyName) -> + ?vtrace("find destinations for ~p", [NotifyName]), case snmp_notification_mib:get_targets(NotifyName) of [] -> - ?vlog("No dests found for snmpNotifyName: ~p",[NotifyName]), + ?vlog("No dests found for NotifyName: ~p", [NotifyName]), []; Dests -> Dests @@ -529,7 +549,8 @@ find_dest(TargetName) -> send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel}, Timeout, Retry}, - Record, ContextName, Vbs, NetIf) -> + Record, ContextName, Vbs, NetIf, + ExtraInfo) -> ?vdebug("send_discovery_pdu -> entry with " "~n Destination address: ~p" "~n Target name: ~p" @@ -539,9 +560,10 @@ send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel}, "~n Timeout: ~p" "~n Retry: ~p" "~n Record: ~p" - "~n ContextName: ~p", + "~n ContextName: ~p" + "~n ExtraInfo: ~p", [Dest, TargetName, SecModel, SecName, SecLevel, - Timeout, Retry, Record, ContextName]), + Timeout, Retry, Record, ContextName, ExtraInfo]), case get_mib_view(SecModel, SecName, SecLevel, ContextName) of {ok, MibView} -> case check_all_varbinds(Record, Vbs, MibView) of @@ -551,7 +573,7 @@ send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel}, SecModel, SecName, SecLevel, TargetName, ContextName, Timeout, Retry, - SysUpTime, NetIf); + SysUpTime, NetIf, ExtraInfo); false -> {error, {mibview_validation_failed, Vbs, MibView}} end; @@ -561,7 +583,7 @@ send_discovery_pdu({Dest, TargetName, {SecModel, SecName, SecLevel}, send_discovery_pdu(Record, Dest, Vbs, SecModel, SecName, SecLevel, TargetName, - ContextName, Timeout, Retry, SysUpTime, NetIf) -> + ContextName, Timeout, Retry, SysUpTime, NetIf, ExtraInfo) -> {_Oid, IVbs} = mk_v2_trap(Record, Vbs, SysUpTime), % v2 refers to SMIv2; Sender = proc_lib:spawn_link(?MODULE, init_discovery_inform, [self(), @@ -570,13 +592,25 @@ send_discovery_pdu(Record, Dest, Vbs, ContextName, Timeout, Retry, IVbs, NetIf, - get(verbosity)]), + get(verbosity), + ExtraInfo]), {ok, Sender, SecLevel}. init_discovery_inform(Parent, Dest, SecModel, SecName, SecLevel, TargetName, ContextName, Timeout, Retry, Vbs, NetIf, Verbosity) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + init_discovery_inform(Parent, + Dest, + SecModel, SecName, SecLevel, TargetName, + ContextName, Timeout, Retry, Vbs, NetIf, + Verbosity, ExtraInfo). +init_discovery_inform(Parent, + Dest, + SecModel, SecName, SecLevel, TargetName, + ContextName, Timeout, Retry, Vbs, NetIf, + Verbosity, ExtraInfo) -> put(verbosity, Verbosity), put(sname, madis), Pdu = make_discovery_pdu(Vbs), @@ -584,7 +618,7 @@ init_discovery_inform(Parent, SecLevelFlag = mk_flag(SecLevel), SecData = {SecModel, SecName, SecLevelFlag, TargetName}, MsgData = {SecData, ContextEngineId, ContextName}, - Msg = {send_discovery, Pdu, MsgData, Dest, self()}, + Msg = {send_discovery, Pdu, MsgData, Dest, self(), ExtraInfo}, ?MODULE:send_discovery_inform(Parent, Timeout*10, Retry, Msg, NetIf). %% note_timeout(Timeout, Retry) @@ -628,11 +662,11 @@ send_discovery_inform(Parent, Timeout, Retry, Msg, NetIf) -> %% should be used for the target, and determine the message %% specific parameters to be used. %%----------------------------------------------------------------- -send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel}, - Type} | T], +send_trap_pdus([{DestAddr, TargetName, + {MpModel, SecModel, SecName, SecLevel}, Type} | T], ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv, - LocalEngineID, NetIf) -> + LocalEngineID, ExtraInfo, NetIf) -> ?vdebug("send trap pdus: " "~n Destination address: ~p" "~n Target name: ~p" @@ -658,13 +692,13 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel}, send_trap_pdus(T, ContextName, {TrapRec, Vbs}, [{DestAddr, Community} | V1Res], V2Res, V3Res, Recv, - LocalEngineID, NetIf); + LocalEngineID, ExtraInfo, NetIf); undefined -> ?vdebug("No community found for v1 dest: ~p", [element(2, DestAddr)]), send_trap_pdus(T, ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv, - LocalEngineID, NetIf) + LocalEngineID, ExtraInfo, NetIf) end; true when MpModel =:= ?MP_V2C -> ?vtrace("send_trap_pdus -> v2c mp model",[]), @@ -679,13 +713,14 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel}, send_trap_pdus(T, ContextName, {TrapRec, Vbs}, V1Res, [{DestAddr, Community, Type}|V2Res], - V3Res, Recv, LocalEngineID, NetIf); + V3Res, Recv, + LocalEngineID, ExtraInfo, NetIf); undefined -> ?vdebug("No community found for v2c dest: ~p", [element(2, DestAddr)]), send_trap_pdus(T, ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv, - LocalEngineID, NetIf) + LocalEngineID, ExtraInfo, NetIf) end; true when MpModel =:= ?MP_V3 -> ?vtrace("send_trap_pdus -> v3 mp model",[]), @@ -694,20 +729,20 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel}, send_trap_pdus(T, ContextName, {TrapRec, Vbs}, V1Res, V2Res, [{DestAddr, MsgData, Type} | V3Res], - Recv, LocalEngineID, NetIf); + Recv, LocalEngineID, ExtraInfo, NetIf); true -> ?vlog("bad MpModel ~p for dest ~p", [MpModel, element(2, DestAddr)]), send_trap_pdus(T, ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv, - LocalEngineID, NetIf); + LocalEngineID, ExtraInfo, NetIf); _ -> ?vlog("no access for dest: " "~n ~p in target ~p", [element(2, DestAddr), TargetName]), send_trap_pdus(T, ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res, Recv, - LocalEngineID, NetIf) + LocalEngineID, ExtraInfo, NetIf) end; {discarded, Reason} -> ?vlog("mib view error ~p for" @@ -715,24 +750,27 @@ send_trap_pdus([{DestAddr, TargetName, {MpModel, SecModel, SecName, SecLevel}, "~n SecName: ~w", [Reason, element(2, DestAddr), SecName]), send_trap_pdus(T, ContextName, {TrapRec, Vbs}, - V1Res, V2Res, V3Res, Recv, LocalEngineID, NetIf) + V1Res, V2Res, V3Res, Recv, + LocalEngineID, ExtraInfo, NetIf) end; -send_trap_pdus([], ContextName, {TrapRec, Vbs}, V1Res, V2Res, V3Res, - Recv, LocalEngineID, NetIf) -> +send_trap_pdus([], ContextName, {TrapRec, Vbs}, + V1Res, V2Res, V3Res, Recv, + LocalEngineID, ExtraInfo, + NetIf) -> SysUpTime = snmp_standard_mib:sys_up_time(), ?vdebug("send trap pdus with sysUpTime ~p", [SysUpTime]), InformRecvs = get_inform_recvs(V2Res ++ V3Res), InformTargets = [Addr || {Addr, _, _, _} <- InformRecvs], deliver_recv(Recv, snmp_targets, InformTargets), - send_v1_trap(TrapRec, V1Res, Vbs, NetIf, SysUpTime), - send_v2_trap(TrapRec, V2Res, Vbs, Recv, NetIf, SysUpTime), - send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, NetIf, + send_v1_trap(TrapRec, V1Res, Vbs, ExtraInfo, NetIf, SysUpTime), + send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime), + send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, ExtraInfo, NetIf, SysUpTime, ContextName). -send_v1_trap(_TrapRec, [], _Vbs, _NetIf, _SysUpTime) -> +send_v1_trap(_TrapRec, [], _Vbs, _ExtraInfo, _NetIf, _SysUpTime) -> ok; send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec}, - V1Res, Vbs, NetIf, SysUpTime) -> + V1Res, Vbs, ExtraInfo, NetIf, SysUpTime) -> ?vdebug("prepare to send v1 trap " "~n '~p'" "~n with" @@ -744,9 +782,10 @@ send_v1_trap(#trap{enterpriseoid = Enter, specificcode = Spec}, lists:foreach(fun({Community, Addrs}) -> ?vtrace("send v1 trap pdu to ~p",[Addrs]), NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs} + {community, Community}, Addrs, ExtraInfo} end, AddrCommunities); -send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, NetIf, SysUpTime) -> +send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, ExtraInfo, NetIf, + SysUpTime) -> %% Use alg. in rfc2089 to map a v2 trap to a v1 trap % delete Counter64 objects from vbs ?vdebug("prepare to send v1 trap '~p'",[Oid]), @@ -768,31 +807,31 @@ send_v1_trap(#notification{oid = Oid}, V1Res, Vbs, NetIf, SysUpTime) -> lists:foreach(fun({Community, Addrs}) -> ?vtrace("send v1 trap to ~p",[Addrs]), NetIf ! {send_pdu, 'version-1', TrapPdu, - {community, Community}, Addrs} + {community, Community}, Addrs, ExtraInfo} end, AddrCommunities). -send_v2_trap(_TrapRec, [], _Vbs, _Recv, _NetIf, _SysUpTime) -> +send_v2_trap(_TrapRec, [], _Vbs, _Recv, _ExtraInfo, _NetIf, _SysUpTime) -> ok; -send_v2_trap(TrapRec, V2Res, Vbs, Recv, NetIf, SysUpTime) -> +send_v2_trap(TrapRec, V2Res, Vbs, Recv, ExtraInfo, NetIf, SysUpTime) -> ?vdebug("prepare to send v2 trap",[]), {_Oid, IVbs} = mk_v2_trap(TrapRec, Vbs, SysUpTime), - TrapRecvs = get_trap_recvs(V2Res), - InformRecvs = get_inform_recvs(V2Res), - do_send_v2_trap(TrapRecvs, IVbs, NetIf), - do_send_v2_inform(InformRecvs, IVbs, Recv, NetIf). + TrapRecvs = get_trap_recvs(V2Res), + InformRecvs = get_inform_recvs(V2Res), + do_send_v2_trap(TrapRecvs, IVbs, ExtraInfo, NetIf), + do_send_v2_inform(InformRecvs, IVbs, Recv, ExtraInfo, NetIf). -send_v3_trap(_TrapRec, [], _Vbs, _Recv, _LocalEngineID, +send_v3_trap(_TrapRec, [], _Vbs, _Recv, _LocalEngineID, _ExtraInfo, _NetIf, _SysUpTime, _ContextName) -> ok; -send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, +send_v3_trap(TrapRec, V3Res, Vbs, Recv, LocalEngineID, ExtraInfo, NetIf, SysUpTime, ContextName) -> ?vdebug("prepare to send v3 trap",[]), {_Oid, IVbs} = mk_v2_trap(TrapRec, Vbs, SysUpTime), % v2 refers to SMIv2; TrapRecvs = get_trap_recvs(V3Res), % same SMI for v3 InformRecvs = get_inform_recvs(V3Res), - do_send_v3_trap(TrapRecvs, ContextName, IVbs, NetIf), + do_send_v3_trap(TrapRecvs, ContextName, IVbs, ExtraInfo, NetIf), do_send_v3_inform(InformRecvs, ContextName, IVbs, Recv, - LocalEngineID, NetIf). + LocalEngineID, ExtraInfo, NetIf). mk_v2_trap(#notification{oid = Oid}, Vbs, SysUpTime) -> @@ -830,60 +869,70 @@ get_inform_recvs(InformRecvs) -> [{Addr, MsgData, Timeout, Retry} || {Addr, MsgData, {inform, Timeout, Retry}} <- InformRecvs]. -do_send_v2_trap([], _Vbs, _NetIf) -> +do_send_v2_trap([], _Vbs, _ExtraInfo, _NetIf) -> ok; -do_send_v2_trap(Recvs, Vbs, NetIf) -> +do_send_v2_trap(Recvs, Vbs, ExtraInfo, NetIf) -> TrapPdu = make_v2_notif_pdu(Vbs, 'snmpv2-trap'), AddrCommunities = mk_addr_communities(Recvs), lists:foreach(fun({Community, Addrs}) -> ?vtrace("~n send v2 trap to ~p",[Addrs]), NetIf ! {send_pdu, 'version-2', TrapPdu, - {community, Community}, Addrs} + {community, Community}, Addrs, ExtraInfo} end, AddrCommunities), ok. -do_send_v2_inform([], _Vbs, _Recv, _NetIf) -> +do_send_v2_inform([], _Vbs, _Recv, _ExtraInfo, _NetIf) -> ok; -do_send_v2_inform(Recvs, Vbs, Recv, NetIf) -> +do_send_v2_inform(Recvs, Vbs, Recv, ExtraInfo, NetIf) -> lists:foreach( fun({Addr, Community, Timeout, Retry}) -> ?vtrace("~n start inform sender to send v2 inform to ~p", [Addr]), proc_lib:spawn_link(?MODULE, init_v2_inform, [Addr, Timeout, Retry, Vbs, - Recv, NetIf, Community, + Recv, ExtraInfo, NetIf, Community, get(verbosity), get(sname)]) end, Recvs). -do_send_v3_trap([], _ContextName, _Vbs, _NetIf) -> +do_send_v3_trap([], _ContextName, _Vbs, _ExtraInfo, _NetIf) -> ok; -do_send_v3_trap(Recvs, ContextName, Vbs, NetIf) -> +do_send_v3_trap(Recvs, ContextName, Vbs, ExtraInfo, NetIf) -> TrapPdu = make_v2_notif_pdu(Vbs, 'snmpv2-trap'), % Yes, v2 ContextEngineId = snmp_framework_mib:get_engine_id(), lists:foreach(fun(Recv) -> ?vtrace("~n send v3 notif to ~p",[Recv]), NetIf ! {send_pdu, 'version-3', TrapPdu, - {v3, ContextEngineId, ContextName}, [Recv]} + {v3, ContextEngineId, ContextName}, + [Recv], ExtraInfo} end, Recvs), ok. -do_send_v3_inform([], _ContextName, _Vbs, _Recv, _LocalEngineID, _NetIf) -> +do_send_v3_inform([], _ContextName, _Vbs, _Recv, + _LocalEngineID, _ExtraInfo, _NetIf) -> ok; -do_send_v3_inform(Recvs, ContextName, Vbs, Recv, LocalEngineID, NetIf) -> +do_send_v3_inform(Recvs, ContextName, Vbs, Recv, + LocalEngineID, ExtraInfo, NetIf) -> lists:foreach( fun({Addr, MsgData, Timeout, Retry}) -> ?vtrace("~n start inform sender to send v3 inform to ~p", [Addr]), proc_lib:spawn_link(?MODULE, init_v3_inform, [{Addr, MsgData}, Timeout, Retry, Vbs, - Recv, LocalEngineID, NetIf, ContextName, + Recv, LocalEngineID, ExtraInfo, + NetIf, ContextName, get(verbosity), get(sname)]) end, Recvs). %% New process -init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community,V,S) -> +init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community, V, S) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, ExtraInfo, NetIf, + Community, V, S). + +init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, ExtraInfo, NetIf, + Community, V, S) -> %% Make a new Inform for each recipient; they need unique %% request-ids! put(verbosity,V), @@ -892,17 +941,26 @@ init_v2_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, Community,V,S) -> [Timeout,Retry]), InformPdu = make_v2_notif_pdu(Vbs, 'inform-request'), Msg = {send_pdu_req, 'version-2', InformPdu, {community, Community}, - [Addr], self()}, + [Addr], self(), ExtraInfo}, ?MODULE:send_inform(Addr, Timeout*10, Retry, Msg, Recv, NetIf). %% New process init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, NetIf, ContextName, V, S) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, LocalEngineID = ?DEFAULT_LOCAL_ENGINE_ID, - init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, + init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, + LocalEngineID, ExtraInfo, + NetIf, ContextName, V, S). + +init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, NetIf, + ContextName, V, S) -> + ExtraInfo = ?DEFAULT_NOTIF_EXTRA_INFO, + init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, + LocalEngineID, ExtraInfo, NetIf, ContextName, V, S). -init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, +init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, ExtraInfo, NetIf, ContextName, V, S) -> %% Make a new Inform for each recipient; they need unique %% request-ids! @@ -913,7 +971,7 @@ init_v3_inform(Addr, Timeout, Retry, Vbs, Recv, LocalEngineID, InformPdu = make_v2_notif_pdu(Vbs, 'inform-request'), % Yes, v2 ContextEngineId = LocalEngineID, Msg = {send_pdu_req, 'version-3', InformPdu, - {v3, ContextEngineId, ContextName}, [Addr], self()}, + {v3, ContextEngineId, ContextName}, [Addr], self(), ExtraInfo}, ?MODULE:send_inform(Addr, Timeout*10, Retry, Msg, Recv, NetIf). send_inform(Addr, _Timeout, -1, _Msg, Recv, _NetIf) -> @@ -1001,9 +1059,27 @@ transform_taddr({?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}) -> % v2 Addr = {A1, A2, A3, A4}, Port = P1 bsl 8 + P2, {Addr, Port}; +transform_taddr({?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}) -> % v2 + Addr = {A1, A2, A3, A4}, + Port = P1 bsl 8 + P2, + {Addr, Port}; +transform_taddr({?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}) -> % v2 + Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, + Port = P1 bsl 8 + P2, + {Addr, Port}; transform_taddr({{?snmpUDPDomain, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 Addr = {A1, A2, A3, A4}, Port = P1 bsl 8 + P2, + {Addr, Port}; +transform_taddr({{?transportDomainUdpIpv4, [A1, A2, A3, A4, P1, P2]}, _MsgData}) -> % v3 + Addr = {A1, A2, A3, A4}, + Port = P1 bsl 8 + P2, + {Addr, Port}; +transform_taddr({{?transportDomainUdpIpv6, + [A1, A2, A3, A4, A5, A6, A7, A8, P1, P2]}, _MsgData}) -> % v3 + Addr = {A1, A2, A3, A4, A5, A6, A7, A8}, + Port = P1 bsl 8 + P2, {Addr, Port}. @@ -1053,13 +1129,14 @@ mk_addr_communities(Recvs) -> [{Addr, Comm} | T] = lists:keysort(2, Recvs), mic(T, Comm, [Addr], []). -mic([{Addr, Comm} | T], CurComm, AddrList, Res) when Comm == CurComm -> +mic([{Addr, Comm} | T], CurComm, AddrList, Res) when Comm =:= CurComm -> mic(T, CurComm, [Addr | AddrList], Res); mic([{Addr, Comm} | T], CurComm, AddrList, Res) -> mic(T, Comm, [Addr], [{CurComm, AddrList} | Res]); mic([], CurComm, AddrList, Res) -> [{CurComm, AddrList} | Res]. + %%----------------------------------------------------------------- %% Convert the SecurityLevel into a flag value used by snmpa_mpd %%----------------------------------------------------------------- diff --git a/lib/snmp/src/agent/snmpa_usm.erl b/lib/snmp/src/agent/snmpa_usm.erl index f35d1f1916..6f54307f9f 100644 --- a/lib/snmp/src/agent/snmpa_usm.erl +++ b/lib/snmp/src/agent/snmpa_usm.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -330,7 +330,6 @@ non_authoritative(SecName, end end. - is_auth(?usmNoAuthProtocol, _, _, _, SecName, _, _, _, _) -> % 3.2.5 error(usmStatsUnsupportedSecLevels, ?usmStatsUnsupportedSecLevels_instance, SecName); % OTP-5464 @@ -613,8 +612,7 @@ authenticate_outgoing(Message, UsmSecParams, end, ?vtrace("authenticate_outgoing -> encode message only",[]), snmp_pdus:enc_message_only(Message2). - - + %%----------------------------------------------------------------- %% Auth and priv algorithms @@ -753,14 +751,19 @@ set_engine_latest_time(SnmpEngineID, EngineTime) -> %%----------------------------------------------------------------- %% Utility functions %%----------------------------------------------------------------- +-spec error(term()) -> no_return(). error(Reason) -> throw({error, Reason}). +-spec error(term(), term()) -> no_return(). error(Reason, ErrorInfo) -> throw({error, Reason, ErrorInfo}). +-spec error(term(), term(), term()) -> no_return(). error(Variable, Oid, SecName) -> error(Variable, Oid, SecName, []). + +-spec error(term(), term(), term(), [term()]) -> no_return(). error(Variable, Oid, SecName, Opts) -> Val = inc(Variable), ErrorInfo = {#varbind{oid = Oid, @@ -772,7 +775,6 @@ error(Variable, Oid, SecName, Opts) -> inc(Name) -> ets:update_counter(snmp_agent_table, Name, 1). - get_counter(Name) -> case (catch ets:lookup(snmp_agent_table, Name)) of [{_, Val}] -> @@ -780,8 +782,3 @@ get_counter(Name) -> _ -> 0 end. - - - - - diff --git a/lib/snmp/src/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src index de0e5d6e14..5deb40be0f 100644 --- a/lib/snmp/src/app/snmp.appup.src +++ b/lib/snmp/src/app/snmp.appup.src @@ -22,10 +22,56 @@ %% ----- U p g r a d e ------------------------------------------------------- [ + {"4.19", + [ + {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]}, + {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, + {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + {update, snmpa_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, + [snmpa_acm, snmpa_mpd, snmpa_trap]} + ] + }, {"4.18", [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm_usm, soft_purge, soft_purge, []}, {load_module, snmp_misc, soft_purge, soft_purge, []}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmp_config, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmpa_conf, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, + [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, + {load_module, snmpa_acm, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd, snmp_target_mib]}, {load_module, snmpa, soft_purge, soft_purge, [snmp_community_mib, snmp_framework_mib, @@ -33,6 +79,8 @@ 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, @@ -45,7 +93,15 @@ [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, []} + {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]} ] } ], @@ -53,10 +109,58 @@ %% ------D o w n g r a d e --------------------------------------------------- [ + {"4.19", + [ + {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]}, + + {update, snmpm_net_if, soft, soft_purge, soft_purge, []}, + {update, snmpm_server, soft, soft_purge, soft_purge, [snmpm_net_if]}, + + {update, snmpa_net_if, soft, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd]}, + {update, snmpa_agent, soft, soft_purge, soft_purge, + [snmpa_acm, snmpa_mpd, snmpa_trap]} + ] + }, {"4.18", [ + {load_module, snmpa, soft_purge, soft_purge, []}, + {load_module, snmpm, soft_purge, soft_purge, [snmpm_server]}, + {load_module, snmpa_usm, soft_purge, soft_purge, []}, + {load_module, snmpm_usm, soft_purge, soft_purge, []}, {load_module, snmp_misc, soft_purge, soft_purge, []}, + {load_module, snmp_log, soft_purge, soft_purge, []}, + {load_module, snmp_pdus, soft_purge, soft_purge, []}, + {load_module, snmp_conf, soft_purge, soft_purge, []}, + {load_module, snmpa_conf, soft_purge, soft_purge, [snmp_conf]}, + {load_module, snmp_config, soft_purge, soft_purge, []}, + {load_module, snmpa_mpd, soft_purge, soft_purge, [snmp_conf]}, {load_module, snmpa_vacm, soft_purge, soft_purge, []}, + {load_module, snmpa_trap, soft_purge, soft_purge, + [snmpa_mpd, snmp_notification_mib, snmp_target_mib, snmpa_net_if]}, + {load_module, snmpa_acm, soft_purge, soft_purge, + [snmp_conf, snmpa_mpd, snmp_target_mib]}, {load_module, snmpa, soft_purge, soft_purge, [snmp_community_mib, snmp_framework_mib, @@ -64,6 +168,8 @@ 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, @@ -76,7 +182,15 @@ [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, []} + {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]} ] } ] diff --git a/lib/snmp/src/manager/snmpm.erl b/lib/snmp/src/manager/snmpm.erl index 5b6321b4c3..49f7d66b9a 100644 --- a/lib/snmp/src/manager/snmpm.erl +++ b/lib/snmp/src/manager/snmpm.erl @@ -57,15 +57,16 @@ usm_user_info/3, update_usm_user_info/4, %% - %% Basic SNMP API - sync_get/3, sync_get/4, sync_get/5, sync_get/6, - async_get/3, async_get/4, async_get/5, async_get/6, - sync_get_next/3, sync_get_next/4, sync_get_next/5, sync_get_next/6, - async_get_next/3, async_get_next/4, async_get_next/5, async_get_next/6, - sync_set/3, sync_set/4, sync_set/5, sync_set/6, - async_set/3, async_set/4, async_set/5, async_set/6, - sync_get_bulk/5, sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, - async_get_bulk/5, async_get_bulk/6, async_get_bulk/7, async_get_bulk/8, + %% Basic SNMP API (version "3"). + sync_get2/3, sync_get2/4, + async_get2/3, async_get2/4, + sync_get_next2/3, sync_get_next2/4, + async_get_next2/3, async_get_next2/4, + sync_set2/3, sync_set2/4, + async_set2/3, async_set2/4, + sync_get_bulk2/5, sync_get_bulk2/6, + async_get_bulk2/5, async_get_bulk2/6, + cancel_async_request/2, %% @@ -91,7 +92,61 @@ -export([format_reason/1, format_reason/2]). -%% Backward compatibillity exports +%% Backward compatibillity exports (API version "2") +-export([ + sync_get/3, sync_get/4, sync_get/5, sync_get/6, + async_get/3, async_get/4, async_get/5, async_get/6, + sync_get_next/3, sync_get_next/4, sync_get_next/5, sync_get_next/6, + async_get_next/3, async_get_next/4, async_get_next/5, async_get_next/6, + sync_set/3, sync_set/4, sync_set/5, sync_set/6, + async_set/3, async_set/4, async_set/5, async_set/6, + sync_get_bulk/5, sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, + async_get_bulk/5, async_get_bulk/6, async_get_bulk/7, async_get_bulk/8 + ]). + +%% Backward compatibillity exports (API version "1") +-deprecated({agent_info, 3}). +-deprecated({update_agent_info, 5}). +-deprecated({g, 3}). +-deprecated({g, 4}). +-deprecated({g, 5}). +-deprecated({g, 6}). +-deprecated({g, 7}). +-deprecated({ag, 3}). +-deprecated({ag, 4}). +-deprecated({ag, 5}). +-deprecated({ag, 6}). +-deprecated({ag, 7}). +-deprecated({gn, 3}). +-deprecated({gn, 4}). +-deprecated({gn, 5}). +-deprecated({gn, 6}). +-deprecated({gn, 7}). +-deprecated({agn, 3}). +-deprecated({agn, 4}). +-deprecated({agn, 5}). +-deprecated({agn, 6}). +-deprecated({agn, 7}). +-deprecated({gb, 5}). +-deprecated({gb, 6}). +-deprecated({gb, 7}). +-deprecated({gb, 8}). +-deprecated({gb, 9}). +-deprecated({agb, 5}). +-deprecated({agb, 6}). +-deprecated({agb, 7}). +-deprecated({agb, 8}). +-deprecated({agb, 9}). +-deprecated({s, 3}). +-deprecated({s, 4}). +-deprecated({s, 5}). +-deprecated({s, 6}). +-deprecated({s, 7}). +-deprecated({as, 3}). +-deprecated({as, 4}). +-deprecated({as, 5}). +-deprecated({as, 6}). +-deprecated({as, 7}). -export([ agent_info/3, update_agent_info/5, g/3, g/4, g/5, g/6, g/7, @@ -108,12 +163,12 @@ -export([start_link/3, snmpm_start_verify/2, snmpm_start_verify/3]). --include("snmp_debug.hrl"). +-include_lib("snmp/src/misc/snmp_debug.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). -include("snmpm_atl.hrl"). --include("snmp_types.hrl"). +-include("snmpm_internal.hrl"). -define(DEFAULT_AGENT_PORT, 161). --define(DEFAULT_CONTEXT, ""). %% This function is called when the snmp application @@ -393,24 +448,12 @@ agent_info(Addr, Port, Item) -> end. update_agent_info(UserId, TargetName, Item, Val) -> -%% p("update_agent_info -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Item: ~p" -%% "~n Val: ~p", [UserId, TargetName, Item, Val]), snmpm_config:update_agent_info(UserId, TargetName, Item, Val). %% Backward compatibillity functions update_agent_info(UserId, Addr, Port, Item, Val) -> -%% p("update_agent_info -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n Item: ~p" -%% "~n Val: ~p", [UserId, Addr, Port, Item, Val]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("update_agent_info -> TargetName: ~p", [TargetName]), update_agent_info(UserId, TargetName, Item, Val); Error -> Error @@ -472,94 +515,54 @@ which_usm_users(EngineID) when is_list(EngineID) -> %% --- synchroneous get-request --- %% +sync_get2(UserId, TargetName, Oids) -> + sync_get2(UserId, TargetName, Oids, []). + +sync_get2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:sync_get2(UserId, TargetName, Oids, SendOpts). + +%% <BACKWARD-COMPAT> sync_get(UserId, TargetName, Oids) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Oids: ~p", [UserId, TargetName, Oids]), - sync_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). - -sync_get(UserId, TargetName, Context, Oids) when is_list(Oids) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p", [UserId, TargetName, Context, Oids]), - snmpm_server:sync_get(UserId, TargetName, Context, Oids); - -sync_get(UserId, TargetName, Oids, Timeout) when is_integer(Timeout) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", [UserId, TargetName, Oids, Timeout]), - sync_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout). + sync_get2(UserId, TargetName, Oids). + +sync_get(UserId, TargetName, Oids, Timeout) + when is_list(Oids) andalso is_integer(Timeout) -> + SendOpts = [{timeout, Timeout}], + sync_get2(UserId, TargetName, Oids, SendOpts); +sync_get(UserId, TargetName, Context, [OH|_] = Oids) + when is_list(Context) andalso is_list(OH) -> + SendOpts = [{context, Context}], + sync_get2(UserId, TargetName, Oids, SendOpts). sync_get(UserId, TargetName, Context, Oids, Timeout) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", [UserId, TargetName, Context, Oids, Timeout]), - snmpm_server:sync_get(UserId, TargetName, Context, Oids, Timeout). + SendOpts = [{context, Context}, {timeout, Timeout}], + sync_get2(UserId, TargetName, Oids, SendOpts). sync_get(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) -> -%% p("sync_get -> entry with" -%% "~n UserId: ~p" -%% "~n TargetName: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p" -%% "~n ExtraInfo: ~p", -%% [UserId, TargetName, Context, Oids, Timeout, ExtraInfo]), - snmpm_server:sync_get(UserId, TargetName, Context, Oids, Timeout, - ExtraInfo). + SendOpts = [{context, Context}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> g(UserId, Addr, Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Oids: ~p", [UserId, Addr, Oids]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). g(UserId, Addr, CtxName, Oids) when is_list(CtxName) andalso is_list(Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p", [UserId, Addr, CtxName, Oids]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids); g(UserId, Addr, Port, Oids) when is_integer(Port) andalso is_list(Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n Oids: ~p", [UserId, Addr, Port, Oids]), g(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids); g(UserId, Addr, Oids, Timeout) when is_list(Oids) andalso is_integer(Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", [UserId, Addr, Oids, Timeout]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids, Timeout). g(UserId, Addr, Port, CtxName, Oids) when is_integer(Port) andalso is_list(CtxName) andalso is_list(Oids) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n Context: ~p" -%% "~n Oids: ~p", [UserId, Addr, Port, CtxName, Oids]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("g -> TargetName: ~p", [TargetName]), sync_get(UserId, TargetName, CtxName, Oids); Error -> Error @@ -567,59 +570,28 @@ g(UserId, Addr, Port, CtxName, Oids) g(UserId, Addr, Port, Oids, Timeout) when is_integer(Port) andalso is_list(Oids) andalso is_integer(Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", -%% [UserId, Addr, Oids, Timeout]), g(UserId, Addr, Port, ?DEFAULT_CONTEXT, Oids, Timeout); g(UserId, Addr, CtxName, Oids, Timeout) when is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", -%% [UserId, Addr, CtxName, Oids, Timeout]), g(UserId, Addr, ?DEFAULT_AGENT_PORT, CtxName, Oids, Timeout). g(UserId, Addr, Port, CtxName, Oids, Timeout) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p", -%% [UserId, Addr, Port, CtxName, Oids, Timeout]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("g -> TargetName: ~p", [TargetName]), sync_get(UserId, TargetName, CtxName, Oids, Timeout); Error -> Error end. g(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) -> -%% p("g -> entry with" -%% "~n UserId: ~p" -%% "~n Addr: ~p" -%% "~n Port: ~p" -%% "~n CtxName: ~p" -%% "~n Oids: ~p" -%% "~n Timeout: ~p" -%% "~n ExtraInfo: ~p", -%% [UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo]), case target_name(Addr, Port) of {ok, TargetName} -> -%% p("g -> TargetName: ~p", [TargetName]), sync_get(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo); Error -> Error end. +%% </DEPRECATED> @@ -629,23 +601,36 @@ g(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) -> %% through a call to handle_pdu/5 %% -async_get(UserId, TargetName, Oids) -> - async_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). +async_get2(UserId, TargetName, Oids) -> + async_get2(UserId, TargetName, Oids, []). + +async_get2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:async_get2(UserId, TargetName, Oids, SendOpts). -async_get(UserId, TargetName, Context, Oids) when is_list(Oids) -> - snmpm_server:async_get(UserId, TargetName, Context, Oids); +%% <BACKWARD-COMPAT> +async_get(UserId, TargetName, Oids) -> + async_get2(UserId, TargetName, Oids). async_get(UserId, TargetName, Oids, Expire) when is_integer(Expire) -> - async_get(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Expire). + SendOpts = [{timeout, Expire}], + async_get2(UserId, TargetName, Oids, SendOpts); +async_get(UserId, TargetName, Context, Oids) + when is_list(Context) andalso is_list(Oids) -> + SendOpts = [{context, Context}], + async_get2(UserId, TargetName, Oids, SendOpts). async_get(UserId, TargetName, Context, Oids, Expire) -> - snmpm_server:async_get(UserId, TargetName, Context, Oids, Expire). + SendOpts = [{timeout, Expire}, {context, Context}], + async_get2(UserId, TargetName, Oids, SendOpts). async_get(UserId, TargetName, Context, Oids, Expire, ExtraInfo) -> - snmpm_server:async_get(UserId, TargetName, Context, Oids, Expire, - ExtraInfo). + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_get2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> ag(UserId, Addr, Oids) -> ag(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). @@ -690,31 +675,44 @@ ag(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- synchroneous get_next-request --- %% -sync_get_next(UserId, TargetName, Oids) -> - sync_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). +sync_get_next2(UserId, TargetName, Oids) -> + sync_get_next2(UserId, TargetName, Oids, []). -sync_get_next(UserId, TargetName, Context, Oids) - when is_list(Context) andalso is_list(Oids) -> - snmpm_server:sync_get_next(UserId, TargetName, Context, Oids); +sync_get_next2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:sync_get_next2(UserId, TargetName, Oids, SendOpts). + +%% <BACKWARD-COMPAT> +sync_get_next(UserId, TargetName, Oids) -> + sync_get_next2(UserId, TargetName, Oids). sync_get_next(UserId, TargetName, Oids, Timeout) when is_list(Oids) andalso is_integer(Timeout) -> - sync_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout). + SendOpts = [{timeout, Timeout}], + sync_get_next2(UserId, TargetName, Oids, SendOpts); +sync_get_next(UserId, TargetName, Context, Oids) + when is_list(Context) andalso is_list(Oids) -> + SendOpts = [{context, Context}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). sync_get_next(UserId, TargetName, Context, Oids, Timeout) -> - snmpm_server:sync_get_next(UserId, TargetName, Context, Oids, Timeout). + SendOpts = [{timeout, Timeout}, {context, Context}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). sync_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) -> - snmpm_server:sync_get_next(UserId, TargetName, Context, Oids, Timeout, - ExtraInfo). + SendOpts = [{timeout, Timeout}, {context, Context}, {extra, ExtraInfo}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> gn(UserId, Addr, Oids) -> gn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). @@ -759,30 +757,44 @@ gn(UserId, Addr, Port, CtxName, Oids, Timeout, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- asynchroneous get_next-request --- %% +async_get_next2(UserId, TargetName, Oids) -> + async_get_next2(UserId, TargetName, Oids, []). + +async_get_next2(UserId, TargetName, Oids, SendOpts) + when is_list(Oids) andalso is_list(SendOpts) -> + snmpm_server:async_get_next2(UserId, TargetName, Oids, SendOpts). + +%% <BACKWARD-COMPAT> async_get_next(UserId, TargetName, Oids) -> - async_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids). + async_get_next2(UserId, TargetName, Oids). +async_get_next(UserId, TargetName, Oids, Expire) + when is_list(Oids) andalso is_integer(Expire) -> + SendOpts = [{timeout, Expire}], + async_get_next2(UserId, TargetName, Oids, SendOpts); async_get_next(UserId, TargetName, Context, Oids) when is_list(Context) andalso is_list(Oids) -> - snmpm_server:async_get_next(UserId, TargetName, Context, Oids); + SendOpts = [{context, Context}], + async_get_next2(UserId, TargetName, Oids, SendOpts). -async_get_next(UserId, TargetName, Oids, Timeout) - when is_list(Oids) andalso is_integer(Timeout) -> - async_get_next(UserId, TargetName, ?DEFAULT_CONTEXT, Oids, Timeout). +async_get_next(UserId, TargetName, Context, Oids, Expire) -> + SendOpts = [{timeout, Expire}, {context, Context}], + async_get_next2(UserId, TargetName, Oids, SendOpts). -async_get_next(UserId, TargetName, Context, Oids, Timeout) -> - snmpm_server:async_get_next(UserId, TargetName, Context, Oids, Timeout). +async_get_next(UserId, TargetName, Context, Oids, Expire, ExtraInfo) -> + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_get_next2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> -async_get_next(UserId, TargetName, Context, Oids, Timeout, ExtraInfo) -> - snmpm_server:async_get_next(UserId, TargetName, Context, Oids, Timeout, - ExtraInfo). +%% <DEPRECATED> agn(UserId, Addr, Oids) -> agn(UserId, Addr, ?DEFAULT_AGENT_PORT, Oids). @@ -828,31 +840,44 @@ agn(UserId, Addr, Port, CtxName, Oids, Expire, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- synchroneous set-request --- %% -sync_set(UserId, TargetName, VarsAndVals) -> - sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals). +sync_set2(UserId, TargetName, VarsAndVals) -> + sync_set2(UserId, TargetName, VarsAndVals, []). -sync_set(UserId, TargetName, Context, VarsAndVals) - when is_list(Context) andalso is_list(VarsAndVals) -> - snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals); +sync_set2(UserId, TargetName, VarsAndVals, SendOpts) + when is_list(VarsAndVals) andalso is_list(SendOpts) -> + snmpm_server:sync_set2(UserId, TargetName, VarsAndVals, SendOpts). + +%% <BACKWARD-COMPAT> +sync_set(UserId, TargetName, VarsAndVals) -> + sync_set2(UserId, TargetName, VarsAndVals). sync_set(UserId, TargetName, VarsAndVals, Timeout) when is_list(VarsAndVals) andalso is_integer(Timeout) -> - sync_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Timeout). + SendOpts = [{timeout, Timeout}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts); +sync_set(UserId, TargetName, Context, VarsAndVals) + when is_list(Context) andalso is_list(VarsAndVals) -> + SendOpts = [{context, Context}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). sync_set(UserId, TargetName, Context, VarsAndVals, Timeout) -> - snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals, Timeout). + SendOpts = [{timeout, Timeout}, {context, Context}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). sync_set(UserId, TargetName, Context, VarsAndVals, Timeout, ExtraInfo) -> - snmpm_server:sync_set(UserId, TargetName, Context, VarsAndVals, Timeout, - ExtraInfo). + SendOpts = [{timeout, Timeout}, {context, Context}, {extra, ExtraInfo}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> s(UserId, Addr, VarsAndVals) -> s(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals). @@ -906,31 +931,44 @@ s(UserId, Addr, Port, CtxName, VarsAndVals, Timeout, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- asynchroneous set-request --- %% -async_set(UserId, TargetName, VarsAndVals) -> - async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals). +async_set2(UserId, TargetName, VarsAndVals) -> + async_set2(UserId, TargetName, VarsAndVals, []). -async_set(UserId, TargetName, Context, VarsAndVals) - when is_list(Context) andalso is_list(VarsAndVals) -> - snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals); +async_set2(UserId, TargetName, VarsAndVals, SendOpts) + when is_list(VarsAndVals) andalso is_list(SendOpts) -> + snmpm_server:async_set2(UserId, TargetName, VarsAndVals, SendOpts). + +%% <BACKWARD-COMPAT> +async_set(UserId, TargetName, VarsAndVals) -> + async_set2(UserId, TargetName, VarsAndVals). async_set(UserId, TargetName, VarsAndVals, Expire) when is_list(VarsAndVals) andalso is_integer(Expire) -> - async_set(UserId, TargetName, ?DEFAULT_CONTEXT, VarsAndVals, Expire). + SendOpts = [{timeout, Expire}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts); +async_set(UserId, TargetName, Context, VarsAndVals) + when is_list(Context) andalso is_list(VarsAndVals) -> + SendOpts = [{context, Context}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). async_set(UserId, TargetName, Context, VarsAndVals, Expire) -> - snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals, Expire). + SendOpts = [{timeout, Expire}, {context, Context}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). async_set(UserId, TargetName, Context, VarsAndVals, Expire, ExtraInfo) -> - snmpm_server:async_set(UserId, TargetName, Context, VarsAndVals, Expire, - ExtraInfo). + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> as(UserId, Addr, VarsAndVals) -> as(UserId, Addr, ?DEFAULT_AGENT_PORT, VarsAndVals). @@ -984,44 +1022,77 @@ as(UserId, Addr, Port, CtxName, VarsAndVals, Expire, ExtraInfo) -> Error -> Error end. - - +%% </DEPRECATED> %% --- synchroneous get-bulk --- %% -sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> - sync_get_bulk(UserId, TargetName, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids). +sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). -sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) +sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) when is_integer(NonRep) andalso is_integer(MaxRep) andalso - is_list(Context) andalso - is_list(Oids) -> - snmpm_server:sync_get_bulk(UserId, TargetName, - NonRep, MaxRep, - Context, Oids); + is_list(Oids) andalso + is_list(SendOpts) -> + %% p("sync_get_bulk -> entry with" + %% "~n UserId: ~p" + %% "~n TargetName: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n SendOpts: ~p", + %% [UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), + snmpm_server:sync_get_bulk2(UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts). + +%% <BACKWARD-COMPAT> +sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Timeout) when is_integer(NonRep) andalso is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Timeout) -> - sync_get_bulk(UserId, TargetName, NonRep, MaxRep, - ?DEFAULT_CONTEXT, Oids, Timeout). + SendOpts = [{timeout, Timeout}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts); +sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) + when is_integer(NonRep) andalso + is_integer(MaxRep) andalso + is_list(Context) andalso + is_list(Oids) -> + %% p("sync_get_bulk -> entry with" + %% "~n UserId: ~p" + %% "~n TargetName: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Context: ~p" + %% "~n Oids: ~p", [UserId, TargetName, NonRep, MaxRep, Context, Oids]), + SendOpts = [{context, Context}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout) -> - snmpm_server:sync_get_bulk(UserId, TargetName, NonRep, MaxRep, - Context, Oids, Timeout). + SendOpts = [{timeout, Timeout}, {context, Context}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Timeout, ExtraInfo) -> - snmpm_server:sync_get_bulk(UserId, TargetName, NonRep, MaxRep, - Context, Oids, Timeout, ExtraInfo). + SendOpts = [{timeout, Timeout}, {context, Context}, {extra, ExtraInfo}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> gb(UserId, Addr, NonRep, MaxRep, Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, NonRep, MaxRep, Oids]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids). gb(UserId, Addr, Port, NonRep, MaxRep, Oids) @@ -1029,6 +1100,14 @@ gb(UserId, Addr, Port, NonRep, MaxRep, Oids) is_integer(NonRep) andalso is_integer(MaxRep) andalso is_list(Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, Oids]), gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids); gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids) @@ -1036,6 +1115,14 @@ gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids) is_integer(MaxRep) andalso is_list(CtxName) andalso is_list(Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, NonRep, MaxRep, CtxName, Oids]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids); gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout) @@ -1043,6 +1130,14 @@ gb(UserId, Addr, NonRep, MaxRep, Oids, Timeout) is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, NonRep, MaxRep, Oids, Timeout]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids, Timeout). gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids) @@ -1051,8 +1146,18 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids) is_integer(MaxRep) andalso is_list(CtxName) andalso is_list(Oids) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids]), case target_name(Addr, Port) of {ok, TargetName} -> + %% p("gb -> TargetName: ~p", [TargetName]), sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids); Error -> Error @@ -1064,6 +1169,15 @@ gb(UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout) is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, Oids, Timeout]), gb(UserId, Addr, Port, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Timeout); gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout) @@ -1072,10 +1186,29 @@ gb(UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout) is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, NonRep, MaxRep, CtxName, Oids, Timeout]), gb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, CtxName, Oids, Timeout). gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout]), case target_name(Addr, Port) of {ok, TargetName} -> sync_get_bulk(UserId, TargetName, @@ -1085,6 +1218,17 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout) -> end. gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) -> + %% p("gb -> entry with" + %% "~n UserId: ~p" + %% "~n Addr: ~p" + %% "~n Port: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n CtxName: ~p" + %% "~n Oids: ~p" + %% "~n Timeout: ~p" + %% "~n ExtraInfo: ~p", + %% [UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo]), case target_name(Addr, Port) of {ok, TargetName} -> sync_get_bulk(UserId, TargetName, @@ -1092,42 +1236,55 @@ gb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> %% --- asynchroneous get-bulk --- %% -async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> - async_get_bulk(UserId, TargetName, NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids). +async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). -async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) +async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) when is_integer(NonRep) andalso is_integer(MaxRep) andalso - is_list(Context) andalso - is_list(Oids) -> - snmpm_server:async_get_bulk(UserId, TargetName, - NonRep, MaxRep, Context, Oids); + is_list(Oids) andalso + is_list(SendOpts) -> + snmpm_server:async_get_bulk2(UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts). + +%% <BACKWARD-COMPAT> +async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids) -> + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids). async_get_bulk(UserId, TargetName, NonRep, MaxRep, Oids, Expire) when is_integer(NonRep) andalso is_integer(MaxRep) andalso is_list(Oids) andalso is_integer(Expire) -> - async_get_bulk(UserId, TargetName, - NonRep, MaxRep, ?DEFAULT_CONTEXT, Oids, Expire). + SendOpts = [{timeout, Expire}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts); +async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids) + when is_integer(NonRep) andalso + is_integer(MaxRep) andalso + is_list(Context) andalso + is_list(Oids) -> + SendOpts = [{context, Context}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Expire) -> - snmpm_server:async_get_bulk(UserId, TargetName, - NonRep, MaxRep, Context, Oids, Expire). + SendOpts = [{timeout, Expire}, {context, Context}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). async_get_bulk(UserId, TargetName, NonRep, MaxRep, Context, Oids, Expire, ExtraInfo) -> - snmpm_server:async_get_bulk(UserId, TargetName, - NonRep, MaxRep, - Context, Oids, Expire, ExtraInfo). + SendOpts = [{timeout, Expire}, {context, Context}, {extra, ExtraInfo}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). +%% </BACKWARD-COMPAT> +%% <DEPRECATED> agb(UserId, Addr, NonRep, MaxRep, Oids) -> agb(UserId, Addr, ?DEFAULT_AGENT_PORT, NonRep, MaxRep, Oids). @@ -1200,6 +1357,7 @@ agb(UserId, Addr, Port, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo) -> Error -> Error end. +%% </DEPRECATED> cancel_async_request(UserId, ReqId) -> diff --git a/lib/snmp/src/manager/snmpm_internal.hrl b/lib/snmp/src/manager/snmpm_internal.hrl index 5d9b32e3f6..53ad41c6b0 100644 --- a/lib/snmp/src/manager/snmpm_internal.hrl +++ b/lib/snmp/src/manager/snmpm_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2006-2009. All Rights Reserved. +%% Copyright Ericsson AB 2006-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,6 +20,11 @@ -ifndef(snmpm_internal). -define(snmpm_internal, true). +-define(DEFAULT_CONTEXT, ""). +-define(SNMPM_EXTRA_INFO_TAG, snmpm_extra_info_tag). +-define(DEFAULT_EXTRA_INFO, {?SNMPM_EXTRA_INFO_TAG}). + + -include_lib("snmp/src/app/snmp_internal.hrl"). -define(snmpm_info(F, A), ?snmp_info("manager", F, A)). diff --git a/lib/snmp/src/manager/snmpm_net_if.erl b/lib/snmp/src/manager/snmpm_net_if.erl index 07156dacd9..3d248fff57 100644 --- a/lib/snmp/src/manager/snmpm_net_if.erl +++ b/lib/snmp/src/manager/snmpm_net_if.erl @@ -99,7 +99,7 @@ stop(Pid) -> call(Pid, stop). send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port) -> - send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, undefined). + send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ?DEFAULT_EXTRA_INFO). send_pdu(Pid, Pdu, Vsn, MsgData, Addr, Port, ExtraInfo) when is_record(Pdu, pdu) -> @@ -380,13 +380,14 @@ 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, Addr, Port, ExtraInfo}, State) -> ?vlog("received send_pdu message with" "~n Pdu: ~p" "~n Vsn: ~p" "~n MsgData: ~p" "~n Addr: ~p" "~n Port: ~p", [Pdu, Vsn, MsgData, Addr, Port]), + maybe_process_extra_info(ExtraInfo), maybe_handle_send_pdu(Pdu, Vsn, MsgData, Addr, Port, State), {noreply, State}; @@ -999,6 +1000,19 @@ pdu_type_of(TrapPdu) when is_record(TrapPdu, trappdu) -> %% ------------------------------------------------------------------- +%% At this point this function is used during testing +maybe_process_extra_info(?DEFAULT_EXTRA_INFO) -> + ok; +maybe_process_extra_info({?SNMPM_EXTRA_INFO_TAG, Fun}) + when is_function(Fun, 0) -> + (catch Fun()), + ok; +maybe_process_extra_info(_ExtraInfo) -> + ok. + + +%% ------------------------------------------------------------------- + t() -> {A,B,C} = erlang:now(), A*1000000000+B*1000+(C div 1000). diff --git a/lib/snmp/src/manager/snmpm_server.erl b/lib/snmp/src/manager/snmpm_server.erl index d64b5b1d53..b8d7cf6375 100644 --- a/lib/snmp/src/manager/snmpm_server.erl +++ b/lib/snmp/src/manager/snmpm_server.erl @@ -32,14 +32,14 @@ register_user/4, register_user_monitor/4, unregister_user/1, - sync_get/4, sync_get/5, sync_get/6, - async_get/4, async_get/5, async_get/6, - sync_get_next/4, sync_get_next/5, sync_get_next/6, - async_get_next/4, async_get_next/5, async_get_next/6, - sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, - async_get_bulk/6, async_get_bulk/7, async_get_bulk/8, - sync_set/4, sync_set/5, sync_set/6, - async_set/4, async_set/5, async_set/6, + sync_get2/4, + async_get2/4, + sync_get_next2/4, + async_get_next2/4, + sync_get_bulk2/6, + async_get_bulk2/6, + sync_set2/4, + async_set2/4, cancel_async_request/2, %% discovery/2, discovery/3, discovery/4, discovery/5, discovery/6, @@ -55,6 +55,20 @@ ]). +%% <BACKWARD-COMPAT> +-export([sync_get/4, sync_get/5, sync_get/6, + async_get/4, async_get/5, async_get/6, + sync_get_next/4, sync_get_next/5, sync_get_next/6, + async_get_next/4, async_get_next/5, async_get_next/6, + sync_get_bulk/6, sync_get_bulk/7, sync_get_bulk/8, + async_get_bulk/6, async_get_bulk/7, async_get_bulk/8, + sync_set/4, sync_set/5, sync_set/6, + async_set/4, async_set/5, async_set/6 + ]). +%% </BACKWARD-COMPAT> + + + %% Internal exports -export([init/1, handle_call/3, handle_cast/2, handle_info/2, code_change/3, terminate/2]). @@ -75,13 +89,39 @@ -define(SERVER, ?MODULE). --define(SYNC_GET_TIMEOUT, 5000). --define(SYNC_SET_TIMEOUT, 5000). --define(DEFAULT_ASYNC_EXPIRE, 5000). --define(EXTRA_INFO, undefined). - --define(SNMP_AGENT_PORT, 161). - +-define(DEFAULT_SYNC_TIMEOUT, timer:seconds(5)). +-define(DEFAULT_SYNC_GET_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). +-define(DEFAULT_SYNC_GET_NEXT_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). +-define(DEFAULT_SYNC_GET_BULK_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). +-define(DEFAULT_SYNC_SET_TIMEOUT, ?DEFAULT_SYNC_TIMEOUT). + +-define(DEFAULT_ASYNC_TIMEOUT, timer:seconds(5)). +-define(DEFAULT_ASYNC_GET_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). +-define(DEFAULT_ASYNC_GET_NEXT_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). +-define(DEFAULT_ASYNC_GET_BULK_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). +-define(DEFAULT_ASYNC_SET_TIMEOUT, ?DEFAULT_ASYNC_TIMEOUT). + +-define(SNMP_AGENT_PORT, 161). + +-define(SYNC_GET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_GET_TIMEOUT, SendOpts)). +-define(SYNC_GET_NEXT_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_GET_NEXT_TIMEOUT, SendOpts)). +-define(SYNC_GET_BULK_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_GET_BULK_TIMEOUT, SendOpts)). +-define(SYNC_SET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_SYNC_SET_TIMEOUT, SendOpts)). + +-define(ASYNC_GET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_GET_TIMEOUT, SendOpts)). +-define(ASYNC_GET_NEXT_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_GET_NEXT_TIMEOUT, SendOpts)). +-define(ASYNC_GET_BULK_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_GET_BULK_TIMEOUT, SendOpts)). +-define(ASYNC_SET_TIMEOUT(SendOpts), + get_opt(timeout, ?DEFAULT_ASYNC_SET_TIMEOUT, SendOpts)). + +-define(GET_EXTRA(SendOpts), get_opt(extra, ?DEFAULT_EXTRA_INFO, SendOpts)). -ifdef(snmp_debug). -define(GS_START_LINK(Args), @@ -192,82 +232,140 @@ unregister_user(UserId) -> %% -- [sync] get -- +%% The reason why we have a sync_get2 is to simplify backward +%% compatibillity. + +%% sync_get2(UserId, TargetName, Oids) -> +%% sync_get2(UserId, TargetName, Oids, []). +sync_get2(UserId, TargetName, Oids, Opts) -> + call({sync_get, self(), UserId, TargetName, Oids, Opts}). + + +%% <BACKWARD-COMPAT> sync_get(UserId, TargetName, CtxName, Oids) -> sync_get(UserId, TargetName, CtxName, Oids, - ?SYNC_GET_TIMEOUT). + ?DEFAULT_SYNC_GET_TIMEOUT). sync_get(UserId, TargetName, CtxName, Oids, Timeout) -> - sync_get(UserId, TargetName, CtxName, Oids, Timeout, ?EXTRA_INFO). + sync_get(UserId, TargetName, CtxName, Oids, Timeout, ?DEFAULT_EXTRA_INFO). sync_get(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo) when is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> - call({sync_get, self(), UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}). + Opts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get2(UserId, TargetName, Oids, Opts). +%% </BACKWARD-COMPAT> + + %% -- [async] get -- +%% async_get2(UserId, TargetName, Oids) -> +%% async_get2(UserId, TargetName, Oids, []). +async_get2(UserId, TargetName, Oids, SendOpts) -> + call({async_get, self(), UserId, TargetName, Oids, SendOpts}). + + +%% <BACKWARD-COMPAT> async_get(UserId, TargetName, CtxName, Oids) -> async_get(UserId, TargetName, CtxName, Oids, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_GET_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_get(UserId, TargetName, CtxName, Oids, Expire) -> - async_get(UserId, TargetName, CtxName, Oids, Expire, ?EXTRA_INFO). + async_get(UserId, TargetName, CtxName, Oids, Expire, ?DEFAULT_EXTRA_INFO). async_get(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo) when (is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) andalso (Expire >= 0)) -> - call({async_get, self(), UserId, TargetName, CtxName, Oids, Expire, - ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_get2(UserId, TargetName, Oids, SendOpts). +%% </BACKWARD-COMPAT> + + %% -- [sync] get-next -- +%% sync_get_next2(UserId, TargetName, Oids) -> +%% sync_get_next2(UserId, TargetName, Oids, []). +sync_get_next2(UserId, TargetName, Oids, SendOpts) -> + call({sync_get_next, self(), UserId, TargetName, Oids, SendOpts}). + + +%% <BACKWARD-COMPAT> sync_get_next(UserId, TargetName, CtxName, Oids) -> - sync_get_next(UserId, TargetName, CtxName, Oids, ?SYNC_GET_TIMEOUT, - ?EXTRA_INFO). + sync_get_next(UserId, TargetName, CtxName, Oids, + ?DEFAULT_SYNC_GET_TIMEOUT, ?DEFAULT_EXTRA_INFO). sync_get_next(UserId, TargetName, CtxName, Oids, Timeout) -> - sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ?EXTRA_INFO). + sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, + ?DEFAULT_EXTRA_INFO). sync_get_next(UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo) when is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> - call({sync_get_next, self(), UserId, TargetName, CtxName, Oids, Timeout, - ExtraInfo}). + SendOpts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get_next2(UserId, TargetName, Oids, SendOpts). +%% <BACKWARD-COMPAT> + + %% -- [async] get-next -- +%% async_get_next2(UserId, TargetName, Oids) -> +%% async_get_next2(UserId, TargetName, Oids, []). +async_get_next2(UserId, TargetName, Oids, SendOpts) -> + call({async_get_next, self(), UserId, TargetName, Oids, SendOpts}). + + async_get_next(UserId, TargetName, CtxName, Oids) -> async_get_next(UserId, TargetName, CtxName, Oids, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_GET_NEXT_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_get_next(UserId, TargetName, CtxName, Oids, Expire) -> - async_get_next(UserId, TargetName, CtxName, Oids, Expire, ?EXTRA_INFO). + async_get_next(UserId, TargetName, CtxName, Oids, Expire, + ?DEFAULT_EXTRA_INFO). async_get_next(UserId, TargetName, CtxName, Oids, Expire, ExtraInfo) when (is_list(TargetName) andalso is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) andalso (Expire >= 0)) -> - call({async_get_next, self(), UserId, TargetName, CtxName, Oids, - Expire, ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_get_next2(UserId, TargetName, Oids, SendOpts). + + %% -- [sync] get-bulk -- +%% sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> +%% sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). +sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> + %% p("sync_get_bulk2 -> entry with" + %% "~n UserId: ~p" + %% "~n TargetName: ~p" + %% "~n NonRep: ~p" + %% "~n MaxRep: ~p" + %% "~n Oids: ~p" + %% "~n SendOpts: ~p", + %% [UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), + call({sync_get_bulk, self(), UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts}). + sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids) -> sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - ?SYNC_GET_TIMEOUT, ?EXTRA_INFO). + ?DEFAULT_SYNC_GET_TIMEOUT, ?DEFAULT_EXTRA_INFO). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout) -> sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - Timeout, ?EXTRA_INFO). + Timeout, ?DEFAULT_EXTRA_INFO). sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo) @@ -277,20 +375,28 @@ sync_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout, is_list(CtxName) andalso is_list(Oids) andalso is_integer(Timeout) -> - call({sync_get_bulk, self(), UserId, TargetName, - NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo}). + SendOpts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). + %% -- [async] get-bulk -- +%% async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids) -> +%% async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, []). +async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts) -> + call({async_get_bulk, self(), UserId, TargetName, NonRep, MaxRep, + Oids, SendOpts}). + + async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids) -> async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_GET_BULK_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire) -> async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, - Expire, ?EXTRA_INFO). + Expire, ?DEFAULT_EXTRA_INFO). async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo) @@ -300,45 +406,61 @@ async_get_bulk(UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire, is_list(CtxName) andalso is_list(Oids) andalso is_integer(Expire) -> - call({async_get_bulk, self(), UserId, TargetName, - NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_get_bulk2(UserId, TargetName, NonRep, MaxRep, Oids, SendOpts). + + %% -- [sync] set -- %% VarsAndValues is: {PlainOid, o|s|i, Value} (unknown mibs) | {Oid, Value} +%% sync_set2(UserId, TargetName, VarsAndVals) -> +%% sync_set2(UserId, TargetName, VarsAndVals, []). +sync_set2(UserId, TargetName, VarsAndVals, SendOpts) -> + call({sync_set, self(), UserId, TargetName, VarsAndVals, SendOpts}). + + sync_set(UserId, TargetName, CtxName, VarsAndVals) -> sync_set(UserId, TargetName, CtxName, VarsAndVals, - ?SYNC_SET_TIMEOUT, ?EXTRA_INFO). + ?DEFAULT_SYNC_SET_TIMEOUT, ?DEFAULT_EXTRA_INFO). sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout) -> sync_set(UserId, TargetName, CtxName, VarsAndVals, - Timeout, ?EXTRA_INFO). + Timeout, ?DEFAULT_EXTRA_INFO). sync_set(UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo) when is_list(TargetName) andalso is_list(CtxName) andalso is_list(VarsAndVals) andalso is_integer(Timeout) -> - call({sync_set, self(), UserId, TargetName, - CtxName, VarsAndVals, Timeout, ExtraInfo}). + SendOpts = [{context, CtxName}, {timeout, Timeout}, {extra, ExtraInfo}], + sync_set2(UserId, TargetName, VarsAndVals, SendOpts). + + %% -- [async] set -- +%% async_set2(UserId, TargetName, VarsAndVals) -> +%% async_set2(UserId, TargetName, VarsAndVals, []). +async_set2(UserId, TargetName, VarsAndVals, SendOpts) -> + call({async_set, self(), UserId, TargetName, VarsAndVals, SendOpts}). + + async_set(UserId, TargetName, CtxName, VarsAndVals) -> async_set(UserId, TargetName, CtxName, VarsAndVals, - ?DEFAULT_ASYNC_EXPIRE, ?EXTRA_INFO). + ?DEFAULT_ASYNC_SET_TIMEOUT, ?DEFAULT_EXTRA_INFO). async_set(UserId, TargetName, CtxName, VarsAndVals, Expire) -> async_set(UserId, TargetName, CtxName, VarsAndVals, - Expire, ?EXTRA_INFO). + Expire, ?DEFAULT_EXTRA_INFO). async_set(UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo) when (is_list(TargetName) andalso is_list(CtxName) andalso is_list(VarsAndVals) andalso is_integer(Expire) andalso (Expire >= 0)) -> - call({async_set, self(), UserId, TargetName, - CtxName, VarsAndVals, Expire, ExtraInfo}). + SendOpts = [{context, CtxName}, {expire, Expire}, {extra, ExtraInfo}], + async_set2(UserId, TargetName, VarsAndVals, SendOpts). cancel_async_request(UserId, ReqId) -> @@ -571,9 +693,26 @@ handle_call({unregister_user, UserId}, _From, State) -> %% We will reply to this request later, when the reply comes in from the %% agent, or when the timeout hits (unless we get an error now). -handle_call({sync_get, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, +handle_call({sync_get, Pid, UserId, TargetName, Oids, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_get request for: " + "~n ~p", [UserId, TargetName, Oids]), + case (catch handle_sync_get(Pid, + UserId, TargetName, Oids, SendOpts, + From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade +handle_call({sync_get, + Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_get [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received sync_get request for: " + "~n ~p", [UserId, TargetName, CtxName, Oids]), case (catch handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State)) of @@ -582,10 +721,30 @@ handle_call({sync_get, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInf Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> + + +handle_call({sync_get_next, Pid, UserId, TargetName, Oids, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_get_next request for: " + "~n ~p", [UserId, TargetName, SendOpts]), + case (catch handle_sync_get_next(Pid, + UserId, TargetName, Oids, SendOpts, + From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; -handle_call({sync_get_next, Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_get_next [~p] request", [CtxName]), +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade +handle_call({sync_get_next, + Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo}, + From, State) -> + ?vlog("[~p,~p,~p] received sync_get_next request for" + "~n ~p", [UserId, TargetName, CtxName, Oids]), case (catch handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State)) of @@ -594,13 +753,31 @@ handle_call({sync_get_next, Pid, UserId, TargetName, CtxName, Oids, Timeout, Ext Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> %% Check agent version? This op not in v1 +handle_call({sync_get_bulk, + Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_get_bulk request for: " + "~n ~p", [UserId, TargetName, Oids]), + case (catch handle_sync_get_bulk(Pid, + UserId, TargetName, NonRep, MaxRep, Oids, + SendOpts, From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({sync_get_bulk, Pid, UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_get_bulk [~p] request", [CtxName]), + ?vlog("[~p,~p] received sync_get_bulk request for: ~p" + "~n ~p", [UserId, TargetName, CtxName, Oids]), case (catch handle_sync_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, @@ -610,12 +787,31 @@ handle_call({sync_get_bulk, Pid, UserId, TargetName, Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> + + +handle_call({sync_set, + Pid, UserId, TargetName, VarsAndVals, SendOpts}, + From, State) -> + ?vlog("[~p,~p] received sync_set request for: " + "~n ~p", [UserId, TargetName, VarsAndVals]), + case (catch handle_sync_set(Pid, + UserId, TargetName, VarsAndVals, SendOpts, + From, State)) of + ok -> + {noreply, State}; + Error -> + {reply, Error, State} + end; +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({sync_set, Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo}, From, State) -> - ?vlog("received sync_set [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received sync_set request for: " + "~n ~p", [UserId, TargetName, CtxName, VarsAndVals]), case (catch handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo, From, State)) of @@ -624,45 +820,105 @@ handle_call({sync_set, Pid, UserId, TargetName, Error -> {reply, Error, State} end; +%% </BACKWARD-COMPAT> +handle_call({async_get, Pid, UserId, TargetName, Oids, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_get request for: " + "~n ~p", [UserId, TargetName, Oids]), + Reply = (catch handle_async_get(Pid, + UserId, TargetName, Oids, SendOpts, + State)), + {reply, Reply, State}; + + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_get, Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_get [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_get request for: " + "~n ~p", [UserId, TargetName, CtxName, Oids]), Reply = (catch handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> + + +handle_call({async_get_next, Pid, UserId, TargetName, Oids, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_get_next request for: " + "~n ~p", [UserId, TargetName, Oids]), + Reply = (catch handle_async_get_next(Pid, + UserId, TargetName, Oids, SendOpts, + State)), + {reply, Reply, State}; +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_get_next, Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_get_next [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_get_next request for: ", + [UserId, TargetName, CtxName, Oids]), Reply = (catch handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> %% Check agent version? This op not in v1 +handle_call({async_get_bulk, + Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_get_bulk request for: " + "~n ~p", [UserId, TargetName, Oids]), + Reply = (catch handle_async_get_bulk(Pid, + UserId, TargetName, + NonRep, MaxRep, Oids, SendOpts, + State)), + {reply, Reply, State}; + + +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_get_bulk, Pid, UserId, TargetName, NonRep, MaxRep, CtxName, Oids, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_get_bulk [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_get_bulk request for: " + "~n ~p", [UserId, TargetName, CtxName, Oids]), Reply = (catch handle_async_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> + + +handle_call({async_set, + Pid, UserId, TargetName, VarsAndVals, SendOpts}, + _From, State) -> + ?vlog("[~p,~p] received async_set request for: " + "~n ~p", [UserId, TargetName, VarsAndVals]), + Reply = (catch handle_async_set(Pid, + UserId, TargetName, VarsAndVals, SendOpts, + State)), + {reply, Reply, State}; +%% <BACKWARD-COMPAT> +%% The only case where this would be called is during code upgrade handle_call({async_set, Pid, UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo}, _From, State) -> - ?vlog("received async_set [~p] request", [CtxName]), + ?vlog("[~p,~p,~p] received async_set request for: " + "~n ~p", [UserId, TargetName, CtxName, VarsAndVals]), Reply = (catch handle_async_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo, State)), {reply, Reply, State}; +%% </BACKWARD-COMPAT> handle_call({cancel_async_request, UserId, ReqId}, _From, State) -> @@ -901,36 +1157,46 @@ terminate(Reason, #state{gct = GCT}) -> handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State). + +handle_sync_get(Pid, UserId, TargetName, Oids, SendOpts, From, State) -> ?vtrace("handle_sync_get -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, Oids, SendOpts, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get -> send a ~p message", [Vsn]), - ReqId = send_get_request(Oids, Vsn, MsgData, Addr, Port, - ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_get_request(Oids, Vsn, MsgData, + Addr, Port, Extra, State), ?vdebug("handle_sync_get -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_GET_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_get -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = get, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = get, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; Error -> @@ -940,39 +1206,49 @@ handle_sync_get(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, Error end. - handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, From, State). + +handle_sync_get_next(Pid, UserId, TargetName, Oids, SendOpts, + From, State) -> ?vtrace("handle_sync_get_next -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, Oids, SendOpts, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get_next -> send a ~p message", [Vsn]), - ReqId = send_get_next_request(Oids, Vsn, MsgData, - Addr, Port, ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_get_next_request(Oids, Vsn, MsgData, + Addr, Port, Extra, State), ?vdebug("handle_sync_get_next -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_GET_NEXT_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_get_next -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = get_next, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = get_next, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -987,39 +1263,50 @@ handle_sync_get_next(Pid, UserId, TargetName, CtxName, Oids, Timeout, handle_sync_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, + SendOpts, From, State). + +handle_sync_get_bulk(Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, + From, State) -> ?vtrace("handle_sync_get_bulk -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n NonRep: ~p" "~n MaxRep: ~p" "~n Oids: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, - Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_get_bulk -> send a ~p message", [Vsn]), - ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, - NonRep, MaxRep, ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_get_bulk_request(Oids, Vsn, MsgData, Addr, Port, + NonRep, MaxRep, Extra, State), ?vdebug("handle_sync_get_bulk -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_GET_BULK_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_get_bulk -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = get_bulk, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = get_bulk, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -1033,36 +1320,47 @@ handle_sync_get_bulk(Pid, UserId, TargetName, CtxName, handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, ExtraInfo, From, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Timeout}, + {extra, ExtraInfo} + ], + handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, + From, State). + +handle_sync_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, From, State) -> ?vtrace("handle_sync_set -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n VarsAndVals: ~p" - "~n Timeout: ~p" + "~n SendOpts: ~p" "~n From: ~p", - [Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, From]), - case agent_data(TargetName, CtxName) of + [Pid, UserId, TargetName, VarsAndVals, From]), + case agent_data(TargetName, SendOpts) of {ok, RegType, Addr, Port, Vsn, MsgData} -> ?vtrace("handle_sync_set -> send a ~p message", [Vsn]), - ReqId = send_set_request(VarsAndVals, Vsn, MsgData, - Addr, Port, ExtraInfo, State), + Extra = ?GET_EXTRA(SendOpts), + ReqId = send_set_request(VarsAndVals, Vsn, MsgData, + Addr, Port, Extra, State), ?vdebug("handle_sync_set -> ReqId: ~p", [ReqId]), - Msg = {sync_timeout, ReqId, From}, - Ref = erlang:send_after(Timeout, self(), Msg), - MonRef = erlang:monitor(process, Pid), + Msg = {sync_timeout, ReqId, From}, + Timeout = ?SYNC_SET_TIMEOUT(SendOpts), + Ref = erlang:send_after(Timeout, self(), Msg), + MonRef = erlang:monitor(process, Pid), ?vtrace("handle_sync_set -> MonRef: ~p", [MonRef]), - Req = #request{id = ReqId, - user_id = UserId, - reg_type = RegType, - target = TargetName, - addr = Addr, - port = Port, - type = set, - data = MsgData, - ref = Ref, - mon = MonRef, - from = From}, + Req = #request{id = ReqId, + user_id = UserId, + reg_type = RegType, + target = TargetName, + addr = Addr, + port = Port, + type = set, + data = MsgData, + ref = Ref, + mon = MonRef, + from = From}, ets:insert(snmpm_request_table, Req), ok; @@ -1076,20 +1374,30 @@ handle_sync_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Timeout, handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State). + +handle_async_get(Pid, UserId, TargetName, Oids, SendOpts, State) -> ?vtrace("handle_async_get -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, Oids, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, 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, - ExtraInfo, State), + Extra, State), ?vdebug("handle_async_get -> ReqId: ~p", [ReqId]), + Expire = ?ASYNC_GET_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, @@ -1114,20 +1422,30 @@ handle_async_get(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State). + +handle_async_get_next(Pid, UserId, TargetName, Oids, SendOpts, State) -> ?vtrace("handle_async_get_next -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n Oids: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, Oids, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, Oids, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, 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, ExtraInfo, State), + 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, @@ -1153,22 +1471,36 @@ handle_async_get_next(Pid, UserId, TargetName, CtxName, Oids, Expire, handle_async_get_bulk(Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_get_bulk(Pid, + UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, + State). + +handle_async_get_bulk(Pid, + UserId, TargetName, NonRep, MaxRep, Oids, SendOpts, + State) -> ?vtrace("handle_async_get_bulk -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n NonRep: ~p" "~n MaxRep: ~p" "~n Oids: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, NonRep, MaxRep, Oids, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, NonRep, MaxRep, Oids, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, 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, - NonRep, MaxRep, ExtraInfo, State), + NonRep, MaxRep, Extra, State), ?vdebug("handle_async_get_bulk -> ReqId: ~p", [ReqId]), + Expire = ?ASYNC_GET_BULK_TIMEOUT(SendOpts), Req = #request{id = ReqId, user_id = UserId, reg_type = RegType, @@ -1192,20 +1524,30 @@ handle_async_get_bulk(Pid, UserId, TargetName, CtxName, handle_async_set(Pid, UserId, TargetName, CtxName, VarsAndVals, Expire, ExtraInfo, State) -> + SendOpts = + [ + {context, CtxName}, + {timeout, Expire}, + {extra, ExtraInfo} + ], + handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State). + +handle_async_set(Pid, UserId, TargetName, VarsAndVals, SendOpts, State) -> ?vtrace("handle_async_set -> entry with" "~n Pid: ~p" "~n UserId: ~p" "~n TargetName: ~p" - "~n CtxName: ~p" "~n VarsAndVals: ~p" - "~n Expire: ~p", - [Pid, UserId, TargetName, CtxName, VarsAndVals, Expire]), - case agent_data(TargetName, CtxName) of + "~n SendOpts: ~p", + [Pid, UserId, TargetName, VarsAndVals, SendOpts]), + case agent_data(TargetName, SendOpts) of {ok, RegType, 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, ExtraInfo, State), + 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, @@ -2798,10 +3140,7 @@ request_id() -> %%---------------------------------------------------------------------- -agent_data(TargetName, CtxName) -> - agent_data(TargetName, CtxName, []). - -agent_data(TargetName, CtxName, Config) -> +agent_data(TargetName, SendOpts) -> case snmpm_config:agent_info(TargetName, all) of {ok, Info} -> Version = agent_data_item(version, Info), @@ -2813,15 +3152,18 @@ agent_data(TargetName, CtxName, Config) -> DefSecLevel = agent_data_item(sec_level, Info), EngineId = agent_data_item(engine_id, Info), + CtxName = agent_data_item(context, + SendOpts, + ?DEFAULT_CONTEXT), SecModel = agent_data_item(sec_model, - Config, + SendOpts, DefSecModel), SecName = agent_data_item(sec_name, - Config, + SendOpts, DefSecName), SecLevel = agent_data_item(sec_level, - Config, + SendOpts, DefSecLevel), {SecModel, SecName, mk_sec_level_flag(SecLevel), @@ -2831,10 +3173,10 @@ agent_data(TargetName, CtxName, Config) -> DefSecModel = agent_data_item(sec_model, Info), Comm = agent_data_item(community, - Config, + SendOpts, DefComm), SecModel = agent_data_item(sec_model, - Config, + SendOpts, DefSecModel), {Comm, SecModel} @@ -3003,6 +3345,12 @@ default_agent_config() -> %%---------------------------------------------------------------------- +get_opt(Key, Default, Opts) -> + proplists:get_value(Key, Opts, Default). + + +%%---------------------------------------------------------------------- + is_started(#state{net_if = _Pid, net_if_mod = _Mod}) -> %% Mod:is_started(Pid) and snmpm_config:is_started(). case snmpm_config:is_started() of diff --git a/lib/snmp/src/manager/snmpm_usm.erl b/lib/snmp/src/manager/snmpm_usm.erl index 449127844a..ef2070a90e 100644 --- a/lib/snmp/src/manager/snmpm_usm.erl +++ b/lib/snmp/src/manager/snmpm_usm.erl @@ -476,14 +476,19 @@ set_engine_latest_time(SnmpEngineID, EngineTime) -> %%----------------------------------------------------------------- %% Utility functions %%----------------------------------------------------------------- +-spec error(term()) -> no_return(). error(Reason) -> throw({error, Reason}). +-spec error(term(), term()) -> no_return(). error(Reason, ErrorInfo) -> throw({error, Reason, ErrorInfo}). +-spec error(term(), term(), term()) -> no_return(). error(Variable, Oid, SecName) -> error(Variable, Oid, SecName, []). + +-spec error(term(), term(), term(), [term()]) -> no_return(). error(Variable, Oid, SecName, Opts) -> Val = inc(Variable), ErrorInfo = {#varbind{oid = Oid, diff --git a/lib/snmp/src/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl index 4d2f5d8f92..cb5b3bbfbd 100644 --- a/lib/snmp/src/misc/snmp_conf.erl +++ b/lib/snmp/src/misc/snmp_conf.erl @@ -37,7 +37,13 @@ check_timer/1, - check_ip/1, check_taddress/1, + check_domain/1, + check_tdomain/1, + mk_tdomain/1, + which_domain/1, + check_ip/1, check_ip/2, + check_taddress/1, check_taddress/2, + mk_taddress/3, check_packet_size/1, @@ -52,8 +58,10 @@ -define(SNMP_USE_V3, true). --include("snmp_types.hrl"). --include("SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/snmp_types.hrl"). +-include_lib("snmp/include/SNMP-FRAMEWORK-MIB.hrl"). +-include_lib("snmp/include/TRANSPORT-ADDRESS-MIB.hrl"). +-include_lib("snmp/include/SNMPv2-TM.hrl"). -define(VMODULE,"CONF"). -include("snmp_verbosity.hrl"). @@ -338,15 +346,96 @@ check_sec_level(BadSecLevel) -> %% --------- -check_taddress(X) when is_list(X) andalso (length(X) =:= 6) -> +check_tdomain(TDomain) -> + SupportedTDomains = + [ + ?snmpUDPDomain, + ?transportDomainUdpIpv4, + ?transportDomainUdpIpv6 + ], + AllTDomains = + [ + ?transportDomainUdpIpv4, + ?transportDomainUdpIpv6, + ?transportDomainUdpIpv4z, + ?transportDomainUdpIpv6z, + ?transportDomainTcpIpv4, + ?transportDomainTcpIpv6, + ?transportDomainTcpIpv4z, + ?transportDomainTcpIpv6z, + ?transportDomainSctpIpv4, + ?transportDomainSctpIpv6, + ?transportDomainSctpIpv4z, + ?transportDomainSctpIpv6z, + ?transportDomainLocal, + ?transportDomainUdpDns, + ?transportDomainTcpDns, + ?transportDomainSctpDns + ], + case lists:member(TDomain, SupportedTDomains) of + true -> + ok; + false -> + case lists:member(TDomain, AllTDomains) of + true -> + error({unsupported_tdomain, TDomain}); + false -> + error({unknown_tdomain, TDomain}) + end + end. + + +%% --------- + +mk_tdomain(snmpUDPDomain) -> + ?snmpUDPDomain; +mk_tdomain(transportDomainUdpIpv4) -> + ?transportDomainUdpIpv4; +mk_tdomain(transportDomainUdpIpv6) -> + ?transportDomainUdpIpv6; +mk_tdomain(BadDomain) -> + error({bad_domain, BadDomain}). + + +%% --------- + +check_taddress(X) -> + check_taddress(snmpUDPDomain, X). + +check_taddress(?snmpUDPDomain, X) -> + check_taddress(transportDomainUdpIpv4, X); +check_taddress(snmpUDPDomain, X) -> + check_taddress(transportDomainUdpIpv4, X); + +check_taddress(?transportDomainUdpIpv4, X) -> + check_taddress(transportDomainUdpIpv4, X); +check_taddress(transportDomainUdpIpv4, X) + when is_list(X) andalso (length(X) =:= 6) -> case (catch all_integer(X)) of true -> ok; false -> error({invalid_taddress, X}) end; -check_taddress(X) -> - error({invalid_taddress, X}). +check_taddress(transportDomainUdpIpv4, X) -> + error({invalid_taddress, X}); + +check_taddress(?transportDomainUdpIpv6, X) -> + check_taddress(transportDomainUdpIpv6, X); +check_taddress(transportDomainUdpIpv6, X) + when is_list(X) andalso (length(X) =:= 10) -> + case (catch all_integer(X)) of + true -> + ok; + false -> + error({invalid_taddress, X}) + end; +check_taddress(transportDomainUdpIpv6, X) -> + error({invalid_taddress, X}); + +check_taddress(BadDomain, _X) -> + error({invalid_tdomain, BadDomain}). + %% --------- @@ -385,15 +474,115 @@ do_check_timer(WaitFor, Factor, Incr, Retry) -> %% --------- -check_ip(X) when is_list(X) andalso (length(X) =:= 4) -> +check_domain(Domain) -> + SupportedDomains = + [ + snmpUDPDomain, + transportDomainUdpIpv4, + transportDomainUdpIpv6 + ], + AllDomains = + [ + transportDomainUdpIpv4, + transportDomainUdpIpv6, + transportDomainUdpIpv4z, + transportDomainUdpIpv6z, + transportDomainTcpIpv4, + transportDomainTcpIpv6, + transportDomainTcpIpv4z, + transportDomainTcpIpv6z, + transportDomainSctpIpv4, + transportDomainSctpIpv6, + transportDomainSctpIpv4z, + transportDomainSctpIpv6z, + transportDomainLocal, + transportDomainUdpDns, + transportDomainTcpDns, + transportDomainSctpDns + ], + case lists:member(Domain, SupportedDomains) of + true -> + ok; + false -> + case lists:member(Domain, AllDomains) of + true -> + error({unsupported_domain, Domain}); + false -> + error({unknown_domain, Domain}) + end + end. + + +%% --------- + +%% The values of Ip and Port has both been checked at this +%% point, so we dont need to do that again. +mk_taddress(snmpUDPDomain, Ip, Port) -> + mk_taddress(transportDomainUdpIpv4, Ip, Port); +mk_taddress(transportDomainUdpIpv4, Ip, Port) when is_list(Ip) -> + Ip ++ [Port div 256, Port rem 256]; +mk_taddress(transportDomainUdpIpv4 = Domain, Ip, Port) when is_tuple(Ip) -> + mk_taddress(Domain, tuple_to_list(Ip), Port); +mk_taddress(transportDomainUdpIpv6, Ip, Port) when is_list(Ip) -> + Ip ++ [Port div 256, Port rem 256]; +mk_taddress(transportDomainUdpIpv6 = Domain, Ip, Port) when is_tuple(Ip) -> + mk_taddress(Domain, tuple_to_list(Ip), Port); + +%% These are just for convenience +mk_taddress(?snmpUDPDomain, Ip, Port) -> + mk_taddress(snmpUDPDomain, Ip, Port); +mk_taddress(?transportDomainUdpIpv4, Ip, Port) -> + mk_taddress(transportDomainUdpIpv4, Ip, Port); +mk_taddress(?transportDomainUdpIpv6, Ip, Port) -> + mk_taddress(transportDomainUdpIpv6, Ip, Port); + +%% Bad domain +mk_taddress(BadDomain, _Ip, _Port) -> + error({bad_domain, BadDomain}). + + +%% --------- + +which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 4) -> + transportDomainUdpIpv4; +which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 4) -> + transportDomainUdpIpv4; +which_domain(Ip) when is_list(Ip) andalso (length(Ip) =:= 8) -> + transportDomainUdpIpv6; +which_domain(Ip) when is_tuple(Ip) andalso (size(Ip) =:= 8) -> + transportDomainUdpIpv6. + + +%% --------- + +check_ip(X) -> + check_ip(snmpUDPDomain, X). + +check_ip(snmpUDPDomain, X) -> + check_ip(transportDomainUdpIpv4, X); +check_ip(transportDomainUdpIpv4, X) when is_list(X) andalso (length(X) =:= 4) -> case (catch all_integer(X)) of true -> ok; false -> error({invalid_ip_address, X}) end; -check_ip(X) -> - error({invalid_ip_address, X}). +check_ip(transportDomainUdpIpv4, X) -> + error({invalid_ip_address, X}); + +check_ip(transportDomainUdpIpv6, X) when is_list(X) andalso (length(X) =:= 8) -> + case (catch all_integer(X)) of + true -> + ok; + false -> + error({invalid_ip_address, X}) + end; +check_ip(transportDomainUdpIpv6, X) -> + error({invalid_ip_address, X}); + +check_ip(BadDomain, _X) -> + error({invalid_domain, BadDomain}). + %% --------- diff --git a/lib/snmp/src/misc/snmp_config.erl b/lib/snmp/src/misc/snmp_config.erl index 25350e08cb..813942225e 100644 --- a/lib/snmp/src/misc/snmp_config.erl +++ b/lib/snmp/src/misc/snmp_config.erl @@ -491,6 +491,9 @@ config_agent_snmp(Dir, Vsns) -> Host = host(), AgentIP = ask("5. IP address for the agent (only used as id ~n" " when sending traps)", Host, fun verify_address/1), + %% We intentionally skip TDomain... + %% If the user wish to use IPv6, the user must create an dummy entry here + %% and then manually edit these entries later. ManagerIP = ask("6. IP address for the manager (only this manager ~n" " will have access to the agent, traps are sent ~n" " to this one)", Host, fun verify_address/1), @@ -1062,9 +1065,19 @@ verify_sec_type(ST) -> {error, "invalid security type: " ++ ST}. verify_address(A) -> - case (catch snmp_misc:ip(A)) of + verify_address(A, snmpUDPDomain). + +verify_address(A, snmpUDPDomain = _Domain) -> + do_verify_address(A, inet); +verify_address(A, transportDomainUdpIpv4 = _Domain) -> + do_verify_address(A, inet); +verify_address(A, transportDomainUdpIpv6 = _Domain) -> + do_verify_address(A, inet6). + +do_verify_address(A, Family) -> + case (catch snmp_misc:ip(A, Family)) of {ok, IP} -> - {ok, tuple_to_list(IP)}; + {ok, tuple_to_list(IP)}; {error, _} -> {error, "invalid address: " ++ A}; _E -> @@ -1721,10 +1734,12 @@ write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, Hdr = header() ++ Comment, F = fun(v1 = Vsn, Acc) -> [{mk_ip(ManagerIp, Vsn), + snmp_target_mib:default_domain(), ManagerIp, UDP, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}| Acc]; (v2 = Vsn, Acc) -> [{mk_ip(ManagerIp, Vsn), + snmp_target_mib:default_domain(), ManagerIp, UDP, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, {lists:flatten(io_lib:format("~s.2",[mk_ip(ManagerIp, Vsn)])), @@ -1732,6 +1747,7 @@ write_agent_snmp_target_addr_conf(Dir, ManagerIp, UDP, "std_inform", mk_param(Vsn), "", [], 2048}| Acc]; (v3 = Vsn, Acc) -> [{mk_ip(ManagerIp, Vsn), + snmp_target_mib:default_domain(), ManagerIp, UDP, Timeout, RetryCount, "std_trap", mk_param(Vsn), "", [], 2048}, {lists:flatten(io_lib:format("~s.3",[mk_ip(ManagerIp, Vsn)])), diff --git a/lib/snmp/src/misc/snmp_log.erl b/lib/snmp/src/misc/snmp_log.erl index f9aa911817..7930e37c66 100644 --- a/lib/snmp/src/misc/snmp_log.erl +++ b/lib/snmp/src/misc/snmp_log.erl @@ -266,9 +266,6 @@ validate_loop(eof, _Log, _Validatior, _PrevTS, _PrevSN) -> ok; validate_loop({error, _} = Error, _Log, _Validator, _PrevTS, _PrevSN) -> Error; -validate_loop({corrupt_log_file, _} = Reason, - _Log, _Validator, _PrevTS, _PrevSN) -> - {error, Reason}; validate_loop({Cont, Terms}, Log, Validator, PrevTS, PrevSN) -> ?vtrace("validate_loop -> entry with" "~n Terms: ~p" @@ -508,8 +505,6 @@ loop(eof, _Log, _Write) -> ok; loop({error, _} = Error, _Log, _Write) -> Error; -loop({corrupt_log_file, _} = Reason, _Log, _Write) -> - {error, Reason}; loop({Cont, Terms}, Log, Write) -> case (catch lists:foreach(Write, Terms)) of {'EXIT', Reason} -> diff --git a/lib/snmp/src/misc/snmp_misc.erl b/lib/snmp/src/misc/snmp_misc.erl index 1b535743a4..6adef06ab9 100644 --- a/lib/snmp/src/misc/snmp_misc.erl +++ b/lib/snmp/src/misc/snmp_misc.erl @@ -40,7 +40,7 @@ get_option/2, get_option/3, get_sec_level/1, - ip/1, + ip/1, ip/2, is_auth/1, is_BitString/1, is_oid/1, @@ -347,10 +347,15 @@ bits_to_int([Kibble|Ks],Kibbles,Res) -> %%---------------------------------------------------------------------- -%% Returns: {ok, {int(),int(),int(),int()}} | {error, Reason} +%% Returns: {ok, {int(),int(),int(),int()}} | +%% {ok, {int(),int(),int(),int()},int(),int(),int(),int()} | +%% {error, Reason} %%---------------------------------------------------------------------- ip(Host) -> - inet:getaddr(Host, inet). + ip(Host, inet). + +ip(Host, Family) -> + inet:getaddr(Host, Family). ensure_trailing_dir_delimiter([]) -> "/"; ensure_trailing_dir_delimiter(DirSuggestion) -> diff --git a/lib/snmp/src/misc/snmp_pdus.erl b/lib/snmp/src/misc/snmp_pdus.erl index dc8900c8cd..82618a0b86 100644 --- a/lib/snmp/src/misc/snmp_pdus.erl +++ b/lib/snmp/src/misc/snmp_pdus.erl @@ -269,24 +269,35 @@ dec_value([64 | Bytes]) -> {Value, Rest} = dec_oct_str_notag(Bytes), {{'IpAddress', Value}, Rest}; dec_value([65 | Bytes]) -> + %% Counter32 is an unsigned 32 but is actually encoded as + %% a signed integer 32 (INTEGER). {Value, Rest} = dec_integer_notag(Bytes), - if Value >= 0, Value =< 4294967295 -> - {{'Counter32', Value}, Rest}; - true -> - exit({error, {bad_counter32, Value}}) - end; + Value2 = + if + (Value >= 0) andalso (Value =< 16#ffffffff) -> + %% We accept value above 16#7fffffff + %% in order to be backward bug-compatible + Value; + (Value < 0) -> + 16#ffffffff + Value + 1; + true -> + exit({error, {bad_counter32, Value}}) + end, + {{'Counter32', Value2}, Rest}; dec_value([66 | Bytes]) -> {Value, Rest} = dec_integer_notag(Bytes), - if Value >= 0, Value =< 4294967295 -> + if + (Value >= 0) andalso (Value =< 4294967295) -> {{'Unsigned32', Value}, Rest}; - true -> + true -> exit({error, {bad_unsigned32, Value}}) end; dec_value([67 | Bytes]) -> {Value, Rest} = dec_integer_notag(Bytes), - if Value >= 0, Value =< 4294967295 -> + if + (Value >= 0) andalso (Value =< 4294967295) -> {{'TimeTicks', Value}, Rest}; - true -> + true -> exit({error, {bad_timeticks, Value}}) end; dec_value([68 | Bytes]) -> @@ -642,6 +653,21 @@ enc_value(_Type, endOfMibView) -> [130,0]; enc_value('NULL', _Val) -> [5,0]; +enc_value('Counter32', Val) -> + Val2 = + if + Val > 16#ffffffff -> + exit({error, {bad_counter32, Val}}); + Val >= 16#80000000 -> + (Val band 16#7fffffff) - 16#80000000; + Val >= 0 -> + Val; + true -> + exit({error, {bad_counter32, Val}}) + end, + Bytes2 = enc_integer_notag(Val2), + Len2 = elength(length(Bytes2)), + lists:append([65 | Len2],Bytes2); enc_value('Counter64', Val) -> Val2 = if diff --git a/lib/snmp/test/Makefile b/lib/snmp/test/Makefile index b7975024b4..0e9c73081d 100644 --- a/lib/snmp/test/Makefile +++ b/lib/snmp/test/Makefile @@ -145,9 +145,12 @@ endif # ---------------------------------------------------- EBIN = . -ERL_COMPILE_FLAGS += -I../src \ +ERL_COMPILE_FLAGS += -I../../snmp/src/app \ + -I../../snmp/src/misc \ + -I../../snmp/src/agent \ + -I../../snmp/src/manager \ -I$(ERL_TOP)/lib/test_server/include \ - -I../include \ + -I../../snmp/include \ -Dsnmp_test_data=snmp_test_data \ -Dversion=\"$(VSN)$(PRE_VSN)\" \ +'{parse_transform,sys_pre_attributes}' \ diff --git a/lib/snmp/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl index 692d29fda0..acf62f5646 100644 --- a/lib/snmp/test/snmp_agent_test.erl +++ b/lib/snmp/test/snmp_agent_test.erl @@ -81,13 +81,12 @@ case get(vsn) of v1 -> V1; v2 -> V2; - _ -> V3 + _ -> V3 end). all() -> - Reqs = [mnesia, distribution, {local_slave_nodes, 2}, - {time, 360}], + %% Reqs = [mnesia, distribution, {local_slave_nodes, 2}, {time, 360}], Conf1 = [{group, all_tcs}], Conf2 = [{group, tickets2}], Conf1 ++ Conf2. @@ -95,67 +94,138 @@ all() -> groups() -> [{all_tcs, [], cases()}, {mib_storage, [], - [{group, mib_storage_ets}, {group, mib_storage_dets}, + [ + {group, mib_storage_ets}, + {group, mib_storage_dets}, {group, mib_storage_mnesia}, {group, mib_storage_size_check_ets}, {group, mib_storage_size_check_dets}, {group, mib_storage_size_check_mnesia}, {group, mib_storage_varm_dets}, - {group, mib_storage_varm_mnesia}]}, - {mib_storage_ets, [], mib_storage_ets_cases()}, - {mib_storage_dets, [], mib_storage_dets_cases()}, - {mib_storage_mnesia, [], mib_storage_mnesia_cases()}, - {mib_storage_size_check_ets, [], - mse_size_check_cases()}, - {mib_storage_size_check_dets, [], - msd_size_check_cases()}, - {mib_storage_size_check_mnesia, [], - msm_size_check_cases()}, - {mib_storage_varm_dets, [], - varm_mib_storage_dets_cases()}, - {mib_storage_varm_mnesia, [], - varm_mib_storage_mnesia_cases()}, - {misc, [], misc_cases()}, {test_v1, [], v1_cases()}, - {test_v2, [], v2_cases()}, - {test_v1_v2, [], v1_v2_cases()}, - {test_v3, [], v3_cases()}, - {test_multi_threaded, [], mt_cases()}, - {multiple_reqs, [], mul_cases()}, - {multiple_reqs_2, [], mul_cases_2()}, - {v2_inform, [], [v2_inform_i]}, + {group, mib_storage_varm_mnesia} + ] + }, + {mib_storage_ets, [], mib_storage_ets_cases()}, + {mib_storage_dets, [], mib_storage_dets_cases()}, + {mib_storage_mnesia, [], mib_storage_mnesia_cases()}, + {mib_storage_size_check_ets, [], mse_size_check_cases()}, + {mib_storage_size_check_dets, [], msd_size_check_cases()}, + {mib_storage_size_check_mnesia, [], msm_size_check_cases()}, + {mib_storage_varm_dets, [], varm_mib_storage_dets_cases()}, + {mib_storage_varm_mnesia, [], varm_mib_storage_mnesia_cases()}, + {misc, [], misc_cases()}, + {test_v1, [], v1_cases()}, + {test_v2, [], v2_cases()}, + {test_v1_v2, [], v1_v2_cases()}, + {test_v3, [], v3_cases()}, + {test_multi_threaded, [], mt_cases()}, + {multiple_reqs, [], mul_cases()}, + {multiple_reqs_2, [], mul_cases_2()}, + {v2_inform, [], + [ + v2_inform_i + ] + }, {v3_security, [], - [v3_crypto_basic, v3_md5_auth, v3_sha_auth, - v3_des_priv]}, + [ + v3_crypto_basic, + v3_md5_auth, + v3_sha_auth, + v3_des_priv + ] + }, {standard_mibs, [], - [snmp_standard_mib, snmp_community_mib, - snmp_framework_mib, snmp_target_mib, - snmp_notification_mib, snmp_view_based_acm_mib]}, + [ + snmp_standard_mib, + snmp_community_mib, + snmp_framework_mib, + snmp_target_mib, + snmp_notification_mib, + snmp_view_based_acm_mib + ] + }, {standard_mibs_2, [], - [snmpv2_mib_2, snmp_community_mib_2, - snmp_framework_mib_2, snmp_target_mib_2, - snmp_notification_mib_2, snmp_view_based_acm_mib_2]}, + [ + snmpv2_mib_2, + snmp_community_mib_2, + snmp_framework_mib_2, + snmp_target_mib_2, + snmp_notification_mib_2, + snmp_view_based_acm_mib_2 + ] + }, {standard_mibs_3, [], - [snmpv2_mib_3, snmp_framework_mib_3, snmp_mpd_mib_3, - snmp_target_mib_3, snmp_notification_mib_3, - snmp_view_based_acm_mib_3, snmp_user_based_sm_mib_3]}, + [ + snmpv2_mib_3, + snmp_framework_mib_3, + snmp_mpd_mib_3, + snmp_target_mib_3, + snmp_notification_mib_3, + snmp_view_based_acm_mib_3, + snmp_user_based_sm_mib_3 + ] + }, {reported_bugs, [], - [otp_1128, otp_1129, otp_1131, otp_1162, otp_1222, - otp_1298, otp_1331, otp_1338, otp_1342, otp_2776, - otp_2979, otp_3187, otp_3725]}, + [ + otp_1128, + otp_1129, + otp_1131, + otp_1162, + otp_1222, + otp_1298, + otp_1331, + otp_1338, + otp_1342, + otp_2776, + otp_2979, + otp_3187, + otp_3725 + ] + }, {reported_bugs_2, [], - [otp_1128_2, otp_1129_2, otp_1131_2, otp_1162_2, - otp_1222_2, otp_1298_2, otp_1331_2, otp_1338_2, - otp_1342_2, otp_2776_2, otp_2979_2, otp_3187_2]}, + [ + otp_1128_2, + otp_1129_2, + otp_1131_2, + otp_1162_2, + otp_1222_2, + otp_1298_2, + otp_1331_2, + otp_1338_2, + otp_1342_2, + otp_2776_2, + otp_2979_2, + otp_3187_2 + ] + }, {reported_bugs_3, [], - [otp_1128_3, otp_1129_3, otp_1131_3, otp_1162_3, - otp_1222_3, otp_1298_3, otp_1331_3, otp_1338_3, - otp_1342_3, otp_2776_3, otp_2979_3, otp_3187_3, - otp_3542]}, - {tickets1, [], [{group, otp_4394}, {group, otp_7157}]}, + [ + otp_1128_3, + otp_1129_3, + otp_1131_3, + otp_1162_3, + otp_1222_3, + otp_1298_3, + otp_1331_3, + otp_1338_3, + otp_1342_3, + otp_2776_3, + otp_2979_3, + otp_3187_3, + otp_3542 + ] + }, + {tickets1, [], + [ + {group, otp_4394}, + {group, otp_7157} + ] + }, {tickets2, [], [otp8395]}, {otp_4394, [], [otp_4394_test]}, - {otp_7157, [], - begin Reqs = [], Conf = [otp_7157_test], Conf end}]. + {otp_7157, [], [otp_7157_test] + } + ]. init_per_group(all_tcs, Config) -> init_all(Config); @@ -378,17 +448,29 @@ end_per_testcase2(_Case, Config) -> cases() -> -case ?OSTYPE() of - vxworks -> - [{group, misc}, {group, test_v1}, {group, test_v2}, - {group, test_v1_v2}, {group, test_multi_threaded}, - {group, mib_storage}, {group, tickets1}]; - _Else -> - [{group, misc}, {group, test_v1}, {group, test_v2}, - {group, test_v1_v2}, {group, test_v3}, - {group, test_multi_threaded}, {group, mib_storage}, - {group, tickets1}] -end. + case ?OSTYPE() of + vxworks -> + [ + {group, misc}, + {group, test_v1}, + {group, test_v2}, + {group, test_v1_v2}, + {group, test_multi_threaded}, + {group, mib_storage}, + {group, tickets1} + ]; + _Else -> + [ + {group, misc}, + {group, test_v1}, + {group, test_v2}, + {group, test_v1_v2}, + {group, test_v3}, + {group, test_multi_threaded}, + {group, mib_storage}, + {group, tickets1} + ] + end. %%%----------------------------------------------------------------- @@ -1071,11 +1153,29 @@ app_dir(App) -> %v1_cases() -> [loop_mib]; v1_cases() -> -[simple, db_notify_client, v1_processing, big, big2, - loop_mib, api, subagent, mnesia, {group, multiple_reqs}, - sa_register, v1_trap, sa_error, next_across_sa, undo, - {group, reported_bugs}, {group, standard_mibs}, - sparse_table, cnt_64, opaque, change_target_addr_config]. + [ + simple, + db_notify_client, + v1_processing, + big, + big2, + loop_mib, + api, + subagent, + mnesia, + {group, multiple_reqs}, + sa_register, + v1_trap, + sa_error, + next_across_sa, + undo, + {group, reported_bugs}, + {group, standard_mibs}, + sparse_table, + cnt_64, + opaque, + change_target_addr_config + ]. init_v1(Config) when is_list(Config) -> ?line SaNode = ?config(snmp_sa, Config), @@ -1094,12 +1194,31 @@ finish_v1(Config) when is_list(Config) -> v2_cases() -> -[simple_2, v2_processing, big_2, big2_2, loop_mib_2, - api_2, subagent_2, mnesia_2, {group, multiple_reqs_2}, - sa_register_2, v2_trap, {group, v2_inform}, sa_error_2, - next_across_sa_2, undo_2, {group, reported_bugs_2}, - {group, standard_mibs_2}, v2_types, implied, - sparse_table_2, cnt_64_2, opaque_2, v2_caps]. + [ + simple_2, + v2_processing, + big_2, + big2_2, + loop_mib_2, + api_2, + subagent_2, + mnesia_2, + {group, multiple_reqs_2}, + sa_register_2, + v2_trap, + {group, v2_inform}, + sa_error_2, + next_across_sa_2, + undo_2, + {group, reported_bugs_2}, + {group, standard_mibs_2}, + v2_types, + implied, + sparse_table_2, + cnt_64_2, + opaque_2, + v2_caps + ]. init_v2(Config) when is_list(Config) -> SaNode = ?config(snmp_sa, Config), @@ -1118,7 +1237,7 @@ finish_v2(Config) when is_list(Config) -> v1_v2_cases() -> -[simple_bi]. + [simple_bi]. init_v1_v2(Config) when is_list(Config) -> SaNode = ?config(snmp_sa, Config), @@ -1137,13 +1256,32 @@ finish_v1_v2(Config) when is_list(Config) -> v3_cases() -> -[simple_3, v3_processing, big_3, big2_3, api_3, - subagent_3, mnesia_3, loop_mib_3, multiple_reqs_3, - sa_register_3, v3_trap, v3_inform, sa_error_3, - next_across_sa_3, undo_3, {group, reported_bugs_3}, - {group, standard_mibs_3}, {group, v3_security}, - v2_types_3, implied_3, sparse_table_3, cnt_64_3, - opaque_3, v2_caps_3]. + [ + simple_3, + v3_processing, + big_3, + big2_3, + api_3, + subagent_3, + mnesia_3, + loop_mib_3, + multiple_reqs_3, + sa_register_3, + v3_trap, + v3_inform, + sa_error_3, + next_across_sa_3, + undo_3, + {group, reported_bugs_3}, + {group, standard_mibs_3}, + {group, v3_security}, + v2_types_3, + implied_3, + sparse_table_3, + cnt_64_3, + opaque_3, + v2_caps_3 + ]. init_v3(Config) when is_list(Config) -> %% Make sure crypto works, otherwise start_agent will fail diff --git a/lib/snmp/test/snmp_agent_test_lib.erl b/lib/snmp/test/snmp_agent_test_lib.erl index 9e89aa889c..3ae2409997 100644 --- a/lib/snmp/test/snmp_agent_test_lib.erl +++ b/lib/snmp/test/snmp_agent_test_lib.erl @@ -1311,10 +1311,12 @@ rewrite_target_addr_conf(Dir, NewPort) -> "~n NewPort: ~p", [NewPort]), TAFile = filename:join(Dir, "target_addr.conf"), case file:read_file_info(TAFile) of - {ok, _} -> ok; - {error, R} -> ?ERR("failure reading file info of " - "target address config file: ~p",[R]), - ok + {ok, _} -> + ok; + {error, R} -> + ?ERR("failure reading file info of " + "target address config file: ~p",[R]), + ok end, ?line [TrapAddr|Addrs] = @@ -1335,8 +1337,9 @@ rewrite_target_addr_conf(Dir, NewPort) -> rewrite_target_addr_conf_check(O) -> {ok,O}. -rewrite_target_addr_conf2(NewPort,{Name,Ip,_Port,Timeout,Retry, - "std_trap",EngineId}) -> +rewrite_target_addr_conf2(NewPort, + {Name, Ip, _Port, Timeout, Retry, + "std_trap", EngineId}) -> ?LOG("rewrite_target_addr_conf2 -> entry with std_trap",[]), {Name,Ip,NewPort,Timeout,Retry,"std_trap",EngineId}; rewrite_target_addr_conf2(_NewPort,O) -> diff --git a/lib/snmp/test/snmp_manager_test.erl b/lib/snmp/test/snmp_manager_test.erl index 50836db731..6bd62df655 100644 --- a/lib/snmp/test/snmp_manager_test.erl +++ b/lib/snmp/test/snmp_manager_test.erl @@ -37,13 +37,16 @@ -include_lib("snmp/include/snmp_types.hrl"). -include_lib("snmp/include/STANDARD-MIB.hrl"). +-include_lib("snmp/src/manager/snmpm_internal.hrl"). %%---------------------------------------------------------------------- %% External exports %%---------------------------------------------------------------------- -export([ - all/0,groups/0,init_per_group/2,end_per_group/2, + all/0, + groups/0, + init_per_group/2, end_per_group/2, init_per_testcase/2, end_per_testcase/2, @@ -54,49 +57,45 @@ notify_started01/1, notify_started02/1, - register_user1/1, - register_agent1/1, register_agent2/1, - info/1, - - - simple_sync_get1/1, simple_sync_get2/1, + simple_sync_get3/1, simple_async_get1/1, simple_async_get2/1, - + simple_async_get3/1, simple_sync_get_next1/1, simple_sync_get_next2/1, + simple_sync_get_next3/1, simple_async_get_next1/1, simple_async_get_next2/1, - + simple_async_get_next3/1, simple_sync_set1/1, simple_sync_set2/1, + simple_sync_set3/1, simple_async_set1/1, simple_async_set2/1, - + simple_async_set3/1, simple_sync_get_bulk1/1, simple_sync_get_bulk2/1, + simple_sync_get_bulk3/1, simple_async_get_bulk1/1, simple_async_get_bulk2/1, - + simple_async_get_bulk3/1, misc_async1/1, misc_async2/1, discovery/1, - - trap1/1, trap2/1, @@ -109,8 +108,6 @@ report/1, - - otp8015_1/1, otp8395_1/1 @@ -220,7 +217,7 @@ init_per_testcase2(Case, Config) -> Conf2. init_per_testcase3(Case, Config) -> - OldApiCases = + ApiCases01 = [ simple_sync_get1, simple_async_get1, @@ -232,7 +229,7 @@ init_per_testcase3(Case, Config) -> simple_async_get_bulk1, misc_async1 ], - NewApiCases = + ApiCases02 = [ simple_sync_get2, simple_async_get2, @@ -245,6 +242,17 @@ init_per_testcase3(Case, Config) -> misc_async2, otp8395_1 ], + ApiCases03 = + [ + simple_sync_get3, + simple_async_get3, + simple_sync_get_next3, + simple_async_get_next3, + simple_sync_set3, + simple_async_set3, + simple_sync_get_bulk3, + simple_async_get_bulk3 + ], Cases = [ trap1, @@ -256,8 +264,9 @@ init_per_testcase3(Case, Config) -> inform_swarm, report ] ++ - OldApiCases ++ - NewApiCases, + ApiCases01 ++ + ApiCases02 ++ + ApiCases03, case lists:member(Case, Cases) of true -> NoAutoInformCases = [inform1, inform2, inform3, inform_swarm], @@ -279,7 +288,7 @@ init_per_testcase3(Case, Config) -> Conf2 = init_agent(Conf1), Conf3 = init_manager(AutoInform, Conf2), Conf4 = init_mgr_user(Conf3), - case lists:member(Case, NewApiCases) of + case lists:member(Case, ApiCases02 ++ ApiCases03) of true -> init_mgr_user_data2(Conf4); false -> @@ -301,7 +310,7 @@ end_per_testcase(Case, Config) when is_list(Config) -> Conf2. end_per_testcase2(Case, Config) -> - OldApiCases = + ApiCases01 = [ simple_sync_get1, simple_async_get1, @@ -313,7 +322,7 @@ end_per_testcase2(Case, Config) -> simple_async_get_bulk1, misc_async1 ], - NewApiCases = + ApiCases02 = [ simple_sync_get2, simple_async_get2, @@ -326,6 +335,17 @@ end_per_testcase2(Case, Config) -> misc_async2, otp8395_1 ], + ApiCases03 = + [ + simple_sync_get3, + simple_async_get3, + simple_sync_get_next3, + simple_async_get_next3, + simple_sync_set3, + simple_async_set3, + simple_sync_get_bulk3, + simple_async_get_bulk3 + ], Cases = [ trap1, @@ -337,11 +357,12 @@ end_per_testcase2(Case, Config) -> inform_swarm, report ] ++ - OldApiCases ++ - NewApiCases, + ApiCases01 ++ + ApiCases02 ++ + ApiCases03, case lists:member(Case, Cases) of true -> - Conf1 = case lists:member(Case, NewApiCases) of + Conf1 = case lists:member(Case, ApiCases02 ++ ApiCases03) of true -> fin_mgr_user_data2(Config); false -> @@ -360,42 +381,129 @@ end_per_testcase2(Case, Config) -> %%====================================================================== all() -> -[{group, start_and_stop_tests}, {group, misc_tests}, - {group, user_tests}, {group, agent_tests}, - {group, request_tests}, {group, event_tests}, discovery, - {group, tickets}]. + [ + {group, start_and_stop_tests}, + {group, misc_tests}, + {group, user_tests}, + {group, agent_tests}, + {group, request_tests}, + {group, event_tests}, + discovery, + {group, tickets} + ]. groups() -> - [{start_and_stop_tests, [], - [simple_start_and_stop1, simple_start_and_stop2, - simple_start_and_monitor_crash1, - simple_start_and_monitor_crash2, notify_started01, - notify_started02]}, - {misc_tests, [], [info]}, - {user_tests, [], [register_user1]}, - {agent_tests, [], [register_agent1, register_agent2]}, - {request_tests, [], - [{group, get_tests}, {group, get_next_tests}, - {group, set_tests}, {group, bulk_tests}, - {group, misc_request_tests}]}, - {get_tests, [], - [simple_sync_get1, simple_sync_get2, simple_async_get1, - simple_async_get2]}, - {get_next_tests, [], - [simple_sync_get_next1, simple_sync_get_next2, - simple_async_get_next1, simple_async_get_next2]}, - {set_tests, [], - [simple_sync_set1, simple_sync_set2, simple_async_set1, - simple_async_set2]}, - {bulk_tests, [], - [simple_sync_get_bulk1, simple_sync_get_bulk2, - simple_async_get_bulk1, simple_async_get_bulk2]}, - {misc_request_tests, [], [misc_async1, misc_async2]}, - {event_tests, [], - [trap1, trap2, inform1, inform2, inform3, inform4, - inform_swarm, report]}, - {tickets, [], [{group, otp8015}, {group, otp8395}]}, - {otp8015, [], [otp8015_1]}, {otp8395, [], [otp8395_1]}]. + [ + {start_and_stop_tests, [], + [ + simple_start_and_stop1, + simple_start_and_stop2, + simple_start_and_monitor_crash1, + simple_start_and_monitor_crash2, + notify_started01, + notify_started02 + ] + }, + {misc_tests, [], + [ + info + ] + }, + {user_tests, [], + [ + register_user1 + ] + }, + {agent_tests, [], + [ + register_agent1, + register_agent2 + ] + }, + {request_tests, [], + [ + {group, get_tests}, + {group, get_next_tests}, + {group, set_tests}, + {group, bulk_tests}, + {group, misc_request_tests} + ] + }, + {get_tests, [], + [ + simple_sync_get1, + simple_sync_get2, + simple_sync_get3, + simple_async_get1, + simple_async_get2, + simple_async_get3 + ] + }, + {get_next_tests, [], + [ + simple_sync_get_next1, + simple_sync_get_next2, + simple_sync_get_next3, + simple_async_get_next1, + simple_async_get_next2, + simple_async_get_next3 + ] + }, + {set_tests, [], + [ + simple_sync_set1, + simple_sync_set2, + simple_sync_set3, + simple_async_set1, + simple_async_set2, + simple_async_set3 + ] + }, + {bulk_tests, [], + [ + simple_sync_get_bulk1, + simple_sync_get_bulk2, + simple_sync_get_bulk3, + simple_async_get_bulk1, + simple_async_get_bulk2, + simple_async_get_bulk3 + ] + }, + {misc_request_tests, [], + [ + misc_async1, + misc_async2 + ] + }, + {event_tests, [], + [ + trap1, + trap2, + inform1, + inform2, + inform3, + inform4, + inform_swarm, + report + ] + }, + {tickets, [], + [ + {group, otp8015}, + {group, otp8395} + ] + }, + {otp8015, [], + [ + otp8015_1 + ] + }, + {otp8395, [], + [ + otp8395_1 + ] + } + ]. init_per_group(_GroupName, Config) -> Config. @@ -404,21 +512,6 @@ end_per_group(_GroupName, Config) -> Config. - - - - - - - - - - - - - - - %%====================================================================== %% Test functions %%====================================================================== @@ -1319,15 +1412,15 @@ simple_sync_get1(Config) when is_list(Config) -> p("issue get-request without loading the mib"), Oids1 = [?sysObjectID_instance, ?sysDescr_instance, ?sysUpTime_instance], - ?line ok = do_simple_get(Node, Addr, Port, Oids1), + ?line ok = do_simple_sync_get(Node, Addr, Port, Oids1), p("issue get-request after first loading the mibs"), ?line ok = mgr_user_load_mib(Node, std_mib()), Oids2 = [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - ?line ok = do_simple_get(Node, Addr, Port, Oids2), + ?line ok = do_simple_sync_get(Node, Addr, Port, Oids2), ok. -do_simple_get(Node, Addr, Port, Oids) -> +do_simple_sync_get(Node, Addr, Port, Oids) -> ?line {ok, Reply, Rem} = mgr_user_sync_get(Node, Addr, Port, Oids), ?DBG("~n Reply: ~p" @@ -1360,14 +1453,22 @@ do_simple_get(Node, Addr, Port, Oids) -> %%====================================================================== -simple_sync_get2(doc) -> ["Simple sync get-request - New style (TargetName)"]; +simple_sync_get2(doc) -> + ["Simple sync get-request - Version 2 API (TargetName)"]; simple_sync_get2(suite) -> []; simple_sync_get2(Config) when is_list(Config) -> process_flag(trap_exit, true), put(tname, ssg2), - do_simple_get(Config). + do_simple_sync_get2(Config). -do_simple_get(Config) -> +do_simple_sync_get2(Config) -> + Get = fun(Node, TargetName, Oids) -> + mgr_user_sync_get(Node, TargetName, Oids) + end, + PostVerify = fun() -> ok end, + do_simple_sync_get2(Config, Get, PostVerify). + +do_simple_sync_get2(Config, Get, PostVerify) -> p("starting with Config: ~p~n", [Config]), Node = ?config(manager_node, Config), @@ -1375,20 +1476,21 @@ do_simple_get(Config) -> p("issue get-request without loading the mib"), Oids1 = [?sysObjectID_instance, ?sysDescr_instance, ?sysUpTime_instance], - ?line ok = do_simple_get(Node, TargetName, Oids1), + ?line ok = do_simple_sync_get2(Node, TargetName, Oids1, Get, PostVerify), p("issue get-request after first loading the mibs"), ?line ok = mgr_user_load_mib(Node, std_mib()), Oids2 = [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - ?line ok = do_simple_get(Node, TargetName, Oids2), + ?line ok = do_simple_sync_get2(Node, TargetName, Oids2, Get, PostVerify), ok. - -do_simple_get(Node, TargetName, Oids) -> - ?line {ok, Reply, Rem} = mgr_user_sync_get(Node, TargetName, Oids), + +do_simple_sync_get2(Node, TargetName, Oids, Get, PostVerify) + when is_function(Get, 3) andalso is_function(PostVerify, 0) -> + ?line {ok, Reply, Rem} = Get(Node, TargetName, Oids), ?DBG("~n Reply: ~p" "~n Rem: ~w", [Reply, Rem]), - + %% verify that the operation actually worked: %% The order should be the same, so no need to seach ?line ok = case Reply of @@ -1403,7 +1505,7 @@ do_simple_get(Node, TargetName, Oids) -> "~n SysDescr: ~s" "~n SysUpTime: ~w", [SysObjectID, SysDescr, SysUpTime]), - ok; + PostVerify(); {noError, 0, Vbs} -> p("unexpected varbinds: ~n~p", [Vbs]), {error, {unexpected_vbs, Vbs}}; @@ -1416,6 +1518,38 @@ do_simple_get(Node, TargetName, Oids) -> %%====================================================================== +simple_sync_get3(doc) -> + ["Simple sync get-request - Version 3 API (TargetName and send-opts)"]; +simple_sync_get3(suite) -> []; +simple_sync_get3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, ssg3), + do_simple_sync_get3(Config). + +do_simple_sync_get3(Config) -> + Self = self(), + Msg = simple_sync_get3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + Get = fun(Node, TargetName, Oids) -> + mgr_user_sync_get2(Node, TargetName, Oids, SendOpts) + end, + PostVerify = + fun() -> + receive + Msg -> + ok + end + end, + do_simple_sync_get2(Config, Get, PostVerify). + + +%%====================================================================== + simple_async_get1(doc) -> ["Simple (async) get-request - " "Old style (Addr & Port)"]; simple_async_get1(suite) -> []; @@ -1435,40 +1569,41 @@ simple_async_get1(Config) when is_list(Config) -> ?line ok = agent_load_mib(AgentNode, Test2Mib), Exec = fun(Data) -> - async_g_exec1(MgrNode, Addr, Port, Data) + async_g_exec1(MgrNode, Addr, Port, Data) end, - Requests = [ - { 1, - [?sysObjectID_instance], - Exec, - fun(X) -> sag_verify(X, [?sysObjectID_instance]) end}, - { 2, - [?sysDescr_instance, ?sysUpTime_instance], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysUpTime_instance]) - end}, - { 3, - [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end}, - { 4, - [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end} - ], + Requests = + [ + { 1, + [?sysObjectID_instance], + Exec, + fun(X) -> sag_verify(X, [?sysObjectID_instance]) end }, + { 2, + [?sysDescr_instance, ?sysUpTime_instance], + Exec, + fun(X) -> + sag_verify(X, [?sysObjectID_instance, + ?sysUpTime_instance]) + end }, + { 3, + [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], + Exec, + fun(X) -> + sag_verify(X, [?sysObjectID_instance, + ?sysDescr_instance, + ?sysUpTime_instance]) + end }, + { 4, + [?sysObjectID_instance, + ?sysDescr_instance, + ?sysUpTime_instance], + Exec, + fun(X) -> + sag_verify(X, [?sysObjectID_instance, + ?sysDescr_instance, + ?sysUpTime_instance]) + end } + ], p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), @@ -1516,66 +1651,76 @@ sag_verify_vbs([Vb|_], [E|_]) -> %%====================================================================== -simple_async_get2(doc) -> ["Simple (async) get-request - " - "New style (TargetName)"]; +simple_async_get2(doc) -> + ["Simple (async) get-request - Version 2 API (TargetName)"]; simple_async_get2(suite) -> []; simple_async_get2(Config) when is_list(Config) -> process_flag(trap_exit, true), put(tname, sag2), p("starting with Config: ~p~n", [Config]), - MgrNode = ?config(manager_node, Config), AgentNode = ?config(agent_node, Config), TargetName = ?config(manager_agent_target_name, Config), + Get = fun(Oids) -> async_g_exec2(MgrNode, TargetName, Oids) end, + PostVerify = fun(Res) -> Res end, + do_simple_async_sync_get2(Config, MgrNode, AgentNode, Get, PostVerify). +do_simple_async_sync_get2(Config, MgrNode, AgentNode, Get, PostVerify) -> ?line ok = mgr_user_load_mib(MgrNode, std_mib()), Test2Mib = test2_mib(Config), ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), ?line ok = agent_load_mib(AgentNode, Test2Mib), - - Exec = fun(Data) -> - async_g_exec2(MgrNode, TargetName, Data) - end, - - Requests = [ - { 1, - [?sysObjectID_instance], - Exec, - fun(X) -> sag_verify(X, [?sysObjectID_instance]) end}, - { 2, - [?sysDescr_instance, ?sysUpTime_instance], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysUpTime_instance]) - end}, - { 3, - [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end}, - { 4, - [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance], - Exec, - fun(X) -> - sag_verify(X, [?sysObjectID_instance, - ?sysDescr_instance, - ?sysUpTime_instance]) - end} - ], + do_simple_async_sync_get2(fun() -> mgr_info(MgrNode) end, + fun() -> agent_info(AgentNode) end, + Get, PostVerify). + +do_simple_async_sync_get2(MgrInfo, AgentInfo, Get, PostVerify) + when is_function(MgrInfo, 0) andalso + is_function(AgentInfo, 0) andalso + is_function(Get, 1) andalso + is_function(PostVerify, 1) -> + Requests = + [ + { 1, + [?sysObjectID_instance], + Get, + fun(X) -> + PostVerify(sag_verify(X, [?sysObjectID_instance])) end}, + { 2, + [?sysDescr_instance, ?sysUpTime_instance], + Get, + fun(X) -> + PostVerify(sag_verify(X, [?sysObjectID_instance, + ?sysUpTime_instance])) + end}, + { 3, + [[sysObjectID, 0], [sysDescr, 0], [sysUpTime, 0]], + Get, + fun(X) -> + PostVerify(sag_verify(X, [?sysObjectID_instance, + ?sysDescr_instance, + ?sysUpTime_instance])) + + end}, + { 4, + [?sysObjectID_instance, + ?sysDescr_instance, + ?sysUpTime_instance], + Get, + fun(X) -> + PostVerify(sag_verify(X, [?sysObjectID_instance, + ?sysDescr_instance, + ?sysUpTime_instance])) + end} + ], - p("manager info when starting test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when starting test: ~n~p", [agent_info(AgentNode)]), + p("manager info when starting test: ~n~p", [MgrInfo()]), + p("agent info when starting test: ~n~p", [AgentInfo()]), ?line ok = async_exec(Requests, []), - p("manager info when ending test: ~n~p", [mgr_info(MgrNode)]), - p("agent info when ending test: ~n~p", [agent_info(AgentNode)]), + p("manager info when ending test: ~n~p", [MgrInfo()]), + p("agent info when ending test: ~n~p", [AgentInfo()]), ok. @@ -1585,6 +1730,36 @@ async_g_exec2(Node, TargetName, Oids) -> %%====================================================================== +simple_async_get3(doc) -> + ["Simple (async) get-request - Version 3 API (TargetName and send-opts)"]; +simple_async_get3(suite) -> []; +simple_async_get3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, sag3), + p("starting with Config: ~p~n", [Config]), + MgrNode = ?config(manager_node, Config), + AgentNode = ?config(agent_node, Config), + TargetName = ?config(manager_agent_target_name, Config), + Self = self(), + Msg = simple_async_get3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + Get = fun(Oids) -> async_g_exec3(MgrNode, TargetName, Oids, SendOpts) end, + PostVerify = fun(ok) -> receive Msg -> ok end; + (Error) -> Error + end, + do_simple_async_sync_get2(Config, MgrNode, AgentNode, Get, PostVerify). + +async_g_exec3(Node, TargetName, Oids, SendOpts) -> + mgr_user_async_get2(Node, TargetName, Oids, SendOpts). + + +%%====================================================================== + simple_sync_get_next1(doc) -> ["Simple (sync) get_next-request - " "Old style (Addr & Port)"]; simple_sync_get_next1(suite) -> []; @@ -1722,23 +1897,33 @@ check_ssgn_vbs([Vb|_], [E|_]) -> %%====================================================================== -simple_sync_get_next2(doc) -> ["Simple (sync) get_next-request - " - "New style (TargetName)"]; +simple_sync_get_next2(doc) -> + ["Simple (sync) get_next-request - Version 2 API (TargetName)"]; simple_sync_get_next2(suite) -> []; simple_sync_get_next2(Config) when is_list(Config) -> process_flag(trap_exit, true), - put(tname, ssgn), + put(tname, ssgn2), p("starting with Config: ~p~n", [Config]), - MgrNode = ?config(manager_node, Config), - AgentNode = ?config(agent_node, Config), + GetNext = fun(Node, TargetName, Oids) -> + mgr_user_sync_get_next(Node, TargetName, Oids) + end, + PostVerify = fun(Res) -> Res end, + do_simple_sync_get_next2(Config, GetNext, PostVerify). + +do_simple_sync_get_next2(Config, GetNext, PostVerify) + when is_function(GetNext, 3) andalso is_function(PostVerify, 1) -> + + MgrNode = ?config(manager_node, Config), + AgentNode = ?config(agent_node, Config), TargetName = ?config(manager_agent_target_name, Config), %% -- 1 -- Oids01 = [[1,3,7,1]], VF01 = fun(X) -> verify_ssgn_reply1(X, [{[1,3,7,1],endOfMibView}]) end, ?line ok = do_simple_get_next(1, - MgrNode, TargetName, Oids01, VF01), + MgrNode, TargetName, Oids01, VF01, + GetNext, PostVerify), ?line ok = mgr_user_load_mib(MgrNode, std_mib()), @@ -1748,7 +1933,8 @@ simple_sync_get_next2(Config) when is_list(Config) -> verify_ssgn_reply1(X, [?sysDescr_instance, endOfMibView]) end, ?line ok = do_simple_get_next(2, - MgrNode, TargetName, Oids02, VF02), + MgrNode, TargetName, Oids02, VF02, + GetNext, PostVerify), Test2Mib = test2_mib(Config), ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), @@ -1761,7 +1947,8 @@ simple_sync_get_next2(Config) when is_list(Config) -> verify_ssgn_reply1(X, [{fl([TCnt2,2]), 100}]) end, ?line ok = do_simple_get_next(3, - MgrNode, TargetName, Oids03, VF03), + MgrNode, TargetName, Oids03, VF03, + GetNext, PostVerify), %% -- 4 -- Oids04 = [[TCnt2, 2]], @@ -1769,7 +1956,8 @@ simple_sync_get_next2(Config) when is_list(Config) -> verify_ssgn_reply1(X, [{fl([TCnt2,2]), endOfMibView}]) end, ?line ok = do_simple_get_next(4, - MgrNode, TargetName, Oids04, VF04), + MgrNode, TargetName, Oids04, VF04, + GetNext, PostVerify), %% -- 5 -- ?line {ok, [TGenErr1|_]} = mgr_user_name_to_oid(MgrNode, tGenErr1), @@ -1778,7 +1966,8 @@ simple_sync_get_next2(Config) when is_list(Config) -> verify_ssgn_reply2(X, {genErr, 1, [TGenErr1]}) end, ?line ok = do_simple_get_next(5, - MgrNode, TargetName, Oids05, VF05), + MgrNode, TargetName, Oids05, VF05, + GetNext, PostVerify), %% -- 6 -- ?line {ok, [TGenErr2|_]} = mgr_user_name_to_oid(MgrNode, tGenErr2), @@ -1787,7 +1976,8 @@ simple_sync_get_next2(Config) when is_list(Config) -> verify_ssgn_reply2(X, {genErr, 1, [TGenErr2]}) end, ?line ok = do_simple_get_next(6, - MgrNode, TargetName, Oids06, VF06), + MgrNode, TargetName, Oids06, VF06, + GetNext, PostVerify), %% -- 7 -- ?line {ok, [TGenErr3|_]} = mgr_user_name_to_oid(MgrNode, tGenErr3), @@ -1797,7 +1987,8 @@ simple_sync_get_next2(Config) when is_list(Config) -> [?sysDescr, TGenErr3]}) end, ?line ok = do_simple_get_next(7, - MgrNode, TargetName, Oids07, VF07), + MgrNode, TargetName, Oids07, VF07, + GetNext, PostVerify), %% -- 8 -- ?line {ok, [TTooBig|_]} = mgr_user_name_to_oid(MgrNode, tTooBig), @@ -1806,18 +1997,19 @@ simple_sync_get_next2(Config) when is_list(Config) -> verify_ssgn_reply2(X, {tooBig, 0, []}) end, ?line ok = do_simple_get_next(8, - MgrNode, TargetName, Oids08, VF08), + MgrNode, TargetName, Oids08, VF08, + GetNext, PostVerify), ok. -do_simple_get_next(N, Node, TargetName, Oids, Verify) -> +do_simple_get_next(N, Node, TargetName, Oids, Verify, GetNext, PostVerify) -> p("issue get-next command ~w", [N]), - case mgr_user_sync_get_next(Node, TargetName, Oids) of + case GetNext(Node, TargetName, Oids) of {ok, Reply, Rem} -> ?DBG("get-next ok:" "~n Reply: ~p" "~n Rem: ~w", [Reply, Rem]), - Verify(Reply); + PostVerify(Verify(Reply)); Error -> {error, {unexpected_reply, Error}} @@ -1826,6 +2018,33 @@ do_simple_get_next(N, Node, TargetName, Oids, Verify) -> %%====================================================================== +simple_sync_get_next3(doc) -> + ["Simple (sync) get_next-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_sync_get_next3(suite) -> []; +simple_sync_get_next3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, ssgn3), + p("starting with Config: ~p~n", [Config]), + Self = self(), + Msg = simple_sync_get_next3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + GetNext = fun(Node, TargetName, Oids) -> + mgr_user_sync_get_next2(Node, TargetName, Oids, SendOpts) + end, + PostVerify = fun(ok) -> receive Msg -> ok end; + (Error) -> Error + end, + do_simple_sync_get_next2(Config, GetNext, PostVerify). + + +%%====================================================================== + simple_async_get_next1(doc) -> ["Simple (async) get_next-request - " "Old style (Addr & Port)"]; simple_async_get_next1(suite) -> []; @@ -1923,8 +2142,8 @@ async_gn_exec1(Node, Addr, Port, Oids) -> %%====================================================================== -simple_async_get_next2(doc) -> ["Simple (async) get_next-request - " - "New style (TargetName)"]; +simple_async_get_next2(doc) -> + ["Simple (async) get_next-request - Version 2 API (TargetName)"]; simple_async_get_next2(suite) -> []; simple_async_get_next2(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -1939,11 +2158,14 @@ simple_async_get_next2(Config) when is_list(Config) -> Test2Mib = test2_mib(Config), ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), ?line ok = agent_load_mib(AgentNode, Test2Mib), - - Exec = fun(X) -> - async_gn_exec2(MgrNode, TargetName, X) - end, - + GetNext = fun(Oids) -> + async_gn_exec2(MgrNode, TargetName, Oids) + end, + PostVerify = fun(Res) -> Res end, + do_simple_async_get_next2(MgrNode, AgentNode, GetNext, PostVerify). + +do_simple_async_get_next2(MgrNode, AgentNode, GetNext, PostVerify) + when is_function(GetNext, 1) andalso is_function(PostVerify, 1) -> ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), ?line {ok, [TGenErr1|_]} = mgr_user_name_to_oid(MgrNode, tGenErr1), ?line {ok, [TGenErr2|_]} = mgr_user_name_to_oid(MgrNode, tGenErr2), @@ -1954,51 +2176,60 @@ simple_async_get_next2(Config) when is_list(Config) -> [ {1, [[1,3,7,1]], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply1(X, [{[1,3,7,1], endOfMibView}]) + PostVerify( + verify_ssgn_reply1(X, [{[1,3,7,1], endOfMibView}])) + end}, {2, [[sysDescr], [1,3,7,1]], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply1(X, [?sysDescr_instance, endOfMibView]) + PostVerify( + verify_ssgn_reply1(X, [?sysDescr_instance, endOfMibView])) end}, {3, [[TCnt2, 1]], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply1(X, [{fl([TCnt2,2]), 100}]) + PostVerify( + verify_ssgn_reply1(X, [{fl([TCnt2,2]), 100}])) end}, {4, [[TCnt2, 2]], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply1(X, [{fl([TCnt2,2]), endOfMibView}]) + PostVerify( + verify_ssgn_reply1(X, [{fl([TCnt2,2]), endOfMibView}])) end}, {5, [TGenErr1], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr1]}) + PostVerify( + verify_ssgn_reply2(X, {genErr, 1, [TGenErr1]})) end}, {6, [TGenErr2], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply2(X, {genErr, 1, [TGenErr2]}) + PostVerify( + verify_ssgn_reply2(X, {genErr, 1, [TGenErr2]})) end}, {7, [[sysDescr], TGenErr3], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply2(X, {genErr, 2, [TGenErr3]}) + PostVerify( + verify_ssgn_reply2(X, {genErr, 2, [TGenErr3]})) end}, {8, [TTooBig], - Exec, + GetNext, fun(X) -> - verify_ssgn_reply2(X, {tooBig, 0, []}) + PostVerify( + verify_ssgn_reply2(X, {tooBig, 0, []})) end} ], @@ -2019,6 +2250,48 @@ async_gn_exec2(Node, TargetName, Oids) -> %%====================================================================== +simple_async_get_next3(doc) -> + ["Simple (async) get_next-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_async_get_next3(suite) -> []; +simple_async_get_next3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, ssgn2), + p("starting with Config: ~p~n", [Config]), + + MgrNode = ?config(manager_node, Config), + AgentNode = ?config(agent_node, Config), + TargetName = ?config(manager_agent_target_name, Config), + + ?line ok = mgr_user_load_mib(MgrNode, std_mib()), + Test2Mib = test2_mib(Config), + ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), + ?line ok = agent_load_mib(AgentNode, Test2Mib), + + Self = self(), + Msg = simple_async_get_next3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + + GetNext = fun(Oids) -> + async_gn_exec3(MgrNode, TargetName, Oids, SendOpts) + end, + PostVerify = fun(ok) -> receive Msg -> ok end; + (Error) -> Error + end, + + do_simple_async_get_next2(MgrNode, AgentNode, GetNext, PostVerify). + +async_gn_exec3(Node, TargetName, Oids, SendOpts) -> + mgr_user_async_get_next2(Node, TargetName, Oids, SendOpts). + + +%%====================================================================== + simple_sync_set1(doc) -> ["Simple (sync) set-request - " "Old style (Addr & Port)"]; simple_sync_set1(suite) -> []; @@ -2088,14 +2361,25 @@ value_of_vavs([{_Oid, Val}|VAVs], Acc) -> %%====================================================================== -simple_sync_set2(doc) -> ["Simple (sync) set-request - New style (TargetName)"]; +simple_sync_set2(doc) -> + ["Simple (sync) set-request - Version 2 API (TargetName)"]; simple_sync_set2(suite) -> []; simple_sync_set2(Config) when is_list(Config) -> process_flag(trap_exit, true), put(tname, sss2), p("starting with Config: ~p~n", [Config]), - Node = ?config(manager_node, Config), + Set = fun(Node, TargetName, VAVs) -> + mgr_user_sync_set(Node, TargetName, VAVs) + end, + PostVerify = fun() -> ok end, + + do_simple_sync_set2(Config, Set, PostVerify). + +do_simple_sync_set2(Config, Set, PostVerify) + when is_function(Set, 3) andalso is_function(PostVerify, 0) -> + + Node = ?config(manager_node, Config), TargetName = ?config(manager_agent_target_name, Config), p("issue set-request without loading the mib"), @@ -2105,7 +2389,7 @@ simple_sync_set2(Config) when is_list(Config) -> {?sysName_instance, s, Val11}, {?sysLocation_instance, s, Val12} ], - ?line ok = do_simple_set2(Node, TargetName, VAVs1), + ?line ok = do_simple_set2(Node, TargetName, VAVs1, Set, PostVerify), p("issue set-request after first loading the mibs"), ?line ok = mgr_user_load_mib(Node, std_mib()), @@ -2115,12 +2399,12 @@ simple_sync_set2(Config) when is_list(Config) -> {[sysName, 0], Val21}, {[sysLocation, 0], Val22} ], - ?line ok = do_simple_set2(Node, TargetName, VAVs2), + ?line ok = do_simple_set2(Node, TargetName, VAVs2, Set, PostVerify), ok. -do_simple_set2(Node, TargetName, VAVs) -> +do_simple_set2(Node, TargetName, VAVs, Set, PostVerify) -> [SysName, SysLoc] = value_of_vavs(VAVs), - ?line {ok, Reply, Rem} = mgr_user_sync_set(Node, TargetName, VAVs), + ?line {ok, Reply, Rem} = Set(Node, TargetName, VAVs), ?DBG("~n Reply: ~p" "~n Rem: ~w", [Reply, Rem]), @@ -2133,7 +2417,7 @@ do_simple_set2(Node, TargetName, VAVs) -> value = SysName}, #varbind{oid = ?sysLocation_instance, value = SysLoc}]} -> - ok; + PostVerify(); {noError, 0, Vbs} -> {error, {unexpected_vbs, Vbs}}; Else -> @@ -2145,6 +2429,33 @@ do_simple_set2(Node, TargetName, VAVs) -> %%====================================================================== +simple_sync_set3(doc) -> + ["Simple (sync) set-request - Version 3 API (TargetName with send-opts)"]; +simple_sync_set3(suite) -> []; +simple_sync_set3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, sss3), + p("starting with Config: ~p~n", [Config]), + + Self = self(), + Msg = simple_sync_set3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + + Set = fun(Node, TargetName, VAVs) -> + mgr_user_sync_set2(Node, TargetName, VAVs, SendOpts) + end, + PostVerify = fun() -> receive Msg -> ok end end, + + do_simple_sync_set2(Config, Set, PostVerify). + + +%%====================================================================== + simple_async_set1(doc) -> ["Simple (async) set-request - " "Old style (Addr & Port)"]; simple_async_set1(suite) -> []; @@ -2237,8 +2548,8 @@ sas_verify_vbs([Vb|_], [E|_]) -> %%====================================================================== -simple_async_set2(doc) -> ["Simple (async) set-request - " - "New style (TargetName)"]; +simple_async_set2(doc) -> + ["Simple (async) set-request - Version 2 API (TargetName)"]; simple_async_set2(suite) -> []; simple_async_set2(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -2254,31 +2565,40 @@ simple_async_set2(Config) when is_list(Config) -> ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), ?line ok = agent_load_mib(AgentNode, Test2Mib), - Exec = fun(X) -> - async_s_exec2(MgrNode, TargetName, X) - end, + Set = + fun(Oids) -> + async_s_exec2(MgrNode, TargetName, Oids) + end, + PostVerify = fun(Res) -> Res end, + + do_simple_async_set2(MgrNode, AgentNode, Set, PostVerify). +do_simple_async_set2(MgrNode, AgentNode, Set, PostVerify) -> Requests = [ {1, [{?sysName_instance, s, "Arne Anka"}], - Exec, + Set, fun(X) -> - sas_verify(X, [?sysName_instance]) + PostVerify(sas_verify(X, [?sysName_instance])) end}, {2, [{?sysLocation_instance, s, "Stockholm"}, {?sysName_instance, s, "Arne Anka"}], - Exec, + Set, fun(X) -> - sas_verify(X, [?sysLocation_instance, ?sysName_instance]) + PostVerify(sas_verify(X, + [?sysLocation_instance, + ?sysName_instance])) end}, {3, [{[sysName, 0], "Gothenburg"}, {[sysLocation, 0], "Sune Anka"}], - Exec, + Set, fun(X) -> - sas_verify(X, [?sysName_instance, ?sysLocation_instance]) + PostVerify(sas_verify(X, + [?sysName_instance, + ?sysLocation_instance])) end} ], @@ -2299,6 +2619,48 @@ async_s_exec2(Node, TargetName, VAVs) -> %%====================================================================== +simple_async_set3(doc) -> + ["Simple (async) set-request - Version 3 API (TargetName with send-opts)"]; +simple_async_set3(suite) -> []; +simple_async_set3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, sas3), + p("starting with Config: ~p~n", [Config]), + + MgrNode = ?config(manager_node, Config), + AgentNode = ?config(agent_node, Config), + TargetName = ?config(manager_agent_target_name, Config), + + ?line ok = mgr_user_load_mib(MgrNode, std_mib()), + Test2Mib = test2_mib(Config), + ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), + ?line ok = agent_load_mib(AgentNode, Test2Mib), + + Self = self(), + Msg = simple_async_set3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + + Set = + fun(Oids) -> + async_s_exec3(MgrNode, TargetName, Oids, SendOpts) + end, + PostVerify = fun(ok) -> receive Msg -> ok end; + (Res) -> Res + end, + + do_simple_async_set2(MgrNode, AgentNode, Set, PostVerify). + +async_s_exec3(Node, TargetName, VAVs, SendOpts) -> + mgr_user_async_set2(Node, TargetName, VAVs, SendOpts). + + +%%====================================================================== + simple_sync_get_bulk1(doc) -> ["Simple (sync) get_bulk-request - " "Old style (Addr & Port)"]; simple_sync_get_bulk1(suite) -> []; @@ -2470,8 +2832,8 @@ check_ssgb_vbs([R|_], [E|_]) -> %%====================================================================== -simple_sync_get_bulk2(doc) -> ["Simple (sync) get_bulk-request - " - "New style (TargetName)"]; +simple_sync_get_bulk2(doc) -> + ["Simple (sync) get_bulk-request - Version 2 API (TargetName)"]; simple_sync_get_bulk2(suite) -> []; simple_sync_get_bulk2(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -2482,20 +2844,33 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> AgentNode = ?config(agent_node, Config), TargetName = ?config(manager_agent_target_name, Config), + GetBulk = + fun(NonRep, MaxRep, Oids) -> + mgr_user_sync_get_bulk(MgrNode, TargetName, + NonRep, MaxRep, Oids) + end, + PostVerify = fun(Res) -> Res end, + + do_simple_sync_get_bulk2(Config, MgrNode, AgentNode, GetBulk, PostVerify). + +do_simple_sync_get_bulk2(Config, MgrNode, AgentNode, GetBulk, PostVerify) -> %% -- 1 -- ?line ok = do_simple_get_bulk2(1, - MgrNode, TargetName, 1, 1, [], - fun verify_ssgb_reply1/1), + 1, 1, [], + fun verify_ssgb_reply1/1, + GetBulk, PostVerify), %% -- 2 -- ?line ok = do_simple_get_bulk2(2, - MgrNode, TargetName, -1, 1, [], - fun verify_ssgb_reply1/1), + -1, 1, [], + fun verify_ssgb_reply1/1, + GetBulk, PostVerify), %% -- 3 -- ?line ok = do_simple_get_bulk2(3, - MgrNode, TargetName, -1, -1, [], - fun verify_ssgb_reply1/1), + -1, -1, [], + fun verify_ssgb_reply1/1, + GetBulk, PostVerify), ?line ok = mgr_user_load_mib(MgrNode, std_mib()), %% -- 4 -- @@ -2503,13 +2878,13 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView]) end, ?line ok = do_simple_get_bulk2(4, - MgrNode, TargetName, - 2, 0, [[sysDescr],[1,3,7,1]], VF04), + 2, 0, [[sysDescr],[1,3,7,1]], VF04, + GetBulk, PostVerify), %% -- 5 -- ?line ok = do_simple_get_bulk2(5, - MgrNode, TargetName, - 1, 2, [[sysDescr],[1,3,7,1]], VF04), + 1, 2, [[sysDescr],[1,3,7,1]], VF04, + GetBulk, PostVerify), %% -- 6 -- VF06 = fun(X) -> @@ -2518,8 +2893,8 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> ?sysObjectID_instance, endOfMibView]) end, ?line ok = do_simple_get_bulk2(6, - MgrNode, TargetName, - 0, 2, [[sysDescr],[1,3,7,1]], VF06), + 0, 2, [[sysDescr],[1,3,7,1]], VF06, + GetBulk, PostVerify), %% -- 7 -- VF07 = fun(X) -> @@ -2529,10 +2904,10 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> ?sysObjectID_instance, endOfMibView]) end, ?line ok = do_simple_get_bulk2(7, - MgrNode, TargetName, 2, 2, [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]], - VF07), + VF07, + GetBulk, PostVerify), Test2Mib = test2_mib(Config), ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), @@ -2545,17 +2920,17 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> ?sysDescr_instance]) end, ?line ok = do_simple_get_bulk2(8, - MgrNode, TargetName, 1, 2, [[sysDescr],[sysDescr],[tTooBig]], - VF08), + VF08, + GetBulk, PostVerify), %% -- 9 -- ?line ok = do_simple_get_bulk2(9, - MgrNode, TargetName, 1, 12, [[tDescr2], [sysDescr]], - fun verify_ssgb_reply1/1), + fun verify_ssgb_reply1/1, + GetBulk, PostVerify), %% -- 10 -- VF10 = fun(X) -> @@ -2566,13 +2941,13 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> {?sysDescr, 'NULL'}]) end, ?line ok = do_simple_get_bulk2(10, - MgrNode, TargetName, 2, 2, [[sysDescr], [sysObjectID], [tGenErr1], [sysDescr]], - VF10), + VF10, + GetBulk, PostVerify), %% -- 11 -- ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), @@ -2583,20 +2958,25 @@ simple_sync_get_bulk2(Config) when is_list(Config) -> {fl([TCnt2,2]), endOfMibView}]) end, ?line ok = do_simple_get_bulk2(11, - MgrNode, TargetName, 0, 2, - [[TCnt2, 1]], VF11), + [[TCnt2, 1]], VF11, + GetBulk, PostVerify), ok. -do_simple_get_bulk2(N, Node, TargetName, NonRep, MaxRep, Oids, Verify) -> +do_simple_get_bulk2(N, + NonRep, MaxRep, Oids, + Verify, GetBulk, PostVerify) + when is_function(Verify, 1) andalso + is_function(GetBulk, 3) andalso + is_function(PostVerify) -> p("issue get-bulk command ~w", [N]), - case mgr_user_sync_get_bulk(Node, TargetName, NonRep, MaxRep, Oids) of + case GetBulk(NonRep, MaxRep, Oids) of {ok, Reply, Rem} -> ?DBG("get-bulk ok:" "~n Reply: ~p" "~n Rem: ~w", [Reply, Rem]), - Verify(Reply); + PostVerify(Verify(Reply)); Error -> {error, {unexpected_reply, Error}} @@ -2605,6 +2985,42 @@ do_simple_get_bulk2(N, Node, TargetName, NonRep, MaxRep, Oids, Verify) -> %%====================================================================== +simple_sync_get_bulk3(doc) -> + ["Simple (sync) get_bulk-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_sync_get_bulk3(suite) -> []; +simple_sync_get_bulk3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, ssgb3), + p("starting with Config: ~p~n", [Config]), + + MgrNode = ?config(manager_node, Config), + AgentNode = ?config(agent_node, Config), + TargetName = ?config(manager_agent_target_name, Config), + + Self = self(), + Msg = simple_async_set3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + + GetBulk = + fun(NonRep, MaxRep, Oids) -> + mgr_user_sync_get_bulk2(MgrNode, TargetName, + NonRep, MaxRep, Oids, SendOpts) + end, + PostVerify = fun(ok) -> receive Msg -> ok end; + (Res) -> Res + end, + + do_simple_sync_get_bulk2(Config, MgrNode, AgentNode, GetBulk, PostVerify). + + +%%====================================================================== + simple_async_get_bulk1(doc) -> ["Simple (async) get_bulk-request - " "Old style (Addr & Port)"]; simple_async_get_bulk1(suite) -> []; @@ -2748,8 +3164,8 @@ async_gb_exec1(Node, Addr, Port, {NR, MR, Oids}) -> %%====================================================================== -simple_async_get_bulk2(doc) -> ["Simple (async) get_bulk-request - " - "New style (TargetName)"]; +simple_async_get_bulk2(doc) -> + ["Simple (async) get_bulk-request - Version 2 API (TargetName)"]; simple_async_get_bulk2(suite) -> []; simple_async_get_bulk2(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -2765,111 +3181,122 @@ simple_async_get_bulk2(Config) when is_list(Config) -> ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), ?line ok = agent_load_mib(AgentNode, Test2Mib), - Exec = fun(Data) -> - async_gb_exec2(MgrNode, TargetName, Data) - end, + GetBulk = + fun(Data) -> + async_gb_exec2(MgrNode, TargetName, Data) + end, + PostVerify = fun(Res) -> Res end, + do_simple_async_get_bulk2(MgrNode, AgentNode, GetBulk, PostVerify). + +do_simple_async_get_bulk2(MgrNode, AgentNode, GetBulk, PostVerify) -> %% We re-use the verification functions from the ssgb test-case VF04 = fun(X) -> - verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView]) + PostVerify( + verify_ssgb_reply2(X, [?sysDescr_instance, endOfMibView])) end, VF06 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) + PostVerify( + verify_ssgb_reply2(X, + [?sysDescr_instance, endOfMibView, + ?sysObjectID_instance, endOfMibView])) end, VF07 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, endOfMibView, - ?sysDescr_instance, endOfMibView, - ?sysObjectID_instance, endOfMibView]) + PostVerify( + verify_ssgb_reply2(X, + [?sysDescr_instance, endOfMibView, + ?sysDescr_instance, endOfMibView, + ?sysObjectID_instance, endOfMibView])) end, VF08 = fun(X) -> - verify_ssgb_reply2(X, - [?sysDescr_instance, - ?sysDescr_instance]) + PostVerify( + verify_ssgb_reply2(X, + [?sysDescr_instance, + ?sysDescr_instance])) end, VF10 = fun(X) -> - verify_ssgb_reply3(X, - [{?sysDescr, 'NULL'}, - {?sysObjectID, 'NULL'}, - {?tGenErr1, 'NULL'}, - {?sysDescr, 'NULL'}]) + PostVerify( + verify_ssgb_reply3(X, + [{?sysDescr, 'NULL'}, + {?sysObjectID, 'NULL'}, + {?tGenErr1, 'NULL'}, + {?sysDescr, 'NULL'}])) end, ?line {ok, [TCnt2|_]} = mgr_user_name_to_oid(MgrNode, tCnt2), VF11 = fun(X) -> - verify_ssgb_reply2(X, - [{fl([TCnt2,2]), 100}, - {fl([TCnt2,2]), endOfMibView}]) + PostVerify( + verify_ssgb_reply2(X, + [{fl([TCnt2,2]), 100}, + {fl([TCnt2,2]), endOfMibView}])) end, Requests = [ { 1, {1, 1, []}, - Exec, - fun verify_ssgb_reply1/1}, + GetBulk, + fun(X) -> PostVerify(verify_ssgb_reply1(X)) end}, { 2, {-1, 1, []}, - Exec, - fun verify_ssgb_reply1/1}, + GetBulk, + fun(X) -> PostVerify(verify_ssgb_reply1(X)) end}, { 3, {-1, -1, []}, - Exec, - fun verify_ssgb_reply1/1}, + GetBulk, + fun(X) -> PostVerify(verify_ssgb_reply1(X)) end}, { 4, {2, 0, [[sysDescr],[1,3,7,1]]}, - Exec, + GetBulk, VF04}, { 5, {1, 2, [[sysDescr],[1,3,7,1]]}, - Exec, + GetBulk, VF04}, { 6, {0, 2, [[sysDescr],[1,3,7,1]]}, - Exec, + GetBulk, VF06}, { 7, {2, 2, [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]]}, - Exec, + GetBulk, VF07}, { 8, {1, 2, [[sysDescr],[sysDescr],[tTooBig]]}, - Exec, + GetBulk, VF08}, { 9, {1, 12, [[tDescr2], [sysDescr]]}, - Exec, - fun verify_ssgb_reply1/1}, + GetBulk, + fun(X) -> PostVerify(verify_ssgb_reply1(X)) end}, {10, {2, 2, [[sysDescr],[sysObjectID], [tGenErr1],[sysDescr]]}, - Exec, + GetBulk, VF10}, {11, {0, 2, [[TCnt2, 1]]}, - Exec, + GetBulk, VF11}, {12, {2, 0, [[sysDescr],[1,3,7,1]]}, - Exec, + GetBulk, VF04}, {13, {1, 12, [[tDescr2], [sysDescr]]}, - Exec, - fun verify_ssgb_reply1/1}, + GetBulk, + fun(X) -> PostVerify(verify_ssgb_reply1(X)) end}, {14, {2, 2, [[sysDescr],[sysObjectID],[tGenErr1],[sysDescr]]}, - Exec, + GetBulk, VF10}, {15, {0, 2, [[TCnt2, 1]]}, - Exec, + GetBulk, VF11}, {16, {2, 2, [[sysDescr],[1,3,7,1],[sysDescr],[1,3,7,1]]}, - Exec, + GetBulk, VF07}, {17, {2, 2, [[sysDescr],[sysObjectID], [tGenErr1],[sysDescr]]}, - Exec, + GetBulk, VF10} ], @@ -2890,6 +3317,49 @@ async_gb_exec2(Node, TargetName, {NR, MR, Oids}) -> %%====================================================================== +simple_async_get_bulk3(doc) -> + ["Simple (async) get_bulk-request - " + "Version 3 API (TargetName with send-opts)"]; +simple_async_get_bulk3(suite) -> []; +simple_async_get_bulk3(Config) when is_list(Config) -> + process_flag(trap_exit, true), + put(tname, sagb3), + p("starting with Config: ~p~n", [Config]), + + MgrNode = ?config(manager_node, Config), + AgentNode = ?config(agent_node, Config), + TargetName = ?config(manager_agent_target_name, Config), + + ?line ok = mgr_user_load_mib(MgrNode, std_mib()), + Test2Mib = test2_mib(Config), + ?line ok = mgr_user_load_mib(MgrNode, Test2Mib), + ?line ok = agent_load_mib(AgentNode, Test2Mib), + + Self = self(), + Msg = simple_async_get_bulk3, + Fun = fun() -> Self ! Msg end, + Extra = {?SNMPM_EXTRA_INFO_TAG, Fun}, + SendOpts = + [ + {extra, Extra} + ], + + GetBulk = + fun(Data) -> + async_gb_exec3(MgrNode, TargetName, Data, SendOpts) + end, + PostVerify = fun(ok) -> receive Msg -> ok end; + (Res) -> Res + end, + + do_simple_async_get_bulk2(MgrNode, AgentNode, GetBulk, PostVerify). + +async_gb_exec3(Node, TargetName, {NR, MR, Oids}, SendOpts) -> + mgr_user_async_get_bulk2(Node, TargetName, NR, MR, Oids, SendOpts). + + +%%====================================================================== + misc_async1(doc) -> ["Misc (async) request(s) - " "Old style (Addr & Port)"]; misc_async1(suite) -> []; @@ -3079,8 +3549,8 @@ misc_async1(Config) when is_list(Config) -> %%====================================================================== -misc_async2(doc) -> ["Misc (async) request(s) - " - "New style (TargetName)"]; +misc_async2(doc) -> + ["Misc (async) request(s) - Version 2 API (TargetName)"]; misc_async2(suite) -> []; misc_async2(Config) when is_list(Config) -> process_flag(trap_exit, true), @@ -4440,7 +4910,7 @@ otp8395_1(suite) -> []; otp8395_1(Config) when is_list(Config) -> process_flag(trap_exit, true), put(tname, otp8395_1), - do_simple_get(Config). + do_simple_sync_get2(Config). %%====================================================================== @@ -4986,6 +5456,9 @@ mgr_user_sync_get(Node, Addr_or_TargetName, Oids) -> mgr_user_sync_get(Node, Addr, Port, Oids) -> rcall(Node, snmp_manager_user, sync_get, [Addr, Port, Oids]). +mgr_user_sync_get2(Node, TargetName, Oids, SendOpts) -> + rcall(Node, snmp_manager_user, sync_get2, [TargetName, Oids, SendOpts]). + %% mgr_user_async_get(Node, Oids) -> %% mgr_user_async_get(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_async_get(Node, Addr_or_TargetName, Oids) -> @@ -4993,6 +5466,9 @@ mgr_user_async_get(Node, Addr_or_TargetName, Oids) -> mgr_user_async_get(Node, Addr, Port, Oids) -> rcall(Node, snmp_manager_user, async_get, [Addr, Port, Oids]). +mgr_user_async_get2(Node, TargetName, Oids, SendOpts) -> + rcall(Node, snmp_manager_user, async_get2, [TargetName, Oids, SendOpts]). + %% mgr_user_sync_get_next(Node, Oids) -> %% mgr_user_sync_get_next(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_sync_get_next(Node, Addr_or_TargetName, Oids) -> @@ -5000,6 +5476,9 @@ mgr_user_sync_get_next(Node, Addr_or_TargetName, Oids) -> mgr_user_sync_get_next(Node, Addr, Port, Oids) -> rcall(Node, snmp_manager_user, sync_get_next, [Addr, Port, Oids]). +mgr_user_sync_get_next2(Node, TargetName, Oids, SendOpts) -> + rcall(Node, snmp_manager_user, sync_get_next2, [TargetName, Oids, SendOpts]). + %% mgr_user_async_get_next(Node, Oids) -> %% mgr_user_async_get_next(Node, ?LOCALHOST(), ?AGENT_PORT, Oids). mgr_user_async_get_next(Node, Addr_or_TargetName, Oids) -> @@ -5007,6 +5486,9 @@ mgr_user_async_get_next(Node, Addr_or_TargetName, Oids) -> mgr_user_async_get_next(Node, Addr, Port, Oids) -> rcall(Node, snmp_manager_user, async_get_next, [Addr, Port, Oids]). +mgr_user_async_get_next2(Node, TargetName, Oids, SendOpts) -> + rcall(Node, snmp_manager_user, async_get_next2, [TargetName, Oids, SendOpts]). + %% mgr_user_sync_set(Node, VAV) -> %% mgr_user_sync_set(Node, ?LOCALHOST(), ?AGENT_PORT, VAV). mgr_user_sync_set(Node, Addr_or_TargetName, VAV) -> @@ -5014,6 +5496,9 @@ mgr_user_sync_set(Node, Addr_or_TargetName, VAV) -> mgr_user_sync_set(Node, Addr, Port, VAV) -> rcall(Node, snmp_manager_user, sync_set, [Addr, Port, VAV]). +mgr_user_sync_set2(Node, TargetName, VAV, SendOpts) -> + rcall(Node, snmp_manager_user, sync_set2, [TargetName, VAV, SendOpts]). + %% mgr_user_async_set(Node, VAV) -> %% mgr_user_async_set(Node, ?LOCALHOST(), ?AGENT_PORT, VAV). mgr_user_async_set(Node, Addr_or_TargetName, VAV) -> @@ -5021,26 +5506,37 @@ mgr_user_async_set(Node, Addr_or_TargetName, VAV) -> mgr_user_async_set(Node, Addr, Port, VAV) -> rcall(Node, snmp_manager_user, async_set, [Addr, Port, VAV]). +mgr_user_async_set2(Node, TargetName, VAV, SendOpts) -> + rcall(Node, snmp_manager_user, async_set2, [TargetName, VAV, SendOpts]). + %% mgr_user_sync_get_bulk(Node, NonRep, MaxRep, Oids) -> %% mgr_user_sync_get_bulk(Node, ?LOCALHOST(), ?AGENT_PORT, %% NonRep, MaxRep, Oids). mgr_user_sync_get_bulk(Node, Addr_or_TargetName, NonRep, MaxRep, Oids) -> rcall(Node, snmp_manager_user, sync_get_bulk, - [Addr_or_TargetName, NonRep, MaxRep, Oids]). + [Addr_or_TargetName, NonRep, MaxRep, Oids]). mgr_user_sync_get_bulk(Node, Addr, Port, NonRep, MaxRep, Oids) -> rcall(Node, snmp_manager_user, sync_get_bulk, [Addr, Port, NonRep, MaxRep, Oids]). +mgr_user_sync_get_bulk2(Node, TargetName, NonRep, MaxRep, Oids, SendOpts) -> + rcall(Node, snmp_manager_user, sync_get_bulk2, + [TargetName, NonRep, MaxRep, Oids, SendOpts]). + %% mgr_user_async_get_bulk(Node, NonRep, MaxRep, Oids) -> %% mgr_user_async_get_bulk(Node, ?LOCALHOST(), ?AGENT_PORT, %% NonRep, MaxRep, Oids). mgr_user_async_get_bulk(Node, Addr_or_TargetName, NonRep, MaxRep, Oids) -> rcall(Node, snmp_manager_user, async_get_bulk, - [Addr_or_TargetName, NonRep, MaxRep, Oids]). + [Addr_or_TargetName, NonRep, MaxRep, Oids]). mgr_user_async_get_bulk(Node, Addr, Port, NonRep, MaxRep, Oids) -> rcall(Node, snmp_manager_user, async_get_bulk, [Addr, Port, NonRep, MaxRep, Oids]). +mgr_user_async_get_bulk2(Node, TargetName, NonRep, MaxRep, Oids, SendOpts) -> + rcall(Node, snmp_manager_user, async_get_bulk2, + [TargetName, NonRep, MaxRep, Oids, SendOpts]). + mgr_user_purify_oid(Node, Oid) -> rcall(Node, snmp_manager_user, purify_oid, [Oid]). diff --git a/lib/snmp/test/snmp_manager_user.erl b/lib/snmp/test/snmp_manager_user.erl index b0e192344d..30b5dd1fc7 100644 --- a/lib/snmp/test/snmp_manager_user.erl +++ b/lib/snmp/test/snmp_manager_user.erl @@ -50,14 +50,14 @@ update_agent_info/3, update_agent_info/4, which_all_agents/0, which_own_agents/0, load_mib/1, unload_mib/1, - sync_get/1, sync_get/2, sync_get/3, - async_get/1, async_get/2, async_get/3, - sync_get_next/1, sync_get_next/2, sync_get_next/3, - async_get_next/1, async_get_next/2, async_get_next/3, - sync_set/1, sync_set/2, sync_set/3, - async_set/1, async_set/2, async_set/3, - sync_get_bulk/3, sync_get_bulk/4, sync_get_bulk/5, - async_get_bulk/3, async_get_bulk/4, async_get_bulk/5, + sync_get/1, sync_get/2, sync_get/3, sync_get2/3, + async_get/1, async_get/2, async_get/3, async_get2/3, + sync_get_next/1, sync_get_next/2, sync_get_next/3, sync_get_next2/3, + async_get_next/1, async_get_next/2, async_get_next/3, async_get_next2/3, + sync_set/1, sync_set/2, sync_set/3, sync_set2/3, + async_set/1, async_set/2, async_set/3, async_set2/3, + sync_get_bulk/3, sync_get_bulk/4, sync_get_bulk/5, sync_get_bulk2/5, + async_get_bulk/3, async_get_bulk/4, async_get_bulk/5, async_get_bulk2/5, name_to_oid/1, oid_to_name/1, purify_oid/1 ]). @@ -171,6 +171,10 @@ sync_get(Addr_or_TargetName, Oids) -> sync_get(Addr, Port, Oids) -> call({sync_get, Addr, Port, Oids}). +sync_get2(TargetName, Oids, SendOpts) -> + call({sync_get2, TargetName, Oids, SendOpts}). + + %% -- async_get(Oids) -> @@ -182,6 +186,9 @@ async_get(Addr_or_TargetName, Oids) -> async_get(Addr, Port, Oids) -> call({async_get, Addr, Port, Oids}). +async_get2(TargetName, Oids, SendOpts) -> + call({async_get2, TargetName, Oids, SendOpts}). + %% -- sync_get_next(Oids) -> @@ -193,6 +200,9 @@ sync_get_next(Addr_or_TargetName, Oids) -> sync_get_next(Addr, Port, Oids) -> call({sync_get_next, Addr, Port, Oids}). +sync_get_next2(TargetName, Oids, SendOpts) -> + call({sync_get_next2, TargetName, Oids, SendOpts}). + %% -- async_get_next(Oids) -> @@ -204,6 +214,9 @@ async_get_next(Addr_or_TargetName, Oids) -> async_get_next(Addr, Port, Oids) -> call({async_get_next, Addr, Port, Oids}). +async_get_next2(TargetName, Oids, SendOpts) -> + call({async_get_next2, TargetName, Oids, SendOpts}). + %% -- sync_set(VAV) -> @@ -215,6 +228,9 @@ sync_set(Addr_or_TargetName, VAV) -> sync_set(Addr, Port, VAV) -> call({sync_set, Addr, Port, VAV}). +sync_set2(TargetName, VAV, SendOpts) -> + call({sync_set2, TargetName, VAV, SendOpts}). + %% -- async_set(VAV) -> @@ -226,6 +242,9 @@ async_set(Addr_or_TargetName, VAV) -> async_set(Addr, Port, VAV) -> call({async_set, Addr, Port, VAV}). +async_set2(TargetName, VAV, SendOpts) -> + call({async_set2, TargetName, VAV, SendOpts}). + %% -- sync_get_bulk(NonRep, MaxRep, Oids) -> @@ -237,6 +256,9 @@ sync_get_bulk(Addr_or_TargetName, NonRep, MaxRep, Oids) -> sync_get_bulk(Addr, Port, NonRep, MaxRep, Oids) -> call({sync_get_bulk, Addr, Port, NonRep, MaxRep, Oids}). +sync_get_bulk2(TargetName, NonRep, MaxRep, Oids, SendOpts) -> + call({sync_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}). + %% -- async_get_bulk(NonRep, MaxRep, Oids) -> @@ -248,6 +270,9 @@ async_get_bulk(Addr_or_TargetName, NonRep, MaxRep, Oids) -> async_get_bulk(Addr, Port, NonRep, MaxRep, Oids) -> call({async_get_bulk, Addr, Port, NonRep, MaxRep, Oids}). +async_get_bulk2(TargetName, NonRep, MaxRep, Oids, SendOpts) -> + call({async_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}). + %% -- name_to_oid(Name) -> @@ -400,6 +425,16 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (sync) get-request -- %% + {{sync_get2, TargetName, Oids, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received sync_get2 request with" + "~n TargetName: ~p" + "~n Oids: ~p" + "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), + Res = snmpm:sync_get2(Id, TargetName, Oids, SendOpts), + reply(From, Res, Ref), + loop(S); + %% No agent specified, so send it to all of them {{sync_get, Oids}, From, Ref} -> d("loop -> received sync_get request " @@ -439,6 +474,16 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (async) get-request -- %% + {{async_get2, TargetName, Oids, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received async_get2 request with" + "~n TargetName: ~p" + "~n Oids: ~p" + "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), + Res = snmpm:async_get2(Id, TargetName, Oids, SendOpts), + reply(From, Res, Ref), + loop(S); + %% No agent specified, so send it to all of them {{async_get, Oids}, From, Ref} -> d("loop -> received async_get request"), @@ -472,6 +517,16 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (sync) get_next-request -- %% + {{sync_get_next2, TargetName, Oids, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received sync_get_next2 request with" + "~n TargetName: ~p" + "~n Oids: ~p" + "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), + Res = snmpm:sync_get_next2(Id, TargetName, Oids, SendOpts), + reply(From, Res, Ref), + loop(S); + %% No agent specified, so send it to all of them {{sync_get_next, Oids}, From, Ref} -> d("loop -> received sync_get_next request"), @@ -505,6 +560,16 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (async) get_next-request -- %% + {{async_get_next2, TargetName, Oids, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received async_get_next2 request with" + "~n TargetName: ~p" + "~n Oids: ~p" + "~n SendOpts: ~p", [TargetName, Oids, SendOpts]), + Res = snmpm:async_get_next2(Id, TargetName, Oids, SendOpts), + reply(From, Res, Ref), + loop(S); + %% No agent specified, so send it to all of them {{async_get_next, Oids}, From, Ref} -> d("loop -> received async_get_next request"), @@ -538,6 +603,16 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (sync) set-request -- %% + {{sync_set2, TargetName, VAV, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received sync_set2 request with" + "~n TargetName: ~p" + "~n VAV: ~p" + "~n SendOpts: ~p", [TargetName, VAV, SendOpts]), + Res = snmpm:sync_set2(Id, TargetName, VAV, SendOpts), + reply(From, Res, Ref), + loop(S); + {{sync_set, VAV}, From, Ref} -> d("loop -> received sync_set request"), Res = [snmpm:sync_set(Id, TargetName, VAV) || @@ -568,6 +643,16 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (async) set-request -- %% + {{async_set2, TargetName, VAV, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received async_set2 request with" + "~n TargetName: ~p" + "~n VAV: ~p" + "~n SendOpts: ~p", [TargetName, VAV, SendOpts]), + Res = snmpm:async_set2(Id, TargetName, VAV, SendOpts), + reply(From, Res, Ref), + loop(S); + {{async_set, VAV}, From, Ref} -> d("loop -> received async_set request"), Res = [snmpm:async_set(Id, TargetName, VAV) || @@ -598,6 +683,20 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (sync) get-bulk-request -- %% + {{sync_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}, From, Ref} + when is_list(TargetName) -> + d("loop -> received sync_get_bulk request with" + "~n TargetName: ~p" + "~n NonRep: ~w" + "~n MaxRep: ~w" + "~n Oids: ~p" + "~n SendOpts: ~p", + [TargetName, NonRep, MaxRep, Oids, SendOpts]), + Res = snmpm:sync_get_bulk2(Id, TargetName, + NonRep, MaxRep, Oids, SendOpts), + reply(From, Res, Ref), + loop(S); + %% No agent specified, so send it to all of them {{sync_get_bulk, NonRep, MaxRep, Oids}, From, Ref} -> d("loop -> received sync_get_bulk request with" @@ -645,6 +744,20 @@ loop(#state{parent = Parent, id = Id} = S) -> %% -- (async) get-bulk-request -- %% + {{async_get_bulk2, TargetName, NonRep, MaxRep, Oids, SendOpts}, + From, Ref} when is_list(TargetName) -> + d("loop -> received async_get_bulk2 request with" + "~n TargetName: ~p" + "~n NonRep: ~w" + "~n MaxRep: ~w" + "~n Oids: ~p" + "~n SendOpts: ~p", + [TargetName, NonRep, MaxRep, Oids, SendOpts]), + Res = snmpm:async_get_bulk2(Id, TargetName, + NonRep, MaxRep, Oids, SendOpts), + reply(From, Res, Ref), + loop(S); + %% No agent specified, so send it to all of them {{async_get_bulk, NonRep, MaxRep, Oids}, From, Ref} -> d("loop -> received async_get_bulk request with" @@ -847,7 +960,11 @@ call(Req, To) when is_integer(To) -> {error, timeout} end. -reply(Pid, Reply, Ref) -> +reply(Pid, Reply, Ref) -> + d("reply -> entry with" + "~n Pid: ~p" + "~n Reply: ~p" + "~n Ref: ~p", [Pid, Reply, Ref]), Pid ! {Reply, Ref}. cast(Msg) -> diff --git a/lib/snmp/test/snmp_pdus_test.erl b/lib/snmp/test/snmp_pdus_test.erl index ef510ad62e..197797c816 100644 --- a/lib/snmp/test/snmp_pdus_test.erl +++ b/lib/snmp/test/snmp_pdus_test.erl @@ -38,6 +38,8 @@ otp7575/1, otp8563/1, + otp9022/1, + init_per_testcase/2, end_per_testcase/2 ]). @@ -75,7 +77,7 @@ all() -> [{group, tickets}]. groups() -> - [{tickets, [], [otp7575, otp8563]}]. + [{tickets, [], [otp7575, otp8563, otp9022]}]. init_per_group(_GroupName, Config) -> Config. @@ -169,7 +171,56 @@ otp8563(Config) when is_list(Config) -> Unexpected7 -> exit({unexpected_encode_result, Unexpected7, Val7}) end, - + + ok. + + +otp9022(suite) -> []; +otp9022(doc) -> ["OTP-9022"]; +otp9022(Config) when is_list(Config) -> + Val1 = 16#7fffffff, + io:format("try encode and decode ~w~n", [Val1]), + Enc1 = snmp_pdus:enc_value('Counter32', Val1), + {{'Counter32', Val1}, []} = snmp_pdus:dec_value(Enc1), + + Val2 = Val1 + 1, + io:format("try encode and decode ~w~n", [Val2]), + Enc2 = snmp_pdus:enc_value('Counter32', Val2), + {{'Counter32', Val2}, []} = snmp_pdus:dec_value(Enc2), + + Val3 = Val2 + 1, + io:format("try encode and decode ~w~n", [Val3]), + Enc3 = snmp_pdus:enc_value('Counter32', Val3), + {{'Counter32', Val3}, []} = snmp_pdus:dec_value(Enc3), + + Val4 = 16#fffffffe, + io:format("try encode and decode ~w~n", [Val4]), + Enc4 = snmp_pdus:enc_value('Counter32', Val4), + {{'Counter32', Val4}, []} = snmp_pdus:dec_value(Enc4), + + Val5 = Val4 + 1, + io:format("try encode and decode ~w~n", [Val5]), + Enc5 = snmp_pdus:enc_value('Counter32', Val5), + {{'Counter32', Val5}, []} = snmp_pdus:dec_value(Enc5), + + Val6 = 16#ffffffff + 1, + io:format("try and fail to encode ~w~n", [Val6]), + case (catch snmp_pdus:enc_value('Counter32', Val6)) of + {'EXIT', {error, {bad_counter32, Val6}}} -> + ok; + Unexpected6 -> + exit({unexpected_encode_result, Unexpected6, Val6}) + end, + + Val7 = -1, + io:format("try and fail to encode ~w~n", [Val7]), + case (catch snmp_pdus:enc_value('Counter32', Val7)) of + {'EXIT', {error, {bad_counter32, Val7}}} -> + ok; + Unexpected7 -> + exit({unexpected_encode_result, Unexpected7, Val7}) + end, + ok. diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk index e70c97dcb8..29228fc59b 100644 --- a/lib/snmp/vsn.mk +++ b/lib/snmp/vsn.mk @@ -17,6 +17,6 @@ # # %CopyrightEnd% -SNMP_VSN = 4.19 +SNMP_VSN = 4.20 PRE_VSN = APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)" diff --git a/lib/stdlib/src/otp_internal.erl b/lib/stdlib/src/otp_internal.erl index 5c52dfcbf0..39d017d430 100644 --- a/lib/stdlib/src/otp_internal.erl +++ b/lib/stdlib/src/otp_internal.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2010. All Rights Reserved. +%% Copyright Ericsson AB 1999-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 @@ -180,6 +180,9 @@ obsolete_1(calendar, local_time_to_universal_time, 1) -> obsolete_1(rpc, safe_multi_server_call, A) when A =:= 2; A =:= 3 -> {deprecated, {rpc, multi_server_call, A}}; + +%% *** SNMP *** + obsolete_1(snmp, N, A) -> case is_snmp_agent_function(N, A) of false -> @@ -189,9 +192,100 @@ obsolete_1(snmp, N, A) -> integer_to_list(A)++" instead"} end; +obsolete_1(snmpm, agent_info, 3) -> + {deprecated, {snmpm, agent_info, 2}, "R16B"}; +obsolete_1(snmpm, update_agent_info, 5) -> + {deprecated, {snmpm, update_agent_info, 4}, "R16B"}; +obsolete_1(snmpm, g, 3) -> + {deprecated, {snmpm, sync_get, 3}, "R16B"}; +obsolete_1(snmpm, g, 4) -> + {deprecated, {snmpm, sync_get, [3,4]}, "R16B"}; +obsolete_1(snmpm, g, 5) -> + {deprecated, {snmpm, sync_get, [4,5]}, "R16B"}; +obsolete_1(snmpm, g, 6) -> + {deprecated, {snmpm, sync_get, [5,6]}, "R16B"}; +obsolete_1(snmpm, g, 7) -> + {deprecated, {snmpm, sync_get, 6}, "R16B"}; +obsolete_1(snmpm, ag, 3) -> + {deprecated, {snmpm, async_get, 3}, "R16B"}; +obsolete_1(snmpm, ag, 4) -> + {deprecated, {snmpm, async_get, [3,4]}, "R16B"}; +obsolete_1(snmpm, ag, 5) -> + {deprecated, {snmpm, async_get, [4,5]}, "R16B"}; +obsolete_1(snmpm, ag, 6) -> + {deprecated, {snmpm, async_get, [5,6]}, "R16B"}; +obsolete_1(snmpm, ag, 7) -> + {deprecated, {snmpm, async_get, 6}, "R16B"}; +obsolete_1(snmpm, gn, 3) -> + {deprecated, {snmpm, sync_get_next, 3}, "R16B"}; +obsolete_1(snmpm, gn, 4) -> + {deprecated, {snmpm, sync_get_next, [3,4]}, "R16B"}; +obsolete_1(snmpm, gn, 5) -> + {deprecated, {snmpm, sync_get_next, [4,5]}, "R16B"}; +obsolete_1(snmpm, gn, 6) -> + {deprecated, {snmpm, sync_get_next, [5,6]}, "R16B"}; +obsolete_1(snmpm, gn, 7) -> + {deprecated, {snmpm, sync_get_next, 6}, "R16B"}; +obsolete_1(snmpm, agn, 3) -> + {deprecated, {snmpm, async_get_next, 3}, "R16B"}; +obsolete_1(snmpm, agn, 4) -> + {deprecated, {snmpm, async_get_next, [3,4]}, "R16B"}; +obsolete_1(snmpm, agn, 5) -> + {deprecated, {snmpm, async_get_next, [4,5]}, "R16B"}; +obsolete_1(snmpm, agn, 6) -> + {deprecated, {snmpm, async_get_next, [5,6]}, "R16B"}; +obsolete_1(snmpm, agn, 7) -> + {deprecated, {snmpm, async_get_next, 6}, "R16B"}; +obsolete_1(snmpm, s, 3) -> + {deprecated, {snmpm, sync_set, 3}, "R16B"}; +obsolete_1(snmpm, s, 4) -> + {deprecated, {snmpm, sync_set, [3,4]}, "R16B"}; +obsolete_1(snmpm, s, 5) -> + {deprecated, {snmpm, sync_set, [4,5]}, "R16B"}; +obsolete_1(snmpm, s, 6) -> + {deprecated, {snmpm, sync_set, [5,6]}, "R16B"}; +obsolete_1(snmpm, s, 7) -> + {deprecated, {snmpm, sync_set, 6}, "R16B"}; +obsolete_1(snmpm, as, 3) -> + {deprecated, {snmpm, async_set, 3}, "R16B"}; +obsolete_1(snmpm, as, 4) -> + {deprecated, {snmpm, async_set, [3,4]}, "R16B"}; +obsolete_1(snmpm, as, 5) -> + {deprecated, {snmpm, async_set, [4,5]}, "R16B"}; +obsolete_1(snmpm, as, 6) -> + {deprecated, {snmpm, async_set, [5,6]}, "R16B"}; +obsolete_1(snmpm, as, 7) -> + {deprecated, {snmpm, async_set, 6}, "R16B"}; +obsolete_1(snmpm, gb, 5) -> + {deprecated, {snmpm, sync_get_bulk, 5}, "R16B"}; +obsolete_1(snmpm, gb, 6) -> + {deprecated, {snmpm, sync_get_bulk, [5,6]}, "R16B"}; +obsolete_1(snmpm, gb, 7) -> + {deprecated, {snmpm, sync_get_bulk, [6,7]}, "R16B"}; +obsolete_1(snmpm, gb, 8) -> + {deprecated, {snmpm, sync_get_bulk, [7,8]}, "R16B"}; +obsolete_1(snmpm, gb, 9) -> + {deprecated, {snmpm, sync_get_bulk, 8}, "R16B"}; +obsolete_1(snmpm, agb, 5) -> + {deprecated, {snmpm, async_get_bulk, 5}, "R16B"}; +obsolete_1(snmpm, agb, 6) -> + {deprecated, {snmpm, async_get_bulk, [5,6]}, "R16B"}; +obsolete_1(snmpm, agb, 7) -> + {deprecated, {snmpm, async_get_bulk, [6,7]}, "R16B"}; +obsolete_1(snmpm, agb, 8) -> + {deprecated, {snmpm, async_get_bulk, [7,8]}, "R16B"}; +obsolete_1(snmpm, agb, 9) -> + {deprecated, {snmpm, async_get_bulk, 8}, "R16B"}; + + +%% *** MEGACO *** + obsolete_1(megaco, format_versions, 1) -> {deprecated, "Deprecated; use megaco:print_version_info/0,1 instead"}; + +%% *** OS-MON-MIB *** + obsolete_1(os_mon_mib, init, 1) -> {deprecated, {os_mon_mib, load, 1}}; obsolete_1(os_mon_mib, stop, 1) -> |