aboutsummaryrefslogtreecommitdiffstats
path: root/lib/snmp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/snmp')
-rw-r--r--lib/snmp/doc/src/notes.xml53
-rw-r--r--lib/snmp/doc/src/snmp_agent_config_files.xml60
-rw-r--r--lib/snmp/doc/src/snmp_target_mib.xml24
-rw-r--r--lib/snmp/doc/src/snmpa_conf.xml25
-rw-r--r--lib/snmp/mibs/Makefile.in3
-rw-r--r--lib/snmp/mibs/TRANSPORT-ADDRESS-MIB.mib417
-rw-r--r--lib/snmp/priv/conf/agent/target_addr.conf10
-rw-r--r--lib/snmp/src/agent/snmp_notification_mib.erl7
-rw-r--r--lib/snmp/src/agent/snmp_target_mib.erl166
-rw-r--r--lib/snmp/src/agent/snmpa_acm.erl26
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl21
-rw-r--r--lib/snmp/src/agent/snmpa_authentication_service.erl9
-rw-r--r--lib/snmp/src/agent/snmpa_conf.erl63
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl44
-rw-r--r--lib/snmp/src/agent/snmpa_net_if.erl48
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl40
-rw-r--r--lib/snmp/src/app/snmp.appup.src80
-rw-r--r--lib/snmp/src/misc/snmp_conf.erl205
-rw-r--r--lib/snmp/src/misc/snmp_config.erl3
-rw-r--r--lib/snmp/test/snmp_agent_test.erl143
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl15
-rw-r--r--lib/snmp/vsn.mk2
22 files changed, 1229 insertions, 235 deletions
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index 2efeb8ae3f..8dd5bcb2c0 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,6 +33,59 @@
</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>[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>
+
+ </list>
+ </section>
+
+ <section>
+ <title>Fixed Bugs and Malfunctions</title>
+ <p>-</p>
+<!--
+ <item>
+ <p>[agent] When calling
+ <seealso marker="snmp_view_based_acm_mib#reconfigure">snmp_view_based_acm_mib:reconfigure/1</seealso>
+ on a running node, the table <c>vacmAccessTable</c> was not properly
+ cleaned.
+ This meant that if some entries in the vacm.conf file was removed
+ (compared to the <c>current</c> config),
+ while others where modified and/or added, the removed entrie(s)
+ would still exist in the <c>vacmAccessTable</c> table. </p>
+ <p>Own Id: OTP-8981</p>
+ <p>Aux Id: Seq 11750</p>
+ </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>
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_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_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/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
+
+ 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_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..a2820269d0 100644
--- a/lib/snmp/src/agent/snmp_target_mib.erl
+++ b/lib/snmp/src/agent/snmp_target_mib.erl
@@ -29,13 +29,15 @@
-export([add_addr/10, 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_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..d9a0438b56 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -754,8 +754,8 @@ handle_info({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds}, S) ->
"~n Varbinds: ~p",
[Trap, NotifyName, ContextName, Recv, Varbinds]),
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)) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -775,8 +775,8 @@ 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
+ case (catch handle_send_trap(S, Trap, NotifyName, ContextName,
+ Recv, Varbinds, LocalEngineID)) of
{ok, NewS} ->
{noreply, NewS};
{'EXIT', R} ->
@@ -923,9 +923,9 @@ handle_call({send_trap, Trap, NotifyName, ContextName, Recv, Varbinds},
?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,
@@ -1470,7 +1470,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}.
@@ -1717,7 +1720,7 @@ handle_acm_error(Vsn, Reason, Pdu, ACMData, Address, Extra) ->
handle_send_trap(S, TrapName, NotifyName, ContextName, Recv, Varbinds,
LocalEngineID) ->
?vtrace("handle_send_trap -> entry with"
- "~n S#state.type: ~p"
+ "~n Agent type: ~p"
"~n TrapName: ~p"
"~n NotifyName: ~p"
"~n ContextName: ~p"
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_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..d4bb5bdf9f 100644
--- a/lib/snmp/src/agent/snmpa_net_if.erl
+++ b/lib/snmp/src/agent/snmpa_net_if.erl
@@ -504,7 +504,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 +512,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 +637,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 +776,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..09ecb5228b 100644
--- a/lib/snmp/src/agent/snmpa_trap.erl
+++ b/lib/snmp/src/agent/snmpa_trap.erl
@@ -33,13 +33,14 @@
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").
+-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).
@@ -440,11 +441,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
@@ -1001,9 +1004,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 +1074,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/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index de0e5d6e14..b8aea85cbe 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -22,8 +22,41 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.19",
+ [
+ {load_module, snmp_conf, 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]},
+ {load_module, snmpa_acm, soft_purge, soft_purge,
+ [snmp_conf, snmpa_acm, 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_target_mib, soft_purge, soft_purge,
+ [snmp_conf]},
+ {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, snmp_conf, 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]},
+ {load_module, snmpa_acm, soft_purge, soft_purge,
+ [snmp_conf, snmpa_acm, 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_misc, soft_purge, soft_purge, []},
{load_module, snmpa_vacm, soft_purge, soft_purge, []},
{load_module, snmpa, soft_purge, soft_purge,
@@ -45,7 +78,12 @@
[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, 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,8 +91,41 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.19",
+ [
+ {load_module, snmp_conf, 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]},
+ {load_module, snmpa_acm, soft_purge, soft_purge,
+ [snmp_conf, snmpa_acm, 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_target_mib, soft_purge, soft_purge,
+ [snmp_conf]},
+ {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, snmp_conf, 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]},
+ {load_module, snmpa_acm, soft_purge, soft_purge,
+ [snmp_conf, snmpa_acm, 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_misc, soft_purge, soft_purge, []},
{load_module, snmpa_vacm, soft_purge, soft_purge, []},
{load_module, snmpa, soft_purge, soft_purge,
@@ -76,7 +147,12 @@
[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, 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/misc/snmp_conf.erl b/lib/snmp/src/misc/snmp_conf.erl
index 4d2f5d8f92..4fffb0fe38 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,94 @@ 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(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(?transportDomainUdpIpv4, X) ->
+ check_taddress(transportDomainUdpIpv4, 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(?transportDomainUdpIpv6, X) ->
+ check_taddress(transportDomainUdpIpv6, X);
+
+check_taddress(BadDomain, _X) ->
+ error({invalid_tdomain, BadDomain}).
+
%% ---------
@@ -385,15 +472,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..91a6550b0a 100644
--- a/lib/snmp/src/misc/snmp_config.erl
+++ b/lib/snmp/src/misc/snmp_config.erl
@@ -1721,10 +1721,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 +1734,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/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index 692d29fda0..cf4d5523bf 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -105,16 +105,11 @@ groups() ->
{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()},
+ {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()},
@@ -378,17 +373,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 +1078,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 +1119,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 +1162,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 +1181,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/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)"