RFC 3781
Next Generation Structure of Management Information (SMIng) Mappings to the Simple Network Management Protocol (SNMP)
RFC 3781 ๐
Next Generation Structure of Management Information (SMIng) Mappings to the Simple Network Management Protocol (SNMP) โจ
Okay bestie, this one is an RFC, which is basically the Internet's official rulebook. It was published in May 2004 by the Network Working Group. F. Strauss (TU Braunschweig) and J. Schoenwaelder (International University Bremen) wrote it. It's labeled Experimental, so it's not an Internet standard, and its title block doesn't list anything it obsoletes or updates. ๐ฆ
Status of this Memo ๐
This memo defines an Experimental Protocol for the Internet community, and it does not specify an Internet standard of any kind ๐ง They're actively asking for discussion and suggestions for improvement. The memo can be distributed without limits. ๐
Copyright Notice ๐
Copyright (C) The Internet Society (2004). All Rights Reserved. ๐ธ
Abstract ๐ฅ
SMIng (Structure of Management Information, Next Generation) (RFC3780) is a protocol-independent data definition language for management information. This memo adds an SMIng language extension that maps SMIng definitions of identities, classes, and their attributes and events onto dedicated definitions of nodes, scalar objects, tables and columnar objects, and notifications, so they can be used with the SNMP management framework. It's giving organized ๐
Table of Contents ๐
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. SNMP Based Internet Management . . . . . . . . . . . . . . . . 3
2.1. Kinds of Nodes. . . . . . . . . . . . . . . . . . . . . 4
2.2. Scalar and Columnar Object Instances. . . . . . . . . . 5
2.3. Object Identifier Hierarchy . . . . . . . . . . . . . . 7
3. SMIng Data Type Mappings . . . . . . . . . . . . . . . . . . . 8
3.1. ASN.1 Definitions . . . . . . . . . . . . . . . . . . . 9
4. The snmp Extension Statement . . . . . . . . . . . . . . . . . 10
4.1. The oid Statement . . . . . . . . . . . . . . . . . . . 10
4.2. The node Statement. . . . . . . . . . . . . . . . . . . 10
4.2.1. The node's oid Statement . . . . . . . . . . . . 10
4.2.2. The node's represents Statement. . . . . . . . . 10
4.2.3. The node's status Statement. . . . . . . . . . . 11
4.2.4. The node's description Statement . . . . . . . . 11
4.2.5. The node's reference Statement . . . . . . . . . 11
4.2.6. Usage Examples . . . . . . . . . . . . . . . . . 11
4.3. The scalars Statement . . . . . . . . . . . . . . . . . 11
4.3.1. The scalars' oid Statement . . . . . . . . . . . 12
4.3.2. The scalars' object Statement . . . . . . . . . 12
4.3.3. The scalars' status Statement . . . . . . . . . 13
4.3.4. The scalars' description Statement . . . . . . . 14
4.3.5. The scalars' reference Statement . . . . . . . . 14
4.3.6. Usage Example. . . . . . . . . . . . . . . . . . 14
4.4. The table Statement . . . . . . . . . . . . . . . . . . 14
4.4.1. The table's oid Statement. . . . . . . . . . . . 15
4.4.2. Table Indexing Statements. . . . . . . . . . . . 15
4.4.3. The table's create Statement . . . . . . . . . . 17
4.4.4. The table's object Statement . . . . . . . . . . 17
4.4.5. The table's status Statement . . . . . . . . . . 19
4.4.6. The table's description Statement . . . . . . . 19
4.4.7. The table's reference Statement . . . . . . . . 19
4.4.8. Usage Example . . . . . . . . . . . . . . . . . 19
4.5. The notification Statement . . . . . . . . . . . . . . 20
4.5.1. The notification's oid Statement . . . . . . . . 20
4.5.2. The notification's signals Statement . . . . . . 20
4.5.3. The notification's status Statement . . . . . . 20
4.5.4. The notification's description Statement . . . . 21
4.5.5. The notification's reference Statement . . . . . 21
4.5.6. Usage Example. . . . . . . . . . . . . . . . . . 21
4.6. The group Statement . . . . . . . . . . . . . . . . . . 21
4.6.1. The group's oid Statement . . . . . . . . . . . 22
4.6.2. The group's members Statement . . . . . . . . . 22
4.6.3. The group's status Statement . . . . . . . . . . 22
4.6.4. The group's description Statement . . . . . . . 22
4.6.5. The group's reference Statement . . . . . . . . 22
4.6.6. Usage Example . . . . . . . . . . . . . . . . . 22
4.7. The compliance Statement. . . . . . . . . . . . . . . . 23
4.7.1. The compliance's oid Statement . . . . . . . . . 23
4.7.2. The compliance's status Statement . . . . . . . 23
4.7.3. The compliance's description Statement . . . . . 23
4.7.4. The compliance's reference Statement . . . . . . 23
4.7.5. The compliance's mandatory Statement . . . . . . 24
4.7.6. The compliance's optional Statement. . . . . . . 24
4.7.7. The compliance's refine Statement . . . . . . . 24
4.7.8. Usage Example . . . . . . . . . . . . . . . . . 26
5. NMRG-SMING-SNMP-EXT . . . . . . . . . . . . . . . . . . . . . 26
6. NMRG-SMING-SNMP . . . . . . . . . . . . . . . . . . . . . . . 33
7. Security Considerations . . . . . . . . . . . . . . . . . . . 46
8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 46
9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 47
9.1. Normative References. . . . . . . . . . . . . . . . . . 47
9.2. Informative References. . . . . . . . . . . . . . . . . 47
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . . 48
Full Copyright Statement . . . . . . . . . . . . . . . . . . . . . 49
1. Introduction โจ
SMIng (Structure of Management Information, Next Generation) [RFC3780] is a protocol-independent data definition language for management information. This memo adds an SMIng language extension that maps SMIng definitions of identities, classes, and their attributes and events onto dedicated definitions of nodes, scalar objects, tables and columnar objects, and notifications, for use in the SNMP management framework. ๐ฆ
Section 2 introduces the basics of the SNMP management framework. Section 3 defines how SMIng data types are mapped to the data types supported by the SNMP protocol. It also introduces some new ASN.1 [ASN1] definitions, which are used to represent new SMIng base types such as floats in the SNMP protocol. ๐
Section 4 describes the semantics of the SNMP mapping extensions for SMIng. The formal SMIng specification of the extension is provided in Section 5. ๐
Section 6 contains an SMIng module that defines derived types (such as RowStatus) that are specific to the SNMP mapping. ๐ซถ
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119]. ๐
2. SNMP-Based Internet Management ๐ง
The SNMP network management framework [RFC3410] is based on the concept of "managed objects". Managed objects represent real or synthesized variables of systems that are to be managed. Note that in spite of these terms, this model is not object-oriented. For naming purposes, the managed objects are organized hierarchically in an "object identifier tree", where only leaf nodes may represent objects. ๐ธ
Nodes in the object identifier tree may also identify conceptual tables, rows of conceptual tables, notifications, groups of objects and/or notifications, compliance statements, modules, or other information. Each node is identified by a unique "object identifier" value, which is a sequence of non-negative numbers named "sub-identifiers". The left-most sub-identifier refers to the node next to the root of the tree, and the right-most sub-identifier refers to the node that is identified by the complete object identifier value. Each sub-identifier has a value between 0 and 2^32-1 (4294967295). ๐
The SMIng extensions described in this document are used to map SMIng data definitions to SNMP compliant managed objects. This mapping is designed to be readable to computer programs, named MIB compilers, as well as to human readers. ๐
2.1. Kinds of Nodes ๐ฅ
Each node in the object identifier tree is of a certain kind and may or may not represent management information:
- Simple nodes, which do not represent management information but may be used for grouping nodes in a subtree. Those nodes are defined by the
node'statement. This statement can also be used to map an SMIngidentity'to a node. - Nodes representing the identity of a module, to allow references to a module in other objects of type
ObjectIdentifier'. Those nodes are defined by thesnmp'statement, - Scalar objects, which have exactly one object instance and no child nodes. See Section 2.2 for scalar objects' instances. A set of scalar objects is mapped from one or more SMIng classes using the
scalars'statement. The statement block of thescalars'statement contains oneimplements'statement for each class. The associated statement blocks in turn containobject'statements that specify the mapping of attributes to scalar objects. Scalar objects MUST not have any child node. ๐ - Tables, which represent the root node of a collection of information structured in table rows. Table nodes are defined by the
table'statement. A table object identifier SHOULD not have any other child node than the implicitly defined row node (see below). ๐ - Rows, which belong to a table (that is, a row's object identifier consists of the table's full object identifier plus a single
1'sub-identifier) and represent a sequence of one or more columnar objects. A row node is implicitly defined for each table node. ๐ง - Columnar objects, which belong to a row (that is, the columnar objects' object identifier consists of the row's full object identifier plus a single column-identifying sub-identifier) and have zero or more object instances and no child nodes. They are defined as follows: the classes that are implemented by a
table'statement are identified byimplements'statements. The statement block of eachimplements'statement containsobject'statements that specify the mapping of attributes to columnar objects of this table. Columnar objects MUST not have any child node. ๐ - Notifications, which represent information that is sent by agents within unsolicited transmissions. The
notification'statement is used to map an SMIng event to a notification. A notification's object identifier SHOULD not have any child node. ๐ - Groups of objects and notifications, which may be used for compliance statements. They are defined using the
group'statement. ๐ซง - Compliance statements, which define requirements for MIB module implementations. They are defined using the
compliance'statement. ๐
2.2. Scalar and Columnar Object Instances โจ
Okay bestie, instances of managed objects get identified by tacking an instance-identifier onto the end of the object's object identifier ๐. Scalars and columnar objects build that instance-identifier differently, so pay attention ๐ .
Scalar objects are the chill ones. They have exactly one object instance, and it's identified by appending a single `0' sub-identifier to the scalar's object identifier ๐ธ.
Inside tables, each instance of a columnar object gets its own ID by adding one or more sub-identifiers, built from the values of the object instances that uniquely pick out a table row ๐ฆ. The indexing objects can be columnar objects from the same table and/or from another table, but they MUST NOT be scalar objects ๐ . Listing the same object more than once in a single table indexing spec is strongly discouraged ๐.
The base type of each indexing object decides how the instance-identifier gets formed:
- integer-valued or enumeration-valued: one sub-identifier that takes the integer value. This only works for non-negative integers and integers up to 32 bits ๐ข,
- string-valued, fixed-length strings (or variable-length with compact encoding):
n' sub-identifiers, wheren' is the length of the string. Each octet of the string gets its own sub-identifier ๐งต, - string-valued, variable-length strings or bits-valued:
n+1' sub-identifiers, wheren' is the length of the string or bits encoding. The first sub-identifier is `n' itself, and then each octet of the string or bits gets its own sub-identifier ๐ซถ, - object identifier-valued (with compact encoding):
n' sub-identifiers, wheren' is the number of sub-identifiers in the value. Each sub-identifier of the value gets copied into its own sub-identifier ๐, - object identifier-valued:
n+1' sub-identifiers, wheren' is the number of sub-identifiers in the value. The first sub-identifier is `n' itself, and then each sub-identifier in the value gets copied ๐ง.
Now the compact encoding rules, which are a whole mood ๐ญ. Compact encoding can only be applied to an object with a variable-length syntax (like variable-length strings, bits objects or object identifier-valued objects). It can also only be associated with the last object in a list of indexing objects. And finally, compact encoding MUST NOT be used on a variable-length string object if that string might have a value of zero-length ๐.
Instances identified by integer-valued or enumeration-valued objects are RECOMMENDED to be numbered starting from one (i.e., not from zero) ๐. Integer objects that allow negative values, Unsigned64 objects, Integer64 objects and floating point objects MUST NOT be used for table indexing. No exceptions, periodt ๐ซ.
Objects that are both specified for indexing in a row AND are columnar objects of the same row are called auxiliary objects ๐. Auxiliary objects SHOULD be non-accessible, except in these situations:
- within a module originally written to conform to SMIv1, or
- a row must contain at least one columnar object which is not an auxiliary object. If all of a row's columnar objects are also specified to be indexing objects, then one of them MUST be accessible โจ.
2.3. Object Identifier Hierarchy ๐ณ
The layers of the object identifier tree near the root are well defined and organized by standardization bodies ๐๏ธ. The first level next to the root has three nodes:
0: ccitt
1: iso
2: joint-iso-ccitt
Quick tea: the renaming of the Commite Consultatif International de Telegraphique et Telephonique (CCITT) to International Telecommunications Union (ITU) had zero consequences on the names used in the object identifier tree ๐คทโโ๏ธ.
The root of the subtree run by the Internet Assigned Numbers Authority (IANA) for the Internet is 1.3.6.1', which is named internet'. So the whole Internet subtree starts with the prefix `1.3.6.1.' ๐.
A few branches under this subtree are used for network management ๐:
The `mgmt' (internet.2) subtree is used to identify "standard" definitions. An information module produced by an IETF working group becomes a "standard" information module when the document is first approved by the IESG and enters the Internet standards track ๐.
The `experimental' (internet.3) subtree is used to identify experimental definitions being designed by working groups of the IETF or IRTF. If an information module from a working group becomes a "standard" module, then right at the very beginning of its entry onto the Internet standards track, the definitions get moved under the mgmt subtree ๐งชโก๏ธ๐.
The private' (internet.4) subtree is used to identify definitions defined unilaterally ๐ต๏ธ. The enterprises' (private.1) subtree beneath private is used, among other things, to let providers of networking subsystems register information modules for their products ๐ข.
These and some other nodes are defined in the SMIng module NMRG-SMING-SNMP-EXT (Section 5) ๐.
3. SMIng Data Type Mappings ๐งธ
SMIng [RFC3780] supports this set of base types: OctetString, Pointer, Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64, Float128, Enumeration, Bits, and ObjectIdentifier ๐งฉ.
The SMIng core module NMRG-SMING ([RFC3780], Appendix A) defines extra derived types too, like Counter32 (derived from Unsigned32), Counter64 (derived from Unsigned64), TimeTicks32 and TimeTicks64 (derived from Unsigned32 and Unsigned64), IpAddress (derived from OctetString), and Opaque (derived from OctetString) ๐.
The version 2 of the protocol operations for SNMP document [RFC3416] defines these 9 data types, which the protocol uses to tell them apart: INTEGER, OCTET STRING, OBJECT IDENTIFIER, IpAddress, Counter32, TimeTicks, Opaque, Counter64, and Unsigned32 ๐ญ.
Now the mapping table, where SMIng base types and their derived types get mapped to SNMP data types ๐บ๏ธ:
SMIng Data Type SNMP Data Type Comment
--------------- ------------------- -------
OctetString OCTET STRING (1)
Pointer OBJECT IDENTIFIER
Integer32 INTEGER
Integer64 Opaque (Integer64) (2)
Unsigned32 Unsigned32 (3)
Unsigned64 Opaque (Unsigned64) (2) (4)
Float32 Opaque (Float32) (2)
Float64 Opaque (Float64) (2)
Float128 Opaque (Float128) (2)
Enumeration INTEGER
Bits OCTET STRING
ObjectIdentifier OBJECT IDENTIFIER
Counter32 Counter32
Counter64 Counter64
TimeTicks32 TimeTicks
TimeTicks64 Opaque (Unsigned64) (2)
IpAddress IpAddress
Opaque Opaque
And here are the footnotes that go with it ๐:
(1) This mapping includes all types derived from the OctetString
type except those types derived from the IpAddress and Opaque
SMIng types defined in the module NMRG-SMING.
(2) This type is encoded according to the ASN.1 type with the same
name defined in Section 3.1. The resulting BER encoded value
is then wrapped in an Opaque value.
(3) This mapping includes all types derived from the Unsigned32
type except those types derived from the Counter32 and
TimeTicks32 SMIng types defined in the module NMRG-SMING.
(4) This mapping includes all types derived from the Unsigned64
type except those types derived from the Counter64 SMIng type
defined in the module NMRG-SMING.
3.1. ASN.1 Definitions ๐ง
These ASN.1 [ASN1] type definitions introduce data types that are used to map the new SMIng base types into the set of ASN.1 types supported by the second version of SNMP protocol operations [RFC3416]. Let's look ๐:
NMRG-SMING-SNMP-MAPPING DEFINITIONS ::= BEGIN
Integer64 ::=
[APPLICATION 10]
IMPLICIT INTEGER (-9223372036854775808..9223372036854775807)
Unsigned64
[APPLICATION 11]
IMPLICIT INTEGER (0..18446744073709551615)
Float32
[APPLICATION 12]
IMPLICIT OCTET STRING (SIZE (4))
Float64
[APPLICATION 13]
IMPLICIT OCTET STRING (SIZE (8))
Float128
[APPLICATION 14]
IMPLICIT OCTET STRING (SIZE (16))
END
The definitions of Integer64 and Unsigned64 are consistent with the same definitions in the SPPI [RFC3159] ๐ค. The floating point types Float32, Float64 and Float128 support single, double and quadruple IEEE floating point values ๐ฅ. The encoding of the values follows the "IEEE Standard for Binary Floating-Point Arithmetic" as defined in ANSI/IEEE Standard 754-1985 [IEEE754] ๐งฎ.
4. The snmp Extension Statement ๐
The snmp' statement is the main statement of the SNMP mapping specification. It gets one or two arguments: an optional lower-case identifier that specifies a node representing the module's identity, and a mandatory statement block that holds all the details of the SNMP mapping. All information of an SNMP mapping gets mapped to an SNMP conformant module with the same name as the containing SMIng module. A single SMIng module must not contain more than one snmp' statement ๐
โโ๏ธ.
4.1. The oid Statement ๐
The snmp's `oid' statement must be present if the snmp statement contains a module identifier, and must be absent otherwise. It gets one argument, which specifies the object identifier value assigned to this module's identity node ๐ชช.
4.2. The node Statement ๐ชด
The node' statement is used to name and describe a node in the object identifier tree, without associating any class or attribute information with it. This can be handy for grouping definitions in a subtree of related management information, or for uniquely defining an SMIng identity' to be referenced in attributes of type Pointer ๐ท. The `node' statement gets two arguments: a lower-case node identifier and a statement block that holds detailed node information in an obligatory order ๐.
See the nodeStatement' rule of the grammar (Section 5) for the formal syntax of the node' statement ๐.
4.2.1. The node's oid Statement ๐งญ
The node's `oid' statement must be present. It gets one argument, which specifies the object identifier value assigned to this node ๐ฏ.
4.2.2. The node's represents Statement ๐ช
The node's `represents' statement need not be present. It makes this node represent an SMIng identity, so that objects of type Pointer can reference that identity. The statement gets one argument, which specifies the identity name ๐ซง.
4.2.3 The node's status Statement ๐ฆ
The node's status' statement must be present. It gets one argument, which is used to say whether this node definition is current or historic. The value current' means the definition is current and valid โ
. The value obsolete' means the definition is obsolete and should not be implemented, and/or can be removed if it was previously implemented ๐๏ธ. The value deprecated' also indicates an obsolete definition, but it permits new or continued implementation in order to foster interoperability with older and existing implementations ๐ค๐.
4.2.4. The node's description Statement โจ
Okay so the node's description statement is totally optional, and it takes one argument that gives a high-level text description of the node. ๐
It is RECOMMENDED to include all semantics and purposes of this node. Tell the whole story, bestie! ๐
4.2.5. The node's reference Statement ๐
The node's reference statement is also optional, and it takes one argument that points to some other document. That could be another module with related definitions, or some other doc with extra info about this node. ๐
4.2.6. Usage Examples ๐ฆ
node iso { oid 1; status current; };
node org { oid iso.3; status current; };
node dod { oid org.6; status current; };
node internet { oid dod.1; status current; };
node zeroDotZero {
oid 0.0;
represents NMRG-SMING::null;
status current;
description "A null value used for pointers.";
};
4.3. The scalars Statement ๐
The scalars statement is how you map one or more classes onto a group of SNMP scalar managed objects that all sit under the same parent node. ๐ธ It takes two arguments: a lower-case scalar group identifier, and a statement block that holds the mapping details of the group, in a required order. ๐
See the scalarsStatement rule of the grammar (Section 5) for the formal syntax of the scalars statement. ๐ง
4.3.1. The scalars' oid Statement
The scalars' oid statement must be there. It takes one argument, which is the object identifier value given to the common parent node of this scalar group. ๐
4.3.2. The scalars' object Statement
The scalars' object statement must show up at least once. It makes the scalar group contain a certain scalar object. It takes two arguments: the name of that scalar object, and a statement block with more detailed info, in a required order. โจ
4.3.2.1. The object's implements Statement
The implements statement must be there. It names a single leaf attribute of a class that this scalar object implements. The type of that attribute has to be a simple type, meaning not a class. ๐ฅ
4.3.2.2. The object's subid Statement
The subid statement is optional. It sets the sub-identifier that picks out the scalar object within its scalar group. Basically, the object identifier of the scalar object is the scalar group's oid value joined with this subid value. ๐ฆ
If this statement is left out, the sub-identifier is the previous object statement's sub-identifier in this scalar group, plus 1. If the object statement is the first one in its scalar group and there's no subid, the sub-identifier is 1. ๐
4.3.2.3. The object's status Statement
The object's status statement is optional, and it says whether this scalar object definition is current or historic. ๐ The value current means the definition is current and valid. The value obsolete means the definition is obsolete, so it should not be implemented and can be removed if someone already implemented it. โญ The value deprecated also means obsolete, but it still lets people keep implementing it, so older and existing implementations keep working together. ๐ซถ
Scalar objects SHOULD NOT be defined as current if the implemented attribute definition is deprecated or obsolete. In the same way, they SHOULD NOT be defined as deprecated if the implemented attribute is obsolete. Still, changes to the class definitions being used can't be avoided, and they SHOULD be taken into account in later revisions of the local module. ๐
Note that it is RECOMMENDED to leave out the status statement, since the status then gets inherited from the containing scalars statement. But if a scalar object's status is different from its scalar group's, you have to spell it out, for example when the implemented attribute has been deprecated or obsoleted. ๐
4.3.2.4. The object's description Statement
The object's description statement is optional, and it takes one argument that gives a high-level text description of this scalar object. ๐ธ
Heads up, this one is different from the others: it's not mandatory, and it is RECOMMENDED to leave it out if the object is already fully described by the description of the implemented attribute. ๐ง
4.3.2.5. The object's reference Statement
The object's reference statement is optional and takes one argument that cross-references some other document. That could be another module with related definitions, or another doc with more info about this scalar object. ๐
It is RECOMMENDED to leave this statement out if the object's references are already fully covered by the implemented attribute. ๐
4.3.3. The scalars' status Statement
The scalars' status statement must be there. It takes one argument that says whether this scalar group definition is current or historic. The value current means it's current and valid. The value obsolete means it's obsolete and should not be implemented, and it can be removed if someone already implemented it. The value deprecated also means obsolete, but it still permits new or continued implementation so that older and existing implementations keep playing nicely. โจ
4.3.4. The scalars' description Statement
The scalars' description statement must be there. It takes one argument that gives a high-level text description of this scalar group. ๐
It is RECOMMENDED to include all the semantic definitions needed to implement this scalar group. ๐
4.3.5. The scalars' reference Statement
The scalars' reference statement is optional. It takes one argument that cross-references some other document, either another module with related definitions or another doc with extra info about this scalars statement. ๐
4.3.6. Usage Example ๐ฌ
scalars ip {
oid mib-2.4;
object ipForwarding { implements Ip.forwarding; };
object ipDefaultTTL { implements Ip.defaultTTL; };
// ...
status current;
description
"This scalar group implements the Ip class.";
};
4.4. The table Statement ๐ง
The table statement maps one or more classes onto a single SNMP table of columnar managed objects. ๐ It takes two arguments: a lower-case table identifier, and a statement block with the mapping details of this table, in a required order. โจ
See the tableStatement rule of the grammar (Section 5) for the formal syntax of the table statement. ๐ง
4.4.1. The table's oid Statement
The table's oid statement must be there. It takes one argument, which is the object identifier value assigned to this table's node. ๐
4.4.2. Table Indexing Statements ๐๏ธ
SNMP table mappings have five ways to hand over indexing info: ordinary tables, table augmentations, sparse table augmentations, table expansions, and reordered tables. Each one uses its own statements to say what its indexing info is. ๐ Each table definition must contain exactly one of the following indexing statements. ๐ฅ
4.4.2.1. The table's index Statement for Table Indexing
The table's index statement gives the indexing info for base tables. It takes one argument: a comma-separated list of the objects used for indexing, wrapped in parentheses. ๐ฆ
The elements of the unique statement of the implemented class(es), and their order, should be treated as a hint for the index elements of the table. ๐ก
If you're writing modules that need to stay compatible with SMIv2 versions of the module at the SNMP protocol level, you can add an optional implied keyword in front of the list. That signals a compact encoding of the last object in the list. Check Section 2.2 for the details. ๐ซถ
4.4.2.2. The table's augments Statement for Table Indexing
The table's augments statement gives the indexing info for tables that augment a base table. It takes one argument: the identifier of the table being augmented. Heads up, a table augmentation can't be augmented itself. But a base table can have several table augmentations. ๐
A table augmentation makes instances of its subordinate columnar objects, identified using the index spec of the base table that the augments statement names. Those instances follow the same rules as the subordinate columnar objects of the base table being augmented. So creating a base table row also means creating the matching row augmentations. ๐ธ Table augmentations MUST NOT be used in table row creation and deletion operations. โ
4.4.2.3. The table's extends Statement for Table Indexing
The table's extends statement gives the indexing info for tables that sparsely augment a base table. It takes one argument: the identifier of the table being sparsely augmented. Again, a sparse table augmentation can't be augmented itself, but a base table can be augmented by several table augmentations, sparse or not. ๐
A sparse table augmentation makes instances of its subordinate columnar objects, identified (if present) using the index spec of the base table that the extends statement names. Those instances follow the same semantics as the base table's subordinate columnar objects, plus the non-formal rules that define the sparse relationship. So creating a base table row might imply a sparse row augmentation, but it can also happen through an explicit creation. Watch out, though: if a base table row gets deleted, any dependent sparse table row augmentations get deleted automatically too. ๐ญ
4.4.2.4. The table's reorders Statement for Table Indexing ๐โจ
okay so the table's reorders statement is for when you've got tables with the exact same index objects as a base table, just lined up in a different order ๐ it takes at least two arguments. the first one is the identifier of the base table. the second one is a comma-separated list of exactly those object identifiers from the base table's index statement, in the order this table wants to use them ๐
a reordered table can't be reordered itself tho (no cap). but a base table can totally have multiple reordered tables, so go wild ๐ฆ
under some circumstances you can add an optional implied keyword in front of the list, which means a compact encoding of the last object in the list. see Section 2.2 for the deets ๐ซถ
the subordinate columnar objects of a reordered table exist under the same semantics as those of the base table. so creating a base table row means the matching reordered table row gets created too ๐ญ which is exactly why reordered tables MUST NOT be used in table row creation and deletion operations ๐ซ
4.4.2.5. The table's expands Statement for Table Indexing ๐
the expands statement supplies table indexing info for table expansions. expansions use the same index objects as another table, plus some extra indexing objects ๐ so it takes at least two arguments. the first one is the identifier of the base table. the second one is a comma-separated list of the additional object identifiers used for indexing. an expanded table can itself get expanded, and base tables can be used for multiple expansions ๐ง
again, under some circumstances you can add an optional implied keyword in front of the list to get that compact encoding of the last object. see Section 2.2 ๐
4.4.3. The table's create Statement ๐
the create statement need not be present, and it gets no argument. if it's there, table row creation (and deletion) is possible ๐
4.4.4. The table's object Statement ๐งฉ
the object statement must be present at least once, and it makes this table contain a given columnar object. it gets two arguments: the name of the columnar object being defined, and a statement block with extra detailed info in an obligatory order ๐
4.4.4.1. The object's implements Statement ๐
the implements statement must be present. it's used to specify a single leaf attribute of a class that this columnar object implements. that attribute's type must be a simple type, i.e., not a class ๐
โโ๏ธ
4.4.4.2. The object's subid Statement ๐ข
the subid statement need not be present. it's used to specify the sub-identifier that identifies the columnar object within this table. basically, the object identifier of the columnar object is the concatenation of this table's oid statement value and this subid statement value ๐ซง
if you leave the subid statement out, the sub-identifier is the one from the previous object statement within this table, plus 1. and if the containing object statement is the first one within the containing table and you skip subid, the sub-identifier is 1 ๐ธ
4.4.4.3. The object's status Statement ๐ฆ
the object's status statement need not be present. it gets one argument that says whether this columnar object definition is current or historic. current means the definition is current and valid. obsolete means the definition is obsolete, so it should not be implemented and/or can be removed if it was implemented before. deprecated also means obsolete, but it still permits new or continued implementation to foster interoperability with older and existing implementations ๐
columnar objects SHOULD NOT be defined as current if the implemented attribute definition is deprecated or obsolete ๐
โโ๏ธ similarly, they SHOULD NOT be defined as deprecated if the implemented attribute is obsolete. nevertheless, subsequent revisions of used class definitions can't be avoided, but they SHOULD be taken into account in subsequent revisions of the local module ๐ค
note that it is RECOMMENDED to omit the status statement, which means the status is inherited from the containing table statement. however, if the status of a columnar object varies from the containing table, it has to be expressed explicitly, e.g., if the implemented attribute has been deprecated or obsoleted ๐ซถ
4.4.4.4. The object's description Statement ๐
the object's description statement need not be present. it gets one argument, which is used to specify a high-level textual description of this columnar object.
note that, unlike other definitions, this description statement isn't mandatory, and it is RECOMMENDED to omit it if the object is fully described by the description of the implemented attribute โจ
4.4.4.5. The object's reference Statement ๐
the object's reference statement need not be present. it gets one argument, which is used to specify a textual cross-reference to some other document. that could be another module defining related definitions, or some other document with additional info relevant to this columnar object ๐
it is RECOMMENDED to omit this statement if the object's references are fully described by the implemented attribute ๐
4.4.5. The table's status Statement ๐
the table's status statement must be present. it gets one argument that says whether this table definition is current or historic. current means the definition is current and valid. obsolete means the definition is obsolete, so it should not be implemented and/or can be removed if it was implemented before. deprecated also indicates an obsolete definition, but it permits new or continued implementation to foster interoperability with older and existing implementations ๐ฆ
4.4.6. The table's description Statement ๐ท
the table's description statement must be present. it gets one argument, which is used to specify a high-level textual description of this table ๐
it is RECOMMENDED to include all semantic definitions necessary for the implementation of this table ๐ง
4.4.7. The table's reference Statement ๐
the table's reference statement need not be present. it gets one argument, which is used to specify a textual cross-reference to some other document. that could be another module defining related definitions, or some other document that gives additional info relevant to this table statement ๐
4.4.8. Usage Example ๐ก
table ifTable {
oid interfaces.2;
index (ifIndex);
object ifIndex { implements Interface.index; };
object ifDescr { implements Interface.description; };
// ...
status current;
description
"This table implements the Interface class.";
};
4.5. The notification Statement ๐
the notification statement is used to map events defined within classes to SNMP notifications. it gets two arguments: a lower-case notification identifier, and a statement block with detailed notification info in an obligatory order ๐
see the notificationStatement rule of the grammar (Section 5) for the formal syntax of the notification statement ๐ง
4.5.1. The notification's oid Statement ๐
the notification's oid statement must be present. it gets one argument, which specifies the object identifier value assigned to this notification ๐
4.5.2. The notification's signals Statement ๐ก
the notification's signals statement must be present, and it denotes the event signaled by this notification. it gets two arguments: the event to be signaled (in the qualified form Class.event), and a statement block with detailed info on the objects transmitted with this notification in an obligatory order ๐
4.5.2.1. The signals' object Statement ๐งพ
the signals' object statement can be present zero, one, or multiple times. each one makes a single instance of a class attribute be contained in this notification. it gets one argument: the specific class attribute. attributes not specified by qualified names use the namespace of the event's class, which is specified in the signals statement ๐
4.5.3. The notification's status Statement ๐ฆ
the notification's status statement must be present. it gets one argument that says whether this notification definition is current or historic. current means the definition is current and valid. obsolete means the definition is obsolete, so it should not be implemented and/or can be removed if it was implemented before. deprecated also indicates an obsolete definition, but it permits new or continued implementation to foster interoperability with older and existing implementations ๐
4.5.4. The notification's description Statement ๐
the notification's description statement need not be present. it gets one argument, which is used to specify a high-level textual description of this notification โจ
it is RECOMMENDED to include all semantics and purposes of this notification ๐ซถ
4.5.5. The notification's reference Statement ๐
the notification's reference statement need not be present. it gets one argument, which is used to specify a textual cross-reference to some other document. that could be another module defining related definitions, or some other document with additional info relevant to this notification statement ๐
4.5.6. Usage Example ๐ก
notification linkDown {
oid snmpTraps.3;
signals Interface.linkDown {
object ifIndex;
object ifAdminStatus;
object ifOperStatus;
};
status current;
description
"This notification signals the linkDown event
of the Interface class.";
};
4.6. The group Statement ๐
the group statement is used to define a group of arbitrary nodes in the object identifier tree. it gets two arguments: a lower-case group identifier, and a statement block with detailed group info in an obligatory order ๐ธ
note that the primary application of groups is compliance statements, although they might be referred to in other formal or informal documents ๐ฅ
see the groupStatement rule of the grammar (Section 5) for the formal syntax of the group statement ๐ง
4.6.1. The group's oid Statement ๐
the group's oid statement must be present. it gets one argument, which specifies the object identifier value assigned to this group ๐
4.6.2. The group's members Statement ๐ฏ
the group's members statement must be present. it gets one argument, which specifies the list of nodes, by their identifiers, to be contained in this group. the list has to be comma-separated and enclosed in parenthesis ๐
4.6.3. The group's status Statement ๐ฆ
okay so the group's status statement is a must-have (it's required, bestie ๐
). It takes one argument that tells everyone whether the group definition is current or historic. current means the definition is still valid and totally good to use โจ. obsolete means it's outdated and the group should no longer be used ๐. deprecated also means outdated, but it still lets people keep using it, new and old, so it's like a soft retirement ๐ธ
4.6.4. The group's description Statement ๐
The group's description statement is required too. It takes one argument, a high-level text description of the group ๐ Also, it is RECOMMENDED to spill the tea on any relation to other groups ๐ซถ
4.6.5. The group's reference Statement ๐ง
The group's reference statement is totally optional ๐ It takes one argument, a text cross-reference to some other document. That could be another module that defines related groups, or some other document with extra info about this group ๐
4.6.6. Usage Example ๐
The snmpGroup, originally defined in [RFC3418], may be described like this:
group snmpGroup {
oid snmpMIBGroups.8;
objects (snmpInPkts, snmpInBadVersions,
snmpInASNParseErrs,
snmpSilentDrops, snmpProxyDrops,
snmpEnableAuthenTraps);
status current;
description
"A collection of objects providing basic
instrumentation and control of an agent.";
};
4.7. The compliance Statement ๐
okay the compliance statement is how you define a set of conformance requirements, called a compliance statement ๐ It gets two arguments: a lower-case compliance identifier, and a statement block with detailed compliance info in a fixed order ๐
See the complianceStatement rule of the grammar (Section 5) for the formal syntax of the compliance statement ๐ง
4.7.1. The compliance's oid Statement ๐ธ
The compliance's oid statement is required ๐ It takes one argument, the object identifier value assigned to this compliance statement.
4.7.2. The compliance's status Statement ๐ฆ
The compliance's status statement is required too โจ It takes one argument that says whether this compliance statement is current or historic. current means the definition is valid and good to go ๐ฅ obsolete means it's outdated and no longer a valid definition of conformance ๐ deprecated also means outdated, but it still permits new and continued use of the compliance specification ๐ซถ
4.7.3. The compliance's description Statement ๐
The compliance's description statement is required ๐ It takes one argument, a high-level text description of this compliance statement.
4.7.4. The compliance's reference Statement ๐ง
The compliance's reference statement is optional ๐ It takes one argument, a text cross-reference to another document. That could be another module that defines related compliance statements, or some other document with extra info about this compliance statement ๐
4.7.5. The compliance's mandatory Statement ๐
The compliance's mandatory statement is optional, but when it shows up it takes one argument: a comma-separated list of one or more groups (Section 4.6) of objects and/or notifications, wrapped in parentheses. These groups are unconditionally mandatory for implementation ๐ฅ
If an agent claims compliance to a MIB module, then it must implement each and every object and notification within each group listed in the mandatory statement(s) of the compliance statement(s) of that module ๐ญ
4.7.6. The compliance's optional Statement ๐
The compliance's optional statement is optional too, but you can use it again and again to name each group that is conditionally mandatory for the compliance statement ๐
It can also name unconditionally optional groups. A group named in an optional statement MUST be absent from the matching mandatory statement ๐ The optional statement gets two arguments: a lower-case group identifier and a statement block with detailed compliance info on that group.
Conditionally mandatory groups are the ones that are only mandatory if a particular protocol is implemented, or only if another group is implemented ๐ง The description statement spells out the conditions for when the group is conditionally mandatory.
A group that's named in neither a mandatory statement nor an optional statement is unconditionally optional for compliance to the module ๐ฆ
See the optionalStatement rule of the grammar (Section 5) for the formal syntax of the optional statement ๐ง
4.7.6.1. The optional's description Statement ๐
The optional's description statement is required ๐ It takes one argument, a high-level text description of the conditions under which this group is conditionally mandatory or unconditionally optional.
4.7.7. The compliance's refine Statement ๐ง
The compliance's refine statement is optional, and you can repeat it as much as you need ๐ Each one specifies an object that has a refined requirement for compliance compared to the module definition. The object must be present in one of the conformance groups named in the matching mandatory or optional statements ๐ซถ The refine statement gets two arguments: a lower-case identifier of a scalar or columnar object, and a statement block with detailed refinement info on that object.
See the refineStatement rule of the grammar (Section 5) for the formal syntax of the refine statement ๐ง
4.7.7.1. The refine's type Statement ๐ธ
The refine's type statement is optional ๐
It takes one argument that provides a refined type for the matching object. You can apply type restrictions by adding subtyping info, following the rules of the base type. See [RFC3780] for SMIng base types and their type restrictions. For enumeration or bitset types, the order of named numbers doesn't matter ๐
Note that if both a type and a writetype statement are present, then this type only applies when instances of the matching object are read ๐
4.7.7.2. The refine's writetype Statement โ๏ธ
The refine's writetype statement is optional too ๐ฆ It takes one argument that provides a refined type for the matching object, but only when instances of that object are written. Type restrictions work the same way: add subtyping info following the rules of the base type. See [RFC3780] for SMIng base types and their type restrictions. For enumeration or bitset types, the order of named numbers doesn't matter ๐
4.7.7.3. The refine's access Statement ๐
The refine's access statement is optional ๐ซถ It takes one argument that specifies the minimal level of access the matching object must implement, in the sense of its original access statement. So the refine's access statement MUST NOT specify a greater level of access than the matching object definition does ๐
โโ๏ธ
An implementation is compliant if the level of access it provides is greater than or equal to the minimal level in the refine'saccessstatement, and less than or equal to the maximal level in the object'saccessstatement ๐
4.7.7.4. The refine's description Statement ๐
The refine's description statement is required โจ It takes one argument, a high-level text description of the refined compliance requirement.
4.7.8. Usage Example ๐
The compliance statement in the SNMPv2-MIB [RFC3418], converted to SMIng, looks like this:
compliance snmpBasicComplianceRev2 {
oid snmpMIBCompliances.3;
status current;
description
"The compliance statement for SNMP entities which
implement this MIB module.";
mandatory (snmpGroup, snmpSetGroup, systemGroup,
snmpBasicNotificationsGroup);
optional snmpCommunityGroup {
description
"This group is mandatory for SNMP entities which
support community-based authentication.";
};
optional snmpWarmStartNotificationGroup {
description
"This group is mandatory for an SNMP entity which
supports command responder applications, and is
able to reinitialize itself such that its
configuration is unaltered.";
};
};
5. NMRG-SMING-SNMP-EXT ๐ง
okay the grammar of the snmp statement (including all of its contained statements) follows the Augmented Backus-Naur Form (ABNF) [RFC2234] ๐ง It's included in the abnf statement of the snmp SMIng extension definition, inside the NMRG-SMING-SNMP-EXT module below ๐
module NMRG-SMING-SNMP-EXT {
organization "IRTF Network Management Research Group (NMRG)";
contact "IRTF Network Management Research Group (NMRG)
http://www.ibr.cs.tu-bs.de/projects/nmrg/
Frank Strauss
TU Braunschweig
Muehlenpfordtstrasse 23
38106 Braunschweig
Germany
Phone: +49 531 391 3266
EMail: strauss@ibr.cs.tu-bs.de
Juergen Schoenwaelder
International University Bremen
P.O. Box 750 561
28725 Bremen
Germany
Phone: +49 421 200 3587
EMail: j.schoenwaelder@iu-bremen.de";
description "This module defines a SMIng extension to define
the mapping of SMIng definitions of class and
their attributes and events to SNMP compatible
definitions of modules, node, scalars, tables,
and notifications, and additional information on
module compliances.
Copyright (C) The Internet Society (2004).
All Rights Reserved.
This version of this module is part of
RFC 3781, see the RFC itself for full
legal notices.";
revision {
date "2003-12-16";
description "Initial revision, published as RFC 3781.";
};
//
//
//
extension snmp {
status current;
description
"The snmp statement maps SMIng definitions to SNMP
conformant definitions.";
abnf "
;;
;; sming-snmp.abnf -- Grammar of SNMP mappings in ABNF
;; notation (RFC 2234).
;;
;; @(#) $Id: sming-snmp.abnf,v 1.14 2003/10/23 19:31:55 strauss Exp $
;;
;; Copyright (C) The Internet Society (2004). All Rights Reserved.
;;
;;
;; Statement rules.
;;
Okay bestie, the grammar is about to get long, but it's just the rules for how these SNMP statements stack together ๐
snmpStatement = snmpKeyword *1(sep lcIdentifier) optsep
"{" stmtsep
*1(oidStatement stmtsep)
*(nodeStatement stmtsep)
*(scalarsStatement stmtsep)
*(tableStatement stmtsep)
*(notificationStatement stmtsep)
*(groupStatement stmtsep)
*(complianceStatement stmtsep)
statusStatement stmtsep
descriptionStatement stmtsep
*1(referenceStatement stmtsep)
"}" optsep ";"
nodeStatement = nodeKeyword sep lcIdentifier optsep
"{" stmtsep
oidStatement stmtsep
*1(representsStatement stmtsep)
statusStatement stmtsep
*1(descriptionStatement stmtsep)
*1(referenceStatement stmtsep)
"}" optsep ";"
representsStatement = representsKeyword sep
qucIdentifier optsep ";"
scalarsStatement = scalarsKeyword sep lcIdentifier optsep
"{" stmtsep
oidStatement stmtsep
1*(objectStatement stmtsep)
statusStatement stmtsep
descriptionStatement stmtsep
*1(referenceStatement stmtsep)
"}" optsep ";"
tableStatement = tableKeyword sep lcIdentifier optsep
"{" stmtsep
oidStatement stmtsep
anyIndexStatement stmtsep
*1(createStatement stmtsep)
1*(objectStatement stmtsep)
statusStatement stmtsep
descriptionStatement stmtsep
*1(referenceStatement stmtsep)
"}" optsep ";"
objectStatement = objectKeyword sep lcIdentifier optsep
"{" stmtsep
implementsStatement stmtsep
*1(subidStatement stmtsep)
*1(statusStatement stmtsep)
*1(descriptionStatement stmtsep)
*1(referenceStatement stmtsep)
"}" optsep ";"
implementsStatement = implementsKeyword sep qcattrIdentifier
optsep ";"
notificationStatement = notificationKeyword sep lcIdentifier
optsep "{" stmtsep
oidStatement stmtsep
signalsStatement stmtsep
statusStatement stmtsep
descriptionStatement stmtsep
*1(referenceStatement stmtsep)
"}" optsep ";"
signalsStatement = signalsKeyword sep qattrIdentifier
optsep "{" stmtsep
*(signalsObjectStatement)
"}" optsep ";"
signalsObjectStatement = objectKeyword sep
qattrIdentifier optsep ";"
groupStatement = groupKeyword sep lcIdentifier optsep
"{" stmtsep
oidStatement stmtsep
membersStatement stmtsep
statusStatement stmtsep
descriptionStatement stmtsep
*1(referenceStatement stmtsep)
"}" optsep ";"
complianceStatement = complianceKeyword sep lcIdentifier optsep
"{" stmtsep
oidStatement stmtsep
statusStatement stmtsep
descriptionStatement stmtsep
*1(referenceStatement stmtsep)
*1(mandatoryStatement stmtsep)
*(optionalStatement stmtsep)
*(refineStatement stmtsep)
"}" optsep ";"
anyIndexStatement = indexStatement /
augmentsStatement /
reordersStatement /
extendsStatement /
expandsStatement
indexStatement = indexKeyword *1(sep impliedKeyword) optsep
"(" optsep qlcIdentifierList
optsep ")" optsep ";"
augmentsStatement = augmentsKeyword sep qlcIdentifier
optsep ";"
reordersStatement = reordersKeyword sep qlcIdentifier
*1(sep impliedKeyword)
optsep "(" optsep
qlcIdentifierList optsep ")"
optsep ";"
extendsStatement = extendsKeyword sep qlcIdentifier optsep ";"
expandsStatement = expandsKeyword sep qlcIdentifier
*1(sep impliedKeyword)
optsep "(" optsep
qlcIdentifierList optsep ")"
optsep ";"
createStatement = createKeyword optsep ";"
membersStatement = membersKeyword optsep "(" optsep
qlcIdentifierList optsep
")" optsep ";"
mandatoryStatement = mandatoryKeyword optsep "(" optsep
qlcIdentifierList optsep
")" optsep ";"
optionalStatement = optionalKeyword sep qlcIdentifier optsep
"{" descriptionStatement stmtsep
"}" optsep ";"
refineStatement = refineKeyword sep qlcIdentifier optsep "{"
*1(typeStatement stmtsep)
*1(writetypeStatement stmtsep)
*1(accessStatement stmtsep)
descriptionStatement stmtsep
"}" optsep ";"
typeStatement = typeKeyword sep
(refinedBaseType / refinedType)
optsep ";"
writetypeStatement = writetypeKeyword sep
(refinedBaseType / refinedType)
optsep ";"
oidStatement = oidKeyword sep objectIdentifier optsep ";"
subidStatement = subidKeyword sep subid optsep ";"
;;
;; Statement keywords.
;;
snmpKeyword = %x73 %x6E %x6D %x70
nodeKeyword = %x6E %x6F %x64 %x65
representsKeyword = %x72 %x65 %x70 %x72 %x65 %x73 %x65 %x6E %x74
%x73
scalarsKeyword = %x73 %x63 %x61 %x6C %x61 %x72 %x73
tableKeyword = %x74 %x61 %x62 %x6C %x65
implementsKeyword = %x69 %x6D %x70 %x6C %x65 %x6D %x65 %x6E %x74
%x73
subidKeyword = %x73 %x75 %x62 %x69 %x64
objectKeyword = %x6F %x62 %x6A %x65 %x63 %x74
notificationKeyword = %x6E %x6F %x74 %x69 %x66 %x69 %x63 %x61 %x74
%x69 %x6F %x6E
signalsKeyword = %x73 %x69 %x67 %x6E %x61 %x6C %x73
oidKeyword = %x6F %x69 %x64
groupKeyword = %x67 %x72 %x6F %x75 %x70
complianceKeyword = %x63 %x6F %x6D %x70 %x6C %x69 %x61 %x6E %x63
%x65
impliedKeyword = %x69 %x6D %x70 %x6C %x69 %x65 %x64
indexKeyword = %x69 %x6E %x64 %x65 %x78
augmentsKeyword = %x61 %x75 %x67 %x6D %x65 %x6E %x74 %x73
reordersKeyword = %x72 %x65 %x6F %x72 %x64 %x65 %x72 %x73
extendsKeyword = %x65 %x78 %x74 %x65 %x6E %x64 %x73
expandsKeyword = %x65 %x78 %x70 %x61 %x6E %x64 %x73
createKeyword = %x63 %x72 %x65 %x61 %x74 %x65
membersKeyword = %x6D %x65 %x6D %x62 %x65 %x72 %x73
mandatoryKeyword = %x6D %x61 %x6E %x64 %x61 %x74 %x6F %x72 %x79
optionalKeyword = %x6F %x70 %x74 %x69 %x6F %x6E %x61 %x6C
refineKeyword = %x72 %x65 %x66 %x69 %x6E %x65
writetypeKeyword = %x77 %x72 %x69 %x74 %x65 %x74 %x79 %x70 %x65
;; End of ABNF
";
};
//
//
//
snmp {
node ccitt { oid 0; };
node zeroDotZero {
oid 0.0;
description "A null value used for pointers.";
};
node iso { oid 1; };
node org { oid iso.3; };
node dod { oid org.6; };
node internet { oid dod.1; };
node directory { oid internet.1; };
node mgmt { oid internet.2; };
node mib-2 { oid mgmt.1; };
node transmission { oid mib-2.10; };
node experimental { oid internet.3; };
node private { oid internet.4; };
node enterprises { oid private.1; };
node security { oid internet.5; };
node snmpV2 { oid internet.6; };
node snmpDomains { oid snmpV2.1; };
node snmpProxys { oid snmpV2.2; };
node snmpModules { oid snmpV2.3; };
node joint-iso-ccitt { oid 2; };
status current;
description
"This set of nodes defines the core object
identifier hierarchy";
reference
"RFC 2578, Section 2.";
};
};
6. NMRG-SMING-SNMP โจ
okay so the NMRG-SMING-SNMP module below is where the derived types live ๐ they're specifically made for the SNMP mapping, and that's literally the whole point ๐ฆ
okay bestie, the RowStatus part is where this module really shows off ๐ โจcreateAndGovscreateAndWaitis giving me big "you can have it now or later" energy ๐ฆ
typedef TestAndIncr {
type Integer32 (0..2147483647);
description
"Represents integer-valued information used for atomic
operations. When the management protocol is used to
specify that an object instance having this type is to
be modified, the new value supplied via the management
protocol must precisely match the value presently held by
the instance. If not, the management protocol set
operation fails with an error of `inconsistentValue'.
Otherwise, if the current value is the maximum value of
2^31-1 (2147483647 decimal), then the value held by the
instance is wrapped to zero; otherwise, the value held by
the instance is incremented by one. (Note that
regardless of whether the management protocol set
operation succeeds, the variable-binding in the request
and response PDUs are identical.)
The value of the SNMP access clause for objects having
this type has to be `readwrite'. When an instance of a
columnar object having this type is created, any value
may be supplied via the management protocol.
When the network management portion of the system is re-
initialized, the value of every object instance having
this type must either be incremented from its value prior
to the re-initialization, or (if the value prior to the
re-initialization is unknown) be set to a
pseudo-randomly generated value."; };
typedef AutonomousType {
type Pointer;
description
"Represents an independently extensible type
identification value. It may, for example, indicate a
particular OID sub-tree with further MIB definitions, or
define a particular type of protocol or hardware.";
};
typedef VariablePointer {
type Pointer;
description
"A pointer to a specific object instance. For example,
sysContact.0 or ifInOctets.3.";
};
typedef RowPointer {
type Pointer;
description
"Represents a pointer to a conceptual row. The value is
the name of the instance of the first accessible columnar
object in the conceptual row.
For example, ifIndex.3 would point to the 3rd row in the
ifTable (note that if ifIndex were not-accessible, then
ifDescr.3 would be used instead).";
};
typedef RowStatus {
type Enumeration (active(1), notInService(2),
notReady(3), createAndGo(4),
createAndWait(5), destroy(6));
description
"The RowStatus type is used to manage the creation and
deletion of conceptual rows, and is used as the type for the
row status column of a conceptual row.
The status column has six defined values:
- `active', which indicates that the conceptual row is
available for use by the managed device;
- `notInService', which indicates that the conceptual
row exists in the agent, but is unavailable for use by
the managed device (see NOTE below);
- `notReady', which indicates that the conceptual row
exists in the agent, but is missing information
necessary in order to be available for use by the
managed device;
- `createAndGo', which is supplied by a management
station wishing to create a new instance of a
conceptual row and to have its status automatically set
to active, making it available for use by the managed
device;
- `createAndWait', which is supplied by a management
station wishing to create a new instance of a
conceptual row (but not make it available for use by
the managed device); and,
- `destroy', which is supplied by a management station
wishing to delete all of the instances associated with
an existing conceptual row.
Whereas five of the six values (all except `notReady') may
be specified in a management protocol set operation, only
three values will be returned in response to a management
protocol retrieval operation: `notReady', `notInService' or
`active'. That is, when queried, an existing conceptual row
has only three states: it is either available for use by the
managed device (the status column has value `active'); it is
not available for use by the managed device, though the
agent has sufficient information to make it so (the status
column has value `notInService'); or, it is not available
for use by the managed device, and an attempt to make it so
would fail because the agent has insufficient information
(the state column has value `notReady').
NOTE WELL
This textual convention may be used for a MIB table,
irrespective of whether the values of that table's
conceptual rows are able to be modified while it is
active, or whether its conceptual rows must be taken
out of service in order to be modified. That is, it is
the responsibility of the DESCRIPTION clause of the
status column to specify whether the status column must
not be `active' in order for the value of some other
column of the same conceptual row to be modified. If
such a specification is made, affected columns may be
changed by an SNMP set PDU if the RowStatus would not
be equal to `active' either immediately before or after
processing the PDU. In other words, if the PDU also
contained a varbind that would change the RowStatus
value, the column in question may be changed if the
RowStatus was not equal to `active' as the PDU was
received, or if the varbind sets the status to a value
other than 'active'.
Also note that whenever any elements of a row exist, the
RowStatus column must also exist.
To summarize the effect of having a conceptual row with a
column having a type of RowStatus, consider the following
state diagram:
STATE
+--------------+-----------+-------------+-------------
| A | B | C | D
| |status col.|status column|
|status column | is | is |status column
ACTION |does not exist| notReady | notInService| is active
--------------+--------------+-----------+-------------+-------------
set status |noError ->D|inconsist- |inconsistent-|inconsistent-
column to | or | entValue| Value| Value
createAndGo |inconsistent- | | |
| Value| | |
--------------+--------------+-----------+-------------+-------------
set status |noError see 1|inconsist- |inconsistent-|inconsistent-
column to | or | entValue| Value| Value
createAndWait |wrongValue | | |
--------------+--------------+-----------+-------------+-------------
set status |inconsistent- |inconsist- |noError |noError
column to | Value| entValue| |
active | | | |
| | or | |
| | | |
| |see 2 ->D|see 8 ->D| ->D
--------------+--------------+-----------+-------------+-------------
set status |inconsistent- |inconsist- |noError |noError ->C
column to | Value| entValue| |
notInService | | | |
| | or | | or
| | | |
| |see 3 ->C| ->C|see 6
--------------+--------------+-----------+-------------+-------------
set status |noError |noError |noError |noError ->A
column to | | | | or
destroy | ->A| ->A| ->A|see 7
--------------+--------------+-----------+-------------+-------------
set any other |see 4 |noError |noError |see 5
column to some| | | |
value | | see 1| ->C| ->D
--------------+--------------+-----------+-------------+-------------
(1) go to B or C, depending on information available to the
agent.
(2) if other variable bindings included in the same PDU,
provide values for all columns which are missing but
required, then return noError and goto D.
(3) if other variable bindings included in the same PDU,
provide values for all columns which are missing but
required, then return noError and goto C.
(4) at the discretion of the agent, the return value may be
either:
inconsistentName: because the agent does not choose to
create such an instance when the corresponding
RowStatus instance does not exist, or
inconsistentValue: if the supplied value is
inconsistent with the state of some other MIB object's
value, or
noError: because the agent chooses to create the
instance.
If noError is returned, then the instance of the status
column must also be created, and the new state is B or C,
depending on the information available to the agent. If
inconsistentName or inconsistentValue is returned, the row
remains in state A.
(5) depending on the MIB definition for the column/table,
either noError or inconsistentValue may be returned.
(6) okay so the return value can indicate one of these errors ๐ฅบ:
wrongValue: because the agent does not supportcreateAndWait, orinconsistentValue: because the agent is unable to take the row out of service at this time, perhaps because it is in use and cannot be de-activated.
(7) the return value can indicate this error ๐:
inconsistentValue: because the agent is unable to remove the row at this time, perhaps because it is in use and cannot be de-activated.
NOTE: other processing of the set request may result in a response other than noError being returned, e.g., wrongValue, noCreation, etc. ๐
Conceptual Row Creation โจ
Making a conceptual row has four possible interactions, bestie ๐ :
- selecting an instance-identifier that isn't in use,
- creating the conceptual row,
- initializing any objects the agent doesn't supply a default for, and
- making the conceptual row available for use by the managed device.
Interaction 1: Selecting an Instance-Identifier ๐ฆ
The way an instance-identifier gets picked is different for every conceptual row. Sometimes the instance-identifier actually means something, like the destination address of a route, so the management station picks it based on that meaning ๐งญ.
Other times the instance-identifier is only there to tell rows apart. A management station that has no specific knowledge of the conceptual row could look at the instances that already exist and hunt for an unused instance-identifier. (This approach may be used, but it's honestly super sub-optimal ๐ญ. It's also a questionable move for a naive management station to try creating a row in the first place.)
Another option is that the MIB module defining the conceptual row gives you one or more objects that help find an unused instance-identifier. For example, if the conceptual row is indexed by an integer-value, the MIB module could define an object with an integer-valued SYNTAX clause for exactly this job, so a management station can just send a management protocol retrieval operation and grab an answer ๐. To avoid pointless collisions between competing management stations, `adjacent' retrievals of this object should be different.
The last option is for the management station to pick a pseudo-random number and use it as the index. If that index is already in use and the management protocol set operation comes back with inconsistentValue, the management station should just pick a fresh pseudo-random number and retry ๐.
A MIB designer should choose between the two latter algorithms based on the size of the table, since that decides how efficient each one is ๐. For tables where a large number of entries are expected, it is recommended that a MIB object be defined that returns an acceptable index for creation. For tables with a small number of entries, it is recommended that the latter pseudo-random index mechanism be used.
Interaction 2: Creating the Conceptual Row ๐ธ
Once an unused instance-identifier has been selected, the management station decides whether it wants to create and activate the conceptual row in one transaction, or work it out through a negotiated set of interactions ๐ค.
Interaction 2a: Creating and Activating the Conceptual Row ๐
First things first: the management station must determine the column requirements. That means figuring out which columns it must provide values for, and which columns it must not. Depending on how complicated the table is and how much the management station knows about the agent's capabilities, it can figure this out locally. Otherwise, the management station can issue a management protocol get operation to examine all the columns in the conceptual row it wants to create. For each column, there are three possible outcomes in the response ๐:
- A value is returned, which means some other management station has already created this conceptual row. We return to interaction 1.
- The exception
noSuchInstance' is returned, which means the agent implements the object-type associated with this column, and this column would be accessible in the MIB view used by the retrieval in at least one conceptual row if it existed. For columns the agent gives read-create access to,noSuchInstance' tells the management station it should supply a value for this column when the conceptual row is created. - The exception `noSuchObject' is returned, which means either the agent doesn't implement the object-type associated with this column, or there's no conceptual row where this column would be accessible in the MIB view used by the retrieval. So the management station can't issue any management protocol set operations to create an instance of this column ๐ซ.
Once the column requirements are sorted, a management protocol set operation gets issued to match. This operation also sets the new instance of the status column to `createAndGo'.
When the agent processes the set operation, it checks whether it has enough information to make the conceptual row available for use by the managed device. The agent gets that information from two places: the management protocol set operation that creates the row, and implementation-specific defaults the agent supplies (and note that an agent must provide implementation-specific defaults for at least the objects it implements as read-only ๐).
If there's enough information, the conceptual row is created, a noError' response comes back, the status column is set to active', and nothing else is needed. Interactions 3 and 4 get skipped โญ๏ธ. If there isn't enough information, the conceptual row is not created, and the set operation fails with an error of inconsistentValue'. The management station can then issue a management protocol retrieval operation to find out why. Was it because a required column didn't get a value, or because the selected instance of the status column already existed? If it's the latter, we return to interaction 1. If it's the former, the management station can re-issue the set operation with the extra information, or start interaction 2 over using createAndWait' to negotiate the creation of the conceptual row ๐.
NOTE WELL โ ๏ธ No matter how the column requirements were figured out, the management station might decide a column is necessary when the agent actually won't let that particular columnar instance be created or written. In that case, the management protocol set operation fails with an error such as noCreation' or notWritable'. The management station then decides whether it really needs to set a value for that particular columnar instance. If not, it re-issues the management protocol set operation without setting a value for that columnar instance. Otherwise, it aborts the row creation algorithm ๐.
Interaction 2b: Negotiating the Creation of the Conceptual Row ๐ค
The management station issues a management protocol set operation that sets the desired instance of the status column to createAndWait'. If the agent isn't willing to process a request like this, the set operation fails with an error of wrongValue'. (So an agent like this must be ready to accept a single management protocol set operation, which is interaction 2a above, containing all of the columns in its column requirements ๐ซถ.) Otherwise, the conceptual row is created, a noError' response comes back, and the status column is immediately set to either notInService' or notReady', depending on whether the agent has enough information to make the conceptual row available for use by the managed device. If there's enough information, the status column is set to notInService'. If there isn't, the status column is set to `notReady'. Either way, we proceed to interaction 3 ๐ฆ.
Interaction 3: Initializing non-defaulted Objects ๐ง
Now the management station must determine the column requirements. It issues a management protocol get operation to examine all the columns in the created conceptual row. For each column, there are three possible outcomes in the response ๐:
- A value is returned, which means the agent implements the object-type associated with this column and had enough information to provide a value. For columns the agent gives read-create access to (and for which the agent allows their values to be changed after creation), a returned value tells the management station it may issue additional management protocol set operations, if it wants to, to change the value of this column.
- The exception
noSuchInstance' is returned, which means the agent implements the object-type associated with this column, and this column would be accessible in the MIB view used by the retrieval in at least one conceptual row if it existed. However, the agent doesn't have enough information to provide a value, and until a value is provided, the conceptual row may not be made available for use by the managed device. For columns the agent gives read-create access to,noSuchInstance' tells the management station that it must issue additional management protocol set operations to provide a value for this column ๐. - the exception
noSuchObjectcomes back, meaning the agent doesn't implement the object type for this column, or there's no conceptual row this column could be reached through in the MIB view used for that retrieval. So the management station can't issue any management protocol set operations to create an instance of this column ๐
If the status column is notReady, the management station must first deal with any noSuchInstance columns. Once that's sorted, the status column moves to notInService, and we move on to interaction 4 ๐
Interaction 4: Making the Conceptual Row Available ๐ฆ
Once the management station is happy with the values in the columns of the conceptual row, it sends a management protocol set operation to set the status column to active. If the agent has enough information to make the row available for the managed device, the set succeeds and a noError response comes back. If not, the set fails with an error of inconsistentValue ๐ญ
NOTE WELL: a conceptual row whose status isnotInServiceornotReadyis unavailable to the managed device. That means the managed device can create its own instances in the gap between the set that puts the status tocreateAndWaitand the set that puts it toactive. When the set toactivefinally goes through, the values held in the agent supersede the ones the managed device used. Main character drama ๐
If the management station gets stopped from setting the status to active (for example, because of a management station or network failure), the row stays in notInService or notReady and keeps eating resources indefinitely. The agent must detect rows that have been in either state for an abnormally long time and remove them. The DESCRIPTION clause of the status column is the one that's supposed to say what "abnormally long" means. That period should be long enough for human response time (including "think time") between creating the row and setting it to active. If the DESCRIPTION clause doesn't say anything about it, the suggestion is about 5 minutes โฐ This removal rule covers more than brand-new rows, too. It also applies to previously active rows that get set to, and left in, the notInService state for longer than is considered normal for that kind of row ๐ฅน
Conceptual Row Suspension ๐ธ
When a conceptual row is active, the management station may send a set operation that puts the status instance to notInService. If the agent isn't willing to do that, the set fails with an error of wrongValue or inconsistentValue. Otherwise the row is taken out of service and a noError response comes back. The DESCRIPTION clause of the status column is responsible for explaining when the status column should be taken out of service, for example so another column in the same row can be modified ๐
Conceptual Row Deletion ๐
To delete a conceptual row, the management station sends a set operation that puts the status instance to destroy. This works no matter what the current status is, so you can delete rows that are notReady, notInService, or active ๐ง If the operation succeeds, every instance tied to that row is removed right away โจ
typedef StorageType {
type Enumeration (other(1), volatile(2),
nonVolatile(3), permanent(4),
readOnly(5));
description
"Describes the memory realization of a conceptual row. A
row which is volatile(2) is lost upon reboot. A row
which is either nonVolatile(3), permanent(4) or
readOnly(5), is backed up by stable storage. A row which
is permanent(4) can be changed but not deleted. A row
which is readOnly(5) cannot be changed nor deleted.
If the value of an object with this syntax is either
permanent(4) or readOnly(5), it cannot be modified.
Conversely, if the value is either other(1), volatile(2)
or nonVolatile(3), it cannot be modified to be
permanent(4) or readOnly(5). (All illegal modifications
result in a 'wrongValue' error.)
Every usage of this textual convention is required to
specify the columnar objects which a permanent(4) row
must at a minimum allow to be writable.";
};
typedef TDomain {
type Pointer;
description
"Denotes a kind of transport service.
Some possible values, such as snmpUDPDomain, are defined
in the SNMPv2-TM MIB module. Other possible values are
defined in other MIB modules."
reference
"The SNMPv2-TM MIB module is defined in RFC 3417."
};
typedef TAddressOrZero {
type OctetString (0..255);
description
"Denotes a transport service address.
A TAddress value is always interpreted within the context
of a TDomain value. Thus, each definition of a TDomain
value must be accompanied by a definition of a textual
convention for use with that TDomain. Some possible
textual conventions, such as SnmpUDPAddress for
snmpUDPDomain, are defined in the SNMPv2-TM MIB module.
Other possible textual conventions are defined in other
MIB modules.
A zero-length TAddress value denotes an unknown transport
service address."
reference
"The SNMPv2-TM MIB module is defined in RFC 3417."
};
typedef TAddress {
type TAddressOrZero (1..255);
description
"Denotes a transport service address.
This type does not allow a zero-length TAddress value."
};
};
7. Security Considerations ๐
This document extends the SMIng data definition language so that SMIng data definitions can be mapped and used with the SNMP management framework. ngl, the language extension and the mapping itself have no security impact on the Internet ๐ซถ
8. Acknowledgements ๐
Since SMIng started out as a close successor to SMIv2, some paragraphs and phrases were taken directly from the SMIv2 specifications [RFC2578], [RFC2579], [RFC2580]. Those were written by Jeff Case, Keith McCloghrie, David Perkins, Marshall T. Rose, Juergen Schoenwaelder, and Steven L. Waldbusser, and we owe them so much ๐
The authors would like to thank everyone who took part in the 7th NMRG meeting, held at Schloss Kleinheubach from 6-8 September 2000. That meeting was a big step toward where this memo is now. Thank you to Heiko Dassow, David Durham, Keith McCloghrie, and Bert Wijnen ๐
On top of that, several discussions within the SMING Working Group drew on experience with SMIv2 and shaped this specification in a few places โจ
9. References ๐
9.1. Normative References
- [RFC3780] Strauss, F. and J. Schoenwaelder, "SMIng - Next Generation Structure of Management Information", RFC 3780, May 2004.
- [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997.
- [RFC2234] Crocker, D. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 2234, November 1997.
9.2. Informative References
- [RFC3410] Case, J., Mundy, R., Partain, D. and B. Stewart, "Introduction and Applicability Statements for Internet Standard Management Framework", RFC 3410, December 2002.
- [RFC2578] McCloghrie, K., Perkins, D. and J. Schoenwaelder, "Structure of Management Information Version 2 (SMIv2)", STD 58, RFC 2578, April 1999.
- [RFC2579] McCloghrie, K., Perkins, D. and J. Schoenwaelder, "Textual Conventions for SMIv2", STD 59, RFC 2579, April 1999.
- [RFC2580] McCloghrie, K., Perkins, D. and J. Schoenwaelder, "Conformance Statements for SMIv2", STD 60, RFC 2580, April 1999.
- [ASN1] International Organization for Standardization, "Specification of Abstract Syntax Notation One (ASN.1)", International Standard 8824, December 1987.
- [RFC3159] McCloghrie, K., Fine, M., Seligson, J., Chan, K., Hahn, S., Sahita, R., Smith, A. and F. Reichmeyer, "Structure of Policy Provisioning Information (SPPI)", RFC 3159, August 2001.
- [IEEE754] Institute of Electrical and Electronics Engineers, "IEEE Standard for Binary Floating-Point Arithmetic", ANSI/IEEE Standard 754-1985, August 1985.
- [RFC3418] Presuhn, R., Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Management Information Base (MIB) for the Simple Network Management Protocol (SNMP)", STD 62, RFC 3418, December 2002.
- [RFC3416] Presuhn, R., Case, J., McCloghrie, K., Rose, M. and S. Waldbusser, "Version 2 of the Protocol Operations for the Simple Network Management Protocol (SNMP)", STD 62, RFC 3416, December 2002.
Authors' Addresses ๐
Frank Strauss
TU Braunschweig
Muehlenpfordtstrasse 23
38106 Braunschweig
Germany
Phone: +49 531 391 3266
EMail: strauss@ibr.cs.tu-bs.de
URI: http://www.ibr.cs.tu-bs.de/
Juergen Schoenwaelder
International University Bremen
P.O. Box 750 561
28725 Bremen
Germany
Phone: +49 421 200 3587
EMail: j.schoenwaelder@iu-bremen.de
URI: http://www.eecs.iu-bremen.de/
Full Copyright Statement โญ
Copyright (C) The Internet Society (2004). This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth there, the authors keep all their rights ๐ฆ
This document and the information in it are provided on an "AS IS" basis. THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, including but not limited to any warranty that using the information here will not infringe any rights, and any implied warranties of merchantability or fitness for a particular purpose ๐
Intellectual Property ๐
Okay bestie, this part is the legal stuff, but it's still important ๐ซถ The IETF doesn't take a side on whether anyone owns rights to the tech in this doc, or whether you can get a license for it. It also doesn't claim it went out and checked for any of that ๐ If you want the rules on RFC rights, check out BCP 78 and BCP 79 โจ
If you're an implementer or user and want to see IPR disclosures, the stuff people have sent to the IETF Secretariat, or any license assurances, head to the IETF's online IPR repository at http://www.ietf.org/ipr ๐ฆ
And if you know about any copyrights, patents, patent applications, or other proprietary rights that might cover tech you'd need to build this standard, tell the IETF! Send it to ietf-ipr@ietf.org ๐ฌ Spill the tea, it helps everyone ๐
Acknowledgement ๐ธ
The RFC Editor function is funded right now by the Internet Society. Thank you, Internet Society, you're iconic ๐โจ
๐ฆ where this page comes from
- ietf: rfc3781 2004-05
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms