RFC 3781

Next Generation Structure of Management Information (SMIng) Mappings to the Simple Network Management Protocol (SNMP)

๐Ÿ“… published May 2004, from ietf

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 (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 SMIng identity' 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 the snmp' 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 the scalars' statement contains one implements' statement for each class. The associated statement blocks in turn contain object' 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 by implements' statements. The statement block of each implements' statement contains object' 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, where n' 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, where n' 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, where n' 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, where n' 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's access statement, and less than or equal to the maximal level in the object's access statement ๐ŸŽ€

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 ๐Ÿ’…โœจ createAndGo vs createAndWait is 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 support createAndWait, or
  • inconsistentValue: 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 ๐Ÿ’…:

  1. selecting an instance-identifier that isn't in use,
  2. creating the conceptual row,
  3. initializing any objects the agent doesn't supply a default for, and
  4. 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 noSuchObject comes 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 is notInService or notReady is 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 to createAndWait and the set that puts it to active. When the set to active finally 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/

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